aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-09 17:50:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-09 17:50:09 -0400
commitea5aee6d97fd2d4499b1eebc233861c1def70f06 (patch)
tree6b332e66bb0ec00b2e35c074ec3f09fb7cf56a1e
parent8e4ff713ce313dcabbb60e6ede1ffc193e67631f (diff)
parentc1157f60d72e8b20efc670cef28883832f42406c (diff)
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk framework updates from Stephen Boyd: "We have a couple new features and changes in the core clk framework this time around because we've finally gotten around to fixing some long standing issues. There's still work to do though, so this pull request is largely laying down the foundation for all the driver changes to come in the next merge window. The first problem we're alleviating is how parents of clks are specified. With the new method, we should see lots of drivers migrate away from the current design of string comparisons on the entire clk tree to a more direct method where they can use clk_hw pointers or more localized names specified in DT or via clkdev. This should reduce our reliance on string comparisons for all the topology description logic that we've been using for years and hopefully speed some things up while avoiding problems we have with generating clk names. Beyond that we also got rid of the CLK_IS_BASIC flag because it wasn't really helping anyone and we introduced big-endian versions of the basic clk types so that we can get rid of clk_{readl,writel}(). Both of these are things that driver developers have tried to use over the years that I typically bat away during code reviews because they're not useful. It's great to see these two things go away so maintainers can save time not worrying about these things. On the driver side we got the usual collection of new SoC support and non-critical fixes and updates to existing code. The big topics that stand out are the new driver support for Mediatek MT8183 and MT8516 SoCs, Amlogic Meson8b and G12a SoCs, and the SiFive FU540 SoC. The other patches in the driver pile are mostly fixes for things that are being used for the first time or additions for clks that couldn't be tested before because there wasn't a consumer driver that exercised them. Details are below and also in the sub-maintainer tags. Core: - Remove clk_readl() and introduce BE versions of basic clk types - Rewrite how clk parents can be specified to allow DT/clkdev lookups - Removal of the CLK_IS_BASIC clk flag - Framework documentation updates and fixes New Drivers: - Support for STM32F769 - AT91 sam9x60 PMC support - SiFive FU540 PRCI and PLL support - Qualcomm QCS404 CDSP clk support - Qualcomm QCS404 Turing clk support - Mediatek MT8183 clock support - Mediatek MT8516 clock support - Milbeaut M10V clk controller support - Support for Cirrus Logic Lochnagar clks Updates: - Rework AT91 sckc DT bindings - Fix slow RC oscillator issue on sama5d3 - Mark UFS clk as critical on Hi-Silicon hi3660 SoCs - Various static analysis fixes/finds and const markings - Video Engine (ECLK) support on Aspeed SoCs - Xilinx ZynqMP Versal platform support - Convert Xilinx ZynqMP driver to be struct oriented - Fixes for Rockchip rk3328 and rk3288 SoCs - Sub-type for Rockchip SoCs where mux and divider aren't a single register - Remove SNVS clock from i.MX7UPL clock driver and bindings - Improve i.MX5 clock driver for i.MX50 support - Addition of ADC clock definition for Exynos 5410 SoC (Odroid XU) - Export a new clock for the MBUS controller on the A13 - Allwinner H6 fixes to support a finer clocking of the video and VPU engines - Add g12a support in the Amlogic axg audio clock controller - Add missing PCI USB clock on Rensas RZ/N1 - Add Z2 (Cortex-A53) clocks on Rensas R-Car E3 and RZ/G2E - A new helper DIV64_U64_ROUND_CLOSEST() in <linux/math64.h> - VPU and Video Decoder clocks on Amlogic Meson8b - Finally remove the wrong ABP Meson8b clock id - Add Video Decoder, PCIe PLL, and CPU Clocks on Amlogic G12A - Re-expose SAR_ADC_SEL and CTS_OSCIN on Amlogic G12A AO clock controller - Un-expose some Amlogic AXG-Audio input clocks IDs" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (172 commits) clk: Cache core in clk_fetch_parent_index() without names clk: imx: correct pfdv2 gate_bit/vld_bit operations clk: sifive: add a driver for the SiFive FU540 PRCI IP block clk: analogbits: add Wide-Range PLL library clk: imx: clk-pllv3: mark expected switch fall-throughs clk: imx8mq: Add dsi_ipg_div clk: imx: pllv4: add fractional-N pll support clk: sunxi-ng: Use the correct style for SPDX License Identifier clk: sprd: Use the correct style for SPDX License Identifier clk: renesas: Use the correct style for SPDX License Identifier clk: qcom: Use the correct style for SPDX License Identifier clk: davinci: Use the correct style for SPDX License Identifier clk: actions: Use the correct style for SPDX License Identifier clk: imx: keep uart clock on during system boot clk: imx: correct i.MX7D AV PLL num/denom offset dt-bindings: clk: add documentation for the SiFive PRCI driver clk: stm32mp1: Add ddrperfm clock clk: Remove CLK_IS_BASIC clk flag clock: milbeaut: Add Milbeaut M10V clock controller dt-bindings: clock: milbeaut: add Milbeaut clock description ...
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt2
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt1
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt22
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt1
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt2
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,ipu.txt43
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt1
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt1
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt1
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt2
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt1
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt1
-rw-r--r--Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt3
-rw-r--r--Documentation/devicetree/bindings/clock/at91-clock.txt33
-rw-r--r--Documentation/devicetree/bindings/clock/cirrus,lochnagar.txt93
-rw-r--r--Documentation/devicetree/bindings/clock/milbeaut-clock.yaml73
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,turingcc.txt19
-rw-r--r--Documentation/devicetree/bindings/clock/qoriq-clock.txt5
-rw-r--r--Documentation/devicetree/bindings/clock/sifive/fu540-prci.txt46
-rw-r--r--Documentation/devicetree/bindings/clock/st,stm32-rcc.txt6
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arm/mach-omap2/clock.c3
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c4
-rw-r--r--arch/mips/alchemy/common/clock.c2
-rw-r--r--arch/powerpc/platforms/512x/clock-commonclk.c9
-rw-r--r--drivers/clk/Kconfig11
-rw-r--r--drivers/clk/Makefile4
-rw-r--r--drivers/clk/actions/owl-common.h2
-rw-r--r--drivers/clk/actions/owl-composite.h2
-rw-r--r--drivers/clk/actions/owl-divider.h2
-rw-r--r--drivers/clk/actions/owl-factor.h2
-rw-r--r--drivers/clk/actions/owl-fixed-factor.h2
-rw-r--r--drivers/clk/actions/owl-gate.h2
-rw-r--r--drivers/clk/actions/owl-mux.h2
-rw-r--r--drivers/clk/actions/owl-pll.h2
-rw-r--r--drivers/clk/actions/owl-reset.h2
-rw-r--r--drivers/clk/analogbits/Kconfig2
-rw-r--r--drivers/clk/analogbits/Makefile3
-rw-r--r--drivers/clk/analogbits/wrpll-cln28hpc.c364
-rw-r--r--drivers/clk/at91/Makefile2
-rw-r--r--drivers/clk/at91/at91sam9260.c14
-rw-r--r--drivers/clk/at91/at91sam9rl.c2
-rw-r--r--drivers/clk/at91/at91sam9x5.c11
-rw-r--r--drivers/clk/at91/clk-generated.c48
-rw-r--r--drivers/clk/at91/clk-master.c8
-rw-r--r--drivers/clk/at91/clk-peripheral.c46
-rw-r--r--drivers/clk/at91/clk-sam9x60-pll.c330
-rw-r--r--drivers/clk/at91/clk-usb.c33
-rw-r--r--drivers/clk/at91/dt-compat.c12
-rw-r--r--drivers/clk/at91/pmc.h25
-rw-r--r--drivers/clk/at91/sam9x60.c307
-rw-r--r--drivers/clk/at91/sama5d2.c12
-rw-r--r--drivers/clk/at91/sama5d4.c10
-rw-r--r--drivers/clk/at91/sckc.c134
-rw-r--r--drivers/clk/clk-aspeed.c42
-rw-r--r--drivers/clk/clk-composite.c2
-rw-r--r--drivers/clk/clk-divider.c26
-rw-r--r--drivers/clk/clk-fixed-factor.c57
-rw-r--r--drivers/clk/clk-fixed-rate.c2
-rw-r--r--drivers/clk/clk-fractional-divider.c24
-rw-r--r--drivers/clk/clk-gate.c24
-rw-r--r--drivers/clk/clk-gpio.c2
-rw-r--r--drivers/clk/clk-highbank.c23
-rw-r--r--drivers/clk/clk-lochnagar.c336
-rw-r--r--drivers/clk/clk-milbeaut.c663
-rw-r--r--drivers/clk/clk-multiplier.c22
-rw-r--r--drivers/clk/clk-mux.c24
-rw-r--r--drivers/clk/clk-pwm.c2
-rw-r--r--drivers/clk/clk-qoriq.c77
-rw-r--r--drivers/clk/clk-stm32f4.c307
-rw-r--r--drivers/clk/clk-stm32mp1.c3
-rw-r--r--drivers/clk/clk-xgene.c6
-rw-r--r--drivers/clk/clk.c392
-rw-r--r--drivers/clk/clk.h2
-rw-r--r--drivers/clk/clkdev.c25
-rw-r--r--drivers/clk/davinci/da8xx-cfgchip.c4
-rw-r--r--drivers/clk/davinci/pll.h2
-rw-r--r--drivers/clk/davinci/psc.h2
-rw-r--r--drivers/clk/hisilicon/clk-hi3660.c6
-rw-r--r--drivers/clk/hisilicon/clk-hisi-phase.c4
-rw-r--r--drivers/clk/imx/Makefile2
-rw-r--r--drivers/clk/imx/clk-divider-gate.c20
-rw-r--r--drivers/clk/imx/clk-imx5.c (renamed from drivers/clk/imx/clk-imx51-imx53.c)59
-rw-r--r--drivers/clk/imx/clk-imx6sll.c18
-rw-r--r--drivers/clk/imx/clk-imx7d.c4
-rw-r--r--drivers/clk/imx/clk-imx7ulp.c1
-rw-r--r--drivers/clk/imx/clk-imx8mq.c1
-rw-r--r--drivers/clk/imx/clk-pfdv2.c10
-rw-r--r--drivers/clk/imx/clk-pll14xx.c6
-rw-r--r--drivers/clk/imx/clk-pllv3.c31
-rw-r--r--drivers/clk/imx/clk-pllv4.c72
-rw-r--r--drivers/clk/imx/clk-sccg-pll.c12
-rw-r--r--drivers/clk/imx/clk.h6
-rw-r--r--drivers/clk/ingenic/jz4725b-cgu.c6
-rw-r--r--drivers/clk/mediatek/Kconfig83
-rw-r--r--drivers/clk/mediatek/Makefile16
-rw-r--r--drivers/clk/mediatek/clk-gate.h14
-rw-r--r--drivers/clk/mediatek/clk-mt8183-audio.c105
-rw-r--r--drivers/clk/mediatek/clk-mt8183-cam.c63
-rw-r--r--drivers/clk/mediatek/clk-mt8183-img.c63
-rw-r--r--drivers/clk/mediatek/clk-mt8183-ipu0.c56
-rw-r--r--drivers/clk/mediatek/clk-mt8183-ipu1.c56
-rw-r--r--drivers/clk/mediatek/clk-mt8183-ipu_adl.c54
-rw-r--r--drivers/clk/mediatek/clk-mt8183-ipu_conn.c123
-rw-r--r--drivers/clk/mediatek/clk-mt8183-mfgcfg.c54
-rw-r--r--drivers/clk/mediatek/clk-mt8183-mm.c111
-rw-r--r--drivers/clk/mediatek/clk-mt8183-vdec.c67
-rw-r--r--drivers/clk/mediatek/clk-mt8183-venc.c59
-rw-r--r--drivers/clk/mediatek/clk-mt8183.c1284
-rw-r--r--drivers/clk/mediatek/clk-mt8516.c815
-rw-r--r--drivers/clk/mediatek/clk-mtk.h3
-rw-r--r--drivers/clk/mediatek/clk-mux.c223
-rw-r--r--drivers/clk/mediatek/clk-mux.h89
-rw-r--r--drivers/clk/mediatek/clk-pll.c87
-rw-r--r--drivers/clk/meson/axg-audio.c1219
-rw-r--r--drivers/clk/meson/axg-audio.h16
-rw-r--r--drivers/clk/meson/clk-pll.c26
-rw-r--r--drivers/clk/meson/clk-pll.h1
-rw-r--r--drivers/clk/meson/g12a-aoclk.h2
-rw-r--r--drivers/clk/meson/g12a.c631
-rw-r--r--drivers/clk/meson/g12a.h31
-rw-r--r--drivers/clk/meson/meson8b.c734
-rw-r--r--drivers/clk/meson/meson8b.h27
-rw-r--r--drivers/clk/mmp/clk-gate.c2
-rw-r--r--drivers/clk/mvebu/common.c2
-rw-r--r--drivers/clk/mvebu/cp110-system-controller.c4
-rw-r--r--drivers/clk/nxp/clk-lpc18xx-ccu.c6
-rw-r--r--drivers/clk/nxp/clk-lpc18xx-cgu.c24
-rw-r--r--drivers/clk/nxp/clk-lpc32xx.c7
-rw-r--r--drivers/clk/qcom/Kconfig6
-rw-r--r--drivers/clk/qcom/Makefile1
-rw-r--r--drivers/clk/qcom/clk-branch.c6
-rw-r--r--drivers/clk/qcom/clk-branch.h1
-rw-r--r--drivers/clk/qcom/clk-regmap-mux-div.h2
-rw-r--r--drivers/clk/qcom/gcc-msm8998.c2
-rw-r--r--drivers/clk/qcom/gcc-qcs404.c90
-rw-r--r--drivers/clk/qcom/turingcc-qcs404.c170
-rw-r--r--drivers/clk/renesas/r7s9210-cpg-mssr.c3
-rw-r--r--drivers/clk/renesas/r8a774a1-cpg-mssr.c18
-rw-r--r--drivers/clk/renesas/r8a774c0-cpg-mssr.c7
-rw-r--r--drivers/clk/renesas/r8a7795-cpg-mssr.c41
-rw-r--r--drivers/clk/renesas/r8a7796-cpg-mssr.c35
-rw-r--r--drivers/clk/renesas/r8a77965-cpg-mssr.c33
-rw-r--r--drivers/clk/renesas/r8a77980-cpg-mssr.c2
-rw-r--r--drivers/clk/renesas/r8a77990-cpg-mssr.c25
-rw-r--r--drivers/clk/renesas/r8a77995-cpg-mssr.c2
-rw-r--r--drivers/clk/renesas/r9a06g032-clocks.c1
-rw-r--r--drivers/clk/renesas/rcar-gen2-cpg.h4
-rw-r--r--drivers/clk/renesas/rcar-gen3-cpg.c71
-rw-r--r--drivers/clk/renesas/rcar-gen3-cpg.h9
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.h4
-rw-r--r--drivers/clk/rockchip/clk-ddr.c2
-rw-r--r--drivers/clk/rockchip/clk-half-divider.c6
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c36
-rw-r--r--drivers/clk/rockchip/clk-rk3328.c18
-rw-r--r--drivers/clk/rockchip/clk.c9
-rw-r--r--drivers/clk/rockchip/clk.h23
-rw-r--r--drivers/clk/samsung/clk-exynos5410.c1
-rw-r--r--drivers/clk/sifive/Kconfig18
-rw-r--r--drivers/clk/sifive/Makefile1
-rw-r--r--drivers/clk/sifive/fu540-prci.c626
-rw-r--r--drivers/clk/sprd/common.h2
-rw-r--r--drivers/clk/sprd/composite.h2
-rw-r--r--drivers/clk/sprd/div.h2
-rw-r--r--drivers/clk/sprd/gate.h2
-rw-r--r--drivers/clk/sprd/mux.h2
-rw-r--r--drivers/clk/sprd/pll.h2
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun50i-a64.c3
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun50i-h6.c19
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun50i-h6.h2
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun5i.h4
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a83t.c5
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-v3s.c3
-rw-r--r--drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c2
-rw-r--r--drivers/clk/sunxi-ng/ccu-suniv-f1c100s.h4
-rw-r--r--drivers/clk/sunxi/Kconfig43
-rw-r--r--drivers/clk/sunxi/Makefile49
-rw-r--r--drivers/clk/tegra/clk-divider.c3
-rw-r--r--drivers/clk/tegra/clk-emc.c57
-rw-r--r--drivers/clk/tegra/clk-pll.c54
-rw-r--r--drivers/clk/tegra/clk-super.c2
-rw-r--r--drivers/clk/tegra/clk-tegra124.c7
-rw-r--r--drivers/clk/tegra/clk-tegra210.c6
-rw-r--r--drivers/clk/ti/clk-7xx-compat.c6
-rw-r--r--drivers/clk/ti/clk-7xx.c6
-rw-r--r--drivers/clk/ti/clkctrl.c17
-rw-r--r--drivers/clk/ti/clock.h8
-rw-r--r--drivers/clk/ux500/clk-sysctrl.c3
-rw-r--r--drivers/clk/zynq/clkc.c6
-rw-r--r--drivers/clk/zynq/pll.c18
-rw-r--r--drivers/clk/zynqmp/clk-mux-zynqmp.c1
-rw-r--r--drivers/clk/zynqmp/clk-zynqmp.h6
-rw-r--r--drivers/clk/zynqmp/clkc.c180
-rw-r--r--drivers/clk/zynqmp/divider.c17
-rw-r--r--drivers/pwm/pwm-meson.c2
-rw-r--r--include/dt-bindings/clock/axg-audio-clkc.h30
-rw-r--r--include/dt-bindings/clock/exynos5410.h3
-rw-r--r--include/dt-bindings/clock/g12a-aoclkc.h2
-rw-r--r--include/dt-bindings/clock/g12a-clkc.h5
-rw-r--r--include/dt-bindings/clock/imx7ulp-clock.h1
-rw-r--r--include/dt-bindings/clock/jz4725b-cgu.h1
-rw-r--r--include/dt-bindings/clock/meson8b-clkc.h6
-rw-r--r--include/dt-bindings/clock/mt8183-clk.h422
-rw-r--r--include/dt-bindings/clock/mt8516-clk.h211
-rw-r--r--include/dt-bindings/clock/qcom,gcc-qcs404.h5
-rw-r--r--include/dt-bindings/clock/qcom,turingcc-qcs404.h15
-rw-r--r--include/dt-bindings/clock/stm32fx-clock.h7
-rw-r--r--include/dt-bindings/clock/sun5i-ccu.h2
-rw-r--r--include/linux/clk-provider.h112
-rw-r--r--include/linux/clk/analogbits-wrpll-cln28hpc.h79
-rw-r--r--include/linux/clk/at91_pmc.h12
-rw-r--r--include/linux/clk/ti.h2
-rw-r--r--include/linux/device.h2
-rw-r--r--include/linux/math64.h13
214 files changed, 11543 insertions, 1465 deletions
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
index de4075413d91..161e63a6c254 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
@@ -14,6 +14,8 @@ Required Properties:
14 - "mediatek,mt7629-apmixedsys" 14 - "mediatek,mt7629-apmixedsys"
15 - "mediatek,mt8135-apmixedsys" 15 - "mediatek,mt8135-apmixedsys"
16 - "mediatek,mt8173-apmixedsys" 16 - "mediatek,mt8173-apmixedsys"
17 - "mediatek,mt8183-apmixedsys", "syscon"
18 - "mediatek,mt8516-apmixedsys"
17- #clock-cells: Must be 1 19- #clock-cells: Must be 1
18 20
19The apmixedsys controller uses the common clk binding from 21The apmixedsys controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
index d1606b2c3e63..f3cef1a6d95c 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
@@ -9,6 +9,7 @@ Required Properties:
9 - "mediatek,mt2701-audsys", "syscon" 9 - "mediatek,mt2701-audsys", "syscon"
10 - "mediatek,mt7622-audsys", "syscon" 10 - "mediatek,mt7622-audsys", "syscon"
11 - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon" 11 - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon"
12 - "mediatek,mt8183-audiosys", "syscon"
12- #clock-cells: Must be 1 13- #clock-cells: Must be 1
13 14
14The AUDSYS controller uses the common clk binding from 15The AUDSYS controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
new file mode 100644
index 000000000000..d8930f64aa98
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt
@@ -0,0 +1,22 @@
1MediaTek CAMSYS controller
2============================
3
4The MediaTek camsys controller provides various clocks to the system.
5
6Required Properties:
7
8- compatible: Should be one of:
9 - "mediatek,mt8183-camsys", "syscon"
10- #clock-cells: Must be 1
11
12The camsys controller uses the common clk binding from
13Documentation/devicetree/bindings/clock/clock-bindings.txt
14The available clocks are defined in dt-bindings/clock/mt*-clk.h.
15
16Example:
17
18camsys: camsys@1a000000 {
19 compatible = "mediatek,mt8183-camsys", "syscon";
20 reg = <0 0x1a000000 0 0x1000>;
21 #clock-cells = <1>;
22};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
index 3f99672163e3..e3bc4a1e7a6e 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
@@ -11,6 +11,7 @@ Required Properties:
11 - "mediatek,mt6797-imgsys", "syscon" 11 - "mediatek,mt6797-imgsys", "syscon"
12 - "mediatek,mt7623-imgsys", "mediatek,mt2701-imgsys", "syscon" 12 - "mediatek,mt7623-imgsys", "mediatek,mt2701-imgsys", "syscon"
13 - "mediatek,mt8173-imgsys", "syscon" 13 - "mediatek,mt8173-imgsys", "syscon"
14 - "mediatek,mt8183-imgsys", "syscon"
14- #clock-cells: Must be 1 15- #clock-cells: Must be 1
15 16
16The imgsys controller uses the common clk binding from 17The imgsys controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
index 417bd83d1378..a90913988d7e 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
@@ -15,6 +15,8 @@ Required Properties:
15 - "mediatek,mt7629-infracfg", "syscon" 15 - "mediatek,mt7629-infracfg", "syscon"
16 - "mediatek,mt8135-infracfg", "syscon" 16 - "mediatek,mt8135-infracfg", "syscon"
17 - "mediatek,mt8173-infracfg", "syscon" 17 - "mediatek,mt8173-infracfg", "syscon"
18 - "mediatek,mt8183-infracfg", "syscon"
19 - "mediatek,mt8516-infracfg", "syscon"
18- #clock-cells: Must be 1 20- #clock-cells: Must be 1
19- #reset-cells: Must be 1 21- #reset-cells: Must be 1
20 22
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ipu.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ipu.txt
new file mode 100644
index 000000000000..aabc8c5c8ed2
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ipu.txt
@@ -0,0 +1,43 @@
1Mediatek IPU controller
2============================
3
4The Mediatek ipu controller provides various clocks to the system.
5
6Required Properties:
7
8- compatible: Should be one of:
9 - "mediatek,mt8183-ipu_conn", "syscon"
10 - "mediatek,mt8183-ipu_adl", "syscon"
11 - "mediatek,mt8183-ipu_core0", "syscon"
12 - "mediatek,mt8183-ipu_core1", "syscon"
13- #clock-cells: Must be 1
14
15The ipu controller uses the common clk binding from
16Documentation/devicetree/bindings/clock/clock-bindings.txt
17The available clocks are defined in dt-bindings/clock/mt*-clk.h.
18
19Example:
20
21ipu_conn: syscon@19000000 {
22 compatible = "mediatek,mt8183-ipu_conn", "syscon";
23 reg = <0 0x19000000 0 0x1000>;
24 #clock-cells = <1>;
25};
26
27ipu_adl: syscon@19010000 {
28 compatible = "mediatek,mt8183-ipu_adl", "syscon";
29 reg = <0 0x19010000 0 0x1000>;
30 #clock-cells = <1>;
31};
32
33ipu_core0: syscon@19180000 {
34 compatible = "mediatek,mt8183-ipu_core0", "syscon";
35 reg = <0 0x19180000 0 0x1000>;
36 #clock-cells = <1>;
37};
38
39ipu_core1: syscon@19280000 {
40 compatible = "mediatek,mt8183-ipu_core1", "syscon";
41 reg = <0 0x19280000 0 0x1000>;
42 #clock-cells = <1>;
43};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt
index b8fb03f3613e..2b882b7ca72e 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mcucfg.txt
@@ -7,6 +7,7 @@ Required Properties:
7 7
8- compatible: Should be one of: 8- compatible: Should be one of:
9 - "mediatek,mt2712-mcucfg", "syscon" 9 - "mediatek,mt2712-mcucfg", "syscon"
10 - "mediatek,mt8183-mcucfg", "syscon"
10- #clock-cells: Must be 1 11- #clock-cells: Must be 1
11 12
12The mcucfg controller uses the common clk binding from 13The mcucfg controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt
index 859e67b416d5..72787e7dd227 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt
@@ -7,6 +7,7 @@ Required Properties:
7 7
8- compatible: Should be one of: 8- compatible: Should be one of:
9 - "mediatek,mt2712-mfgcfg", "syscon" 9 - "mediatek,mt2712-mfgcfg", "syscon"
10 - "mediatek,mt8183-mfgcfg", "syscon"
10- #clock-cells: Must be 1 11- #clock-cells: Must be 1
11 12
12The mfgcfg controller uses the common clk binding from 13The mfgcfg controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
index 15d977afad31..545eab717c96 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
@@ -11,6 +11,7 @@ Required Properties:
11 - "mediatek,mt6797-mmsys", "syscon" 11 - "mediatek,mt6797-mmsys", "syscon"
12 - "mediatek,mt7623-mmsys", "mediatek,mt2701-mmsys", "syscon" 12 - "mediatek,mt7623-mmsys", "mediatek,mt2701-mmsys", "syscon"
13 - "mediatek,mt8173-mmsys", "syscon" 13 - "mediatek,mt8173-mmsys", "syscon"
14 - "mediatek,mt8183-mmsys", "syscon"
14- #clock-cells: Must be 1 15- #clock-cells: Must be 1
15 16
16The mmsys controller uses the common clk binding from 17The mmsys controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
index d160c2b4b6fe..a023b8338960 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
@@ -14,6 +14,8 @@ Required Properties:
14 - "mediatek,mt7629-topckgen" 14 - "mediatek,mt7629-topckgen"
15 - "mediatek,mt8135-topckgen" 15 - "mediatek,mt8135-topckgen"
16 - "mediatek,mt8173-topckgen" 16 - "mediatek,mt8173-topckgen"
17 - "mediatek,mt8183-topckgen", "syscon"
18 - "mediatek,mt8516-topckgen"
17- #clock-cells: Must be 1 19- #clock-cells: Must be 1
18 20
19The topckgen controller uses the common clk binding from 21The topckgen controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
index 3212afc753c8..57176bb8dbb5 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
@@ -11,6 +11,7 @@ Required Properties:
11 - "mediatek,mt6797-vdecsys", "syscon" 11 - "mediatek,mt6797-vdecsys", "syscon"
12 - "mediatek,mt7623-vdecsys", "mediatek,mt2701-vdecsys", "syscon" 12 - "mediatek,mt7623-vdecsys", "mediatek,mt2701-vdecsys", "syscon"
13 - "mediatek,mt8173-vdecsys", "syscon" 13 - "mediatek,mt8173-vdecsys", "syscon"
14 - "mediatek,mt8183-vdecsys", "syscon"
14- #clock-cells: Must be 1 15- #clock-cells: Must be 1
15 16
16The vdecsys controller uses the common clk binding from 17The vdecsys controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
index 851545357e94..c9faa6269087 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
@@ -9,6 +9,7 @@ Required Properties:
9 - "mediatek,mt2712-vencsys", "syscon" 9 - "mediatek,mt2712-vencsys", "syscon"
10 - "mediatek,mt6797-vencsys", "syscon" 10 - "mediatek,mt6797-vencsys", "syscon"
11 - "mediatek,mt8173-vencsys", "syscon" 11 - "mediatek,mt8173-vencsys", "syscon"
12 - "mediatek,mt8183-vencsys", "syscon"
12- #clock-cells: Must be 1 13- #clock-cells: Must be 1
13 14
14The vencsys controller uses the common clk binding from 15The vencsys controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt
index 61777ad24f61..0f777749f4f1 100644
--- a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt
+++ b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt
@@ -6,7 +6,8 @@ devices.
6 6
7Required Properties: 7Required Properties:
8 8
9- compatible : should be "amlogic,axg-audio-clkc" for the A113X and A113D 9- compatible : should be "amlogic,axg-audio-clkc" for the A113X and A113D,
10 "amlogic,g12a-audio-clkc" for G12A.
10- reg : physical base address of the clock controller and length of 11- reg : physical base address of the clock controller and length of
11 memory mapped region. 12 memory mapped region.
12- clocks : a list of phandle + clock-specifier pairs for the clocks listed 13- clocks : a list of phandle + clock-specifier pairs for the clocks listed
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt
index e9f70fcdfe80..b520280e33ff 100644
--- a/Documentation/devicetree/bindings/clock/at91-clock.txt
+++ b/Documentation/devicetree/bindings/clock/at91-clock.txt
@@ -8,35 +8,30 @@ Slow Clock controller:
8 8
9Required properties: 9Required properties:
10- compatible : shall be one of the following: 10- compatible : shall be one of the following:
11 "atmel,at91sam9x5-sckc" or 11 "atmel,at91sam9x5-sckc",
12 "atmel,sama5d3-sckc" or
12 "atmel,sama5d4-sckc": 13 "atmel,sama5d4-sckc":
13 at91 SCKC (Slow Clock Controller) 14 at91 SCKC (Slow Clock Controller)
14 This node contains the slow clock definitions. 15- #clock-cells : shall be 0.
15 16- clocks : shall be the input parent clock phandle for the clock.
16 "atmel,at91sam9x5-clk-slow-osc":
17 at91 slow oscillator
18
19 "atmel,at91sam9x5-clk-slow-rc-osc":
20 at91 internal slow RC oscillator
21- reg : defines the IO memory reserved for the SCKC.
22- #size-cells : shall be 0 (reg is used to encode clk id).
23- #address-cells : shall be 1 (reg is used to encode clk id).
24 17
18Optional properties:
19- atmel,osc-bypass : boolean property. Set this when a clock signal is directly
20 provided on XIN.
25 21
26For example: 22For example:
27 sckc: sckc@fffffe50 { 23 sckc@fffffe50 {
28 compatible = "atmel,sama5d3-pmc"; 24 compatible = "atmel,at91sam9x5-sckc";
29 reg = <0xfffffe50 0x4> 25 reg = <0xfffffe50 0x4>;
30 #size-cells = <0>; 26 clocks = <&slow_xtal>;
31 #address-cells = <1>; 27 #clock-cells = <0>;
32
33 /* put at91 slow clocks here */
34 }; 28 };
35 29
36Power Management Controller (PMC): 30Power Management Controller (PMC):
37 31
38Required properties: 32Required properties:
39- compatible : shall be "atmel,<chip>-pmc", "syscon": 33- compatible : shall be "atmel,<chip>-pmc", "syscon" or
34 "microchip,sam9x60-pmc"
40 <chip> can be: at91rm9200, at91sam9260, at91sam9261, 35 <chip> can be: at91rm9200, at91sam9260, at91sam9261,
41 at91sam9263, at91sam9g45, at91sam9n12, at91sam9rl, at91sam9g15, 36 at91sam9263, at91sam9g45, at91sam9n12, at91sam9rl, at91sam9g15,
42 at91sam9g25, at91sam9g35, at91sam9x25, at91sam9x35, at91sam9x5, 37 at91sam9g25, at91sam9g35, at91sam9x25, at91sam9x35, at91sam9x5,
diff --git a/Documentation/devicetree/bindings/clock/cirrus,lochnagar.txt b/Documentation/devicetree/bindings/clock/cirrus,lochnagar.txt
new file mode 100644
index 000000000000..b8d8ef3bdc5f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/cirrus,lochnagar.txt
@@ -0,0 +1,93 @@
1Cirrus Logic Lochnagar Audio Development Board
2
3Lochnagar is an evaluation and development board for Cirrus Logic
4Smart CODEC and Amp devices. It allows the connection of most Cirrus
5Logic devices on mini-cards, as well as allowing connection of
6various application processor systems to provide a full evaluation
7platform. Audio system topology, clocking and power can all be
8controlled through the Lochnagar, allowing the device under test
9to be used in a variety of possible use cases.
10
11This binding document describes the binding for the clock portion of
12the driver.
13
14Also see these documents for generic binding information:
15 [1] Clock : ../clock/clock-bindings.txt
16
17And these for relevant defines:
18 [2] include/dt-bindings/clock/lochnagar.h
19
20This binding must be part of the Lochnagar MFD binding:
21 [3] ../mfd/cirrus,lochnagar.txt
22
23Required properties:
24
25 - compatible : One of the following strings:
26 "cirrus,lochnagar1-clk"
27 "cirrus,lochnagar2-clk"
28
29 - #clock-cells : Must be 1. The first cell indicates the clock
30 number, see [2] for available clocks and [1].
31
32Optional properties:
33
34 - clocks : Must contain an entry for each clock in clock-names.
35 - clock-names : May contain entries for each of the following
36 clocks:
37 - ln-cdc-clkout : Output clock from CODEC card.
38 - ln-dsp-clkout : Output clock from DSP card.
39 - ln-gf-mclk1,ln-gf-mclk2,ln-gf-mclk3,ln-gf-mclk4 : Optional
40 input audio clocks from host system.
41 - ln-psia1-mclk, ln-psia2-mclk : Optional input audio clocks from
42 external connector.
43 - ln-spdif-clkout : Optional input audio clock from SPDIF.
44 - ln-adat-mclk : Optional input audio clock from ADAT.
45 - ln-pmic-32k : On board fixed clock.
46 - ln-clk-12m : On board fixed clock.
47 - ln-clk-11m : On board fixed clock.
48 - ln-clk-24m : On board fixed clock.
49 - ln-clk-22m : On board fixed clock.
50 - ln-clk-8m : On board fixed clock.
51 - ln-usb-clk-24m : On board fixed clock.
52 - ln-usb-clk-12m : On board fixed clock.
53
54 - assigned-clocks : A list of Lochnagar clocks to be reparented, see
55 [2] for available clocks.
56 - assigned-clock-parents : Parents to be assigned to the clocks
57 listed in "assigned-clocks".
58
59Optional nodes:
60
61 - fixed-clock nodes may be registered for the following on board clocks:
62 - ln-pmic-32k : 32768 Hz
63 - ln-clk-12m : 12288000 Hz
64 - ln-clk-11m : 11298600 Hz
65 - ln-clk-24m : 24576000 Hz
66 - ln-clk-22m : 22579200 Hz
67 - ln-clk-8m : 8192000 Hz
68 - ln-usb-clk-24m : 24576000 Hz
69 - ln-usb-clk-12m : 12288000 Hz
70
71Example:
72
73lochnagar {
74 lochnagar-clk {
75 compatible = "cirrus,lochnagar2-clk";
76
77 #clock-cells = <1>;
78
79 clocks = <&clk-audio>, <&clk_pmic>;
80 clock-names = "ln-gf-mclk2", "ln-pmic-32k";
81
82 assigned-clocks = <&lochnagar-clk LOCHNAGAR_CDC_MCLK1>,
83 <&lochnagar-clk LOCHNAGAR_CDC_MCLK2>;
84 assigned-clock-parents = <&clk-audio>,
85 <&clk-pmic>;
86 };
87
88 clk-pmic: clk-pmic {
89 compatible = "fixed-clock";
90 clock-cells = <0>;
91 clock-frequency = <32768>;
92 };
93};
diff --git a/Documentation/devicetree/bindings/clock/milbeaut-clock.yaml b/Documentation/devicetree/bindings/clock/milbeaut-clock.yaml
new file mode 100644
index 000000000000..5cf0b811821e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/milbeaut-clock.yaml
@@ -0,0 +1,73 @@
1# SPDX-License-Identifier: GPL-2.0
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/bindings/clock/milbeaut-clock.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Milbeaut SoCs Clock Controller Binding
8
9maintainers:
10 - Taichi Sugaya <sugaya.taichi@socionext.com>
11
12description: |
13 Milbeaut SoCs Clock controller is an integrated clock controller, which
14 generates and supplies to all modules.
15
16 This binding uses common clock bindings
17 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
18
19properties:
20 compatible:
21 oneOf:
22 - items:
23 - enum:
24 - socionext,milbeaut-m10v-ccu
25 clocks:
26 maxItems: 1
27 description: external clock
28
29 '#clock-cells':
30 const: 1
31
32required:
33 - compatible
34 - reg
35 - clocks
36 - '#clock-cells'
37
38examples:
39 # Clock controller node:
40 - |
41 m10v-clk-ctrl@1d021000 {
42 compatible = "socionext,milbeaut-m10v-clk-ccu";
43 reg = <0x1d021000 0x4000>;
44 #clock-cells = <1>;
45 clocks = <&clki40mhz>;
46 };
47
48 # Required an external clock for Clock controller node:
49 - |
50 clocks {
51 clki40mhz: clki40mhz {
52 compatible = "fixed-clock";
53 #clock-cells = <0>;
54 clock-frequency = <40000000>;
55 };
56 /* other clocks */
57 };
58
59 # The clock consumer shall specify the desired clock-output of the clock
60 # controller as below by specifying output-id in its "clk" phandle cell.
61 # 2: uart
62 # 4: 32-bit timer
63 # 7: UHS-I/II
64 - |
65 serial@1e700010 {
66 compatible = "socionext,milbeaut-usio-uart";
67 reg = <0x1e700010 0x10>;
68 interrupts = <0 141 0x4>, <0 149 0x4>;
69 interrupt-names = "rx", "tx";
70 clocks = <&clk 2>;
71 };
72
73...
diff --git a/Documentation/devicetree/bindings/clock/qcom,turingcc.txt b/Documentation/devicetree/bindings/clock/qcom,turingcc.txt
new file mode 100644
index 000000000000..126517de5f9a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,turingcc.txt
@@ -0,0 +1,19 @@
1Qualcomm Turing Clock & Reset Controller Binding
2------------------------------------------------
3
4Required properties :
5- compatible: shall contain "qcom,qcs404-turingcc".
6- reg: shall contain base register location and length.
7- clocks: ahb clock for the TuringCC
8- #clock-cells: from common clock binding, shall contain 1.
9- #reset-cells: from common reset binding, shall contain 1.
10
11Example:
12 turingcc: clock-controller@800000 {
13 compatible = "qcom,qcs404-turingcc";
14 reg = <0x00800000 0x30000>;
15 clocks = <&gcc GCC_CDSP_CFG_AHB_CLK>;
16
17 #clock-cells = <1>;
18 #reset-cells = <1>;
19 };
diff --git a/Documentation/devicetree/bindings/clock/qoriq-clock.txt b/Documentation/devicetree/bindings/clock/qoriq-clock.txt
index c655f28d5918..f7d48f23da44 100644
--- a/Documentation/devicetree/bindings/clock/qoriq-clock.txt
+++ b/Documentation/devicetree/bindings/clock/qoriq-clock.txt
@@ -39,6 +39,7 @@ Required properties:
39 * "fsl,b4860-clockgen" 39 * "fsl,b4860-clockgen"
40 * "fsl,ls1012a-clockgen" 40 * "fsl,ls1012a-clockgen"
41 * "fsl,ls1021a-clockgen" 41 * "fsl,ls1021a-clockgen"
42 * "fsl,ls1028a-clockgen"
42 * "fsl,ls1043a-clockgen" 43 * "fsl,ls1043a-clockgen"
43 * "fsl,ls1046a-clockgen" 44 * "fsl,ls1046a-clockgen"
44 * "fsl,ls1088a-clockgen" 45 * "fsl,ls1088a-clockgen"
@@ -83,8 +84,8 @@ second cell is the clock index for the specified type.
83 1 cmux index (n in CLKCnCSR) 84 1 cmux index (n in CLKCnCSR)
84 2 hwaccel index (n in CLKCGnHWACSR) 85 2 hwaccel index (n in CLKCGnHWACSR)
85 3 fman 0 for fm1, 1 for fm2 86 3 fman 0 for fm1, 1 for fm2
86 4 platform pll 0=pll, 1=pll/2, 2=pll/3, 3=pll/4 87 4 platform pll n=pll/(n+1). For example, when n=1,
87 4=pll/5, 5=pll/6, 6=pll/7, 7=pll/8 88 that means output_freq=PLL_freq/2.
88 5 coreclk must be 0 89 5 coreclk must be 0
89 90
903. Example 913. Example
diff --git a/Documentation/devicetree/bindings/clock/sifive/fu540-prci.txt b/Documentation/devicetree/bindings/clock/sifive/fu540-prci.txt
new file mode 100644
index 000000000000..349808f4fb8c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sifive/fu540-prci.txt
@@ -0,0 +1,46 @@
1SiFive FU540 PRCI bindings
2
3On the FU540 family of SoCs, most system-wide clock and reset integration
4is via the PRCI IP block.
5
6Required properties:
7- compatible: Should be "sifive,<chip>-prci". Only one value is
8 supported: "sifive,fu540-c000-prci"
9- reg: Should describe the PRCI's register target physical address region
10- clocks: Should point to the hfclk device tree node and the rtcclk
11 device tree node. The RTC clock here is not a time-of-day clock,
12 but is instead a high-stability clock source for system timers
13 and cycle counters.
14- #clock-cells: Should be <1>
15
16The clock consumer should specify the desired clock via the clock ID
17macros defined in include/dt-bindings/clock/sifive-fu540-prci.h.
18These macros begin with PRCI_CLK_.
19
20The hfclk and rtcclk nodes are required, and represent physical
21crystals or resonators located on the PCB. These nodes should be present
22underneath /, rather than /soc.
23
24Examples:
25
26/* under /, in PCB-specific DT data */
27hfclk: hfclk {
28 #clock-cells = <0>;
29 compatible = "fixed-clock";
30 clock-frequency = <33333333>;
31 clock-output-names = "hfclk";
32};
33rtcclk: rtcclk {
34 #clock-cells = <0>;
35 compatible = "fixed-clock";
36 clock-frequency = <1000000>;
37 clock-output-names = "rtcclk";
38};
39
40/* under /soc, in SoC-specific DT data */
41prci: clock-controller@10000000 {
42 compatible = "sifive,fu540-c000-prci";
43 reg = <0x0 0x10000000 0x0 0x1000>;
44 clocks = <&hfclk>, <&rtcclk>;
45 #clock-cells = <1>;
46};
diff --git a/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt b/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt
index b240121d2ac9..cfa04b614d8a 100644
--- a/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt
+++ b/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt
@@ -11,6 +11,8 @@ Required properties:
11 "st,stm32f42xx-rcc" 11 "st,stm32f42xx-rcc"
12 "st,stm32f469-rcc" 12 "st,stm32f469-rcc"
13 "st,stm32f746-rcc" 13 "st,stm32f746-rcc"
14 "st,stm32f769-rcc"
15
14- reg: should be register base and length as documented in the 16- reg: should be register base and length as documented in the
15 datasheet 17 datasheet
16- #reset-cells: 1, see below 18- #reset-cells: 1, see below
@@ -102,6 +104,10 @@ The secondary index is bound with the following magic numbers:
102 28 CLK_I2C3 104 28 CLK_I2C3
103 29 CLK_I2C4 105 29 CLK_I2C4
104 30 CLK_LPTIMER (LPTimer1 clock) 106 30 CLK_LPTIMER (LPTimer1 clock)
107 31 CLK_PLL_SRC
108 32 CLK_DFSDM1
109 33 CLK_ADFSDM1
110 34 CLK_F769_DSI
105) 111)
106 112
107Example: 113Example:
diff --git a/MAINTAINERS b/MAINTAINERS
index a3143515e134..960070e36bd9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -979,6 +979,12 @@ F: drivers/iio/adc/ltc2497*
979X: drivers/iio/*/adjd* 979X: drivers/iio/*/adjd*
980F: drivers/staging/iio/*/ad* 980F: drivers/staging/iio/*/ad*
981 981
982ANALOGBITS PLL LIBRARIES
983M: Paul Walmsley <paul.walmsley@sifive.com>
984S: Supported
985F: drivers/clk/analogbits/*
986F: include/linux/clk/analogbits*
987
982ANDES ARCHITECTURE 988ANDES ARCHITECTURE
983M: Greentime Hu <green.hu@gmail.com> 989M: Greentime Hu <green.hu@gmail.com>
984M: Vincent Chen <deanbo422@gmail.com> 990M: Vincent Chen <deanbo422@gmail.com>
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 42881f21cede..3e0f09cc0028 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -119,6 +119,9 @@ void __init ti_clk_init_features(void)
119 if (cpu_is_omap343x()) 119 if (cpu_is_omap343x())
120 features.flags |= TI_CLK_DPLL_HAS_FREQSEL; 120 features.flags |= TI_CLK_DPLL_HAS_FREQSEL;
121 121
122 if (omap_type() == OMAP2_DEVICE_TYPE_GP)
123 features.flags |= TI_CLK_DEVICE_TYPE_GP;
124
122 /* Idlest value for interface clocks. 125 /* Idlest value for interface clocks.
123 * 24xx uses 0 to indicate not ready, and 1 to indicate ready. 126 * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
124 * 34xx reverses this, just to keep us on our toes 127 * 34xx reverses this, just to keep us on our toes
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 3a04c73ac03c..baadddf9aad4 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -648,10 +648,10 @@ static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
648 if (oh->clkdm) { 648 if (oh->clkdm) {
649 return oh->clkdm; 649 return oh->clkdm;
650 } else if (oh->_clk) { 650 } else if (oh->_clk) {
651 if (__clk_get_flags(oh->_clk) & CLK_IS_BASIC) 651 if (!omap2_clk_is_hw_omap(__clk_get_hw(oh->_clk)))
652 return NULL; 652 return NULL;
653 clk = to_clk_hw_omap(__clk_get_hw(oh->_clk)); 653 clk = to_clk_hw_omap(__clk_get_hw(oh->_clk));
654 return clk->clkdm; 654 return clk->clkdm;
655 } 655 }
656 return NULL; 656 return NULL;
657} 657}
diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c
index d129475fd40d..a95a894aceaf 100644
--- a/arch/mips/alchemy/common/clock.c
+++ b/arch/mips/alchemy/common/clock.c
@@ -160,7 +160,7 @@ static struct clk __init *alchemy_clk_setup_cpu(const char *parent_name,
160 id.name = ALCHEMY_CPU_CLK; 160 id.name = ALCHEMY_CPU_CLK;
161 id.parent_names = &parent_name; 161 id.parent_names = &parent_name;
162 id.num_parents = 1; 162 id.num_parents = 1;
163 id.flags = CLK_IS_BASIC; 163 id.flags = 0;
164 id.ops = &alchemy_clkops_cpu; 164 id.ops = &alchemy_clkops_cpu;
165 h->init = &id; 165 h->init = &id;
166 166
diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c
index b3097fe6441b..af265ae40a61 100644
--- a/arch/powerpc/platforms/512x/clock-commonclk.c
+++ b/arch/powerpc/platforms/512x/clock-commonclk.c
@@ -239,6 +239,7 @@ static inline struct clk *mpc512x_clk_divider(
239 const char *name, const char *parent_name, u8 clkflags, 239 const char *name, const char *parent_name, u8 clkflags,
240 u32 __iomem *reg, u8 pos, u8 len, int divflags) 240 u32 __iomem *reg, u8 pos, u8 len, int divflags)
241{ 241{
242 divflags |= CLK_DIVIDER_BIG_ENDIAN;
242 return clk_register_divider(NULL, name, parent_name, clkflags, 243 return clk_register_divider(NULL, name, parent_name, clkflags,
243 reg, pos, len, divflags, &clklock); 244 reg, pos, len, divflags, &clklock);
244} 245}
@@ -250,7 +251,7 @@ static inline struct clk *mpc512x_clk_divtable(
250{ 251{
251 u8 divflags; 252 u8 divflags;
252 253
253 divflags = 0; 254 divflags = CLK_DIVIDER_BIG_ENDIAN;
254 return clk_register_divider_table(NULL, name, parent_name, 0, 255 return clk_register_divider_table(NULL, name, parent_name, 0,
255 reg, pos, len, divflags, 256 reg, pos, len, divflags,
256 divtab, &clklock); 257 divtab, &clklock);
@@ -261,10 +262,12 @@ static inline struct clk *mpc512x_clk_gated(
261 u32 __iomem *reg, u8 pos) 262 u32 __iomem *reg, u8 pos)
262{ 263{
263 int clkflags; 264 int clkflags;
265 u8 gateflags;
264 266
265 clkflags = CLK_SET_RATE_PARENT; 267 clkflags = CLK_SET_RATE_PARENT;
268 gateflags = CLK_GATE_BIG_ENDIAN;
266 return clk_register_gate(NULL, name, parent_name, clkflags, 269 return clk_register_gate(NULL, name, parent_name, clkflags,
267 reg, pos, 0, &clklock); 270 reg, pos, gateflags, &clklock);
268} 271}
269 272
270static inline struct clk *mpc512x_clk_muxed(const char *name, 273static inline struct clk *mpc512x_clk_muxed(const char *name,
@@ -275,7 +278,7 @@ static inline struct clk *mpc512x_clk_muxed(const char *name,
275 u8 muxflags; 278 u8 muxflags;
276 279
277 clkflags = CLK_SET_RATE_PARENT; 280 clkflags = CLK_SET_RATE_PARENT;
278 muxflags = 0; 281 muxflags = CLK_MUX_BIG_ENDIAN;
279 return clk_register_mux(NULL, name, 282 return clk_register_mux(NULL, name,
280 parent_names, parent_count, clkflags, 283 parent_names, parent_count, clkflags,
281 reg, pos, len, muxflags, &clklock); 284 reg, pos, len, muxflags, &clklock);
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index e705aab9e38b..fc1e0cf44995 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -1,3 +1,4 @@
1# SPDX-License-Identifier: GPL-2.0
1 2
2config CLKDEV_LOOKUP 3config CLKDEV_LOOKUP
3 bool 4 bool
@@ -219,6 +220,13 @@ config COMMON_CLK_XGENE
219 ---help--- 220 ---help---
220 Sypport for the APM X-Gene SoC reference, PLL, and device clocks. 221 Sypport for the APM X-Gene SoC reference, PLL, and device clocks.
221 222
223config COMMON_CLK_LOCHNAGAR
224 tristate "Cirrus Logic Lochnagar clock driver"
225 depends on MFD_LOCHNAGAR
226 help
227 This driver supports the clocking features of the Cirrus Logic
228 Lochnagar audio development board.
229
222config COMMON_CLK_NXP 230config COMMON_CLK_NXP
223 def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX) 231 def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX)
224 select REGMAP_MMIO if ARCH_LPC32XX 232 select REGMAP_MMIO if ARCH_LPC32XX
@@ -297,6 +305,7 @@ config COMMON_CLK_FIXED_MMIO
297 Support for Memory Mapped IO Fixed clocks 305 Support for Memory Mapped IO Fixed clocks
298 306
299source "drivers/clk/actions/Kconfig" 307source "drivers/clk/actions/Kconfig"
308source "drivers/clk/analogbits/Kconfig"
300source "drivers/clk/bcm/Kconfig" 309source "drivers/clk/bcm/Kconfig"
301source "drivers/clk/hisilicon/Kconfig" 310source "drivers/clk/hisilicon/Kconfig"
302source "drivers/clk/imgtec/Kconfig" 311source "drivers/clk/imgtec/Kconfig"
@@ -309,7 +318,9 @@ source "drivers/clk/mvebu/Kconfig"
309source "drivers/clk/qcom/Kconfig" 318source "drivers/clk/qcom/Kconfig"
310source "drivers/clk/renesas/Kconfig" 319source "drivers/clk/renesas/Kconfig"
311source "drivers/clk/samsung/Kconfig" 320source "drivers/clk/samsung/Kconfig"
321source "drivers/clk/sifive/Kconfig"
312source "drivers/clk/sprd/Kconfig" 322source "drivers/clk/sprd/Kconfig"
323source "drivers/clk/sunxi/Kconfig"
313source "drivers/clk/sunxi-ng/Kconfig" 324source "drivers/clk/sunxi-ng/Kconfig"
314source "drivers/clk/tegra/Kconfig" 325source "drivers/clk/tegra/Kconfig"
315source "drivers/clk/ti/Kconfig" 326source "drivers/clk/ti/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 1db133652f0c..9ef4305d55e0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -32,8 +32,10 @@ obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o
32obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o 32obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o
33obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 33obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
34obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o 34obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o
35obj-$(CONFIG_COMMON_CLK_LOCHNAGAR) += clk-lochnagar.o
35obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o 36obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
36obj-$(CONFIG_COMMON_CLK_MAX9485) += clk-max9485.o 37obj-$(CONFIG_COMMON_CLK_MAX9485) += clk-max9485.o
38obj-$(CONFIG_ARCH_MILBEAUT_M10V) += clk-milbeaut.o
37obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o 39obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
38obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 40obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
39obj-$(CONFIG_ARCH_NPCM7XX) += clk-npcm7xx.o 41obj-$(CONFIG_ARCH_NPCM7XX) += clk-npcm7xx.o
@@ -64,6 +66,7 @@ obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
64 66
65# please keep this section sorted lexicographically by directory path name 67# please keep this section sorted lexicographically by directory path name
66obj-y += actions/ 68obj-y += actions/
69obj-y += analogbits/
67obj-$(CONFIG_COMMON_CLK_AT91) += at91/ 70obj-$(CONFIG_COMMON_CLK_AT91) += at91/
68obj-$(CONFIG_ARCH_ARTPEC) += axis/ 71obj-$(CONFIG_ARCH_ARTPEC) += axis/
69obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/ 72obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
@@ -93,6 +96,7 @@ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
93obj-y += renesas/ 96obj-y += renesas/
94obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ 97obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
95obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ 98obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
99obj-$(CONFIG_CLK_SIFIVE) += sifive/
96obj-$(CONFIG_ARCH_SIRF) += sirf/ 100obj-$(CONFIG_ARCH_SIRF) += sirf/
97obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ 101obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
98obj-$(CONFIG_PLAT_SPEAR) += spear/ 102obj-$(CONFIG_PLAT_SPEAR) += spear/
diff --git a/drivers/clk/actions/owl-common.h b/drivers/clk/actions/owl-common.h
index 5a866a8b913d..c000a431471e 100644
--- a/drivers/clk/actions/owl-common.h
+++ b/drivers/clk/actions/owl-common.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1/* SPDX-License-Identifier: GPL-2.0+ */
2// 2//
3// OWL common clock driver 3// OWL common clock driver
4// 4//
diff --git a/drivers/clk/actions/owl-composite.h b/drivers/clk/actions/owl-composite.h
index b410ed5bf308..bca38bf8f218 100644
--- a/drivers/clk/actions/owl-composite.h
+++ b/drivers/clk/actions/owl-composite.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1/* SPDX-License-Identifier: GPL-2.0+ */
2// 2//
3// OWL composite clock driver 3// OWL composite clock driver
4// 4//
diff --git a/drivers/clk/actions/owl-divider.h b/drivers/clk/actions/owl-divider.h
index 92d3e3d23967..083be6d80954 100644
--- a/drivers/clk/actions/owl-divider.h
+++ b/drivers/clk/actions/owl-divider.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1/* SPDX-License-Identifier: GPL-2.0+ */
2// 2//
3// OWL divider clock driver 3// OWL divider clock driver
4// 4//
diff --git a/drivers/clk/actions/owl-factor.h b/drivers/clk/actions/owl-factor.h
index f1a7ffe896e1..04b89cbfdccb 100644
--- a/drivers/clk/actions/owl-factor.h
+++ b/drivers/clk/actions/owl-factor.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1/* SPDX-License-Identifier: GPL-2.0+ */
2// 2//
3// OWL factor clock driver 3// OWL factor clock driver
4// 4//
diff --git a/drivers/clk/actions/owl-fixed-factor.h b/drivers/clk/actions/owl-fixed-factor.h
index cc9fe36c0964..3dfd7fd7d292 100644
--- a/drivers/clk/actions/owl-fixed-factor.h
+++ b/drivers/clk/actions/owl-fixed-factor.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1/* SPDX-License-Identifier: GPL-2.0+ */
2// 2//
3// OWL fixed factor clock driver 3// OWL fixed factor clock driver
4// 4//
diff --git a/drivers/clk/actions/owl-gate.h b/drivers/clk/actions/owl-gate.h
index c2d61ceebce2..c2f161c93fda 100644
--- a/drivers/clk/actions/owl-gate.h
+++ b/drivers/clk/actions/owl-gate.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1/* SPDX-License-Identifier: GPL-2.0+ */
2// 2//
3// OWL gate clock driver 3// OWL gate clock driver
4// 4//
diff --git a/drivers/clk/actions/owl-mux.h b/drivers/clk/actions/owl-mux.h
index 834284c8c3ae..53b9ab665294 100644
--- a/drivers/clk/actions/owl-mux.h
+++ b/drivers/clk/actions/owl-mux.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1/* SPDX-License-Identifier: GPL-2.0+ */
2// 2//
3// OWL mux clock driver 3// OWL mux clock driver
4// 4//
diff --git a/drivers/clk/actions/owl-pll.h b/drivers/clk/actions/owl-pll.h
index 6fb0d45bb088..78e5fc360b03 100644
--- a/drivers/clk/actions/owl-pll.h
+++ b/drivers/clk/actions/owl-pll.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1/* SPDX-License-Identifier: GPL-2.0+ */
2// 2//
3// OWL pll clock driver 3// OWL pll clock driver
4// 4//
diff --git a/drivers/clk/actions/owl-reset.h b/drivers/clk/actions/owl-reset.h
index 10f5774979a6..a947ffcb5a02 100644
--- a/drivers/clk/actions/owl-reset.h
+++ b/drivers/clk/actions/owl-reset.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0-or-later 1/* SPDX-License-Identifier: GPL-2.0-or-later */
2// 2//
3// Actions Semi Owl SoCs Reset Management Unit driver 3// Actions Semi Owl SoCs Reset Management Unit driver
4// 4//
diff --git a/drivers/clk/analogbits/Kconfig b/drivers/clk/analogbits/Kconfig
new file mode 100644
index 000000000000..b5fd60c7f136
--- /dev/null
+++ b/drivers/clk/analogbits/Kconfig
@@ -0,0 +1,2 @@
1config CLK_ANALOGBITS_WRPLL_CLN28HPC
2 bool
diff --git a/drivers/clk/analogbits/Makefile b/drivers/clk/analogbits/Makefile
new file mode 100644
index 000000000000..bf017447451e
--- /dev/null
+++ b/drivers/clk/analogbits/Makefile
@@ -0,0 +1,3 @@
1# SPDX-License-Identifier: GPL-2.0
2
3obj-$(CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC) += wrpll-cln28hpc.o
diff --git a/drivers/clk/analogbits/wrpll-cln28hpc.c b/drivers/clk/analogbits/wrpll-cln28hpc.c
new file mode 100644
index 000000000000..776ead319ae9
--- /dev/null
+++ b/drivers/clk/analogbits/wrpll-cln28hpc.c
@@ -0,0 +1,364 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2018-2019 SiFive, Inc.
4 * Wesley Terpstra
5 * Paul Walmsley
6 *
7 * This library supports configuration parsing and reprogramming of
8 * the CLN28HPC variant of the Analog Bits Wide Range PLL. The
9 * intention is for this library to be reusable for any device that
10 * integrates this PLL; thus the register structure and programming
11 * details are expected to be provided by a separate IP block driver.
12 *
13 * The bulk of this code is primarily useful for clock configurations
14 * that must operate at arbitrary rates, as opposed to clock configurations
15 * that are restricted by software or manufacturer guidance to a small,
16 * pre-determined set of performance points.
17 *
18 * References:
19 * - Analog Bits "Wide Range PLL Datasheet", version 2015.10.01
20 * - SiFive FU540-C000 Manual v1p0, Chapter 7 "Clocking and Reset"
21 * https://static.dev.sifive.com/FU540-C000-v1.0.pdf
22 */
23
24#include <linux/bug.h>
25#include <linux/err.h>
26#include <linux/log2.h>
27#include <linux/math64.h>
28#include <linux/clk/analogbits-wrpll-cln28hpc.h>
29
30/* MIN_INPUT_FREQ: minimum input clock frequency, in Hz (Fref_min) */
31#define MIN_INPUT_FREQ 7000000
32
33/* MAX_INPUT_FREQ: maximum input clock frequency, in Hz (Fref_max) */
34#define MAX_INPUT_FREQ 600000000
35
36/* MIN_POST_DIVIDE_REF_FREQ: minimum post-divider reference frequency, in Hz */
37#define MIN_POST_DIVR_FREQ 7000000
38
39/* MAX_POST_DIVIDE_REF_FREQ: maximum post-divider reference frequency, in Hz */
40#define MAX_POST_DIVR_FREQ 200000000
41
42/* MIN_VCO_FREQ: minimum VCO frequency, in Hz (Fvco_min) */
43#define MIN_VCO_FREQ 2400000000UL
44
45/* MAX_VCO_FREQ: maximum VCO frequency, in Hz (Fvco_max) */
46#define MAX_VCO_FREQ 4800000000ULL
47
48/* MAX_DIVQ_DIVISOR: maximum output divisor. Selected by DIVQ = 6 */
49#define MAX_DIVQ_DIVISOR 64
50
51/* MAX_DIVR_DIVISOR: maximum reference divisor. Selected by DIVR = 63 */
52#define MAX_DIVR_DIVISOR 64
53
54/* MAX_LOCK_US: maximum PLL lock time, in microseconds (tLOCK_max) */
55#define MAX_LOCK_US 70
56
57/*
58 * ROUND_SHIFT: number of bits to shift to avoid precision loss in the rounding
59 * algorithm
60 */
61#define ROUND_SHIFT 20
62
63/*
64 * Private functions
65 */
66
67/**
68 * __wrpll_calc_filter_range() - determine PLL loop filter bandwidth
69 * @post_divr_freq: input clock rate after the R divider
70 *
71 * Select the value to be presented to the PLL RANGE input signals, based
72 * on the input clock frequency after the post-R-divider @post_divr_freq.
73 * This code follows the recommendations in the PLL datasheet for filter
74 * range selection.
75 *
76 * Return: The RANGE value to be presented to the PLL configuration inputs,
77 * or a negative return code upon error.
78 */
79static int __wrpll_calc_filter_range(unsigned long post_divr_freq)
80{
81 if (post_divr_freq < MIN_POST_DIVR_FREQ ||
82 post_divr_freq > MAX_POST_DIVR_FREQ) {
83 WARN(1, "%s: post-divider reference freq out of range: %lu",
84 __func__, post_divr_freq);
85 return -ERANGE;
86 }
87
88 switch (post_divr_freq) {
89 case 0 ... 10999999:
90 return 1;
91 case 11000000 ... 17999999:
92 return 2;
93 case 18000000 ... 29999999:
94 return 3;
95 case 30000000 ... 49999999:
96 return 4;
97 case 50000000 ... 79999999:
98 return 5;
99 case 80000000 ... 129999999:
100 return 6;
101 }
102
103 return 7;
104}
105
106/**
107 * __wrpll_calc_fbdiv() - return feedback fixed divide value
108 * @c: ptr to a struct wrpll_cfg record to read from
109 *
110 * The internal feedback path includes a fixed by-two divider; the
111 * external feedback path does not. Return the appropriate divider
112 * value (2 or 1) depending on whether internal or external feedback
113 * is enabled. This code doesn't test for invalid configurations
114 * (e.g. both or neither of WRPLL_FLAGS_*_FEEDBACK are set); it relies
115 * on the caller to do so.
116 *
117 * Context: Any context. Caller must protect the memory pointed to by
118 * @c from simultaneous modification.
119 *
120 * Return: 2 if internal feedback is enabled or 1 if external feedback
121 * is enabled.
122 */
123static u8 __wrpll_calc_fbdiv(const struct wrpll_cfg *c)
124{
125 return (c->flags & WRPLL_FLAGS_INT_FEEDBACK_MASK) ? 2 : 1;
126}
127
128/**
129 * __wrpll_calc_divq() - determine DIVQ based on target PLL output clock rate
130 * @target_rate: target PLL output clock rate
131 * @vco_rate: pointer to a u64 to store the computed VCO rate into
132 *
133 * Determine a reasonable value for the PLL Q post-divider, based on the
134 * target output rate @target_rate for the PLL. Along with returning the
135 * computed Q divider value as the return value, this function stores the
136 * desired target VCO rate into the variable pointed to by @vco_rate.
137 *
138 * Context: Any context. Caller must protect the memory pointed to by
139 * @vco_rate from simultaneous access or modification.
140 *
141 * Return: a positive integer DIVQ value to be programmed into the hardware
142 * upon success, or 0 upon error (since 0 is an invalid DIVQ value)
143 */
144static u8 __wrpll_calc_divq(u32 target_rate, u64 *vco_rate)
145{
146 u64 s;
147 u8 divq = 0;
148
149 if (!vco_rate) {
150 WARN_ON(1);
151 goto wcd_out;
152 }
153
154 s = div_u64(MAX_VCO_FREQ, target_rate);
155 if (s <= 1) {
156 divq = 1;
157 *vco_rate = MAX_VCO_FREQ;
158 } else if (s > MAX_DIVQ_DIVISOR) {
159 divq = ilog2(MAX_DIVQ_DIVISOR);
160 *vco_rate = MIN_VCO_FREQ;
161 } else {
162 divq = ilog2(s);
163 *vco_rate = (u64)target_rate << divq;
164 }
165
166wcd_out:
167 return divq;
168}
169
170/**
171 * __wrpll_update_parent_rate() - update PLL data when parent rate changes
172 * @c: ptr to a struct wrpll_cfg record to write PLL data to
173 * @parent_rate: PLL input refclk rate (pre-R-divider)
174 *
175 * Pre-compute some data used by the PLL configuration algorithm when
176 * the PLL's reference clock rate changes. The intention is to avoid
177 * computation when the parent rate remains constant - expected to be
178 * the common case.
179 *
180 * Returns: 0 upon success or -ERANGE if the reference clock rate is
181 * out of range.
182 */
183static int __wrpll_update_parent_rate(struct wrpll_cfg *c,
184 unsigned long parent_rate)
185{
186 u8 max_r_for_parent;
187
188 if (parent_rate > MAX_INPUT_FREQ || parent_rate < MIN_POST_DIVR_FREQ)
189 return -ERANGE;
190
191 c->parent_rate = parent_rate;
192 max_r_for_parent = div_u64(parent_rate, MIN_POST_DIVR_FREQ);
193 c->max_r = min_t(u8, MAX_DIVR_DIVISOR, max_r_for_parent);
194
195 c->init_r = DIV_ROUND_UP_ULL(parent_rate, MAX_POST_DIVR_FREQ);
196
197 return 0;
198}
199
200/**
201 * wrpll_configure() - compute PLL configuration for a target rate
202 * @c: ptr to a struct wrpll_cfg record to write into
203 * @target_rate: target PLL output clock rate (post-Q-divider)
204 * @parent_rate: PLL input refclk rate (pre-R-divider)
205 *
206 * Compute the appropriate PLL signal configuration values and store
207 * in PLL context @c. PLL reprogramming is not glitchless, so the
208 * caller should switch any downstream logic to a different clock
209 * source or clock-gate it before presenting these values to the PLL
210 * configuration signals.
211 *
212 * The caller must pass this function a pre-initialized struct
213 * wrpll_cfg record: either initialized to zero (with the
214 * exception of the .name and .flags fields) or read from the PLL.
215 *
216 * Context: Any context. Caller must protect the memory pointed to by @c
217 * from simultaneous access or modification.
218 *
219 * Return: 0 upon success; anything else upon failure.
220 */
221int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate,
222 unsigned long parent_rate)
223{
224 unsigned long ratio;
225 u64 target_vco_rate, delta, best_delta, f_pre_div, vco, vco_pre;
226 u32 best_f, f, post_divr_freq;
227 u8 fbdiv, divq, best_r, r;
228 int range;
229
230 if (c->flags == 0) {
231 WARN(1, "%s called with uninitialized PLL config", __func__);
232 return -EINVAL;
233 }
234
235 /* Initialize rounding data if it hasn't been initialized already */
236 if (parent_rate != c->parent_rate) {
237 if (__wrpll_update_parent_rate(c, parent_rate)) {
238 pr_err("%s: PLL input rate is out of range\n",
239 __func__);
240 return -ERANGE;
241 }
242 }
243
244 c->flags &= ~WRPLL_FLAGS_RESET_MASK;
245
246 /* Put the PLL into bypass if the user requests the parent clock rate */
247 if (target_rate == parent_rate) {
248 c->flags |= WRPLL_FLAGS_BYPASS_MASK;
249 return 0;
250 }
251
252 c->flags &= ~WRPLL_FLAGS_BYPASS_MASK;
253
254 /* Calculate the Q shift and target VCO rate */
255 divq = __wrpll_calc_divq(target_rate, &target_vco_rate);
256 if (!divq)
257 return -1;
258 c->divq = divq;
259
260 /* Precalculate the pre-Q divider target ratio */
261 ratio = div64_u64((target_vco_rate << ROUND_SHIFT), parent_rate);
262
263 fbdiv = __wrpll_calc_fbdiv(c);
264 best_r = 0;
265 best_f = 0;
266 best_delta = MAX_VCO_FREQ;
267
268 /*
269 * Consider all values for R which land within
270 * [MIN_POST_DIVR_FREQ, MAX_POST_DIVR_FREQ]; prefer smaller R
271 */
272 for (r = c->init_r; r <= c->max_r; ++r) {
273 f_pre_div = ratio * r;
274 f = (f_pre_div + (1 << ROUND_SHIFT)) >> ROUND_SHIFT;
275 f >>= (fbdiv - 1);
276
277 post_divr_freq = div_u64(parent_rate, r);
278 vco_pre = fbdiv * post_divr_freq;
279 vco = vco_pre * f;
280
281 /* Ensure rounding didn't take us out of range */
282 if (vco > target_vco_rate) {
283 --f;
284 vco = vco_pre * f;
285 } else if (vco < MIN_VCO_FREQ) {
286 ++f;
287 vco = vco_pre * f;
288 }
289
290 delta = abs(target_rate - vco);
291 if (delta < best_delta) {
292 best_delta = delta;
293 best_r = r;
294 best_f = f;
295 }
296 }
297
298 c->divr = best_r - 1;
299 c->divf = best_f - 1;
300
301 post_divr_freq = div_u64(parent_rate, best_r);
302
303 /* Pick the best PLL jitter filter */
304 range = __wrpll_calc_filter_range(post_divr_freq);
305 if (range < 0)
306 return range;
307 c->range = range;
308
309 return 0;
310}
311
312/**
313 * wrpll_calc_output_rate() - calculate the PLL's target output rate
314 * @c: ptr to a struct wrpll_cfg record to read from
315 * @parent_rate: PLL refclk rate
316 *
317 * Given a pointer to the PLL's current input configuration @c and the
318 * PLL's input reference clock rate @parent_rate (before the R
319 * pre-divider), calculate the PLL's output clock rate (after the Q
320 * post-divider).
321 *
322 * Context: Any context. Caller must protect the memory pointed to by @c
323 * from simultaneous modification.
324 *
325 * Return: the PLL's output clock rate, in Hz. The return value from
326 * this function is intended to be convenient to pass directly
327 * to the Linux clock framework; thus there is no explicit
328 * error return value.
329 */
330unsigned long wrpll_calc_output_rate(const struct wrpll_cfg *c,
331 unsigned long parent_rate)
332{
333 u8 fbdiv;
334 u64 n;
335
336 if (c->flags & WRPLL_FLAGS_EXT_FEEDBACK_MASK) {
337 WARN(1, "external feedback mode not yet supported");
338 return ULONG_MAX;
339 }
340
341 fbdiv = __wrpll_calc_fbdiv(c);
342 n = parent_rate * fbdiv * (c->divf + 1);
343 n = div_u64(n, c->divr + 1);
344 n >>= c->divq;
345
346 return n;
347}
348
349/**
350 * wrpll_calc_max_lock_us() - return the time for the PLL to lock
351 * @c: ptr to a struct wrpll_cfg record to read from
352 *
353 * Return the minimum amount of time (in microseconds) that the caller
354 * must wait after reprogramming the PLL to ensure that it is locked
355 * to the input frequency and stable. This is likely to depend on the DIVR
356 * value; this is under discussion with the manufacturer.
357 *
358 * Return: the minimum amount of time the caller must wait for the PLL
359 * to lock (in microseconds)
360 */
361unsigned int wrpll_calc_max_lock_us(const struct wrpll_cfg *c)
362{
363 return MAX_LOCK_US;
364}
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index c75df1cad60e..3732241352ce 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -14,6 +14,8 @@ obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o
14obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o 14obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o
15obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o 15obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o
16obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK) += clk-i2s-mux.o 16obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK) += clk-i2s-mux.o
17obj-$(CONFIG_HAVE_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
17obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o 18obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o
19obj-$(CONFIG_SOC_SAM9X60) += sam9x60.o
18obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o 20obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
19obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o 21obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o
diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c
index b1af5a395423..0aabe49aed09 100644
--- a/drivers/clk/at91/at91sam9260.c
+++ b/drivers/clk/at91/at91sam9260.c
@@ -41,7 +41,7 @@ static u8 sam9260_plla_out[] = { 0, 2 };
41 41
42static u16 sam9260_plla_icpll[] = { 1, 1 }; 42static u16 sam9260_plla_icpll[] = { 1, 1 };
43 43
44static struct clk_range sam9260_plla_outputs[] = { 44static const struct clk_range sam9260_plla_outputs[] = {
45 { .min = 80000000, .max = 160000000 }, 45 { .min = 80000000, .max = 160000000 },
46 { .min = 150000000, .max = 240000000 }, 46 { .min = 150000000, .max = 240000000 },
47}; 47};
@@ -58,7 +58,7 @@ static u8 sam9260_pllb_out[] = { 1 };
58 58
59static u16 sam9260_pllb_icpll[] = { 1 }; 59static u16 sam9260_pllb_icpll[] = { 1 };
60 60
61static struct clk_range sam9260_pllb_outputs[] = { 61static const struct clk_range sam9260_pllb_outputs[] = {
62 { .min = 70000000, .max = 130000000 }, 62 { .min = 70000000, .max = 130000000 },
63}; 63};
64 64
@@ -128,7 +128,7 @@ static u8 sam9g20_plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
128 128
129static u16 sam9g20_plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 }; 129static u16 sam9g20_plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
130 130
131static struct clk_range sam9g20_plla_outputs[] = { 131static const struct clk_range sam9g20_plla_outputs[] = {
132 { .min = 745000000, .max = 800000000 }, 132 { .min = 745000000, .max = 800000000 },
133 { .min = 695000000, .max = 750000000 }, 133 { .min = 695000000, .max = 750000000 },
134 { .min = 645000000, .max = 700000000 }, 134 { .min = 645000000, .max = 700000000 },
@@ -151,7 +151,7 @@ static u8 sam9g20_pllb_out[] = { 0 };
151 151
152static u16 sam9g20_pllb_icpll[] = { 0 }; 152static u16 sam9g20_pllb_icpll[] = { 0 };
153 153
154static struct clk_range sam9g20_pllb_outputs[] = { 154static const struct clk_range sam9g20_pllb_outputs[] = {
155 { .min = 30000000, .max = 100000000 }, 155 { .min = 30000000, .max = 100000000 },
156}; 156};
157 157
@@ -182,7 +182,7 @@ static const struct clk_master_characteristics sam9261_mck_characteristics = {
182 .divisors = { 1, 2, 4, 0 }, 182 .divisors = { 1, 2, 4, 0 },
183}; 183};
184 184
185static struct clk_range sam9261_plla_outputs[] = { 185static const struct clk_range sam9261_plla_outputs[] = {
186 { .min = 80000000, .max = 200000000 }, 186 { .min = 80000000, .max = 200000000 },
187 { .min = 190000000, .max = 240000000 }, 187 { .min = 190000000, .max = 240000000 },
188}; 188};
@@ -199,7 +199,7 @@ static u8 sam9261_pllb_out[] = { 1 };
199 199
200static u16 sam9261_pllb_icpll[] = { 1 }; 200static u16 sam9261_pllb_icpll[] = { 1 };
201 201
202static struct clk_range sam9261_pllb_outputs[] = { 202static const struct clk_range sam9261_pllb_outputs[] = {
203 { .min = 70000000, .max = 130000000 }, 203 { .min = 70000000, .max = 130000000 },
204}; 204};
205 205
@@ -262,7 +262,7 @@ static const struct clk_master_characteristics sam9263_mck_characteristics = {
262 .divisors = { 1, 2, 4, 0 }, 262 .divisors = { 1, 2, 4, 0 },
263}; 263};
264 264
265static struct clk_range sam9263_pll_outputs[] = { 265static const struct clk_range sam9263_pll_outputs[] = {
266 { .min = 80000000, .max = 200000000 }, 266 { .min = 80000000, .max = 200000000 },
267 { .min = 190000000, .max = 240000000 }, 267 { .min = 190000000, .max = 240000000 },
268}; 268};
diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c
index 5aeef68b4bdd..0ac34cdaa106 100644
--- a/drivers/clk/at91/at91sam9rl.c
+++ b/drivers/clk/at91/at91sam9rl.c
@@ -14,7 +14,7 @@ static const struct clk_master_characteristics sam9rl_mck_characteristics = {
14 14
15static u8 sam9rl_plla_out[] = { 0, 2 }; 15static u8 sam9rl_plla_out[] = { 0, 2 };
16 16
17static struct clk_range sam9rl_plla_outputs[] = { 17static const struct clk_range sam9rl_plla_outputs[] = {
18 { .min = 80000000, .max = 200000000 }, 18 { .min = 80000000, .max = 200000000 },
19 { .min = 190000000, .max = 240000000 }, 19 { .min = 190000000, .max = 240000000 },
20}; 20};
diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c
index 3487e03d4bc6..0855f3a80cc7 100644
--- a/drivers/clk/at91/at91sam9x5.c
+++ b/drivers/clk/at91/at91sam9x5.c
@@ -17,7 +17,7 @@ static u8 plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
17 17
18static u16 plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 }; 18static u16 plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
19 19
20static struct clk_range plla_outputs[] = { 20static const struct clk_range plla_outputs[] = {
21 { .min = 745000000, .max = 800000000 }, 21 { .min = 745000000, .max = 800000000 },
22 { .min = 695000000, .max = 750000000 }, 22 { .min = 695000000, .max = 750000000 },
23 { .min = 645000000, .max = 700000000 }, 23 { .min = 645000000, .max = 700000000 },
@@ -49,6 +49,13 @@ static const struct {
49 { .n = "pck1", .p = "prog1", .id = 9 }, 49 { .n = "pck1", .p = "prog1", .id = 9 },
50}; 50};
51 51
52static const struct clk_pcr_layout at91sam9x5_pcr_layout = {
53 .offset = 0x10c,
54 .cmd = BIT(12),
55 .pid_mask = GENMASK(5, 0),
56 .div_mask = GENMASK(17, 16),
57};
58
52struct pck { 59struct pck {
53 char *n; 60 char *n;
54 u8 id; 61 u8 id;
@@ -242,6 +249,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
242 249
243 for (i = 0; i < ARRAY_SIZE(at91sam9x5_periphck); i++) { 250 for (i = 0; i < ARRAY_SIZE(at91sam9x5_periphck); i++) {
244 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 251 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
252 &at91sam9x5_pcr_layout,
245 at91sam9x5_periphck[i].n, 253 at91sam9x5_periphck[i].n,
246 "masterck", 254 "masterck",
247 at91sam9x5_periphck[i].id, 255 at91sam9x5_periphck[i].id,
@@ -254,6 +262,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
254 262
255 for (i = 0; extra_pcks[i].id; i++) { 263 for (i = 0; extra_pcks[i].id; i++) {
256 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 264 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
265 &at91sam9x5_pcr_layout,
257 extra_pcks[i].n, 266 extra_pcks[i].n,
258 "masterck", 267 "masterck",
259 extra_pcks[i].id, 268 extra_pcks[i].id,
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
index 66e7f7baf958..5f18847965c1 100644
--- a/drivers/clk/at91/clk-generated.c
+++ b/drivers/clk/at91/clk-generated.c
@@ -11,6 +11,7 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/bitfield.h>
14#include <linux/clk-provider.h> 15#include <linux/clk-provider.h>
15#include <linux/clkdev.h> 16#include <linux/clkdev.h>
16#include <linux/clk/at91_pmc.h> 17#include <linux/clk/at91_pmc.h>
@@ -31,6 +32,7 @@ struct clk_generated {
31 spinlock_t *lock; 32 spinlock_t *lock;
32 u32 id; 33 u32 id;
33 u32 gckdiv; 34 u32 gckdiv;
35 const struct clk_pcr_layout *layout;
34 u8 parent_id; 36 u8 parent_id;
35 bool audio_pll_allowed; 37 bool audio_pll_allowed;
36}; 38};
@@ -47,14 +49,14 @@ static int clk_generated_enable(struct clk_hw *hw)
47 __func__, gck->gckdiv, gck->parent_id); 49 __func__, gck->gckdiv, gck->parent_id);
48 50
49 spin_lock_irqsave(gck->lock, flags); 51 spin_lock_irqsave(gck->lock, flags);
50 regmap_write(gck->regmap, AT91_PMC_PCR, 52 regmap_write(gck->regmap, gck->layout->offset,
51 (gck->id & AT91_PMC_PCR_PID_MASK)); 53 (gck->id & gck->layout->pid_mask));
52 regmap_update_bits(gck->regmap, AT91_PMC_PCR, 54 regmap_update_bits(gck->regmap, gck->layout->offset,
53 AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK | 55 AT91_PMC_PCR_GCKDIV_MASK | gck->layout->gckcss_mask |
54 AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN, 56 gck->layout->cmd | AT91_PMC_PCR_GCKEN,
55 AT91_PMC_PCR_GCKCSS(gck->parent_id) | 57 field_prep(gck->layout->gckcss_mask, gck->parent_id) |
56 AT91_PMC_PCR_CMD | 58 gck->layout->cmd |
57 AT91_PMC_PCR_GCKDIV(gck->gckdiv) | 59 FIELD_PREP(AT91_PMC_PCR_GCKDIV_MASK, gck->gckdiv) |
58 AT91_PMC_PCR_GCKEN); 60 AT91_PMC_PCR_GCKEN);
59 spin_unlock_irqrestore(gck->lock, flags); 61 spin_unlock_irqrestore(gck->lock, flags);
60 return 0; 62 return 0;
@@ -66,11 +68,11 @@ static void clk_generated_disable(struct clk_hw *hw)
66 unsigned long flags; 68 unsigned long flags;
67 69
68 spin_lock_irqsave(gck->lock, flags); 70 spin_lock_irqsave(gck->lock, flags);
69 regmap_write(gck->regmap, AT91_PMC_PCR, 71 regmap_write(gck->regmap, gck->layout->offset,
70 (gck->id & AT91_PMC_PCR_PID_MASK)); 72 (gck->id & gck->layout->pid_mask));
71 regmap_update_bits(gck->regmap, AT91_PMC_PCR, 73 regmap_update_bits(gck->regmap, gck->layout->offset,
72 AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN, 74 gck->layout->cmd | AT91_PMC_PCR_GCKEN,
73 AT91_PMC_PCR_CMD); 75 gck->layout->cmd);
74 spin_unlock_irqrestore(gck->lock, flags); 76 spin_unlock_irqrestore(gck->lock, flags);
75} 77}
76 78
@@ -81,9 +83,9 @@ static int clk_generated_is_enabled(struct clk_hw *hw)
81 unsigned int status; 83 unsigned int status;
82 84
83 spin_lock_irqsave(gck->lock, flags); 85 spin_lock_irqsave(gck->lock, flags);
84 regmap_write(gck->regmap, AT91_PMC_PCR, 86 regmap_write(gck->regmap, gck->layout->offset,
85 (gck->id & AT91_PMC_PCR_PID_MASK)); 87 (gck->id & gck->layout->pid_mask));
86 regmap_read(gck->regmap, AT91_PMC_PCR, &status); 88 regmap_read(gck->regmap, gck->layout->offset, &status);
87 spin_unlock_irqrestore(gck->lock, flags); 89 spin_unlock_irqrestore(gck->lock, flags);
88 90
89 return status & AT91_PMC_PCR_GCKEN ? 1 : 0; 91 return status & AT91_PMC_PCR_GCKEN ? 1 : 0;
@@ -259,19 +261,18 @@ static void clk_generated_startup(struct clk_generated *gck)
259 unsigned long flags; 261 unsigned long flags;
260 262
261 spin_lock_irqsave(gck->lock, flags); 263 spin_lock_irqsave(gck->lock, flags);
262 regmap_write(gck->regmap, AT91_PMC_PCR, 264 regmap_write(gck->regmap, gck->layout->offset,
263 (gck->id & AT91_PMC_PCR_PID_MASK)); 265 (gck->id & gck->layout->pid_mask));
264 regmap_read(gck->regmap, AT91_PMC_PCR, &tmp); 266 regmap_read(gck->regmap, gck->layout->offset, &tmp);
265 spin_unlock_irqrestore(gck->lock, flags); 267 spin_unlock_irqrestore(gck->lock, flags);
266 268
267 gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK) 269 gck->parent_id = field_get(gck->layout->gckcss_mask, tmp);
268 >> AT91_PMC_PCR_GCKCSS_OFFSET; 270 gck->gckdiv = FIELD_GET(AT91_PMC_PCR_GCKDIV_MASK, tmp);
269 gck->gckdiv = (tmp & AT91_PMC_PCR_GCKDIV_MASK)
270 >> AT91_PMC_PCR_GCKDIV_OFFSET;
271} 271}
272 272
273struct clk_hw * __init 273struct clk_hw * __init
274at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, 274at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
275 const struct clk_pcr_layout *layout,
275 const char *name, const char **parent_names, 276 const char *name, const char **parent_names,
276 u8 num_parents, u8 id, bool pll_audio, 277 u8 num_parents, u8 id, bool pll_audio,
277 const struct clk_range *range) 278 const struct clk_range *range)
@@ -298,6 +299,7 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
298 gck->lock = lock; 299 gck->lock = lock;
299 gck->range = *range; 300 gck->range = *range;
300 gck->audio_pll_allowed = pll_audio; 301 gck->audio_pll_allowed = pll_audio;
302 gck->layout = layout;
301 303
302 clk_generated_startup(gck); 304 clk_generated_startup(gck);
303 hw = &gck->hw; 305 hw = &gck->hw;
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index eb53b4a8fab6..12b5bf4cc7bb 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -29,6 +29,7 @@ struct clk_master {
29 struct regmap *regmap; 29 struct regmap *regmap;
30 const struct clk_master_layout *layout; 30 const struct clk_master_layout *layout;
31 const struct clk_master_characteristics *characteristics; 31 const struct clk_master_characteristics *characteristics;
32 u32 mckr;
32}; 33};
33 34
34static inline bool clk_master_ready(struct regmap *regmap) 35static inline bool clk_master_ready(struct regmap *regmap)
@@ -69,7 +70,7 @@ static unsigned long clk_master_recalc_rate(struct clk_hw *hw,
69 master->characteristics; 70 master->characteristics;
70 unsigned int mckr; 71 unsigned int mckr;
71 72
72 regmap_read(master->regmap, AT91_PMC_MCKR, &mckr); 73 regmap_read(master->regmap, master->layout->offset, &mckr);
73 mckr &= layout->mask; 74 mckr &= layout->mask;
74 75
75 pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK; 76 pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK;
@@ -95,7 +96,7 @@ static u8 clk_master_get_parent(struct clk_hw *hw)
95 struct clk_master *master = to_clk_master(hw); 96 struct clk_master *master = to_clk_master(hw);
96 unsigned int mckr; 97 unsigned int mckr;
97 98
98 regmap_read(master->regmap, AT91_PMC_MCKR, &mckr); 99 regmap_read(master->regmap, master->layout->offset, &mckr);
99 100
100 return mckr & AT91_PMC_CSS; 101 return mckr & AT91_PMC_CSS;
101} 102}
@@ -147,13 +148,14 @@ at91_clk_register_master(struct regmap *regmap,
147 return hw; 148 return hw;
148} 149}
149 150
150
151const struct clk_master_layout at91rm9200_master_layout = { 151const struct clk_master_layout at91rm9200_master_layout = {
152 .mask = 0x31F, 152 .mask = 0x31F,
153 .pres_shift = 2, 153 .pres_shift = 2,
154 .offset = AT91_PMC_MCKR,
154}; 155};
155 156
156const struct clk_master_layout at91sam9x5_master_layout = { 157const struct clk_master_layout at91sam9x5_master_layout = {
157 .mask = 0x373, 158 .mask = 0x373,
158 .pres_shift = 4, 159 .pres_shift = 4,
160 .offset = AT91_PMC_MCKR,
159}; 161};
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index 65c1defa78e4..6b7748b9588a 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -8,6 +8,7 @@
8 * 8 *
9 */ 9 */
10 10
11#include <linux/bitops.h>
11#include <linux/clk-provider.h> 12#include <linux/clk-provider.h>
12#include <linux/clkdev.h> 13#include <linux/clkdev.h>
13#include <linux/clk/at91_pmc.h> 14#include <linux/clk/at91_pmc.h>
@@ -23,9 +24,6 @@ DEFINE_SPINLOCK(pmc_pcr_lock);
23#define PERIPHERAL_ID_MAX 31 24#define PERIPHERAL_ID_MAX 31
24#define PERIPHERAL_MASK(id) (1 << ((id) & PERIPHERAL_ID_MAX)) 25#define PERIPHERAL_MASK(id) (1 << ((id) & PERIPHERAL_ID_MAX))
25 26
26#define PERIPHERAL_RSHIFT_MASK 0x3
27#define PERIPHERAL_RSHIFT(val) (((val) >> 16) & PERIPHERAL_RSHIFT_MASK)
28
29#define PERIPHERAL_MAX_SHIFT 3 27#define PERIPHERAL_MAX_SHIFT 3
30 28
31struct clk_peripheral { 29struct clk_peripheral {
@@ -43,6 +41,7 @@ struct clk_sam9x5_peripheral {
43 spinlock_t *lock; 41 spinlock_t *lock;
44 u32 id; 42 u32 id;
45 u32 div; 43 u32 div;
44 const struct clk_pcr_layout *layout;
46 bool auto_div; 45 bool auto_div;
47}; 46};
48 47
@@ -169,13 +168,13 @@ static int clk_sam9x5_peripheral_enable(struct clk_hw *hw)
169 return 0; 168 return 0;
170 169
171 spin_lock_irqsave(periph->lock, flags); 170 spin_lock_irqsave(periph->lock, flags);
172 regmap_write(periph->regmap, AT91_PMC_PCR, 171 regmap_write(periph->regmap, periph->layout->offset,
173 (periph->id & AT91_PMC_PCR_PID_MASK)); 172 (periph->id & periph->layout->pid_mask));
174 regmap_update_bits(periph->regmap, AT91_PMC_PCR, 173 regmap_update_bits(periph->regmap, periph->layout->offset,
175 AT91_PMC_PCR_DIV_MASK | AT91_PMC_PCR_CMD | 174 periph->layout->div_mask | periph->layout->cmd |
176 AT91_PMC_PCR_EN, 175 AT91_PMC_PCR_EN,
177 AT91_PMC_PCR_DIV(periph->div) | 176 field_prep(periph->layout->div_mask, periph->div) |
178 AT91_PMC_PCR_CMD | 177 periph->layout->cmd |
179 AT91_PMC_PCR_EN); 178 AT91_PMC_PCR_EN);
180 spin_unlock_irqrestore(periph->lock, flags); 179 spin_unlock_irqrestore(periph->lock, flags);
181 180
@@ -191,11 +190,11 @@ static void clk_sam9x5_peripheral_disable(struct clk_hw *hw)
191 return; 190 return;
192 191
193 spin_lock_irqsave(periph->lock, flags); 192 spin_lock_irqsave(periph->lock, flags);
194 regmap_write(periph->regmap, AT91_PMC_PCR, 193 regmap_write(periph->regmap, periph->layout->offset,
195 (periph->id & AT91_PMC_PCR_PID_MASK)); 194 (periph->id & periph->layout->pid_mask));
196 regmap_update_bits(periph->regmap, AT91_PMC_PCR, 195 regmap_update_bits(periph->regmap, periph->layout->offset,
197 AT91_PMC_PCR_EN | AT91_PMC_PCR_CMD, 196 AT91_PMC_PCR_EN | periph->layout->cmd,
198 AT91_PMC_PCR_CMD); 197 periph->layout->cmd);
199 spin_unlock_irqrestore(periph->lock, flags); 198 spin_unlock_irqrestore(periph->lock, flags);
200} 199}
201 200
@@ -209,9 +208,9 @@ static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)
209 return 1; 208 return 1;
210 209
211 spin_lock_irqsave(periph->lock, flags); 210 spin_lock_irqsave(periph->lock, flags);
212 regmap_write(periph->regmap, AT91_PMC_PCR, 211 regmap_write(periph->regmap, periph->layout->offset,
213 (periph->id & AT91_PMC_PCR_PID_MASK)); 212 (periph->id & periph->layout->pid_mask));
214 regmap_read(periph->regmap, AT91_PMC_PCR, &status); 213 regmap_read(periph->regmap, periph->layout->offset, &status);
215 spin_unlock_irqrestore(periph->lock, flags); 214 spin_unlock_irqrestore(periph->lock, flags);
216 215
217 return status & AT91_PMC_PCR_EN ? 1 : 0; 216 return status & AT91_PMC_PCR_EN ? 1 : 0;
@@ -229,13 +228,13 @@ clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw,
229 return parent_rate; 228 return parent_rate;
230 229
231 spin_lock_irqsave(periph->lock, flags); 230 spin_lock_irqsave(periph->lock, flags);
232 regmap_write(periph->regmap, AT91_PMC_PCR, 231 regmap_write(periph->regmap, periph->layout->offset,
233 (periph->id & AT91_PMC_PCR_PID_MASK)); 232 (periph->id & periph->layout->pid_mask));
234 regmap_read(periph->regmap, AT91_PMC_PCR, &status); 233 regmap_read(periph->regmap, periph->layout->offset, &status);
235 spin_unlock_irqrestore(periph->lock, flags); 234 spin_unlock_irqrestore(periph->lock, flags);
236 235
237 if (status & AT91_PMC_PCR_EN) { 236 if (status & AT91_PMC_PCR_EN) {
238 periph->div = PERIPHERAL_RSHIFT(status); 237 periph->div = field_get(periph->layout->div_mask, status);
239 periph->auto_div = false; 238 periph->auto_div = false;
240 } else { 239 } else {
241 clk_sam9x5_peripheral_autodiv(periph); 240 clk_sam9x5_peripheral_autodiv(periph);
@@ -328,6 +327,7 @@ static const struct clk_ops sam9x5_peripheral_ops = {
328 327
329struct clk_hw * __init 328struct clk_hw * __init
330at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, 329at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
330 const struct clk_pcr_layout *layout,
331 const char *name, const char *parent_name, 331 const char *name, const char *parent_name,
332 u32 id, const struct clk_range *range) 332 u32 id, const struct clk_range *range)
333{ 333{
@@ -354,7 +354,9 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
354 periph->div = 0; 354 periph->div = 0;
355 periph->regmap = regmap; 355 periph->regmap = regmap;
356 periph->lock = lock; 356 periph->lock = lock;
357 periph->auto_div = true; 357 if (layout->div_mask)
358 periph->auto_div = true;
359 periph->layout = layout;
358 periph->range = *range; 360 periph->range = *range;
359 361
360 hw = &periph->hw; 362 hw = &periph->hw;
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
new file mode 100644
index 000000000000..34b817825b22
--- /dev/null
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -0,0 +1,330 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019 Microchip Technology Inc.
4 *
5 */
6
7#include <linux/bitfield.h>
8#include <linux/clk-provider.h>
9#include <linux/clkdev.h>
10#include <linux/clk/at91_pmc.h>
11#include <linux/of.h>
12#include <linux/mfd/syscon.h>
13#include <linux/regmap.h>
14
15#include "pmc.h"
16
17#define PMC_PLL_CTRL0 0xc
18#define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0)
19#define PMC_PLL_CTRL0_ENPLL BIT(28)
20#define PMC_PLL_CTRL0_ENPLLCK BIT(29)
21#define PMC_PLL_CTRL0_ENLOCK BIT(31)
22
23#define PMC_PLL_CTRL1 0x10
24#define PMC_PLL_CTRL1_FRACR_MSK GENMASK(21, 0)
25#define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24)
26
27#define PMC_PLL_ACR 0x18
28#define PMC_PLL_ACR_DEFAULT 0x1b040010UL
29#define PMC_PLL_ACR_UTMIVR BIT(12)
30#define PMC_PLL_ACR_UTMIBG BIT(13)
31#define PMC_PLL_ACR_LOOP_FILTER_MSK GENMASK(31, 24)
32
33#define PMC_PLL_UPDT 0x1c
34#define PMC_PLL_UPDT_UPDATE BIT(8)
35
36#define PMC_PLL_ISR0 0xec
37
38#define PLL_DIV_MAX (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
39#define UPLL_DIV 2
40#define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
41
42#define PLL_MAX_ID 1
43
44struct sam9x60_pll {
45 struct clk_hw hw;
46 struct regmap *regmap;
47 spinlock_t *lock;
48 const struct clk_pll_characteristics *characteristics;
49 u32 frac;
50 u8 id;
51 u8 div;
52 u16 mul;
53};
54
55#define to_sam9x60_pll(hw) container_of(hw, struct sam9x60_pll, hw)
56
57static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
58{
59 unsigned int status;
60
61 regmap_read(regmap, PMC_PLL_ISR0, &status);
62
63 return !!(status & BIT(id));
64}
65
66static int sam9x60_pll_prepare(struct clk_hw *hw)
67{
68 struct sam9x60_pll *pll = to_sam9x60_pll(hw);
69 struct regmap *regmap = pll->regmap;
70 unsigned long flags;
71 u8 div;
72 u16 mul;
73 u32 val;
74
75 spin_lock_irqsave(pll->lock, flags);
76 regmap_write(regmap, PMC_PLL_UPDT, pll->id);
77
78 regmap_read(regmap, PMC_PLL_CTRL0, &val);
79 div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val);
80
81 regmap_read(regmap, PMC_PLL_CTRL1, &val);
82 mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val);
83
84 if (sam9x60_pll_ready(regmap, pll->id) &&
85 (div == pll->div && mul == pll->mul)) {
86 spin_unlock_irqrestore(pll->lock, flags);
87 return 0;
88 }
89
90 /* Recommended value for PMC_PLL_ACR */
91 val = PMC_PLL_ACR_DEFAULT;
92 regmap_write(regmap, PMC_PLL_ACR, val);
93
94 regmap_write(regmap, PMC_PLL_CTRL1,
95 FIELD_PREP(PMC_PLL_CTRL1_MUL_MSK, pll->mul));
96
97 if (pll->characteristics->upll) {
98 /* Enable the UTMI internal bandgap */
99 val |= PMC_PLL_ACR_UTMIBG;
100 regmap_write(regmap, PMC_PLL_ACR, val);
101
102 udelay(10);
103
104 /* Enable the UTMI internal regulator */
105 val |= PMC_PLL_ACR_UTMIVR;
106 regmap_write(regmap, PMC_PLL_ACR, val);
107
108 udelay(10);
109 }
110
111 regmap_update_bits(regmap, PMC_PLL_UPDT,
112 PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
113
114 regmap_write(regmap, PMC_PLL_CTRL0,
115 PMC_PLL_CTRL0_ENLOCK | PMC_PLL_CTRL0_ENPLL |
116 PMC_PLL_CTRL0_ENPLLCK | pll->div);
117
118 regmap_update_bits(regmap, PMC_PLL_UPDT,
119 PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
120
121 while (!sam9x60_pll_ready(regmap, pll->id))
122 cpu_relax();
123
124 spin_unlock_irqrestore(pll->lock, flags);
125
126 return 0;
127}
128
129static int sam9x60_pll_is_prepared(struct clk_hw *hw)
130{
131 struct sam9x60_pll *pll = to_sam9x60_pll(hw);
132
133 return sam9x60_pll_ready(pll->regmap, pll->id);
134}
135
136static void sam9x60_pll_unprepare(struct clk_hw *hw)
137{
138 struct sam9x60_pll *pll = to_sam9x60_pll(hw);
139 unsigned long flags;
140
141 spin_lock_irqsave(pll->lock, flags);
142
143 regmap_write(pll->regmap, PMC_PLL_UPDT, pll->id);
144
145 regmap_update_bits(pll->regmap, PMC_PLL_CTRL0,
146 PMC_PLL_CTRL0_ENPLLCK, 0);
147
148 regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
149 PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
150
151 regmap_update_bits(pll->regmap, PMC_PLL_CTRL0, PMC_PLL_CTRL0_ENPLL, 0);
152
153 if (pll->characteristics->upll)
154 regmap_update_bits(pll->regmap, PMC_PLL_ACR,
155 PMC_PLL_ACR_UTMIBG | PMC_PLL_ACR_UTMIVR, 0);
156
157 regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
158 PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
159
160 spin_unlock_irqrestore(pll->lock, flags);
161}
162
163static unsigned long sam9x60_pll_recalc_rate(struct clk_hw *hw,
164 unsigned long parent_rate)
165{
166 struct sam9x60_pll *pll = to_sam9x60_pll(hw);
167
168 return (parent_rate * (pll->mul + 1)) / (pll->div + 1);
169}
170
171static long sam9x60_pll_get_best_div_mul(struct sam9x60_pll *pll,
172 unsigned long rate,
173 unsigned long parent_rate,
174 bool update)
175{
176 const struct clk_pll_characteristics *characteristics =
177 pll->characteristics;
178 unsigned long bestremainder = ULONG_MAX;
179 unsigned long maxdiv, mindiv, tmpdiv;
180 long bestrate = -ERANGE;
181 unsigned long bestdiv = 0;
182 unsigned long bestmul = 0;
183 unsigned long bestfrac = 0;
184
185 if (rate < characteristics->output[0].min ||
186 rate > characteristics->output[0].max)
187 return -ERANGE;
188
189 if (!pll->characteristics->upll) {
190 mindiv = parent_rate / rate;
191 if (mindiv < 2)
192 mindiv = 2;
193
194 maxdiv = DIV_ROUND_UP(parent_rate * PLL_MUL_MAX, rate);
195 if (maxdiv > PLL_DIV_MAX)
196 maxdiv = PLL_DIV_MAX;
197 } else {
198 mindiv = maxdiv = UPLL_DIV;
199 }
200
201 for (tmpdiv = mindiv; tmpdiv <= maxdiv; tmpdiv++) {
202 unsigned long remainder;
203 unsigned long tmprate;
204 unsigned long tmpmul;
205 unsigned long tmpfrac = 0;
206
207 /*
208 * Calculate the multiplier associated with the current
209 * divider that provide the closest rate to the requested one.
210 */
211 tmpmul = mult_frac(rate, tmpdiv, parent_rate);
212 tmprate = mult_frac(parent_rate, tmpmul, tmpdiv);
213 remainder = rate - tmprate;
214
215 if (remainder) {
216 tmpfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * tmpdiv * (1 << 22),
217 parent_rate);
218
219 tmprate += DIV_ROUND_CLOSEST_ULL((u64)tmpfrac * parent_rate,
220 tmpdiv * (1 << 22));
221
222 if (tmprate > rate)
223 remainder = tmprate - rate;
224 else
225 remainder = rate - tmprate;
226 }
227
228 /*
229 * Compare the remainder with the best remainder found until
230 * now and elect a new best multiplier/divider pair if the
231 * current remainder is smaller than the best one.
232 */
233 if (remainder < bestremainder) {
234 bestremainder = remainder;
235 bestdiv = tmpdiv;
236 bestmul = tmpmul;
237 bestrate = tmprate;
238 bestfrac = tmpfrac;
239 }
240
241 /* We've found a perfect match! */
242 if (!remainder)
243 break;
244 }
245
246 /* Check if bestrate is a valid output rate */
247 if (bestrate < characteristics->output[0].min &&
248 bestrate > characteristics->output[0].max)
249 return -ERANGE;
250
251 if (update) {
252 pll->div = bestdiv - 1;
253 pll->mul = bestmul - 1;
254 pll->frac = bestfrac;
255 }
256
257 return bestrate;
258}
259
260static long sam9x60_pll_round_rate(struct clk_hw *hw, unsigned long rate,
261 unsigned long *parent_rate)
262{
263 struct sam9x60_pll *pll = to_sam9x60_pll(hw);
264
265 return sam9x60_pll_get_best_div_mul(pll, rate, *parent_rate, false);
266}
267
268static int sam9x60_pll_set_rate(struct clk_hw *hw, unsigned long rate,
269 unsigned long parent_rate)
270{
271 struct sam9x60_pll *pll = to_sam9x60_pll(hw);
272
273 return sam9x60_pll_get_best_div_mul(pll, rate, parent_rate, true);
274}
275
276static const struct clk_ops pll_ops = {
277 .prepare = sam9x60_pll_prepare,
278 .unprepare = sam9x60_pll_unprepare,
279 .is_prepared = sam9x60_pll_is_prepared,
280 .recalc_rate = sam9x60_pll_recalc_rate,
281 .round_rate = sam9x60_pll_round_rate,
282 .set_rate = sam9x60_pll_set_rate,
283};
284
285struct clk_hw * __init
286sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock,
287 const char *name, const char *parent_name, u8 id,
288 const struct clk_pll_characteristics *characteristics)
289{
290 struct sam9x60_pll *pll;
291 struct clk_hw *hw;
292 struct clk_init_data init;
293 unsigned int pllr;
294 int ret;
295
296 if (id > PLL_MAX_ID)
297 return ERR_PTR(-EINVAL);
298
299 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
300 if (!pll)
301 return ERR_PTR(-ENOMEM);
302
303 init.name = name;
304 init.ops = &pll_ops;
305 init.parent_names = &parent_name;
306 init.num_parents = 1;
307 init.flags = CLK_SET_RATE_GATE;
308
309 pll->id = id;
310 pll->hw.init = &init;
311 pll->characteristics = characteristics;
312 pll->regmap = regmap;
313 pll->lock = lock;
314
315 regmap_write(regmap, PMC_PLL_UPDT, id);
316 regmap_read(regmap, PMC_PLL_CTRL0, &pllr);
317 pll->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, pllr);
318 regmap_read(regmap, PMC_PLL_CTRL1, &pllr);
319 pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr);
320
321 hw = &pll->hw;
322 ret = clk_hw_register(NULL, hw);
323 if (ret) {
324 kfree(pll);
325 hw = ERR_PTR(ret);
326 }
327
328 return hw;
329}
330
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c
index 79ee1c760f2a..ebc37ee33518 100644
--- a/drivers/clk/at91/clk-usb.c
+++ b/drivers/clk/at91/clk-usb.c
@@ -23,9 +23,13 @@
23#define RM9200_USB_DIV_SHIFT 28 23#define RM9200_USB_DIV_SHIFT 28
24#define RM9200_USB_DIV_TAB_SIZE 4 24#define RM9200_USB_DIV_TAB_SIZE 4
25 25
26#define SAM9X5_USBS_MASK GENMASK(0, 0)
27#define SAM9X60_USBS_MASK GENMASK(1, 0)
28
26struct at91sam9x5_clk_usb { 29struct at91sam9x5_clk_usb {
27 struct clk_hw hw; 30 struct clk_hw hw;
28 struct regmap *regmap; 31 struct regmap *regmap;
32 u32 usbs_mask;
29}; 33};
30 34
31#define to_at91sam9x5_clk_usb(hw) \ 35#define to_at91sam9x5_clk_usb(hw) \
@@ -111,8 +115,7 @@ static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
111 if (index > 1) 115 if (index > 1)
112 return -EINVAL; 116 return -EINVAL;
113 117
114 regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS, 118 regmap_update_bits(usb->regmap, AT91_PMC_USB, usb->usbs_mask, index);
115 index ? AT91_PMC_USBS : 0);
116 119
117 return 0; 120 return 0;
118} 121}
@@ -124,7 +127,7 @@ static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw)
124 127
125 regmap_read(usb->regmap, AT91_PMC_USB, &usbr); 128 regmap_read(usb->regmap, AT91_PMC_USB, &usbr);
126 129
127 return usbr & AT91_PMC_USBS; 130 return usbr & usb->usbs_mask;
128} 131}
129 132
130static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, 133static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -190,9 +193,10 @@ static const struct clk_ops at91sam9n12_usb_ops = {
190 .set_rate = at91sam9x5_clk_usb_set_rate, 193 .set_rate = at91sam9x5_clk_usb_set_rate,
191}; 194};
192 195
193struct clk_hw * __init 196static struct clk_hw * __init
194at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, 197_at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
195 const char **parent_names, u8 num_parents) 198 const char **parent_names, u8 num_parents,
199 u32 usbs_mask)
196{ 200{
197 struct at91sam9x5_clk_usb *usb; 201 struct at91sam9x5_clk_usb *usb;
198 struct clk_hw *hw; 202 struct clk_hw *hw;
@@ -212,6 +216,7 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
212 216
213 usb->hw.init = &init; 217 usb->hw.init = &init;
214 usb->regmap = regmap; 218 usb->regmap = regmap;
219 usb->usbs_mask = SAM9X5_USBS_MASK;
215 220
216 hw = &usb->hw; 221 hw = &usb->hw;
217 ret = clk_hw_register(NULL, &usb->hw); 222 ret = clk_hw_register(NULL, &usb->hw);
@@ -224,6 +229,22 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
224} 229}
225 230
226struct clk_hw * __init 231struct clk_hw * __init
232at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
233 const char **parent_names, u8 num_parents)
234{
235 return _at91sam9x5_clk_register_usb(regmap, name, parent_names,
236 num_parents, SAM9X5_USBS_MASK);
237}
238
239struct clk_hw * __init
240sam9x60_clk_register_usb(struct regmap *regmap, const char *name,
241 const char **parent_names, u8 num_parents)
242{
243 return _at91sam9x5_clk_register_usb(regmap, name, parent_names,
244 num_parents, SAM9X60_USBS_MASK);
245}
246
247struct clk_hw * __init
227at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, 248at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
228 const char *parent_name) 249 const char *parent_name)
229{ 250{
diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c
index b95bb4e2a927..aa1754eac59f 100644
--- a/drivers/clk/at91/dt-compat.c
+++ b/drivers/clk/at91/dt-compat.c
@@ -93,6 +93,14 @@ CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup,
93 of_sama5d2_clk_audio_pll_pmc_setup); 93 of_sama5d2_clk_audio_pll_pmc_setup);
94#endif /* CONFIG_HAVE_AT91_AUDIO_PLL */ 94#endif /* CONFIG_HAVE_AT91_AUDIO_PLL */
95 95
96static const struct clk_pcr_layout dt_pcr_layout = {
97 .offset = 0x10c,
98 .cmd = BIT(12),
99 .pid_mask = GENMASK(5, 0),
100 .div_mask = GENMASK(17, 16),
101 .gckcss_mask = GENMASK(10, 8),
102};
103
96#ifdef CONFIG_HAVE_AT91_GENERATED_CLK 104#ifdef CONFIG_HAVE_AT91_GENERATED_CLK
97#define GENERATED_SOURCE_MAX 6 105#define GENERATED_SOURCE_MAX 6
98 106
@@ -146,7 +154,8 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
146 id == GCK_ID_CLASSD)) 154 id == GCK_ID_CLASSD))
147 pll_audio = true; 155 pll_audio = true;
148 156
149 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name, 157 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
158 &dt_pcr_layout, name,
150 parent_names, num_parents, 159 parent_names, num_parents,
151 id, pll_audio, &range); 160 id, pll_audio, &range);
152 if (IS_ERR(hw)) 161 if (IS_ERR(hw))
@@ -448,6 +457,7 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type)
448 457
449 hw = at91_clk_register_sam9x5_peripheral(regmap, 458 hw = at91_clk_register_sam9x5_peripheral(regmap,
450 &pmc_pcr_lock, 459 &pmc_pcr_lock,
460 &dt_pcr_layout,
451 name, 461 name,
452 parent_name, 462 parent_name,
453 id, &range); 463 id, &range);
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index a0e5ce9c9b9e..2311204948be 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -38,6 +38,7 @@ struct clk_range {
38#define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,} 38#define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,}
39 39
40struct clk_master_layout { 40struct clk_master_layout {
41 u32 offset;
41 u32 mask; 42 u32 mask;
42 u8 pres_shift; 43 u8 pres_shift;
43}; 44};
@@ -65,9 +66,10 @@ extern const struct clk_pll_layout sama5d3_pll_layout;
65struct clk_pll_characteristics { 66struct clk_pll_characteristics {
66 struct clk_range input; 67 struct clk_range input;
67 int num_output; 68 int num_output;
68 struct clk_range *output; 69 const struct clk_range *output;
69 u16 *icpll; 70 u16 *icpll;
70 u8 *out; 71 u8 *out;
72 u8 upll : 1;
71}; 73};
72 74
73struct clk_programmable_layout { 75struct clk_programmable_layout {
@@ -82,6 +84,17 @@ extern const struct clk_programmable_layout at91rm9200_programmable_layout;
82extern const struct clk_programmable_layout at91sam9g45_programmable_layout; 84extern const struct clk_programmable_layout at91sam9g45_programmable_layout;
83extern const struct clk_programmable_layout at91sam9x5_programmable_layout; 85extern const struct clk_programmable_layout at91sam9x5_programmable_layout;
84 86
87struct clk_pcr_layout {
88 u32 offset;
89 u32 cmd;
90 u32 div_mask;
91 u32 gckcss_mask;
92 u32 pid_mask;
93};
94
95#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
96#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
97
85#define ndck(a, s) (a[s - 1].id + 1) 98#define ndck(a, s) (a[s - 1].id + 1)
86#define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1) 99#define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
87struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem, 100struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
@@ -107,6 +120,7 @@ at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
107 120
108struct clk_hw * __init 121struct clk_hw * __init
109at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, 122at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
123 const struct clk_pcr_layout *layout,
110 const char *name, const char **parent_names, 124 const char *name, const char **parent_names,
111 u8 num_parents, u8 id, bool pll_audio, 125 u8 num_parents, u8 id, bool pll_audio,
112 const struct clk_range *range); 126 const struct clk_range *range);
@@ -145,6 +159,7 @@ at91_clk_register_peripheral(struct regmap *regmap, const char *name,
145 const char *parent_name, u32 id); 159 const char *parent_name, u32 id);
146struct clk_hw * __init 160struct clk_hw * __init
147at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, 161at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
162 const struct clk_pcr_layout *layout,
148 const char *name, const char *parent_name, 163 const char *name, const char *parent_name,
149 u32 id, const struct clk_range *range); 164 u32 id, const struct clk_range *range);
150 165
@@ -158,6 +173,11 @@ at91_clk_register_plldiv(struct regmap *regmap, const char *name,
158 const char *parent_name); 173 const char *parent_name);
159 174
160struct clk_hw * __init 175struct clk_hw * __init
176sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock,
177 const char *name, const char *parent_name, u8 id,
178 const struct clk_pll_characteristics *characteristics);
179
180struct clk_hw * __init
161at91_clk_register_programmable(struct regmap *regmap, const char *name, 181at91_clk_register_programmable(struct regmap *regmap, const char *name,
162 const char **parent_names, u8 num_parents, u8 id, 182 const char **parent_names, u8 num_parents, u8 id,
163 const struct clk_programmable_layout *layout); 183 const struct clk_programmable_layout *layout);
@@ -183,6 +203,9 @@ struct clk_hw * __init
183at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, 203at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
184 const char *parent_name); 204 const char *parent_name);
185struct clk_hw * __init 205struct clk_hw * __init
206sam9x60_clk_register_usb(struct regmap *regmap, const char *name,
207 const char **parent_names, u8 num_parents);
208struct clk_hw * __init
186at91rm9200_clk_register_usb(struct regmap *regmap, const char *name, 209at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
187 const char *parent_name, const u32 *divisors); 210 const char *parent_name, const u32 *divisors);
188 211
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
new file mode 100644
index 000000000000..9790ddfa5b3c
--- /dev/null
+++ b/drivers/clk/at91/sam9x60.c
@@ -0,0 +1,307 @@
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/clk-provider.h>
3#include <linux/mfd/syscon.h>
4#include <linux/slab.h>
5
6#include <dt-bindings/clock/at91.h>
7
8#include "pmc.h"
9
10static DEFINE_SPINLOCK(pmc_pll_lock);
11
12static const struct clk_master_characteristics mck_characteristics = {
13 .output = { .min = 140000000, .max = 200000000 },
14 .divisors = { 1, 2, 4, 3 },
15 .have_div3_pres = 1,
16};
17
18static const struct clk_master_layout sam9x60_master_layout = {
19 .mask = 0x373,
20 .pres_shift = 4,
21 .offset = 0x28,
22};
23
24static const struct clk_range plla_outputs[] = {
25 { .min = 300000000, .max = 600000000 },
26};
27
28static const struct clk_pll_characteristics plla_characteristics = {
29 .input = { .min = 12000000, .max = 48000000 },
30 .num_output = ARRAY_SIZE(plla_outputs),
31 .output = plla_outputs,
32};
33
34static const struct clk_range upll_outputs[] = {
35 { .min = 300000000, .max = 500000000 },
36};
37
38static const struct clk_pll_characteristics upll_characteristics = {
39 .input = { .min = 12000000, .max = 48000000 },
40 .num_output = ARRAY_SIZE(upll_outputs),
41 .output = upll_outputs,
42 .upll = true,
43};
44
45static const struct clk_programmable_layout sam9x60_programmable_layout = {
46 .pres_shift = 8,
47 .css_mask = 0x1f,
48 .have_slck_mck = 0,
49};
50
51static const struct clk_pcr_layout sam9x60_pcr_layout = {
52 .offset = 0x88,
53 .cmd = BIT(31),
54 .gckcss_mask = GENMASK(12, 8),
55 .pid_mask = GENMASK(6, 0),
56};
57
58static const struct {
59 char *n;
60 char *p;
61 u8 id;
62} sam9x60_systemck[] = {
63 { .n = "ddrck", .p = "masterck", .id = 2 },
64 { .n = "uhpck", .p = "usbck", .id = 6 },
65 { .n = "pck0", .p = "prog0", .id = 8 },
66 { .n = "pck1", .p = "prog1", .id = 9 },
67 { .n = "qspick", .p = "masterck", .id = 19 },
68};
69
70static const struct {
71 char *n;
72 u8 id;
73} sam9x60_periphck[] = {
74 { .n = "pioA_clk", .id = 2, },
75 { .n = "pioB_clk", .id = 3, },
76 { .n = "pioC_clk", .id = 4, },
77 { .n = "flex0_clk", .id = 5, },
78 { .n = "flex1_clk", .id = 6, },
79 { .n = "flex2_clk", .id = 7, },
80 { .n = "flex3_clk", .id = 8, },
81 { .n = "flex6_clk", .id = 9, },
82 { .n = "flex7_clk", .id = 10, },
83 { .n = "flex8_clk", .id = 11, },
84 { .n = "sdmmc0_clk", .id = 12, },
85 { .n = "flex4_clk", .id = 13, },
86 { .n = "flex5_clk", .id = 14, },
87 { .n = "flex9_clk", .id = 15, },
88 { .n = "flex10_clk", .id = 16, },
89 { .n = "tcb0_clk", .id = 17, },
90 { .n = "pwm_clk", .id = 18, },
91 { .n = "adc_clk", .id = 19, },
92 { .n = "dma0_clk", .id = 20, },
93 { .n = "matrix_clk", .id = 21, },
94 { .n = "uhphs_clk", .id = 22, },
95 { .n = "udphs_clk", .id = 23, },
96 { .n = "macb0_clk", .id = 24, },
97 { .n = "lcd_clk", .id = 25, },
98 { .n = "sdmmc1_clk", .id = 26, },
99 { .n = "macb1_clk", .id = 27, },
100 { .n = "ssc_clk", .id = 28, },
101 { .n = "can0_clk", .id = 29, },
102 { .n = "can1_clk", .id = 30, },
103 { .n = "flex11_clk", .id = 32, },
104 { .n = "flex12_clk", .id = 33, },
105 { .n = "i2s_clk", .id = 34, },
106 { .n = "qspi_clk", .id = 35, },
107 { .n = "gfx2d_clk", .id = 36, },
108 { .n = "pit64b_clk", .id = 37, },
109 { .n = "trng_clk", .id = 38, },
110 { .n = "aes_clk", .id = 39, },
111 { .n = "tdes_clk", .id = 40, },
112 { .n = "sha_clk", .id = 41, },
113 { .n = "classd_clk", .id = 42, },
114 { .n = "isi_clk", .id = 43, },
115 { .n = "pioD_clk", .id = 44, },
116 { .n = "tcb1_clk", .id = 45, },
117 { .n = "dbgu_clk", .id = 47, },
118 { .n = "mpddr_clk", .id = 49, },
119};
120
121static const struct {
122 char *n;
123 u8 id;
124 struct clk_range r;
125 bool pll;
126} sam9x60_gck[] = {
127 { .n = "flex0_gclk", .id = 5, },
128 { .n = "flex1_gclk", .id = 6, },
129 { .n = "flex2_gclk", .id = 7, },
130 { .n = "flex3_gclk", .id = 8, },
131 { .n = "flex6_gclk", .id = 9, },
132 { .n = "flex7_gclk", .id = 10, },
133 { .n = "flex8_gclk", .id = 11, },
134 { .n = "sdmmc0_gclk", .id = 12, .r = { .min = 0, .max = 105000000 }, },
135 { .n = "flex4_gclk", .id = 13, },
136 { .n = "flex5_gclk", .id = 14, },
137 { .n = "flex9_gclk", .id = 15, },
138 { .n = "flex10_gclk", .id = 16, },
139 { .n = "tcb0_gclk", .id = 17, },
140 { .n = "adc_gclk", .id = 19, },
141 { .n = "lcd_gclk", .id = 25, .r = { .min = 0, .max = 140000000 }, },
142 { .n = "sdmmc1_gclk", .id = 26, .r = { .min = 0, .max = 105000000 }, },
143 { .n = "flex11_gclk", .id = 32, },
144 { .n = "flex12_gclk", .id = 33, },
145 { .n = "i2s_gclk", .id = 34, .r = { .min = 0, .max = 105000000 },
146 .pll = true, },
147 { .n = "pit64b_gclk", .id = 37, },
148 { .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 },
149 .pll = true, },
150 { .n = "tcb1_gclk", .id = 45, },
151 { .n = "dbgu_gclk", .id = 47, },
152};
153
154static void __init sam9x60_pmc_setup(struct device_node *np)
155{
156 struct clk_range range = CLK_RANGE(0, 0);
157 const char *td_slck_name, *md_slck_name, *mainxtal_name;
158 struct pmc_data *sam9x60_pmc;
159 const char *parent_names[6];
160 struct regmap *regmap;
161 struct clk_hw *hw;
162 int i;
163 bool bypass;
164
165 i = of_property_match_string(np, "clock-names", "td_slck");
166 if (i < 0)
167 return;
168
169 td_slck_name = of_clk_get_parent_name(np, i);
170
171 i = of_property_match_string(np, "clock-names", "md_slck");
172 if (i < 0)
173 return;
174
175 md_slck_name = of_clk_get_parent_name(np, i);
176
177 i = of_property_match_string(np, "clock-names", "main_xtal");
178 if (i < 0)
179 return;
180 mainxtal_name = of_clk_get_parent_name(np, i);
181
182 regmap = syscon_node_to_regmap(np);
183 if (IS_ERR(regmap))
184 return;
185
186 sam9x60_pmc = pmc_data_allocate(PMC_MAIN + 1,
187 nck(sam9x60_systemck),
188 nck(sam9x60_periphck),
189 nck(sam9x60_gck));
190 if (!sam9x60_pmc)
191 return;
192
193 hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 24000000,
194 50000000);
195 if (IS_ERR(hw))
196 goto err_free;
197
198 bypass = of_property_read_bool(np, "atmel,osc-bypass");
199
200 hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
201 bypass);
202 if (IS_ERR(hw))
203 goto err_free;
204
205 parent_names[0] = "main_rc_osc";
206 parent_names[1] = "main_osc";
207 hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2);
208 if (IS_ERR(hw))
209 goto err_free;
210
211 sam9x60_pmc->chws[PMC_MAIN] = hw;
212
213 hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "pllack",
214 "mainck", 0, &plla_characteristics);
215 if (IS_ERR(hw))
216 goto err_free;
217
218 hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "upllck",
219 "main_osc", 1, &upll_characteristics);
220 if (IS_ERR(hw))
221 goto err_free;
222
223 sam9x60_pmc->chws[PMC_UTMI] = hw;
224
225 parent_names[0] = md_slck_name;
226 parent_names[1] = "mainck";
227 parent_names[2] = "pllack";
228 hw = at91_clk_register_master(regmap, "masterck", 3, parent_names,
229 &sam9x60_master_layout,
230 &mck_characteristics);
231 if (IS_ERR(hw))
232 goto err_free;
233
234 sam9x60_pmc->chws[PMC_MCK] = hw;
235
236 parent_names[0] = "pllack";
237 parent_names[1] = "upllck";
238 parent_names[2] = "mainck";
239 parent_names[3] = "mainck";
240 hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 4);
241 if (IS_ERR(hw))
242 goto err_free;
243
244 parent_names[0] = md_slck_name;
245 parent_names[1] = td_slck_name;
246 parent_names[2] = "mainck";
247 parent_names[3] = "masterck";
248 parent_names[4] = "pllack";
249 parent_names[5] = "upllck";
250 for (i = 0; i < 8; i++) {
251 char name[6];
252
253 snprintf(name, sizeof(name), "prog%d", i);
254
255 hw = at91_clk_register_programmable(regmap, name,
256 parent_names, 6, i,
257 &sam9x60_programmable_layout);
258 if (IS_ERR(hw))
259 goto err_free;
260 }
261
262 for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) {
263 hw = at91_clk_register_system(regmap, sam9x60_systemck[i].n,
264 sam9x60_systemck[i].p,
265 sam9x60_systemck[i].id);
266 if (IS_ERR(hw))
267 goto err_free;
268
269 sam9x60_pmc->shws[sam9x60_systemck[i].id] = hw;
270 }
271
272 for (i = 0; i < ARRAY_SIZE(sam9x60_periphck); i++) {
273 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
274 &sam9x60_pcr_layout,
275 sam9x60_periphck[i].n,
276 "masterck",
277 sam9x60_periphck[i].id,
278 &range);
279 if (IS_ERR(hw))
280 goto err_free;
281
282 sam9x60_pmc->phws[sam9x60_periphck[i].id] = hw;
283 }
284
285 for (i = 0; i < ARRAY_SIZE(sam9x60_gck); i++) {
286 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
287 &sam9x60_pcr_layout,
288 sam9x60_gck[i].n,
289 parent_names, 6,
290 sam9x60_gck[i].id,
291 sam9x60_gck[i].pll,
292 &sam9x60_gck[i].r);
293 if (IS_ERR(hw))
294 goto err_free;
295
296 sam9x60_pmc->ghws[sam9x60_gck[i].id] = hw;
297 }
298
299 of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sam9x60_pmc);
300
301 return;
302
303err_free:
304 pmc_data_free(sam9x60_pmc);
305}
306/* Some clks are used for a clocksource */
307CLK_OF_DECLARE(sam9x60_pmc, "microchip,sam9x60-pmc", sam9x60_pmc_setup);
diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
index 81943fac4537..6509d0934804 100644
--- a/drivers/clk/at91/sama5d2.c
+++ b/drivers/clk/at91/sama5d2.c
@@ -16,7 +16,7 @@ static u8 plla_out[] = { 0 };
16 16
17static u16 plla_icpll[] = { 0 }; 17static u16 plla_icpll[] = { 0 };
18 18
19static struct clk_range plla_outputs[] = { 19static const struct clk_range plla_outputs[] = {
20 { .min = 600000000, .max = 1200000000 }, 20 { .min = 600000000, .max = 1200000000 },
21}; 21};
22 22
@@ -28,6 +28,13 @@ static const struct clk_pll_characteristics plla_characteristics = {
28 .out = plla_out, 28 .out = plla_out,
29}; 29};
30 30
31static const struct clk_pcr_layout sama5d2_pcr_layout = {
32 .offset = 0x10c,
33 .cmd = BIT(12),
34 .gckcss_mask = GENMASK(10, 8),
35 .pid_mask = GENMASK(6, 0),
36};
37
31static const struct { 38static const struct {
32 char *n; 39 char *n;
33 char *p; 40 char *p;
@@ -274,6 +281,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
274 281
275 for (i = 0; i < ARRAY_SIZE(sama5d2_periphck); i++) { 282 for (i = 0; i < ARRAY_SIZE(sama5d2_periphck); i++) {
276 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 283 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
284 &sama5d2_pcr_layout,
277 sama5d2_periphck[i].n, 285 sama5d2_periphck[i].n,
278 "masterck", 286 "masterck",
279 sama5d2_periphck[i].id, 287 sama5d2_periphck[i].id,
@@ -286,6 +294,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
286 294
287 for (i = 0; i < ARRAY_SIZE(sama5d2_periph32ck); i++) { 295 for (i = 0; i < ARRAY_SIZE(sama5d2_periph32ck); i++) {
288 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 296 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
297 &sama5d2_pcr_layout,
289 sama5d2_periph32ck[i].n, 298 sama5d2_periph32ck[i].n,
290 "h32mxck", 299 "h32mxck",
291 sama5d2_periph32ck[i].id, 300 sama5d2_periph32ck[i].id,
@@ -304,6 +313,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
304 parent_names[5] = "audiopll_pmcck"; 313 parent_names[5] = "audiopll_pmcck";
305 for (i = 0; i < ARRAY_SIZE(sama5d2_gck); i++) { 314 for (i = 0; i < ARRAY_SIZE(sama5d2_gck); i++) {
306 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, 315 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
316 &sama5d2_pcr_layout,
307 sama5d2_gck[i].n, 317 sama5d2_gck[i].n,
308 parent_names, 6, 318 parent_names, 6,
309 sama5d2_gck[i].id, 319 sama5d2_gck[i].id,
diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c
index b645a9d59cdb..25b156d4e645 100644
--- a/drivers/clk/at91/sama5d4.c
+++ b/drivers/clk/at91/sama5d4.c
@@ -16,7 +16,7 @@ static u8 plla_out[] = { 0 };
16 16
17static u16 plla_icpll[] = { 0 }; 17static u16 plla_icpll[] = { 0 };
18 18
19static struct clk_range plla_outputs[] = { 19static const struct clk_range plla_outputs[] = {
20 { .min = 600000000, .max = 1200000000 }, 20 { .min = 600000000, .max = 1200000000 },
21}; 21};
22 22
@@ -28,6 +28,12 @@ static const struct clk_pll_characteristics plla_characteristics = {
28 .out = plla_out, 28 .out = plla_out,
29}; 29};
30 30
31static const struct clk_pcr_layout sama5d4_pcr_layout = {
32 .offset = 0x10c,
33 .cmd = BIT(12),
34 .pid_mask = GENMASK(6, 0),
35};
36
31static const struct { 37static const struct {
32 char *n; 38 char *n;
33 char *p; 39 char *p;
@@ -232,6 +238,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
232 238
233 for (i = 0; i < ARRAY_SIZE(sama5d4_periphck); i++) { 239 for (i = 0; i < ARRAY_SIZE(sama5d4_periphck); i++) {
234 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 240 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
241 &sama5d4_pcr_layout,
235 sama5d4_periphck[i].n, 242 sama5d4_periphck[i].n,
236 "masterck", 243 "masterck",
237 sama5d4_periphck[i].id, 244 sama5d4_periphck[i].id,
@@ -244,6 +251,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
244 251
245 for (i = 0; i < ARRAY_SIZE(sama5d4_periph32ck); i++) { 252 for (i = 0; i < ARRAY_SIZE(sama5d4_periph32ck); i++) {
246 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 253 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
254 &sama5d4_pcr_layout,
247 sama5d4_periph32ck[i].n, 255 sama5d4_periph32ck[i].n,
248 "h32mxck", 256 "h32mxck",
249 sama5d4_periph32ck[i].id, 257 sama5d4_periph32ck[i].id,
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
index ab6ecefc49ad..e76b1d64e905 100644
--- a/drivers/clk/at91/sckc.c
+++ b/drivers/clk/at91/sckc.c
@@ -152,28 +152,6 @@ at91_clk_register_slow_osc(void __iomem *sckcr,
152 return hw; 152 return hw;
153} 153}
154 154
155static void __init
156of_at91sam9x5_clk_slow_osc_setup(struct device_node *np, void __iomem *sckcr)
157{
158 struct clk_hw *hw;
159 const char *parent_name;
160 const char *name = np->name;
161 u32 startup;
162 bool bypass;
163
164 parent_name = of_clk_get_parent_name(np, 0);
165 of_property_read_string(np, "clock-output-names", &name);
166 of_property_read_u32(np, "atmel,startup-time-usec", &startup);
167 bypass = of_property_read_bool(np, "atmel,osc-bypass");
168
169 hw = at91_clk_register_slow_osc(sckcr, name, parent_name, startup,
170 bypass);
171 if (IS_ERR(hw))
172 return;
173
174 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
175}
176
177static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw, 155static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
178 unsigned long parent_rate) 156 unsigned long parent_rate)
179{ 157{
@@ -266,28 +244,6 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr,
266 return hw; 244 return hw;
267} 245}
268 246
269static void __init
270of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np, void __iomem *sckcr)
271{
272 struct clk_hw *hw;
273 u32 frequency = 0;
274 u32 accuracy = 0;
275 u32 startup = 0;
276 const char *name = np->name;
277
278 of_property_read_string(np, "clock-output-names", &name);
279 of_property_read_u32(np, "clock-frequency", &frequency);
280 of_property_read_u32(np, "clock-accuracy", &accuracy);
281 of_property_read_u32(np, "atmel,startup-time-usec", &startup);
282
283 hw = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy,
284 startup);
285 if (IS_ERR(hw))
286 return;
287
288 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
289}
290
291static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) 247static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
292{ 248{
293 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 249 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
@@ -365,68 +321,72 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr,
365 return hw; 321 return hw;
366} 322}
367 323
368static void __init 324static void __init at91sam9x5_sckc_register(struct device_node *np,
369of_at91sam9x5_clk_slow_setup(struct device_node *np, void __iomem *sckcr) 325 unsigned int rc_osc_startup_us)
370{ 326{
327 const char *parent_names[2] = { "slow_rc_osc", "slow_osc" };
328 void __iomem *regbase = of_iomap(np, 0);
329 struct device_node *child = NULL;
330 const char *xtal_name;
371 struct clk_hw *hw; 331 struct clk_hw *hw;
372 const char *parent_names[2]; 332 bool bypass;
373 unsigned int num_parents;
374 const char *name = np->name;
375 333
376 num_parents = of_clk_get_parent_count(np); 334 if (!regbase)
377 if (num_parents == 0 || num_parents > 2) 335 return;
336
337 hw = at91_clk_register_slow_rc_osc(regbase, parent_names[0], 32768,
338 50000000, rc_osc_startup_us);
339 if (IS_ERR(hw))
378 return; 340 return;
379 341
380 of_clk_parent_fill(np, parent_names, num_parents); 342 xtal_name = of_clk_get_parent_name(np, 0);
343 if (!xtal_name) {
344 /* DT backward compatibility */
345 child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow-osc");
346 if (!child)
347 return;
348
349 xtal_name = of_clk_get_parent_name(child, 0);
350 bypass = of_property_read_bool(child, "atmel,osc-bypass");
351
352 child = of_get_compatible_child(np, "atmel,at91sam9x5-clk-slow");
353 } else {
354 bypass = of_property_read_bool(np, "atmel,osc-bypass");
355 }
356
357 if (!xtal_name)
358 return;
381 359
382 of_property_read_string(np, "clock-output-names", &name); 360 hw = at91_clk_register_slow_osc(regbase, parent_names[1], xtal_name,
361 1200000, bypass);
362 if (IS_ERR(hw))
363 return;
383 364
384 hw = at91_clk_register_sam9x5_slow(sckcr, name, parent_names, 365 hw = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, 2);
385 num_parents);
386 if (IS_ERR(hw)) 366 if (IS_ERR(hw))
387 return; 367 return;
388 368
389 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 369 of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
390}
391 370
392static const struct of_device_id sckc_clk_ids[] __initconst = { 371 /* DT backward compatibility */
393 /* Slow clock */ 372 if (child)
394 { 373 of_clk_add_hw_provider(child, of_clk_hw_simple_get, hw);
395 .compatible = "atmel,at91sam9x5-clk-slow-osc", 374}
396 .data = of_at91sam9x5_clk_slow_osc_setup,
397 },
398 {
399 .compatible = "atmel,at91sam9x5-clk-slow-rc-osc",
400 .data = of_at91sam9x5_clk_slow_rc_osc_setup,
401 },
402 {
403 .compatible = "atmel,at91sam9x5-clk-slow",
404 .data = of_at91sam9x5_clk_slow_setup,
405 },
406 { /*sentinel*/ }
407};
408 375
409static void __init of_at91sam9x5_sckc_setup(struct device_node *np) 376static void __init of_at91sam9x5_sckc_setup(struct device_node *np)
410{ 377{
411 struct device_node *childnp; 378 at91sam9x5_sckc_register(np, 75);
412 void (*clk_setup)(struct device_node *, void __iomem *);
413 const struct of_device_id *clk_id;
414 void __iomem *regbase = of_iomap(np, 0);
415
416 if (!regbase)
417 return;
418
419 for_each_child_of_node(np, childnp) {
420 clk_id = of_match_node(sckc_clk_ids, childnp);
421 if (!clk_id)
422 continue;
423 clk_setup = clk_id->data;
424 clk_setup(childnp, regbase);
425 }
426} 379}
427CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc", 380CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc",
428 of_at91sam9x5_sckc_setup); 381 of_at91sam9x5_sckc_setup);
429 382
383static void __init of_sama5d3_sckc_setup(struct device_node *np)
384{
385 at91sam9x5_sckc_register(np, 500);
386}
387CLK_OF_DECLARE(sama5d3_clk_sckc, "atmel,sama5d3-sckc",
388 of_sama5d3_sckc_setup);
389
430static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw) 390static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw)
431{ 391{
432 struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw); 392 struct clk_sama5d4_slow_osc *osc = to_clk_sama5d4_slow_osc(hw);
diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/clk-aspeed.c
index 596136793fc4..42b4df6ba249 100644
--- a/drivers/clk/clk-aspeed.c
+++ b/drivers/clk/clk-aspeed.c
@@ -87,10 +87,10 @@ struct aspeed_clk_gate {
87/* TODO: ask Aspeed about the actual parent data */ 87/* TODO: ask Aspeed about the actual parent data */
88static const struct aspeed_gate_data aspeed_gates[] = { 88static const struct aspeed_gate_data aspeed_gates[] = {
89 /* clk rst name parent flags */ 89 /* clk rst name parent flags */
90 [ASPEED_CLK_GATE_ECLK] = { 0, -1, "eclk-gate", "eclk", 0 }, /* Video Engine */ 90 [ASPEED_CLK_GATE_ECLK] = { 0, 6, "eclk-gate", "eclk", 0 }, /* Video Engine */
91 [ASPEED_CLK_GATE_GCLK] = { 1, 7, "gclk-gate", NULL, 0 }, /* 2D engine */ 91 [ASPEED_CLK_GATE_GCLK] = { 1, 7, "gclk-gate", NULL, 0 }, /* 2D engine */
92 [ASPEED_CLK_GATE_MCLK] = { 2, -1, "mclk-gate", "mpll", CLK_IS_CRITICAL }, /* SDRAM */ 92 [ASPEED_CLK_GATE_MCLK] = { 2, -1, "mclk-gate", "mpll", CLK_IS_CRITICAL }, /* SDRAM */
93 [ASPEED_CLK_GATE_VCLK] = { 3, 6, "vclk-gate", NULL, 0 }, /* Video Capture */ 93 [ASPEED_CLK_GATE_VCLK] = { 3, -1, "vclk-gate", NULL, 0 }, /* Video Capture */
94 [ASPEED_CLK_GATE_BCLK] = { 4, 8, "bclk-gate", "bclk", CLK_IS_CRITICAL }, /* PCIe/PCI */ 94 [ASPEED_CLK_GATE_BCLK] = { 4, 8, "bclk-gate", "bclk", CLK_IS_CRITICAL }, /* PCIe/PCI */
95 [ASPEED_CLK_GATE_DCLK] = { 5, -1, "dclk-gate", NULL, CLK_IS_CRITICAL }, /* DAC */ 95 [ASPEED_CLK_GATE_DCLK] = { 5, -1, "dclk-gate", NULL, CLK_IS_CRITICAL }, /* DAC */
96 [ASPEED_CLK_GATE_REFCLK] = { 6, -1, "refclk-gate", "clkin", CLK_IS_CRITICAL }, 96 [ASPEED_CLK_GATE_REFCLK] = { 6, -1, "refclk-gate", "clkin", CLK_IS_CRITICAL },
@@ -113,6 +113,24 @@ static const struct aspeed_gate_data aspeed_gates[] = {
113 [ASPEED_CLK_GATE_LHCCLK] = { 28, -1, "lhclk-gate", "lhclk", 0 }, /* LPC master/LPC+ */ 113 [ASPEED_CLK_GATE_LHCCLK] = { 28, -1, "lhclk-gate", "lhclk", 0 }, /* LPC master/LPC+ */
114}; 114};
115 115
116static const char * const eclk_parent_names[] = {
117 "mpll",
118 "hpll",
119 "dpll",
120};
121
122static const struct clk_div_table ast2500_eclk_div_table[] = {
123 { 0x0, 2 },
124 { 0x1, 2 },
125 { 0x2, 3 },
126 { 0x3, 4 },
127 { 0x4, 5 },
128 { 0x5, 6 },
129 { 0x6, 7 },
130 { 0x7, 8 },
131 { 0 }
132};
133
116static const struct clk_div_table ast2500_mac_div_table[] = { 134static const struct clk_div_table ast2500_mac_div_table[] = {
117 { 0x0, 4 }, /* Yep, really. Aspeed confirmed this is correct */ 135 { 0x0, 4 }, /* Yep, really. Aspeed confirmed this is correct */
118 { 0x1, 4 }, 136 { 0x1, 4 },
@@ -192,18 +210,21 @@ static struct clk_hw *aspeed_ast2500_calc_pll(const char *name, u32 val)
192 210
193struct aspeed_clk_soc_data { 211struct aspeed_clk_soc_data {
194 const struct clk_div_table *div_table; 212 const struct clk_div_table *div_table;
213 const struct clk_div_table *eclk_div_table;
195 const struct clk_div_table *mac_div_table; 214 const struct clk_div_table *mac_div_table;
196 struct clk_hw *(*calc_pll)(const char *name, u32 val); 215 struct clk_hw *(*calc_pll)(const char *name, u32 val);
197}; 216};
198 217
199static const struct aspeed_clk_soc_data ast2500_data = { 218static const struct aspeed_clk_soc_data ast2500_data = {
200 .div_table = ast2500_div_table, 219 .div_table = ast2500_div_table,
220 .eclk_div_table = ast2500_eclk_div_table,
201 .mac_div_table = ast2500_mac_div_table, 221 .mac_div_table = ast2500_mac_div_table,
202 .calc_pll = aspeed_ast2500_calc_pll, 222 .calc_pll = aspeed_ast2500_calc_pll,
203}; 223};
204 224
205static const struct aspeed_clk_soc_data ast2400_data = { 225static const struct aspeed_clk_soc_data ast2400_data = {
206 .div_table = ast2400_div_table, 226 .div_table = ast2400_div_table,
227 .eclk_div_table = ast2400_div_table,
207 .mac_div_table = ast2400_div_table, 228 .mac_div_table = ast2400_div_table,
208 .calc_pll = aspeed_ast2400_calc_pll, 229 .calc_pll = aspeed_ast2400_calc_pll,
209}; 230};
@@ -522,6 +543,22 @@ static int aspeed_clk_probe(struct platform_device *pdev)
522 return PTR_ERR(hw); 543 return PTR_ERR(hw);
523 aspeed_clk_data->hws[ASPEED_CLK_24M] = hw; 544 aspeed_clk_data->hws[ASPEED_CLK_24M] = hw;
524 545
546 hw = clk_hw_register_mux(dev, "eclk-mux", eclk_parent_names,
547 ARRAY_SIZE(eclk_parent_names), 0,
548 scu_base + ASPEED_CLK_SELECTION, 2, 0x3, 0,
549 &aspeed_clk_lock);
550 if (IS_ERR(hw))
551 return PTR_ERR(hw);
552 aspeed_clk_data->hws[ASPEED_CLK_ECLK_MUX] = hw;
553
554 hw = clk_hw_register_divider_table(dev, "eclk", "eclk-mux", 0,
555 scu_base + ASPEED_CLK_SELECTION, 28,
556 3, 0, soc_data->eclk_div_table,
557 &aspeed_clk_lock);
558 if (IS_ERR(hw))
559 return PTR_ERR(hw);
560 aspeed_clk_data->hws[ASPEED_CLK_ECLK] = hw;
561
525 /* 562 /*
526 * TODO: There are a number of clocks that not included in this driver 563 * TODO: There are a number of clocks that not included in this driver
527 * as more information is required: 564 * as more information is required:
@@ -531,7 +568,6 @@ static int aspeed_clk_probe(struct platform_device *pdev)
531 * RGMII 568 * RGMII
532 * RMII 569 * RMII
533 * UART[1..5] clock source mux 570 * UART[1..5] clock source mux
534 * Video Engine (ECLK) mux and clock divider
535 */ 571 */
536 572
537 for (i = 0; i < ARRAY_SIZE(aspeed_gates); i++) { 573 for (i = 0; i < ARRAY_SIZE(aspeed_gates); i++) {
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 46604214bba0..b06038b8f658 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -218,7 +218,7 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
218 return ERR_PTR(-ENOMEM); 218 return ERR_PTR(-ENOMEM);
219 219
220 init.name = name; 220 init.name = name;
221 init.flags = flags | CLK_IS_BASIC; 221 init.flags = flags;
222 init.parent_names = parent_names; 222 init.parent_names = parent_names;
223 init.num_parents = num_parents; 223 init.num_parents = num_parents;
224 hw = &composite->hw; 224 hw = &composite->hw;
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index e5a17265cfaf..3f9ff78c4a2a 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -25,6 +25,22 @@
25 * parent - fixed parent. No clk_set_parent support 25 * parent - fixed parent. No clk_set_parent support
26 */ 26 */
27 27
28static inline u32 clk_div_readl(struct clk_divider *divider)
29{
30 if (divider->flags & CLK_DIVIDER_BIG_ENDIAN)
31 return ioread32be(divider->reg);
32
33 return readl(divider->reg);
34}
35
36static inline void clk_div_writel(struct clk_divider *divider, u32 val)
37{
38 if (divider->flags & CLK_DIVIDER_BIG_ENDIAN)
39 iowrite32be(val, divider->reg);
40 else
41 writel(val, divider->reg);
42}
43
28static unsigned int _get_table_maxdiv(const struct clk_div_table *table, 44static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
29 u8 width) 45 u8 width)
30{ 46{
@@ -135,7 +151,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
135 struct clk_divider *divider = to_clk_divider(hw); 151 struct clk_divider *divider = to_clk_divider(hw);
136 unsigned int val; 152 unsigned int val;
137 153
138 val = clk_readl(divider->reg) >> divider->shift; 154 val = clk_div_readl(divider) >> divider->shift;
139 val &= clk_div_mask(divider->width); 155 val &= clk_div_mask(divider->width);
140 156
141 return divider_recalc_rate(hw, parent_rate, val, divider->table, 157 return divider_recalc_rate(hw, parent_rate, val, divider->table,
@@ -370,7 +386,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
370 if (divider->flags & CLK_DIVIDER_READ_ONLY) { 386 if (divider->flags & CLK_DIVIDER_READ_ONLY) {
371 u32 val; 387 u32 val;
372 388
373 val = clk_readl(divider->reg) >> divider->shift; 389 val = clk_div_readl(divider) >> divider->shift;
374 val &= clk_div_mask(divider->width); 390 val &= clk_div_mask(divider->width);
375 391
376 return divider_ro_round_rate(hw, rate, prate, divider->table, 392 return divider_ro_round_rate(hw, rate, prate, divider->table,
@@ -420,11 +436,11 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
420 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { 436 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
421 val = clk_div_mask(divider->width) << (divider->shift + 16); 437 val = clk_div_mask(divider->width) << (divider->shift + 16);
422 } else { 438 } else {
423 val = clk_readl(divider->reg); 439 val = clk_div_readl(divider);
424 val &= ~(clk_div_mask(divider->width) << divider->shift); 440 val &= ~(clk_div_mask(divider->width) << divider->shift);
425 } 441 }
426 val |= (u32)value << divider->shift; 442 val |= (u32)value << divider->shift;
427 clk_writel(val, divider->reg); 443 clk_div_writel(divider, val);
428 444
429 if (divider->lock) 445 if (divider->lock)
430 spin_unlock_irqrestore(divider->lock, flags); 446 spin_unlock_irqrestore(divider->lock, flags);
@@ -475,7 +491,7 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name,
475 init.ops = &clk_divider_ro_ops; 491 init.ops = &clk_divider_ro_ops;
476 else 492 else
477 init.ops = &clk_divider_ops; 493 init.ops = &clk_divider_ops;
478 init.flags = flags | CLK_IS_BASIC; 494 init.flags = flags;
479 init.parent_names = (parent_name ? &parent_name: NULL); 495 init.parent_names = (parent_name ? &parent_name: NULL);
480 init.num_parents = (parent_name ? 1 : 0); 496 init.num_parents = (parent_name ? 1 : 0);
481 497
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index 241b3f8c61a9..8b343e59dc61 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -64,12 +64,14 @@ const struct clk_ops clk_fixed_factor_ops = {
64}; 64};
65EXPORT_SYMBOL_GPL(clk_fixed_factor_ops); 65EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
66 66
67struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, 67static struct clk_hw *
68 const char *name, const char *parent_name, unsigned long flags, 68__clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
69 unsigned int mult, unsigned int div) 69 const char *name, const char *parent_name, int index,
70 unsigned long flags, unsigned int mult, unsigned int div)
70{ 71{
71 struct clk_fixed_factor *fix; 72 struct clk_fixed_factor *fix;
72 struct clk_init_data init; 73 struct clk_init_data init = { };
74 struct clk_parent_data pdata = { .index = index };
73 struct clk_hw *hw; 75 struct clk_hw *hw;
74 int ret; 76 int ret;
75 77
@@ -84,12 +86,18 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
84 86
85 init.name = name; 87 init.name = name;
86 init.ops = &clk_fixed_factor_ops; 88 init.ops = &clk_fixed_factor_ops;
87 init.flags = flags | CLK_IS_BASIC; 89 init.flags = flags;
88 init.parent_names = &parent_name; 90 if (parent_name)
91 init.parent_names = &parent_name;
92 else
93 init.parent_data = &pdata;
89 init.num_parents = 1; 94 init.num_parents = 1;
90 95
91 hw = &fix->hw; 96 hw = &fix->hw;
92 ret = clk_hw_register(dev, hw); 97 if (dev)
98 ret = clk_hw_register(dev, hw);
99 else
100 ret = of_clk_hw_register(np, hw);
93 if (ret) { 101 if (ret) {
94 kfree(fix); 102 kfree(fix);
95 hw = ERR_PTR(ret); 103 hw = ERR_PTR(ret);
@@ -97,6 +105,14 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
97 105
98 return hw; 106 return hw;
99} 107}
108
109struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
110 const char *name, const char *parent_name, unsigned long flags,
111 unsigned int mult, unsigned int div)
112{
113 return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
114 flags, mult, div);
115}
100EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor); 116EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
101 117
102struct clk *clk_register_fixed_factor(struct device *dev, const char *name, 118struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
@@ -143,11 +159,10 @@ static const struct of_device_id set_rate_parent_matches[] = {
143 { /* Sentinel */ }, 159 { /* Sentinel */ },
144}; 160};
145 161
146static struct clk *_of_fixed_factor_clk_setup(struct device_node *node) 162static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
147{ 163{
148 struct clk *clk; 164 struct clk_hw *hw;
149 const char *clk_name = node->name; 165 const char *clk_name = node->name;
150 const char *parent_name;
151 unsigned long flags = 0; 166 unsigned long flags = 0;
152 u32 div, mult; 167 u32 div, mult;
153 int ret; 168 int ret;
@@ -165,30 +180,28 @@ static struct clk *_of_fixed_factor_clk_setup(struct device_node *node)
165 } 180 }
166 181
167 of_property_read_string(node, "clock-output-names", &clk_name); 182 of_property_read_string(node, "clock-output-names", &clk_name);
168 parent_name = of_clk_get_parent_name(node, 0);
169 183
170 if (of_match_node(set_rate_parent_matches, node)) 184 if (of_match_node(set_rate_parent_matches, node))
171 flags |= CLK_SET_RATE_PARENT; 185 flags |= CLK_SET_RATE_PARENT;
172 186
173 clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags, 187 hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0,
174 mult, div); 188 flags, mult, div);
175 if (IS_ERR(clk)) { 189 if (IS_ERR(hw)) {
176 /* 190 /*
177 * If parent clock is not registered, registration would fail.
178 * Clear OF_POPULATED flag so that clock registration can be 191 * Clear OF_POPULATED flag so that clock registration can be
179 * attempted again from probe function. 192 * attempted again from probe function.
180 */ 193 */
181 of_node_clear_flag(node, OF_POPULATED); 194 of_node_clear_flag(node, OF_POPULATED);
182 return clk; 195 return ERR_CAST(hw);
183 } 196 }
184 197
185 ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); 198 ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
186 if (ret) { 199 if (ret) {
187 clk_unregister(clk); 200 clk_hw_unregister_fixed_factor(hw);
188 return ERR_PTR(ret); 201 return ERR_PTR(ret);
189 } 202 }
190 203
191 return clk; 204 return hw;
192} 205}
193 206
194/** 207/**
@@ -203,17 +216,17 @@ CLK_OF_DECLARE(fixed_factor_clk, "fixed-factor-clock",
203 216
204static int of_fixed_factor_clk_remove(struct platform_device *pdev) 217static int of_fixed_factor_clk_remove(struct platform_device *pdev)
205{ 218{
206 struct clk *clk = platform_get_drvdata(pdev); 219 struct clk_hw *clk = platform_get_drvdata(pdev);
207 220
208 of_clk_del_provider(pdev->dev.of_node); 221 of_clk_del_provider(pdev->dev.of_node);
209 clk_unregister_fixed_factor(clk); 222 clk_hw_unregister_fixed_factor(clk);
210 223
211 return 0; 224 return 0;
212} 225}
213 226
214static int of_fixed_factor_clk_probe(struct platform_device *pdev) 227static int of_fixed_factor_clk_probe(struct platform_device *pdev)
215{ 228{
216 struct clk *clk; 229 struct clk_hw *clk;
217 230
218 /* 231 /*
219 * This function is not executed when of_fixed_factor_clk_setup 232 * This function is not executed when of_fixed_factor_clk_setup
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index 00ef4f5e53fe..a7e4aef7a376 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -68,7 +68,7 @@ struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
68 68
69 init.name = name; 69 init.name = name;
70 init.ops = &clk_fixed_rate_ops; 70 init.ops = &clk_fixed_rate_ops;
71 init.flags = flags | CLK_IS_BASIC; 71 init.flags = flags;
72 init.parent_names = (parent_name ? &parent_name: NULL); 72 init.parent_names = (parent_name ? &parent_name: NULL);
73 init.num_parents = (parent_name ? 1 : 0); 73 init.num_parents = (parent_name ? 1 : 0);
74 74
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index fdfe2e423d15..d81f1d2e9129 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -13,6 +13,22 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/rational.h> 14#include <linux/rational.h>
15 15
16static inline u32 clk_fd_readl(struct clk_fractional_divider *fd)
17{
18 if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
19 return ioread32be(fd->reg);
20
21 return readl(fd->reg);
22}
23
24static inline void clk_fd_writel(struct clk_fractional_divider *fd, u32 val)
25{
26 if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
27 iowrite32be(val, fd->reg);
28 else
29 writel(val, fd->reg);
30}
31
16static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, 32static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
17 unsigned long parent_rate) 33 unsigned long parent_rate)
18{ 34{
@@ -27,7 +43,7 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
27 else 43 else
28 __acquire(fd->lock); 44 __acquire(fd->lock);
29 45
30 val = clk_readl(fd->reg); 46 val = clk_fd_readl(fd);
31 47
32 if (fd->lock) 48 if (fd->lock)
33 spin_unlock_irqrestore(fd->lock, flags); 49 spin_unlock_irqrestore(fd->lock, flags);
@@ -115,10 +131,10 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
115 else 131 else
116 __acquire(fd->lock); 132 __acquire(fd->lock);
117 133
118 val = clk_readl(fd->reg); 134 val = clk_fd_readl(fd);
119 val &= ~(fd->mmask | fd->nmask); 135 val &= ~(fd->mmask | fd->nmask);
120 val |= (m << fd->mshift) | (n << fd->nshift); 136 val |= (m << fd->mshift) | (n << fd->nshift);
121 clk_writel(val, fd->reg); 137 clk_fd_writel(fd, val);
122 138
123 if (fd->lock) 139 if (fd->lock)
124 spin_unlock_irqrestore(fd->lock, flags); 140 spin_unlock_irqrestore(fd->lock, flags);
@@ -151,7 +167,7 @@ struct clk_hw *clk_hw_register_fractional_divider(struct device *dev,
151 167
152 init.name = name; 168 init.name = name;
153 init.ops = &clk_fractional_divider_ops; 169 init.ops = &clk_fractional_divider_ops;
154 init.flags = flags | CLK_IS_BASIC; 170 init.flags = flags;
155 init.parent_names = parent_name ? &parent_name : NULL; 171 init.parent_names = parent_name ? &parent_name : NULL;
156 init.num_parents = parent_name ? 1 : 0; 172 init.num_parents = parent_name ? 1 : 0;
157 173
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index f05823cd9b21..1b99fc962745 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -23,6 +23,22 @@
23 * parent - fixed parent. No clk_set_parent support 23 * parent - fixed parent. No clk_set_parent support
24 */ 24 */
25 25
26static inline u32 clk_gate_readl(struct clk_gate *gate)
27{
28 if (gate->flags & CLK_GATE_BIG_ENDIAN)
29 return ioread32be(gate->reg);
30
31 return readl(gate->reg);
32}
33
34static inline void clk_gate_writel(struct clk_gate *gate, u32 val)
35{
36 if (gate->flags & CLK_GATE_BIG_ENDIAN)
37 iowrite32be(val, gate->reg);
38 else
39 writel(val, gate->reg);
40}
41
26/* 42/*
27 * It works on following logic: 43 * It works on following logic:
28 * 44 *
@@ -55,7 +71,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
55 if (set) 71 if (set)
56 reg |= BIT(gate->bit_idx); 72 reg |= BIT(gate->bit_idx);
57 } else { 73 } else {
58 reg = clk_readl(gate->reg); 74 reg = clk_gate_readl(gate);
59 75
60 if (set) 76 if (set)
61 reg |= BIT(gate->bit_idx); 77 reg |= BIT(gate->bit_idx);
@@ -63,7 +79,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
63 reg &= ~BIT(gate->bit_idx); 79 reg &= ~BIT(gate->bit_idx);
64 } 80 }
65 81
66 clk_writel(reg, gate->reg); 82 clk_gate_writel(gate, reg);
67 83
68 if (gate->lock) 84 if (gate->lock)
69 spin_unlock_irqrestore(gate->lock, flags); 85 spin_unlock_irqrestore(gate->lock, flags);
@@ -88,7 +104,7 @@ int clk_gate_is_enabled(struct clk_hw *hw)
88 u32 reg; 104 u32 reg;
89 struct clk_gate *gate = to_clk_gate(hw); 105 struct clk_gate *gate = to_clk_gate(hw);
90 106
91 reg = clk_readl(gate->reg); 107 reg = clk_gate_readl(gate);
92 108
93 /* if a set bit disables this clk, flip it before masking */ 109 /* if a set bit disables this clk, flip it before masking */
94 if (gate->flags & CLK_GATE_SET_TO_DISABLE) 110 if (gate->flags & CLK_GATE_SET_TO_DISABLE)
@@ -142,7 +158,7 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
142 158
143 init.name = name; 159 init.name = name;
144 init.ops = &clk_gate_ops; 160 init.ops = &clk_gate_ops;
145 init.flags = flags | CLK_IS_BASIC; 161 init.flags = flags;
146 init.parent_names = parent_name ? &parent_name : NULL; 162 init.parent_names = parent_name ? &parent_name : NULL;
147 init.num_parents = parent_name ? 1 : 0; 163 init.num_parents = parent_name ? 1 : 0;
148 164
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index c2f07f0d077c..9d930edd6516 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -137,7 +137,7 @@ static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
137 137
138 init.name = name; 138 init.name = name;
139 init.ops = clk_gpio_ops; 139 init.ops = clk_gpio_ops;
140 init.flags = flags | CLK_IS_BASIC; 140 init.flags = flags;
141 init.parent_names = parent_names; 141 init.parent_names = parent_names;
142 init.num_parents = num_parents; 142 init.num_parents = num_parents;
143 143
diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c
index 8e4581004695..bd328b0eb243 100644
--- a/drivers/clk/clk-highbank.c
+++ b/drivers/clk/clk-highbank.c
@@ -17,7 +17,6 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/clk.h>
21#include <linux/clk-provider.h> 20#include <linux/clk-provider.h>
22#include <linux/io.h> 21#include <linux/io.h>
23#include <linux/of.h> 22#include <linux/of.h>
@@ -272,7 +271,7 @@ static const struct clk_ops periclk_ops = {
272 .set_rate = clk_periclk_set_rate, 271 .set_rate = clk_periclk_set_rate,
273}; 272};
274 273
275static __init struct clk *hb_clk_init(struct device_node *node, const struct clk_ops *ops) 274static void __init hb_clk_init(struct device_node *node, const struct clk_ops *ops, unsigned long clkflags)
276{ 275{
277 u32 reg; 276 u32 reg;
278 struct hb_clk *hb_clk; 277 struct hb_clk *hb_clk;
@@ -284,11 +283,11 @@ static __init struct clk *hb_clk_init(struct device_node *node, const struct clk
284 283
285 rc = of_property_read_u32(node, "reg", &reg); 284 rc = of_property_read_u32(node, "reg", &reg);
286 if (WARN_ON(rc)) 285 if (WARN_ON(rc))
287 return NULL; 286 return;
288 287
289 hb_clk = kzalloc(sizeof(*hb_clk), GFP_KERNEL); 288 hb_clk = kzalloc(sizeof(*hb_clk), GFP_KERNEL);
290 if (WARN_ON(!hb_clk)) 289 if (WARN_ON(!hb_clk))
291 return NULL; 290 return;
292 291
293 /* Map system registers */ 292 /* Map system registers */
294 srnp = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs"); 293 srnp = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs");
@@ -301,7 +300,7 @@ static __init struct clk *hb_clk_init(struct device_node *node, const struct clk
301 300
302 init.name = clk_name; 301 init.name = clk_name;
303 init.ops = ops; 302 init.ops = ops;
304 init.flags = 0; 303 init.flags = clkflags;
305 parent_name = of_clk_get_parent_name(node, 0); 304 parent_name = of_clk_get_parent_name(node, 0);
306 init.parent_names = &parent_name; 305 init.parent_names = &parent_name;
307 init.num_parents = 1; 306 init.num_parents = 1;
@@ -311,33 +310,31 @@ static __init struct clk *hb_clk_init(struct device_node *node, const struct clk
311 rc = clk_hw_register(NULL, &hb_clk->hw); 310 rc = clk_hw_register(NULL, &hb_clk->hw);
312 if (WARN_ON(rc)) { 311 if (WARN_ON(rc)) {
313 kfree(hb_clk); 312 kfree(hb_clk);
314 return NULL; 313 return;
315 } 314 }
316 rc = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &hb_clk->hw); 315 of_clk_add_hw_provider(node, of_clk_hw_simple_get, &hb_clk->hw);
317 return hb_clk->hw.clk;
318} 316}
319 317
320static void __init hb_pll_init(struct device_node *node) 318static void __init hb_pll_init(struct device_node *node)
321{ 319{
322 hb_clk_init(node, &clk_pll_ops); 320 hb_clk_init(node, &clk_pll_ops, 0);
323} 321}
324CLK_OF_DECLARE(hb_pll, "calxeda,hb-pll-clock", hb_pll_init); 322CLK_OF_DECLARE(hb_pll, "calxeda,hb-pll-clock", hb_pll_init);
325 323
326static void __init hb_a9periph_init(struct device_node *node) 324static void __init hb_a9periph_init(struct device_node *node)
327{ 325{
328 hb_clk_init(node, &a9periphclk_ops); 326 hb_clk_init(node, &a9periphclk_ops, 0);
329} 327}
330CLK_OF_DECLARE(hb_a9periph, "calxeda,hb-a9periph-clock", hb_a9periph_init); 328CLK_OF_DECLARE(hb_a9periph, "calxeda,hb-a9periph-clock", hb_a9periph_init);
331 329
332static void __init hb_a9bus_init(struct device_node *node) 330static void __init hb_a9bus_init(struct device_node *node)
333{ 331{
334 struct clk *clk = hb_clk_init(node, &a9bclk_ops); 332 hb_clk_init(node, &a9bclk_ops, CLK_IS_CRITICAL);
335 clk_prepare_enable(clk);
336} 333}
337CLK_OF_DECLARE(hb_a9bus, "calxeda,hb-a9bus-clock", hb_a9bus_init); 334CLK_OF_DECLARE(hb_a9bus, "calxeda,hb-a9bus-clock", hb_a9bus_init);
338 335
339static void __init hb_emmc_init(struct device_node *node) 336static void __init hb_emmc_init(struct device_node *node)
340{ 337{
341 hb_clk_init(node, &periclk_ops); 338 hb_clk_init(node, &periclk_ops, 0);
342} 339}
343CLK_OF_DECLARE(hb_emmc, "calxeda,hb-emmc-clock", hb_emmc_init); 340CLK_OF_DECLARE(hb_emmc, "calxeda,hb-emmc-clock", hb_emmc_init);
diff --git a/drivers/clk/clk-lochnagar.c b/drivers/clk/clk-lochnagar.c
new file mode 100644
index 000000000000..a2f31e58ee48
--- /dev/null
+++ b/drivers/clk/clk-lochnagar.c
@@ -0,0 +1,336 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Lochnagar clock control
4 *
5 * Copyright (c) 2017-2018 Cirrus Logic, Inc. and
6 * Cirrus Logic International Semiconductor Ltd.
7 *
8 * Author: Charles Keepax <ckeepax@opensource.cirrus.com>
9 */
10
11#include <linux/clk-provider.h>
12#include <linux/device.h>
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/of_device.h>
16#include <linux/platform_device.h>
17#include <linux/regmap.h>
18
19#include <linux/mfd/lochnagar.h>
20#include <linux/mfd/lochnagar1_regs.h>
21#include <linux/mfd/lochnagar2_regs.h>
22
23#include <dt-bindings/clk/lochnagar.h>
24
25#define LOCHNAGAR_NUM_CLOCKS (LOCHNAGAR_SPDIF_CLKOUT + 1)
26
27struct lochnagar_clk {
28 const char * const name;
29 struct clk_hw hw;
30
31 struct lochnagar_clk_priv *priv;
32
33 u16 cfg_reg;
34 u16 ena_mask;
35
36 u16 src_reg;
37 u16 src_mask;
38};
39
40struct lochnagar_clk_priv {
41 struct device *dev;
42 struct regmap *regmap;
43 enum lochnagar_type type;
44
45 const char **parents;
46 unsigned int nparents;
47
48 struct lochnagar_clk lclks[LOCHNAGAR_NUM_CLOCKS];
49};
50
51static const char * const lochnagar1_clk_parents[] = {
52 "ln-none",
53 "ln-spdif-mclk",
54 "ln-psia1-mclk",
55 "ln-psia2-mclk",
56 "ln-cdc-clkout",
57 "ln-dsp-clkout",
58 "ln-pmic-32k",
59 "ln-gf-mclk1",
60 "ln-gf-mclk3",
61 "ln-gf-mclk2",
62 "ln-gf-mclk4",
63};
64
65static const char * const lochnagar2_clk_parents[] = {
66 "ln-none",
67 "ln-cdc-clkout",
68 "ln-dsp-clkout",
69 "ln-pmic-32k",
70 "ln-spdif-mclk",
71 "ln-clk-12m",
72 "ln-clk-11m",
73 "ln-clk-24m",
74 "ln-clk-22m",
75 "ln-clk-8m",
76 "ln-usb-clk-24m",
77 "ln-gf-mclk1",
78 "ln-gf-mclk3",
79 "ln-gf-mclk2",
80 "ln-psia1-mclk",
81 "ln-psia2-mclk",
82 "ln-spdif-clkout",
83 "ln-adat-mclk",
84 "ln-usb-clk-12m",
85};
86
87#define LN1_CLK(ID, NAME, REG) \
88 [LOCHNAGAR_##ID] = { \
89 .name = NAME, \
90 .cfg_reg = LOCHNAGAR1_##REG, \
91 .ena_mask = LOCHNAGAR1_##ID##_ENA_MASK, \
92 .src_reg = LOCHNAGAR1_##ID##_SEL, \
93 .src_mask = LOCHNAGAR1_SRC_MASK, \
94 }
95
96#define LN2_CLK(ID, NAME) \
97 [LOCHNAGAR_##ID] = { \
98 .name = NAME, \
99 .cfg_reg = LOCHNAGAR2_##ID##_CTRL, \
100 .src_reg = LOCHNAGAR2_##ID##_CTRL, \
101 .ena_mask = LOCHNAGAR2_CLK_ENA_MASK, \
102 .src_mask = LOCHNAGAR2_CLK_SRC_MASK, \
103 }
104
105static const struct lochnagar_clk lochnagar1_clks[LOCHNAGAR_NUM_CLOCKS] = {
106 LN1_CLK(CDC_MCLK1, "ln-cdc-mclk1", CDC_AIF_CTRL2),
107 LN1_CLK(CDC_MCLK2, "ln-cdc-mclk2", CDC_AIF_CTRL2),
108 LN1_CLK(DSP_CLKIN, "ln-dsp-clkin", DSP_AIF),
109 LN1_CLK(GF_CLKOUT1, "ln-gf-clkout1", GF_AIF1),
110};
111
112static const struct lochnagar_clk lochnagar2_clks[LOCHNAGAR_NUM_CLOCKS] = {
113 LN2_CLK(CDC_MCLK1, "ln-cdc-mclk1"),
114 LN2_CLK(CDC_MCLK2, "ln-cdc-mclk2"),
115 LN2_CLK(DSP_CLKIN, "ln-dsp-clkin"),
116 LN2_CLK(GF_CLKOUT1, "ln-gf-clkout1"),
117 LN2_CLK(GF_CLKOUT2, "ln-gf-clkout2"),
118 LN2_CLK(PSIA1_MCLK, "ln-psia1-mclk"),
119 LN2_CLK(PSIA2_MCLK, "ln-psia2-mclk"),
120 LN2_CLK(SPDIF_MCLK, "ln-spdif-mclk"),
121 LN2_CLK(ADAT_MCLK, "ln-adat-mclk"),
122 LN2_CLK(SOUNDCARD_MCLK, "ln-soundcard-mclk"),
123};
124
125static inline struct lochnagar_clk *lochnagar_hw_to_lclk(struct clk_hw *hw)
126{
127 return container_of(hw, struct lochnagar_clk, hw);
128}
129
130static int lochnagar_clk_prepare(struct clk_hw *hw)
131{
132 struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
133 struct lochnagar_clk_priv *priv = lclk->priv;
134 struct regmap *regmap = priv->regmap;
135 int ret;
136
137 ret = regmap_update_bits(regmap, lclk->cfg_reg,
138 lclk->ena_mask, lclk->ena_mask);
139 if (ret < 0)
140 dev_dbg(priv->dev, "Failed to prepare %s: %d\n",
141 lclk->name, ret);
142
143 return ret;
144}
145
146static void lochnagar_clk_unprepare(struct clk_hw *hw)
147{
148 struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
149 struct lochnagar_clk_priv *priv = lclk->priv;
150 struct regmap *regmap = priv->regmap;
151 int ret;
152
153 ret = regmap_update_bits(regmap, lclk->cfg_reg, lclk->ena_mask, 0);
154 if (ret < 0)
155 dev_dbg(priv->dev, "Failed to unprepare %s: %d\n",
156 lclk->name, ret);
157}
158
159static int lochnagar_clk_set_parent(struct clk_hw *hw, u8 index)
160{
161 struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
162 struct lochnagar_clk_priv *priv = lclk->priv;
163 struct regmap *regmap = priv->regmap;
164 int ret;
165
166 ret = regmap_update_bits(regmap, lclk->src_reg, lclk->src_mask, index);
167 if (ret < 0)
168 dev_dbg(priv->dev, "Failed to reparent %s: %d\n",
169 lclk->name, ret);
170
171 return ret;
172}
173
174static u8 lochnagar_clk_get_parent(struct clk_hw *hw)
175{
176 struct lochnagar_clk *lclk = lochnagar_hw_to_lclk(hw);
177 struct lochnagar_clk_priv *priv = lclk->priv;
178 struct regmap *regmap = priv->regmap;
179 unsigned int val;
180 int ret;
181
182 ret = regmap_read(regmap, lclk->src_reg, &val);
183 if (ret < 0) {
184 dev_dbg(priv->dev, "Failed to read parent of %s: %d\n",
185 lclk->name, ret);
186 return priv->nparents;
187 }
188
189 val &= lclk->src_mask;
190
191 return val;
192}
193
194static const struct clk_ops lochnagar_clk_ops = {
195 .prepare = lochnagar_clk_prepare,
196 .unprepare = lochnagar_clk_unprepare,
197 .set_parent = lochnagar_clk_set_parent,
198 .get_parent = lochnagar_clk_get_parent,
199};
200
201static int lochnagar_init_parents(struct lochnagar_clk_priv *priv)
202{
203 struct device_node *np = priv->dev->of_node;
204 int i, j;
205
206 switch (priv->type) {
207 case LOCHNAGAR1:
208 memcpy(priv->lclks, lochnagar1_clks, sizeof(lochnagar1_clks));
209
210 priv->nparents = ARRAY_SIZE(lochnagar1_clk_parents);
211 priv->parents = devm_kmemdup(priv->dev, lochnagar1_clk_parents,
212 sizeof(lochnagar1_clk_parents),
213 GFP_KERNEL);
214 break;
215 case LOCHNAGAR2:
216 memcpy(priv->lclks, lochnagar2_clks, sizeof(lochnagar2_clks));
217
218 priv->nparents = ARRAY_SIZE(lochnagar2_clk_parents);
219 priv->parents = devm_kmemdup(priv->dev, lochnagar2_clk_parents,
220 sizeof(lochnagar2_clk_parents),
221 GFP_KERNEL);
222 break;
223 default:
224 dev_err(priv->dev, "Unknown Lochnagar type: %d\n", priv->type);
225 return -EINVAL;
226 }
227
228 if (!priv->parents)
229 return -ENOMEM;
230
231 for (i = 0; i < priv->nparents; i++) {
232 j = of_property_match_string(np, "clock-names",
233 priv->parents[i]);
234 if (j >= 0)
235 priv->parents[i] = of_clk_get_parent_name(np, j);
236 }
237
238 return 0;
239}
240
241static struct clk_hw *
242lochnagar_of_clk_hw_get(struct of_phandle_args *clkspec, void *data)
243{
244 struct lochnagar_clk_priv *priv = data;
245 unsigned int idx = clkspec->args[0];
246
247 if (idx >= ARRAY_SIZE(priv->lclks)) {
248 dev_err(priv->dev, "Invalid index %u\n", idx);
249 return ERR_PTR(-EINVAL);
250 }
251
252 return &priv->lclks[idx].hw;
253}
254
255static int lochnagar_init_clks(struct lochnagar_clk_priv *priv)
256{
257 struct clk_init_data clk_init = {
258 .ops = &lochnagar_clk_ops,
259 .parent_names = priv->parents,
260 .num_parents = priv->nparents,
261 };
262 struct lochnagar_clk *lclk;
263 int ret, i;
264
265 for (i = 0; i < ARRAY_SIZE(priv->lclks); i++) {
266 lclk = &priv->lclks[i];
267
268 if (!lclk->name)
269 continue;
270
271 clk_init.name = lclk->name;
272
273 lclk->priv = priv;
274 lclk->hw.init = &clk_init;
275
276 ret = devm_clk_hw_register(priv->dev, &lclk->hw);
277 if (ret) {
278 dev_err(priv->dev, "Failed to register %s: %d\n",
279 lclk->name, ret);
280 return ret;
281 }
282 }
283
284 ret = devm_of_clk_add_hw_provider(priv->dev, lochnagar_of_clk_hw_get,
285 priv);
286 if (ret < 0)
287 dev_err(priv->dev, "Failed to register provider: %d\n", ret);
288
289 return ret;
290}
291
292static const struct of_device_id lochnagar_of_match[] = {
293 { .compatible = "cirrus,lochnagar1-clk", .data = (void *)LOCHNAGAR1 },
294 { .compatible = "cirrus,lochnagar2-clk", .data = (void *)LOCHNAGAR2 },
295 {}
296};
297MODULE_DEVICE_TABLE(of, lochnagar_of_match);
298
299static int lochnagar_clk_probe(struct platform_device *pdev)
300{
301 struct device *dev = &pdev->dev;
302 struct lochnagar_clk_priv *priv;
303 const struct of_device_id *of_id;
304 int ret;
305
306 of_id = of_match_device(lochnagar_of_match, dev);
307 if (!of_id)
308 return -EINVAL;
309
310 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
311 if (!priv)
312 return -ENOMEM;
313
314 priv->dev = dev;
315 priv->regmap = dev_get_regmap(dev->parent, NULL);
316 priv->type = (enum lochnagar_type)of_id->data;
317
318 ret = lochnagar_init_parents(priv);
319 if (ret)
320 return ret;
321
322 return lochnagar_init_clks(priv);
323}
324
325static struct platform_driver lochnagar_clk_driver = {
326 .driver = {
327 .name = "lochnagar-clk",
328 .of_match_table = lochnagar_of_match,
329 },
330 .probe = lochnagar_clk_probe,
331};
332module_platform_driver(lochnagar_clk_driver);
333
334MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
335MODULE_DESCRIPTION("Clock driver for Cirrus Logic Lochnagar Board");
336MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/clk-milbeaut.c b/drivers/clk/clk-milbeaut.c
new file mode 100644
index 000000000000..5fc78faf820c
--- /dev/null
+++ b/drivers/clk/clk-milbeaut.c
@@ -0,0 +1,663 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2018 Socionext Inc.
4 * Copyright (C) 2016 Linaro Ltd.
5 */
6
7#include <linux/clk-provider.h>
8#include <linux/err.h>
9#include <linux/io.h>
10#include <linux/iopoll.h>
11#include <linux/of_address.h>
12#include <linux/platform_device.h>
13#include <linux/slab.h>
14#include <linux/spinlock.h>
15
16#define M10V_CLKSEL1 0x0
17#define CLKSEL(n) (((n) - 1) * 4 + M10V_CLKSEL1)
18
19#define M10V_PLL1 "pll1"
20#define M10V_PLL1DIV2 "pll1-2"
21#define M10V_PLL2 "pll2"
22#define M10V_PLL2DIV2 "pll2-2"
23#define M10V_PLL6 "pll6"
24#define M10V_PLL6DIV2 "pll6-2"
25#define M10V_PLL6DIV3 "pll6-3"
26#define M10V_PLL7 "pll7"
27#define M10V_PLL7DIV2 "pll7-2"
28#define M10V_PLL7DIV5 "pll7-5"
29#define M10V_PLL9 "pll9"
30#define M10V_PLL10 "pll10"
31#define M10V_PLL10DIV2 "pll10-2"
32#define M10V_PLL11 "pll11"
33
34#define M10V_SPI_PARENT0 "spi-parent0"
35#define M10V_SPI_PARENT1 "spi-parent1"
36#define M10V_SPI_PARENT2 "spi-parent2"
37#define M10V_UHS1CLK2_PARENT0 "uhs1clk2-parent0"
38#define M10V_UHS1CLK2_PARENT1 "uhs1clk2-parent1"
39#define M10V_UHS1CLK2_PARENT2 "uhs1clk2-parent2"
40#define M10V_UHS1CLK1_PARENT0 "uhs1clk1-parent0"
41#define M10V_UHS1CLK1_PARENT1 "uhs1clk1-parent1"
42#define M10V_NFCLK_PARENT0 "nfclk-parent0"
43#define M10V_NFCLK_PARENT1 "nfclk-parent1"
44#define M10V_NFCLK_PARENT2 "nfclk-parent2"
45#define M10V_NFCLK_PARENT3 "nfclk-parent3"
46#define M10V_NFCLK_PARENT4 "nfclk-parent4"
47#define M10V_NFCLK_PARENT5 "nfclk-parent5"
48
49#define M10V_DCHREQ 1
50#define M10V_UPOLL_RATE 1
51#define M10V_UTIMEOUT 250
52
53#define M10V_EMMCCLK_ID 0
54#define M10V_ACLK_ID 1
55#define M10V_HCLK_ID 2
56#define M10V_PCLK_ID 3
57#define M10V_RCLK_ID 4
58#define M10V_SPICLK_ID 5
59#define M10V_NFCLK_ID 6
60#define M10V_UHS1CLK2_ID 7
61#define M10V_NUM_CLKS 8
62
63#define to_m10v_div(_hw) container_of(_hw, struct m10v_clk_divider, hw)
64
65static struct clk_hw_onecell_data *m10v_clk_data;
66
67static DEFINE_SPINLOCK(m10v_crglock);
68
69struct m10v_clk_div_factors {
70 const char *name;
71 const char *parent_name;
72 u32 offset;
73 u8 shift;
74 u8 width;
75 const struct clk_div_table *table;
76 unsigned long div_flags;
77 int onecell_idx;
78};
79
80struct m10v_clk_div_fixed_data {
81 const char *name;
82 const char *parent_name;
83 u8 div;
84 u8 mult;
85 int onecell_idx;
86};
87
88struct m10v_clk_mux_factors {
89 const char *name;
90 const char * const *parent_names;
91 u8 num_parents;
92 u32 offset;
93 u8 shift;
94 u8 mask;
95 u32 *table;
96 unsigned long mux_flags;
97 int onecell_idx;
98};
99
100static const struct clk_div_table emmcclk_table[] = {
101 { .val = 0, .div = 8 },
102 { .val = 1, .div = 9 },
103 { .val = 2, .div = 10 },
104 { .val = 3, .div = 15 },
105 { .div = 0 },
106};
107
108static const struct clk_div_table mclk400_table[] = {
109 { .val = 1, .div = 2 },
110 { .val = 3, .div = 4 },
111 { .div = 0 },
112};
113
114static const struct clk_div_table mclk200_table[] = {
115 { .val = 3, .div = 4 },
116 { .val = 7, .div = 8 },
117 { .div = 0 },
118};
119
120static const struct clk_div_table aclk400_table[] = {
121 { .val = 1, .div = 2 },
122 { .val = 3, .div = 4 },
123 { .div = 0 },
124};
125
126static const struct clk_div_table aclk300_table[] = {
127 { .val = 0, .div = 2 },
128 { .val = 1, .div = 3 },
129 { .div = 0 },
130};
131
132static const struct clk_div_table aclk_table[] = {
133 { .val = 3, .div = 4 },
134 { .val = 7, .div = 8 },
135 { .div = 0 },
136};
137
138static const struct clk_div_table aclkexs_table[] = {
139 { .val = 3, .div = 4 },
140 { .val = 4, .div = 5 },
141 { .val = 5, .div = 6 },
142 { .val = 7, .div = 8 },
143 { .div = 0 },
144};
145
146static const struct clk_div_table hclk_table[] = {
147 { .val = 7, .div = 8 },
148 { .val = 15, .div = 16 },
149 { .div = 0 },
150};
151
152static const struct clk_div_table hclkbmh_table[] = {
153 { .val = 3, .div = 4 },
154 { .val = 7, .div = 8 },
155 { .div = 0 },
156};
157
158static const struct clk_div_table pclk_table[] = {
159 { .val = 15, .div = 16 },
160 { .val = 31, .div = 32 },
161 { .div = 0 },
162};
163
164static const struct clk_div_table rclk_table[] = {
165 { .val = 0, .div = 8 },
166 { .val = 1, .div = 16 },
167 { .val = 2, .div = 24 },
168 { .val = 3, .div = 32 },
169 { .div = 0 },
170};
171
172static const struct clk_div_table uhs1clk0_table[] = {
173 { .val = 0, .div = 2 },
174 { .val = 1, .div = 3 },
175 { .val = 2, .div = 4 },
176 { .val = 3, .div = 8 },
177 { .val = 4, .div = 16 },
178 { .div = 0 },
179};
180
181static const struct clk_div_table uhs2clk_table[] = {
182 { .val = 0, .div = 9 },
183 { .val = 1, .div = 10 },
184 { .val = 2, .div = 11 },
185 { .val = 3, .div = 12 },
186 { .val = 4, .div = 13 },
187 { .val = 5, .div = 14 },
188 { .val = 6, .div = 16 },
189 { .val = 7, .div = 18 },
190 { .div = 0 },
191};
192
193static u32 spi_mux_table[] = {0, 1, 2};
194static const char * const spi_mux_names[] = {
195 M10V_SPI_PARENT0, M10V_SPI_PARENT1, M10V_SPI_PARENT2
196};
197
198static u32 uhs1clk2_mux_table[] = {2, 3, 4, 8};
199static const char * const uhs1clk2_mux_names[] = {
200 M10V_UHS1CLK2_PARENT0, M10V_UHS1CLK2_PARENT1,
201 M10V_UHS1CLK2_PARENT2, M10V_PLL6DIV2
202};
203
204static u32 uhs1clk1_mux_table[] = {3, 4, 8};
205static const char * const uhs1clk1_mux_names[] = {
206 M10V_UHS1CLK1_PARENT0, M10V_UHS1CLK1_PARENT1, M10V_PLL6DIV2
207};
208
209static u32 nfclk_mux_table[] = {0, 1, 2, 3, 4, 8};
210static const char * const nfclk_mux_names[] = {
211 M10V_NFCLK_PARENT0, M10V_NFCLK_PARENT1, M10V_NFCLK_PARENT2,
212 M10V_NFCLK_PARENT3, M10V_NFCLK_PARENT4, M10V_NFCLK_PARENT5
213};
214
215static const struct m10v_clk_div_fixed_data m10v_pll_fixed_data[] = {
216 {M10V_PLL1, NULL, 1, 40, -1},
217 {M10V_PLL2, NULL, 1, 30, -1},
218 {M10V_PLL6, NULL, 1, 35, -1},
219 {M10V_PLL7, NULL, 1, 40, -1},
220 {M10V_PLL9, NULL, 1, 33, -1},
221 {M10V_PLL10, NULL, 5, 108, -1},
222 {M10V_PLL10DIV2, M10V_PLL10, 2, 1, -1},
223 {M10V_PLL11, NULL, 2, 75, -1},
224};
225
226static const struct m10v_clk_div_fixed_data m10v_div_fixed_data[] = {
227 {"usb2", NULL, 2, 1, -1},
228 {"pcisuppclk", NULL, 20, 1, -1},
229 {M10V_PLL1DIV2, M10V_PLL1, 2, 1, -1},
230 {M10V_PLL2DIV2, M10V_PLL2, 2, 1, -1},
231 {M10V_PLL6DIV2, M10V_PLL6, 2, 1, -1},
232 {M10V_PLL6DIV3, M10V_PLL6, 3, 1, -1},
233 {M10V_PLL7DIV2, M10V_PLL7, 2, 1, -1},
234 {M10V_PLL7DIV5, M10V_PLL7, 5, 1, -1},
235 {"ca7wd", M10V_PLL2DIV2, 12, 1, -1},
236 {"pclkca7wd", M10V_PLL1DIV2, 16, 1, -1},
237 {M10V_SPI_PARENT0, M10V_PLL10DIV2, 2, 1, -1},
238 {M10V_SPI_PARENT1, M10V_PLL10DIV2, 4, 1, -1},
239 {M10V_SPI_PARENT2, M10V_PLL7DIV2, 8, 1, -1},
240 {M10V_UHS1CLK2_PARENT0, M10V_PLL7, 4, 1, -1},
241 {M10V_UHS1CLK2_PARENT1, M10V_PLL7, 8, 1, -1},
242 {M10V_UHS1CLK2_PARENT2, M10V_PLL7, 16, 1, -1},
243 {M10V_UHS1CLK1_PARENT0, M10V_PLL7, 8, 1, -1},
244 {M10V_UHS1CLK1_PARENT1, M10V_PLL7, 16, 1, -1},
245 {M10V_NFCLK_PARENT0, M10V_PLL7DIV2, 8, 1, -1},
246 {M10V_NFCLK_PARENT1, M10V_PLL7DIV2, 10, 1, -1},
247 {M10V_NFCLK_PARENT2, M10V_PLL7DIV2, 13, 1, -1},
248 {M10V_NFCLK_PARENT3, M10V_PLL7DIV2, 16, 1, -1},
249 {M10V_NFCLK_PARENT4, M10V_PLL7DIV2, 40, 1, -1},
250 {M10V_NFCLK_PARENT5, M10V_PLL7DIV5, 10, 1, -1},
251};
252
253static const struct m10v_clk_div_factors m10v_div_factor_data[] = {
254 {"emmc", M10V_PLL11, CLKSEL(1), 28, 3, emmcclk_table, 0,
255 M10V_EMMCCLK_ID},
256 {"mclk400", M10V_PLL1DIV2, CLKSEL(10), 7, 3, mclk400_table, 0, -1},
257 {"mclk200", M10V_PLL1DIV2, CLKSEL(10), 3, 4, mclk200_table, 0, -1},
258 {"aclk400", M10V_PLL1DIV2, CLKSEL(10), 0, 3, aclk400_table, 0, -1},
259 {"aclk300", M10V_PLL2DIV2, CLKSEL(12), 0, 2, aclk300_table, 0, -1},
260 {"aclk", M10V_PLL1DIV2, CLKSEL(9), 20, 4, aclk_table, 0, M10V_ACLK_ID},
261 {"aclkexs", M10V_PLL1DIV2, CLKSEL(9), 16, 4, aclkexs_table, 0, -1},
262 {"hclk", M10V_PLL1DIV2, CLKSEL(9), 7, 5, hclk_table, 0, M10V_HCLK_ID},
263 {"hclkbmh", M10V_PLL1DIV2, CLKSEL(9), 12, 4, hclkbmh_table, 0, -1},
264 {"pclk", M10V_PLL1DIV2, CLKSEL(9), 0, 7, pclk_table, 0, M10V_PCLK_ID},
265 {"uhs1clk0", M10V_PLL7, CLKSEL(1), 3, 5, uhs1clk0_table, 0, -1},
266 {"uhs2clk", M10V_PLL6DIV3, CLKSEL(1), 18, 4, uhs2clk_table, 0, -1},
267};
268
269static const struct m10v_clk_mux_factors m10v_mux_factor_data[] = {
270 {"spi", spi_mux_names, ARRAY_SIZE(spi_mux_names),
271 CLKSEL(8), 3, 7, spi_mux_table, 0, M10V_SPICLK_ID},
272 {"uhs1clk2", uhs1clk2_mux_names, ARRAY_SIZE(uhs1clk2_mux_names),
273 CLKSEL(1), 13, 31, uhs1clk2_mux_table, 0, M10V_UHS1CLK2_ID},
274 {"uhs1clk1", uhs1clk1_mux_names, ARRAY_SIZE(uhs1clk1_mux_names),
275 CLKSEL(1), 8, 31, uhs1clk1_mux_table, 0, -1},
276 {"nfclk", nfclk_mux_names, ARRAY_SIZE(nfclk_mux_names),
277 CLKSEL(1), 22, 127, nfclk_mux_table, 0, M10V_NFCLK_ID},
278};
279
280static u8 m10v_mux_get_parent(struct clk_hw *hw)
281{
282 struct clk_mux *mux = to_clk_mux(hw);
283 u32 val;
284
285 val = readl(mux->reg) >> mux->shift;
286 val &= mux->mask;
287
288 return clk_mux_val_to_index(hw, mux->table, mux->flags, val);
289}
290
291static int m10v_mux_set_parent(struct clk_hw *hw, u8 index)
292{
293 struct clk_mux *mux = to_clk_mux(hw);
294 u32 val = clk_mux_index_to_val(mux->table, mux->flags, index);
295 unsigned long flags = 0;
296 u32 reg;
297 u32 write_en = BIT(fls(mux->mask) - 1);
298
299 if (mux->lock)
300 spin_lock_irqsave(mux->lock, flags);
301 else
302 __acquire(mux->lock);
303
304 reg = readl(mux->reg);
305 reg &= ~(mux->mask << mux->shift);
306
307 val = (val | write_en) << mux->shift;
308 reg |= val;
309 writel(reg, mux->reg);
310
311 if (mux->lock)
312 spin_unlock_irqrestore(mux->lock, flags);
313 else
314 __release(mux->lock);
315
316 return 0;
317}
318
319static const struct clk_ops m10v_mux_ops = {
320 .get_parent = m10v_mux_get_parent,
321 .set_parent = m10v_mux_set_parent,
322 .determine_rate = __clk_mux_determine_rate,
323};
324
325static struct clk_hw *m10v_clk_hw_register_mux(struct device *dev,
326 const char *name, const char * const *parent_names,
327 u8 num_parents, unsigned long flags, void __iomem *reg,
328 u8 shift, u32 mask, u8 clk_mux_flags, u32 *table,
329 spinlock_t *lock)
330{
331 struct clk_mux *mux;
332 struct clk_hw *hw;
333 struct clk_init_data init;
334 int ret;
335
336 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
337 if (!mux)
338 return ERR_PTR(-ENOMEM);
339
340 init.name = name;
341 init.ops = &m10v_mux_ops;
342 init.flags = flags;
343 init.parent_names = parent_names;
344 init.num_parents = num_parents;
345
346 mux->reg = reg;
347 mux->shift = shift;
348 mux->mask = mask;
349 mux->flags = clk_mux_flags;
350 mux->lock = lock;
351 mux->table = table;
352 mux->hw.init = &init;
353
354 hw = &mux->hw;
355 ret = clk_hw_register(dev, hw);
356 if (ret) {
357 kfree(mux);
358 hw = ERR_PTR(ret);
359 }
360
361 return hw;
362
363}
364
365struct m10v_clk_divider {
366 struct clk_hw hw;
367 void __iomem *reg;
368 u8 shift;
369 u8 width;
370 u8 flags;
371 const struct clk_div_table *table;
372 spinlock_t *lock;
373 void __iomem *write_valid_reg;
374};
375
376static unsigned long m10v_clk_divider_recalc_rate(struct clk_hw *hw,
377 unsigned long parent_rate)
378{
379 struct m10v_clk_divider *divider = to_m10v_div(hw);
380 unsigned int val;
381
382 val = readl(divider->reg) >> divider->shift;
383 val &= clk_div_mask(divider->width);
384
385 return divider_recalc_rate(hw, parent_rate, val, divider->table,
386 divider->flags, divider->width);
387}
388
389static long m10v_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
390 unsigned long *prate)
391{
392 struct m10v_clk_divider *divider = to_m10v_div(hw);
393
394 /* if read only, just return current value */
395 if (divider->flags & CLK_DIVIDER_READ_ONLY) {
396 u32 val;
397
398 val = readl(divider->reg) >> divider->shift;
399 val &= clk_div_mask(divider->width);
400
401 return divider_ro_round_rate(hw, rate, prate, divider->table,
402 divider->width, divider->flags,
403 val);
404 }
405
406 return divider_round_rate(hw, rate, prate, divider->table,
407 divider->width, divider->flags);
408}
409
410static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
411 unsigned long parent_rate)
412{
413 struct m10v_clk_divider *divider = to_m10v_div(hw);
414 int value;
415 unsigned long flags = 0;
416 u32 val;
417 u32 write_en = BIT(divider->width - 1);
418
419 value = divider_get_val(rate, parent_rate, divider->table,
420 divider->width, divider->flags);
421 if (value < 0)
422 return value;
423
424 if (divider->lock)
425 spin_lock_irqsave(divider->lock, flags);
426 else
427 __acquire(divider->lock);
428
429 val = readl(divider->reg);
430 val &= ~(clk_div_mask(divider->width) << divider->shift);
431
432 val |= ((u32)value | write_en) << divider->shift;
433 writel(val, divider->reg);
434
435 if (divider->write_valid_reg) {
436 writel(M10V_DCHREQ, divider->write_valid_reg);
437 if (readl_poll_timeout(divider->write_valid_reg, val,
438 !val, M10V_UPOLL_RATE, M10V_UTIMEOUT))
439 pr_err("%s:%s couldn't stabilize\n",
440 __func__, divider->hw.init->name);
441 }
442
443 if (divider->lock)
444 spin_unlock_irqrestore(divider->lock, flags);
445 else
446 __release(divider->lock);
447
448 return 0;
449}
450
451static const struct clk_ops m10v_clk_divider_ops = {
452 .recalc_rate = m10v_clk_divider_recalc_rate,
453 .round_rate = m10v_clk_divider_round_rate,
454 .set_rate = m10v_clk_divider_set_rate,
455};
456
457static struct clk_hw *m10v_clk_hw_register_divider(struct device *dev,
458 const char *name, const char *parent_name, unsigned long flags,
459 void __iomem *reg, u8 shift, u8 width,
460 u8 clk_divider_flags, const struct clk_div_table *table,
461 spinlock_t *lock, void __iomem *write_valid_reg)
462{
463 struct m10v_clk_divider *div;
464 struct clk_hw *hw;
465 struct clk_init_data init;
466 int ret;
467
468 div = kzalloc(sizeof(*div), GFP_KERNEL);
469 if (!div)
470 return ERR_PTR(-ENOMEM);
471
472 init.name = name;
473 init.ops = &m10v_clk_divider_ops;
474 init.flags = flags;
475 init.parent_names = &parent_name;
476 init.num_parents = 1;
477
478 div->reg = reg;
479 div->shift = shift;
480 div->width = width;
481 div->flags = clk_divider_flags;
482 div->lock = lock;
483 div->hw.init = &init;
484 div->table = table;
485 div->write_valid_reg = write_valid_reg;
486
487 /* register the clock */
488 hw = &div->hw;
489 ret = clk_hw_register(dev, hw);
490 if (ret) {
491 kfree(div);
492 hw = ERR_PTR(ret);
493 }
494
495 return hw;
496}
497
498static void m10v_reg_div_pre(const struct m10v_clk_div_factors *factors,
499 struct clk_hw_onecell_data *clk_data,
500 void __iomem *base)
501{
502 struct clk_hw *hw;
503 void __iomem *write_valid_reg;
504
505 /*
506 * The registers on CLKSEL(9) or CLKSEL(10) need additional
507 * writing to become valid.
508 */
509 if ((factors->offset == CLKSEL(9)) || (factors->offset == CLKSEL(10)))
510 write_valid_reg = base + CLKSEL(11);
511 else
512 write_valid_reg = NULL;
513
514 hw = m10v_clk_hw_register_divider(NULL, factors->name,
515 factors->parent_name,
516 CLK_SET_RATE_PARENT,
517 base + factors->offset,
518 factors->shift,
519 factors->width, factors->div_flags,
520 factors->table,
521 &m10v_crglock, write_valid_reg);
522
523 if (factors->onecell_idx >= 0)
524 clk_data->hws[factors->onecell_idx] = hw;
525}
526
527static void m10v_reg_fixed_pre(const struct m10v_clk_div_fixed_data *factors,
528 struct clk_hw_onecell_data *clk_data,
529 const char *parent_name)
530{
531 struct clk_hw *hw;
532 const char *pn = factors->parent_name ?
533 factors->parent_name : parent_name;
534
535 hw = clk_hw_register_fixed_factor(NULL, factors->name, pn, 0,
536 factors->mult, factors->div);
537
538 if (factors->onecell_idx >= 0)
539 clk_data->hws[factors->onecell_idx] = hw;
540}
541
542static void m10v_reg_mux_pre(const struct m10v_clk_mux_factors *factors,
543 struct clk_hw_onecell_data *clk_data,
544 void __iomem *base)
545{
546 struct clk_hw *hw;
547
548 hw = m10v_clk_hw_register_mux(NULL, factors->name,
549 factors->parent_names,
550 factors->num_parents,
551 CLK_SET_RATE_PARENT,
552 base + factors->offset, factors->shift,
553 factors->mask, factors->mux_flags,
554 factors->table, &m10v_crglock);
555
556 if (factors->onecell_idx >= 0)
557 clk_data->hws[factors->onecell_idx] = hw;
558}
559
560static int m10v_clk_probe(struct platform_device *pdev)
561{
562 int id;
563 struct resource *res;
564 struct device *dev = &pdev->dev;
565 struct device_node *np = dev->of_node;
566 void __iomem *base;
567 const char *parent_name;
568
569 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
570 base = devm_ioremap_resource(dev, res);
571 if (IS_ERR(base))
572 return PTR_ERR(base);
573
574 parent_name = of_clk_get_parent_name(np, 0);
575
576 for (id = 0; id < ARRAY_SIZE(m10v_div_factor_data); ++id)
577 m10v_reg_div_pre(&m10v_div_factor_data[id],
578 m10v_clk_data, base);
579
580 for (id = 0; id < ARRAY_SIZE(m10v_div_fixed_data); ++id)
581 m10v_reg_fixed_pre(&m10v_div_fixed_data[id],
582 m10v_clk_data, parent_name);
583
584 for (id = 0; id < ARRAY_SIZE(m10v_mux_factor_data); ++id)
585 m10v_reg_mux_pre(&m10v_mux_factor_data[id],
586 m10v_clk_data, base);
587
588 for (id = 0; id < M10V_NUM_CLKS; id++) {
589 if (IS_ERR(m10v_clk_data->hws[id]))
590 return PTR_ERR(m10v_clk_data->hws[id]);
591 }
592
593 return 0;
594}
595
596static const struct of_device_id m10v_clk_dt_ids[] = {
597 { .compatible = "socionext,milbeaut-m10v-ccu", },
598 { }
599};
600
601static struct platform_driver m10v_clk_driver = {
602 .probe = m10v_clk_probe,
603 .driver = {
604 .name = "m10v-ccu",
605 .of_match_table = m10v_clk_dt_ids,
606 },
607};
608builtin_platform_driver(m10v_clk_driver);
609
610static void __init m10v_cc_init(struct device_node *np)
611{
612 int id;
613 void __iomem *base;
614 const char *parent_name;
615 struct clk_hw *hw;
616
617 m10v_clk_data = kzalloc(struct_size(m10v_clk_data, hws,
618 M10V_NUM_CLKS),
619 GFP_KERNEL);
620
621 if (!m10v_clk_data)
622 return;
623
624 base = of_iomap(np, 0);
625 if (!base) {
626 kfree(m10v_clk_data);
627 return;
628 }
629
630 parent_name = of_clk_get_parent_name(np, 0);
631 if (!parent_name) {
632 kfree(m10v_clk_data);
633 iounmap(base);
634 return;
635 }
636
637 /*
638 * This way all clocks fetched before the platform device probes,
639 * except those we assign here for early use, will be deferred.
640 */
641 for (id = 0; id < M10V_NUM_CLKS; id++)
642 m10v_clk_data->hws[id] = ERR_PTR(-EPROBE_DEFER);
643
644 /*
645 * PLLs are set by bootloader so this driver registers them as the
646 * fixed factor.
647 */
648 for (id = 0; id < ARRAY_SIZE(m10v_pll_fixed_data); ++id)
649 m10v_reg_fixed_pre(&m10v_pll_fixed_data[id],
650 m10v_clk_data, parent_name);
651
652 /*
653 * timer consumes "rclk" so it needs to register here.
654 */
655 hw = m10v_clk_hw_register_divider(NULL, "rclk", M10V_PLL10DIV2, 0,
656 base + CLKSEL(1), 0, 3, 0, rclk_table,
657 &m10v_crglock, NULL);
658 m10v_clk_data->hws[M10V_RCLK_ID] = hw;
659
660 m10v_clk_data->num = M10V_NUM_CLKS;
661 of_clk_add_hw_provider(np, of_clk_hw_onecell_get, m10v_clk_data);
662}
663CLK_OF_DECLARE_DRIVER(m10v_cc, "socionext,milbeaut-m10v-ccu", m10v_cc_init);
diff --git a/drivers/clk/clk-multiplier.c b/drivers/clk/clk-multiplier.c
index 3c86f859c199..94470b4eadf4 100644
--- a/drivers/clk/clk-multiplier.c
+++ b/drivers/clk/clk-multiplier.c
@@ -11,6 +11,22 @@
11#include <linux/of.h> 11#include <linux/of.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13 13
14static inline u32 clk_mult_readl(struct clk_multiplier *mult)
15{
16 if (mult->flags & CLK_MULTIPLIER_BIG_ENDIAN)
17 return ioread32be(mult->reg);
18
19 return readl(mult->reg);
20}
21
22static inline void clk_mult_writel(struct clk_multiplier *mult, u32 val)
23{
24 if (mult->flags & CLK_MULTIPLIER_BIG_ENDIAN)
25 iowrite32be(val, mult->reg);
26 else
27 writel(val, mult->reg);
28}
29
14static unsigned long __get_mult(struct clk_multiplier *mult, 30static unsigned long __get_mult(struct clk_multiplier *mult,
15 unsigned long rate, 31 unsigned long rate,
16 unsigned long parent_rate) 32 unsigned long parent_rate)
@@ -27,7 +43,7 @@ static unsigned long clk_multiplier_recalc_rate(struct clk_hw *hw,
27 struct clk_multiplier *mult = to_clk_multiplier(hw); 43 struct clk_multiplier *mult = to_clk_multiplier(hw);
28 unsigned long val; 44 unsigned long val;
29 45
30 val = clk_readl(mult->reg) >> mult->shift; 46 val = clk_mult_readl(mult) >> mult->shift;
31 val &= GENMASK(mult->width - 1, 0); 47 val &= GENMASK(mult->width - 1, 0);
32 48
33 if (!val && mult->flags & CLK_MULTIPLIER_ZERO_BYPASS) 49 if (!val && mult->flags & CLK_MULTIPLIER_ZERO_BYPASS)
@@ -118,10 +134,10 @@ static int clk_multiplier_set_rate(struct clk_hw *hw, unsigned long rate,
118 else 134 else
119 __acquire(mult->lock); 135 __acquire(mult->lock);
120 136
121 val = clk_readl(mult->reg); 137 val = clk_mult_readl(mult);
122 val &= ~GENMASK(mult->width + mult->shift - 1, mult->shift); 138 val &= ~GENMASK(mult->width + mult->shift - 1, mult->shift);
123 val |= factor << mult->shift; 139 val |= factor << mult->shift;
124 clk_writel(val, mult->reg); 140 clk_mult_writel(mult, val);
125 141
126 if (mult->lock) 142 if (mult->lock)
127 spin_unlock_irqrestore(mult->lock, flags); 143 spin_unlock_irqrestore(mult->lock, flags);
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 2ad2df2e8909..66e91f740508 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -23,6 +23,22 @@
23 * parent - parent is adjustable through clk_set_parent 23 * parent - parent is adjustable through clk_set_parent
24 */ 24 */
25 25
26static inline u32 clk_mux_readl(struct clk_mux *mux)
27{
28 if (mux->flags & CLK_MUX_BIG_ENDIAN)
29 return ioread32be(mux->reg);
30
31 return readl(mux->reg);
32}
33
34static inline void clk_mux_writel(struct clk_mux *mux, u32 val)
35{
36 if (mux->flags & CLK_MUX_BIG_ENDIAN)
37 iowrite32be(val, mux->reg);
38 else
39 writel(val, mux->reg);
40}
41
26int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags, 42int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags,
27 unsigned int val) 43 unsigned int val)
28{ 44{
@@ -73,7 +89,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
73 struct clk_mux *mux = to_clk_mux(hw); 89 struct clk_mux *mux = to_clk_mux(hw);
74 u32 val; 90 u32 val;
75 91
76 val = clk_readl(mux->reg) >> mux->shift; 92 val = clk_mux_readl(mux) >> mux->shift;
77 val &= mux->mask; 93 val &= mux->mask;
78 94
79 return clk_mux_val_to_index(hw, mux->table, mux->flags, val); 95 return clk_mux_val_to_index(hw, mux->table, mux->flags, val);
@@ -94,12 +110,12 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
94 if (mux->flags & CLK_MUX_HIWORD_MASK) { 110 if (mux->flags & CLK_MUX_HIWORD_MASK) {
95 reg = mux->mask << (mux->shift + 16); 111 reg = mux->mask << (mux->shift + 16);
96 } else { 112 } else {
97 reg = clk_readl(mux->reg); 113 reg = clk_mux_readl(mux);
98 reg &= ~(mux->mask << mux->shift); 114 reg &= ~(mux->mask << mux->shift);
99 } 115 }
100 val = val << mux->shift; 116 val = val << mux->shift;
101 reg |= val; 117 reg |= val;
102 clk_writel(reg, mux->reg); 118 clk_mux_writel(mux, reg);
103 119
104 if (mux->lock) 120 if (mux->lock)
105 spin_unlock_irqrestore(mux->lock, flags); 121 spin_unlock_irqrestore(mux->lock, flags);
@@ -159,7 +175,7 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
159 init.ops = &clk_mux_ro_ops; 175 init.ops = &clk_mux_ro_ops;
160 else 176 else
161 init.ops = &clk_mux_ops; 177 init.ops = &clk_mux_ops;
162 init.flags = flags | CLK_IS_BASIC; 178 init.flags = flags;
163 init.parent_names = parent_names; 179 init.parent_names = parent_names;
164 init.num_parents = num_parents; 180 init.num_parents = num_parents;
165 181
diff --git a/drivers/clk/clk-pwm.c b/drivers/clk/clk-pwm.c
index 8cb9d117fdbf..02b472a1f9b0 100644
--- a/drivers/clk/clk-pwm.c
+++ b/drivers/clk/clk-pwm.c
@@ -101,7 +101,7 @@ static int clk_pwm_probe(struct platform_device *pdev)
101 101
102 init.name = clk_name; 102 init.name = clk_name;
103 init.ops = &clk_pwm_ops; 103 init.ops = &clk_pwm_ops;
104 init.flags = CLK_IS_BASIC; 104 init.flags = 0;
105 init.num_parents = 0; 105 init.num_parents = 0;
106 106
107 clk_pwm->pwm = pwm; 107 clk_pwm->pwm = pwm;
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index 1212a9be7e80..4739a47ec8bd 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -34,6 +34,7 @@
34#define CGA_PLL4 4 /* only on clockgen-1.0, which lacks CGB */ 34#define CGA_PLL4 4 /* only on clockgen-1.0, which lacks CGB */
35#define CGB_PLL1 4 35#define CGB_PLL1 4
36#define CGB_PLL2 5 36#define CGB_PLL2 5
37#define MAX_PLL_DIV 16
37 38
38struct clockgen_pll_div { 39struct clockgen_pll_div {
39 struct clk *clk; 40 struct clk *clk;
@@ -41,7 +42,7 @@ struct clockgen_pll_div {
41}; 42};
42 43
43struct clockgen_pll { 44struct clockgen_pll {
44 struct clockgen_pll_div div[8]; 45 struct clockgen_pll_div div[MAX_PLL_DIV];
45}; 46};
46 47
47#define CLKSEL_VALID 1 48#define CLKSEL_VALID 1
@@ -79,7 +80,7 @@ struct clockgen_chipinfo {
79 const struct clockgen_muxinfo *cmux_groups[2]; 80 const struct clockgen_muxinfo *cmux_groups[2];
80 const struct clockgen_muxinfo *hwaccel[NUM_HWACCEL]; 81 const struct clockgen_muxinfo *hwaccel[NUM_HWACCEL];
81 void (*init_periph)(struct clockgen *cg); 82 void (*init_periph)(struct clockgen *cg);
82 int cmux_to_group[NUM_CMUX]; /* -1 terminates if fewer than NUM_CMUX */ 83 int cmux_to_group[NUM_CMUX + 1]; /* array should be -1 terminated */
83 u32 pll_mask; /* 1 << n bit set if PLL n is valid */ 84 u32 pll_mask; /* 1 << n bit set if PLL n is valid */
84 u32 flags; /* CG_xxx */ 85 u32 flags; /* CG_xxx */
85}; 86};
@@ -245,6 +246,58 @@ static const struct clockgen_muxinfo clockgen2_cmux_cgb = {
245 }, 246 },
246}; 247};
247 248
249static const struct clockgen_muxinfo ls1028a_hwa1 = {
250 {
251 { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
252 { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
253 { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
254 { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
255 { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
256 {},
257 { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
258 { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
259 },
260};
261
262static const struct clockgen_muxinfo ls1028a_hwa2 = {
263 {
264 { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
265 { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
266 { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
267 { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
268 { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
269 {},
270 { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
271 { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
272 },
273};
274
275static const struct clockgen_muxinfo ls1028a_hwa3 = {
276 {
277 { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
278 { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
279 { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
280 { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
281 { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
282 {},
283 { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
284 { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
285 },
286};
287
288static const struct clockgen_muxinfo ls1028a_hwa4 = {
289 {
290 { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
291 { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
292 { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
293 { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
294 { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
295 {},
296 { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
297 { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
298 },
299};
300
248static const struct clockgen_muxinfo ls1043a_hwa1 = { 301static const struct clockgen_muxinfo ls1043a_hwa1 = {
249 { 302 {
250 {}, 303 {},
@@ -508,6 +561,21 @@ static const struct clockgen_chipinfo chipinfo[] = {
508 .pll_mask = 0x03, 561 .pll_mask = 0x03,
509 }, 562 },
510 { 563 {
564 .compat = "fsl,ls1028a-clockgen",
565 .cmux_groups = {
566 &clockgen2_cmux_cga12
567 },
568 .hwaccel = {
569 &ls1028a_hwa1, &ls1028a_hwa2,
570 &ls1028a_hwa3, &ls1028a_hwa4
571 },
572 .cmux_to_group = {
573 0, 0, 0, 0, -1
574 },
575 .pll_mask = 0x07,
576 .flags = CG_VER3 | CG_LITTLE_ENDIAN,
577 },
578 {
511 .compat = "fsl,ls1043a-clockgen", 579 .compat = "fsl,ls1043a-clockgen",
512 .init_periph = t2080_init_periph, 580 .init_periph = t2080_init_periph,
513 .cmux_groups = { 581 .cmux_groups = {
@@ -601,7 +669,7 @@ static const struct clockgen_chipinfo chipinfo[] = {
601 &p4080_cmux_grp1, &p4080_cmux_grp2 669 &p4080_cmux_grp1, &p4080_cmux_grp2
602 }, 670 },
603 .cmux_to_group = { 671 .cmux_to_group = {
604 0, 0, 0, 0, 1, 1, 1, 1 672 0, 0, 0, 0, 1, 1, 1, 1, -1
605 }, 673 },
606 .pll_mask = 0x1f, 674 .pll_mask = 0x1f,
607 }, 675 },
@@ -1128,7 +1196,7 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
1128 int ret; 1196 int ret;
1129 1197
1130 /* 1198 /*
1131 * For platform PLL, there are 8 divider clocks. 1199 * For platform PLL, there are MAX_PLL_DIV divider clocks.
1132 * For core PLL, there are 4 divider clocks at most. 1200 * For core PLL, there are 4 divider clocks at most.
1133 */ 1201 */
1134 if (idx != PLATFORM_PLL && i >= 4) 1202 if (idx != PLATFORM_PLL && i >= 4)
@@ -1423,6 +1491,7 @@ CLK_OF_DECLARE(qoriq_clockgen_b4420, "fsl,b4420-clockgen", clockgen_init);
1423CLK_OF_DECLARE(qoriq_clockgen_b4860, "fsl,b4860-clockgen", clockgen_init); 1491CLK_OF_DECLARE(qoriq_clockgen_b4860, "fsl,b4860-clockgen", clockgen_init);
1424CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init); 1492CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init);
1425CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); 1493CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
1494CLK_OF_DECLARE(qoriq_clockgen_ls1028a, "fsl,ls1028a-clockgen", clockgen_init);
1426CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); 1495CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
1427CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); 1496CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init);
1428CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init); 1497CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init);
diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index cdaa567c8042..fdac33a9be2f 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -300,6 +300,85 @@ static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
300 { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, 300 { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" },
301}; 301};
302 302
303static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
304 { STM32F4_RCC_AHB1ENR, 0, "gpioa", "ahb_div" },
305 { STM32F4_RCC_AHB1ENR, 1, "gpiob", "ahb_div" },
306 { STM32F4_RCC_AHB1ENR, 2, "gpioc", "ahb_div" },
307 { STM32F4_RCC_AHB1ENR, 3, "gpiod", "ahb_div" },
308 { STM32F4_RCC_AHB1ENR, 4, "gpioe", "ahb_div" },
309 { STM32F4_RCC_AHB1ENR, 5, "gpiof", "ahb_div" },
310 { STM32F4_RCC_AHB1ENR, 6, "gpiog", "ahb_div" },
311 { STM32F4_RCC_AHB1ENR, 7, "gpioh", "ahb_div" },
312 { STM32F4_RCC_AHB1ENR, 8, "gpioi", "ahb_div" },
313 { STM32F4_RCC_AHB1ENR, 9, "gpioj", "ahb_div" },
314 { STM32F4_RCC_AHB1ENR, 10, "gpiok", "ahb_div" },
315 { STM32F4_RCC_AHB1ENR, 12, "crc", "ahb_div" },
316 { STM32F4_RCC_AHB1ENR, 18, "bkpsra", "ahb_div" },
317 { STM32F4_RCC_AHB1ENR, 20, "dtcmram", "ahb_div" },
318 { STM32F4_RCC_AHB1ENR, 21, "dma1", "ahb_div" },
319 { STM32F4_RCC_AHB1ENR, 22, "dma2", "ahb_div" },
320 { STM32F4_RCC_AHB1ENR, 23, "dma2d", "ahb_div" },
321 { STM32F4_RCC_AHB1ENR, 25, "ethmac", "ahb_div" },
322 { STM32F4_RCC_AHB1ENR, 26, "ethmactx", "ahb_div" },
323 { STM32F4_RCC_AHB1ENR, 27, "ethmacrx", "ahb_div" },
324 { STM32F4_RCC_AHB1ENR, 28, "ethmacptp", "ahb_div" },
325 { STM32F4_RCC_AHB1ENR, 29, "otghs", "ahb_div" },
326 { STM32F4_RCC_AHB1ENR, 30, "otghsulpi", "ahb_div" },
327
328 { STM32F4_RCC_AHB2ENR, 0, "dcmi", "ahb_div" },
329 { STM32F4_RCC_AHB2ENR, 1, "jpeg", "ahb_div" },
330 { STM32F4_RCC_AHB2ENR, 4, "cryp", "ahb_div" },
331 { STM32F4_RCC_AHB2ENR, 5, "hash", "ahb_div" },
332 { STM32F4_RCC_AHB2ENR, 6, "rng", "pll48" },
333 { STM32F4_RCC_AHB2ENR, 7, "otgfs", "pll48" },
334
335 { STM32F4_RCC_AHB3ENR, 0, "fmc", "ahb_div",
336 CLK_IGNORE_UNUSED },
337 { STM32F4_RCC_AHB3ENR, 1, "qspi", "ahb_div",
338 CLK_IGNORE_UNUSED },
339
340 { STM32F4_RCC_APB1ENR, 0, "tim2", "apb1_mul" },
341 { STM32F4_RCC_APB1ENR, 1, "tim3", "apb1_mul" },
342 { STM32F4_RCC_APB1ENR, 2, "tim4", "apb1_mul" },
343 { STM32F4_RCC_APB1ENR, 3, "tim5", "apb1_mul" },
344 { STM32F4_RCC_APB1ENR, 4, "tim6", "apb1_mul" },
345 { STM32F4_RCC_APB1ENR, 5, "tim7", "apb1_mul" },
346 { STM32F4_RCC_APB1ENR, 6, "tim12", "apb1_mul" },
347 { STM32F4_RCC_APB1ENR, 7, "tim13", "apb1_mul" },
348 { STM32F4_RCC_APB1ENR, 8, "tim14", "apb1_mul" },
349 { STM32F4_RCC_APB1ENR, 10, "rtcapb", "apb1_mul" },
350 { STM32F4_RCC_APB1ENR, 11, "wwdg", "apb1_div" },
351 { STM32F4_RCC_APB1ENR, 13, "can3", "apb1_div" },
352 { STM32F4_RCC_APB1ENR, 14, "spi2", "apb1_div" },
353 { STM32F4_RCC_APB1ENR, 15, "spi3", "apb1_div" },
354 { STM32F4_RCC_APB1ENR, 16, "spdifrx", "apb1_div" },
355 { STM32F4_RCC_APB1ENR, 25, "can1", "apb1_div" },
356 { STM32F4_RCC_APB1ENR, 26, "can2", "apb1_div" },
357 { STM32F4_RCC_APB1ENR, 27, "cec", "apb1_div" },
358 { STM32F4_RCC_APB1ENR, 28, "pwr", "apb1_div" },
359 { STM32F4_RCC_APB1ENR, 29, "dac", "apb1_div" },
360
361 { STM32F4_RCC_APB2ENR, 0, "tim1", "apb2_mul" },
362 { STM32F4_RCC_APB2ENR, 1, "tim8", "apb2_mul" },
363 { STM32F4_RCC_APB2ENR, 7, "sdmmc2", "sdmux2" },
364 { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" },
365 { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" },
366 { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" },
367 { STM32F4_RCC_APB2ENR, 11, "sdmmc1", "sdmux1" },
368 { STM32F4_RCC_APB2ENR, 12, "spi1", "apb2_div" },
369 { STM32F4_RCC_APB2ENR, 13, "spi4", "apb2_div" },
370 { STM32F4_RCC_APB2ENR, 14, "syscfg", "apb2_div" },
371 { STM32F4_RCC_APB2ENR, 16, "tim9", "apb2_mul" },
372 { STM32F4_RCC_APB2ENR, 17, "tim10", "apb2_mul" },
373 { STM32F4_RCC_APB2ENR, 18, "tim11", "apb2_mul" },
374 { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" },
375 { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" },
376 { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" },
377 { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" },
378 { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" },
379 { STM32F4_RCC_APB2ENR, 30, "mdio", "apb2_div" },
380};
381
303/* 382/*
304 * This bitmask tells us which bit offsets (0..192) on STM32F4[23]xxx 383 * This bitmask tells us which bit offsets (0..192) on STM32F4[23]xxx
305 * have gate bits associated with them. Its combined hweight is 71. 384 * have gate bits associated with them. Its combined hweight is 71.
@@ -318,6 +397,10 @@ static const u64 stm32f746_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull,
318 0x0000000000000003ull, 397 0x0000000000000003ull,
319 0x04f77f833e01c9ffull }; 398 0x04f77f833e01c9ffull };
320 399
400static const u64 stm32f769_gate_map[MAX_GATE_MAP] = { 0x000000f37ef417ffull,
401 0x0000000000000003ull,
402 0x44F77F833E01EDFFull };
403
321static const u64 *stm32f4_gate_map; 404static const u64 *stm32f4_gate_map;
322 405
323static struct clk_hw **clks; 406static struct clk_hw **clks;
@@ -1048,6 +1131,10 @@ static const char *rtc_parents[4] = {
1048 "no-clock", "lse", "lsi", "hse-rtc" 1131 "no-clock", "lse", "lsi", "hse-rtc"
1049}; 1132};
1050 1133
1134static const char *pll_src = "pll-src";
1135
1136static const char *pllsrc_parent[2] = { "hsi", NULL };
1137
1051static const char *dsi_parent[2] = { NULL, "pll-r" }; 1138static const char *dsi_parent[2] = { NULL, "pll-r" };
1052 1139
1053static const char *lcd_parent[1] = { "pllsai-r-div" }; 1140static const char *lcd_parent[1] = { "pllsai-r-div" };
@@ -1072,6 +1159,9 @@ static const char *uart_parents2[4] = { "apb1_div", "sys", "hsi", "lse" };
1072 1159
1073static const char *i2c_parents[4] = { "apb1_div", "sys", "hsi", "no-clock" }; 1160static const char *i2c_parents[4] = { "apb1_div", "sys", "hsi", "no-clock" };
1074 1161
1162static const char * const dfsdm1_src[] = { "apb2_div", "sys" };
1163static const char * const adsfdm1_parent[] = { "sai1_clk", "sai2_clk" };
1164
1075struct stm32_aux_clk { 1165struct stm32_aux_clk {
1076 int idx; 1166 int idx;
1077 const char *name; 1167 const char *name;
@@ -1313,6 +1403,177 @@ static const struct stm32_aux_clk stm32f746_aux_clk[] = {
1313 }, 1403 },
1314}; 1404};
1315 1405
1406static const struct stm32_aux_clk stm32f769_aux_clk[] = {
1407 {
1408 CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent),
1409 NO_MUX, 0, 0,
1410 STM32F4_RCC_APB2ENR, 26,
1411 CLK_SET_RATE_PARENT
1412 },
1413 {
1414 CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents),
1415 STM32F4_RCC_CFGR, 23, 1,
1416 NO_GATE, 0,
1417 CLK_SET_RATE_PARENT
1418 },
1419 {
1420 CLK_SAI1, "sai1_clk", sai_parents, ARRAY_SIZE(sai_parents),
1421 STM32F4_RCC_DCKCFGR, 20, 3,
1422 STM32F4_RCC_APB2ENR, 22,
1423 CLK_SET_RATE_PARENT
1424 },
1425 {
1426 CLK_SAI2, "sai2_clk", sai_parents, ARRAY_SIZE(sai_parents),
1427 STM32F4_RCC_DCKCFGR, 22, 3,
1428 STM32F4_RCC_APB2ENR, 23,
1429 CLK_SET_RATE_PARENT
1430 },
1431 {
1432 NO_IDX, "pll48", pll48_parents, ARRAY_SIZE(pll48_parents),
1433 STM32F7_RCC_DCKCFGR2, 27, 1,
1434 NO_GATE, 0,
1435 0
1436 },
1437 {
1438 NO_IDX, "sdmux1", sdmux_parents, ARRAY_SIZE(sdmux_parents),
1439 STM32F7_RCC_DCKCFGR2, 28, 1,
1440 NO_GATE, 0,
1441 0
1442 },
1443 {
1444 NO_IDX, "sdmux2", sdmux_parents, ARRAY_SIZE(sdmux_parents),
1445 STM32F7_RCC_DCKCFGR2, 29, 1,
1446 NO_GATE, 0,
1447 0
1448 },
1449 {
1450 CLK_HDMI_CEC, "hdmi-cec",
1451 hdmi_parents, ARRAY_SIZE(hdmi_parents),
1452 STM32F7_RCC_DCKCFGR2, 26, 1,
1453 NO_GATE, 0,
1454 0
1455 },
1456 {
1457 CLK_SPDIF, "spdif-rx",
1458 spdif_parent, ARRAY_SIZE(spdif_parent),
1459 STM32F7_RCC_DCKCFGR2, 22, 3,
1460 STM32F4_RCC_APB2ENR, 23,
1461 CLK_SET_RATE_PARENT
1462 },
1463 {
1464 CLK_USART1, "usart1",
1465 uart_parents1, ARRAY_SIZE(uart_parents1),
1466 STM32F7_RCC_DCKCFGR2, 0, 3,
1467 STM32F4_RCC_APB2ENR, 4,
1468 CLK_SET_RATE_PARENT,
1469 },
1470 {
1471 CLK_USART2, "usart2",
1472 uart_parents2, ARRAY_SIZE(uart_parents1),
1473 STM32F7_RCC_DCKCFGR2, 2, 3,
1474 STM32F4_RCC_APB1ENR, 17,
1475 CLK_SET_RATE_PARENT,
1476 },
1477 {
1478 CLK_USART3, "usart3",
1479 uart_parents2, ARRAY_SIZE(uart_parents1),
1480 STM32F7_RCC_DCKCFGR2, 4, 3,
1481 STM32F4_RCC_APB1ENR, 18,
1482 CLK_SET_RATE_PARENT,
1483 },
1484 {
1485 CLK_UART4, "uart4",
1486 uart_parents2, ARRAY_SIZE(uart_parents1),
1487 STM32F7_RCC_DCKCFGR2, 6, 3,
1488 STM32F4_RCC_APB1ENR, 19,
1489 CLK_SET_RATE_PARENT,
1490 },
1491 {
1492 CLK_UART5, "uart5",
1493 uart_parents2, ARRAY_SIZE(uart_parents1),
1494 STM32F7_RCC_DCKCFGR2, 8, 3,
1495 STM32F4_RCC_APB1ENR, 20,
1496 CLK_SET_RATE_PARENT,
1497 },
1498 {
1499 CLK_USART6, "usart6",
1500 uart_parents1, ARRAY_SIZE(uart_parents1),
1501 STM32F7_RCC_DCKCFGR2, 10, 3,
1502 STM32F4_RCC_APB2ENR, 5,
1503 CLK_SET_RATE_PARENT,
1504 },
1505 {
1506 CLK_UART7, "uart7",
1507 uart_parents2, ARRAY_SIZE(uart_parents1),
1508 STM32F7_RCC_DCKCFGR2, 12, 3,
1509 STM32F4_RCC_APB1ENR, 30,
1510 CLK_SET_RATE_PARENT,
1511 },
1512 {
1513 CLK_UART8, "uart8",
1514 uart_parents2, ARRAY_SIZE(uart_parents1),
1515 STM32F7_RCC_DCKCFGR2, 14, 3,
1516 STM32F4_RCC_APB1ENR, 31,
1517 CLK_SET_RATE_PARENT,
1518 },
1519 {
1520 CLK_I2C1, "i2c1",
1521 i2c_parents, ARRAY_SIZE(i2c_parents),
1522 STM32F7_RCC_DCKCFGR2, 16, 3,
1523 STM32F4_RCC_APB1ENR, 21,
1524 CLK_SET_RATE_PARENT,
1525 },
1526 {
1527 CLK_I2C2, "i2c2",
1528 i2c_parents, ARRAY_SIZE(i2c_parents),
1529 STM32F7_RCC_DCKCFGR2, 18, 3,
1530 STM32F4_RCC_APB1ENR, 22,
1531 CLK_SET_RATE_PARENT,
1532 },
1533 {
1534 CLK_I2C3, "i2c3",
1535 i2c_parents, ARRAY_SIZE(i2c_parents),
1536 STM32F7_RCC_DCKCFGR2, 20, 3,
1537 STM32F4_RCC_APB1ENR, 23,
1538 CLK_SET_RATE_PARENT,
1539 },
1540 {
1541 CLK_I2C4, "i2c4",
1542 i2c_parents, ARRAY_SIZE(i2c_parents),
1543 STM32F7_RCC_DCKCFGR2, 22, 3,
1544 STM32F4_RCC_APB1ENR, 24,
1545 CLK_SET_RATE_PARENT,
1546 },
1547 {
1548 CLK_LPTIMER, "lptim1",
1549 lptim_parent, ARRAY_SIZE(lptim_parent),
1550 STM32F7_RCC_DCKCFGR2, 24, 3,
1551 STM32F4_RCC_APB1ENR, 9,
1552 CLK_SET_RATE_PARENT
1553 },
1554 {
1555 CLK_F769_DSI, "dsi",
1556 dsi_parent, ARRAY_SIZE(dsi_parent),
1557 STM32F7_RCC_DCKCFGR2, 0, 1,
1558 STM32F4_RCC_APB2ENR, 27,
1559 CLK_SET_RATE_PARENT
1560 },
1561 {
1562 CLK_DFSDM1, "dfsdm1",
1563 dfsdm1_src, ARRAY_SIZE(dfsdm1_src),
1564 STM32F4_RCC_DCKCFGR, 25, 1,
1565 STM32F4_RCC_APB2ENR, 29,
1566 CLK_SET_RATE_PARENT
1567 },
1568 {
1569 CLK_ADFSDM1, "adfsdm1",
1570 adsfdm1_parent, ARRAY_SIZE(adsfdm1_parent),
1571 STM32F4_RCC_DCKCFGR, 26, 1,
1572 STM32F4_RCC_APB2ENR, 29,
1573 CLK_SET_RATE_PARENT
1574 },
1575};
1576
1316static const struct stm32f4_clk_data stm32f429_clk_data = { 1577static const struct stm32f4_clk_data stm32f429_clk_data = {
1317 .end_primary = END_PRIMARY_CLK, 1578 .end_primary = END_PRIMARY_CLK,
1318 .gates_data = stm32f429_gates, 1579 .gates_data = stm32f429_gates,
@@ -1343,6 +1604,16 @@ static const struct stm32f4_clk_data stm32f746_clk_data = {
1343 .aux_clk_num = ARRAY_SIZE(stm32f746_aux_clk), 1604 .aux_clk_num = ARRAY_SIZE(stm32f746_aux_clk),
1344}; 1605};
1345 1606
1607static const struct stm32f4_clk_data stm32f769_clk_data = {
1608 .end_primary = END_PRIMARY_CLK_F7,
1609 .gates_data = stm32f769_gates,
1610 .gates_map = stm32f769_gate_map,
1611 .gates_num = ARRAY_SIZE(stm32f769_gates),
1612 .pll_data = stm32f469_pll,
1613 .aux_clk = stm32f769_aux_clk,
1614 .aux_clk_num = ARRAY_SIZE(stm32f769_aux_clk),
1615};
1616
1346static const struct of_device_id stm32f4_of_match[] = { 1617static const struct of_device_id stm32f4_of_match[] = {
1347 { 1618 {
1348 .compatible = "st,stm32f42xx-rcc", 1619 .compatible = "st,stm32f42xx-rcc",
@@ -1356,6 +1627,10 @@ static const struct of_device_id stm32f4_of_match[] = {
1356 .compatible = "st,stm32f746-rcc", 1627 .compatible = "st,stm32f746-rcc",
1357 .data = &stm32f746_clk_data 1628 .data = &stm32f746_clk_data
1358 }, 1629 },
1630 {
1631 .compatible = "st,stm32f769-rcc",
1632 .data = &stm32f769_clk_data
1633 },
1359 {} 1634 {}
1360}; 1635};
1361 1636
@@ -1427,9 +1702,8 @@ static void __init stm32f4_rcc_init(struct device_node *np)
1427 int n; 1702 int n;
1428 const struct of_device_id *match; 1703 const struct of_device_id *match;
1429 const struct stm32f4_clk_data *data; 1704 const struct stm32f4_clk_data *data;
1430 unsigned long pllcfgr;
1431 const char *pllsrc;
1432 unsigned long pllm; 1705 unsigned long pllm;
1706 struct clk_hw *pll_src_hw;
1433 1707
1434 base = of_iomap(np, 0); 1708 base = of_iomap(np, 0);
1435 if (!base) { 1709 if (!base) {
@@ -1460,21 +1734,33 @@ static void __init stm32f4_rcc_init(struct device_node *np)
1460 1734
1461 hse_clk = of_clk_get_parent_name(np, 0); 1735 hse_clk = of_clk_get_parent_name(np, 0);
1462 dsi_parent[0] = hse_clk; 1736 dsi_parent[0] = hse_clk;
1737 pllsrc_parent[1] = hse_clk;
1463 1738
1464 i2s_in_clk = of_clk_get_parent_name(np, 1); 1739 i2s_in_clk = of_clk_get_parent_name(np, 1);
1465 1740
1466 i2s_parents[1] = i2s_in_clk; 1741 i2s_parents[1] = i2s_in_clk;
1467 sai_parents[2] = i2s_in_clk; 1742 sai_parents[2] = i2s_in_clk;
1468 1743
1744 if (of_device_is_compatible(np, "st,stm32f769-rcc")) {
1745 clk_hw_register_gate(NULL, "dfsdm1_apb", "apb2_div", 0,
1746 base + STM32F4_RCC_APB2ENR, 29,
1747 CLK_IGNORE_UNUSED, &stm32f4_clk_lock);
1748 dsi_parent[0] = pll_src;
1749 sai_parents[3] = pll_src;
1750 }
1751
1469 clks[CLK_HSI] = clk_hw_register_fixed_rate_with_accuracy(NULL, "hsi", 1752 clks[CLK_HSI] = clk_hw_register_fixed_rate_with_accuracy(NULL, "hsi",
1470 NULL, 0, 16000000, 160000); 1753 NULL, 0, 16000000, 160000);
1471 1754
1472 pllcfgr = readl(base + STM32F4_RCC_PLLCFGR); 1755 pll_src_hw = clk_hw_register_mux(NULL, pll_src, pllsrc_parent,
1473 pllsrc = pllcfgr & BIT(22) ? hse_clk : "hsi"; 1756 ARRAY_SIZE(pllsrc_parent), 0,
1474 pllm = pllcfgr & 0x3f; 1757 base + STM32F4_RCC_PLLCFGR, 22, 1, 0,
1758 &stm32f4_clk_lock);
1759
1760 pllm = readl(base + STM32F4_RCC_PLLCFGR) & 0x3f;
1475 1761
1476 clk_hw_register_fixed_factor(NULL, "vco_in", pllsrc, 1762 clk_hw_register_fixed_factor(NULL, "vco_in", pll_src,
1477 0, 1, pllm); 1763 0, 1, pllm);
1478 1764
1479 stm32f4_rcc_register_pll("vco_in", &data->pll_data[0], 1765 stm32f4_rcc_register_pll("vco_in", &data->pll_data[0],
1480 &stm32f4_clk_lock); 1766 &stm32f4_clk_lock);
@@ -1612,12 +1898,16 @@ static void __init stm32f4_rcc_init(struct device_node *np)
1612 clks[aux_clk->idx] = hw; 1898 clks[aux_clk->idx] = hw;
1613 } 1899 }
1614 1900
1615 if (of_device_is_compatible(np, "st,stm32f746-rcc")) 1901 if (of_device_is_compatible(np, "st,stm32f746-rcc")) {
1616 1902
1617 clk_hw_register_fixed_factor(NULL, "hsi_div488", "hsi", 0, 1903 clk_hw_register_fixed_factor(NULL, "hsi_div488", "hsi", 0,
1618 1, 488); 1904 1, 488);
1619 1905
1906 clks[CLK_PLL_SRC] = pll_src_hw;
1907 }
1908
1620 of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL); 1909 of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL);
1910
1621 return; 1911 return;
1622fail: 1912fail:
1623 kfree(clks); 1913 kfree(clks);
@@ -1626,3 +1916,4 @@ fail:
1626CLK_OF_DECLARE_DRIVER(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init); 1916CLK_OF_DECLARE_DRIVER(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init);
1627CLK_OF_DECLARE_DRIVER(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init); 1917CLK_OF_DECLARE_DRIVER(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init);
1628CLK_OF_DECLARE_DRIVER(stm32f746_rcc, "st,stm32f746-rcc", stm32f4_rcc_init); 1918CLK_OF_DECLARE_DRIVER(stm32f746_rcc, "st,stm32f746-rcc", stm32f4_rcc_init);
1919CLK_OF_DECLARE_DRIVER(stm32f769_rcc, "st,stm32f769-rcc", stm32f4_rcc_init);
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index a0ae8dc16909..a875649df8b8 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -1402,6 +1402,7 @@ enum {
1402 G_CRYP1, 1402 G_CRYP1,
1403 G_HASH1, 1403 G_HASH1,
1404 G_BKPSRAM, 1404 G_BKPSRAM,
1405 G_DDRPERFM,
1405 1406
1406 G_LAST 1407 G_LAST
1407}; 1408};
@@ -1488,6 +1489,7 @@ static struct stm32_gate_cfg per_gate_cfg[G_LAST] = {
1488 K_GATE(G_STGENRO, RCC_APB4ENSETR, 20, 0), 1489 K_GATE(G_STGENRO, RCC_APB4ENSETR, 20, 0),
1489 K_MGATE(G_USBPHY, RCC_APB4ENSETR, 16, 0), 1490 K_MGATE(G_USBPHY, RCC_APB4ENSETR, 16, 0),
1490 K_GATE(G_IWDG2, RCC_APB4ENSETR, 15, 0), 1491 K_GATE(G_IWDG2, RCC_APB4ENSETR, 15, 0),
1492 K_GATE(G_DDRPERFM, RCC_APB4ENSETR, 8, 0),
1491 K_MGATE(G_DSI, RCC_APB4ENSETR, 4, 0), 1493 K_MGATE(G_DSI, RCC_APB4ENSETR, 4, 0),
1492 K_MGATE(G_LTDC, RCC_APB4ENSETR, 0, 0), 1494 K_MGATE(G_LTDC, RCC_APB4ENSETR, 0, 0),
1493 1495
@@ -1899,6 +1901,7 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
1899 PCLK(CRC1, "crc1", "ck_axi", 0, G_CRC1), 1901 PCLK(CRC1, "crc1", "ck_axi", 0, G_CRC1),
1900 PCLK(USBH, "usbh", "ck_axi", 0, G_USBH), 1902 PCLK(USBH, "usbh", "ck_axi", 0, G_USBH),
1901 PCLK(ETHSTP, "ethstp", "ck_axi", 0, G_ETHSTP), 1903 PCLK(ETHSTP, "ethstp", "ck_axi", 0, G_ETHSTP),
1904 PCLK(DDRPERFM, "ddrperfm", "pclk4", 0, G_DDRPERFM),
1902 1905
1903 /* Kernel clocks */ 1906 /* Kernel clocks */
1904 KCLK(SDMMC1_K, "sdmmc1_k", sdmmc12_src, 0, G_SDMMC1, M_SDMMC12), 1907 KCLK(SDMMC1_K, "sdmmc1_k", sdmmc12_src, 0, G_SDMMC1, M_SDMMC12),
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index 531b030d4d4e..d975465fe2a8 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -262,7 +262,7 @@ static unsigned long xgene_clk_pmd_recalc_rate(struct clk_hw *hw,
262 else 262 else
263 __acquire(fd->lock); 263 __acquire(fd->lock);
264 264
265 val = clk_readl(fd->reg); 265 val = readl(fd->reg);
266 266
267 if (fd->lock) 267 if (fd->lock)
268 spin_unlock_irqrestore(fd->lock, flags); 268 spin_unlock_irqrestore(fd->lock, flags);
@@ -333,10 +333,10 @@ static int xgene_clk_pmd_set_rate(struct clk_hw *hw, unsigned long rate,
333 else 333 else
334 __acquire(fd->lock); 334 __acquire(fd->lock);
335 335
336 val = clk_readl(fd->reg); 336 val = readl(fd->reg);
337 val &= ~fd->mask; 337 val &= ~fd->mask;
338 val |= (scale << fd->shift); 338 val |= (scale << fd->shift);
339 clk_writel(val, fd->reg); 339 writel(val, fd->reg);
340 340
341 if (fd->lock) 341 if (fd->lock)
342 spin_unlock_irqrestore(fd->lock, flags); 342 spin_unlock_irqrestore(fd->lock, flags);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 96053a96fe2f..aa51756fd4d6 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -39,15 +39,23 @@ static LIST_HEAD(clk_notifier_list);
39 39
40/*** private data structures ***/ 40/*** private data structures ***/
41 41
42struct clk_parent_map {
43 const struct clk_hw *hw;
44 struct clk_core *core;
45 const char *fw_name;
46 const char *name;
47 int index;
48};
49
42struct clk_core { 50struct clk_core {
43 const char *name; 51 const char *name;
44 const struct clk_ops *ops; 52 const struct clk_ops *ops;
45 struct clk_hw *hw; 53 struct clk_hw *hw;
46 struct module *owner; 54 struct module *owner;
47 struct device *dev; 55 struct device *dev;
56 struct device_node *of_node;
48 struct clk_core *parent; 57 struct clk_core *parent;
49 const char **parent_names; 58 struct clk_parent_map *parents;
50 struct clk_core **parents;
51 u8 num_parents; 59 u8 num_parents;
52 u8 new_parent_index; 60 u8 new_parent_index;
53 unsigned long rate; 61 unsigned long rate;
@@ -316,17 +324,102 @@ static struct clk_core *clk_core_lookup(const char *name)
316 return NULL; 324 return NULL;
317} 325}
318 326
327/**
328 * clk_core_get - Find the clk_core parent of a clk
329 * @core: clk to find parent of
330 * @p_index: parent index to search for
331 *
332 * This is the preferred method for clk providers to find the parent of a
333 * clk when that parent is external to the clk controller. The parent_names
334 * array is indexed and treated as a local name matching a string in the device
335 * node's 'clock-names' property or as the 'con_id' matching the device's
336 * dev_name() in a clk_lookup. This allows clk providers to use their own
337 * namespace instead of looking for a globally unique parent string.
338 *
339 * For example the following DT snippet would allow a clock registered by the
340 * clock-controller@c001 that has a clk_init_data::parent_data array
341 * with 'xtal' in the 'name' member to find the clock provided by the
342 * clock-controller@f00abcd without needing to get the globally unique name of
343 * the xtal clk.
344 *
345 * parent: clock-controller@f00abcd {
346 * reg = <0xf00abcd 0xabcd>;
347 * #clock-cells = <0>;
348 * };
349 *
350 * clock-controller@c001 {
351 * reg = <0xc001 0xf00d>;
352 * clocks = <&parent>;
353 * clock-names = "xtal";
354 * #clock-cells = <1>;
355 * };
356 *
357 * Returns: -ENOENT when the provider can't be found or the clk doesn't
358 * exist in the provider. -EINVAL when the name can't be found. NULL when the
359 * provider knows about the clk but it isn't provided on this system.
360 * A valid clk_core pointer when the clk can be found in the provider.
361 */
362static struct clk_core *clk_core_get(struct clk_core *core, u8 p_index)
363{
364 const char *name = core->parents[p_index].fw_name;
365 int index = core->parents[p_index].index;
366 struct clk_hw *hw = ERR_PTR(-ENOENT);
367 struct device *dev = core->dev;
368 const char *dev_id = dev ? dev_name(dev) : NULL;
369 struct device_node *np = core->of_node;
370
371 if (np && index >= 0)
372 hw = of_clk_get_hw(np, index, name);
373
374 /*
375 * If the DT search above couldn't find the provider or the provider
376 * didn't know about this clk, fallback to looking up via clkdev based
377 * clk_lookups
378 */
379 if (PTR_ERR(hw) == -ENOENT && name)
380 hw = clk_find_hw(dev_id, name);
381
382 if (IS_ERR(hw))
383 return ERR_CAST(hw);
384
385 return hw->core;
386}
387
388static void clk_core_fill_parent_index(struct clk_core *core, u8 index)
389{
390 struct clk_parent_map *entry = &core->parents[index];
391 struct clk_core *parent = ERR_PTR(-ENOENT);
392
393 if (entry->hw) {
394 parent = entry->hw->core;
395 /*
396 * We have a direct reference but it isn't registered yet?
397 * Orphan it and let clk_reparent() update the orphan status
398 * when the parent is registered.
399 */
400 if (!parent)
401 parent = ERR_PTR(-EPROBE_DEFER);
402 } else {
403 parent = clk_core_get(core, index);
404 if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT)
405 parent = clk_core_lookup(entry->name);
406 }
407
408 /* Only cache it if it's not an error */
409 if (!IS_ERR(parent))
410 entry->core = parent;
411}
412
319static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core, 413static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
320 u8 index) 414 u8 index)
321{ 415{
322 if (!core || index >= core->num_parents) 416 if (!core || index >= core->num_parents || !core->parents)
323 return NULL; 417 return NULL;
324 418
325 if (!core->parents[index]) 419 if (!core->parents[index].core)
326 core->parents[index] = 420 clk_core_fill_parent_index(core, index);
327 clk_core_lookup(core->parent_names[index]);
328 421
329 return core->parents[index]; 422 return core->parents[index].core;
330} 423}
331 424
332struct clk_hw * 425struct clk_hw *
@@ -347,23 +440,18 @@ unsigned int __clk_get_enable_count(struct clk *clk)
347 440
348static unsigned long clk_core_get_rate_nolock(struct clk_core *core) 441static unsigned long clk_core_get_rate_nolock(struct clk_core *core)
349{ 442{
350 unsigned long ret; 443 if (!core)
351 444 return 0;
352 if (!core) {
353 ret = 0;
354 goto out;
355 }
356
357 ret = core->rate;
358
359 if (!core->num_parents)
360 goto out;
361 445
362 if (!core->parent) 446 if (!core->num_parents || core->parent)
363 ret = 0; 447 return core->rate;
364 448
365out: 449 /*
366 return ret; 450 * Clk must have a parent because num_parents > 0 but the parent isn't
451 * known yet. Best to return 0 as the rate of this clk until we can
452 * properly recalc the rate based on the parent's rate.
453 */
454 return 0;
367} 455}
368 456
369unsigned long clk_hw_get_rate(const struct clk_hw *hw) 457unsigned long clk_hw_get_rate(const struct clk_hw *hw)
@@ -524,9 +612,15 @@ void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
524EXPORT_SYMBOL_GPL(clk_hw_set_rate_range); 612EXPORT_SYMBOL_GPL(clk_hw_set_rate_range);
525 613
526/* 614/*
615 * __clk_mux_determine_rate - clk_ops::determine_rate implementation for a mux type clk
616 * @hw: mux type clk to determine rate on
617 * @req: rate request, also used to return preferred parent and frequencies
618 *
527 * Helper for finding best parent to provide a given frequency. This can be used 619 * Helper for finding best parent to provide a given frequency. This can be used
528 * directly as a determine_rate callback (e.g. for a mux), or from a more 620 * directly as a determine_rate callback (e.g. for a mux), or from a more
529 * complex clock that may combine a mux with other operations. 621 * complex clock that may combine a mux with other operations.
622 *
623 * Returns: 0 on success, -EERROR value on error
530 */ 624 */
531int __clk_mux_determine_rate(struct clk_hw *hw, 625int __clk_mux_determine_rate(struct clk_hw *hw,
532 struct clk_rate_request *req) 626 struct clk_rate_request *req)
@@ -1519,20 +1613,37 @@ static int clk_fetch_parent_index(struct clk_core *core,
1519 return -EINVAL; 1613 return -EINVAL;
1520 1614
1521 for (i = 0; i < core->num_parents; i++) { 1615 for (i = 0; i < core->num_parents; i++) {
1522 if (core->parents[i] == parent) 1616 /* Found it first try! */
1617 if (core->parents[i].core == parent)
1523 return i; 1618 return i;
1524 1619
1525 if (core->parents[i]) 1620 /* Something else is here, so keep looking */
1621 if (core->parents[i].core)
1526 continue; 1622 continue;
1527 1623
1528 /* Fallback to comparing globally unique names */ 1624 /* Maybe core hasn't been cached but the hw is all we know? */
1529 if (!strcmp(parent->name, core->parent_names[i])) { 1625 if (core->parents[i].hw) {
1530 core->parents[i] = parent; 1626 if (core->parents[i].hw == parent->hw)
1531 return i; 1627 break;
1628
1629 /* Didn't match, but we're expecting a clk_hw */
1630 continue;
1532 } 1631 }
1632
1633 /* Maybe it hasn't been cached (clk_set_parent() path) */
1634 if (parent == clk_core_get(core, i))
1635 break;
1636
1637 /* Fallback to comparing globally unique names */
1638 if (!strcmp(parent->name, core->parents[i].name))
1639 break;
1533 } 1640 }
1534 1641
1535 return -EINVAL; 1642 if (i == core->num_parents)
1643 return -EINVAL;
1644
1645 core->parents[i].core = parent;
1646 return i;
1536} 1647}
1537 1648
1538/* 1649/*
@@ -2293,6 +2404,7 @@ void clk_hw_reparent(struct clk_hw *hw, struct clk_hw *new_parent)
2293bool clk_has_parent(struct clk *clk, struct clk *parent) 2404bool clk_has_parent(struct clk *clk, struct clk *parent)
2294{ 2405{
2295 struct clk_core *core, *parent_core; 2406 struct clk_core *core, *parent_core;
2407 int i;
2296 2408
2297 /* NULL clocks should be nops, so return success if either is NULL. */ 2409 /* NULL clocks should be nops, so return success if either is NULL. */
2298 if (!clk || !parent) 2410 if (!clk || !parent)
@@ -2305,8 +2417,11 @@ bool clk_has_parent(struct clk *clk, struct clk *parent)
2305 if (core->parent == parent_core) 2417 if (core->parent == parent_core)
2306 return true; 2418 return true;
2307 2419
2308 return match_string(core->parent_names, core->num_parents, 2420 for (i = 0; i < core->num_parents; i++)
2309 parent_core->name) >= 0; 2421 if (!strcmp(core->parents[i].name, parent_core->name))
2422 return true;
2423
2424 return false;
2310} 2425}
2311EXPORT_SYMBOL_GPL(clk_has_parent); 2426EXPORT_SYMBOL_GPL(clk_has_parent);
2312 2427
@@ -2850,7 +2965,6 @@ static const struct {
2850 ENTRY(CLK_SET_PARENT_GATE), 2965 ENTRY(CLK_SET_PARENT_GATE),
2851 ENTRY(CLK_SET_RATE_PARENT), 2966 ENTRY(CLK_SET_RATE_PARENT),
2852 ENTRY(CLK_IGNORE_UNUSED), 2967 ENTRY(CLK_IGNORE_UNUSED),
2853 ENTRY(CLK_IS_BASIC),
2854 ENTRY(CLK_GET_RATE_NOCACHE), 2968 ENTRY(CLK_GET_RATE_NOCACHE),
2855 ENTRY(CLK_SET_RATE_NO_REPARENT), 2969 ENTRY(CLK_SET_RATE_NO_REPARENT),
2856 ENTRY(CLK_GET_ACCURACY_NOCACHE), 2970 ENTRY(CLK_GET_ACCURACY_NOCACHE),
@@ -2889,9 +3003,9 @@ static int possible_parents_show(struct seq_file *s, void *data)
2889 int i; 3003 int i;
2890 3004
2891 for (i = 0; i < core->num_parents - 1; i++) 3005 for (i = 0; i < core->num_parents - 1; i++)
2892 seq_printf(s, "%s ", core->parent_names[i]); 3006 seq_printf(s, "%s ", core->parents[i].name);
2893 3007
2894 seq_printf(s, "%s\n", core->parent_names[i]); 3008 seq_printf(s, "%s\n", core->parents[i].name);
2895 3009
2896 return 0; 3010 return 0;
2897} 3011}
@@ -3025,7 +3139,7 @@ static inline void clk_debug_unregister(struct clk_core *core)
3025 */ 3139 */
3026static int __clk_core_init(struct clk_core *core) 3140static int __clk_core_init(struct clk_core *core)
3027{ 3141{
3028 int i, ret; 3142 int ret;
3029 struct clk_core *orphan; 3143 struct clk_core *orphan;
3030 struct hlist_node *tmp2; 3144 struct hlist_node *tmp2;
3031 unsigned long rate; 3145 unsigned long rate;
@@ -3079,12 +3193,6 @@ static int __clk_core_init(struct clk_core *core)
3079 goto out; 3193 goto out;
3080 } 3194 }
3081 3195
3082 /* throw a WARN if any entries in parent_names are NULL */
3083 for (i = 0; i < core->num_parents; i++)
3084 WARN(!core->parent_names[i],
3085 "%s: invalid NULL in %s's .parent_names\n",
3086 __func__, core->name);
3087
3088 core->parent = __clk_init_parent(core); 3196 core->parent = __clk_init_parent(core);
3089 3197
3090 /* 3198 /*
@@ -3313,20 +3421,104 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
3313 return clk; 3421 return clk;
3314} 3422}
3315 3423
3316/** 3424static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist)
3317 * clk_register - allocate a new clock, register it and return an opaque cookie 3425{
3318 * @dev: device that is registering this clock 3426 const char *dst;
3319 * @hw: link to hardware-specific clock data 3427
3320 * 3428 if (!src) {
3321 * clk_register is the primary interface for populating the clock tree with new 3429 if (must_exist)
3322 * clock nodes. It returns a pointer to the newly allocated struct clk which 3430 return -EINVAL;
3323 * cannot be dereferenced by driver code but may be used in conjunction with the 3431 return 0;
3324 * rest of the clock API. In the event of an error clk_register will return an 3432 }
3325 * error code; drivers must test for an error code after calling clk_register. 3433
3326 */ 3434 *dst_p = dst = kstrdup_const(src, GFP_KERNEL);
3327struct clk *clk_register(struct device *dev, struct clk_hw *hw) 3435 if (!dst)
3436 return -ENOMEM;
3437
3438 return 0;
3439}
3440
3441static int clk_core_populate_parent_map(struct clk_core *core)
3442{
3443 const struct clk_init_data *init = core->hw->init;
3444 u8 num_parents = init->num_parents;
3445 const char * const *parent_names = init->parent_names;
3446 const struct clk_hw **parent_hws = init->parent_hws;
3447 const struct clk_parent_data *parent_data = init->parent_data;
3448 int i, ret = 0;
3449 struct clk_parent_map *parents, *parent;
3450
3451 if (!num_parents)
3452 return 0;
3453
3454 /*
3455 * Avoid unnecessary string look-ups of clk_core's possible parents by
3456 * having a cache of names/clk_hw pointers to clk_core pointers.
3457 */
3458 parents = kcalloc(num_parents, sizeof(*parents), GFP_KERNEL);
3459 core->parents = parents;
3460 if (!parents)
3461 return -ENOMEM;
3462
3463 /* Copy everything over because it might be __initdata */
3464 for (i = 0, parent = parents; i < num_parents; i++, parent++) {
3465 parent->index = -1;
3466 if (parent_names) {
3467 /* throw a WARN if any entries are NULL */
3468 WARN(!parent_names[i],
3469 "%s: invalid NULL in %s's .parent_names\n",
3470 __func__, core->name);
3471 ret = clk_cpy_name(&parent->name, parent_names[i],
3472 true);
3473 } else if (parent_data) {
3474 parent->hw = parent_data[i].hw;
3475 parent->index = parent_data[i].index;
3476 ret = clk_cpy_name(&parent->fw_name,
3477 parent_data[i].fw_name, false);
3478 if (!ret)
3479 ret = clk_cpy_name(&parent->name,
3480 parent_data[i].name,
3481 false);
3482 } else if (parent_hws) {
3483 parent->hw = parent_hws[i];
3484 } else {
3485 ret = -EINVAL;
3486 WARN(1, "Must specify parents if num_parents > 0\n");
3487 }
3488
3489 if (ret) {
3490 do {
3491 kfree_const(parents[i].name);
3492 kfree_const(parents[i].fw_name);
3493 } while (--i >= 0);
3494 kfree(parents);
3495
3496 return ret;
3497 }
3498 }
3499
3500 return 0;
3501}
3502
3503static void clk_core_free_parent_map(struct clk_core *core)
3504{
3505 int i = core->num_parents;
3506
3507 if (!core->num_parents)
3508 return;
3509
3510 while (--i >= 0) {
3511 kfree_const(core->parents[i].name);
3512 kfree_const(core->parents[i].fw_name);
3513 }
3514
3515 kfree(core->parents);
3516}
3517
3518static struct clk *
3519__clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
3328{ 3520{
3329 int i, ret; 3521 int ret;
3330 struct clk_core *core; 3522 struct clk_core *core;
3331 3523
3332 core = kzalloc(sizeof(*core), GFP_KERNEL); 3524 core = kzalloc(sizeof(*core), GFP_KERNEL);
@@ -3350,6 +3542,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
3350 if (dev && pm_runtime_enabled(dev)) 3542 if (dev && pm_runtime_enabled(dev))
3351 core->rpm_enabled = true; 3543 core->rpm_enabled = true;
3352 core->dev = dev; 3544 core->dev = dev;
3545 core->of_node = np;
3353 if (dev && dev->driver) 3546 if (dev && dev->driver)
3354 core->owner = dev->driver->owner; 3547 core->owner = dev->driver->owner;
3355 core->hw = hw; 3548 core->hw = hw;
@@ -3359,33 +3552,9 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
3359 core->max_rate = ULONG_MAX; 3552 core->max_rate = ULONG_MAX;
3360 hw->core = core; 3553 hw->core = core;
3361 3554
3362 /* allocate local copy in case parent_names is __initdata */ 3555 ret = clk_core_populate_parent_map(core);
3363 core->parent_names = kcalloc(core->num_parents, sizeof(char *), 3556 if (ret)
3364 GFP_KERNEL);
3365
3366 if (!core->parent_names) {
3367 ret = -ENOMEM;
3368 goto fail_parent_names;
3369 }
3370
3371
3372 /* copy each string name in case parent_names is __initdata */
3373 for (i = 0; i < core->num_parents; i++) {
3374 core->parent_names[i] = kstrdup_const(hw->init->parent_names[i],
3375 GFP_KERNEL);
3376 if (!core->parent_names[i]) {
3377 ret = -ENOMEM;
3378 goto fail_parent_names_copy;
3379 }
3380 }
3381
3382 /* avoid unnecessary string look-ups of clk_core's possible parents. */
3383 core->parents = kcalloc(core->num_parents, sizeof(*core->parents),
3384 GFP_KERNEL);
3385 if (!core->parents) {
3386 ret = -ENOMEM;
3387 goto fail_parents; 3557 goto fail_parents;
3388 };
3389 3558
3390 INIT_HLIST_HEAD(&core->clks); 3559 INIT_HLIST_HEAD(&core->clks);
3391 3560
@@ -3396,7 +3565,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
3396 hw->clk = alloc_clk(core, NULL, NULL); 3565 hw->clk = alloc_clk(core, NULL, NULL);
3397 if (IS_ERR(hw->clk)) { 3566 if (IS_ERR(hw->clk)) {
3398 ret = PTR_ERR(hw->clk); 3567 ret = PTR_ERR(hw->clk);
3399 goto fail_parents; 3568 goto fail_create_clk;
3400 } 3569 }
3401 3570
3402 clk_core_link_consumer(hw->core, hw->clk); 3571 clk_core_link_consumer(hw->core, hw->clk);
@@ -3412,13 +3581,9 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
3412 free_clk(hw->clk); 3581 free_clk(hw->clk);
3413 hw->clk = NULL; 3582 hw->clk = NULL;
3414 3583
3584fail_create_clk:
3585 clk_core_free_parent_map(core);
3415fail_parents: 3586fail_parents:
3416 kfree(core->parents);
3417fail_parent_names_copy:
3418 while (--i >= 0)
3419 kfree_const(core->parent_names[i]);
3420 kfree(core->parent_names);
3421fail_parent_names:
3422fail_ops: 3587fail_ops:
3423 kfree_const(core->name); 3588 kfree_const(core->name);
3424fail_name: 3589fail_name:
@@ -3426,6 +3591,24 @@ fail_name:
3426fail_out: 3591fail_out:
3427 return ERR_PTR(ret); 3592 return ERR_PTR(ret);
3428} 3593}
3594
3595/**
3596 * clk_register - allocate a new clock, register it and return an opaque cookie
3597 * @dev: device that is registering this clock
3598 * @hw: link to hardware-specific clock data
3599 *
3600 * clk_register is the *deprecated* interface for populating the clock tree with
3601 * new clock nodes. Use clk_hw_register() instead.
3602 *
3603 * Returns: a pointer to the newly allocated struct clk which
3604 * cannot be dereferenced by driver code but may be used in conjunction with the
3605 * rest of the clock API. In the event of an error clk_register will return an
3606 * error code; drivers must test for an error code after calling clk_register.
3607 */
3608struct clk *clk_register(struct device *dev, struct clk_hw *hw)
3609{
3610 return __clk_register(dev, dev_of_node(dev), hw);
3611}
3429EXPORT_SYMBOL_GPL(clk_register); 3612EXPORT_SYMBOL_GPL(clk_register);
3430 3613
3431/** 3614/**
@@ -3440,23 +3623,35 @@ EXPORT_SYMBOL_GPL(clk_register);
3440 */ 3623 */
3441int clk_hw_register(struct device *dev, struct clk_hw *hw) 3624int clk_hw_register(struct device *dev, struct clk_hw *hw)
3442{ 3625{
3443 return PTR_ERR_OR_ZERO(clk_register(dev, hw)); 3626 return PTR_ERR_OR_ZERO(__clk_register(dev, dev_of_node(dev), hw));
3444} 3627}
3445EXPORT_SYMBOL_GPL(clk_hw_register); 3628EXPORT_SYMBOL_GPL(clk_hw_register);
3446 3629
3630/*
3631 * of_clk_hw_register - register a clk_hw and return an error code
3632 * @node: device_node of device that is registering this clock
3633 * @hw: link to hardware-specific clock data
3634 *
3635 * of_clk_hw_register() is the primary interface for populating the clock tree
3636 * with new clock nodes when a struct device is not available, but a struct
3637 * device_node is. It returns an integer equal to zero indicating success or
3638 * less than zero indicating failure. Drivers must test for an error code after
3639 * calling of_clk_hw_register().
3640 */
3641int of_clk_hw_register(struct device_node *node, struct clk_hw *hw)
3642{
3643 return PTR_ERR_OR_ZERO(__clk_register(NULL, node, hw));
3644}
3645EXPORT_SYMBOL_GPL(of_clk_hw_register);
3646
3447/* Free memory allocated for a clock. */ 3647/* Free memory allocated for a clock. */
3448static void __clk_release(struct kref *ref) 3648static void __clk_release(struct kref *ref)
3449{ 3649{
3450 struct clk_core *core = container_of(ref, struct clk_core, ref); 3650 struct clk_core *core = container_of(ref, struct clk_core, ref);
3451 int i = core->num_parents;
3452 3651
3453 lockdep_assert_held(&prepare_lock); 3652 lockdep_assert_held(&prepare_lock);
3454 3653
3455 kfree(core->parents); 3654 clk_core_free_parent_map(core);
3456 while (--i >= 0)
3457 kfree_const(core->parent_names[i]);
3458
3459 kfree(core->parent_names);
3460 kfree_const(core->name); 3655 kfree_const(core->name);
3461 kfree(core); 3656 kfree(core);
3462} 3657}
@@ -3575,9 +3770,10 @@ static void devm_clk_hw_release(struct device *dev, void *res)
3575 * @dev: device that is registering this clock 3770 * @dev: device that is registering this clock
3576 * @hw: link to hardware-specific clock data 3771 * @hw: link to hardware-specific clock data
3577 * 3772 *
3578 * Managed clk_register(). Clocks returned from this function are 3773 * Managed clk_register(). This function is *deprecated*, use devm_clk_hw_register() instead.
3579 * automatically clk_unregister()ed on driver detach. See clk_register() for 3774 *
3580 * more information. 3775 * Clocks returned from this function are automatically clk_unregister()ed on
3776 * driver detach. See clk_register() for more information.
3581 */ 3777 */
3582struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw) 3778struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
3583{ 3779{
@@ -3895,6 +4091,8 @@ EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get);
3895 * @np: Device node pointer associated with clock provider 4091 * @np: Device node pointer associated with clock provider
3896 * @clk_src_get: callback for decoding clock 4092 * @clk_src_get: callback for decoding clock
3897 * @data: context pointer for @clk_src_get callback. 4093 * @data: context pointer for @clk_src_get callback.
4094 *
4095 * This function is *deprecated*. Use of_clk_add_hw_provider() instead.
3898 */ 4096 */
3899int of_clk_add_provider(struct device_node *np, 4097int of_clk_add_provider(struct device_node *np,
3900 struct clk *(*clk_src_get)(struct of_phandle_args *clkspec, 4098 struct clk *(*clk_src_get)(struct of_phandle_args *clkspec,
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h
index 553f531cc232..d8400d623b34 100644
--- a/drivers/clk/clk.h
+++ b/drivers/clk/clk.h
@@ -19,6 +19,8 @@ static inline struct clk_hw *of_clk_get_hw(struct device_node *np,
19} 19}
20#endif 20#endif
21 21
22struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id);
23
22#ifdef CONFIG_COMMON_CLK 24#ifdef CONFIG_COMMON_CLK
23struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw, 25struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
24 const char *dev_id, const char *con_id); 26 const char *dev_id, const char *con_id);
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 6e787cc9e5b9..2afc8df8acff 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -72,25 +72,26 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
72 return cl; 72 return cl;
73} 73}
74 74
75static struct clk *__clk_get_sys(struct device *dev, const char *dev_id, 75struct clk_hw *clk_find_hw(const char *dev_id, const char *con_id)
76 const char *con_id)
77{ 76{
78 struct clk_lookup *cl; 77 struct clk_lookup *cl;
79 struct clk *clk = NULL; 78 struct clk_hw *hw = ERR_PTR(-ENOENT);
80 79
81 mutex_lock(&clocks_mutex); 80 mutex_lock(&clocks_mutex);
82
83 cl = clk_find(dev_id, con_id); 81 cl = clk_find(dev_id, con_id);
84 if (!cl) 82 if (cl)
85 goto out; 83 hw = cl->clk_hw;
86
87 clk = clk_hw_create_clk(dev, cl->clk_hw, dev_id, con_id);
88 if (IS_ERR(clk))
89 cl = NULL;
90out:
91 mutex_unlock(&clocks_mutex); 84 mutex_unlock(&clocks_mutex);
92 85
93 return cl ? clk : ERR_PTR(-ENOENT); 86 return hw;
87}
88
89static struct clk *__clk_get_sys(struct device *dev, const char *dev_id,
90 const char *con_id)
91{
92 struct clk_hw *hw = clk_find_hw(dev_id, con_id);
93
94 return clk_hw_create_clk(dev, hw, dev_id, con_id);
94} 95}
95 96
96struct clk *clk_get_sys(const char *dev_id, const char *con_id) 97struct clk *clk_get_sys(const char *dev_id, const char *con_id)
diff --git a/drivers/clk/davinci/da8xx-cfgchip.c b/drivers/clk/davinci/da8xx-cfgchip.c
index d1bbee19ed0f..bdc52364b421 100644
--- a/drivers/clk/davinci/da8xx-cfgchip.c
+++ b/drivers/clk/davinci/da8xx-cfgchip.c
@@ -160,10 +160,8 @@ static int __init da8xx_cfgchip_register_div4p5(struct device *dev,
160 struct da8xx_cfgchip_gate_clk *gate; 160 struct da8xx_cfgchip_gate_clk *gate;
161 161
162 gate = da8xx_cfgchip_gate_clk_register(dev, &da8xx_div4p5ena_info, regmap); 162 gate = da8xx_cfgchip_gate_clk_register(dev, &da8xx_div4p5ena_info, regmap);
163 if (IS_ERR(gate))
164 return PTR_ERR(gate);
165 163
166 return 0; 164 return PTR_ERR_OR_ZERO(gate);
167} 165}
168 166
169static int __init 167static int __init
diff --git a/drivers/clk/davinci/pll.h b/drivers/clk/davinci/pll.h
index 7cc354dd29e2..c2a453caa131 100644
--- a/drivers/clk/davinci/pll.h
+++ b/drivers/clk/davinci/pll.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2/* 2/*
3 * Clock driver for TI Davinci PSC controllers 3 * Clock driver for TI Davinci PSC controllers
4 * 4 *
diff --git a/drivers/clk/davinci/psc.h b/drivers/clk/davinci/psc.h
index cc5614567a70..69070f834391 100644
--- a/drivers/clk/davinci/psc.h
+++ b/drivers/clk/davinci/psc.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2/* 2/*
3 * Clock driver for TI Davinci PSC controllers 3 * Clock driver for TI Davinci PSC controllers
4 * 4 *
diff --git a/drivers/clk/hisilicon/clk-hi3660.c b/drivers/clk/hisilicon/clk-hi3660.c
index f40419959656..794eeff0d5d2 100644
--- a/drivers/clk/hisilicon/clk-hi3660.c
+++ b/drivers/clk/hisilicon/clk-hi3660.c
@@ -163,8 +163,12 @@ static const struct hisi_gate_clock hi3660_crgctrl_gate_sep_clks[] = {
163 "clk_isp_snclk_mux", CLK_SET_RATE_PARENT, 0x50, 17, 0, }, 163 "clk_isp_snclk_mux", CLK_SET_RATE_PARENT, 0x50, 17, 0, },
164 { HI3660_CLK_GATE_ISP_SNCLK2, "clk_gate_isp_snclk2", 164 { HI3660_CLK_GATE_ISP_SNCLK2, "clk_gate_isp_snclk2",
165 "clk_isp_snclk_mux", CLK_SET_RATE_PARENT, 0x50, 18, 0, }, 165 "clk_isp_snclk_mux", CLK_SET_RATE_PARENT, 0x50, 18, 0, },
166 /*
167 * clk_gate_ufs_subsys is a system bus clock, mark it as critical
168 * clock and keep it on for system suspend and resume.
169 */
166 { HI3660_CLK_GATE_UFS_SUBSYS, "clk_gate_ufs_subsys", "clk_div_sysbus", 170 { HI3660_CLK_GATE_UFS_SUBSYS, "clk_gate_ufs_subsys", "clk_div_sysbus",
167 CLK_SET_RATE_PARENT, 0x50, 21, 0, }, 171 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0x50, 21, 0, },
168 { HI3660_PCLK_GATE_DSI0, "pclk_gate_dsi0", "clk_div_cfgbus", 172 { HI3660_PCLK_GATE_DSI0, "pclk_gate_dsi0", "clk_div_cfgbus",
169 CLK_SET_RATE_PARENT, 0x50, 28, 0, }, 173 CLK_SET_RATE_PARENT, 0x50, 28, 0, },
170 { HI3660_PCLK_GATE_DSI1, "pclk_gate_dsi1", "clk_div_cfgbus", 174 { HI3660_PCLK_GATE_DSI1, "pclk_gate_dsi1", "clk_div_cfgbus",
diff --git a/drivers/clk/hisilicon/clk-hisi-phase.c b/drivers/clk/hisilicon/clk-hisi-phase.c
index 5fdc267bb2da..ba6afad66a2b 100644
--- a/drivers/clk/hisilicon/clk-hisi-phase.c
+++ b/drivers/clk/hisilicon/clk-hisi-phase.c
@@ -75,10 +75,10 @@ static int hisi_clk_set_phase(struct clk_hw *hw, int degrees)
75 75
76 spin_lock_irqsave(phase->lock, flags); 76 spin_lock_irqsave(phase->lock, flags);
77 77
78 val = clk_readl(phase->reg); 78 val = readl(phase->reg);
79 val &= ~phase->mask; 79 val &= ~phase->mask;
80 val |= regval << phase->shift; 80 val |= regval << phase->shift;
81 clk_writel(val, phase->reg); 81 writel(val, phase->reg);
82 82
83 spin_unlock_irqrestore(phase->lock, flags); 83 spin_unlock_irqrestore(phase->lock, flags);
84 84
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 0d5180fbe988..05641c64b317 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -35,7 +35,7 @@ obj-$(CONFIG_SOC_IMX25) += clk-imx25.o
35obj-$(CONFIG_SOC_IMX27) += clk-imx27.o 35obj-$(CONFIG_SOC_IMX27) += clk-imx27.o
36obj-$(CONFIG_SOC_IMX31) += clk-imx31.o 36obj-$(CONFIG_SOC_IMX31) += clk-imx31.o
37obj-$(CONFIG_SOC_IMX35) += clk-imx35.o 37obj-$(CONFIG_SOC_IMX35) += clk-imx35.o
38obj-$(CONFIG_SOC_IMX5) += clk-imx51-imx53.o 38obj-$(CONFIG_SOC_IMX5) += clk-imx5.o
39obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o 39obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o
40obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o 40obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o
41obj-$(CONFIG_SOC_IMX6SLL) += clk-imx6sll.o 41obj-$(CONFIG_SOC_IMX6SLL) += clk-imx6sll.o
diff --git a/drivers/clk/imx/clk-divider-gate.c b/drivers/clk/imx/clk-divider-gate.c
index df1f8429fe16..2a8352a316c7 100644
--- a/drivers/clk/imx/clk-divider-gate.c
+++ b/drivers/clk/imx/clk-divider-gate.c
@@ -29,7 +29,7 @@ static unsigned long clk_divider_gate_recalc_rate_ro(struct clk_hw *hw,
29 struct clk_divider *div = to_clk_divider(hw); 29 struct clk_divider *div = to_clk_divider(hw);
30 unsigned int val; 30 unsigned int val;
31 31
32 val = clk_readl(div->reg) >> div->shift; 32 val = readl(div->reg) >> div->shift;
33 val &= clk_div_mask(div->width); 33 val &= clk_div_mask(div->width);
34 if (!val) 34 if (!val)
35 return 0; 35 return 0;
@@ -51,7 +51,7 @@ static unsigned long clk_divider_gate_recalc_rate(struct clk_hw *hw,
51 if (!clk_hw_is_enabled(hw)) { 51 if (!clk_hw_is_enabled(hw)) {
52 val = div_gate->cached_val; 52 val = div_gate->cached_val;
53 } else { 53 } else {
54 val = clk_readl(div->reg) >> div->shift; 54 val = readl(div->reg) >> div->shift;
55 val &= clk_div_mask(div->width); 55 val &= clk_div_mask(div->width);
56 } 56 }
57 57
@@ -87,10 +87,10 @@ static int clk_divider_gate_set_rate(struct clk_hw *hw, unsigned long rate,
87 spin_lock_irqsave(div->lock, flags); 87 spin_lock_irqsave(div->lock, flags);
88 88
89 if (clk_hw_is_enabled(hw)) { 89 if (clk_hw_is_enabled(hw)) {
90 val = clk_readl(div->reg); 90 val = readl(div->reg);
91 val &= ~(clk_div_mask(div->width) << div->shift); 91 val &= ~(clk_div_mask(div->width) << div->shift);
92 val |= (u32)value << div->shift; 92 val |= (u32)value << div->shift;
93 clk_writel(val, div->reg); 93 writel(val, div->reg);
94 } else { 94 } else {
95 div_gate->cached_val = value; 95 div_gate->cached_val = value;
96 } 96 }
@@ -114,9 +114,9 @@ static int clk_divider_enable(struct clk_hw *hw)
114 114
115 spin_lock_irqsave(div->lock, flags); 115 spin_lock_irqsave(div->lock, flags);
116 /* restore div val */ 116 /* restore div val */
117 val = clk_readl(div->reg); 117 val = readl(div->reg);
118 val |= div_gate->cached_val << div->shift; 118 val |= div_gate->cached_val << div->shift;
119 clk_writel(val, div->reg); 119 writel(val, div->reg);
120 120
121 spin_unlock_irqrestore(div->lock, flags); 121 spin_unlock_irqrestore(div->lock, flags);
122 122
@@ -133,10 +133,10 @@ static void clk_divider_disable(struct clk_hw *hw)
133 spin_lock_irqsave(div->lock, flags); 133 spin_lock_irqsave(div->lock, flags);
134 134
135 /* store the current div val */ 135 /* store the current div val */
136 val = clk_readl(div->reg) >> div->shift; 136 val = readl(div->reg) >> div->shift;
137 val &= clk_div_mask(div->width); 137 val &= clk_div_mask(div->width);
138 div_gate->cached_val = val; 138 div_gate->cached_val = val;
139 clk_writel(0, div->reg); 139 writel(0, div->reg);
140 140
141 spin_unlock_irqrestore(div->lock, flags); 141 spin_unlock_irqrestore(div->lock, flags);
142} 142}
@@ -146,7 +146,7 @@ static int clk_divider_is_enabled(struct clk_hw *hw)
146 struct clk_divider *div = to_clk_divider(hw); 146 struct clk_divider *div = to_clk_divider(hw);
147 u32 val; 147 u32 val;
148 148
149 val = clk_readl(div->reg) >> div->shift; 149 val = readl(div->reg) >> div->shift;
150 val &= clk_div_mask(div->width); 150 val &= clk_div_mask(div->width);
151 151
152 return val ? 1 : 0; 152 return val ? 1 : 0;
@@ -206,7 +206,7 @@ struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name,
206 div_gate->divider.hw.init = &init; 206 div_gate->divider.hw.init = &init;
207 div_gate->divider.flags = CLK_DIVIDER_ONE_BASED | clk_divider_flags; 207 div_gate->divider.flags = CLK_DIVIDER_ONE_BASED | clk_divider_flags;
208 /* cache gate status */ 208 /* cache gate status */
209 val = clk_readl(reg) >> shift; 209 val = readl(reg) >> shift;
210 val &= clk_div_mask(width); 210 val &= clk_div_mask(width);
211 div_gate->cached_val = val; 211 div_gate->cached_val = val;
212 212
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx5.c
index e91c826bce70..c85ebd74a8a5 100644
--- a/drivers/clk/imx/clk-imx51-imx53.c
+++ b/drivers/clk/imx/clk-imx5.c
@@ -164,10 +164,6 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
164 clk[IMX5_CLK_CKIH1] = imx_obtain_fixed_clock("ckih1", 0); 164 clk[IMX5_CLK_CKIH1] = imx_obtain_fixed_clock("ckih1", 0);
165 clk[IMX5_CLK_CKIH2] = imx_obtain_fixed_clock("ckih2", 0); 165 clk[IMX5_CLK_CKIH2] = imx_obtain_fixed_clock("ckih2", 0);
166 166
167 clk[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2,
168 periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
169 clk[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1,
170 main_bus_sel, ARRAY_SIZE(main_bus_sel));
171 clk[IMX5_CLK_PER_LP_APM] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1, 167 clk[IMX5_CLK_PER_LP_APM] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1,
172 per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel)); 168 per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel));
173 clk[IMX5_CLK_PER_PRED1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2); 169 clk[IMX5_CLK_PER_PRED1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2);
@@ -191,16 +187,10 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
191 clk[IMX5_CLK_UART_PRED] = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3); 187 clk[IMX5_CLK_UART_PRED] = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3);
192 clk[IMX5_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3); 188 clk[IMX5_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3);
193 189
194 clk[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2,
195 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
196 clk[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2,
197 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
198 clk[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3); 190 clk[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3);
199 clk[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3); 191 clk[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3);
200 clk[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3); 192 clk[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3);
201 clk[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3); 193 clk[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3);
202 clk[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
203 clk[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
204 194
205 clk[IMX5_CLK_EMI_SEL] = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1, 195 clk[IMX5_CLK_EMI_SEL] = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1,
206 emi_slow_sel, ARRAY_SIZE(emi_slow_sel)); 196 emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
@@ -311,10 +301,6 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
311 clk_register_clkdev(clk[IMX5_CLK_CPU_PODF], NULL, "cpu0"); 301 clk_register_clkdev(clk[IMX5_CLK_CPU_PODF], NULL, "cpu0");
312 clk_register_clkdev(clk[IMX5_CLK_GPC_DVFS], "gpc_dvfs", NULL); 302 clk_register_clkdev(clk[IMX5_CLK_GPC_DVFS], "gpc_dvfs", NULL);
313 303
314 /* Set SDHC parents to be PLL2 */
315 clk_set_parent(clk[IMX5_CLK_ESDHC_A_SEL], clk[IMX5_CLK_PLL2_SW]);
316 clk_set_parent(clk[IMX5_CLK_ESDHC_B_SEL], clk[IMX5_CLK_PLL2_SW]);
317
318 /* move usb phy clk to 24MHz */ 304 /* move usb phy clk to 24MHz */
319 clk_set_parent(clk[IMX5_CLK_USB_PHY_SEL], clk[IMX5_CLK_OSC]); 305 clk_set_parent(clk[IMX5_CLK_USB_PHY_SEL], clk[IMX5_CLK_OSC]);
320} 306}
@@ -342,8 +328,21 @@ static void __init mx50_clocks_init(struct device_node *np)
342 328
343 mx5_clocks_common_init(ccm_base); 329 mx5_clocks_common_init(ccm_base);
344 330
331 /*
332 * This clock is called periph_clk in the i.MX50 Reference Manual, but
333 * it comes closest in scope to the main_bus_clk of i.MX51 and i.MX53
334 */
335 clk[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 2,
336 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
337
345 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1, 338 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1,
346 lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); 339 lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
340 clk[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 21, 2,
341 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
342 clk[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2,
343 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
344 clk[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 20, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
345 clk[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
347 clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); 346 clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
348 clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6); 347 clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
349 clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10); 348 clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
@@ -372,6 +371,10 @@ static void __init mx50_clocks_init(struct device_node *np)
372 clk_data.clk_num = ARRAY_SIZE(clk); 371 clk_data.clk_num = ARRAY_SIZE(clk);
373 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 372 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
374 373
374 /* Set SDHC parents to be PLL2 */
375 clk_set_parent(clk[IMX5_CLK_ESDHC_A_SEL], clk[IMX5_CLK_PLL2_SW]);
376 clk_set_parent(clk[IMX5_CLK_ESDHC_B_SEL], clk[IMX5_CLK_PLL2_SW]);
377
375 /* set SDHC root clock to 200MHZ*/ 378 /* set SDHC root clock to 200MHZ*/
376 clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000); 379 clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000);
377 clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000); 380 clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000);
@@ -410,6 +413,10 @@ static void __init mx51_clocks_init(struct device_node *np)
410 413
411 mx5_clocks_common_init(ccm_base); 414 mx5_clocks_common_init(ccm_base);
412 415
416 clk[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2,
417 periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
418 clk[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1,
419 main_bus_sel, ARRAY_SIZE(main_bus_sel));
413 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1, 420 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
414 lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); 421 lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
415 clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_flags("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, 422 clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_flags("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
@@ -422,6 +429,12 @@ static void __init mx51_clocks_init(struct device_node *np)
422 mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel)); 429 mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
423 clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30); 430 clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
424 clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3); 431 clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
432 clk[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2,
433 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
434 clk[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2,
435 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
436 clk[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
437 clk[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
425 clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); 438 clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
426 clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6); 439 clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6);
427 clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10); 440 clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10);
@@ -452,6 +465,10 @@ static void __init mx51_clocks_init(struct device_node *np)
452 /* set the usboh3 parent to pll2_sw */ 465 /* set the usboh3 parent to pll2_sw */
453 clk_set_parent(clk[IMX5_CLK_USBOH3_SEL], clk[IMX5_CLK_PLL2_SW]); 466 clk_set_parent(clk[IMX5_CLK_USBOH3_SEL], clk[IMX5_CLK_PLL2_SW]);
454 467
468 /* Set SDHC parents to be PLL2 */
469 clk_set_parent(clk[IMX5_CLK_ESDHC_A_SEL], clk[IMX5_CLK_PLL2_SW]);
470 clk_set_parent(clk[IMX5_CLK_ESDHC_B_SEL], clk[IMX5_CLK_PLL2_SW]);
471
455 /* set SDHC root clock to 166.25MHZ*/ 472 /* set SDHC root clock to 166.25MHZ*/
456 clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 166250000); 473 clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 166250000);
457 clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 166250000); 474 clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 166250000);
@@ -506,6 +523,10 @@ static void __init mx53_clocks_init(struct device_node *np)
506 523
507 mx5_clocks_common_init(ccm_base); 524 mx5_clocks_common_init(ccm_base);
508 525
526 clk[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2,
527 periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
528 clk[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1,
529 main_bus_sel, ARRAY_SIZE(main_bus_sel));
509 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1, 530 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1,
510 lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); 531 lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
511 clk[IMX5_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); 532 clk[IMX5_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
@@ -527,6 +548,12 @@ static void __init mx53_clocks_init(struct device_node *np)
527 mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT); 548 mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT);
528 clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30); 549 clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
529 clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3); 550 clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
551 clk[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2,
552 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
553 clk[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2,
554 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
555 clk[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
556 clk[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
530 clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); 557 clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
531 clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6); 558 clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
532 clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10); 559 clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
@@ -589,6 +616,10 @@ static void __init mx53_clocks_init(struct device_node *np)
589 clk_data.clk_num = ARRAY_SIZE(clk); 616 clk_data.clk_num = ARRAY_SIZE(clk);
590 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 617 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
591 618
619 /* Set SDHC parents to be PLL2 */
620 clk_set_parent(clk[IMX5_CLK_ESDHC_A_SEL], clk[IMX5_CLK_PLL2_SW]);
621 clk_set_parent(clk[IMX5_CLK_ESDHC_B_SEL], clk[IMX5_CLK_PLL2_SW]);
622
592 /* set SDHC root clock to 200MHZ*/ 623 /* set SDHC root clock to 200MHZ*/
593 clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000); 624 clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000);
594 clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000); 625 clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000);
diff --git a/drivers/clk/imx/clk-imx6sll.c b/drivers/clk/imx/clk-imx6sll.c
index 3bd2044cf25c..7eea448cb9a9 100644
--- a/drivers/clk/imx/clk-imx6sll.c
+++ b/drivers/clk/imx/clk-imx6sll.c
@@ -76,6 +76,20 @@ static u32 share_count_ssi1;
76static u32 share_count_ssi2; 76static u32 share_count_ssi2;
77static u32 share_count_ssi3; 77static u32 share_count_ssi3;
78 78
79static struct clk ** const uart_clks[] __initconst = {
80 &clks[IMX6SLL_CLK_UART1_IPG],
81 &clks[IMX6SLL_CLK_UART1_SERIAL],
82 &clks[IMX6SLL_CLK_UART2_IPG],
83 &clks[IMX6SLL_CLK_UART2_SERIAL],
84 &clks[IMX6SLL_CLK_UART3_IPG],
85 &clks[IMX6SLL_CLK_UART3_SERIAL],
86 &clks[IMX6SLL_CLK_UART4_IPG],
87 &clks[IMX6SLL_CLK_UART4_SERIAL],
88 &clks[IMX6SLL_CLK_UART5_IPG],
89 &clks[IMX6SLL_CLK_UART5_SERIAL],
90 NULL
91};
92
79static void __init imx6sll_clocks_init(struct device_node *ccm_node) 93static void __init imx6sll_clocks_init(struct device_node *ccm_node)
80{ 94{
81 struct device_node *np; 95 struct device_node *np;
@@ -268,7 +282,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node)
268 clks[IMX6SLL_CLK_GPT_BUS] = imx_clk_gate2("gpt1_bus", "perclk", base + 0x6c, 20); 282 clks[IMX6SLL_CLK_GPT_BUS] = imx_clk_gate2("gpt1_bus", "perclk", base + 0x6c, 20);
269 clks[IMX6SLL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22); 283 clks[IMX6SLL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22);
270 clks[IMX6SLL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24); 284 clks[IMX6SLL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24);
271 clks[IMX6SLL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serail", "uart_podf", base + 0x6c, 24); 285 clks[IMX6SLL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serial", "uart_podf", base + 0x6c, 24);
272 clks[IMX6SLL_CLK_GPIO1] = imx_clk_gate2("gpio1", "ipg", base + 0x6c, 26); 286 clks[IMX6SLL_CLK_GPIO1] = imx_clk_gate2("gpio1", "ipg", base + 0x6c, 26);
273 clks[IMX6SLL_CLK_GPIO5] = imx_clk_gate2("gpio5", "ipg", base + 0x6c, 30); 287 clks[IMX6SLL_CLK_GPIO5] = imx_clk_gate2("gpio5", "ipg", base + 0x6c, 30);
274 288
@@ -334,6 +348,8 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node)
334 clk_data.clk_num = ARRAY_SIZE(clks); 348 clk_data.clk_num = ARRAY_SIZE(clks);
335 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 349 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
336 350
351 imx_register_uart_clocks(uart_clks);
352
337 /* Lower the AHB clock rate before changing the clock source. */ 353 /* Lower the AHB clock rate before changing the clock source. */
338 clk_set_rate(clks[IMX6SLL_CLK_AHB], 99000000); 354 clk_set_rate(clks[IMX6SLL_CLK_AHB], 99000000);
339 355
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index cfbd8d4edb85..5b8a0c729f90 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -417,8 +417,8 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
417 clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_DDR_IMX7, "pll_dram_main", "osc", base + 0x70, 0x7f); 417 clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_DDR_IMX7, "pll_dram_main", "osc", base + 0x70, 0x7f);
418 clks[IMX7D_PLL_SYS_MAIN] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "osc", base + 0xb0, 0x1); 418 clks[IMX7D_PLL_SYS_MAIN] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "osc", base + 0xb0, 0x1);
419 clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "osc", base + 0xe0, 0x0); 419 clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "osc", base + 0xe0, 0x0);
420 clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_audio_main", "osc", base + 0xf0, 0x7f); 420 clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV_IMX7, "pll_audio_main", "osc", base + 0xf0, 0x7f);
421 clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_video_main", "osc", base + 0x130, 0x7f); 421 clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV_IMX7, "pll_video_main", "osc", base + 0x130, 0x7f);
422 422
423 clks[IMX7D_PLL_ARM_MAIN_BYPASS] = imx_clk_mux_flags("pll_arm_main_bypass", base + 0x60, 16, 1, pll_arm_bypass_sel, ARRAY_SIZE(pll_arm_bypass_sel), CLK_SET_RATE_PARENT); 423 clks[IMX7D_PLL_ARM_MAIN_BYPASS] = imx_clk_mux_flags("pll_arm_main_bypass", base + 0x60, 16, 1, pll_arm_bypass_sel, ARRAY_SIZE(pll_arm_bypass_sel), CLK_SET_RATE_PARENT);
424 clks[IMX7D_PLL_DRAM_MAIN_BYPASS] = imx_clk_mux_flags("pll_dram_main_bypass", base + 0x70, 16, 1, pll_dram_bypass_sel, ARRAY_SIZE(pll_dram_bypass_sel), CLK_SET_RATE_PARENT); 424 clks[IMX7D_PLL_DRAM_MAIN_BYPASS] = imx_clk_mux_flags("pll_dram_main_bypass", base + 0x70, 16, 1, pll_dram_bypass_sel, ARRAY_SIZE(pll_dram_bypass_sel), CLK_SET_RATE_PARENT);
diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c
index ce306631e844..66682100f14c 100644
--- a/drivers/clk/imx/clk-imx7ulp.c
+++ b/drivers/clk/imx/clk-imx7ulp.c
@@ -151,7 +151,6 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
151 clks[IMX7ULP_CLK_DMA1] = imx_clk_hw_gate("dma1", "nic1_clk", base + 0x20, 30); 151 clks[IMX7ULP_CLK_DMA1] = imx_clk_hw_gate("dma1", "nic1_clk", base + 0x20, 30);
152 clks[IMX7ULP_CLK_RGPIO2P1] = imx_clk_hw_gate("rgpio2p1", "nic1_bus_clk", base + 0x3c, 30); 152 clks[IMX7ULP_CLK_RGPIO2P1] = imx_clk_hw_gate("rgpio2p1", "nic1_bus_clk", base + 0x3c, 30);
153 clks[IMX7ULP_CLK_DMA_MUX1] = imx_clk_hw_gate("dma_mux1", "nic1_bus_clk", base + 0x84, 30); 153 clks[IMX7ULP_CLK_DMA_MUX1] = imx_clk_hw_gate("dma_mux1", "nic1_bus_clk", base + 0x84, 30);
154 clks[IMX7ULP_CLK_SNVS] = imx_clk_hw_gate("snvs", "nic1_bus_clk", base + 0x8c, 30);
155 clks[IMX7ULP_CLK_CAAM] = imx_clk_hw_gate("caam", "nic1_clk", base + 0x90, 30); 154 clks[IMX7ULP_CLK_CAAM] = imx_clk_hw_gate("caam", "nic1_clk", base + 0x90, 30);
156 clks[IMX7ULP_CLK_LPTPM4] = imx7ulp_clk_composite("lptpm4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94); 155 clks[IMX7ULP_CLK_LPTPM4] = imx7ulp_clk_composite("lptpm4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
157 clks[IMX7ULP_CLK_LPTPM5] = imx7ulp_clk_composite("lptpm5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98); 156 clks[IMX7ULP_CLK_LPTPM5] = imx7ulp_clk_composite("lptpm5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index a9b3888aef0c..daf1841b2adb 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -458,6 +458,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
458 clks[IMX8MQ_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mq_dsi_dbi_sels, base + 0xbc00); 458 clks[IMX8MQ_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mq_dsi_dbi_sels, base + 0xbc00);
459 clks[IMX8MQ_CLK_DSI_ESC] = imx8m_clk_composite("dsi_esc", imx8mq_dsi_esc_sels, base + 0xbc80); 459 clks[IMX8MQ_CLK_DSI_ESC] = imx8m_clk_composite("dsi_esc", imx8mq_dsi_esc_sels, base + 0xbc80);
460 clks[IMX8MQ_CLK_DSI_AHB] = imx8m_clk_composite("dsi_ahb", imx8mq_dsi_ahb_sels, base + 0x9200); 460 clks[IMX8MQ_CLK_DSI_AHB] = imx8m_clk_composite("dsi_ahb", imx8mq_dsi_ahb_sels, base + 0x9200);
461 clks[IMX8MQ_CLK_DSI_IPG_DIV] = imx_clk_divider2("dsi_ipg_div", "dsi_ahb", base + 0x9280, 0, 6);
461 clks[IMX8MQ_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mq_csi1_core_sels, base + 0xbd00); 462 clks[IMX8MQ_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mq_csi1_core_sels, base + 0xbd00);
462 clks[IMX8MQ_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mq_csi1_phy_sels, base + 0xbd80); 463 clks[IMX8MQ_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mq_csi1_phy_sels, base + 0xbd80);
463 clks[IMX8MQ_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mq_csi1_esc_sels, base + 0xbe00); 464 clks[IMX8MQ_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mq_csi1_esc_sels, base + 0xbe00);
diff --git a/drivers/clk/imx/clk-pfdv2.c b/drivers/clk/imx/clk-pfdv2.c
index 7e9134b205ab..fb567dcc2118 100644
--- a/drivers/clk/imx/clk-pfdv2.c
+++ b/drivers/clk/imx/clk-pfdv2.c
@@ -43,7 +43,7 @@ static int clk_pfdv2_wait(struct clk_pfdv2 *pfd)
43{ 43{
44 u32 val; 44 u32 val;
45 45
46 return readl_poll_timeout(pfd->reg, val, val & pfd->vld_bit, 46 return readl_poll_timeout(pfd->reg, val, val & (1 << pfd->vld_bit),
47 0, LOCK_TIMEOUT_US); 47 0, LOCK_TIMEOUT_US);
48} 48}
49 49
@@ -55,7 +55,7 @@ static int clk_pfdv2_enable(struct clk_hw *hw)
55 55
56 spin_lock_irqsave(&pfd_lock, flags); 56 spin_lock_irqsave(&pfd_lock, flags);
57 val = readl_relaxed(pfd->reg); 57 val = readl_relaxed(pfd->reg);
58 val &= ~pfd->gate_bit; 58 val &= ~(1 << pfd->gate_bit);
59 writel_relaxed(val, pfd->reg); 59 writel_relaxed(val, pfd->reg);
60 spin_unlock_irqrestore(&pfd_lock, flags); 60 spin_unlock_irqrestore(&pfd_lock, flags);
61 61
@@ -70,7 +70,7 @@ static void clk_pfdv2_disable(struct clk_hw *hw)
70 70
71 spin_lock_irqsave(&pfd_lock, flags); 71 spin_lock_irqsave(&pfd_lock, flags);
72 val = readl_relaxed(pfd->reg); 72 val = readl_relaxed(pfd->reg);
73 val |= pfd->gate_bit; 73 val |= (1 << pfd->gate_bit);
74 writel_relaxed(val, pfd->reg); 74 writel_relaxed(val, pfd->reg);
75 spin_unlock_irqrestore(&pfd_lock, flags); 75 spin_unlock_irqrestore(&pfd_lock, flags);
76} 76}
@@ -123,7 +123,7 @@ static int clk_pfdv2_is_enabled(struct clk_hw *hw)
123{ 123{
124 struct clk_pfdv2 *pfd = to_clk_pfdv2(hw); 124 struct clk_pfdv2 *pfd = to_clk_pfdv2(hw);
125 125
126 if (readl_relaxed(pfd->reg) & pfd->gate_bit) 126 if (readl_relaxed(pfd->reg) & (1 << pfd->gate_bit))
127 return 0; 127 return 0;
128 128
129 return 1; 129 return 1;
@@ -180,7 +180,7 @@ struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name,
180 return ERR_PTR(-ENOMEM); 180 return ERR_PTR(-ENOMEM);
181 181
182 pfd->reg = reg; 182 pfd->reg = reg;
183 pfd->gate_bit = 1 << ((idx + 1) * 8 - 1); 183 pfd->gate_bit = (idx + 1) * 8 - 1;
184 pfd->vld_bit = pfd->gate_bit - 1; 184 pfd->vld_bit = pfd->gate_bit - 1;
185 pfd->frac_off = idx * 8; 185 pfd->frac_off = idx * 8;
186 186
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index 113d71042199..b7213023b238 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -74,10 +74,9 @@ static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw,
74 unsigned long parent_rate) 74 unsigned long parent_rate)
75{ 75{
76 struct clk_pll14xx *pll = to_clk_pll14xx(hw); 76 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
77 u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div; 77 u32 mdiv, pdiv, sdiv, pll_div;
78 u64 fvco = parent_rate; 78 u64 fvco = parent_rate;
79 79
80 pll_gnrl = readl_relaxed(pll->base);
81 pll_div = readl_relaxed(pll->base + 4); 80 pll_div = readl_relaxed(pll->base + 4);
82 mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT; 81 mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT;
83 pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT; 82 pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT;
@@ -93,11 +92,10 @@ static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw,
93 unsigned long parent_rate) 92 unsigned long parent_rate)
94{ 93{
95 struct clk_pll14xx *pll = to_clk_pll14xx(hw); 94 struct clk_pll14xx *pll = to_clk_pll14xx(hw);
96 u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1; 95 u32 mdiv, pdiv, sdiv, pll_div_ctl0, pll_div_ctl1;
97 short int kdiv; 96 short int kdiv;
98 u64 fvco = parent_rate; 97 u64 fvco = parent_rate;
99 98
100 pll_gnrl = readl_relaxed(pll->base);
101 pll_div_ctl0 = readl_relaxed(pll->base + 4); 99 pll_div_ctl0 = readl_relaxed(pll->base + 4);
102 pll_div_ctl1 = readl_relaxed(pll->base + 8); 100 pll_div_ctl1 = readl_relaxed(pll->base + 8);
103 mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT; 101 mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT;
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 9af62ee8f347..4110e713d259 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -20,6 +20,8 @@
20 20
21#define PLL_NUM_OFFSET 0x10 21#define PLL_NUM_OFFSET 0x10
22#define PLL_DENOM_OFFSET 0x20 22#define PLL_DENOM_OFFSET 0x20
23#define PLL_IMX7_NUM_OFFSET 0x20
24#define PLL_IMX7_DENOM_OFFSET 0x30
23 25
24#define PLL_VF610_NUM_OFFSET 0x20 26#define PLL_VF610_NUM_OFFSET 0x20
25#define PLL_VF610_DENOM_OFFSET 0x30 27#define PLL_VF610_DENOM_OFFSET 0x30
@@ -49,6 +51,8 @@ struct clk_pllv3 {
49 u32 div_mask; 51 u32 div_mask;
50 u32 div_shift; 52 u32 div_shift;
51 unsigned long ref_clock; 53 unsigned long ref_clock;
54 u32 num_offset;
55 u32 denom_offset;
52}; 56};
53 57
54#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw) 58#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
@@ -219,8 +223,8 @@ static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
219 unsigned long parent_rate) 223 unsigned long parent_rate)
220{ 224{
221 struct clk_pllv3 *pll = to_clk_pllv3(hw); 225 struct clk_pllv3 *pll = to_clk_pllv3(hw);
222 u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET); 226 u32 mfn = readl_relaxed(pll->base + pll->num_offset);
223 u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET); 227 u32 mfd = readl_relaxed(pll->base + pll->denom_offset);
224 u32 div = readl_relaxed(pll->base) & pll->div_mask; 228 u32 div = readl_relaxed(pll->base) & pll->div_mask;
225 u64 temp64 = (u64)parent_rate; 229 u64 temp64 = (u64)parent_rate;
226 230
@@ -289,8 +293,8 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
289 val &= ~pll->div_mask; 293 val &= ~pll->div_mask;
290 val |= div; 294 val |= div;
291 writel_relaxed(val, pll->base); 295 writel_relaxed(val, pll->base);
292 writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET); 296 writel_relaxed(mfn, pll->base + pll->num_offset);
293 writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET); 297 writel_relaxed(mfd, pll->base + pll->denom_offset);
294 298
295 return clk_pllv3_wait_lock(pll); 299 return clk_pllv3_wait_lock(pll);
296} 300}
@@ -352,8 +356,8 @@ static unsigned long clk_pllv3_vf610_recalc_rate(struct clk_hw *hw,
352 struct clk_pllv3 *pll = to_clk_pllv3(hw); 356 struct clk_pllv3 *pll = to_clk_pllv3(hw);
353 struct clk_pllv3_vf610_mf mf; 357 struct clk_pllv3_vf610_mf mf;
354 358
355 mf.mfn = readl_relaxed(pll->base + PLL_VF610_NUM_OFFSET); 359 mf.mfn = readl_relaxed(pll->base + pll->num_offset);
356 mf.mfd = readl_relaxed(pll->base + PLL_VF610_DENOM_OFFSET); 360 mf.mfd = readl_relaxed(pll->base + pll->denom_offset);
357 mf.mfi = (readl_relaxed(pll->base) & pll->div_mask) ? 22 : 20; 361 mf.mfi = (readl_relaxed(pll->base) & pll->div_mask) ? 22 : 20;
358 362
359 return clk_pllv3_vf610_mf_to_rate(parent_rate, mf); 363 return clk_pllv3_vf610_mf_to_rate(parent_rate, mf);
@@ -382,8 +386,8 @@ static int clk_pllv3_vf610_set_rate(struct clk_hw *hw, unsigned long rate,
382 val |= pll->div_mask; /* set bit for mfi=22 */ 386 val |= pll->div_mask; /* set bit for mfi=22 */
383 writel_relaxed(val, pll->base); 387 writel_relaxed(val, pll->base);
384 388
385 writel_relaxed(mf.mfn, pll->base + PLL_VF610_NUM_OFFSET); 389 writel_relaxed(mf.mfn, pll->base + pll->num_offset);
386 writel_relaxed(mf.mfd, pll->base + PLL_VF610_DENOM_OFFSET); 390 writel_relaxed(mf.mfd, pll->base + pll->denom_offset);
387 391
388 return clk_pllv3_wait_lock(pll); 392 return clk_pllv3_wait_lock(pll);
389} 393}
@@ -426,6 +430,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
426 return ERR_PTR(-ENOMEM); 430 return ERR_PTR(-ENOMEM);
427 431
428 pll->power_bit = BM_PLL_POWER; 432 pll->power_bit = BM_PLL_POWER;
433 pll->num_offset = PLL_NUM_OFFSET;
434 pll->denom_offset = PLL_DENOM_OFFSET;
429 435
430 switch (type) { 436 switch (type) {
431 case IMX_PLLV3_SYS: 437 case IMX_PLLV3_SYS:
@@ -433,13 +439,20 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
433 break; 439 break;
434 case IMX_PLLV3_SYS_VF610: 440 case IMX_PLLV3_SYS_VF610:
435 ops = &clk_pllv3_vf610_ops; 441 ops = &clk_pllv3_vf610_ops;
442 pll->num_offset = PLL_VF610_NUM_OFFSET;
443 pll->denom_offset = PLL_VF610_DENOM_OFFSET;
436 break; 444 break;
437 case IMX_PLLV3_USB_VF610: 445 case IMX_PLLV3_USB_VF610:
438 pll->div_shift = 1; 446 pll->div_shift = 1;
447 /* fall through */
439 case IMX_PLLV3_USB: 448 case IMX_PLLV3_USB:
440 ops = &clk_pllv3_ops; 449 ops = &clk_pllv3_ops;
441 pll->powerup_set = true; 450 pll->powerup_set = true;
442 break; 451 break;
452 case IMX_PLLV3_AV_IMX7:
453 pll->num_offset = PLL_IMX7_NUM_OFFSET;
454 pll->denom_offset = PLL_IMX7_DENOM_OFFSET;
455 /* fall through */
443 case IMX_PLLV3_AV: 456 case IMX_PLLV3_AV:
444 ops = &clk_pllv3_av_ops; 457 ops = &clk_pllv3_av_ops;
445 break; 458 break;
@@ -454,6 +467,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
454 break; 467 break;
455 case IMX_PLLV3_DDR_IMX7: 468 case IMX_PLLV3_DDR_IMX7:
456 pll->power_bit = IMX7_DDR_PLL_POWER; 469 pll->power_bit = IMX7_DDR_PLL_POWER;
470 pll->num_offset = PLL_IMX7_NUM_OFFSET;
471 pll->denom_offset = PLL_IMX7_DENOM_OFFSET;
457 ops = &clk_pllv3_av_ops; 472 ops = &clk_pllv3_av_ops;
458 break; 473 break;
459 default: 474 default:
diff --git a/drivers/clk/imx/clk-pllv4.c b/drivers/clk/imx/clk-pllv4.c
index d38bc9f87c1d..d7e62c3620d3 100644
--- a/drivers/clk/imx/clk-pllv4.c
+++ b/drivers/clk/imx/clk-pllv4.c
@@ -30,6 +30,9 @@
30/* PLL Denominator Register (xPLLDENOM) */ 30/* PLL Denominator Register (xPLLDENOM) */
31#define PLL_DENOM_OFFSET 0x14 31#define PLL_DENOM_OFFSET 0x14
32 32
33#define MAX_MFD 0x3fffffff
34#define DEFAULT_MFD 1000000
35
33struct clk_pllv4 { 36struct clk_pllv4 {
34 struct clk_hw hw; 37 struct clk_hw hw;
35 void __iomem *base; 38 void __iomem *base;
@@ -64,13 +67,20 @@ static unsigned long clk_pllv4_recalc_rate(struct clk_hw *hw,
64 unsigned long parent_rate) 67 unsigned long parent_rate)
65{ 68{
66 struct clk_pllv4 *pll = to_clk_pllv4(hw); 69 struct clk_pllv4 *pll = to_clk_pllv4(hw);
67 u32 div; 70 u32 mult, mfn, mfd;
71 u64 temp64;
72
73 mult = readl_relaxed(pll->base + PLL_CFG_OFFSET);
74 mult &= BM_PLL_MULT;
75 mult >>= BP_PLL_MULT;
68 76
69 div = readl_relaxed(pll->base + PLL_CFG_OFFSET); 77 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
70 div &= BM_PLL_MULT; 78 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
71 div >>= BP_PLL_MULT; 79 temp64 = parent_rate;
80 temp64 *= mfn;
81 do_div(temp64, mfd);
72 82
73 return parent_rate * div; 83 return (parent_rate * mult) + (u32)temp64;
74} 84}
75 85
76static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate, 86static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -78,14 +88,46 @@ static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate,
78{ 88{
79 unsigned long parent_rate = *prate; 89 unsigned long parent_rate = *prate;
80 unsigned long round_rate, i; 90 unsigned long round_rate, i;
91 u32 mfn, mfd = DEFAULT_MFD;
92 bool found = false;
93 u64 temp64;
81 94
82 for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) { 95 for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) {
83 round_rate = parent_rate * pllv4_mult_table[i]; 96 round_rate = parent_rate * pllv4_mult_table[i];
84 if (rate >= round_rate) 97 if (rate >= round_rate) {
85 return round_rate; 98 found = true;
99 break;
100 }
101 }
102
103 if (!found) {
104 pr_warn("%s: unable to round rate %lu, parent rate %lu\n",
105 clk_hw_get_name(hw), rate, parent_rate);
106 return 0;
86 } 107 }
87 108
88 return round_rate; 109 if (parent_rate <= MAX_MFD)
110 mfd = parent_rate;
111
112 temp64 = (u64)(rate - round_rate);
113 temp64 *= mfd;
114 do_div(temp64, parent_rate);
115 mfn = temp64;
116
117 /*
118 * NOTE: The value of numerator must always be configured to be
119 * less than the value of the denominator. If we can't get a proper
120 * pair of mfn/mfd, we simply return the round_rate without using
121 * the frac part.
122 */
123 if (mfn >= mfd)
124 return round_rate;
125
126 temp64 = (u64)parent_rate;
127 temp64 *= mfn;
128 do_div(temp64, mfd);
129
130 return round_rate + (u32)temp64;
89} 131}
90 132
91static bool clk_pllv4_is_valid_mult(unsigned int mult) 133static bool clk_pllv4_is_valid_mult(unsigned int mult)
@@ -105,18 +147,30 @@ static int clk_pllv4_set_rate(struct clk_hw *hw, unsigned long rate,
105 unsigned long parent_rate) 147 unsigned long parent_rate)
106{ 148{
107 struct clk_pllv4 *pll = to_clk_pllv4(hw); 149 struct clk_pllv4 *pll = to_clk_pllv4(hw);
108 u32 val, mult; 150 u32 val, mult, mfn, mfd = DEFAULT_MFD;
151 u64 temp64;
109 152
110 mult = rate / parent_rate; 153 mult = rate / parent_rate;
111 154
112 if (!clk_pllv4_is_valid_mult(mult)) 155 if (!clk_pllv4_is_valid_mult(mult))
113 return -EINVAL; 156 return -EINVAL;
114 157
158 if (parent_rate <= MAX_MFD)
159 mfd = parent_rate;
160
161 temp64 = (u64)(rate - mult * parent_rate);
162 temp64 *= mfd;
163 do_div(temp64, parent_rate);
164 mfn = temp64;
165
115 val = readl_relaxed(pll->base + PLL_CFG_OFFSET); 166 val = readl_relaxed(pll->base + PLL_CFG_OFFSET);
116 val &= ~BM_PLL_MULT; 167 val &= ~BM_PLL_MULT;
117 val |= mult << BP_PLL_MULT; 168 val |= mult << BP_PLL_MULT;
118 writel_relaxed(val, pll->base + PLL_CFG_OFFSET); 169 writel_relaxed(val, pll->base + PLL_CFG_OFFSET);
119 170
171 writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
172 writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
173
120 return 0; 174 return 0;
121} 175}
122 176
diff --git a/drivers/clk/imx/clk-sccg-pll.c b/drivers/clk/imx/clk-sccg-pll.c
index 9dfd03a95557..991bbe63f156 100644
--- a/drivers/clk/imx/clk-sccg-pll.c
+++ b/drivers/clk/imx/clk-sccg-pll.c
@@ -348,7 +348,7 @@ static unsigned long clk_sccg_pll_recalc_rate(struct clk_hw *hw,
348 348
349 temp64 = parent_rate; 349 temp64 = parent_rate;
350 350
351 val = clk_readl(pll->base + PLL_CFG0); 351 val = readl(pll->base + PLL_CFG0);
352 if (val & SSCG_PLL_BYPASS2_MASK) { 352 if (val & SSCG_PLL_BYPASS2_MASK) {
353 temp64 = parent_rate; 353 temp64 = parent_rate;
354 } else if (val & SSCG_PLL_BYPASS1_MASK) { 354 } else if (val & SSCG_PLL_BYPASS1_MASK) {
@@ -371,10 +371,10 @@ static int clk_sccg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
371 u32 val; 371 u32 val;
372 372
373 /* set bypass here too since the parent might be the same */ 373 /* set bypass here too since the parent might be the same */
374 val = clk_readl(pll->base + PLL_CFG0); 374 val = readl(pll->base + PLL_CFG0);
375 val &= ~SSCG_PLL_BYPASS_MASK; 375 val &= ~SSCG_PLL_BYPASS_MASK;
376 val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, setup->bypass); 376 val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, setup->bypass);
377 clk_writel(val, pll->base + PLL_CFG0); 377 writel(val, pll->base + PLL_CFG0);
378 378
379 val = readl_relaxed(pll->base + PLL_CFG2); 379 val = readl_relaxed(pll->base + PLL_CFG2);
380 val &= ~(PLL_DIVF1_MASK | PLL_DIVF2_MASK); 380 val &= ~(PLL_DIVF1_MASK | PLL_DIVF2_MASK);
@@ -395,7 +395,7 @@ static u8 clk_sccg_pll_get_parent(struct clk_hw *hw)
395 u32 val; 395 u32 val;
396 u8 ret = pll->parent; 396 u8 ret = pll->parent;
397 397
398 val = clk_readl(pll->base + PLL_CFG0); 398 val = readl(pll->base + PLL_CFG0);
399 if (val & SSCG_PLL_BYPASS2_MASK) 399 if (val & SSCG_PLL_BYPASS2_MASK)
400 ret = pll->bypass2; 400 ret = pll->bypass2;
401 else if (val & SSCG_PLL_BYPASS1_MASK) 401 else if (val & SSCG_PLL_BYPASS1_MASK)
@@ -408,10 +408,10 @@ static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index)
408 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw); 408 struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
409 u32 val; 409 u32 val;
410 410
411 val = clk_readl(pll->base + PLL_CFG0); 411 val = readl(pll->base + PLL_CFG0);
412 val &= ~SSCG_PLL_BYPASS_MASK; 412 val &= ~SSCG_PLL_BYPASS_MASK;
413 val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass); 413 val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass);
414 clk_writel(val, pll->base + PLL_CFG0); 414 writel(val, pll->base + PLL_CFG0);
415 415
416 return clk_sccg_pll_wait_lock(pll); 416 return clk_sccg_pll_wait_lock(pll);
417} 417}
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 5748ec8673e4..8639a8f2153e 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -77,6 +77,7 @@ enum imx_pllv3_type {
77 IMX_PLLV3_ENET_IMX7, 77 IMX_PLLV3_ENET_IMX7,
78 IMX_PLLV3_SYS_VF610, 78 IMX_PLLV3_SYS_VF610,
79 IMX_PLLV3_DDR_IMX7, 79 IMX_PLLV3_DDR_IMX7,
80 IMX_PLLV3_AV_IMX7,
80}; 81};
81 82
82struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, 83struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
@@ -138,11 +139,6 @@ static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
138 return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate); 139 return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
139} 140}
140 141
141static inline struct clk_hw *imx_get_clk_hw_fixed(const char *name, int rate)
142{
143 return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
144}
145
146static inline struct clk *imx_clk_mux_ldb(const char *name, void __iomem *reg, 142static inline struct clk *imx_clk_mux_ldb(const char *name, void __iomem *reg,
147 u8 shift, u8 width, const char * const *parents, 143 u8 shift, u8 width, const char * const *parents,
148 int num_parents) 144 int num_parents)
diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c
index 584ff4ff81c7..8901ea0295b7 100644
--- a/drivers/clk/ingenic/jz4725b-cgu.c
+++ b/drivers/clk/ingenic/jz4725b-cgu.c
@@ -205,6 +205,12 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
205 .parents = { JZ4725B_CLK_EXT512, JZ4725B_CLK_OSC32K, -1, -1 }, 205 .parents = { JZ4725B_CLK_EXT512, JZ4725B_CLK_OSC32K, -1, -1 },
206 .mux = { CGU_REG_OPCR, 2, 1}, 206 .mux = { CGU_REG_OPCR, 2, 1},
207 }, 207 },
208
209 [JZ4725B_CLK_UDC_PHY] = {
210 "udc_phy", CGU_CLK_GATE,
211 .parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
212 .gate = { CGU_REG_OPCR, 6, true },
213 },
208}; 214};
209 215
210static void __init jz4725b_cgu_init(struct device_node *np) 216static void __init jz4725b_cgu_init(struct device_node *np)
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 53edade25a1d..4d8a9aef95f6 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -216,4 +216,87 @@ config COMMON_CLK_MT8173
216 default ARCH_MEDIATEK 216 default ARCH_MEDIATEK
217 ---help--- 217 ---help---
218 This driver supports MediaTek MT8173 clocks. 218 This driver supports MediaTek MT8173 clocks.
219
220config COMMON_CLK_MT8183
221 bool "Clock driver for MediaTek MT8183"
222 depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
223 select COMMON_CLK_MEDIATEK
224 default ARCH_MEDIATEK && ARM64
225 help
226 This driver supports MediaTek MT8183 basic clocks.
227
228config COMMON_CLK_MT8183_AUDIOSYS
229 bool "Clock driver for MediaTek MT8183 audiosys"
230 depends on COMMON_CLK_MT8183
231 help
232 This driver supports MediaTek MT8183 audiosys clocks.
233
234config COMMON_CLK_MT8183_CAMSYS
235 bool "Clock driver for MediaTek MT8183 camsys"
236 depends on COMMON_CLK_MT8183
237 help
238 This driver supports MediaTek MT8183 camsys clocks.
239
240config COMMON_CLK_MT8183_IMGSYS
241 bool "Clock driver for MediaTek MT8183 imgsys"
242 depends on COMMON_CLK_MT8183
243 help
244 This driver supports MediaTek MT8183 imgsys clocks.
245
246config COMMON_CLK_MT8183_IPU_CORE0
247 bool "Clock driver for MediaTek MT8183 ipu_core0"
248 depends on COMMON_CLK_MT8183
249 help
250 This driver supports MediaTek MT8183 ipu_core0 clocks.
251
252config COMMON_CLK_MT8183_IPU_CORE1
253 bool "Clock driver for MediaTek MT8183 ipu_core1"
254 depends on COMMON_CLK_MT8183
255 help
256 This driver supports MediaTek MT8183 ipu_core1 clocks.
257
258config COMMON_CLK_MT8183_IPU_ADL
259 bool "Clock driver for MediaTek MT8183 ipu_adl"
260 depends on COMMON_CLK_MT8183
261 help
262 This driver supports MediaTek MT8183 ipu_adl clocks.
263
264config COMMON_CLK_MT8183_IPU_CONN
265 bool "Clock driver for MediaTek MT8183 ipu_conn"
266 depends on COMMON_CLK_MT8183
267 help
268 This driver supports MediaTek MT8183 ipu_conn clocks.
269
270config COMMON_CLK_MT8183_MFGCFG
271 bool "Clock driver for MediaTek MT8183 mfgcfg"
272 depends on COMMON_CLK_MT8183
273 help
274 This driver supports MediaTek MT8183 mfgcfg clocks.
275
276config COMMON_CLK_MT8183_MMSYS
277 bool "Clock driver for MediaTek MT8183 mmsys"
278 depends on COMMON_CLK_MT8183
279 help
280 This driver supports MediaTek MT8183 mmsys clocks.
281
282config COMMON_CLK_MT8183_VDECSYS
283 bool "Clock driver for MediaTek MT8183 vdecsys"
284 depends on COMMON_CLK_MT8183
285 help
286 This driver supports MediaTek MT8183 vdecsys clocks.
287
288config COMMON_CLK_MT8183_VENCSYS
289 bool "Clock driver for MediaTek MT8183 vencsys"
290 depends on COMMON_CLK_MT8183
291 help
292 This driver supports MediaTek MT8183 vencsys clocks.
293
294config COMMON_CLK_MT8516
295 bool "Clock driver for MediaTek MT8516"
296 depends on ARCH_MEDIATEK || COMPILE_TEST
297 select COMMON_CLK_MEDIATEK
298 default ARCH_MEDIATEK
299 help
300 This driver supports MediaTek MT8516 clocks.
301
219endmenu 302endmenu
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index ee4410ff43ab..f74937b35f68 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,5 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o 2obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.o
3
3obj-$(CONFIG_COMMON_CLK_MT6797) += clk-mt6797.o 4obj-$(CONFIG_COMMON_CLK_MT6797) += clk-mt6797.o
4obj-$(CONFIG_COMMON_CLK_MT6797_IMGSYS) += clk-mt6797-img.o 5obj-$(CONFIG_COMMON_CLK_MT6797_IMGSYS) += clk-mt6797-img.o
5obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o 6obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o
@@ -31,3 +32,16 @@ obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
31obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o 32obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
32obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o 33obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
33obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o 34obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
35obj-$(CONFIG_COMMON_CLK_MT8183) += clk-mt8183.o
36obj-$(CONFIG_COMMON_CLK_MT8183_AUDIOSYS) += clk-mt8183-audio.o
37obj-$(CONFIG_COMMON_CLK_MT8183_CAMSYS) += clk-mt8183-cam.o
38obj-$(CONFIG_COMMON_CLK_MT8183_IMGSYS) += clk-mt8183-img.o
39obj-$(CONFIG_COMMON_CLK_MT8183_IPU_CORE0) += clk-mt8183-ipu0.o
40obj-$(CONFIG_COMMON_CLK_MT8183_IPU_CORE1) += clk-mt8183-ipu1.o
41obj-$(CONFIG_COMMON_CLK_MT8183_IPU_ADL) += clk-mt8183-ipu_adl.o
42obj-$(CONFIG_COMMON_CLK_MT8183_IPU_CONN) += clk-mt8183-ipu_conn.o
43obj-$(CONFIG_COMMON_CLK_MT8183_MFGCFG) += clk-mt8183-mfgcfg.o
44obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
45obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
46obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
47obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h
index 9f766dfe1d57..ab240163f9f8 100644
--- a/drivers/clk/mediatek/clk-gate.h
+++ b/drivers/clk/mediatek/clk-gate.h
@@ -50,4 +50,18 @@ struct clk *mtk_clk_register_gate(
50 const struct clk_ops *ops, 50 const struct clk_ops *ops,
51 unsigned long flags); 51 unsigned long flags);
52 52
53#define GATE_MTK_FLAGS(_id, _name, _parent, _regs, _shift, \
54 _ops, _flags) { \
55 .id = _id, \
56 .name = _name, \
57 .parent_name = _parent, \
58 .regs = _regs, \
59 .shift = _shift, \
60 .ops = _ops, \
61 .flags = _flags, \
62 }
63
64#define GATE_MTK(_id, _name, _parent, _regs, _shift, _ops) \
65 GATE_MTK_FLAGS(_id, _name, _parent, _regs, _shift, _ops, 0)
66
53#endif /* __DRV_CLK_GATE_H */ 67#endif /* __DRV_CLK_GATE_H */
diff --git a/drivers/clk/mediatek/clk-mt8183-audio.c b/drivers/clk/mediatek/clk-mt8183-audio.c
new file mode 100644
index 000000000000..c87450180b7b
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183-audio.c
@@ -0,0 +1,105 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/clk-provider.h>
7#include <linux/of_platform.h>
8#include <linux/platform_device.h>
9
10#include "clk-mtk.h"
11#include "clk-gate.h"
12
13#include <dt-bindings/clock/mt8183-clk.h>
14
15static const struct mtk_gate_regs audio0_cg_regs = {
16 .set_ofs = 0x0,
17 .clr_ofs = 0x0,
18 .sta_ofs = 0x0,
19};
20
21static const struct mtk_gate_regs audio1_cg_regs = {
22 .set_ofs = 0x4,
23 .clr_ofs = 0x4,
24 .sta_ofs = 0x4,
25};
26
27#define GATE_AUDIO0(_id, _name, _parent, _shift) \
28 GATE_MTK(_id, _name, _parent, &audio0_cg_regs, _shift, \
29 &mtk_clk_gate_ops_no_setclr)
30
31#define GATE_AUDIO1(_id, _name, _parent, _shift) \
32 GATE_MTK(_id, _name, _parent, &audio1_cg_regs, _shift, \
33 &mtk_clk_gate_ops_no_setclr)
34
35static const struct mtk_gate audio_clks[] = {
36 /* AUDIO0 */
37 GATE_AUDIO0(CLK_AUDIO_AFE, "aud_afe", "audio_sel",
38 2),
39 GATE_AUDIO0(CLK_AUDIO_22M, "aud_22m", "aud_eng1_sel",
40 8),
41 GATE_AUDIO0(CLK_AUDIO_24M, "aud_24m", "aud_eng2_sel",
42 9),
43 GATE_AUDIO0(CLK_AUDIO_APLL2_TUNER, "aud_apll2_tuner", "aud_eng2_sel",
44 18),
45 GATE_AUDIO0(CLK_AUDIO_APLL_TUNER, "aud_apll_tuner", "aud_eng1_sel",
46 19),
47 GATE_AUDIO0(CLK_AUDIO_TDM, "aud_tdm", "apll12_divb",
48 20),
49 GATE_AUDIO0(CLK_AUDIO_ADC, "aud_adc", "audio_sel",
50 24),
51 GATE_AUDIO0(CLK_AUDIO_DAC, "aud_dac", "audio_sel",
52 25),
53 GATE_AUDIO0(CLK_AUDIO_DAC_PREDIS, "aud_dac_predis", "audio_sel",
54 26),
55 GATE_AUDIO0(CLK_AUDIO_TML, "aud_tml", "audio_sel",
56 27),
57 /* AUDIO1 */
58 GATE_AUDIO1(CLK_AUDIO_I2S1, "aud_i2s1", "audio_sel",
59 4),
60 GATE_AUDIO1(CLK_AUDIO_I2S2, "aud_i2s2", "audio_sel",
61 5),
62 GATE_AUDIO1(CLK_AUDIO_I2S3, "aud_i2s3", "audio_sel",
63 6),
64 GATE_AUDIO1(CLK_AUDIO_I2S4, "aud_i2s4", "audio_sel",
65 7),
66 GATE_AUDIO1(CLK_AUDIO_PDN_ADDA6_ADC, "aud_pdn_adda6_adc", "audio_sel",
67 20),
68};
69
70static int clk_mt8183_audio_probe(struct platform_device *pdev)
71{
72 struct clk_onecell_data *clk_data;
73 int r;
74 struct device_node *node = pdev->dev.of_node;
75
76 clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK);
77
78 mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
79 clk_data);
80
81 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
82 if (r)
83 return r;
84
85 r = devm_of_platform_populate(&pdev->dev);
86 if (r)
87 of_clk_del_provider(node);
88
89 return r;
90}
91
92static const struct of_device_id of_match_clk_mt8183_audio[] = {
93 { .compatible = "mediatek,mt8183-audiosys", },
94 {}
95};
96
97static struct platform_driver clk_mt8183_audio_drv = {
98 .probe = clk_mt8183_audio_probe,
99 .driver = {
100 .name = "clk-mt8183-audio",
101 .of_match_table = of_match_clk_mt8183_audio,
102 },
103};
104
105builtin_platform_driver(clk_mt8183_audio_drv);
diff --git a/drivers/clk/mediatek/clk-mt8183-cam.c b/drivers/clk/mediatek/clk-mt8183-cam.c
new file mode 100644
index 000000000000..8643802c4471
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183-cam.c
@@ -0,0 +1,63 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/clk-provider.h>
7#include <linux/platform_device.h>
8
9#include "clk-mtk.h"
10#include "clk-gate.h"
11
12#include <dt-bindings/clock/mt8183-clk.h>
13
14static const struct mtk_gate_regs cam_cg_regs = {
15 .set_ofs = 0x4,
16 .clr_ofs = 0x8,
17 .sta_ofs = 0x0,
18};
19
20#define GATE_CAM(_id, _name, _parent, _shift) \
21 GATE_MTK(_id, _name, _parent, &cam_cg_regs, _shift, \
22 &mtk_clk_gate_ops_setclr)
23
24static const struct mtk_gate cam_clks[] = {
25 GATE_CAM(CLK_CAM_LARB6, "cam_larb6", "cam_sel", 0),
26 GATE_CAM(CLK_CAM_DFP_VAD, "cam_dfp_vad", "cam_sel", 1),
27 GATE_CAM(CLK_CAM_LARB3, "cam_larb3", "cam_sel", 2),
28 GATE_CAM(CLK_CAM_CAM, "cam_cam", "cam_sel", 6),
29 GATE_CAM(CLK_CAM_CAMTG, "cam_camtg", "cam_sel", 7),
30 GATE_CAM(CLK_CAM_SENINF, "cam_seninf", "cam_sel", 8),
31 GATE_CAM(CLK_CAM_CAMSV0, "cam_camsv0", "cam_sel", 9),
32 GATE_CAM(CLK_CAM_CAMSV1, "cam_camsv1", "cam_sel", 10),
33 GATE_CAM(CLK_CAM_CAMSV2, "cam_camsv2", "cam_sel", 11),
34 GATE_CAM(CLK_CAM_CCU, "cam_ccu", "cam_sel", 12),
35};
36
37static int clk_mt8183_cam_probe(struct platform_device *pdev)
38{
39 struct clk_onecell_data *clk_data;
40 struct device_node *node = pdev->dev.of_node;
41
42 clk_data = mtk_alloc_clk_data(CLK_CAM_NR_CLK);
43
44 mtk_clk_register_gates(node, cam_clks, ARRAY_SIZE(cam_clks),
45 clk_data);
46
47 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
48}
49
50static const struct of_device_id of_match_clk_mt8183_cam[] = {
51 { .compatible = "mediatek,mt8183-camsys", },
52 {}
53};
54
55static struct platform_driver clk_mt8183_cam_drv = {
56 .probe = clk_mt8183_cam_probe,
57 .driver = {
58 .name = "clk-mt8183-cam",
59 .of_match_table = of_match_clk_mt8183_cam,
60 },
61};
62
63builtin_platform_driver(clk_mt8183_cam_drv);
diff --git a/drivers/clk/mediatek/clk-mt8183-img.c b/drivers/clk/mediatek/clk-mt8183-img.c
new file mode 100644
index 000000000000..470d676a4a10
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183-img.c
@@ -0,0 +1,63 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/clk-provider.h>
7#include <linux/platform_device.h>
8
9#include "clk-mtk.h"
10#include "clk-gate.h"
11
12#include <dt-bindings/clock/mt8183-clk.h>
13
14static const struct mtk_gate_regs img_cg_regs = {
15 .set_ofs = 0x4,
16 .clr_ofs = 0x8,
17 .sta_ofs = 0x0,
18};
19
20#define GATE_IMG(_id, _name, _parent, _shift) \
21 GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, \
22 &mtk_clk_gate_ops_setclr)
23
24static const struct mtk_gate img_clks[] = {
25 GATE_IMG(CLK_IMG_LARB5, "img_larb5", "img_sel", 0),
26 GATE_IMG(CLK_IMG_LARB2, "img_larb2", "img_sel", 1),
27 GATE_IMG(CLK_IMG_DIP, "img_dip", "img_sel", 2),
28 GATE_IMG(CLK_IMG_FDVT, "img_fdvt", "img_sel", 3),
29 GATE_IMG(CLK_IMG_DPE, "img_dpe", "img_sel", 4),
30 GATE_IMG(CLK_IMG_RSC, "img_rsc", "img_sel", 5),
31 GATE_IMG(CLK_IMG_MFB, "img_mfb", "img_sel", 6),
32 GATE_IMG(CLK_IMG_WPE_A, "img_wpe_a", "img_sel", 7),
33 GATE_IMG(CLK_IMG_WPE_B, "img_wpe_b", "img_sel", 8),
34 GATE_IMG(CLK_IMG_OWE, "img_owe", "img_sel", 9),
35};
36
37static int clk_mt8183_img_probe(struct platform_device *pdev)
38{
39 struct clk_onecell_data *clk_data;
40 struct device_node *node = pdev->dev.of_node;
41
42 clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
43
44 mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
45 clk_data);
46
47 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
48}
49
50static const struct of_device_id of_match_clk_mt8183_img[] = {
51 { .compatible = "mediatek,mt8183-imgsys", },
52 {}
53};
54
55static struct platform_driver clk_mt8183_img_drv = {
56 .probe = clk_mt8183_img_probe,
57 .driver = {
58 .name = "clk-mt8183-img",
59 .of_match_table = of_match_clk_mt8183_img,
60 },
61};
62
63builtin_platform_driver(clk_mt8183_img_drv);
diff --git a/drivers/clk/mediatek/clk-mt8183-ipu0.c b/drivers/clk/mediatek/clk-mt8183-ipu0.c
new file mode 100644
index 000000000000..c5cb76fc9e5e
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183-ipu0.c
@@ -0,0 +1,56 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/clk-provider.h>
7#include <linux/platform_device.h>
8
9#include "clk-mtk.h"
10#include "clk-gate.h"
11
12#include <dt-bindings/clock/mt8183-clk.h>
13
14static const struct mtk_gate_regs ipu_core0_cg_regs = {
15 .set_ofs = 0x4,
16 .clr_ofs = 0x8,
17 .sta_ofs = 0x0,
18};
19
20#define GATE_IPU_CORE0(_id, _name, _parent, _shift) \
21 GATE_MTK(_id, _name, _parent, &ipu_core0_cg_regs, _shift, \
22 &mtk_clk_gate_ops_setclr)
23
24static const struct mtk_gate ipu_core0_clks[] = {
25 GATE_IPU_CORE0(CLK_IPU_CORE0_JTAG, "ipu_core0_jtag", "dsp_sel", 0),
26 GATE_IPU_CORE0(CLK_IPU_CORE0_AXI, "ipu_core0_axi", "dsp_sel", 1),
27 GATE_IPU_CORE0(CLK_IPU_CORE0_IPU, "ipu_core0_ipu", "dsp_sel", 2),
28};
29
30static int clk_mt8183_ipu_core0_probe(struct platform_device *pdev)
31{
32 struct clk_onecell_data *clk_data;
33 struct device_node *node = pdev->dev.of_node;
34
35 clk_data = mtk_alloc_clk_data(CLK_IPU_CORE0_NR_CLK);
36
37 mtk_clk_register_gates(node, ipu_core0_clks, ARRAY_SIZE(ipu_core0_clks),
38 clk_data);
39
40 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
41}
42
43static const struct of_device_id of_match_clk_mt8183_ipu_core0[] = {
44 { .compatible = "mediatek,mt8183-ipu_core0", },
45 {}
46};
47
48static struct platform_driver clk_mt8183_ipu_core0_drv = {
49 .probe = clk_mt8183_ipu_core0_probe,
50 .driver = {
51 .name = "clk-mt8183-ipu_core0",
52 .of_match_table = of_match_clk_mt8183_ipu_core0,
53 },
54};
55
56builtin_platform_driver(clk_mt8183_ipu_core0_drv);
diff --git a/drivers/clk/mediatek/clk-mt8183-ipu1.c b/drivers/clk/mediatek/clk-mt8183-ipu1.c
new file mode 100644
index 000000000000..8fd5fe002890
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183-ipu1.c
@@ -0,0 +1,56 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/clk-provider.h>
7#include <linux/platform_device.h>
8
9#include "clk-mtk.h"
10#include "clk-gate.h"
11
12#include <dt-bindings/clock/mt8183-clk.h>
13
14static const struct mtk_gate_regs ipu_core1_cg_regs = {
15 .set_ofs = 0x4,
16 .clr_ofs = 0x8,
17 .sta_ofs = 0x0,
18};
19
20#define GATE_IPU_CORE1(_id, _name, _parent, _shift) \
21 GATE_MTK(_id, _name, _parent, &ipu_core1_cg_regs, _shift, \
22 &mtk_clk_gate_ops_setclr)
23
24static const struct mtk_gate ipu_core1_clks[] = {
25 GATE_IPU_CORE1(CLK_IPU_CORE1_JTAG, "ipu_core1_jtag", "dsp_sel", 0),
26 GATE_IPU_CORE1(CLK_IPU_CORE1_AXI, "ipu_core1_axi", "dsp_sel", 1),
27 GATE_IPU_CORE1(CLK_IPU_CORE1_IPU, "ipu_core1_ipu", "dsp_sel", 2),
28};
29
30static int clk_mt8183_ipu_core1_probe(struct platform_device *pdev)
31{
32 struct clk_onecell_data *clk_data;
33 struct device_node *node = pdev->dev.of_node;
34
35 clk_data = mtk_alloc_clk_data(CLK_IPU_CORE1_NR_CLK);
36
37 mtk_clk_register_gates(node, ipu_core1_clks, ARRAY_SIZE(ipu_core1_clks),
38 clk_data);
39
40 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
41}
42
43static const struct of_device_id of_match_clk_mt8183_ipu_core1[] = {
44 { .compatible = "mediatek,mt8183-ipu_core1", },
45 {}
46};
47
48static struct platform_driver clk_mt8183_ipu_core1_drv = {
49 .probe = clk_mt8183_ipu_core1_probe,
50 .driver = {
51 .name = "clk-mt8183-ipu_core1",
52 .of_match_table = of_match_clk_mt8183_ipu_core1,
53 },
54};
55
56builtin_platform_driver(clk_mt8183_ipu_core1_drv);
diff --git a/drivers/clk/mediatek/clk-mt8183-ipu_adl.c b/drivers/clk/mediatek/clk-mt8183-ipu_adl.c
new file mode 100644
index 000000000000..3f37d0ef1df1
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183-ipu_adl.c
@@ -0,0 +1,54 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/clk-provider.h>
7#include <linux/platform_device.h>
8
9#include "clk-mtk.h"
10#include "clk-gate.h"
11
12#include <dt-bindings/clock/mt8183-clk.h>
13
14static const struct mtk_gate_regs ipu_adl_cg_regs = {
15 .set_ofs = 0x204,
16 .clr_ofs = 0x204,
17 .sta_ofs = 0x204,
18};
19
20#define GATE_IPU_ADL_I(_id, _name, _parent, _shift) \
21 GATE_MTK(_id, _name, _parent, &ipu_adl_cg_regs, _shift, \
22 &mtk_clk_gate_ops_no_setclr_inv)
23
24static const struct mtk_gate ipu_adl_clks[] = {
25 GATE_IPU_ADL_I(CLK_IPU_ADL_CABGEN, "ipu_adl_cabgen", "dsp_sel", 24),
26};
27
28static int clk_mt8183_ipu_adl_probe(struct platform_device *pdev)
29{
30 struct clk_onecell_data *clk_data;
31 struct device_node *node = pdev->dev.of_node;
32
33 clk_data = mtk_alloc_clk_data(CLK_IPU_ADL_NR_CLK);
34
35 mtk_clk_register_gates(node, ipu_adl_clks, ARRAY_SIZE(ipu_adl_clks),
36 clk_data);
37
38 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
39}
40
41static const struct of_device_id of_match_clk_mt8183_ipu_adl[] = {
42 { .compatible = "mediatek,mt8183-ipu_adl", },
43 {}
44};
45
46static struct platform_driver clk_mt8183_ipu_adl_drv = {
47 .probe = clk_mt8183_ipu_adl_probe,
48 .driver = {
49 .name = "clk-mt8183-ipu_adl",
50 .of_match_table = of_match_clk_mt8183_ipu_adl,
51 },
52};
53
54builtin_platform_driver(clk_mt8183_ipu_adl_drv);
diff --git a/drivers/clk/mediatek/clk-mt8183-ipu_conn.c b/drivers/clk/mediatek/clk-mt8183-ipu_conn.c
new file mode 100644
index 000000000000..7e0eef79c461
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183-ipu_conn.c
@@ -0,0 +1,123 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/clk-provider.h>
7#include <linux/platform_device.h>
8
9#include "clk-mtk.h"
10#include "clk-gate.h"
11
12#include <dt-bindings/clock/mt8183-clk.h>
13
14static const struct mtk_gate_regs ipu_conn_cg_regs = {
15 .set_ofs = 0x4,
16 .clr_ofs = 0x8,
17 .sta_ofs = 0x0,
18};
19
20static const struct mtk_gate_regs ipu_conn_apb_cg_regs = {
21 .set_ofs = 0x10,
22 .clr_ofs = 0x10,
23 .sta_ofs = 0x10,
24};
25
26static const struct mtk_gate_regs ipu_conn_axi_cg_regs = {
27 .set_ofs = 0x18,
28 .clr_ofs = 0x18,
29 .sta_ofs = 0x18,
30};
31
32static const struct mtk_gate_regs ipu_conn_axi1_cg_regs = {
33 .set_ofs = 0x1c,
34 .clr_ofs = 0x1c,
35 .sta_ofs = 0x1c,
36};
37
38static const struct mtk_gate_regs ipu_conn_axi2_cg_regs = {
39 .set_ofs = 0x20,
40 .clr_ofs = 0x20,
41 .sta_ofs = 0x20,
42};
43
44#define GATE_IPU_CONN(_id, _name, _parent, _shift) \
45 GATE_MTK(_id, _name, _parent, &ipu_conn_cg_regs, _shift, \
46 &mtk_clk_gate_ops_setclr)
47
48#define GATE_IPU_CONN_APB(_id, _name, _parent, _shift) \
49 GATE_MTK(_id, _name, _parent, &ipu_conn_apb_cg_regs, _shift, \
50 &mtk_clk_gate_ops_no_setclr)
51
52#define GATE_IPU_CONN_AXI_I(_id, _name, _parent, _shift) \
53 GATE_MTK(_id, _name, _parent, &ipu_conn_axi_cg_regs, _shift, \
54 &mtk_clk_gate_ops_no_setclr_inv)
55
56#define GATE_IPU_CONN_AXI1_I(_id, _name, _parent, _shift) \
57 GATE_MTK(_id, _name, _parent, &ipu_conn_axi1_cg_regs, _shift, \
58 &mtk_clk_gate_ops_no_setclr_inv)
59
60#define GATE_IPU_CONN_AXI2_I(_id, _name, _parent, _shift) \
61 GATE_MTK(_id, _name, _parent, &ipu_conn_axi2_cg_regs, _shift, \
62 &mtk_clk_gate_ops_no_setclr_inv)
63
64static const struct mtk_gate ipu_conn_clks[] = {
65 GATE_IPU_CONN(CLK_IPU_CONN_IPU,
66 "ipu_conn_ipu", "dsp_sel", 0),
67 GATE_IPU_CONN(CLK_IPU_CONN_AHB,
68 "ipu_conn_ahb", "dsp_sel", 1),
69 GATE_IPU_CONN(CLK_IPU_CONN_AXI,
70 "ipu_conn_axi", "dsp_sel", 2),
71 GATE_IPU_CONN(CLK_IPU_CONN_ISP,
72 "ipu_conn_isp", "dsp_sel", 3),
73 GATE_IPU_CONN(CLK_IPU_CONN_CAM_ADL,
74 "ipu_conn_cam_adl", "dsp_sel", 4),
75 GATE_IPU_CONN(CLK_IPU_CONN_IMG_ADL,
76 "ipu_conn_img_adl", "dsp_sel", 5),
77 GATE_IPU_CONN_APB(CLK_IPU_CONN_DAP_RX,
78 "ipu_conn_dap_rx", "dsp1_sel", 0),
79 GATE_IPU_CONN_APB(CLK_IPU_CONN_APB2AXI,
80 "ipu_conn_apb2axi", "dsp1_sel", 3),
81 GATE_IPU_CONN_APB(CLK_IPU_CONN_APB2AHB,
82 "ipu_conn_apb2ahb", "dsp1_sel", 20),
83 GATE_IPU_CONN_AXI_I(CLK_IPU_CONN_IPU_CAB1TO2,
84 "ipu_conn_ipu_cab1to2", "dsp1_sel", 6),
85 GATE_IPU_CONN_AXI_I(CLK_IPU_CONN_IPU1_CAB1TO2,
86 "ipu_conn_ipu1_cab1to2", "dsp1_sel", 13),
87 GATE_IPU_CONN_AXI_I(CLK_IPU_CONN_IPU2_CAB1TO2,
88 "ipu_conn_ipu2_cab1to2", "dsp1_sel", 20),
89 GATE_IPU_CONN_AXI1_I(CLK_IPU_CONN_CAB3TO3,
90 "ipu_conn_cab3to3", "dsp1_sel", 0),
91 GATE_IPU_CONN_AXI2_I(CLK_IPU_CONN_CAB2TO1,
92 "ipu_conn_cab2to1", "dsp1_sel", 14),
93 GATE_IPU_CONN_AXI2_I(CLK_IPU_CONN_CAB3TO1_SLICE,
94 "ipu_conn_cab3to1_slice", "dsp1_sel", 17),
95};
96
97static int clk_mt8183_ipu_conn_probe(struct platform_device *pdev)
98{
99 struct clk_onecell_data *clk_data;
100 struct device_node *node = pdev->dev.of_node;
101
102 clk_data = mtk_alloc_clk_data(CLK_IPU_CONN_NR_CLK);
103
104 mtk_clk_register_gates(node, ipu_conn_clks, ARRAY_SIZE(ipu_conn_clks),
105 clk_data);
106
107 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
108}
109
110static const struct of_device_id of_match_clk_mt8183_ipu_conn[] = {
111 { .compatible = "mediatek,mt8183-ipu_conn", },
112 {}
113};
114
115static struct platform_driver clk_mt8183_ipu_conn_drv = {
116 .probe = clk_mt8183_ipu_conn_probe,
117 .driver = {
118 .name = "clk-mt8183-ipu_conn",
119 .of_match_table = of_match_clk_mt8183_ipu_conn,
120 },
121};
122
123builtin_platform_driver(clk_mt8183_ipu_conn_drv);
diff --git a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
new file mode 100644
index 000000000000..99a6b020833e
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
@@ -0,0 +1,54 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/clk-provider.h>
7#include <linux/platform_device.h>
8
9#include "clk-mtk.h"
10#include "clk-gate.h"
11
12#include <dt-bindings/clock/mt8183-clk.h>
13
14static const struct mtk_gate_regs mfg_cg_regs = {
15 .set_ofs = 0x4,
16 .clr_ofs = 0x8,
17 .sta_ofs = 0x0,
18};
19
20#define GATE_MFG(_id, _name, _parent, _shift) \
21 GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, \
22 &mtk_clk_gate_ops_setclr)
23
24static const struct mtk_gate mfg_clks[] = {
25 GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0)
26};
27
28static int clk_mt8183_mfg_probe(struct platform_device *pdev)
29{
30 struct clk_onecell_data *clk_data;
31 struct device_node *node = pdev->dev.of_node;
32
33 clk_data = mtk_alloc_clk_data(CLK_MFG_NR_CLK);
34
35 mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks),
36 clk_data);
37
38 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
39}
40
41static const struct of_device_id of_match_clk_mt8183_mfg[] = {
42 { .compatible = "mediatek,mt8183-mfgcfg", },
43 {}
44};
45
46static struct platform_driver clk_mt8183_mfg_drv = {
47 .probe = clk_mt8183_mfg_probe,
48 .driver = {
49 .name = "clk-mt8183-mfg",
50 .of_match_table = of_match_clk_mt8183_mfg,
51 },
52};
53
54builtin_platform_driver(clk_mt8183_mfg_drv);
diff --git a/drivers/clk/mediatek/clk-mt8183-mm.c b/drivers/clk/mediatek/clk-mt8183-mm.c
new file mode 100644
index 000000000000..720c696b506d
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183-mm.c
@@ -0,0 +1,111 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/clk-provider.h>
7#include <linux/platform_device.h>
8
9#include "clk-mtk.h"
10#include "clk-gate.h"
11
12#include <dt-bindings/clock/mt8183-clk.h>
13
14static const struct mtk_gate_regs mm0_cg_regs = {
15 .set_ofs = 0x104,
16 .clr_ofs = 0x108,
17 .sta_ofs = 0x100,
18};
19
20static const struct mtk_gate_regs mm1_cg_regs = {
21 .set_ofs = 0x114,
22 .clr_ofs = 0x118,
23 .sta_ofs = 0x110,
24};
25
26#define GATE_MM0(_id, _name, _parent, _shift) \
27 GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, \
28 &mtk_clk_gate_ops_setclr)
29
30#define GATE_MM1(_id, _name, _parent, _shift) \
31 GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, \
32 &mtk_clk_gate_ops_setclr)
33
34static const struct mtk_gate mm_clks[] = {
35 /* MM0 */
36 GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
37 GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
38 GATE_MM0(CLK_MM_SMI_LARB1, "mm_smi_larb1", "mm_sel", 2),
39 GATE_MM0(CLK_MM_GALS_COMM0, "mm_gals_comm0", "mm_sel", 3),
40 GATE_MM0(CLK_MM_GALS_COMM1, "mm_gals_comm1", "mm_sel", 4),
41 GATE_MM0(CLK_MM_GALS_CCU2MM, "mm_gals_ccu2mm", "mm_sel", 5),
42 GATE_MM0(CLK_MM_GALS_IPU12MM, "mm_gals_ipu12mm", "mm_sel", 6),
43 GATE_MM0(CLK_MM_GALS_IMG2MM, "mm_gals_img2mm", "mm_sel", 7),
44 GATE_MM0(CLK_MM_GALS_CAM2MM, "mm_gals_cam2mm", "mm_sel", 8),
45 GATE_MM0(CLK_MM_GALS_IPU2MM, "mm_gals_ipu2mm", "mm_sel", 9),
46 GATE_MM0(CLK_MM_MDP_DL_TXCK, "mm_mdp_dl_txck", "mm_sel", 10),
47 GATE_MM0(CLK_MM_IPU_DL_TXCK, "mm_ipu_dl_txck", "mm_sel", 11),
48 GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 12),
49 GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 13),
50 GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 14),
51 GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 15),
52 GATE_MM0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "mm_sel", 16),
53 GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 17),
54 GATE_MM0(CLK_MM_MDP_WDMA0, "mm_mdp_wdma0", "mm_sel", 18),
55 GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 19),
56 GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 20),
57 GATE_MM0(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "mm_sel", 21),
58 GATE_MM0(CLK_MM_DISP_OVL1_2L, "mm_disp_ovl1_2l", "mm_sel", 22),
59 GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 23),
60 GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 24),
61 GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 25),
62 GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 26),
63 GATE_MM0(CLK_MM_DISP_CCORR0, "mm_disp_ccorr0", "mm_sel", 27),
64 GATE_MM0(CLK_MM_DISP_AAL0, "mm_disp_aal0", "mm_sel", 28),
65 GATE_MM0(CLK_MM_DISP_GAMMA0, "mm_disp_gamma0", "mm_sel", 29),
66 GATE_MM0(CLK_MM_DISP_DITHER0, "mm_disp_dither0", "mm_sel", 30),
67 GATE_MM0(CLK_MM_DISP_SPLIT, "mm_disp_split", "mm_sel", 31),
68 /* MM1 */
69 GATE_MM1(CLK_MM_DSI0_MM, "mm_dsi0_mm", "mm_sel", 0),
70 GATE_MM1(CLK_MM_DSI0_IF, "mm_dsi0_if", "mm_sel", 1),
71 GATE_MM1(CLK_MM_DPI_MM, "mm_dpi_mm", "mm_sel", 2),
72 GATE_MM1(CLK_MM_DPI_IF, "mm_dpi_if", "dpi0_sel", 3),
73 GATE_MM1(CLK_MM_FAKE_ENG2, "mm_fake_eng2", "mm_sel", 4),
74 GATE_MM1(CLK_MM_MDP_DL_RX, "mm_mdp_dl_rx", "mm_sel", 5),
75 GATE_MM1(CLK_MM_IPU_DL_RX, "mm_ipu_dl_rx", "mm_sel", 6),
76 GATE_MM1(CLK_MM_26M, "mm_26m", "f_f26m_ck", 7),
77 GATE_MM1(CLK_MM_MMSYS_R2Y, "mm_mmsys_r2y", "mm_sel", 8),
78 GATE_MM1(CLK_MM_DISP_RSZ, "mm_disp_rsz", "mm_sel", 9),
79 GATE_MM1(CLK_MM_MDP_AAL, "mm_mdp_aal", "mm_sel", 10),
80 GATE_MM1(CLK_MM_MDP_CCORR, "mm_mdp_ccorr", "mm_sel", 11),
81 GATE_MM1(CLK_MM_DBI_MM, "mm_dbi_mm", "mm_sel", 12),
82 GATE_MM1(CLK_MM_DBI_IF, "mm_dbi_if", "dpi0_sel", 13),
83};
84
85static int clk_mt8183_mm_probe(struct platform_device *pdev)
86{
87 struct clk_onecell_data *clk_data;
88 struct device_node *node = pdev->dev.of_node;
89
90 clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
91
92 mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
93 clk_data);
94
95 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
96}
97
98static const struct of_device_id of_match_clk_mt8183_mm[] = {
99 { .compatible = "mediatek,mt8183-mmsys", },
100 {}
101};
102
103static struct platform_driver clk_mt8183_mm_drv = {
104 .probe = clk_mt8183_mm_probe,
105 .driver = {
106 .name = "clk-mt8183-mm",
107 .of_match_table = of_match_clk_mt8183_mm,
108 },
109};
110
111builtin_platform_driver(clk_mt8183_mm_drv);
diff --git a/drivers/clk/mediatek/clk-mt8183-vdec.c b/drivers/clk/mediatek/clk-mt8183-vdec.c
new file mode 100644
index 000000000000..6250fd1e0edc
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183-vdec.c
@@ -0,0 +1,67 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/clk-provider.h>
7#include <linux/platform_device.h>
8
9#include "clk-mtk.h"
10#include "clk-gate.h"
11
12#include <dt-bindings/clock/mt8183-clk.h>
13
14static const struct mtk_gate_regs vdec0_cg_regs = {
15 .set_ofs = 0x0,
16 .clr_ofs = 0x4,
17 .sta_ofs = 0x0,
18};
19
20static const struct mtk_gate_regs vdec1_cg_regs = {
21 .set_ofs = 0x8,
22 .clr_ofs = 0xc,
23 .sta_ofs = 0x8,
24};
25
26#define GATE_VDEC0_I(_id, _name, _parent, _shift) \
27 GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, \
28 &mtk_clk_gate_ops_setclr_inv)
29
30#define GATE_VDEC1_I(_id, _name, _parent, _shift) \
31 GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, \
32 &mtk_clk_gate_ops_setclr_inv)
33
34static const struct mtk_gate vdec_clks[] = {
35 /* VDEC0 */
36 GATE_VDEC0_I(CLK_VDEC_VDEC, "vdec_vdec", "mm_sel", 0),
37 /* VDEC1 */
38 GATE_VDEC1_I(CLK_VDEC_LARB1, "vdec_larb1", "mm_sel", 0),
39};
40
41static int clk_mt8183_vdec_probe(struct platform_device *pdev)
42{
43 struct clk_onecell_data *clk_data;
44 struct device_node *node = pdev->dev.of_node;
45
46 clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
47
48 mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
49 clk_data);
50
51 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
52}
53
54static const struct of_device_id of_match_clk_mt8183_vdec[] = {
55 { .compatible = "mediatek,mt8183-vdecsys", },
56 {}
57};
58
59static struct platform_driver clk_mt8183_vdec_drv = {
60 .probe = clk_mt8183_vdec_probe,
61 .driver = {
62 .name = "clk-mt8183-vdec",
63 .of_match_table = of_match_clk_mt8183_vdec,
64 },
65};
66
67builtin_platform_driver(clk_mt8183_vdec_drv);
diff --git a/drivers/clk/mediatek/clk-mt8183-venc.c b/drivers/clk/mediatek/clk-mt8183-venc.c
new file mode 100644
index 000000000000..6678ef03fab2
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183-venc.c
@@ -0,0 +1,59 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/clk-provider.h>
7#include <linux/platform_device.h>
8
9#include "clk-mtk.h"
10#include "clk-gate.h"
11
12#include <dt-bindings/clock/mt8183-clk.h>
13
14static const struct mtk_gate_regs venc_cg_regs = {
15 .set_ofs = 0x4,
16 .clr_ofs = 0x8,
17 .sta_ofs = 0x0,
18};
19
20#define GATE_VENC_I(_id, _name, _parent, _shift) \
21 GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, \
22 &mtk_clk_gate_ops_setclr_inv)
23
24static const struct mtk_gate venc_clks[] = {
25 GATE_VENC_I(CLK_VENC_LARB, "venc_larb",
26 "mm_sel", 0),
27 GATE_VENC_I(CLK_VENC_VENC, "venc_venc",
28 "mm_sel", 4),
29 GATE_VENC_I(CLK_VENC_JPGENC, "venc_jpgenc",
30 "mm_sel", 8),
31};
32
33static int clk_mt8183_venc_probe(struct platform_device *pdev)
34{
35 struct clk_onecell_data *clk_data;
36 struct device_node *node = pdev->dev.of_node;
37
38 clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
39
40 mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
41 clk_data);
42
43 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
44}
45
46static const struct of_device_id of_match_clk_mt8183_venc[] = {
47 { .compatible = "mediatek,mt8183-vencsys", },
48 {}
49};
50
51static struct platform_driver clk_mt8183_venc_drv = {
52 .probe = clk_mt8183_venc_probe,
53 .driver = {
54 .name = "clk-mt8183-venc",
55 .of_match_table = of_match_clk_mt8183_venc,
56 },
57};
58
59builtin_platform_driver(clk_mt8183_venc_drv);
diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c
new file mode 100644
index 000000000000..9d8651033ae9
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8183.c
@@ -0,0 +1,1284 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Copyright (c) 2018 MediaTek Inc.
4// Author: Weiyi Lu <weiyi.lu@mediatek.com>
5
6#include <linux/delay.h>
7#include <linux/mfd/syscon.h>
8#include <linux/of.h>
9#include <linux/of_address.h>
10#include <linux/of_device.h>
11#include <linux/platform_device.h>
12#include <linux/slab.h>
13
14#include "clk-mtk.h"
15#include "clk-mux.h"
16#include "clk-gate.h"
17
18#include <dt-bindings/clock/mt8183-clk.h>
19
20static DEFINE_SPINLOCK(mt8183_clk_lock);
21
22static const struct mtk_fixed_clk top_fixed_clks[] = {
23 FIXED_CLK(CLK_TOP_CLK26M, "f_f26m_ck", "clk26m", 26000000),
24 FIXED_CLK(CLK_TOP_ULPOSC, "osc", NULL, 250000),
25 FIXED_CLK(CLK_TOP_UNIVP_192M, "univpll_192m", "univpll", 192000000),
26};
27
28static const struct mtk_fixed_factor top_divs[] = {
29 FACTOR(CLK_TOP_CLK13M, "clk13m", "clk26m", 1,
30 2),
31 FACTOR(CLK_TOP_F26M_CK_D2, "csw_f26m_ck_d2", "clk26m", 1,
32 2),
33 FACTOR(CLK_TOP_SYSPLL_CK, "syspll_ck", "mainpll", 1,
34 1),
35 FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "syspll_ck", 1,
36 2),
37 FACTOR(CLK_TOP_SYSPLL_D2_D2, "syspll_d2_d2", "syspll_d2", 1,
38 2),
39 FACTOR(CLK_TOP_SYSPLL_D2_D4, "syspll_d2_d4", "syspll_d2", 1,
40 4),
41 FACTOR(CLK_TOP_SYSPLL_D2_D8, "syspll_d2_d8", "syspll_d2", 1,
42 8),
43 FACTOR(CLK_TOP_SYSPLL_D2_D16, "syspll_d2_d16", "syspll_d2", 1,
44 16),
45 FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1,
46 3),
47 FACTOR(CLK_TOP_SYSPLL_D3_D2, "syspll_d3_d2", "syspll_d3", 1,
48 2),
49 FACTOR(CLK_TOP_SYSPLL_D3_D4, "syspll_d3_d4", "syspll_d3", 1,
50 4),
51 FACTOR(CLK_TOP_SYSPLL_D3_D8, "syspll_d3_d8", "syspll_d3", 1,
52 8),
53 FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1,
54 5),
55 FACTOR(CLK_TOP_SYSPLL_D5_D2, "syspll_d5_d2", "syspll_d5", 1,
56 2),
57 FACTOR(CLK_TOP_SYSPLL_D5_D4, "syspll_d5_d4", "syspll_d5", 1,
58 4),
59 FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1,
60 7),
61 FACTOR(CLK_TOP_SYSPLL_D7_D2, "syspll_d7_d2", "syspll_d7", 1,
62 2),
63 FACTOR(CLK_TOP_SYSPLL_D7_D4, "syspll_d7_d4", "syspll_d7", 1,
64 4),
65 FACTOR(CLK_TOP_UNIVPLL_CK, "univpll_ck", "univpll", 1,
66 1),
67 FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll_ck", 1,
68 2),
69 FACTOR(CLK_TOP_UNIVPLL_D2_D2, "univpll_d2_d2", "univpll_d2", 1,
70 2),
71 FACTOR(CLK_TOP_UNIVPLL_D2_D4, "univpll_d2_d4", "univpll_d2", 1,
72 4),
73 FACTOR(CLK_TOP_UNIVPLL_D2_D8, "univpll_d2_d8", "univpll_d2", 1,
74 8),
75 FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1,
76 3),
77 FACTOR(CLK_TOP_UNIVPLL_D3_D2, "univpll_d3_d2", "univpll_d3", 1,
78 2),
79 FACTOR(CLK_TOP_UNIVPLL_D3_D4, "univpll_d3_d4", "univpll_d3", 1,
80 4),
81 FACTOR(CLK_TOP_UNIVPLL_D3_D8, "univpll_d3_d8", "univpll_d3", 1,
82 8),
83 FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1,
84 5),
85 FACTOR(CLK_TOP_UNIVPLL_D5_D2, "univpll_d5_d2", "univpll_d5", 1,
86 2),
87 FACTOR(CLK_TOP_UNIVPLL_D5_D4, "univpll_d5_d4", "univpll_d5", 1,
88 4),
89 FACTOR(CLK_TOP_UNIVPLL_D5_D8, "univpll_d5_d8", "univpll_d5", 1,
90 8),
91 FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1,
92 7),
93 FACTOR(CLK_TOP_UNIVP_192M_CK, "univ_192m_ck", "univpll_192m", 1,
94 1),
95 FACTOR(CLK_TOP_UNIVP_192M_D2, "univ_192m_d2", "univ_192m_ck", 1,
96 2),
97 FACTOR(CLK_TOP_UNIVP_192M_D4, "univ_192m_d4", "univ_192m_ck", 1,
98 4),
99 FACTOR(CLK_TOP_UNIVP_192M_D8, "univ_192m_d8", "univ_192m_ck", 1,
100 8),
101 FACTOR(CLK_TOP_UNIVP_192M_D16, "univ_192m_d16", "univ_192m_ck", 1,
102 16),
103 FACTOR(CLK_TOP_UNIVP_192M_D32, "univ_192m_d32", "univ_192m_ck", 1,
104 32),
105 FACTOR(CLK_TOP_APLL1_CK, "apll1_ck", "apll1", 1,
106 1),
107 FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1", 1,
108 2),
109 FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1", 1,
110 4),
111 FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1", 1,
112 8),
113 FACTOR(CLK_TOP_APLL2_CK, "apll2_ck", "apll2", 1,
114 1),
115 FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2", 1,
116 2),
117 FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1,
118 4),
119 FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "apll2", 1,
120 8),
121 FACTOR(CLK_TOP_TVDPLL_CK, "tvdpll_ck", "tvdpll", 1,
122 1),
123 FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_ck", 1,
124 2),
125 FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1,
126 4),
127 FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll", 1,
128 8),
129 FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll", 1,
130 16),
131 FACTOR(CLK_TOP_MMPLL_CK, "mmpll_ck", "mmpll", 1,
132 1),
133 FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll", 1,
134 4),
135 FACTOR(CLK_TOP_MMPLL_D4_D2, "mmpll_d4_d2", "mmpll_d4", 1,
136 2),
137 FACTOR(CLK_TOP_MMPLL_D4_D4, "mmpll_d4_d4", "mmpll_d4", 1,
138 4),
139 FACTOR(CLK_TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1,
140 5),
141 FACTOR(CLK_TOP_MMPLL_D5_D2, "mmpll_d5_d2", "mmpll_d5", 1,
142 2),
143 FACTOR(CLK_TOP_MMPLL_D5_D4, "mmpll_d5_d4", "mmpll_d5", 1,
144 4),
145 FACTOR(CLK_TOP_MMPLL_D6, "mmpll_d6", "mmpll", 1,
146 6),
147 FACTOR(CLK_TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1,
148 7),
149 FACTOR(CLK_TOP_MFGPLL_CK, "mfgpll_ck", "mfgpll", 1,
150 1),
151 FACTOR(CLK_TOP_MSDCPLL_CK, "msdcpll_ck", "msdcpll", 1,
152 1),
153 FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1,
154 2),
155 FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1,
156 4),
157 FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1,
158 8),
159 FACTOR(CLK_TOP_MSDCPLL_D16, "msdcpll_d16", "msdcpll", 1,
160 16),
161 FACTOR(CLK_TOP_AD_OSC_CK, "ad_osc_ck", "osc", 1,
162 1),
163 FACTOR(CLK_TOP_OSC_D2, "osc_d2", "osc", 1,
164 2),
165 FACTOR(CLK_TOP_OSC_D4, "osc_d4", "osc", 1,
166 4),
167 FACTOR(CLK_TOP_OSC_D8, "osc_d8", "osc", 1,
168 8),
169 FACTOR(CLK_TOP_OSC_D16, "osc_d16", "osc", 1,
170 16),
171 FACTOR(CLK_TOP_UNIVPLL, "univpll", "univ2pll", 1,
172 2),
173 FACTOR(CLK_TOP_UNIVPLL_D3_D16, "univpll_d3_d16", "univpll_d3", 1,
174 16),
175};
176
177static const char * const axi_parents[] = {
178 "clk26m",
179 "syspll_d2_d4",
180 "syspll_d7",
181 "osc_d4"
182};
183
184static const char * const mm_parents[] = {
185 "clk26m",
186 "mmpll_d7",
187 "syspll_d3",
188 "univpll_d2_d2",
189 "syspll_d2_d2",
190 "syspll_d3_d2"
191};
192
193static const char * const img_parents[] = {
194 "clk26m",
195 "mmpll_d6",
196 "univpll_d3",
197 "syspll_d3",
198 "univpll_d2_d2",
199 "syspll_d2_d2",
200 "univpll_d3_d2",
201 "syspll_d3_d2"
202};
203
204static const char * const cam_parents[] = {
205 "clk26m",
206 "syspll_d2",
207 "mmpll_d6",
208 "syspll_d3",
209 "mmpll_d7",
210 "univpll_d3",
211 "univpll_d2_d2",
212 "syspll_d2_d2",
213 "syspll_d3_d2",
214 "univpll_d3_d2"
215};
216
217static const char * const dsp_parents[] = {
218 "clk26m",
219 "mmpll_d6",
220 "mmpll_d7",
221 "univpll_d3",
222 "syspll_d3",
223 "univpll_d2_d2",
224 "syspll_d2_d2",
225 "univpll_d3_d2",
226 "syspll_d3_d2"
227};
228
229static const char * const dsp1_parents[] = {
230 "clk26m",
231 "mmpll_d6",
232 "mmpll_d7",
233 "univpll_d3",
234 "syspll_d3",
235 "univpll_d2_d2",
236 "syspll_d2_d2",
237 "univpll_d3_d2",
238 "syspll_d3_d2"
239};
240
241static const char * const dsp2_parents[] = {
242 "clk26m",
243 "mmpll_d6",
244 "mmpll_d7",
245 "univpll_d3",
246 "syspll_d3",
247 "univpll_d2_d2",
248 "syspll_d2_d2",
249 "univpll_d3_d2",
250 "syspll_d3_d2"
251};
252
253static const char * const ipu_if_parents[] = {
254 "clk26m",
255 "mmpll_d6",
256 "mmpll_d7",
257 "univpll_d3",
258 "syspll_d3",
259 "univpll_d2_d2",
260 "syspll_d2_d2",
261 "univpll_d3_d2",
262 "syspll_d3_d2"
263};
264
265static const char * const mfg_parents[] = {
266 "clk26m",
267 "mfgpll_ck",
268 "univpll_d3",
269 "syspll_d3"
270};
271
272static const char * const f52m_mfg_parents[] = {
273 "clk26m",
274 "univpll_d3_d2",
275 "univpll_d3_d4",
276 "univpll_d3_d8"
277};
278
279static const char * const camtg_parents[] = {
280 "clk26m",
281 "univ_192m_d8",
282 "univpll_d3_d8",
283 "univ_192m_d4",
284 "univpll_d3_d16",
285 "csw_f26m_ck_d2",
286 "univ_192m_d16",
287 "univ_192m_d32"
288};
289
290static const char * const camtg2_parents[] = {
291 "clk26m",
292 "univ_192m_d8",
293 "univpll_d3_d8",
294 "univ_192m_d4",
295 "univpll_d3_d16",
296 "csw_f26m_ck_d2",
297 "univ_192m_d16",
298 "univ_192m_d32"
299};
300
301static const char * const camtg3_parents[] = {
302 "clk26m",
303 "univ_192m_d8",
304 "univpll_d3_d8",
305 "univ_192m_d4",
306 "univpll_d3_d16",
307 "csw_f26m_ck_d2",
308 "univ_192m_d16",
309 "univ_192m_d32"
310};
311
312static const char * const camtg4_parents[] = {
313 "clk26m",
314 "univ_192m_d8",
315 "univpll_d3_d8",
316 "univ_192m_d4",
317 "univpll_d3_d16",
318 "csw_f26m_ck_d2",
319 "univ_192m_d16",
320 "univ_192m_d32"
321};
322
323static const char * const uart_parents[] = {
324 "clk26m",
325 "univpll_d3_d8"
326};
327
328static const char * const spi_parents[] = {
329 "clk26m",
330 "syspll_d5_d2",
331 "syspll_d3_d4",
332 "msdcpll_d4"
333};
334
335static const char * const msdc50_hclk_parents[] = {
336 "clk26m",
337 "syspll_d2_d2",
338 "syspll_d3_d2"
339};
340
341static const char * const msdc50_0_parents[] = {
342 "clk26m",
343 "msdcpll_ck",
344 "msdcpll_d2",
345 "univpll_d2_d4",
346 "syspll_d3_d2",
347 "univpll_d2_d2"
348};
349
350static const char * const msdc30_1_parents[] = {
351 "clk26m",
352 "univpll_d3_d2",
353 "syspll_d3_d2",
354 "syspll_d7",
355 "msdcpll_d2"
356};
357
358static const char * const msdc30_2_parents[] = {
359 "clk26m",
360 "univpll_d3_d2",
361 "syspll_d3_d2",
362 "syspll_d7",
363 "msdcpll_d2"
364};
365
366static const char * const audio_parents[] = {
367 "clk26m",
368 "syspll_d5_d4",
369 "syspll_d7_d4",
370 "syspll_d2_d16"
371};
372
373static const char * const aud_intbus_parents[] = {
374 "clk26m",
375 "syspll_d2_d4",
376 "syspll_d7_d2"
377};
378
379static const char * const pmicspi_parents[] = {
380 "clk26m",
381 "syspll_d2_d8",
382 "osc_d8"
383};
384
385static const char * const fpwrap_ulposc_parents[] = {
386 "clk26m",
387 "osc_d16",
388 "osc_d4",
389 "osc_d8"
390};
391
392static const char * const atb_parents[] = {
393 "clk26m",
394 "syspll_d2_d2",
395 "syspll_d5"
396};
397
398static const char * const sspm_parents[] = {
399 "clk26m",
400 "univpll_d2_d4",
401 "syspll_d2_d2",
402 "univpll_d2_d2",
403 "syspll_d3"
404};
405
406static const char * const dpi0_parents[] = {
407 "clk26m",
408 "tvdpll_d2",
409 "tvdpll_d4",
410 "tvdpll_d8",
411 "tvdpll_d16",
412 "univpll_d5_d2",
413 "univpll_d3_d4",
414 "syspll_d3_d4",
415 "univpll_d3_d8"
416};
417
418static const char * const scam_parents[] = {
419 "clk26m",
420 "syspll_d5_d2"
421};
422
423static const char * const disppwm_parents[] = {
424 "clk26m",
425 "univpll_d3_d4",
426 "osc_d2",
427 "osc_d4",
428 "osc_d16"
429};
430
431static const char * const usb_top_parents[] = {
432 "clk26m",
433 "univpll_d5_d4",
434 "univpll_d3_d4",
435 "univpll_d5_d2"
436};
437
438
439static const char * const ssusb_top_xhci_parents[] = {
440 "clk26m",
441 "univpll_d5_d4",
442 "univpll_d3_d4",
443 "univpll_d5_d2"
444};
445
446static const char * const spm_parents[] = {
447 "clk26m",
448 "syspll_d2_d8"
449};
450
451static const char * const i2c_parents[] = {
452 "clk26m",
453 "syspll_d2_d8",
454 "univpll_d5_d2"
455};
456
457static const char * const scp_parents[] = {
458 "clk26m",
459 "univpll_d2_d8",
460 "syspll_d5",
461 "syspll_d2_d2",
462 "univpll_d2_d2",
463 "syspll_d3",
464 "univpll_d3"
465};
466
467static const char * const seninf_parents[] = {
468 "clk26m",
469 "univpll_d2_d2",
470 "univpll_d3_d2",
471 "univpll_d2_d4"
472};
473
474static const char * const dxcc_parents[] = {
475 "clk26m",
476 "syspll_d2_d2",
477 "syspll_d2_d4",
478 "syspll_d2_d8"
479};
480
481static const char * const aud_engen1_parents[] = {
482 "clk26m",
483 "apll1_d2",
484 "apll1_d4",
485 "apll1_d8"
486};
487
488static const char * const aud_engen2_parents[] = {
489 "clk26m",
490 "apll2_d2",
491 "apll2_d4",
492 "apll2_d8"
493};
494
495static const char * const faes_ufsfde_parents[] = {
496 "clk26m",
497 "syspll_d2",
498 "syspll_d2_d2",
499 "syspll_d3",
500 "syspll_d2_d4",
501 "univpll_d3"
502};
503
504static const char * const fufs_parents[] = {
505 "clk26m",
506 "syspll_d2_d4",
507 "syspll_d2_d8",
508 "syspll_d2_d16"
509};
510
511static const char * const aud_1_parents[] = {
512 "clk26m",
513 "apll1_ck"
514};
515
516static const char * const aud_2_parents[] = {
517 "clk26m",
518 "apll2_ck"
519};
520
521/*
522 * CRITICAL CLOCK:
523 * axi_sel is the main bus clock of whole SOC.
524 * spm_sel is the clock of the always-on co-processor.
525 */
526static const struct mtk_mux top_muxes[] = {
527 /* CLK_CFG_0 */
528 MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MUX_AXI, "axi_sel",
529 axi_parents, 0x40,
530 0x44, 0x48, 0, 2, 7, 0x004, 0, CLK_IS_CRITICAL),
531 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_MM, "mm_sel",
532 mm_parents, 0x40,
533 0x44, 0x48, 8, 3, 15, 0x004, 1),
534 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_IMG, "img_sel",
535 img_parents, 0x40,
536 0x44, 0x48, 16, 3, 23, 0x004, 2),
537 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_CAM, "cam_sel",
538 cam_parents, 0x40,
539 0x44, 0x48, 24, 4, 31, 0x004, 3),
540 /* CLK_CFG_1 */
541 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_DSP, "dsp_sel",
542 dsp_parents, 0x50,
543 0x54, 0x58, 0, 4, 7, 0x004, 4),
544 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_DSP1, "dsp1_sel",
545 dsp1_parents, 0x50,
546 0x54, 0x58, 8, 4, 15, 0x004, 5),
547 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_DSP2, "dsp2_sel",
548 dsp2_parents, 0x50,
549 0x54, 0x58, 16, 4, 23, 0x004, 6),
550 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_IPU_IF, "ipu_if_sel",
551 ipu_if_parents, 0x50,
552 0x54, 0x58, 24, 4, 31, 0x004, 7),
553 /* CLK_CFG_2 */
554 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_MFG, "mfg_sel",
555 mfg_parents, 0x60,
556 0x64, 0x68, 0, 2, 7, 0x004, 8),
557 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_F52M_MFG, "f52m_mfg_sel",
558 f52m_mfg_parents, 0x60,
559 0x64, 0x68, 8, 2, 15, 0x004, 9),
560 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_CAMTG, "camtg_sel",
561 camtg_parents, 0x60,
562 0x64, 0x68, 16, 3, 23, 0x004, 10),
563 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_CAMTG2, "camtg2_sel",
564 camtg2_parents, 0x60,
565 0x64, 0x68, 24, 3, 31, 0x004, 11),
566 /* CLK_CFG_3 */
567 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_CAMTG3, "camtg3_sel",
568 camtg3_parents, 0x70,
569 0x74, 0x78, 0, 3, 7, 0x004, 12),
570 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_CAMTG4, "camtg4_sel",
571 camtg4_parents, 0x70,
572 0x74, 0x78, 8, 3, 15, 0x004, 13),
573 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_UART, "uart_sel",
574 uart_parents, 0x70,
575 0x74, 0x78, 16, 1, 23, 0x004, 14),
576 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_SPI, "spi_sel",
577 spi_parents, 0x70,
578 0x74, 0x78, 24, 2, 31, 0x004, 15),
579 /* CLK_CFG_4 */
580 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_MSDC50_0_HCLK, "msdc50_hclk_sel",
581 msdc50_hclk_parents, 0x80,
582 0x84, 0x88, 0, 2, 7, 0x004, 16),
583 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_MSDC50_0, "msdc50_0_sel",
584 msdc50_0_parents, 0x80,
585 0x84, 0x88, 8, 3, 15, 0x004, 17),
586 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_MSDC30_1, "msdc30_1_sel",
587 msdc30_1_parents, 0x80,
588 0x84, 0x88, 16, 3, 23, 0x004, 18),
589 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_MSDC30_2, "msdc30_2_sel",
590 msdc30_2_parents, 0x80,
591 0x84, 0x88, 24, 3, 31, 0x004, 19),
592 /* CLK_CFG_5 */
593 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_AUDIO, "audio_sel",
594 audio_parents, 0x90,
595 0x94, 0x98, 0, 2, 7, 0x004, 20),
596 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_AUD_INTBUS, "aud_intbus_sel",
597 aud_intbus_parents, 0x90,
598 0x94, 0x98, 8, 2, 15, 0x004, 21),
599 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_PMICSPI, "pmicspi_sel",
600 pmicspi_parents, 0x90,
601 0x94, 0x98, 16, 2, 23, 0x004, 22),
602 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_FPWRAP_ULPOSC, "fpwrap_ulposc_sel",
603 fpwrap_ulposc_parents, 0x90,
604 0x94, 0x98, 24, 2, 31, 0x004, 23),
605 /* CLK_CFG_6 */
606 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_ATB, "atb_sel",
607 atb_parents, 0xa0,
608 0xa4, 0xa8, 0, 2, 7, 0x004, 24),
609 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_SSPM, "sspm_sel",
610 sspm_parents, 0xa0,
611 0xa4, 0xa8, 8, 3, 15, 0x004, 25),
612 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_DPI0, "dpi0_sel",
613 dpi0_parents, 0xa0,
614 0xa4, 0xa8, 16, 4, 23, 0x004, 26),
615 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_SCAM, "scam_sel",
616 scam_parents, 0xa0,
617 0xa4, 0xa8, 24, 1, 31, 0x004, 27),
618 /* CLK_CFG_7 */
619 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_DISP_PWM, "disppwm_sel",
620 disppwm_parents, 0xb0,
621 0xb4, 0xb8, 0, 3, 7, 0x004, 28),
622 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_USB_TOP, "usb_top_sel",
623 usb_top_parents, 0xb0,
624 0xb4, 0xb8, 8, 2, 15, 0x004, 29),
625 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_SSUSB_TOP_XHCI, "ssusb_top_xhci_sel",
626 ssusb_top_xhci_parents, 0xb0,
627 0xb4, 0xb8, 16, 2, 23, 0x004, 30),
628 MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MUX_SPM, "spm_sel",
629 spm_parents, 0xb0,
630 0xb4, 0xb8, 24, 1, 31, 0x008, 0, CLK_IS_CRITICAL),
631 /* CLK_CFG_8 */
632 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_I2C, "i2c_sel",
633 i2c_parents, 0xc0,
634 0xc4, 0xc8, 0, 2, 7, 0x008, 1),
635 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_SCP, "scp_sel",
636 scp_parents, 0xc0,
637 0xc4, 0xc8, 8, 3, 15, 0x008, 2),
638 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_SENINF, "seninf_sel",
639 seninf_parents, 0xc0,
640 0xc4, 0xc8, 16, 2, 23, 0x008, 3),
641 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_DXCC, "dxcc_sel",
642 dxcc_parents, 0xc0,
643 0xc4, 0xc8, 24, 2, 31, 0x008, 4),
644 /* CLK_CFG_9 */
645 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_AUD_ENG1, "aud_eng1_sel",
646 aud_engen1_parents, 0xd0,
647 0xd4, 0xd8, 0, 2, 7, 0x008, 5),
648 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_AUD_ENG2, "aud_eng2_sel",
649 aud_engen2_parents, 0xd0,
650 0xd4, 0xd8, 8, 2, 15, 0x008, 6),
651 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_FAES_UFSFDE, "faes_ufsfde_sel",
652 faes_ufsfde_parents, 0xd0,
653 0xd4, 0xd8, 16, 3, 23, 0x008, 7),
654 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_FUFS, "fufs_sel",
655 fufs_parents, 0xd0,
656 0xd4, 0xd8, 24, 2, 31, 0x008, 8),
657 /* CLK_CFG_10 */
658 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_AUD_1, "aud_1_sel",
659 aud_1_parents, 0xe0,
660 0xe4, 0xe8, 0, 1, 7, 0x008, 9),
661 MUX_GATE_CLR_SET_UPD(CLK_TOP_MUX_AUD_2, "aud_2_sel",
662 aud_2_parents, 0xe0,
663 0xe4, 0xe8, 8, 1, 15, 0x008, 10),
664};
665
666static const char * const apll_i2s0_parents[] = {
667 "aud_1_sel",
668 "aud_2_sel"
669};
670
671static const char * const apll_i2s1_parents[] = {
672 "aud_1_sel",
673 "aud_2_sel"
674};
675
676static const char * const apll_i2s2_parents[] = {
677 "aud_1_sel",
678 "aud_2_sel"
679};
680
681static const char * const apll_i2s3_parents[] = {
682 "aud_1_sel",
683 "aud_2_sel"
684};
685
686static const char * const apll_i2s4_parents[] = {
687 "aud_1_sel",
688 "aud_2_sel"
689};
690
691static const char * const apll_i2s5_parents[] = {
692 "aud_1_sel",
693 "aud_2_sel"
694};
695
696static struct mtk_composite top_aud_muxes[] = {
697 MUX(CLK_TOP_MUX_APLL_I2S0, "apll_i2s0_sel", apll_i2s0_parents,
698 0x320, 8, 1),
699 MUX(CLK_TOP_MUX_APLL_I2S1, "apll_i2s1_sel", apll_i2s1_parents,
700 0x320, 9, 1),
701 MUX(CLK_TOP_MUX_APLL_I2S2, "apll_i2s2_sel", apll_i2s2_parents,
702 0x320, 10, 1),
703 MUX(CLK_TOP_MUX_APLL_I2S3, "apll_i2s3_sel", apll_i2s3_parents,
704 0x320, 11, 1),
705 MUX(CLK_TOP_MUX_APLL_I2S4, "apll_i2s4_sel", apll_i2s4_parents,
706 0x320, 12, 1),
707 MUX(CLK_TOP_MUX_APLL_I2S5, "apll_i2s5_sel", apll_i2s5_parents,
708 0x328, 20, 1),
709};
710
711static const char * const mcu_mp0_parents[] = {
712 "clk26m",
713 "armpll_ll",
714 "armpll_div_pll1",
715 "armpll_div_pll2"
716};
717
718static const char * const mcu_mp2_parents[] = {
719 "clk26m",
720 "armpll_l",
721 "armpll_div_pll1",
722 "armpll_div_pll2"
723};
724
725static const char * const mcu_bus_parents[] = {
726 "clk26m",
727 "ccipll",
728 "armpll_div_pll1",
729 "armpll_div_pll2"
730};
731
732static struct mtk_composite mcu_muxes[] = {
733 /* mp0_pll_divider_cfg */
734 MUX(CLK_MCU_MP0_SEL, "mcu_mp0_sel", mcu_mp0_parents, 0x7A0, 9, 2),
735 /* mp2_pll_divider_cfg */
736 MUX(CLK_MCU_MP2_SEL, "mcu_mp2_sel", mcu_mp2_parents, 0x7A8, 9, 2),
737 /* bus_pll_divider_cfg */
738 MUX(CLK_MCU_BUS_SEL, "mcu_bus_sel", mcu_bus_parents, 0x7C0, 9, 2),
739};
740
741static struct mtk_composite top_aud_divs[] = {
742 DIV_GATE(CLK_TOP_APLL12_DIV0, "apll12_div0", "apll_i2s0_sel",
743 0x320, 2, 0x324, 8, 0),
744 DIV_GATE(CLK_TOP_APLL12_DIV1, "apll12_div1", "apll_i2s1_sel",
745 0x320, 3, 0x324, 8, 8),
746 DIV_GATE(CLK_TOP_APLL12_DIV2, "apll12_div2", "apll_i2s2_sel",
747 0x320, 4, 0x324, 8, 16),
748 DIV_GATE(CLK_TOP_APLL12_DIV3, "apll12_div3", "apll_i2s3_sel",
749 0x320, 5, 0x324, 8, 24),
750 DIV_GATE(CLK_TOP_APLL12_DIV4, "apll12_div4", "apll_i2s4_sel",
751 0x320, 6, 0x328, 8, 0),
752 DIV_GATE(CLK_TOP_APLL12_DIVB, "apll12_divb", "apll12_div4",
753 0x320, 7, 0x328, 8, 8),
754};
755
756static const struct mtk_gate_regs top_cg_regs = {
757 .set_ofs = 0x104,
758 .clr_ofs = 0x104,
759 .sta_ofs = 0x104,
760};
761
762#define GATE_TOP(_id, _name, _parent, _shift) \
763 GATE_MTK(_id, _name, _parent, &top_cg_regs, _shift, \
764 &mtk_clk_gate_ops_no_setclr_inv)
765
766static const struct mtk_gate top_clks[] = {
767 /* TOP */
768 GATE_TOP(CLK_TOP_ARMPLL_DIV_PLL1, "armpll_div_pll1", "mainpll", 4),
769 GATE_TOP(CLK_TOP_ARMPLL_DIV_PLL2, "armpll_div_pll2", "univpll", 5),
770};
771
772static const struct mtk_gate_regs infra0_cg_regs = {
773 .set_ofs = 0x80,
774 .clr_ofs = 0x84,
775 .sta_ofs = 0x90,
776};
777
778static const struct mtk_gate_regs infra1_cg_regs = {
779 .set_ofs = 0x88,
780 .clr_ofs = 0x8c,
781 .sta_ofs = 0x94,
782};
783
784static const struct mtk_gate_regs infra2_cg_regs = {
785 .set_ofs = 0xa4,
786 .clr_ofs = 0xa8,
787 .sta_ofs = 0xac,
788};
789
790static const struct mtk_gate_regs infra3_cg_regs = {
791 .set_ofs = 0xc0,
792 .clr_ofs = 0xc4,
793 .sta_ofs = 0xc8,
794};
795
796#define GATE_INFRA0(_id, _name, _parent, _shift) \
797 GATE_MTK(_id, _name, _parent, &infra0_cg_regs, _shift, \
798 &mtk_clk_gate_ops_setclr)
799
800#define GATE_INFRA1(_id, _name, _parent, _shift) \
801 GATE_MTK(_id, _name, _parent, &infra1_cg_regs, _shift, \
802 &mtk_clk_gate_ops_setclr)
803
804#define GATE_INFRA2(_id, _name, _parent, _shift) \
805 GATE_MTK(_id, _name, _parent, &infra2_cg_regs, _shift, \
806 &mtk_clk_gate_ops_setclr)
807
808#define GATE_INFRA3(_id, _name, _parent, _shift) \
809 GATE_MTK(_id, _name, _parent, &infra3_cg_regs, _shift, \
810 &mtk_clk_gate_ops_setclr)
811
812static const struct mtk_gate infra_clks[] = {
813 /* INFRA0 */
814 GATE_INFRA0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr",
815 "axi_sel", 0),
816 GATE_INFRA0(CLK_INFRA_PMIC_AP, "infra_pmic_ap",
817 "axi_sel", 1),
818 GATE_INFRA0(CLK_INFRA_PMIC_MD, "infra_pmic_md",
819 "axi_sel", 2),
820 GATE_INFRA0(CLK_INFRA_PMIC_CONN, "infra_pmic_conn",
821 "axi_sel", 3),
822 GATE_INFRA0(CLK_INFRA_SCPSYS, "infra_scp",
823 "scp_sel", 4),
824 GATE_INFRA0(CLK_INFRA_SEJ, "infra_sej",
825 "f_f26m_ck", 5),
826 GATE_INFRA0(CLK_INFRA_APXGPT, "infra_apxgpt",
827 "axi_sel", 6),
828 GATE_INFRA0(CLK_INFRA_ICUSB, "infra_icusb",
829 "axi_sel", 8),
830 GATE_INFRA0(CLK_INFRA_GCE, "infra_gce",
831 "axi_sel", 9),
832 GATE_INFRA0(CLK_INFRA_THERM, "infra_therm",
833 "axi_sel", 10),
834 GATE_INFRA0(CLK_INFRA_I2C0, "infra_i2c0",
835 "i2c_sel", 11),
836 GATE_INFRA0(CLK_INFRA_I2C1, "infra_i2c1",
837 "i2c_sel", 12),
838 GATE_INFRA0(CLK_INFRA_I2C2, "infra_i2c2",
839 "i2c_sel", 13),
840 GATE_INFRA0(CLK_INFRA_I2C3, "infra_i2c3",
841 "i2c_sel", 14),
842 GATE_INFRA0(CLK_INFRA_PWM_HCLK, "infra_pwm_hclk",
843 "axi_sel", 15),
844 GATE_INFRA0(CLK_INFRA_PWM1, "infra_pwm1",
845 "i2c_sel", 16),
846 GATE_INFRA0(CLK_INFRA_PWM2, "infra_pwm2",
847 "i2c_sel", 17),
848 GATE_INFRA0(CLK_INFRA_PWM3, "infra_pwm3",
849 "i2c_sel", 18),
850 GATE_INFRA0(CLK_INFRA_PWM4, "infra_pwm4",
851 "i2c_sel", 19),
852 GATE_INFRA0(CLK_INFRA_PWM, "infra_pwm",
853 "i2c_sel", 21),
854 GATE_INFRA0(CLK_INFRA_UART0, "infra_uart0",
855 "uart_sel", 22),
856 GATE_INFRA0(CLK_INFRA_UART1, "infra_uart1",
857 "uart_sel", 23),
858 GATE_INFRA0(CLK_INFRA_UART2, "infra_uart2",
859 "uart_sel", 24),
860 GATE_INFRA0(CLK_INFRA_UART3, "infra_uart3",
861 "uart_sel", 25),
862 GATE_INFRA0(CLK_INFRA_GCE_26M, "infra_gce_26m",
863 "axi_sel", 27),
864 GATE_INFRA0(CLK_INFRA_CQ_DMA_FPC, "infra_cqdma_fpc",
865 "axi_sel", 28),
866 GATE_INFRA0(CLK_INFRA_BTIF, "infra_btif",
867 "axi_sel", 31),
868 /* INFRA1 */
869 GATE_INFRA1(CLK_INFRA_SPI0, "infra_spi0",
870 "spi_sel", 1),
871 GATE_INFRA1(CLK_INFRA_MSDC0, "infra_msdc0",
872 "msdc50_hclk_sel", 2),
873 GATE_INFRA1(CLK_INFRA_MSDC1, "infra_msdc1",
874 "axi_sel", 4),
875 GATE_INFRA1(CLK_INFRA_MSDC2, "infra_msdc2",
876 "axi_sel", 5),
877 GATE_INFRA1(CLK_INFRA_MSDC0_SCK, "infra_msdc0_sck",
878 "msdc50_0_sel", 6),
879 GATE_INFRA1(CLK_INFRA_DVFSRC, "infra_dvfsrc",
880 "f_f26m_ck", 7),
881 GATE_INFRA1(CLK_INFRA_GCPU, "infra_gcpu",
882 "axi_sel", 8),
883 GATE_INFRA1(CLK_INFRA_TRNG, "infra_trng",
884 "axi_sel", 9),
885 GATE_INFRA1(CLK_INFRA_AUXADC, "infra_auxadc",
886 "f_f26m_ck", 10),
887 GATE_INFRA1(CLK_INFRA_CPUM, "infra_cpum",
888 "axi_sel", 11),
889 GATE_INFRA1(CLK_INFRA_CCIF1_AP, "infra_ccif1_ap",
890 "axi_sel", 12),
891 GATE_INFRA1(CLK_INFRA_CCIF1_MD, "infra_ccif1_md",
892 "axi_sel", 13),
893 GATE_INFRA1(CLK_INFRA_AUXADC_MD, "infra_auxadc_md",
894 "f_f26m_ck", 14),
895 GATE_INFRA1(CLK_INFRA_MSDC1_SCK, "infra_msdc1_sck",
896 "msdc30_1_sel", 16),
897 GATE_INFRA1(CLK_INFRA_MSDC2_SCK, "infra_msdc2_sck",
898 "msdc30_2_sel", 17),
899 GATE_INFRA1(CLK_INFRA_AP_DMA, "infra_apdma",
900 "axi_sel", 18),
901 GATE_INFRA1(CLK_INFRA_XIU, "infra_xiu",
902 "axi_sel", 19),
903 GATE_INFRA1(CLK_INFRA_DEVICE_APC, "infra_device_apc",
904 "axi_sel", 20),
905 GATE_INFRA1(CLK_INFRA_CCIF_AP, "infra_ccif_ap",
906 "axi_sel", 23),
907 GATE_INFRA1(CLK_INFRA_DEBUGSYS, "infra_debugsys",
908 "axi_sel", 24),
909 GATE_INFRA1(CLK_INFRA_AUDIO, "infra_audio",
910 "axi_sel", 25),
911 GATE_INFRA1(CLK_INFRA_CCIF_MD, "infra_ccif_md",
912 "axi_sel", 26),
913 GATE_INFRA1(CLK_INFRA_DXCC_SEC_CORE, "infra_dxcc_sec_core",
914 "dxcc_sel", 27),
915 GATE_INFRA1(CLK_INFRA_DXCC_AO, "infra_dxcc_ao",
916 "dxcc_sel", 28),
917 GATE_INFRA1(CLK_INFRA_DEVMPU_BCLK, "infra_devmpu_bclk",
918 "axi_sel", 30),
919 GATE_INFRA1(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m",
920 "f_f26m_ck", 31),
921 /* INFRA2 */
922 GATE_INFRA2(CLK_INFRA_IRTX, "infra_irtx",
923 "f_f26m_ck", 0),
924 GATE_INFRA2(CLK_INFRA_USB, "infra_usb",
925 "usb_top_sel", 1),
926 GATE_INFRA2(CLK_INFRA_DISP_PWM, "infra_disppwm",
927 "axi_sel", 2),
928 GATE_INFRA2(CLK_INFRA_CLDMA_BCLK, "infra_cldma_bclk",
929 "axi_sel", 3),
930 GATE_INFRA2(CLK_INFRA_AUDIO_26M_BCLK, "infra_audio_26m_bclk",
931 "f_f26m_ck", 4),
932 GATE_INFRA2(CLK_INFRA_SPI1, "infra_spi1",
933 "spi_sel", 6),
934 GATE_INFRA2(CLK_INFRA_I2C4, "infra_i2c4",
935 "i2c_sel", 7),
936 GATE_INFRA2(CLK_INFRA_MODEM_TEMP_SHARE, "infra_md_tmp_share",
937 "f_f26m_ck", 8),
938 GATE_INFRA2(CLK_INFRA_SPI2, "infra_spi2",
939 "spi_sel", 9),
940 GATE_INFRA2(CLK_INFRA_SPI3, "infra_spi3",
941 "spi_sel", 10),
942 GATE_INFRA2(CLK_INFRA_UNIPRO_SCK, "infra_unipro_sck",
943 "ssusb_top_xhci_sel", 11),
944 GATE_INFRA2(CLK_INFRA_UNIPRO_TICK, "infra_unipro_tick",
945 "fufs_sel", 12),
946 GATE_INFRA2(CLK_INFRA_UFS_MP_SAP_BCLK, "infra_ufs_mp_sap_bck",
947 "fufs_sel", 13),
948 GATE_INFRA2(CLK_INFRA_MD32_BCLK, "infra_md32_bclk",
949 "axi_sel", 14),
950 GATE_INFRA2(CLK_INFRA_SSPM, "infra_sspm",
951 "sspm_sel", 15),
952 GATE_INFRA2(CLK_INFRA_UNIPRO_MBIST, "infra_unipro_mbist",
953 "axi_sel", 16),
954 GATE_INFRA2(CLK_INFRA_SSPM_BUS_HCLK, "infra_sspm_bus_hclk",
955 "axi_sel", 17),
956 GATE_INFRA2(CLK_INFRA_I2C5, "infra_i2c5",
957 "i2c_sel", 18),
958 GATE_INFRA2(CLK_INFRA_I2C5_ARBITER, "infra_i2c5_arbiter",
959 "i2c_sel", 19),
960 GATE_INFRA2(CLK_INFRA_I2C5_IMM, "infra_i2c5_imm",
961 "i2c_sel", 20),
962 GATE_INFRA2(CLK_INFRA_I2C1_ARBITER, "infra_i2c1_arbiter",
963 "i2c_sel", 21),
964 GATE_INFRA2(CLK_INFRA_I2C1_IMM, "infra_i2c1_imm",
965 "i2c_sel", 22),
966 GATE_INFRA2(CLK_INFRA_I2C2_ARBITER, "infra_i2c2_arbiter",
967 "i2c_sel", 23),
968 GATE_INFRA2(CLK_INFRA_I2C2_IMM, "infra_i2c2_imm",
969 "i2c_sel", 24),
970 GATE_INFRA2(CLK_INFRA_SPI4, "infra_spi4",
971 "spi_sel", 25),
972 GATE_INFRA2(CLK_INFRA_SPI5, "infra_spi5",
973 "spi_sel", 26),
974 GATE_INFRA2(CLK_INFRA_CQ_DMA, "infra_cqdma",
975 "axi_sel", 27),
976 GATE_INFRA2(CLK_INFRA_UFS, "infra_ufs",
977 "fufs_sel", 28),
978 GATE_INFRA2(CLK_INFRA_AES_UFSFDE, "infra_aes_ufsfde",
979 "faes_ufsfde_sel", 29),
980 GATE_INFRA2(CLK_INFRA_UFS_TICK, "infra_ufs_tick",
981 "fufs_sel", 30),
982 /* INFRA3 */
983 GATE_INFRA3(CLK_INFRA_MSDC0_SELF, "infra_msdc0_self",
984 "msdc50_0_sel", 0),
985 GATE_INFRA3(CLK_INFRA_MSDC1_SELF, "infra_msdc1_self",
986 "msdc50_0_sel", 1),
987 GATE_INFRA3(CLK_INFRA_MSDC2_SELF, "infra_msdc2_self",
988 "msdc50_0_sel", 2),
989 GATE_INFRA3(CLK_INFRA_SSPM_26M_SELF, "infra_sspm_26m_self",
990 "f_f26m_ck", 3),
991 GATE_INFRA3(CLK_INFRA_SSPM_32K_SELF, "infra_sspm_32k_self",
992 "f_f26m_ck", 4),
993 GATE_INFRA3(CLK_INFRA_UFS_AXI, "infra_ufs_axi",
994 "axi_sel", 5),
995 GATE_INFRA3(CLK_INFRA_I2C6, "infra_i2c6",
996 "i2c_sel", 6),
997 GATE_INFRA3(CLK_INFRA_AP_MSDC0, "infra_ap_msdc0",
998 "msdc50_hclk_sel", 7),
999 GATE_INFRA3(CLK_INFRA_MD_MSDC0, "infra_md_msdc0",
1000 "msdc50_hclk_sel", 8),
1001 GATE_INFRA3(CLK_INFRA_CCIF2_AP, "infra_ccif2_ap",
1002 "axi_sel", 16),
1003 GATE_INFRA3(CLK_INFRA_CCIF2_MD, "infra_ccif2_md",
1004 "axi_sel", 17),
1005 GATE_INFRA3(CLK_INFRA_CCIF3_AP, "infra_ccif3_ap",
1006 "axi_sel", 18),
1007 GATE_INFRA3(CLK_INFRA_CCIF3_MD, "infra_ccif3_md",
1008 "axi_sel", 19),
1009 GATE_INFRA3(CLK_INFRA_SEJ_F13M, "infra_sej_f13m",
1010 "f_f26m_ck", 20),
1011 GATE_INFRA3(CLK_INFRA_AES_BCLK, "infra_aes_bclk",
1012 "axi_sel", 21),
1013 GATE_INFRA3(CLK_INFRA_I2C7, "infra_i2c7",
1014 "i2c_sel", 22),
1015 GATE_INFRA3(CLK_INFRA_I2C8, "infra_i2c8",
1016 "i2c_sel", 23),
1017 GATE_INFRA3(CLK_INFRA_FBIST2FPC, "infra_fbist2fpc",
1018 "msdc50_0_sel", 24),
1019};
1020
1021static const struct mtk_gate_regs apmixed_cg_regs = {
1022 .set_ofs = 0x20,
1023 .clr_ofs = 0x20,
1024 .sta_ofs = 0x20,
1025};
1026
1027#define GATE_APMIXED_FLAGS(_id, _name, _parent, _shift, _flags) \
1028 GATE_MTK_FLAGS(_id, _name, _parent, &apmixed_cg_regs, \
1029 _shift, &mtk_clk_gate_ops_no_setclr_inv, _flags)
1030
1031#define GATE_APMIXED(_id, _name, _parent, _shift) \
1032 GATE_APMIXED_FLAGS(_id, _name, _parent, _shift, 0)
1033
1034/*
1035 * CRITICAL CLOCK:
1036 * apmixed_appll26m is the toppest clock gate of all PLLs.
1037 */
1038static const struct mtk_gate apmixed_clks[] = {
1039 /* AUDIO0 */
1040 GATE_APMIXED(CLK_APMIXED_SSUSB_26M, "apmixed_ssusb26m",
1041 "f_f26m_ck", 4),
1042 GATE_APMIXED_FLAGS(CLK_APMIXED_APPLL_26M, "apmixed_appll26m",
1043 "f_f26m_ck", 5, CLK_IS_CRITICAL),
1044 GATE_APMIXED(CLK_APMIXED_MIPIC0_26M, "apmixed_mipic026m",
1045 "f_f26m_ck", 6),
1046 GATE_APMIXED(CLK_APMIXED_MDPLLGP_26M, "apmixed_mdpll26m",
1047 "f_f26m_ck", 7),
1048 GATE_APMIXED(CLK_APMIXED_MMSYS_26M, "apmixed_mmsys26m",
1049 "f_f26m_ck", 8),
1050 GATE_APMIXED(CLK_APMIXED_UFS_26M, "apmixed_ufs26m",
1051 "f_f26m_ck", 9),
1052 GATE_APMIXED(CLK_APMIXED_MIPIC1_26M, "apmixed_mipic126m",
1053 "f_f26m_ck", 11),
1054 GATE_APMIXED(CLK_APMIXED_MEMPLL_26M, "apmixed_mempll26m",
1055 "f_f26m_ck", 13),
1056 GATE_APMIXED(CLK_APMIXED_CLKSQ_LVPLL_26M, "apmixed_lvpll26m",
1057 "f_f26m_ck", 14),
1058 GATE_APMIXED(CLK_APMIXED_MIPID0_26M, "apmixed_mipid026m",
1059 "f_f26m_ck", 16),
1060 GATE_APMIXED(CLK_APMIXED_MIPID1_26M, "apmixed_mipid126m",
1061 "f_f26m_ck", 17),
1062};
1063
1064#define MT8183_PLL_FMAX (3800UL * MHZ)
1065#define MT8183_PLL_FMIN (1500UL * MHZ)
1066
1067#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \
1068 _rst_bar_mask, _pcwbits, _pcwibits, _pd_reg, \
1069 _pd_shift, _tuner_reg, _tuner_en_reg, \
1070 _tuner_en_bit, _pcw_reg, _pcw_shift, \
1071 _pcw_chg_reg, _div_table) { \
1072 .id = _id, \
1073 .name = _name, \
1074 .reg = _reg, \
1075 .pwr_reg = _pwr_reg, \
1076 .en_mask = _en_mask, \
1077 .flags = _flags, \
1078 .rst_bar_mask = _rst_bar_mask, \
1079 .fmax = MT8183_PLL_FMAX, \
1080 .fmin = MT8183_PLL_FMIN, \
1081 .pcwbits = _pcwbits, \
1082 .pcwibits = _pcwibits, \
1083 .pd_reg = _pd_reg, \
1084 .pd_shift = _pd_shift, \
1085 .tuner_reg = _tuner_reg, \
1086 .tuner_en_reg = _tuner_en_reg, \
1087 .tuner_en_bit = _tuner_en_bit, \
1088 .pcw_reg = _pcw_reg, \
1089 .pcw_shift = _pcw_shift, \
1090 .pcw_chg_reg = _pcw_chg_reg, \
1091 .div_table = _div_table, \
1092 }
1093
1094#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \
1095 _rst_bar_mask, _pcwbits, _pcwibits, _pd_reg, \
1096 _pd_shift, _tuner_reg, _tuner_en_reg, \
1097 _tuner_en_bit, _pcw_reg, _pcw_shift, \
1098 _pcw_chg_reg) \
1099 PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \
1100 _rst_bar_mask, _pcwbits, _pcwibits, _pd_reg, \
1101 _pd_shift, _tuner_reg, _tuner_en_reg, \
1102 _tuner_en_bit, _pcw_reg, _pcw_shift, \
1103 _pcw_chg_reg, NULL)
1104
1105static const struct mtk_pll_div_table armpll_div_table[] = {
1106 { .div = 0, .freq = MT8183_PLL_FMAX },
1107 { .div = 1, .freq = 1500 * MHZ },
1108 { .div = 2, .freq = 750 * MHZ },
1109 { .div = 3, .freq = 375 * MHZ },
1110 { .div = 4, .freq = 187500000 },
1111 { } /* sentinel */
1112};
1113
1114static const struct mtk_pll_div_table mfgpll_div_table[] = {
1115 { .div = 0, .freq = MT8183_PLL_FMAX },
1116 { .div = 1, .freq = 1600 * MHZ },
1117 { .div = 2, .freq = 800 * MHZ },
1118 { .div = 3, .freq = 400 * MHZ },
1119 { .div = 4, .freq = 200 * MHZ },
1120 { } /* sentinel */
1121};
1122
1123static const struct mtk_pll_data plls[] = {
1124 PLL_B(CLK_APMIXED_ARMPLL_LL, "armpll_ll", 0x0200, 0x020C, 0x00000001,
1125 HAVE_RST_BAR | PLL_AO, BIT(24), 22, 8, 0x0204, 24, 0x0, 0x0, 0,
1126 0x0204, 0, 0, armpll_div_table),
1127 PLL_B(CLK_APMIXED_ARMPLL_L, "armpll_l", 0x0210, 0x021C, 0x00000001,
1128 HAVE_RST_BAR | PLL_AO, BIT(24), 22, 8, 0x0214, 24, 0x0, 0x0, 0,
1129 0x0214, 0, 0, armpll_div_table),
1130 PLL(CLK_APMIXED_CCIPLL, "ccipll", 0x0290, 0x029C, 0x00000001,
1131 HAVE_RST_BAR | PLL_AO, BIT(24), 22, 8, 0x0294, 24, 0x0, 0x0, 0,
1132 0x0294, 0, 0),
1133 PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0220, 0x022C, 0x00000001,
1134 HAVE_RST_BAR, BIT(24), 22, 8, 0x0224, 24, 0x0, 0x0, 0,
1135 0x0224, 0, 0),
1136 PLL(CLK_APMIXED_UNIV2PLL, "univ2pll", 0x0230, 0x023C, 0x00000001,
1137 HAVE_RST_BAR, BIT(24), 22, 8, 0x0234, 24, 0x0, 0x0, 0,
1138 0x0234, 0, 0),
1139 PLL_B(CLK_APMIXED_MFGPLL, "mfgpll", 0x0240, 0x024C, 0x00000001,
1140 0, 0, 22, 8, 0x0244, 24, 0x0, 0x0, 0, 0x0244, 0, 0,
1141 mfgpll_div_table),
1142 PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0250, 0x025C, 0x00000001,
1143 0, 0, 22, 8, 0x0254, 24, 0x0, 0x0, 0, 0x0254, 0, 0),
1144 PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0260, 0x026C, 0x00000001,
1145 0, 0, 22, 8, 0x0264, 24, 0x0, 0x0, 0, 0x0264, 0, 0),
1146 PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0270, 0x027C, 0x00000001,
1147 HAVE_RST_BAR, BIT(23), 22, 8, 0x0274, 24, 0x0, 0x0, 0,
1148 0x0274, 0, 0),
1149 PLL(CLK_APMIXED_APLL1, "apll1", 0x02A0, 0x02B0, 0x00000001,
1150 0, 0, 32, 8, 0x02A0, 1, 0x02A8, 0x0014, 0, 0x02A4, 0, 0x02A0),
1151 PLL(CLK_APMIXED_APLL2, "apll2", 0x02b4, 0x02c4, 0x00000001,
1152 0, 0, 32, 8, 0x02B4, 1, 0x02BC, 0x0014, 1, 0x02B8, 0, 0x02B4),
1153};
1154
1155static int clk_mt8183_apmixed_probe(struct platform_device *pdev)
1156{
1157 struct clk_onecell_data *clk_data;
1158 struct device_node *node = pdev->dev.of_node;
1159
1160 clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
1161
1162 mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
1163
1164 mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks),
1165 clk_data);
1166
1167 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
1168}
1169
1170static int clk_mt8183_top_probe(struct platform_device *pdev)
1171{
1172 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1173 void __iomem *base;
1174 struct clk_onecell_data *clk_data;
1175 struct device_node *node = pdev->dev.of_node;
1176
1177 base = devm_ioremap_resource(&pdev->dev, res);
1178 if (IS_ERR(base))
1179 return PTR_ERR(base);
1180
1181 clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
1182
1183 mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
1184 clk_data);
1185
1186 mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
1187
1188 mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes),
1189 node, &mt8183_clk_lock, clk_data);
1190
1191 mtk_clk_register_composites(top_aud_muxes, ARRAY_SIZE(top_aud_muxes),
1192 base, &mt8183_clk_lock, clk_data);
1193
1194 mtk_clk_register_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs),
1195 base, &mt8183_clk_lock, clk_data);
1196
1197 mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
1198 clk_data);
1199
1200 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
1201}
1202
1203static int clk_mt8183_infra_probe(struct platform_device *pdev)
1204{
1205 struct clk_onecell_data *clk_data;
1206 struct device_node *node = pdev->dev.of_node;
1207
1208 clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
1209
1210 mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
1211 clk_data);
1212
1213 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
1214}
1215
1216static int clk_mt8183_mcu_probe(struct platform_device *pdev)
1217{
1218 struct clk_onecell_data *clk_data;
1219 struct device_node *node = pdev->dev.of_node;
1220 void __iomem *base;
1221 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1222
1223 base = devm_ioremap_resource(&pdev->dev, res);
1224 if (IS_ERR(base))
1225 return PTR_ERR(base);
1226
1227 clk_data = mtk_alloc_clk_data(CLK_MCU_NR_CLK);
1228
1229 mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base,
1230 &mt8183_clk_lock, clk_data);
1231
1232 return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
1233}
1234
1235static const struct of_device_id of_match_clk_mt8183[] = {
1236 {
1237 .compatible = "mediatek,mt8183-apmixedsys",
1238 .data = clk_mt8183_apmixed_probe,
1239 }, {
1240 .compatible = "mediatek,mt8183-topckgen",
1241 .data = clk_mt8183_top_probe,
1242 }, {
1243 .compatible = "mediatek,mt8183-infracfg",
1244 .data = clk_mt8183_infra_probe,
1245 }, {
1246 .compatible = "mediatek,mt8183-mcucfg",
1247 .data = clk_mt8183_mcu_probe,
1248 }, {
1249 /* sentinel */
1250 }
1251};
1252
1253static int clk_mt8183_probe(struct platform_device *pdev)
1254{
1255 int (*clk_probe)(struct platform_device *pdev);
1256 int r;
1257
1258 clk_probe = of_device_get_match_data(&pdev->dev);
1259 if (!clk_probe)
1260 return -EINVAL;
1261
1262 r = clk_probe(pdev);
1263 if (r)
1264 dev_err(&pdev->dev,
1265 "could not register clock provider: %s: %d\n",
1266 pdev->name, r);
1267
1268 return r;
1269}
1270
1271static struct platform_driver clk_mt8183_drv = {
1272 .probe = clk_mt8183_probe,
1273 .driver = {
1274 .name = "clk-mt8183",
1275 .of_match_table = of_match_clk_mt8183,
1276 },
1277};
1278
1279static int __init clk_mt8183_init(void)
1280{
1281 return platform_driver_register(&clk_mt8183_drv);
1282}
1283
1284arch_initcall(clk_mt8183_init);
diff --git a/drivers/clk/mediatek/clk-mt8516.c b/drivers/clk/mediatek/clk-mt8516.c
new file mode 100644
index 000000000000..26fe43cc9ea2
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8516.c
@@ -0,0 +1,815 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019 MediaTek Inc.
4 * Author: James Liao <jamesjj.liao@mediatek.com>
5 * Fabien Parent <fparent@baylibre.com>
6 */
7
8#include <linux/delay.h>
9#include <linux/of.h>
10#include <linux/of_address.h>
11#include <linux/slab.h>
12#include <linux/mfd/syscon.h>
13
14#include "clk-mtk.h"
15#include "clk-gate.h"
16
17#include <dt-bindings/clock/mt8516-clk.h>
18
19static DEFINE_SPINLOCK(mt8516_clk_lock);
20
21static const struct mtk_fixed_clk fixed_clks[] __initconst = {
22 FIXED_CLK(CLK_TOP_CLK_NULL, "clk_null", NULL, 0),
23 FIXED_CLK(CLK_TOP_I2S_INFRA_BCK, "i2s_infra_bck", "clk_null", 26000000),
24 FIXED_CLK(CLK_TOP_MEMPLL, "mempll", "clk26m", 800000000),
25};
26
27static const struct mtk_fixed_factor top_divs[] __initconst = {
28 FACTOR(CLK_TOP_DMPLL, "dmpll_ck", "mempll", 1, 1),
29 FACTOR(CLK_TOP_MAINPLL_D2, "mainpll_d2", "mainpll", 1, 2),
30 FACTOR(CLK_TOP_MAINPLL_D4, "mainpll_d4", "mainpll", 1, 4),
31 FACTOR(CLK_TOP_MAINPLL_D8, "mainpll_d8", "mainpll", 1, 8),
32 FACTOR(CLK_TOP_MAINPLL_D16, "mainpll_d16", "mainpll", 1, 16),
33 FACTOR(CLK_TOP_MAINPLL_D11, "mainpll_d11", "mainpll", 1, 11),
34 FACTOR(CLK_TOP_MAINPLL_D22, "mainpll_d22", "mainpll", 1, 22),
35 FACTOR(CLK_TOP_MAINPLL_D3, "mainpll_d3", "mainpll", 1, 3),
36 FACTOR(CLK_TOP_MAINPLL_D6, "mainpll_d6", "mainpll", 1, 6),
37 FACTOR(CLK_TOP_MAINPLL_D12, "mainpll_d12", "mainpll", 1, 12),
38 FACTOR(CLK_TOP_MAINPLL_D5, "mainpll_d5", "mainpll", 1, 5),
39 FACTOR(CLK_TOP_MAINPLL_D10, "mainpll_d10", "mainpll", 1, 10),
40 FACTOR(CLK_TOP_MAINPLL_D20, "mainpll_d20", "mainpll", 1, 20),
41 FACTOR(CLK_TOP_MAINPLL_D40, "mainpll_d40", "mainpll", 1, 40),
42 FACTOR(CLK_TOP_MAINPLL_D7, "mainpll_d7", "mainpll", 1, 7),
43 FACTOR(CLK_TOP_MAINPLL_D14, "mainpll_d14", "mainpll", 1, 14),
44 FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
45 FACTOR(CLK_TOP_UNIVPLL_D4, "univpll_d4", "univpll", 1, 4),
46 FACTOR(CLK_TOP_UNIVPLL_D8, "univpll_d8", "univpll", 1, 8),
47 FACTOR(CLK_TOP_UNIVPLL_D16, "univpll_d16", "univpll", 1, 16),
48 FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
49 FACTOR(CLK_TOP_UNIVPLL_D6, "univpll_d6", "univpll", 1, 6),
50 FACTOR(CLK_TOP_UNIVPLL_D12, "univpll_d12", "univpll", 1, 12),
51 FACTOR(CLK_TOP_UNIVPLL_D24, "univpll_d24", "univpll", 1, 24),
52 FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
53 FACTOR(CLK_TOP_UNIVPLL_D20, "univpll_d20", "univpll", 1, 20),
54 FACTOR(CLK_TOP_MMPLL380M, "mmpll380m", "mmpll", 1, 1),
55 FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
56 FACTOR(CLK_TOP_MMPLL_200M, "mmpll_200m", "mmpll", 1, 3),
57 FACTOR(CLK_TOP_USB_PHY48M, "usb_phy48m_ck", "univpll", 1, 26),
58 FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, 1),
59 FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1_ck", 1, 2),
60 FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "rg_apll1_d2_en", 1, 2),
61 FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "rg_apll1_d4_en", 1, 2),
62 FACTOR(CLK_TOP_APLL2, "apll2_ck", "apll2", 1, 1),
63 FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2_ck", 1, 2),
64 FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "rg_apll2_d2_en", 1, 2),
65 FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "rg_apll2_d4_en", 1, 2),
66 FACTOR(CLK_TOP_CLK26M, "clk26m_ck", "clk26m", 1, 1),
67 FACTOR(CLK_TOP_CLK26M_D2, "clk26m_d2", "clk26m", 1, 2),
68 FACTOR(CLK_TOP_AHB_INFRA_D2, "ahb_infra_d2", "ahb_infra_sel", 1, 2),
69 FACTOR(CLK_TOP_NFI1X, "nfi1x_ck", "nfi2x_pad_sel", 1, 2),
70 FACTOR(CLK_TOP_ETH_D2, "eth_d2_ck", "eth_sel", 1, 2),
71};
72
73static const char * const uart0_parents[] __initconst = {
74 "clk26m_ck",
75 "univpll_d24"
76};
77
78static const char * const ahb_infra_parents[] __initconst = {
79 "clk_null",
80 "clk26m_ck",
81 "mainpll_d11",
82 "clk_null",
83 "mainpll_d12",
84 "clk_null",
85 "clk_null",
86 "clk_null",
87 "clk_null",
88 "clk_null",
89 "clk_null",
90 "clk_null",
91 "mainpll_d10"
92};
93
94static const char * const msdc0_parents[] __initconst = {
95 "clk26m_ck",
96 "univpll_d6",
97 "mainpll_d8",
98 "univpll_d8",
99 "mainpll_d16",
100 "mmpll_200m",
101 "mainpll_d12",
102 "mmpll_d2"
103};
104
105static const char * const uart1_parents[] __initconst = {
106 "clk26m_ck",
107 "univpll_d24"
108};
109
110static const char * const msdc1_parents[] __initconst = {
111 "clk26m_ck",
112 "univpll_d6",
113 "mainpll_d8",
114 "univpll_d8",
115 "mainpll_d16",
116 "mmpll_200m",
117 "mainpll_d12",
118 "mmpll_d2"
119};
120
121static const char * const pmicspi_parents[] __initconst = {
122 "univpll_d20",
123 "usb_phy48m_ck",
124 "univpll_d16",
125 "clk26m_ck"
126};
127
128static const char * const qaxi_aud26m_parents[] __initconst = {
129 "clk26m_ck",
130 "ahb_infra_sel"
131};
132
133static const char * const aud_intbus_parents[] __initconst = {
134 "clk_null",
135 "clk26m_ck",
136 "mainpll_d22",
137 "clk_null",
138 "mainpll_d11"
139};
140
141static const char * const nfi2x_pad_parents[] __initconst = {
142 "clk_null",
143 "clk_null",
144 "clk_null",
145 "clk_null",
146 "clk_null",
147 "clk_null",
148 "clk_null",
149 "clk_null",
150 "clk26m_ck",
151 "clk_null",
152 "clk_null",
153 "clk_null",
154 "clk_null",
155 "clk_null",
156 "clk_null",
157 "clk_null",
158 "clk_null",
159 "mainpll_d12",
160 "mainpll_d8",
161 "clk_null",
162 "mainpll_d6",
163 "clk_null",
164 "clk_null",
165 "clk_null",
166 "clk_null",
167 "clk_null",
168 "clk_null",
169 "clk_null",
170 "clk_null",
171 "clk_null",
172 "clk_null",
173 "clk_null",
174 "mainpll_d4",
175 "clk_null",
176 "clk_null",
177 "clk_null",
178 "clk_null",
179 "clk_null",
180 "clk_null",
181 "clk_null",
182 "clk_null",
183 "clk_null",
184 "clk_null",
185 "clk_null",
186 "clk_null",
187 "clk_null",
188 "clk_null",
189 "clk_null",
190 "clk_null",
191 "clk_null",
192 "clk_null",
193 "clk_null",
194 "clk_null",
195 "clk_null",
196 "clk_null",
197 "clk_null",
198 "clk_null",
199 "clk_null",
200 "clk_null",
201 "clk_null",
202 "clk_null",
203 "clk_null",
204 "clk_null",
205 "clk_null",
206 "clk_null",
207 "clk_null",
208 "clk_null",
209 "clk_null",
210 "clk_null",
211 "clk_null",
212 "clk_null",
213 "clk_null",
214 "clk_null",
215 "clk_null",
216 "clk_null",
217 "clk_null",
218 "clk_null",
219 "clk_null",
220 "clk_null",
221 "clk_null",
222 "clk_null",
223 "mainpll_d10",
224 "mainpll_d7",
225 "clk_null",
226 "mainpll_d5"
227};
228
229static const char * const nfi1x_pad_parents[] __initconst = {
230 "ahb_infra_sel",
231 "nfi1x_ck"
232};
233
234static const char * const ddrphycfg_parents[] __initconst = {
235 "clk26m_ck",
236 "mainpll_d16"
237};
238
239static const char * const usb_78m_parents[] __initconst = {
240 "clk_null",
241 "clk26m_ck",
242 "univpll_d16",
243 "clk_null",
244 "mainpll_d20"
245};
246
247static const char * const spinor_parents[] __initconst = {
248 "clk26m_d2",
249 "clk26m_ck",
250 "mainpll_d40",
251 "univpll_d24",
252 "univpll_d20",
253 "mainpll_d20",
254 "mainpll_d16",
255 "univpll_d12"
256};
257
258static const char * const msdc2_parents[] __initconst = {
259 "clk26m_ck",
260 "univpll_d6",
261 "mainpll_d8",
262 "univpll_d8",
263 "mainpll_d16",
264 "mmpll_200m",
265 "mainpll_d12",
266 "mmpll_d2"
267};
268
269static const char * const eth_parents[] __initconst = {
270 "clk26m_ck",
271 "mainpll_d40",
272 "univpll_d24",
273 "univpll_d20",
274 "mainpll_d20"
275};
276
277static const char * const aud1_parents[] __initconst = {
278 "clk26m_ck",
279 "apll1_ck"
280};
281
282static const char * const aud2_parents[] __initconst = {
283 "clk26m_ck",
284 "apll2_ck"
285};
286
287static const char * const aud_engen1_parents[] __initconst = {
288 "clk26m_ck",
289 "rg_apll1_d2_en",
290 "rg_apll1_d4_en",
291 "rg_apll1_d8_en"
292};
293
294static const char * const aud_engen2_parents[] __initconst = {
295 "clk26m_ck",
296 "rg_apll2_d2_en",
297 "rg_apll2_d4_en",
298 "rg_apll2_d8_en"
299};
300
301static const char * const i2c_parents[] __initconst = {
302 "clk26m_ck",
303 "univpll_d20",
304 "univpll_d16",
305 "univpll_d12"
306};
307
308static const char * const aud_i2s0_m_parents[] __initconst = {
309 "rg_aud1",
310 "rg_aud2"
311};
312
313static const char * const pwm_parents[] __initconst = {
314 "clk26m_ck",
315 "univpll_d12"
316};
317
318static const char * const spi_parents[] __initconst = {
319 "clk26m_ck",
320 "univpll_d12",
321 "univpll_d8",
322 "univpll_d6"
323};
324
325static const char * const aud_spdifin_parents[] __initconst = {
326 "clk26m_ck",
327 "univpll_d2"
328};
329
330static const char * const uart2_parents[] __initconst = {
331 "clk26m_ck",
332 "univpll_d24"
333};
334
335static const char * const bsi_parents[] __initconst = {
336 "clk26m_ck",
337 "mainpll_d10",
338 "mainpll_d12",
339 "mainpll_d20"
340};
341
342static const char * const dbg_atclk_parents[] __initconst = {
343 "clk_null",
344 "clk26m_ck",
345 "mainpll_d5",
346 "clk_null",
347 "univpll_d5"
348};
349
350static const char * const csw_nfiecc_parents[] __initconst = {
351 "clk_null",
352 "mainpll_d7",
353 "mainpll_d6",
354 "clk_null",
355 "mainpll_d5"
356};
357
358static const char * const nfiecc_parents[] __initconst = {
359 "clk_null",
360 "nfi2x_pad_sel",
361 "mainpll_d4",
362 "clk_null",
363 "csw_nfiecc_sel"
364};
365
366static struct mtk_composite top_muxes[] __initdata = {
367 /* CLK_MUX_SEL0 */
368 MUX(CLK_TOP_UART0_SEL, "uart0_sel", uart0_parents,
369 0x000, 0, 1),
370 MUX(CLK_TOP_AHB_INFRA_SEL, "ahb_infra_sel", ahb_infra_parents,
371 0x000, 4, 4),
372 MUX(CLK_TOP_MSDC0_SEL, "msdc0_sel", msdc0_parents,
373 0x000, 11, 3),
374 MUX(CLK_TOP_UART1_SEL, "uart1_sel", uart1_parents,
375 0x000, 19, 1),
376 MUX(CLK_TOP_MSDC1_SEL, "msdc1_sel", msdc1_parents,
377 0x000, 20, 3),
378 MUX(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents,
379 0x000, 24, 2),
380 MUX(CLK_TOP_QAXI_AUD26M_SEL, "qaxi_aud26m_sel", qaxi_aud26m_parents,
381 0x000, 26, 1),
382 MUX(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
383 0x000, 27, 3),
384 /* CLK_MUX_SEL1 */
385 MUX(CLK_TOP_NFI2X_PAD_SEL, "nfi2x_pad_sel", nfi2x_pad_parents,
386 0x004, 0, 7),
387 MUX(CLK_TOP_NFI1X_PAD_SEL, "nfi1x_pad_sel", nfi1x_pad_parents,
388 0x004, 7, 1),
389 MUX(CLK_TOP_USB_78M_SEL, "usb_78m_sel", usb_78m_parents,
390 0x004, 20, 3),
391 /* CLK_MUX_SEL8 */
392 MUX(CLK_TOP_SPINOR_SEL, "spinor_sel", spinor_parents,
393 0x040, 0, 3),
394 MUX(CLK_TOP_MSDC2_SEL, "msdc2_sel", msdc2_parents,
395 0x040, 3, 3),
396 MUX(CLK_TOP_ETH_SEL, "eth_sel", eth_parents,
397 0x040, 6, 3),
398 MUX(CLK_TOP_AUD1_SEL, "aud1_sel", aud1_parents,
399 0x040, 22, 1),
400 MUX(CLK_TOP_AUD2_SEL, "aud2_sel", aud2_parents,
401 0x040, 23, 1),
402 MUX(CLK_TOP_AUD_ENGEN1_SEL, "aud_engen1_sel", aud_engen1_parents,
403 0x040, 24, 2),
404 MUX(CLK_TOP_AUD_ENGEN2_SEL, "aud_engen2_sel", aud_engen2_parents,
405 0x040, 26, 2),
406 MUX(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents,
407 0x040, 28, 2),
408 /* CLK_SEL_9 */
409 MUX(CLK_TOP_AUD_I2S0_M_SEL, "aud_i2s0_m_sel", aud_i2s0_m_parents,
410 0x044, 12, 1),
411 MUX(CLK_TOP_AUD_I2S1_M_SEL, "aud_i2s1_m_sel", aud_i2s0_m_parents,
412 0x044, 13, 1),
413 MUX(CLK_TOP_AUD_I2S2_M_SEL, "aud_i2s2_m_sel", aud_i2s0_m_parents,
414 0x044, 14, 1),
415 MUX(CLK_TOP_AUD_I2S3_M_SEL, "aud_i2s3_m_sel", aud_i2s0_m_parents,
416 0x044, 15, 1),
417 MUX(CLK_TOP_AUD_I2S4_M_SEL, "aud_i2s4_m_sel", aud_i2s0_m_parents,
418 0x044, 16, 1),
419 MUX(CLK_TOP_AUD_I2S5_M_SEL, "aud_i2s5_m_sel", aud_i2s0_m_parents,
420 0x044, 17, 1),
421 MUX(CLK_TOP_AUD_SPDIF_B_SEL, "aud_spdif_b_sel", aud_i2s0_m_parents,
422 0x044, 18, 1),
423 /* CLK_MUX_SEL13 */
424 MUX(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents,
425 0x07c, 0, 1),
426 MUX(CLK_TOP_SPI_SEL, "spi_sel", spi_parents,
427 0x07c, 1, 2),
428 MUX(CLK_TOP_AUD_SPDIFIN_SEL, "aud_spdifin_sel", aud_spdifin_parents,
429 0x07c, 3, 1),
430 MUX(CLK_TOP_UART2_SEL, "uart2_sel", uart2_parents,
431 0x07c, 4, 1),
432 MUX(CLK_TOP_BSI_SEL, "bsi_sel", bsi_parents,
433 0x07c, 5, 2),
434 MUX(CLK_TOP_DBG_ATCLK_SEL, "dbg_atclk_sel", dbg_atclk_parents,
435 0x07c, 7, 3),
436 MUX(CLK_TOP_CSW_NFIECC_SEL, "csw_nfiecc_sel", csw_nfiecc_parents,
437 0x07c, 10, 3),
438 MUX(CLK_TOP_NFIECC_SEL, "nfiecc_sel", nfiecc_parents,
439 0x07c, 13, 3),
440};
441
442static const char * const ifr_mux1_parents[] __initconst = {
443 "clk26m_ck",
444 "armpll",
445 "univpll",
446 "mainpll_d2"
447};
448
449static const char * const ifr_eth_25m_parents[] __initconst = {
450 "eth_d2_ck",
451 "rg_eth"
452};
453
454static const char * const ifr_i2c0_parents[] __initconst = {
455 "ahb_infra_d2",
456 "rg_i2c"
457};
458
459static const struct mtk_composite ifr_muxes[] __initconst = {
460 MUX(CLK_IFR_MUX1_SEL, "ifr_mux1_sel", ifr_mux1_parents, 0x000,
461 2, 2),
462 MUX(CLK_IFR_ETH_25M_SEL, "ifr_eth_25m_sel", ifr_eth_25m_parents, 0x080,
463 0, 1),
464 MUX(CLK_IFR_I2C0_SEL, "ifr_i2c0_sel", ifr_i2c0_parents, 0x080,
465 1, 1),
466 MUX(CLK_IFR_I2C1_SEL, "ifr_i2c1_sel", ifr_i2c0_parents, 0x080,
467 2, 1),
468 MUX(CLK_IFR_I2C2_SEL, "ifr_i2c2_sel", ifr_i2c0_parents, 0x080,
469 3, 1),
470};
471
472#define DIV_ADJ(_id, _name, _parent, _reg, _shift, _width) { \
473 .id = _id, \
474 .name = _name, \
475 .parent_name = _parent, \
476 .div_reg = _reg, \
477 .div_shift = _shift, \
478 .div_width = _width, \
479}
480
481static const struct mtk_clk_divider top_adj_divs[] = {
482 DIV_ADJ(CLK_TOP_APLL12_CK_DIV0, "apll12_ck_div0", "aud_i2s0_m_sel",
483 0x0048, 0, 8),
484 DIV_ADJ(CLK_TOP_APLL12_CK_DIV1, "apll12_ck_div1", "aud_i2s1_m_sel",
485 0x0048, 8, 8),
486 DIV_ADJ(CLK_TOP_APLL12_CK_DIV2, "apll12_ck_div2", "aud_i2s2_m_sel",
487 0x0048, 16, 8),
488 DIV_ADJ(CLK_TOP_APLL12_CK_DIV3, "apll12_ck_div3", "aud_i2s3_m_sel",
489 0x0048, 24, 8),
490 DIV_ADJ(CLK_TOP_APLL12_CK_DIV4, "apll12_ck_div4", "aud_i2s4_m_sel",
491 0x004c, 0, 8),
492 DIV_ADJ(CLK_TOP_APLL12_CK_DIV4B, "apll12_ck_div4b", "apll12_div4",
493 0x004c, 8, 8),
494 DIV_ADJ(CLK_TOP_APLL12_CK_DIV5, "apll12_ck_div5", "aud_i2s5_m_sel",
495 0x004c, 16, 8),
496 DIV_ADJ(CLK_TOP_APLL12_CK_DIV5B, "apll12_ck_div5b", "apll12_div5",
497 0x004c, 24, 8),
498 DIV_ADJ(CLK_TOP_APLL12_CK_DIV6, "apll12_ck_div6", "aud_spdif_b_sel",
499 0x0078, 0, 8),
500};
501
502static const struct mtk_gate_regs top1_cg_regs = {
503 .set_ofs = 0x54,
504 .clr_ofs = 0x84,
505 .sta_ofs = 0x24,
506};
507
508static const struct mtk_gate_regs top2_cg_regs = {
509 .set_ofs = 0x6c,
510 .clr_ofs = 0x9c,
511 .sta_ofs = 0x3c,
512};
513
514static const struct mtk_gate_regs top3_cg_regs = {
515 .set_ofs = 0xa0,
516 .clr_ofs = 0xb0,
517 .sta_ofs = 0x70,
518};
519
520static const struct mtk_gate_regs top4_cg_regs = {
521 .set_ofs = 0xa4,
522 .clr_ofs = 0xb4,
523 .sta_ofs = 0x74,
524};
525
526static const struct mtk_gate_regs top5_cg_regs = {
527 .set_ofs = 0x44,
528 .clr_ofs = 0x44,
529 .sta_ofs = 0x44,
530};
531
532#define GATE_TOP1(_id, _name, _parent, _shift) { \
533 .id = _id, \
534 .name = _name, \
535 .parent_name = _parent, \
536 .regs = &top1_cg_regs, \
537 .shift = _shift, \
538 .ops = &mtk_clk_gate_ops_setclr, \
539 }
540
541#define GATE_TOP2(_id, _name, _parent, _shift) { \
542 .id = _id, \
543 .name = _name, \
544 .parent_name = _parent, \
545 .regs = &top2_cg_regs, \
546 .shift = _shift, \
547 .ops = &mtk_clk_gate_ops_setclr, \
548 }
549
550#define GATE_TOP2_I(_id, _name, _parent, _shift) { \
551 .id = _id, \
552 .name = _name, \
553 .parent_name = _parent, \
554 .regs = &top2_cg_regs, \
555 .shift = _shift, \
556 .ops = &mtk_clk_gate_ops_setclr_inv, \
557 }
558
559#define GATE_TOP3(_id, _name, _parent, _shift) { \
560 .id = _id, \
561 .name = _name, \
562 .parent_name = _parent, \
563 .regs = &top3_cg_regs, \
564 .shift = _shift, \
565 .ops = &mtk_clk_gate_ops_setclr, \
566 }
567
568#define GATE_TOP4_I(_id, _name, _parent, _shift) { \
569 .id = _id, \
570 .name = _name, \
571 .parent_name = _parent, \
572 .regs = &top4_cg_regs, \
573 .shift = _shift, \
574 .ops = &mtk_clk_gate_ops_setclr_inv, \
575 }
576
577#define GATE_TOP5(_id, _name, _parent, _shift) { \
578 .id = _id, \
579 .name = _name, \
580 .parent_name = _parent, \
581 .regs = &top5_cg_regs, \
582 .shift = _shift, \
583 .ops = &mtk_clk_gate_ops_no_setclr, \
584 }
585
586static const struct mtk_gate top_clks[] __initconst = {
587 /* TOP1 */
588 GATE_TOP1(CLK_TOP_THEM, "them", "ahb_infra_sel", 1),
589 GATE_TOP1(CLK_TOP_APDMA, "apdma", "ahb_infra_sel", 2),
590 GATE_TOP1(CLK_TOP_I2C0, "i2c0", "ifr_i2c0_sel", 3),
591 GATE_TOP1(CLK_TOP_I2C1, "i2c1", "ifr_i2c1_sel", 4),
592 GATE_TOP1(CLK_TOP_AUXADC1, "auxadc1", "ahb_infra_sel", 5),
593 GATE_TOP1(CLK_TOP_NFI, "nfi", "nfi1x_pad_sel", 6),
594 GATE_TOP1(CLK_TOP_NFIECC, "nfiecc", "rg_nfiecc", 7),
595 GATE_TOP1(CLK_TOP_DEBUGSYS, "debugsys", "rg_dbg_atclk", 8),
596 GATE_TOP1(CLK_TOP_PWM, "pwm", "ahb_infra_sel", 9),
597 GATE_TOP1(CLK_TOP_UART0, "uart0", "uart0_sel", 10),
598 GATE_TOP1(CLK_TOP_UART1, "uart1", "uart1_sel", 11),
599 GATE_TOP1(CLK_TOP_BTIF, "btif", "ahb_infra_sel", 12),
600 GATE_TOP1(CLK_TOP_USB, "usb", "usb_78m", 13),
601 GATE_TOP1(CLK_TOP_FLASHIF_26M, "flashif_26m", "clk26m_ck", 14),
602 GATE_TOP1(CLK_TOP_AUXADC2, "auxadc2", "ahb_infra_sel", 15),
603 GATE_TOP1(CLK_TOP_I2C2, "i2c2", "ifr_i2c2_sel", 16),
604 GATE_TOP1(CLK_TOP_MSDC0, "msdc0", "msdc0_sel", 17),
605 GATE_TOP1(CLK_TOP_MSDC1, "msdc1", "msdc1_sel", 18),
606 GATE_TOP1(CLK_TOP_NFI2X, "nfi2x", "nfi2x_pad_sel", 19),
607 GATE_TOP1(CLK_TOP_PMICWRAP_AP, "pwrap_ap", "clk26m_ck", 20),
608 GATE_TOP1(CLK_TOP_SEJ, "sej", "ahb_infra_sel", 21),
609 GATE_TOP1(CLK_TOP_MEMSLP_DLYER, "memslp_dlyer", "clk26m_ck", 22),
610 GATE_TOP1(CLK_TOP_SPI, "spi", "spi_sel", 23),
611 GATE_TOP1(CLK_TOP_APXGPT, "apxgpt", "clk26m_ck", 24),
612 GATE_TOP1(CLK_TOP_AUDIO, "audio", "clk26m_ck", 25),
613 GATE_TOP1(CLK_TOP_PMICWRAP_MD, "pwrap_md", "clk26m_ck", 27),
614 GATE_TOP1(CLK_TOP_PMICWRAP_CONN, "pwrap_conn", "clk26m_ck", 28),
615 GATE_TOP1(CLK_TOP_PMICWRAP_26M, "pwrap_26m", "clk26m_ck", 29),
616 GATE_TOP1(CLK_TOP_AUX_ADC, "aux_adc", "clk26m_ck", 30),
617 GATE_TOP1(CLK_TOP_AUX_TP, "aux_tp", "clk26m_ck", 31),
618 /* TOP2 */
619 GATE_TOP2(CLK_TOP_MSDC2, "msdc2", "ahb_infra_sel", 0),
620 GATE_TOP2(CLK_TOP_RBIST, "rbist", "univpll_d12", 1),
621 GATE_TOP2(CLK_TOP_NFI_BUS, "nfi_bus", "ahb_infra_sel", 2),
622 GATE_TOP2(CLK_TOP_GCE, "gce", "ahb_infra_sel", 4),
623 GATE_TOP2(CLK_TOP_TRNG, "trng", "ahb_infra_sel", 5),
624 GATE_TOP2(CLK_TOP_SEJ_13M, "sej_13m", "clk26m_ck", 6),
625 GATE_TOP2(CLK_TOP_AES, "aes", "ahb_infra_sel", 7),
626 GATE_TOP2(CLK_TOP_PWM_B, "pwm_b", "rg_pwm_infra", 8),
627 GATE_TOP2(CLK_TOP_PWM1_FB, "pwm1_fb", "rg_pwm_infra", 9),
628 GATE_TOP2(CLK_TOP_PWM2_FB, "pwm2_fb", "rg_pwm_infra", 10),
629 GATE_TOP2(CLK_TOP_PWM3_FB, "pwm3_fb", "rg_pwm_infra", 11),
630 GATE_TOP2(CLK_TOP_PWM4_FB, "pwm4_fb", "rg_pwm_infra", 12),
631 GATE_TOP2(CLK_TOP_PWM5_FB, "pwm5_fb", "rg_pwm_infra", 13),
632 GATE_TOP2(CLK_TOP_USB_1P, "usb_1p", "usb_78m", 14),
633 GATE_TOP2(CLK_TOP_FLASHIF_FREERUN, "flashif_freerun", "ahb_infra_sel",
634 15),
635 GATE_TOP2(CLK_TOP_66M_ETH, "eth_66m", "ahb_infra_d2", 19),
636 GATE_TOP2(CLK_TOP_133M_ETH, "eth_133m", "ahb_infra_sel", 20),
637 GATE_TOP2(CLK_TOP_FETH_25M, "feth_25m", "ifr_eth_25m_sel", 21),
638 GATE_TOP2(CLK_TOP_FETH_50M, "feth_50m", "rg_eth", 22),
639 GATE_TOP2(CLK_TOP_FLASHIF_AXI, "flashif_axi", "ahb_infra_sel", 23),
640 GATE_TOP2(CLK_TOP_USBIF, "usbif", "ahb_infra_sel", 24),
641 GATE_TOP2(CLK_TOP_UART2, "uart2", "rg_uart2", 25),
642 GATE_TOP2(CLK_TOP_BSI, "bsi", "ahb_infra_sel", 26),
643 GATE_TOP2_I(CLK_TOP_MSDC0_INFRA, "msdc0_infra", "msdc0", 28),
644 GATE_TOP2_I(CLK_TOP_MSDC1_INFRA, "msdc1_infra", "msdc1", 29),
645 GATE_TOP2_I(CLK_TOP_MSDC2_INFRA, "msdc2_infra", "rg_msdc2", 30),
646 GATE_TOP2(CLK_TOP_USB_78M, "usb_78m", "usb_78m_sel", 31),
647 /* TOP3 */
648 GATE_TOP3(CLK_TOP_RG_SPINOR, "rg_spinor", "spinor_sel", 0),
649 GATE_TOP3(CLK_TOP_RG_MSDC2, "rg_msdc2", "msdc2_sel", 1),
650 GATE_TOP3(CLK_TOP_RG_ETH, "rg_eth", "eth_sel", 2),
651 GATE_TOP3(CLK_TOP_RG_AUD1, "rg_aud1", "aud1_sel", 8),
652 GATE_TOP3(CLK_TOP_RG_AUD2, "rg_aud2", "aud2_sel", 9),
653 GATE_TOP3(CLK_TOP_RG_AUD_ENGEN1, "rg_aud_engen1", "aud_engen1_sel", 10),
654 GATE_TOP3(CLK_TOP_RG_AUD_ENGEN2, "rg_aud_engen2", "aud_engen2_sel", 11),
655 GATE_TOP3(CLK_TOP_RG_I2C, "rg_i2c", "i2c_sel", 12),
656 GATE_TOP3(CLK_TOP_RG_PWM_INFRA, "rg_pwm_infra", "pwm_sel", 13),
657 GATE_TOP3(CLK_TOP_RG_AUD_SPDIF_IN, "rg_aud_spdif_in", "aud_spdifin_sel",
658 14),
659 GATE_TOP3(CLK_TOP_RG_UART2, "rg_uart2", "uart2_sel", 15),
660 GATE_TOP3(CLK_TOP_RG_BSI, "rg_bsi", "bsi_sel", 16),
661 GATE_TOP3(CLK_TOP_RG_DBG_ATCLK, "rg_dbg_atclk", "dbg_atclk_sel", 17),
662 GATE_TOP3(CLK_TOP_RG_NFIECC, "rg_nfiecc", "nfiecc_sel", 18),
663 /* TOP4 */
664 GATE_TOP4_I(CLK_TOP_RG_APLL1_D2_EN, "rg_apll1_d2_en", "apll1_d2", 8),
665 GATE_TOP4_I(CLK_TOP_RG_APLL1_D4_EN, "rg_apll1_d4_en", "apll1_d4", 9),
666 GATE_TOP4_I(CLK_TOP_RG_APLL1_D8_EN, "rg_apll1_d8_en", "apll1_d8", 10),
667 GATE_TOP4_I(CLK_TOP_RG_APLL2_D2_EN, "rg_apll2_d2_en", "apll2_d2", 11),
668 GATE_TOP4_I(CLK_TOP_RG_APLL2_D4_EN, "rg_apll2_d4_en", "apll2_d4", 12),
669 GATE_TOP4_I(CLK_TOP_RG_APLL2_D8_EN, "rg_apll2_d8_en", "apll2_d8", 13),
670 /* TOP5 */
671 GATE_TOP5(CLK_TOP_APLL12_DIV0, "apll12_div0", "apll12_ck_div0", 0),
672 GATE_TOP5(CLK_TOP_APLL12_DIV1, "apll12_div1", "apll12_ck_div1", 1),
673 GATE_TOP5(CLK_TOP_APLL12_DIV2, "apll12_div2", "apll12_ck_div2", 2),
674 GATE_TOP5(CLK_TOP_APLL12_DIV3, "apll12_div3", "apll12_ck_div3", 3),
675 GATE_TOP5(CLK_TOP_APLL12_DIV4, "apll12_div4", "apll12_ck_div4", 4),
676 GATE_TOP5(CLK_TOP_APLL12_DIV4B, "apll12_div4b", "apll12_ck_div4b", 5),
677 GATE_TOP5(CLK_TOP_APLL12_DIV5, "apll12_div5", "apll12_ck_div5", 6),
678 GATE_TOP5(CLK_TOP_APLL12_DIV5B, "apll12_div5b", "apll12_ck_div5b", 7),
679 GATE_TOP5(CLK_TOP_APLL12_DIV6, "apll12_div6", "apll12_ck_div6", 8),
680};
681
682static void __init mtk_topckgen_init(struct device_node *node)
683{
684 struct clk_onecell_data *clk_data;
685 int r;
686 void __iomem *base;
687
688 base = of_iomap(node, 0);
689 if (!base) {
690 pr_err("%s(): ioremap failed\n", __func__);
691 return;
692 }
693
694 clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
695
696 mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks),
697 clk_data);
698 mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), clk_data);
699
700 mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
701 mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
702 &mt8516_clk_lock, clk_data);
703 mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
704 base, &mt8516_clk_lock, clk_data);
705
706 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
707 if (r)
708 pr_err("%s(): could not register clock provider: %d\n",
709 __func__, r);
710}
711CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8516-topckgen", mtk_topckgen_init);
712
713static void __init mtk_infracfg_init(struct device_node *node)
714{
715 struct clk_onecell_data *clk_data;
716 int r;
717 void __iomem *base;
718
719 base = of_iomap(node, 0);
720 if (!base) {
721 pr_err("%s(): ioremap failed\n", __func__);
722 return;
723 }
724
725 clk_data = mtk_alloc_clk_data(CLK_IFR_NR_CLK);
726
727 mtk_clk_register_composites(ifr_muxes, ARRAY_SIZE(ifr_muxes), base,
728 &mt8516_clk_lock, clk_data);
729
730 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
731 if (r)
732 pr_err("%s(): could not register clock provider: %d\n",
733 __func__, r);
734}
735CLK_OF_DECLARE(mtk_infracfg, "mediatek,mt8516-infracfg", mtk_infracfg_init);
736
737#define MT8516_PLL_FMAX (1502UL * MHZ)
738
739#define CON0_MT8516_RST_BAR BIT(27)
740
741#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
742 _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, \
743 _pcw_shift, _div_table) { \
744 .id = _id, \
745 .name = _name, \
746 .reg = _reg, \
747 .pwr_reg = _pwr_reg, \
748 .en_mask = _en_mask, \
749 .flags = _flags, \
750 .rst_bar_mask = CON0_MT8516_RST_BAR, \
751 .fmax = MT8516_PLL_FMAX, \
752 .pcwbits = _pcwbits, \
753 .pd_reg = _pd_reg, \
754 .pd_shift = _pd_shift, \
755 .tuner_reg = _tuner_reg, \
756 .pcw_reg = _pcw_reg, \
757 .pcw_shift = _pcw_shift, \
758 .div_table = _div_table, \
759 }
760
761#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
762 _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, \
763 _pcw_shift) \
764 PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
765 _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
766 NULL)
767
768static const struct mtk_pll_div_table mmpll_div_table[] = {
769 { .div = 0, .freq = MT8516_PLL_FMAX },
770 { .div = 1, .freq = 1000000000 },
771 { .div = 2, .freq = 604500000 },
772 { .div = 3, .freq = 253500000 },
773 { .div = 4, .freq = 126750000 },
774 { } /* sentinel */
775};
776
777static const struct mtk_pll_data plls[] = {
778 PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0100, 0x0110, 0x00000001, 0,
779 21, 0x0104, 24, 0, 0x0104, 0),
780 PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0120, 0x0130, 0x00000001,
781 HAVE_RST_BAR, 21, 0x0124, 24, 0, 0x0124, 0),
782 PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x0140, 0x0150, 0x30000001,
783 HAVE_RST_BAR, 7, 0x0144, 24, 0, 0x0144, 0),
784 PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x0160, 0x0170, 0x00000001, 0,
785 21, 0x0164, 24, 0, 0x0164, 0, mmpll_div_table),
786 PLL(CLK_APMIXED_APLL1, "apll1", 0x0180, 0x0190, 0x00000001, 0,
787 31, 0x0180, 1, 0x0194, 0x0184, 0),
788 PLL(CLK_APMIXED_APLL2, "apll2", 0x01A0, 0x01B0, 0x00000001, 0,
789 31, 0x01A0, 1, 0x01B4, 0x01A4, 0),
790};
791
792static void __init mtk_apmixedsys_init(struct device_node *node)
793{
794 struct clk_onecell_data *clk_data;
795 void __iomem *base;
796 int r;
797
798 base = of_iomap(node, 0);
799 if (!base) {
800 pr_err("%s(): ioremap failed\n", __func__);
801 return;
802 }
803
804 clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
805
806 mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
807
808 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
809 if (r)
810 pr_err("%s(): could not register clock provider: %d\n",
811 __func__, r);
812
813}
814CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8516-apmixedsys",
815 mtk_apmixedsys_init);
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index fb27b5bf30d9..33ab1731482f 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -227,10 +227,13 @@ struct mtk_pll_data {
227 unsigned int flags; 227 unsigned int flags;
228 const struct clk_ops *ops; 228 const struct clk_ops *ops;
229 u32 rst_bar_mask; 229 u32 rst_bar_mask;
230 unsigned long fmin;
230 unsigned long fmax; 231 unsigned long fmax;
231 int pcwbits; 232 int pcwbits;
233 int pcwibits;
232 uint32_t pcw_reg; 234 uint32_t pcw_reg;
233 int pcw_shift; 235 int pcw_shift;
236 uint32_t pcw_chg_reg;
234 const struct mtk_pll_div_table *div_table; 237 const struct mtk_pll_div_table *div_table;
235 const char *parent_name; 238 const char *parent_name;
236}; 239};
diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
new file mode 100644
index 000000000000..76f9cd039195
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -0,0 +1,223 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2018 MediaTek Inc.
4 * Author: Owen Chen <owen.chen@mediatek.com>
5 */
6
7#include <linux/of.h>
8#include <linux/of_address.h>
9#include <linux/slab.h>
10#include <linux/mfd/syscon.h>
11
12#include "clk-mtk.h"
13#include "clk-mux.h"
14
15static inline struct mtk_clk_mux *to_mtk_clk_mux(struct clk_hw *hw)
16{
17 return container_of(hw, struct mtk_clk_mux, hw);
18}
19
20static int mtk_clk_mux_enable(struct clk_hw *hw)
21{
22 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
23 u32 mask = BIT(mux->data->gate_shift);
24
25 return regmap_update_bits(mux->regmap, mux->data->mux_ofs,
26 mask, ~mask);
27}
28
29static void mtk_clk_mux_disable(struct clk_hw *hw)
30{
31 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
32 u32 mask = BIT(mux->data->gate_shift);
33
34 regmap_update_bits(mux->regmap, mux->data->mux_ofs, mask, mask);
35}
36
37static int mtk_clk_mux_enable_setclr(struct clk_hw *hw)
38{
39 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
40
41 return regmap_write(mux->regmap, mux->data->clr_ofs,
42 BIT(mux->data->gate_shift));
43}
44
45static void mtk_clk_mux_disable_setclr(struct clk_hw *hw)
46{
47 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
48
49 regmap_write(mux->regmap, mux->data->set_ofs,
50 BIT(mux->data->gate_shift));
51}
52
53static int mtk_clk_mux_is_enabled(struct clk_hw *hw)
54{
55 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
56 u32 val;
57
58 regmap_read(mux->regmap, mux->data->mux_ofs, &val);
59
60 return (val & BIT(mux->data->gate_shift)) == 0;
61}
62
63static u8 mtk_clk_mux_get_parent(struct clk_hw *hw)
64{
65 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
66 u32 mask = GENMASK(mux->data->mux_width - 1, 0);
67 u32 val;
68
69 regmap_read(mux->regmap, mux->data->mux_ofs, &val);
70 val = (val >> mux->data->mux_shift) & mask;
71
72 return val;
73}
74
75static int mtk_clk_mux_set_parent_lock(struct clk_hw *hw, u8 index)
76{
77 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
78 u32 mask = GENMASK(mux->data->mux_width - 1, 0);
79 unsigned long flags = 0;
80
81 if (mux->lock)
82 spin_lock_irqsave(mux->lock, flags);
83 else
84 __acquire(mux->lock);
85
86 regmap_update_bits(mux->regmap, mux->data->mux_ofs, mask,
87 index << mux->data->mux_shift);
88
89 if (mux->lock)
90 spin_unlock_irqrestore(mux->lock, flags);
91 else
92 __release(mux->lock);
93
94 return 0;
95}
96
97static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index)
98{
99 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
100 u32 mask = GENMASK(mux->data->mux_width - 1, 0);
101 u32 val, orig;
102 unsigned long flags = 0;
103
104 if (mux->lock)
105 spin_lock_irqsave(mux->lock, flags);
106 else
107 __acquire(mux->lock);
108
109 regmap_read(mux->regmap, mux->data->mux_ofs, &orig);
110 val = (orig & ~(mask << mux->data->mux_shift))
111 | (index << mux->data->mux_shift);
112
113 if (val != orig) {
114 regmap_write(mux->regmap, mux->data->clr_ofs,
115 mask << mux->data->mux_shift);
116 regmap_write(mux->regmap, mux->data->set_ofs,
117 index << mux->data->mux_shift);
118
119 if (mux->data->upd_shift >= 0)
120 regmap_write(mux->regmap, mux->data->upd_ofs,
121 BIT(mux->data->upd_shift));
122 }
123
124 if (mux->lock)
125 spin_unlock_irqrestore(mux->lock, flags);
126 else
127 __release(mux->lock);
128
129 return 0;
130}
131
132const struct clk_ops mtk_mux_ops = {
133 .get_parent = mtk_clk_mux_get_parent,
134 .set_parent = mtk_clk_mux_set_parent_lock,
135};
136
137const struct clk_ops mtk_mux_clr_set_upd_ops = {
138 .get_parent = mtk_clk_mux_get_parent,
139 .set_parent = mtk_clk_mux_set_parent_setclr_lock,
140};
141
142const struct clk_ops mtk_mux_gate_ops = {
143 .enable = mtk_clk_mux_enable,
144 .disable = mtk_clk_mux_disable,
145 .is_enabled = mtk_clk_mux_is_enabled,
146 .get_parent = mtk_clk_mux_get_parent,
147 .set_parent = mtk_clk_mux_set_parent_lock,
148};
149
150const struct clk_ops mtk_mux_gate_clr_set_upd_ops = {
151 .enable = mtk_clk_mux_enable_setclr,
152 .disable = mtk_clk_mux_disable_setclr,
153 .is_enabled = mtk_clk_mux_is_enabled,
154 .get_parent = mtk_clk_mux_get_parent,
155 .set_parent = mtk_clk_mux_set_parent_setclr_lock,
156};
157
158struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
159 struct regmap *regmap,
160 spinlock_t *lock)
161{
162 struct mtk_clk_mux *clk_mux;
163 struct clk_init_data init;
164 struct clk *clk;
165
166 clk_mux = kzalloc(sizeof(*clk_mux), GFP_KERNEL);
167 if (!clk_mux)
168 return ERR_PTR(-ENOMEM);
169
170 init.name = mux->name;
171 init.flags = mux->flags | CLK_SET_RATE_PARENT;
172 init.parent_names = mux->parent_names;
173 init.num_parents = mux->num_parents;
174 init.ops = mux->ops;
175
176 clk_mux->regmap = regmap;
177 clk_mux->data = mux;
178 clk_mux->lock = lock;
179 clk_mux->hw.init = &init;
180
181 clk = clk_register(NULL, &clk_mux->hw);
182 if (IS_ERR(clk)) {
183 kfree(clk_mux);
184 return clk;
185 }
186
187 return clk;
188}
189
190int mtk_clk_register_muxes(const struct mtk_mux *muxes,
191 int num, struct device_node *node,
192 spinlock_t *lock,
193 struct clk_onecell_data *clk_data)
194{
195 struct regmap *regmap;
196 struct clk *clk;
197 int i;
198
199 regmap = syscon_node_to_regmap(node);
200 if (IS_ERR(regmap)) {
201 pr_err("Cannot find regmap for %pOF: %ld\n", node,
202 PTR_ERR(regmap));
203 return PTR_ERR(regmap);
204 }
205
206 for (i = 0; i < num; i++) {
207 const struct mtk_mux *mux = &muxes[i];
208
209 if (IS_ERR_OR_NULL(clk_data->clks[mux->id])) {
210 clk = mtk_clk_register_mux(mux, regmap, lock);
211
212 if (IS_ERR(clk)) {
213 pr_err("Failed to register clk %s: %ld\n",
214 mux->name, PTR_ERR(clk));
215 continue;
216 }
217
218 clk_data->clks[mux->id] = clk;
219 }
220 }
221
222 return 0;
223}
diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h
new file mode 100644
index 000000000000..f5625f4d9e6c
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mux.h
@@ -0,0 +1,89 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2018 MediaTek Inc.
4 * Author: Owen Chen <owen.chen@mediatek.com>
5 */
6
7#ifndef __DRV_CLK_MTK_MUX_H
8#define __DRV_CLK_MTK_MUX_H
9
10#include <linux/clk-provider.h>
11
12struct mtk_clk_mux {
13 struct clk_hw hw;
14 struct regmap *regmap;
15 const struct mtk_mux *data;
16 spinlock_t *lock;
17};
18
19struct mtk_mux {
20 int id;
21 const char *name;
22 const char * const *parent_names;
23 unsigned int flags;
24
25 u32 mux_ofs;
26 u32 set_ofs;
27 u32 clr_ofs;
28 u32 upd_ofs;
29
30 u8 mux_shift;
31 u8 mux_width;
32 u8 gate_shift;
33 s8 upd_shift;
34
35 const struct clk_ops *ops;
36
37 signed char num_parents;
38};
39
40extern const struct clk_ops mtk_mux_ops;
41extern const struct clk_ops mtk_mux_clr_set_upd_ops;
42extern const struct clk_ops mtk_mux_gate_ops;
43extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
44
45#define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
46 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
47 _gate, _upd_ofs, _upd, _flags, _ops) { \
48 .id = _id, \
49 .name = _name, \
50 .mux_ofs = _mux_ofs, \
51 .set_ofs = _mux_set_ofs, \
52 .clr_ofs = _mux_clr_ofs, \
53 .upd_ofs = _upd_ofs, \
54 .mux_shift = _shift, \
55 .mux_width = _width, \
56 .gate_shift = _gate, \
57 .upd_shift = _upd, \
58 .parent_names = _parents, \
59 .num_parents = ARRAY_SIZE(_parents), \
60 .flags = _flags, \
61 .ops = &_ops, \
62 }
63
64#define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
65 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
66 _gate, _upd_ofs, _upd, _flags) \
67 GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
68 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
69 _gate, _upd_ofs, _upd, _flags, \
70 mtk_mux_gate_clr_set_upd_ops)
71
72#define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \
73 _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
74 _gate, _upd_ofs, _upd) \
75 MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
76 _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift, \
77 _width, _gate, _upd_ofs, _upd, \
78 CLK_SET_RATE_PARENT)
79
80struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
81 struct regmap *regmap,
82 spinlock_t *lock);
83
84int mtk_clk_register_muxes(const struct mtk_mux *muxes,
85 int num, struct device_node *node,
86 spinlock_t *lock,
87 struct clk_onecell_data *clk_data);
88
89#endif /* __DRV_CLK_MTK_MUX_H */
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index f54e4015b0b1..8d556fc99fed 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -27,11 +27,13 @@
27#define CON0_BASE_EN BIT(0) 27#define CON0_BASE_EN BIT(0)
28#define CON0_PWR_ON BIT(0) 28#define CON0_PWR_ON BIT(0)
29#define CON0_ISO_EN BIT(1) 29#define CON0_ISO_EN BIT(1)
30#define CON0_PCW_CHG BIT(31) 30#define PCW_CHG_MASK BIT(31)
31 31
32#define AUDPLL_TUNER_EN BIT(31) 32#define AUDPLL_TUNER_EN BIT(31)
33 33
34#define POSTDIV_MASK 0x7 34#define POSTDIV_MASK 0x7
35
36/* default 7 bits integer, can be overridden with pcwibits. */
35#define INTEGER_BITS 7 37#define INTEGER_BITS 7
36 38
37/* 39/*
@@ -49,6 +51,7 @@ struct mtk_clk_pll {
49 void __iomem *tuner_addr; 51 void __iomem *tuner_addr;
50 void __iomem *tuner_en_addr; 52 void __iomem *tuner_en_addr;
51 void __iomem *pcw_addr; 53 void __iomem *pcw_addr;
54 void __iomem *pcw_chg_addr;
52 const struct mtk_pll_data *data; 55 const struct mtk_pll_data *data;
53}; 56};
54 57
@@ -68,12 +71,15 @@ static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
68 u32 pcw, int postdiv) 71 u32 pcw, int postdiv)
69{ 72{
70 int pcwbits = pll->data->pcwbits; 73 int pcwbits = pll->data->pcwbits;
71 int pcwfbits; 74 int pcwfbits = 0;
75 int ibits;
72 u64 vco; 76 u64 vco;
73 u8 c = 0; 77 u8 c = 0;
74 78
75 /* The fractional part of the PLL divider. */ 79 /* The fractional part of the PLL divider. */
76 pcwfbits = pcwbits > INTEGER_BITS ? pcwbits - INTEGER_BITS : 0; 80 ibits = pll->data->pcwibits ? pll->data->pcwibits : INTEGER_BITS;
81 if (pcwbits > ibits)
82 pcwfbits = pcwbits - ibits;
77 83
78 vco = (u64)fin * pcw; 84 vco = (u64)fin * pcw;
79 85
@@ -88,13 +94,39 @@ static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
88 return ((unsigned long)vco + postdiv - 1) / postdiv; 94 return ((unsigned long)vco + postdiv - 1) / postdiv;
89} 95}
90 96
97static void __mtk_pll_tuner_enable(struct mtk_clk_pll *pll)
98{
99 u32 r;
100
101 if (pll->tuner_en_addr) {
102 r = readl(pll->tuner_en_addr) | BIT(pll->data->tuner_en_bit);
103 writel(r, pll->tuner_en_addr);
104 } else if (pll->tuner_addr) {
105 r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN;
106 writel(r, pll->tuner_addr);
107 }
108}
109
110static void __mtk_pll_tuner_disable(struct mtk_clk_pll *pll)
111{
112 u32 r;
113
114 if (pll->tuner_en_addr) {
115 r = readl(pll->tuner_en_addr) & ~BIT(pll->data->tuner_en_bit);
116 writel(r, pll->tuner_en_addr);
117 } else if (pll->tuner_addr) {
118 r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN;
119 writel(r, pll->tuner_addr);
120 }
121}
122
91static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw, 123static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
92 int postdiv) 124 int postdiv)
93{ 125{
94 u32 con1, val; 126 u32 chg, val;
95 int pll_en;
96 127
97 pll_en = readl(pll->base_addr + REG_CON0) & CON0_BASE_EN; 128 /* disable tuner */
129 __mtk_pll_tuner_disable(pll);
98 130
99 /* set postdiv */ 131 /* set postdiv */
100 val = readl(pll->pd_addr); 132 val = readl(pll->pd_addr);
@@ -112,18 +144,15 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
112 pll->data->pcw_shift); 144 pll->data->pcw_shift);
113 val |= pcw << pll->data->pcw_shift; 145 val |= pcw << pll->data->pcw_shift;
114 writel(val, pll->pcw_addr); 146 writel(val, pll->pcw_addr);
115 147 chg = readl(pll->pcw_chg_addr) | PCW_CHG_MASK;
116 con1 = readl(pll->base_addr + REG_CON1); 148 writel(chg, pll->pcw_chg_addr);
117
118 if (pll_en)
119 con1 |= CON0_PCW_CHG;
120
121 writel(con1, pll->base_addr + REG_CON1);
122 if (pll->tuner_addr) 149 if (pll->tuner_addr)
123 writel(con1 + 1, pll->tuner_addr); 150 writel(val + 1, pll->tuner_addr);
151
152 /* restore tuner_en */
153 __mtk_pll_tuner_enable(pll);
124 154
125 if (pll_en) 155 udelay(20);
126 udelay(20);
127} 156}
128 157
129/* 158/*
@@ -138,9 +167,10 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
138static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv, 167static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
139 u32 freq, u32 fin) 168 u32 freq, u32 fin)
140{ 169{
141 unsigned long fmin = 1000 * MHZ; 170 unsigned long fmin = pll->data->fmin ? pll->data->fmin : (1000 * MHZ);
142 const struct mtk_pll_div_table *div_table = pll->data->div_table; 171 const struct mtk_pll_div_table *div_table = pll->data->div_table;
143 u64 _pcw; 172 u64 _pcw;
173 int ibits;
144 u32 val; 174 u32 val;
145 175
146 if (freq > pll->data->fmax) 176 if (freq > pll->data->fmax)
@@ -164,7 +194,8 @@ static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
164 } 194 }
165 195
166 /* _pcw = freq * postdiv / fin * 2^pcwfbits */ 196 /* _pcw = freq * postdiv / fin * 2^pcwfbits */
167 _pcw = ((u64)freq << val) << (pll->data->pcwbits - INTEGER_BITS); 197 ibits = pll->data->pcwibits ? pll->data->pcwibits : INTEGER_BITS;
198 _pcw = ((u64)freq << val) << (pll->data->pcwbits - ibits);
168 do_div(_pcw, fin); 199 do_div(_pcw, fin);
169 200
170 *pcw = (u32)_pcw; 201 *pcw = (u32)_pcw;
@@ -228,13 +259,7 @@ static int mtk_pll_prepare(struct clk_hw *hw)
228 r |= pll->data->en_mask; 259 r |= pll->data->en_mask;
229 writel(r, pll->base_addr + REG_CON0); 260 writel(r, pll->base_addr + REG_CON0);
230 261
231 if (pll->tuner_en_addr) { 262 __mtk_pll_tuner_enable(pll);
232 r = readl(pll->tuner_en_addr) | BIT(pll->data->tuner_en_bit);
233 writel(r, pll->tuner_en_addr);
234 } else if (pll->tuner_addr) {
235 r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN;
236 writel(r, pll->tuner_addr);
237 }
238 263
239 udelay(20); 264 udelay(20);
240 265
@@ -258,13 +283,7 @@ static void mtk_pll_unprepare(struct clk_hw *hw)
258 writel(r, pll->base_addr + REG_CON0); 283 writel(r, pll->base_addr + REG_CON0);
259 } 284 }
260 285
261 if (pll->tuner_en_addr) { 286 __mtk_pll_tuner_disable(pll);
262 r = readl(pll->tuner_en_addr) & ~BIT(pll->data->tuner_en_bit);
263 writel(r, pll->tuner_en_addr);
264 } else if (pll->tuner_addr) {
265 r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN;
266 writel(r, pll->tuner_addr);
267 }
268 287
269 r = readl(pll->base_addr + REG_CON0); 288 r = readl(pll->base_addr + REG_CON0);
270 r &= ~CON0_BASE_EN; 289 r &= ~CON0_BASE_EN;
@@ -302,6 +321,10 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
302 pll->pwr_addr = base + data->pwr_reg; 321 pll->pwr_addr = base + data->pwr_reg;
303 pll->pd_addr = base + data->pd_reg; 322 pll->pd_addr = base + data->pd_reg;
304 pll->pcw_addr = base + data->pcw_reg; 323 pll->pcw_addr = base + data->pcw_reg;
324 if (data->pcw_chg_reg)
325 pll->pcw_chg_addr = base + data->pcw_chg_reg;
326 else
327 pll->pcw_chg_addr = pll->base_addr + REG_CON1;
305 if (data->tuner_reg) 328 if (data->tuner_reg)
306 pll->tuner_addr = base + data->tuner_reg; 329 pll->tuner_addr = base + data->tuner_reg;
307 if (data->tuner_en_reg) 330 if (data->tuner_en_reg)
diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c
index 7ab200b6c3bf..8028ff6f6610 100644
--- a/drivers/clk/meson/axg-audio.c
+++ b/drivers/clk/meson/axg-audio.c
@@ -20,18 +20,18 @@
20#include "clk-phase.h" 20#include "clk-phase.h"
21#include "sclk-div.h" 21#include "sclk-div.h"
22 22
23#define AXG_MST_IN_COUNT 8 23#define AUD_MST_IN_COUNT 8
24#define AXG_SLV_SCLK_COUNT 10 24#define AUD_SLV_SCLK_COUNT 10
25#define AXG_SLV_LRCLK_COUNT 10 25#define AUD_SLV_LRCLK_COUNT 10
26 26
27#define AXG_AUD_GATE(_name, _reg, _bit, _pname, _iflags) \ 27#define AUD_GATE(_name, _reg, _bit, _pname, _iflags) \
28struct clk_regmap axg_##_name = { \ 28struct clk_regmap aud_##_name = { \
29 .data = &(struct clk_regmap_gate_data){ \ 29 .data = &(struct clk_regmap_gate_data){ \
30 .offset = (_reg), \ 30 .offset = (_reg), \
31 .bit_idx = (_bit), \ 31 .bit_idx = (_bit), \
32 }, \ 32 }, \
33 .hw.init = &(struct clk_init_data) { \ 33 .hw.init = &(struct clk_init_data) { \
34 .name = "axg_"#_name, \ 34 .name = "aud_"#_name, \
35 .ops = &clk_regmap_gate_ops, \ 35 .ops = &clk_regmap_gate_ops, \
36 .parent_names = (const char *[]){ _pname }, \ 36 .parent_names = (const char *[]){ _pname }, \
37 .num_parents = 1, \ 37 .num_parents = 1, \
@@ -39,8 +39,8 @@ struct clk_regmap axg_##_name = { \
39 }, \ 39 }, \
40} 40}
41 41
42#define AXG_AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pnames, _iflags) \ 42#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pnames, _iflags) \
43struct clk_regmap axg_##_name = { \ 43struct clk_regmap aud_##_name = { \
44 .data = &(struct clk_regmap_mux_data){ \ 44 .data = &(struct clk_regmap_mux_data){ \
45 .offset = (_reg), \ 45 .offset = (_reg), \
46 .mask = (_mask), \ 46 .mask = (_mask), \
@@ -48,7 +48,7 @@ struct clk_regmap axg_##_name = { \
48 .flags = (_dflags), \ 48 .flags = (_dflags), \
49 }, \ 49 }, \
50 .hw.init = &(struct clk_init_data){ \ 50 .hw.init = &(struct clk_init_data){ \
51 .name = "axg_"#_name, \ 51 .name = "aud_"#_name, \
52 .ops = &clk_regmap_mux_ops, \ 52 .ops = &clk_regmap_mux_ops, \
53 .parent_names = (_pnames), \ 53 .parent_names = (_pnames), \
54 .num_parents = ARRAY_SIZE(_pnames), \ 54 .num_parents = ARRAY_SIZE(_pnames), \
@@ -56,8 +56,8 @@ struct clk_regmap axg_##_name = { \
56 }, \ 56 }, \
57} 57}
58 58
59#define AXG_AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) \ 59#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) \
60struct clk_regmap axg_##_name = { \ 60struct clk_regmap aud_##_name = { \
61 .data = &(struct clk_regmap_div_data){ \ 61 .data = &(struct clk_regmap_div_data){ \
62 .offset = (_reg), \ 62 .offset = (_reg), \
63 .shift = (_shift), \ 63 .shift = (_shift), \
@@ -65,7 +65,7 @@ struct clk_regmap axg_##_name = { \
65 .flags = (_dflags), \ 65 .flags = (_dflags), \
66 }, \ 66 }, \
67 .hw.init = &(struct clk_init_data){ \ 67 .hw.init = &(struct clk_init_data){ \
68 .name = "axg_"#_name, \ 68 .name = "aud_"#_name, \
69 .ops = &clk_regmap_divider_ops, \ 69 .ops = &clk_regmap_divider_ops, \
70 .parent_names = (const char *[]) { _pname }, \ 70 .parent_names = (const char *[]) { _pname }, \
71 .num_parents = 1, \ 71 .num_parents = 1, \
@@ -73,109 +73,113 @@ struct clk_regmap axg_##_name = { \
73 }, \ 73 }, \
74} 74}
75 75
76#define AXG_PCLK_GATE(_name, _bit) \ 76#define AUD_PCLK_GATE(_name, _bit) \
77 AXG_AUD_GATE(_name, AUDIO_CLK_GATE_EN, _bit, "axg_audio_pclk", 0) 77 AUD_GATE(_name, AUDIO_CLK_GATE_EN, _bit, "audio_pclk", 0)
78 78
79/* Audio peripheral clocks */ 79/* Audio peripheral clocks */
80static AXG_PCLK_GATE(ddr_arb, 0); 80static AUD_PCLK_GATE(ddr_arb, 0);
81static AXG_PCLK_GATE(pdm, 1); 81static AUD_PCLK_GATE(pdm, 1);
82static AXG_PCLK_GATE(tdmin_a, 2); 82static AUD_PCLK_GATE(tdmin_a, 2);
83static AXG_PCLK_GATE(tdmin_b, 3); 83static AUD_PCLK_GATE(tdmin_b, 3);
84static AXG_PCLK_GATE(tdmin_c, 4); 84static AUD_PCLK_GATE(tdmin_c, 4);
85static AXG_PCLK_GATE(tdmin_lb, 5); 85static AUD_PCLK_GATE(tdmin_lb, 5);
86static AXG_PCLK_GATE(tdmout_a, 6); 86static AUD_PCLK_GATE(tdmout_a, 6);
87static AXG_PCLK_GATE(tdmout_b, 7); 87static AUD_PCLK_GATE(tdmout_b, 7);
88static AXG_PCLK_GATE(tdmout_c, 8); 88static AUD_PCLK_GATE(tdmout_c, 8);
89static AXG_PCLK_GATE(frddr_a, 9); 89static AUD_PCLK_GATE(frddr_a, 9);
90static AXG_PCLK_GATE(frddr_b, 10); 90static AUD_PCLK_GATE(frddr_b, 10);
91static AXG_PCLK_GATE(frddr_c, 11); 91static AUD_PCLK_GATE(frddr_c, 11);
92static AXG_PCLK_GATE(toddr_a, 12); 92static AUD_PCLK_GATE(toddr_a, 12);
93static AXG_PCLK_GATE(toddr_b, 13); 93static AUD_PCLK_GATE(toddr_b, 13);
94static AXG_PCLK_GATE(toddr_c, 14); 94static AUD_PCLK_GATE(toddr_c, 14);
95static AXG_PCLK_GATE(loopback, 15); 95static AUD_PCLK_GATE(loopback, 15);
96static AXG_PCLK_GATE(spdifin, 16); 96static AUD_PCLK_GATE(spdifin, 16);
97static AXG_PCLK_GATE(spdifout, 17); 97static AUD_PCLK_GATE(spdifout, 17);
98static AXG_PCLK_GATE(resample, 18); 98static AUD_PCLK_GATE(resample, 18);
99static AXG_PCLK_GATE(power_detect, 19); 99static AUD_PCLK_GATE(power_detect, 19);
100static AUD_PCLK_GATE(spdifout_b, 21);
100 101
101/* Audio Master Clocks */ 102/* Audio Master Clocks */
102static const char * const mst_mux_parent_names[] = { 103static const char * const mst_mux_parent_names[] = {
103 "axg_mst_in0", "axg_mst_in1", "axg_mst_in2", "axg_mst_in3", 104 "aud_mst_in0", "aud_mst_in1", "aud_mst_in2", "aud_mst_in3",
104 "axg_mst_in4", "axg_mst_in5", "axg_mst_in6", "axg_mst_in7", 105 "aud_mst_in4", "aud_mst_in5", "aud_mst_in6", "aud_mst_in7",
105}; 106};
106 107
107#define AXG_MST_MUX(_name, _reg, _flag) \ 108#define AUD_MST_MUX(_name, _reg, _flag) \
108 AXG_AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \ 109 AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \
109 mst_mux_parent_names, CLK_SET_RATE_PARENT) 110 mst_mux_parent_names, CLK_SET_RATE_PARENT)
110 111
111#define AXG_MST_MCLK_MUX(_name, _reg) \ 112#define AUD_MST_MCLK_MUX(_name, _reg) \
112 AXG_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST) 113 AUD_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST)
113 114
114#define AXG_MST_SYS_MUX(_name, _reg) \ 115#define AUD_MST_SYS_MUX(_name, _reg) \
115 AXG_MST_MUX(_name, _reg, 0) 116 AUD_MST_MUX(_name, _reg, 0)
116 117
117static AXG_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL); 118static AUD_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL);
118static AXG_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL); 119static AUD_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL);
119static AXG_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL); 120static AUD_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL);
120static AXG_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL); 121static AUD_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL);
121static AXG_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL); 122static AUD_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL);
122static AXG_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL); 123static AUD_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL);
123static AXG_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); 124static AUD_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL);
124static AXG_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); 125static AUD_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0);
125static AXG_MST_SYS_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); 126static AUD_MST_SYS_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
126static AXG_MST_SYS_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); 127static AUD_MST_SYS_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1);
127 128static AUD_MST_MCLK_MUX(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
128#define AXG_MST_DIV(_name, _reg, _flag) \ 129
129 AXG_AUD_DIV(_name##_div, _reg, 0, 16, _flag, \ 130#define AUD_MST_DIV(_name, _reg, _flag) \
130 "axg_"#_name"_sel", CLK_SET_RATE_PARENT) \ 131 AUD_DIV(_name##_div, _reg, 0, 16, _flag, \
131 132 "aud_"#_name"_sel", CLK_SET_RATE_PARENT) \
132#define AXG_MST_MCLK_DIV(_name, _reg) \ 133
133 AXG_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST) 134#define AUD_MST_MCLK_DIV(_name, _reg) \
134 135 AUD_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST)
135#define AXG_MST_SYS_DIV(_name, _reg) \ 136
136 AXG_MST_DIV(_name, _reg, 0) 137#define AUD_MST_SYS_DIV(_name, _reg) \
137 138 AUD_MST_DIV(_name, _reg, 0)
138static AXG_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL); 139
139static AXG_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL); 140static AUD_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL);
140static AXG_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL); 141static AUD_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL);
141static AXG_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL); 142static AUD_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL);
142static AXG_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL); 143static AUD_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL);
143static AXG_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL); 144static AUD_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL);
144static AXG_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); 145static AUD_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL);
145static AXG_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); 146static AUD_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL);
146static AXG_MST_SYS_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); 147static AUD_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0);
147static AXG_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); 148static AUD_MST_SYS_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
148 149static AUD_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1);
149#define AXG_MST_MCLK_GATE(_name, _reg) \ 150static AUD_MST_MCLK_DIV(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
150 AXG_AUD_GATE(_name, _reg, 31, "axg_"#_name"_div", \ 151
151 CLK_SET_RATE_PARENT) 152#define AUD_MST_MCLK_GATE(_name, _reg) \
152 153 AUD_GATE(_name, _reg, 31, "aud_"#_name"_div", \
153static AXG_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); 154 CLK_SET_RATE_PARENT)
154static AXG_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL); 155
155static AXG_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL); 156static AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL);
156static AXG_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL); 157static AUD_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL);
157static AXG_MST_MCLK_GATE(mst_e_mclk, AUDIO_MCLK_E_CTRL); 158static AUD_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL);
158static AXG_MST_MCLK_GATE(mst_f_mclk, AUDIO_MCLK_F_CTRL); 159static AUD_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL);
159static AXG_MST_MCLK_GATE(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); 160static AUD_MST_MCLK_GATE(mst_e_mclk, AUDIO_MCLK_E_CTRL);
160static AXG_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); 161static AUD_MST_MCLK_GATE(mst_f_mclk, AUDIO_MCLK_F_CTRL);
161static AXG_MST_MCLK_GATE(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); 162static AUD_MST_MCLK_GATE(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL);
162static AXG_MST_MCLK_GATE(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); 163static AUD_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
164static AUD_MST_MCLK_GATE(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0);
165static AUD_MST_MCLK_GATE(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1);
166static AUD_MST_MCLK_GATE(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
163 167
164/* Sample Clocks */ 168/* Sample Clocks */
165#define AXG_MST_SCLK_PRE_EN(_name, _reg) \ 169#define AUD_MST_SCLK_PRE_EN(_name, _reg) \
166 AXG_AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31, \ 170 AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31, \
167 "axg_mst_"#_name"_mclk", 0) 171 "aud_mst_"#_name"_mclk", 0)
168 172
169static AXG_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0); 173static AUD_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0);
170static AXG_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0); 174static AUD_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0);
171static AXG_MST_SCLK_PRE_EN(c, AUDIO_MST_C_SCLK_CTRL0); 175static AUD_MST_SCLK_PRE_EN(c, AUDIO_MST_C_SCLK_CTRL0);
172static AXG_MST_SCLK_PRE_EN(d, AUDIO_MST_D_SCLK_CTRL0); 176static AUD_MST_SCLK_PRE_EN(d, AUDIO_MST_D_SCLK_CTRL0);
173static AXG_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0); 177static AUD_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0);
174static AXG_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0); 178static AUD_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0);
175 179
176#define AXG_AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width, \ 180#define AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width, \
177 _hi_shift, _hi_width, _pname, _iflags) \ 181 _hi_shift, _hi_width, _pname, _iflags) \
178struct clk_regmap axg_##_name = { \ 182struct clk_regmap aud_##_name = { \
179 .data = &(struct meson_sclk_div_data) { \ 183 .data = &(struct meson_sclk_div_data) { \
180 .div = { \ 184 .div = { \
181 .reg_off = (_reg), \ 185 .reg_off = (_reg), \
@@ -189,7 +193,7 @@ struct clk_regmap axg_##_name = { \
189 }, \ 193 }, \
190 }, \ 194 }, \
191 .hw.init = &(struct clk_init_data) { \ 195 .hw.init = &(struct clk_init_data) { \
192 .name = "axg_"#_name, \ 196 .name = "aud_"#_name, \
193 .ops = &meson_sclk_div_ops, \ 197 .ops = &meson_sclk_div_ops, \
194 .parent_names = (const char *[]) { _pname }, \ 198 .parent_names = (const char *[]) { _pname }, \
195 .num_parents = 1, \ 199 .num_parents = 1, \
@@ -197,32 +201,32 @@ struct clk_regmap axg_##_name = { \
197 }, \ 201 }, \
198} 202}
199 203
200#define AXG_MST_SCLK_DIV(_name, _reg) \ 204#define AUD_MST_SCLK_DIV(_name, _reg) \
201 AXG_AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0, \ 205 AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0, \
202 "axg_mst_"#_name"_sclk_pre_en", \ 206 "aud_mst_"#_name"_sclk_pre_en", \
203 CLK_SET_RATE_PARENT) 207 CLK_SET_RATE_PARENT)
204 208
205static AXG_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); 209static AUD_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0);
206static AXG_MST_SCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); 210static AUD_MST_SCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0);
207static AXG_MST_SCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); 211static AUD_MST_SCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0);
208static AXG_MST_SCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); 212static AUD_MST_SCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0);
209static AXG_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); 213static AUD_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0);
210static AXG_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); 214static AUD_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0);
211 215
212#define AXG_MST_SCLK_POST_EN(_name, _reg) \ 216#define AUD_MST_SCLK_POST_EN(_name, _reg) \
213 AXG_AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \ 217 AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \
214 "axg_mst_"#_name"_sclk_div", CLK_SET_RATE_PARENT) 218 "aud_mst_"#_name"_sclk_div", CLK_SET_RATE_PARENT)
215 219
216static AXG_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0); 220static AUD_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0);
217static AXG_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0); 221static AUD_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0);
218static AXG_MST_SCLK_POST_EN(c, AUDIO_MST_C_SCLK_CTRL0); 222static AUD_MST_SCLK_POST_EN(c, AUDIO_MST_C_SCLK_CTRL0);
219static AXG_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0); 223static AUD_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0);
220static AXG_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0); 224static AUD_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0);
221static AXG_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0); 225static AUD_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0);
222 226
223#define AXG_AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \ 227#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \
224 _pname, _iflags) \ 228 _pname, _iflags) \
225struct clk_regmap axg_##_name = { \ 229struct clk_regmap aud_##_name = { \
226 .data = &(struct meson_clk_triphase_data) { \ 230 .data = &(struct meson_clk_triphase_data) { \
227 .ph0 = { \ 231 .ph0 = { \
228 .reg_off = (_reg), \ 232 .reg_off = (_reg), \
@@ -241,7 +245,7 @@ struct clk_regmap axg_##_name = { \
241 }, \ 245 }, \
242 }, \ 246 }, \
243 .hw.init = &(struct clk_init_data) { \ 247 .hw.init = &(struct clk_init_data) { \
244 .name = "axg_"#_name, \ 248 .name = "aud_"#_name, \
245 .ops = &meson_clk_triphase_ops, \ 249 .ops = &meson_clk_triphase_ops, \
246 .parent_names = (const char *[]) { _pname }, \ 250 .parent_names = (const char *[]) { _pname }, \
247 .num_parents = 1, \ 251 .num_parents = 1, \
@@ -249,87 +253,87 @@ struct clk_regmap axg_##_name = { \
249 }, \ 253 }, \
250} 254}
251 255
252#define AXG_MST_SCLK(_name, _reg) \ 256#define AUD_MST_SCLK(_name, _reg) \
253 AXG_AUD_TRIPHASE(mst_##_name##_sclk, _reg, 1, 0, 2, 4, \ 257 AUD_TRIPHASE(mst_##_name##_sclk, _reg, 1, 0, 2, 4, \
254 "axg_mst_"#_name"_sclk_post_en", CLK_SET_RATE_PARENT) 258 "aud_mst_"#_name"_sclk_post_en", CLK_SET_RATE_PARENT)
255 259
256static AXG_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1); 260static AUD_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1);
257static AXG_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1); 261static AUD_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1);
258static AXG_MST_SCLK(c, AUDIO_MST_C_SCLK_CTRL1); 262static AUD_MST_SCLK(c, AUDIO_MST_C_SCLK_CTRL1);
259static AXG_MST_SCLK(d, AUDIO_MST_D_SCLK_CTRL1); 263static AUD_MST_SCLK(d, AUDIO_MST_D_SCLK_CTRL1);
260static AXG_MST_SCLK(e, AUDIO_MST_E_SCLK_CTRL1); 264static AUD_MST_SCLK(e, AUDIO_MST_E_SCLK_CTRL1);
261static AXG_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1); 265static AUD_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1);
262 266
263#define AXG_MST_LRCLK_DIV(_name, _reg) \ 267#define AUD_MST_LRCLK_DIV(_name, _reg) \
264 AXG_AUD_SCLK_DIV(mst_##_name##_lrclk_div, _reg, 0, 10, 10, 10, \ 268 AUD_SCLK_DIV(mst_##_name##_lrclk_div, _reg, 0, 10, 10, 10, \
265 "axg_mst_"#_name"_sclk_post_en", 0) \ 269 "aud_mst_"#_name"_sclk_post_en", 0) \
266 270
267static AXG_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); 271static AUD_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0);
268static AXG_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); 272static AUD_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0);
269static AXG_MST_LRCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); 273static AUD_MST_LRCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0);
270static AXG_MST_LRCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); 274static AUD_MST_LRCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0);
271static AXG_MST_LRCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); 275static AUD_MST_LRCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0);
272static AXG_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); 276static AUD_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0);
273 277
274#define AXG_MST_LRCLK(_name, _reg) \ 278#define AUD_MST_LRCLK(_name, _reg) \
275 AXG_AUD_TRIPHASE(mst_##_name##_lrclk, _reg, 1, 1, 3, 5, \ 279 AUD_TRIPHASE(mst_##_name##_lrclk, _reg, 1, 1, 3, 5, \
276 "axg_mst_"#_name"_lrclk_div", CLK_SET_RATE_PARENT) 280 "aud_mst_"#_name"_lrclk_div", CLK_SET_RATE_PARENT)
277 281
278static AXG_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1); 282static AUD_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1);
279static AXG_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1); 283static AUD_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1);
280static AXG_MST_LRCLK(c, AUDIO_MST_C_SCLK_CTRL1); 284static AUD_MST_LRCLK(c, AUDIO_MST_C_SCLK_CTRL1);
281static AXG_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1); 285static AUD_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1);
282static AXG_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1); 286static AUD_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1);
283static AXG_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1); 287static AUD_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1);
284 288
285static const char * const tdm_sclk_parent_names[] = { 289static const char * const tdm_sclk_parent_names[] = {
286 "axg_mst_a_sclk", "axg_mst_b_sclk", "axg_mst_c_sclk", 290 "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk",
287 "axg_mst_d_sclk", "axg_mst_e_sclk", "axg_mst_f_sclk", 291 "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk",
288 "axg_slv_sclk0", "axg_slv_sclk1", "axg_slv_sclk2", 292 "aud_slv_sclk0", "aud_slv_sclk1", "aud_slv_sclk2",
289 "axg_slv_sclk3", "axg_slv_sclk4", "axg_slv_sclk5", 293 "aud_slv_sclk3", "aud_slv_sclk4", "aud_slv_sclk5",
290 "axg_slv_sclk6", "axg_slv_sclk7", "axg_slv_sclk8", 294 "aud_slv_sclk6", "aud_slv_sclk7", "aud_slv_sclk8",
291 "axg_slv_sclk9" 295 "aud_slv_sclk9"
292}; 296};
293 297
294#define AXG_TDM_SCLK_MUX(_name, _reg) \ 298#define AUD_TDM_SCLK_MUX(_name, _reg) \
295 AXG_AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24, \ 299 AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24, \
296 CLK_MUX_ROUND_CLOSEST, \ 300 CLK_MUX_ROUND_CLOSEST, \
297 tdm_sclk_parent_names, 0) 301 tdm_sclk_parent_names, 0)
298 302
299static AXG_TDM_SCLK_MUX(in_a, AUDIO_CLK_TDMIN_A_CTRL); 303static AUD_TDM_SCLK_MUX(in_a, AUDIO_CLK_TDMIN_A_CTRL);
300static AXG_TDM_SCLK_MUX(in_b, AUDIO_CLK_TDMIN_B_CTRL); 304static AUD_TDM_SCLK_MUX(in_b, AUDIO_CLK_TDMIN_B_CTRL);
301static AXG_TDM_SCLK_MUX(in_c, AUDIO_CLK_TDMIN_C_CTRL); 305static AUD_TDM_SCLK_MUX(in_c, AUDIO_CLK_TDMIN_C_CTRL);
302static AXG_TDM_SCLK_MUX(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); 306static AUD_TDM_SCLK_MUX(in_lb, AUDIO_CLK_TDMIN_LB_CTRL);
303static AXG_TDM_SCLK_MUX(out_a, AUDIO_CLK_TDMOUT_A_CTRL); 307static AUD_TDM_SCLK_MUX(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
304static AXG_TDM_SCLK_MUX(out_b, AUDIO_CLK_TDMOUT_B_CTRL); 308static AUD_TDM_SCLK_MUX(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
305static AXG_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL); 309static AUD_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
306 310
307#define AXG_TDM_SCLK_PRE_EN(_name, _reg) \ 311#define AUD_TDM_SCLK_PRE_EN(_name, _reg) \
308 AXG_AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31, \ 312 AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31, \
309 "axg_tdm"#_name"_sclk_sel", CLK_SET_RATE_PARENT) 313 "aud_tdm"#_name"_sclk_sel", CLK_SET_RATE_PARENT)
310 314
311static AXG_TDM_SCLK_PRE_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); 315static AUD_TDM_SCLK_PRE_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL);
312static AXG_TDM_SCLK_PRE_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); 316static AUD_TDM_SCLK_PRE_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL);
313static AXG_TDM_SCLK_PRE_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); 317static AUD_TDM_SCLK_PRE_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL);
314static AXG_TDM_SCLK_PRE_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); 318static AUD_TDM_SCLK_PRE_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL);
315static AXG_TDM_SCLK_PRE_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); 319static AUD_TDM_SCLK_PRE_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
316static AXG_TDM_SCLK_PRE_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); 320static AUD_TDM_SCLK_PRE_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
317static AXG_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); 321static AUD_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
318 322
319#define AXG_TDM_SCLK_POST_EN(_name, _reg) \ 323#define AUD_TDM_SCLK_POST_EN(_name, _reg) \
320 AXG_AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30, \ 324 AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30, \
321 "axg_tdm"#_name"_sclk_pre_en", CLK_SET_RATE_PARENT) 325 "aud_tdm"#_name"_sclk_pre_en", CLK_SET_RATE_PARENT)
322 326
323static AXG_TDM_SCLK_POST_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); 327static AUD_TDM_SCLK_POST_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL);
324static AXG_TDM_SCLK_POST_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); 328static AUD_TDM_SCLK_POST_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL);
325static AXG_TDM_SCLK_POST_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); 329static AUD_TDM_SCLK_POST_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL);
326static AXG_TDM_SCLK_POST_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); 330static AUD_TDM_SCLK_POST_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL);
327static AXG_TDM_SCLK_POST_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); 331static AUD_TDM_SCLK_POST_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
328static AXG_TDM_SCLK_POST_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); 332static AUD_TDM_SCLK_POST_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
329static AXG_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); 333static AUD_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
330 334
331#define AXG_TDM_SCLK(_name, _reg) \ 335#define AUD_TDM_SCLK(_name, _reg) \
332 struct clk_regmap axg_tdm##_name##_sclk = { \ 336 struct clk_regmap aud_tdm##_name##_sclk = { \
333 .data = &(struct meson_clk_phase_data) { \ 337 .data = &(struct meson_clk_phase_data) { \
334 .ph = { \ 338 .ph = { \
335 .reg_off = (_reg), \ 339 .reg_off = (_reg), \
@@ -338,44 +342,83 @@ static AXG_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
338 }, \ 342 }, \
339 }, \ 343 }, \
340 .hw.init = &(struct clk_init_data) { \ 344 .hw.init = &(struct clk_init_data) { \
341 .name = "axg_tdm"#_name"_sclk", \ 345 .name = "aud_tdm"#_name"_sclk", \
342 .ops = &meson_clk_phase_ops, \ 346 .ops = &meson_clk_phase_ops, \
343 .parent_names = (const char *[]) \ 347 .parent_names = (const char *[]) \
344 { "axg_tdm"#_name"_sclk_post_en" }, \ 348 { "aud_tdm"#_name"_sclk_post_en" }, \
345 .num_parents = 1, \ 349 .num_parents = 1, \
346 .flags = CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT, \ 350 .flags = CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT, \
347 }, \ 351 }, \
348} 352}
349 353
350static AXG_TDM_SCLK(in_a, AUDIO_CLK_TDMIN_A_CTRL); 354static AUD_TDM_SCLK(in_a, AUDIO_CLK_TDMIN_A_CTRL);
351static AXG_TDM_SCLK(in_b, AUDIO_CLK_TDMIN_B_CTRL); 355static AUD_TDM_SCLK(in_b, AUDIO_CLK_TDMIN_B_CTRL);
352static AXG_TDM_SCLK(in_c, AUDIO_CLK_TDMIN_C_CTRL); 356static AUD_TDM_SCLK(in_c, AUDIO_CLK_TDMIN_C_CTRL);
353static AXG_TDM_SCLK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); 357static AUD_TDM_SCLK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL);
354static AXG_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); 358static AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
355static AXG_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); 359static AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
356static AXG_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); 360static AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
357 361
358static const char * const tdm_lrclk_parent_names[] = { 362static const char * const tdm_lrclk_parent_names[] = {
359 "axg_mst_a_lrclk", "axg_mst_b_lrclk", "axg_mst_c_lrclk", 363 "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk",
360 "axg_mst_d_lrclk", "axg_mst_e_lrclk", "axg_mst_f_lrclk", 364 "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk",
361 "axg_slv_lrclk0", "axg_slv_lrclk1", "axg_slv_lrclk2", 365 "aud_slv_lrclk0", "aud_slv_lrclk1", "aud_slv_lrclk2",
362 "axg_slv_lrclk3", "axg_slv_lrclk4", "axg_slv_lrclk5", 366 "aud_slv_lrclk3", "aud_slv_lrclk4", "aud_slv_lrclk5",
363 "axg_slv_lrclk6", "axg_slv_lrclk7", "axg_slv_lrclk8", 367 "aud_slv_lrclk6", "aud_slv_lrclk7", "aud_slv_lrclk8",
364 "axg_slv_lrclk9" 368 "aud_slv_lrclk9"
365}; 369};
366 370
367#define AXG_TDM_LRLCK(_name, _reg) \ 371#define AUD_TDM_LRLCK(_name, _reg) \
368 AXG_AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \ 372 AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \
369 CLK_MUX_ROUND_CLOSEST, \ 373 CLK_MUX_ROUND_CLOSEST, \
370 tdm_lrclk_parent_names, 0) 374 tdm_lrclk_parent_names, 0)
375
376static AUD_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL);
377static AUD_TDM_LRLCK(in_b, AUDIO_CLK_TDMIN_B_CTRL);
378static AUD_TDM_LRLCK(in_c, AUDIO_CLK_TDMIN_C_CTRL);
379static AUD_TDM_LRLCK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL);
380static AUD_TDM_LRLCK(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
381static AUD_TDM_LRLCK(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
382static AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
383
384/* G12a Pad control */
385#define AUD_TDM_PAD_CTRL(_name, _reg, _shift, _parents) \
386 AUD_MUX(tdm_##_name, _reg, 0x7, _shift, 0, _parents, \
387 CLK_SET_RATE_NO_REPARENT)
388
389static const char * const mclk_pad_ctrl_parent_names[] = {
390 "aud_mst_a_mclk", "aud_mst_b_mclk", "aud_mst_c_mclk",
391 "aud_mst_d_mclk", "aud_mst_e_mclk", "aud_mst_f_mclk",
392};
393
394static AUD_TDM_PAD_CTRL(mclk_pad_0, AUDIO_MST_PAD_CTRL0, 0,
395 mclk_pad_ctrl_parent_names);
396static AUD_TDM_PAD_CTRL(mclk_pad_1, AUDIO_MST_PAD_CTRL0, 4,
397 mclk_pad_ctrl_parent_names);
398
399static const char * const lrclk_pad_ctrl_parent_names[] = {
400 "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk",
401 "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk",
402};
371 403
372static AXG_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL); 404static AUD_TDM_PAD_CTRL(lrclk_pad_0, AUDIO_MST_PAD_CTRL1, 16,
373static AXG_TDM_LRLCK(in_b, AUDIO_CLK_TDMIN_B_CTRL); 405 lrclk_pad_ctrl_parent_names);
374static AXG_TDM_LRLCK(in_c, AUDIO_CLK_TDMIN_C_CTRL); 406static AUD_TDM_PAD_CTRL(lrclk_pad_1, AUDIO_MST_PAD_CTRL1, 20,
375static AXG_TDM_LRLCK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); 407 lrclk_pad_ctrl_parent_names);
376static AXG_TDM_LRLCK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); 408static AUD_TDM_PAD_CTRL(lrclk_pad_2, AUDIO_MST_PAD_CTRL1, 24,
377static AXG_TDM_LRLCK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); 409 lrclk_pad_ctrl_parent_names);
378static AXG_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); 410
411static const char * const sclk_pad_ctrl_parent_names[] = {
412 "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk",
413 "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk",
414};
415
416static AUD_TDM_PAD_CTRL(sclk_pad_0, AUDIO_MST_PAD_CTRL1, 0,
417 sclk_pad_ctrl_parent_names);
418static AUD_TDM_PAD_CTRL(sclk_pad_1, AUDIO_MST_PAD_CTRL1, 4,
419 sclk_pad_ctrl_parent_names);
420static AUD_TDM_PAD_CTRL(sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8,
421 sclk_pad_ctrl_parent_names);
379 422
380/* 423/*
381 * Array of all clocks provided by this provider 424 * Array of all clocks provided by this provider
@@ -383,255 +426,416 @@ static AXG_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
383 */ 426 */
384static struct clk_hw_onecell_data axg_audio_hw_onecell_data = { 427static struct clk_hw_onecell_data axg_audio_hw_onecell_data = {
385 .hws = { 428 .hws = {
386 [AUD_CLKID_DDR_ARB] = &axg_ddr_arb.hw, 429 [AUD_CLKID_DDR_ARB] = &aud_ddr_arb.hw,
387 [AUD_CLKID_PDM] = &axg_pdm.hw, 430 [AUD_CLKID_PDM] = &aud_pdm.hw,
388 [AUD_CLKID_TDMIN_A] = &axg_tdmin_a.hw, 431 [AUD_CLKID_TDMIN_A] = &aud_tdmin_a.hw,
389 [AUD_CLKID_TDMIN_B] = &axg_tdmin_b.hw, 432 [AUD_CLKID_TDMIN_B] = &aud_tdmin_b.hw,
390 [AUD_CLKID_TDMIN_C] = &axg_tdmin_c.hw, 433 [AUD_CLKID_TDMIN_C] = &aud_tdmin_c.hw,
391 [AUD_CLKID_TDMIN_LB] = &axg_tdmin_lb.hw, 434 [AUD_CLKID_TDMIN_LB] = &aud_tdmin_lb.hw,
392 [AUD_CLKID_TDMOUT_A] = &axg_tdmout_a.hw, 435 [AUD_CLKID_TDMOUT_A] = &aud_tdmout_a.hw,
393 [AUD_CLKID_TDMOUT_B] = &axg_tdmout_b.hw, 436 [AUD_CLKID_TDMOUT_B] = &aud_tdmout_b.hw,
394 [AUD_CLKID_TDMOUT_C] = &axg_tdmout_c.hw, 437 [AUD_CLKID_TDMOUT_C] = &aud_tdmout_c.hw,
395 [AUD_CLKID_FRDDR_A] = &axg_frddr_a.hw, 438 [AUD_CLKID_FRDDR_A] = &aud_frddr_a.hw,
396 [AUD_CLKID_FRDDR_B] = &axg_frddr_b.hw, 439 [AUD_CLKID_FRDDR_B] = &aud_frddr_b.hw,
397 [AUD_CLKID_FRDDR_C] = &axg_frddr_c.hw, 440 [AUD_CLKID_FRDDR_C] = &aud_frddr_c.hw,
398 [AUD_CLKID_TODDR_A] = &axg_toddr_a.hw, 441 [AUD_CLKID_TODDR_A] = &aud_toddr_a.hw,
399 [AUD_CLKID_TODDR_B] = &axg_toddr_b.hw, 442 [AUD_CLKID_TODDR_B] = &aud_toddr_b.hw,
400 [AUD_CLKID_TODDR_C] = &axg_toddr_c.hw, 443 [AUD_CLKID_TODDR_C] = &aud_toddr_c.hw,
401 [AUD_CLKID_LOOPBACK] = &axg_loopback.hw, 444 [AUD_CLKID_LOOPBACK] = &aud_loopback.hw,
402 [AUD_CLKID_SPDIFIN] = &axg_spdifin.hw, 445 [AUD_CLKID_SPDIFIN] = &aud_spdifin.hw,
403 [AUD_CLKID_SPDIFOUT] = &axg_spdifout.hw, 446 [AUD_CLKID_SPDIFOUT] = &aud_spdifout.hw,
404 [AUD_CLKID_RESAMPLE] = &axg_resample.hw, 447 [AUD_CLKID_RESAMPLE] = &aud_resample.hw,
405 [AUD_CLKID_POWER_DETECT] = &axg_power_detect.hw, 448 [AUD_CLKID_POWER_DETECT] = &aud_power_detect.hw,
406 [AUD_CLKID_MST_A_MCLK_SEL] = &axg_mst_a_mclk_sel.hw, 449 [AUD_CLKID_MST_A_MCLK_SEL] = &aud_mst_a_mclk_sel.hw,
407 [AUD_CLKID_MST_B_MCLK_SEL] = &axg_mst_b_mclk_sel.hw, 450 [AUD_CLKID_MST_B_MCLK_SEL] = &aud_mst_b_mclk_sel.hw,
408 [AUD_CLKID_MST_C_MCLK_SEL] = &axg_mst_c_mclk_sel.hw, 451 [AUD_CLKID_MST_C_MCLK_SEL] = &aud_mst_c_mclk_sel.hw,
409 [AUD_CLKID_MST_D_MCLK_SEL] = &axg_mst_d_mclk_sel.hw, 452 [AUD_CLKID_MST_D_MCLK_SEL] = &aud_mst_d_mclk_sel.hw,
410 [AUD_CLKID_MST_E_MCLK_SEL] = &axg_mst_e_mclk_sel.hw, 453 [AUD_CLKID_MST_E_MCLK_SEL] = &aud_mst_e_mclk_sel.hw,
411 [AUD_CLKID_MST_F_MCLK_SEL] = &axg_mst_f_mclk_sel.hw, 454 [AUD_CLKID_MST_F_MCLK_SEL] = &aud_mst_f_mclk_sel.hw,
412 [AUD_CLKID_MST_A_MCLK_DIV] = &axg_mst_a_mclk_div.hw, 455 [AUD_CLKID_MST_A_MCLK_DIV] = &aud_mst_a_mclk_div.hw,
413 [AUD_CLKID_MST_B_MCLK_DIV] = &axg_mst_b_mclk_div.hw, 456 [AUD_CLKID_MST_B_MCLK_DIV] = &aud_mst_b_mclk_div.hw,
414 [AUD_CLKID_MST_C_MCLK_DIV] = &axg_mst_c_mclk_div.hw, 457 [AUD_CLKID_MST_C_MCLK_DIV] = &aud_mst_c_mclk_div.hw,
415 [AUD_CLKID_MST_D_MCLK_DIV] = &axg_mst_d_mclk_div.hw, 458 [AUD_CLKID_MST_D_MCLK_DIV] = &aud_mst_d_mclk_div.hw,
416 [AUD_CLKID_MST_E_MCLK_DIV] = &axg_mst_e_mclk_div.hw, 459 [AUD_CLKID_MST_E_MCLK_DIV] = &aud_mst_e_mclk_div.hw,
417 [AUD_CLKID_MST_F_MCLK_DIV] = &axg_mst_f_mclk_div.hw, 460 [AUD_CLKID_MST_F_MCLK_DIV] = &aud_mst_f_mclk_div.hw,
418 [AUD_CLKID_MST_A_MCLK] = &axg_mst_a_mclk.hw, 461 [AUD_CLKID_MST_A_MCLK] = &aud_mst_a_mclk.hw,
419 [AUD_CLKID_MST_B_MCLK] = &axg_mst_b_mclk.hw, 462 [AUD_CLKID_MST_B_MCLK] = &aud_mst_b_mclk.hw,
420 [AUD_CLKID_MST_C_MCLK] = &axg_mst_c_mclk.hw, 463 [AUD_CLKID_MST_C_MCLK] = &aud_mst_c_mclk.hw,
421 [AUD_CLKID_MST_D_MCLK] = &axg_mst_d_mclk.hw, 464 [AUD_CLKID_MST_D_MCLK] = &aud_mst_d_mclk.hw,
422 [AUD_CLKID_MST_E_MCLK] = &axg_mst_e_mclk.hw, 465 [AUD_CLKID_MST_E_MCLK] = &aud_mst_e_mclk.hw,
423 [AUD_CLKID_MST_F_MCLK] = &axg_mst_f_mclk.hw, 466 [AUD_CLKID_MST_F_MCLK] = &aud_mst_f_mclk.hw,
424 [AUD_CLKID_SPDIFOUT_CLK_SEL] = &axg_spdifout_clk_sel.hw, 467 [AUD_CLKID_SPDIFOUT_CLK_SEL] = &aud_spdifout_clk_sel.hw,
425 [AUD_CLKID_SPDIFOUT_CLK_DIV] = &axg_spdifout_clk_div.hw, 468 [AUD_CLKID_SPDIFOUT_CLK_DIV] = &aud_spdifout_clk_div.hw,
426 [AUD_CLKID_SPDIFOUT_CLK] = &axg_spdifout_clk.hw, 469 [AUD_CLKID_SPDIFOUT_CLK] = &aud_spdifout_clk.hw,
427 [AUD_CLKID_SPDIFIN_CLK_SEL] = &axg_spdifin_clk_sel.hw, 470 [AUD_CLKID_SPDIFIN_CLK_SEL] = &aud_spdifin_clk_sel.hw,
428 [AUD_CLKID_SPDIFIN_CLK_DIV] = &axg_spdifin_clk_div.hw, 471 [AUD_CLKID_SPDIFIN_CLK_DIV] = &aud_spdifin_clk_div.hw,
429 [AUD_CLKID_SPDIFIN_CLK] = &axg_spdifin_clk.hw, 472 [AUD_CLKID_SPDIFIN_CLK] = &aud_spdifin_clk.hw,
430 [AUD_CLKID_PDM_DCLK_SEL] = &axg_pdm_dclk_sel.hw, 473 [AUD_CLKID_PDM_DCLK_SEL] = &aud_pdm_dclk_sel.hw,
431 [AUD_CLKID_PDM_DCLK_DIV] = &axg_pdm_dclk_div.hw, 474 [AUD_CLKID_PDM_DCLK_DIV] = &aud_pdm_dclk_div.hw,
432 [AUD_CLKID_PDM_DCLK] = &axg_pdm_dclk.hw, 475 [AUD_CLKID_PDM_DCLK] = &aud_pdm_dclk.hw,
433 [AUD_CLKID_PDM_SYSCLK_SEL] = &axg_pdm_sysclk_sel.hw, 476 [AUD_CLKID_PDM_SYSCLK_SEL] = &aud_pdm_sysclk_sel.hw,
434 [AUD_CLKID_PDM_SYSCLK_DIV] = &axg_pdm_sysclk_div.hw, 477 [AUD_CLKID_PDM_SYSCLK_DIV] = &aud_pdm_sysclk_div.hw,
435 [AUD_CLKID_PDM_SYSCLK] = &axg_pdm_sysclk.hw, 478 [AUD_CLKID_PDM_SYSCLK] = &aud_pdm_sysclk.hw,
436 [AUD_CLKID_MST_A_SCLK_PRE_EN] = &axg_mst_a_sclk_pre_en.hw, 479 [AUD_CLKID_MST_A_SCLK_PRE_EN] = &aud_mst_a_sclk_pre_en.hw,
437 [AUD_CLKID_MST_B_SCLK_PRE_EN] = &axg_mst_b_sclk_pre_en.hw, 480 [AUD_CLKID_MST_B_SCLK_PRE_EN] = &aud_mst_b_sclk_pre_en.hw,
438 [AUD_CLKID_MST_C_SCLK_PRE_EN] = &axg_mst_c_sclk_pre_en.hw, 481 [AUD_CLKID_MST_C_SCLK_PRE_EN] = &aud_mst_c_sclk_pre_en.hw,
439 [AUD_CLKID_MST_D_SCLK_PRE_EN] = &axg_mst_d_sclk_pre_en.hw, 482 [AUD_CLKID_MST_D_SCLK_PRE_EN] = &aud_mst_d_sclk_pre_en.hw,
440 [AUD_CLKID_MST_E_SCLK_PRE_EN] = &axg_mst_e_sclk_pre_en.hw, 483 [AUD_CLKID_MST_E_SCLK_PRE_EN] = &aud_mst_e_sclk_pre_en.hw,
441 [AUD_CLKID_MST_F_SCLK_PRE_EN] = &axg_mst_f_sclk_pre_en.hw, 484 [AUD_CLKID_MST_F_SCLK_PRE_EN] = &aud_mst_f_sclk_pre_en.hw,
442 [AUD_CLKID_MST_A_SCLK_DIV] = &axg_mst_a_sclk_div.hw, 485 [AUD_CLKID_MST_A_SCLK_DIV] = &aud_mst_a_sclk_div.hw,
443 [AUD_CLKID_MST_B_SCLK_DIV] = &axg_mst_b_sclk_div.hw, 486 [AUD_CLKID_MST_B_SCLK_DIV] = &aud_mst_b_sclk_div.hw,
444 [AUD_CLKID_MST_C_SCLK_DIV] = &axg_mst_c_sclk_div.hw, 487 [AUD_CLKID_MST_C_SCLK_DIV] = &aud_mst_c_sclk_div.hw,
445 [AUD_CLKID_MST_D_SCLK_DIV] = &axg_mst_d_sclk_div.hw, 488 [AUD_CLKID_MST_D_SCLK_DIV] = &aud_mst_d_sclk_div.hw,
446 [AUD_CLKID_MST_E_SCLK_DIV] = &axg_mst_e_sclk_div.hw, 489 [AUD_CLKID_MST_E_SCLK_DIV] = &aud_mst_e_sclk_div.hw,
447 [AUD_CLKID_MST_F_SCLK_DIV] = &axg_mst_f_sclk_div.hw, 490 [AUD_CLKID_MST_F_SCLK_DIV] = &aud_mst_f_sclk_div.hw,
448 [AUD_CLKID_MST_A_SCLK_POST_EN] = &axg_mst_a_sclk_post_en.hw, 491 [AUD_CLKID_MST_A_SCLK_POST_EN] = &aud_mst_a_sclk_post_en.hw,
449 [AUD_CLKID_MST_B_SCLK_POST_EN] = &axg_mst_b_sclk_post_en.hw, 492 [AUD_CLKID_MST_B_SCLK_POST_EN] = &aud_mst_b_sclk_post_en.hw,
450 [AUD_CLKID_MST_C_SCLK_POST_EN] = &axg_mst_c_sclk_post_en.hw, 493 [AUD_CLKID_MST_C_SCLK_POST_EN] = &aud_mst_c_sclk_post_en.hw,
451 [AUD_CLKID_MST_D_SCLK_POST_EN] = &axg_mst_d_sclk_post_en.hw, 494 [AUD_CLKID_MST_D_SCLK_POST_EN] = &aud_mst_d_sclk_post_en.hw,
452 [AUD_CLKID_MST_E_SCLK_POST_EN] = &axg_mst_e_sclk_post_en.hw, 495 [AUD_CLKID_MST_E_SCLK_POST_EN] = &aud_mst_e_sclk_post_en.hw,
453 [AUD_CLKID_MST_F_SCLK_POST_EN] = &axg_mst_f_sclk_post_en.hw, 496 [AUD_CLKID_MST_F_SCLK_POST_EN] = &aud_mst_f_sclk_post_en.hw,
454 [AUD_CLKID_MST_A_SCLK] = &axg_mst_a_sclk.hw, 497 [AUD_CLKID_MST_A_SCLK] = &aud_mst_a_sclk.hw,
455 [AUD_CLKID_MST_B_SCLK] = &axg_mst_b_sclk.hw, 498 [AUD_CLKID_MST_B_SCLK] = &aud_mst_b_sclk.hw,
456 [AUD_CLKID_MST_C_SCLK] = &axg_mst_c_sclk.hw, 499 [AUD_CLKID_MST_C_SCLK] = &aud_mst_c_sclk.hw,
457 [AUD_CLKID_MST_D_SCLK] = &axg_mst_d_sclk.hw, 500 [AUD_CLKID_MST_D_SCLK] = &aud_mst_d_sclk.hw,
458 [AUD_CLKID_MST_E_SCLK] = &axg_mst_e_sclk.hw, 501 [AUD_CLKID_MST_E_SCLK] = &aud_mst_e_sclk.hw,
459 [AUD_CLKID_MST_F_SCLK] = &axg_mst_f_sclk.hw, 502 [AUD_CLKID_MST_F_SCLK] = &aud_mst_f_sclk.hw,
460 [AUD_CLKID_MST_A_LRCLK_DIV] = &axg_mst_a_lrclk_div.hw, 503 [AUD_CLKID_MST_A_LRCLK_DIV] = &aud_mst_a_lrclk_div.hw,
461 [AUD_CLKID_MST_B_LRCLK_DIV] = &axg_mst_b_lrclk_div.hw, 504 [AUD_CLKID_MST_B_LRCLK_DIV] = &aud_mst_b_lrclk_div.hw,
462 [AUD_CLKID_MST_C_LRCLK_DIV] = &axg_mst_c_lrclk_div.hw, 505 [AUD_CLKID_MST_C_LRCLK_DIV] = &aud_mst_c_lrclk_div.hw,
463 [AUD_CLKID_MST_D_LRCLK_DIV] = &axg_mst_d_lrclk_div.hw, 506 [AUD_CLKID_MST_D_LRCLK_DIV] = &aud_mst_d_lrclk_div.hw,
464 [AUD_CLKID_MST_E_LRCLK_DIV] = &axg_mst_e_lrclk_div.hw, 507 [AUD_CLKID_MST_E_LRCLK_DIV] = &aud_mst_e_lrclk_div.hw,
465 [AUD_CLKID_MST_F_LRCLK_DIV] = &axg_mst_f_lrclk_div.hw, 508 [AUD_CLKID_MST_F_LRCLK_DIV] = &aud_mst_f_lrclk_div.hw,
466 [AUD_CLKID_MST_A_LRCLK] = &axg_mst_a_lrclk.hw, 509 [AUD_CLKID_MST_A_LRCLK] = &aud_mst_a_lrclk.hw,
467 [AUD_CLKID_MST_B_LRCLK] = &axg_mst_b_lrclk.hw, 510 [AUD_CLKID_MST_B_LRCLK] = &aud_mst_b_lrclk.hw,
468 [AUD_CLKID_MST_C_LRCLK] = &axg_mst_c_lrclk.hw, 511 [AUD_CLKID_MST_C_LRCLK] = &aud_mst_c_lrclk.hw,
469 [AUD_CLKID_MST_D_LRCLK] = &axg_mst_d_lrclk.hw, 512 [AUD_CLKID_MST_D_LRCLK] = &aud_mst_d_lrclk.hw,
470 [AUD_CLKID_MST_E_LRCLK] = &axg_mst_e_lrclk.hw, 513 [AUD_CLKID_MST_E_LRCLK] = &aud_mst_e_lrclk.hw,
471 [AUD_CLKID_MST_F_LRCLK] = &axg_mst_f_lrclk.hw, 514 [AUD_CLKID_MST_F_LRCLK] = &aud_mst_f_lrclk.hw,
472 [AUD_CLKID_TDMIN_A_SCLK_SEL] = &axg_tdmin_a_sclk_sel.hw, 515 [AUD_CLKID_TDMIN_A_SCLK_SEL] = &aud_tdmin_a_sclk_sel.hw,
473 [AUD_CLKID_TDMIN_B_SCLK_SEL] = &axg_tdmin_b_sclk_sel.hw, 516 [AUD_CLKID_TDMIN_B_SCLK_SEL] = &aud_tdmin_b_sclk_sel.hw,
474 [AUD_CLKID_TDMIN_C_SCLK_SEL] = &axg_tdmin_c_sclk_sel.hw, 517 [AUD_CLKID_TDMIN_C_SCLK_SEL] = &aud_tdmin_c_sclk_sel.hw,
475 [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &axg_tdmin_lb_sclk_sel.hw, 518 [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &aud_tdmin_lb_sclk_sel.hw,
476 [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &axg_tdmout_a_sclk_sel.hw, 519 [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &aud_tdmout_a_sclk_sel.hw,
477 [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &axg_tdmout_b_sclk_sel.hw, 520 [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &aud_tdmout_b_sclk_sel.hw,
478 [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &axg_tdmout_c_sclk_sel.hw, 521 [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &aud_tdmout_c_sclk_sel.hw,
479 [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &axg_tdmin_a_sclk_pre_en.hw, 522 [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &aud_tdmin_a_sclk_pre_en.hw,
480 [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &axg_tdmin_b_sclk_pre_en.hw, 523 [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &aud_tdmin_b_sclk_pre_en.hw,
481 [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &axg_tdmin_c_sclk_pre_en.hw, 524 [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &aud_tdmin_c_sclk_pre_en.hw,
482 [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &axg_tdmin_lb_sclk_pre_en.hw, 525 [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &aud_tdmin_lb_sclk_pre_en.hw,
483 [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &axg_tdmout_a_sclk_pre_en.hw, 526 [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &aud_tdmout_a_sclk_pre_en.hw,
484 [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &axg_tdmout_b_sclk_pre_en.hw, 527 [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &aud_tdmout_b_sclk_pre_en.hw,
485 [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &axg_tdmout_c_sclk_pre_en.hw, 528 [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &aud_tdmout_c_sclk_pre_en.hw,
486 [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &axg_tdmin_a_sclk_post_en.hw, 529 [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &aud_tdmin_a_sclk_post_en.hw,
487 [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &axg_tdmin_b_sclk_post_en.hw, 530 [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &aud_tdmin_b_sclk_post_en.hw,
488 [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &axg_tdmin_c_sclk_post_en.hw, 531 [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &aud_tdmin_c_sclk_post_en.hw,
489 [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &axg_tdmin_lb_sclk_post_en.hw, 532 [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &aud_tdmin_lb_sclk_post_en.hw,
490 [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &axg_tdmout_a_sclk_post_en.hw, 533 [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &aud_tdmout_a_sclk_post_en.hw,
491 [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &axg_tdmout_b_sclk_post_en.hw, 534 [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &aud_tdmout_b_sclk_post_en.hw,
492 [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &axg_tdmout_c_sclk_post_en.hw, 535 [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &aud_tdmout_c_sclk_post_en.hw,
493 [AUD_CLKID_TDMIN_A_SCLK] = &axg_tdmin_a_sclk.hw, 536 [AUD_CLKID_TDMIN_A_SCLK] = &aud_tdmin_a_sclk.hw,
494 [AUD_CLKID_TDMIN_B_SCLK] = &axg_tdmin_b_sclk.hw, 537 [AUD_CLKID_TDMIN_B_SCLK] = &aud_tdmin_b_sclk.hw,
495 [AUD_CLKID_TDMIN_C_SCLK] = &axg_tdmin_c_sclk.hw, 538 [AUD_CLKID_TDMIN_C_SCLK] = &aud_tdmin_c_sclk.hw,
496 [AUD_CLKID_TDMIN_LB_SCLK] = &axg_tdmin_lb_sclk.hw, 539 [AUD_CLKID_TDMIN_LB_SCLK] = &aud_tdmin_lb_sclk.hw,
497 [AUD_CLKID_TDMOUT_A_SCLK] = &axg_tdmout_a_sclk.hw, 540 [AUD_CLKID_TDMOUT_A_SCLK] = &aud_tdmout_a_sclk.hw,
498 [AUD_CLKID_TDMOUT_B_SCLK] = &axg_tdmout_b_sclk.hw, 541 [AUD_CLKID_TDMOUT_B_SCLK] = &aud_tdmout_b_sclk.hw,
499 [AUD_CLKID_TDMOUT_C_SCLK] = &axg_tdmout_c_sclk.hw, 542 [AUD_CLKID_TDMOUT_C_SCLK] = &aud_tdmout_c_sclk.hw,
500 [AUD_CLKID_TDMIN_A_LRCLK] = &axg_tdmin_a_lrclk.hw, 543 [AUD_CLKID_TDMIN_A_LRCLK] = &aud_tdmin_a_lrclk.hw,
501 [AUD_CLKID_TDMIN_B_LRCLK] = &axg_tdmin_b_lrclk.hw, 544 [AUD_CLKID_TDMIN_B_LRCLK] = &aud_tdmin_b_lrclk.hw,
502 [AUD_CLKID_TDMIN_C_LRCLK] = &axg_tdmin_c_lrclk.hw, 545 [AUD_CLKID_TDMIN_C_LRCLK] = &aud_tdmin_c_lrclk.hw,
503 [AUD_CLKID_TDMIN_LB_LRCLK] = &axg_tdmin_lb_lrclk.hw, 546 [AUD_CLKID_TDMIN_LB_LRCLK] = &aud_tdmin_lb_lrclk.hw,
504 [AUD_CLKID_TDMOUT_A_LRCLK] = &axg_tdmout_a_lrclk.hw, 547 [AUD_CLKID_TDMOUT_A_LRCLK] = &aud_tdmout_a_lrclk.hw,
505 [AUD_CLKID_TDMOUT_B_LRCLK] = &axg_tdmout_b_lrclk.hw, 548 [AUD_CLKID_TDMOUT_B_LRCLK] = &aud_tdmout_b_lrclk.hw,
506 [AUD_CLKID_TDMOUT_C_LRCLK] = &axg_tdmout_c_lrclk.hw, 549 [AUD_CLKID_TDMOUT_C_LRCLK] = &aud_tdmout_c_lrclk.hw,
507 [NR_CLKS] = NULL, 550 [NR_CLKS] = NULL,
508 }, 551 },
509 .num = NR_CLKS, 552 .num = NR_CLKS,
510}; 553};
511 554
512/* Convenience table to populate regmap in .probe() */ 555/*
513static struct clk_regmap *const axg_audio_clk_regmaps[] = { 556 * Array of all G12A clocks provided by this provider
514 &axg_ddr_arb, 557 * The input clocks of the controller will be populated at runtime
515 &axg_pdm, 558 */
516 &axg_tdmin_a, 559static struct clk_hw_onecell_data g12a_audio_hw_onecell_data = {
517 &axg_tdmin_b, 560 .hws = {
518 &axg_tdmin_c, 561 [AUD_CLKID_DDR_ARB] = &aud_ddr_arb.hw,
519 &axg_tdmin_lb, 562 [AUD_CLKID_PDM] = &aud_pdm.hw,
520 &axg_tdmout_a, 563 [AUD_CLKID_TDMIN_A] = &aud_tdmin_a.hw,
521 &axg_tdmout_b, 564 [AUD_CLKID_TDMIN_B] = &aud_tdmin_b.hw,
522 &axg_tdmout_c, 565 [AUD_CLKID_TDMIN_C] = &aud_tdmin_c.hw,
523 &axg_frddr_a, 566 [AUD_CLKID_TDMIN_LB] = &aud_tdmin_lb.hw,
524 &axg_frddr_b, 567 [AUD_CLKID_TDMOUT_A] = &aud_tdmout_a.hw,
525 &axg_frddr_c, 568 [AUD_CLKID_TDMOUT_B] = &aud_tdmout_b.hw,
526 &axg_toddr_a, 569 [AUD_CLKID_TDMOUT_C] = &aud_tdmout_c.hw,
527 &axg_toddr_b, 570 [AUD_CLKID_FRDDR_A] = &aud_frddr_a.hw,
528 &axg_toddr_c, 571 [AUD_CLKID_FRDDR_B] = &aud_frddr_b.hw,
529 &axg_loopback, 572 [AUD_CLKID_FRDDR_C] = &aud_frddr_c.hw,
530 &axg_spdifin, 573 [AUD_CLKID_TODDR_A] = &aud_toddr_a.hw,
531 &axg_spdifout, 574 [AUD_CLKID_TODDR_B] = &aud_toddr_b.hw,
532 &axg_resample, 575 [AUD_CLKID_TODDR_C] = &aud_toddr_c.hw,
533 &axg_power_detect, 576 [AUD_CLKID_LOOPBACK] = &aud_loopback.hw,
534 &axg_mst_a_mclk_sel, 577 [AUD_CLKID_SPDIFIN] = &aud_spdifin.hw,
535 &axg_mst_b_mclk_sel, 578 [AUD_CLKID_SPDIFOUT] = &aud_spdifout.hw,
536 &axg_mst_c_mclk_sel, 579 [AUD_CLKID_RESAMPLE] = &aud_resample.hw,
537 &axg_mst_d_mclk_sel, 580 [AUD_CLKID_POWER_DETECT] = &aud_power_detect.hw,
538 &axg_mst_e_mclk_sel, 581 [AUD_CLKID_SPDIFOUT_B] = &aud_spdifout_b.hw,
539 &axg_mst_f_mclk_sel, 582 [AUD_CLKID_MST_A_MCLK_SEL] = &aud_mst_a_mclk_sel.hw,
540 &axg_mst_a_mclk_div, 583 [AUD_CLKID_MST_B_MCLK_SEL] = &aud_mst_b_mclk_sel.hw,
541 &axg_mst_b_mclk_div, 584 [AUD_CLKID_MST_C_MCLK_SEL] = &aud_mst_c_mclk_sel.hw,
542 &axg_mst_c_mclk_div, 585 [AUD_CLKID_MST_D_MCLK_SEL] = &aud_mst_d_mclk_sel.hw,
543 &axg_mst_d_mclk_div, 586 [AUD_CLKID_MST_E_MCLK_SEL] = &aud_mst_e_mclk_sel.hw,
544 &axg_mst_e_mclk_div, 587 [AUD_CLKID_MST_F_MCLK_SEL] = &aud_mst_f_mclk_sel.hw,
545 &axg_mst_f_mclk_div, 588 [AUD_CLKID_MST_A_MCLK_DIV] = &aud_mst_a_mclk_div.hw,
546 &axg_mst_a_mclk, 589 [AUD_CLKID_MST_B_MCLK_DIV] = &aud_mst_b_mclk_div.hw,
547 &axg_mst_b_mclk, 590 [AUD_CLKID_MST_C_MCLK_DIV] = &aud_mst_c_mclk_div.hw,
548 &axg_mst_c_mclk, 591 [AUD_CLKID_MST_D_MCLK_DIV] = &aud_mst_d_mclk_div.hw,
549 &axg_mst_d_mclk, 592 [AUD_CLKID_MST_E_MCLK_DIV] = &aud_mst_e_mclk_div.hw,
550 &axg_mst_e_mclk, 593 [AUD_CLKID_MST_F_MCLK_DIV] = &aud_mst_f_mclk_div.hw,
551 &axg_mst_f_mclk, 594 [AUD_CLKID_MST_A_MCLK] = &aud_mst_a_mclk.hw,
552 &axg_spdifout_clk_sel, 595 [AUD_CLKID_MST_B_MCLK] = &aud_mst_b_mclk.hw,
553 &axg_spdifout_clk_div, 596 [AUD_CLKID_MST_C_MCLK] = &aud_mst_c_mclk.hw,
554 &axg_spdifout_clk, 597 [AUD_CLKID_MST_D_MCLK] = &aud_mst_d_mclk.hw,
555 &axg_spdifin_clk_sel, 598 [AUD_CLKID_MST_E_MCLK] = &aud_mst_e_mclk.hw,
556 &axg_spdifin_clk_div, 599 [AUD_CLKID_MST_F_MCLK] = &aud_mst_f_mclk.hw,
557 &axg_spdifin_clk, 600 [AUD_CLKID_SPDIFOUT_CLK_SEL] = &aud_spdifout_clk_sel.hw,
558 &axg_pdm_dclk_sel, 601 [AUD_CLKID_SPDIFOUT_CLK_DIV] = &aud_spdifout_clk_div.hw,
559 &axg_pdm_dclk_div, 602 [AUD_CLKID_SPDIFOUT_CLK] = &aud_spdifout_clk.hw,
560 &axg_pdm_dclk, 603 [AUD_CLKID_SPDIFOUT_B_CLK_SEL] = &aud_spdifout_b_clk_sel.hw,
561 &axg_pdm_sysclk_sel, 604 [AUD_CLKID_SPDIFOUT_B_CLK_DIV] = &aud_spdifout_b_clk_div.hw,
562 &axg_pdm_sysclk_div, 605 [AUD_CLKID_SPDIFOUT_B_CLK] = &aud_spdifout_b_clk.hw,
563 &axg_pdm_sysclk, 606 [AUD_CLKID_SPDIFIN_CLK_SEL] = &aud_spdifin_clk_sel.hw,
564 &axg_mst_a_sclk_pre_en, 607 [AUD_CLKID_SPDIFIN_CLK_DIV] = &aud_spdifin_clk_div.hw,
565 &axg_mst_b_sclk_pre_en, 608 [AUD_CLKID_SPDIFIN_CLK] = &aud_spdifin_clk.hw,
566 &axg_mst_c_sclk_pre_en, 609 [AUD_CLKID_PDM_DCLK_SEL] = &aud_pdm_dclk_sel.hw,
567 &axg_mst_d_sclk_pre_en, 610 [AUD_CLKID_PDM_DCLK_DIV] = &aud_pdm_dclk_div.hw,
568 &axg_mst_e_sclk_pre_en, 611 [AUD_CLKID_PDM_DCLK] = &aud_pdm_dclk.hw,
569 &axg_mst_f_sclk_pre_en, 612 [AUD_CLKID_PDM_SYSCLK_SEL] = &aud_pdm_sysclk_sel.hw,
570 &axg_mst_a_sclk_div, 613 [AUD_CLKID_PDM_SYSCLK_DIV] = &aud_pdm_sysclk_div.hw,
571 &axg_mst_b_sclk_div, 614 [AUD_CLKID_PDM_SYSCLK] = &aud_pdm_sysclk.hw,
572 &axg_mst_c_sclk_div, 615 [AUD_CLKID_MST_A_SCLK_PRE_EN] = &aud_mst_a_sclk_pre_en.hw,
573 &axg_mst_d_sclk_div, 616 [AUD_CLKID_MST_B_SCLK_PRE_EN] = &aud_mst_b_sclk_pre_en.hw,
574 &axg_mst_e_sclk_div, 617 [AUD_CLKID_MST_C_SCLK_PRE_EN] = &aud_mst_c_sclk_pre_en.hw,
575 &axg_mst_f_sclk_div, 618 [AUD_CLKID_MST_D_SCLK_PRE_EN] = &aud_mst_d_sclk_pre_en.hw,
576 &axg_mst_a_sclk_post_en, 619 [AUD_CLKID_MST_E_SCLK_PRE_EN] = &aud_mst_e_sclk_pre_en.hw,
577 &axg_mst_b_sclk_post_en, 620 [AUD_CLKID_MST_F_SCLK_PRE_EN] = &aud_mst_f_sclk_pre_en.hw,
578 &axg_mst_c_sclk_post_en, 621 [AUD_CLKID_MST_A_SCLK_DIV] = &aud_mst_a_sclk_div.hw,
579 &axg_mst_d_sclk_post_en, 622 [AUD_CLKID_MST_B_SCLK_DIV] = &aud_mst_b_sclk_div.hw,
580 &axg_mst_e_sclk_post_en, 623 [AUD_CLKID_MST_C_SCLK_DIV] = &aud_mst_c_sclk_div.hw,
581 &axg_mst_f_sclk_post_en, 624 [AUD_CLKID_MST_D_SCLK_DIV] = &aud_mst_d_sclk_div.hw,
582 &axg_mst_a_sclk, 625 [AUD_CLKID_MST_E_SCLK_DIV] = &aud_mst_e_sclk_div.hw,
583 &axg_mst_b_sclk, 626 [AUD_CLKID_MST_F_SCLK_DIV] = &aud_mst_f_sclk_div.hw,
584 &axg_mst_c_sclk, 627 [AUD_CLKID_MST_A_SCLK_POST_EN] = &aud_mst_a_sclk_post_en.hw,
585 &axg_mst_d_sclk, 628 [AUD_CLKID_MST_B_SCLK_POST_EN] = &aud_mst_b_sclk_post_en.hw,
586 &axg_mst_e_sclk, 629 [AUD_CLKID_MST_C_SCLK_POST_EN] = &aud_mst_c_sclk_post_en.hw,
587 &axg_mst_f_sclk, 630 [AUD_CLKID_MST_D_SCLK_POST_EN] = &aud_mst_d_sclk_post_en.hw,
588 &axg_mst_a_lrclk_div, 631 [AUD_CLKID_MST_E_SCLK_POST_EN] = &aud_mst_e_sclk_post_en.hw,
589 &axg_mst_b_lrclk_div, 632 [AUD_CLKID_MST_F_SCLK_POST_EN] = &aud_mst_f_sclk_post_en.hw,
590 &axg_mst_c_lrclk_div, 633 [AUD_CLKID_MST_A_SCLK] = &aud_mst_a_sclk.hw,
591 &axg_mst_d_lrclk_div, 634 [AUD_CLKID_MST_B_SCLK] = &aud_mst_b_sclk.hw,
592 &axg_mst_e_lrclk_div, 635 [AUD_CLKID_MST_C_SCLK] = &aud_mst_c_sclk.hw,
593 &axg_mst_f_lrclk_div, 636 [AUD_CLKID_MST_D_SCLK] = &aud_mst_d_sclk.hw,
594 &axg_mst_a_lrclk, 637 [AUD_CLKID_MST_E_SCLK] = &aud_mst_e_sclk.hw,
595 &axg_mst_b_lrclk, 638 [AUD_CLKID_MST_F_SCLK] = &aud_mst_f_sclk.hw,
596 &axg_mst_c_lrclk, 639 [AUD_CLKID_MST_A_LRCLK_DIV] = &aud_mst_a_lrclk_div.hw,
597 &axg_mst_d_lrclk, 640 [AUD_CLKID_MST_B_LRCLK_DIV] = &aud_mst_b_lrclk_div.hw,
598 &axg_mst_e_lrclk, 641 [AUD_CLKID_MST_C_LRCLK_DIV] = &aud_mst_c_lrclk_div.hw,
599 &axg_mst_f_lrclk, 642 [AUD_CLKID_MST_D_LRCLK_DIV] = &aud_mst_d_lrclk_div.hw,
600 &axg_tdmin_a_sclk_sel, 643 [AUD_CLKID_MST_E_LRCLK_DIV] = &aud_mst_e_lrclk_div.hw,
601 &axg_tdmin_b_sclk_sel, 644 [AUD_CLKID_MST_F_LRCLK_DIV] = &aud_mst_f_lrclk_div.hw,
602 &axg_tdmin_c_sclk_sel, 645 [AUD_CLKID_MST_A_LRCLK] = &aud_mst_a_lrclk.hw,
603 &axg_tdmin_lb_sclk_sel, 646 [AUD_CLKID_MST_B_LRCLK] = &aud_mst_b_lrclk.hw,
604 &axg_tdmout_a_sclk_sel, 647 [AUD_CLKID_MST_C_LRCLK] = &aud_mst_c_lrclk.hw,
605 &axg_tdmout_b_sclk_sel, 648 [AUD_CLKID_MST_D_LRCLK] = &aud_mst_d_lrclk.hw,
606 &axg_tdmout_c_sclk_sel, 649 [AUD_CLKID_MST_E_LRCLK] = &aud_mst_e_lrclk.hw,
607 &axg_tdmin_a_sclk_pre_en, 650 [AUD_CLKID_MST_F_LRCLK] = &aud_mst_f_lrclk.hw,
608 &axg_tdmin_b_sclk_pre_en, 651 [AUD_CLKID_TDMIN_A_SCLK_SEL] = &aud_tdmin_a_sclk_sel.hw,
609 &axg_tdmin_c_sclk_pre_en, 652 [AUD_CLKID_TDMIN_B_SCLK_SEL] = &aud_tdmin_b_sclk_sel.hw,
610 &axg_tdmin_lb_sclk_pre_en, 653 [AUD_CLKID_TDMIN_C_SCLK_SEL] = &aud_tdmin_c_sclk_sel.hw,
611 &axg_tdmout_a_sclk_pre_en, 654 [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &aud_tdmin_lb_sclk_sel.hw,
612 &axg_tdmout_b_sclk_pre_en, 655 [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &aud_tdmout_a_sclk_sel.hw,
613 &axg_tdmout_c_sclk_pre_en, 656 [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &aud_tdmout_b_sclk_sel.hw,
614 &axg_tdmin_a_sclk_post_en, 657 [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &aud_tdmout_c_sclk_sel.hw,
615 &axg_tdmin_b_sclk_post_en, 658 [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &aud_tdmin_a_sclk_pre_en.hw,
616 &axg_tdmin_c_sclk_post_en, 659 [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &aud_tdmin_b_sclk_pre_en.hw,
617 &axg_tdmin_lb_sclk_post_en, 660 [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &aud_tdmin_c_sclk_pre_en.hw,
618 &axg_tdmout_a_sclk_post_en, 661 [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &aud_tdmin_lb_sclk_pre_en.hw,
619 &axg_tdmout_b_sclk_post_en, 662 [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &aud_tdmout_a_sclk_pre_en.hw,
620 &axg_tdmout_c_sclk_post_en, 663 [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &aud_tdmout_b_sclk_pre_en.hw,
621 &axg_tdmin_a_sclk, 664 [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &aud_tdmout_c_sclk_pre_en.hw,
622 &axg_tdmin_b_sclk, 665 [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &aud_tdmin_a_sclk_post_en.hw,
623 &axg_tdmin_c_sclk, 666 [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &aud_tdmin_b_sclk_post_en.hw,
624 &axg_tdmin_lb_sclk, 667 [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &aud_tdmin_c_sclk_post_en.hw,
625 &axg_tdmout_a_sclk, 668 [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &aud_tdmin_lb_sclk_post_en.hw,
626 &axg_tdmout_b_sclk, 669 [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &aud_tdmout_a_sclk_post_en.hw,
627 &axg_tdmout_c_sclk, 670 [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &aud_tdmout_b_sclk_post_en.hw,
628 &axg_tdmin_a_lrclk, 671 [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &aud_tdmout_c_sclk_post_en.hw,
629 &axg_tdmin_b_lrclk, 672 [AUD_CLKID_TDMIN_A_SCLK] = &aud_tdmin_a_sclk.hw,
630 &axg_tdmin_c_lrclk, 673 [AUD_CLKID_TDMIN_B_SCLK] = &aud_tdmin_b_sclk.hw,
631 &axg_tdmin_lb_lrclk, 674 [AUD_CLKID_TDMIN_C_SCLK] = &aud_tdmin_c_sclk.hw,
632 &axg_tdmout_a_lrclk, 675 [AUD_CLKID_TDMIN_LB_SCLK] = &aud_tdmin_lb_sclk.hw,
633 &axg_tdmout_b_lrclk, 676 [AUD_CLKID_TDMOUT_A_SCLK] = &aud_tdmout_a_sclk.hw,
634 &axg_tdmout_c_lrclk, 677 [AUD_CLKID_TDMOUT_B_SCLK] = &aud_tdmout_b_sclk.hw,
678 [AUD_CLKID_TDMOUT_C_SCLK] = &aud_tdmout_c_sclk.hw,
679 [AUD_CLKID_TDMIN_A_LRCLK] = &aud_tdmin_a_lrclk.hw,
680 [AUD_CLKID_TDMIN_B_LRCLK] = &aud_tdmin_b_lrclk.hw,
681 [AUD_CLKID_TDMIN_C_LRCLK] = &aud_tdmin_c_lrclk.hw,
682 [AUD_CLKID_TDMIN_LB_LRCLK] = &aud_tdmin_lb_lrclk.hw,
683 [AUD_CLKID_TDMOUT_A_LRCLK] = &aud_tdmout_a_lrclk.hw,
684 [AUD_CLKID_TDMOUT_B_LRCLK] = &aud_tdmout_b_lrclk.hw,
685 [AUD_CLKID_TDMOUT_C_LRCLK] = &aud_tdmout_c_lrclk.hw,
686 [AUD_CLKID_TDM_MCLK_PAD0] = &aud_tdm_mclk_pad_0.hw,
687 [AUD_CLKID_TDM_MCLK_PAD1] = &aud_tdm_mclk_pad_1.hw,
688 [AUD_CLKID_TDM_LRCLK_PAD0] = &aud_tdm_lrclk_pad_0.hw,
689 [AUD_CLKID_TDM_LRCLK_PAD1] = &aud_tdm_lrclk_pad_1.hw,
690 [AUD_CLKID_TDM_LRCLK_PAD2] = &aud_tdm_lrclk_pad_2.hw,
691 [AUD_CLKID_TDM_SCLK_PAD0] = &aud_tdm_sclk_pad_0.hw,
692 [AUD_CLKID_TDM_SCLK_PAD1] = &aud_tdm_sclk_pad_1.hw,
693 [AUD_CLKID_TDM_SCLK_PAD2] = &aud_tdm_sclk_pad_2.hw,
694 [NR_CLKS] = NULL,
695 },
696 .num = NR_CLKS,
697};
698
699/* Convenience table to populate regmap in .probe()
700 * Note that this table is shared between both AXG and G12A,
701 * with spdifout_b clocks being exclusive to G12A. Since those
702 * clocks are not declared within the AXG onecell table, we do not
703 * feel the need to have separate AXG/G12A regmap tables.
704 */
705static struct clk_regmap *const aud_clk_regmaps[] = {
706 &aud_ddr_arb,
707 &aud_pdm,
708 &aud_tdmin_a,
709 &aud_tdmin_b,
710 &aud_tdmin_c,
711 &aud_tdmin_lb,
712 &aud_tdmout_a,
713 &aud_tdmout_b,
714 &aud_tdmout_c,
715 &aud_frddr_a,
716 &aud_frddr_b,
717 &aud_frddr_c,
718 &aud_toddr_a,
719 &aud_toddr_b,
720 &aud_toddr_c,
721 &aud_loopback,
722 &aud_spdifin,
723 &aud_spdifout,
724 &aud_resample,
725 &aud_power_detect,
726 &aud_spdifout_b,
727 &aud_mst_a_mclk_sel,
728 &aud_mst_b_mclk_sel,
729 &aud_mst_c_mclk_sel,
730 &aud_mst_d_mclk_sel,
731 &aud_mst_e_mclk_sel,
732 &aud_mst_f_mclk_sel,
733 &aud_mst_a_mclk_div,
734 &aud_mst_b_mclk_div,
735 &aud_mst_c_mclk_div,
736 &aud_mst_d_mclk_div,
737 &aud_mst_e_mclk_div,
738 &aud_mst_f_mclk_div,
739 &aud_mst_a_mclk,
740 &aud_mst_b_mclk,
741 &aud_mst_c_mclk,
742 &aud_mst_d_mclk,
743 &aud_mst_e_mclk,
744 &aud_mst_f_mclk,
745 &aud_spdifout_clk_sel,
746 &aud_spdifout_clk_div,
747 &aud_spdifout_clk,
748 &aud_spdifin_clk_sel,
749 &aud_spdifin_clk_div,
750 &aud_spdifin_clk,
751 &aud_pdm_dclk_sel,
752 &aud_pdm_dclk_div,
753 &aud_pdm_dclk,
754 &aud_pdm_sysclk_sel,
755 &aud_pdm_sysclk_div,
756 &aud_pdm_sysclk,
757 &aud_mst_a_sclk_pre_en,
758 &aud_mst_b_sclk_pre_en,
759 &aud_mst_c_sclk_pre_en,
760 &aud_mst_d_sclk_pre_en,
761 &aud_mst_e_sclk_pre_en,
762 &aud_mst_f_sclk_pre_en,
763 &aud_mst_a_sclk_div,
764 &aud_mst_b_sclk_div,
765 &aud_mst_c_sclk_div,
766 &aud_mst_d_sclk_div,
767 &aud_mst_e_sclk_div,
768 &aud_mst_f_sclk_div,
769 &aud_mst_a_sclk_post_en,
770 &aud_mst_b_sclk_post_en,
771 &aud_mst_c_sclk_post_en,
772 &aud_mst_d_sclk_post_en,
773 &aud_mst_e_sclk_post_en,
774 &aud_mst_f_sclk_post_en,
775 &aud_mst_a_sclk,
776 &aud_mst_b_sclk,
777 &aud_mst_c_sclk,
778 &aud_mst_d_sclk,
779 &aud_mst_e_sclk,
780 &aud_mst_f_sclk,
781 &aud_mst_a_lrclk_div,
782 &aud_mst_b_lrclk_div,
783 &aud_mst_c_lrclk_div,
784 &aud_mst_d_lrclk_div,
785 &aud_mst_e_lrclk_div,
786 &aud_mst_f_lrclk_div,
787 &aud_mst_a_lrclk,
788 &aud_mst_b_lrclk,
789 &aud_mst_c_lrclk,
790 &aud_mst_d_lrclk,
791 &aud_mst_e_lrclk,
792 &aud_mst_f_lrclk,
793 &aud_tdmin_a_sclk_sel,
794 &aud_tdmin_b_sclk_sel,
795 &aud_tdmin_c_sclk_sel,
796 &aud_tdmin_lb_sclk_sel,
797 &aud_tdmout_a_sclk_sel,
798 &aud_tdmout_b_sclk_sel,
799 &aud_tdmout_c_sclk_sel,
800 &aud_tdmin_a_sclk_pre_en,
801 &aud_tdmin_b_sclk_pre_en,
802 &aud_tdmin_c_sclk_pre_en,
803 &aud_tdmin_lb_sclk_pre_en,
804 &aud_tdmout_a_sclk_pre_en,
805 &aud_tdmout_b_sclk_pre_en,
806 &aud_tdmout_c_sclk_pre_en,
807 &aud_tdmin_a_sclk_post_en,
808 &aud_tdmin_b_sclk_post_en,
809 &aud_tdmin_c_sclk_post_en,
810 &aud_tdmin_lb_sclk_post_en,
811 &aud_tdmout_a_sclk_post_en,
812 &aud_tdmout_b_sclk_post_en,
813 &aud_tdmout_c_sclk_post_en,
814 &aud_tdmin_a_sclk,
815 &aud_tdmin_b_sclk,
816 &aud_tdmin_c_sclk,
817 &aud_tdmin_lb_sclk,
818 &aud_tdmout_a_sclk,
819 &aud_tdmout_b_sclk,
820 &aud_tdmout_c_sclk,
821 &aud_tdmin_a_lrclk,
822 &aud_tdmin_b_lrclk,
823 &aud_tdmin_c_lrclk,
824 &aud_tdmin_lb_lrclk,
825 &aud_tdmout_a_lrclk,
826 &aud_tdmout_b_lrclk,
827 &aud_tdmout_c_lrclk,
828 &aud_spdifout_b_clk_sel,
829 &aud_spdifout_b_clk_div,
830 &aud_spdifout_b_clk,
831 &aud_tdm_mclk_pad_0,
832 &aud_tdm_mclk_pad_1,
833 &aud_tdm_lrclk_pad_0,
834 &aud_tdm_lrclk_pad_1,
835 &aud_tdm_lrclk_pad_2,
836 &aud_tdm_sclk_pad_0,
837 &aud_tdm_sclk_pad_1,
838 &aud_tdm_sclk_pad_2,
635}; 839};
636 840
637static int devm_clk_get_enable(struct device *dev, char *id) 841static int devm_clk_get_enable(struct device *dev, char *id)
@@ -665,14 +869,13 @@ static int devm_clk_get_enable(struct device *dev, char *id)
665} 869}
666 870
667static int axg_register_clk_hw_input(struct device *dev, 871static int axg_register_clk_hw_input(struct device *dev,
668 const char *name, 872 const char *name)
669 unsigned int clkid)
670{ 873{
671 char *clk_name; 874 char *clk_name;
672 struct clk_hw *hw; 875 struct clk_hw *hw;
673 int err = 0; 876 int err = 0;
674 877
675 clk_name = kasprintf(GFP_KERNEL, "axg_%s", name); 878 clk_name = kasprintf(GFP_KERNEL, "aud_%s", name);
676 if (!clk_name) 879 if (!clk_name)
677 return -ENOMEM; 880 return -ENOMEM;
678 881
@@ -686,8 +889,6 @@ static int axg_register_clk_hw_input(struct device *dev,
686 if (err != -EPROBE_DEFER) 889 if (err != -EPROBE_DEFER)
687 dev_err(dev, "failed to get %s clock", name); 890 dev_err(dev, "failed to get %s clock", name);
688 } 891 }
689 } else {
690 axg_audio_hw_onecell_data.hws[clkid] = hw;
691 } 892 }
692 893
693 kfree(clk_name); 894 kfree(clk_name);
@@ -696,8 +897,7 @@ static int axg_register_clk_hw_input(struct device *dev,
696 897
697static int axg_register_clk_hw_inputs(struct device *dev, 898static int axg_register_clk_hw_inputs(struct device *dev,
698 const char *basename, 899 const char *basename,
699 unsigned int count, 900 unsigned int count)
700 unsigned int clkid)
701{ 901{
702 char *name; 902 char *name;
703 int i, ret; 903 int i, ret;
@@ -707,7 +907,7 @@ static int axg_register_clk_hw_inputs(struct device *dev,
707 if (!name) 907 if (!name)
708 return -ENOMEM; 908 return -ENOMEM;
709 909
710 ret = axg_register_clk_hw_input(dev, name, clkid + i); 910 ret = axg_register_clk_hw_input(dev, name);
711 kfree(name); 911 kfree(name);
712 if (ret) 912 if (ret)
713 return ret; 913 return ret;
@@ -723,15 +923,24 @@ static const struct regmap_config axg_audio_regmap_cfg = {
723 .max_register = AUDIO_CLK_PDMIN_CTRL1, 923 .max_register = AUDIO_CLK_PDMIN_CTRL1,
724}; 924};
725 925
926struct audioclk_data {
927 struct clk_hw_onecell_data *hw_onecell_data;
928};
929
726static int axg_audio_clkc_probe(struct platform_device *pdev) 930static int axg_audio_clkc_probe(struct platform_device *pdev)
727{ 931{
728 struct device *dev = &pdev->dev; 932 struct device *dev = &pdev->dev;
933 const struct audioclk_data *data;
729 struct regmap *map; 934 struct regmap *map;
730 struct resource *res; 935 struct resource *res;
731 void __iomem *regs; 936 void __iomem *regs;
732 struct clk_hw *hw; 937 struct clk_hw *hw;
733 int ret, i; 938 int ret, i;
734 939
940 data = of_device_get_match_data(dev);
941 if (!data)
942 return -EINVAL;
943
735 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 944 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
736 regs = devm_ioremap_resource(dev, res); 945 regs = devm_ioremap_resource(dev, res);
737 if (IS_ERR(regs)) 946 if (IS_ERR(regs))
@@ -755,40 +964,35 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
755 } 964 }
756 965
757 /* Register the peripheral input clock */ 966 /* Register the peripheral input clock */
758 hw = meson_clk_hw_register_input(dev, "pclk", "axg_audio_pclk", 0); 967 hw = meson_clk_hw_register_input(dev, "pclk", "audio_pclk", 0);
759 if (IS_ERR(hw)) 968 if (IS_ERR(hw))
760 return PTR_ERR(hw); 969 return PTR_ERR(hw);
761 970
762 axg_audio_hw_onecell_data.hws[AUD_CLKID_PCLK] = hw;
763
764 /* Register optional input master clocks */ 971 /* Register optional input master clocks */
765 ret = axg_register_clk_hw_inputs(dev, "mst_in", 972 ret = axg_register_clk_hw_inputs(dev, "mst_in",
766 AXG_MST_IN_COUNT, 973 AUD_MST_IN_COUNT);
767 AUD_CLKID_MST0);
768 if (ret) 974 if (ret)
769 return ret; 975 return ret;
770 976
771 /* Register optional input slave sclks */ 977 /* Register optional input slave sclks */
772 ret = axg_register_clk_hw_inputs(dev, "slv_sclk", 978 ret = axg_register_clk_hw_inputs(dev, "slv_sclk",
773 AXG_SLV_SCLK_COUNT, 979 AUD_SLV_SCLK_COUNT);
774 AUD_CLKID_SLV_SCLK0);
775 if (ret) 980 if (ret)
776 return ret; 981 return ret;
777 982
778 /* Register optional input slave lrclks */ 983 /* Register optional input slave lrclks */
779 ret = axg_register_clk_hw_inputs(dev, "slv_lrclk", 984 ret = axg_register_clk_hw_inputs(dev, "slv_lrclk",
780 AXG_SLV_LRCLK_COUNT, 985 AUD_SLV_LRCLK_COUNT);
781 AUD_CLKID_SLV_LRCLK0);
782 if (ret) 986 if (ret)
783 return ret; 987 return ret;
784 988
785 /* Populate regmap for the regmap backed clocks */ 989 /* Populate regmap for the regmap backed clocks */
786 for (i = 0; i < ARRAY_SIZE(axg_audio_clk_regmaps); i++) 990 for (i = 0; i < ARRAY_SIZE(aud_clk_regmaps); i++)
787 axg_audio_clk_regmaps[i]->map = map; 991 aud_clk_regmaps[i]->map = map;
788 992
789 /* Take care to skip the registered input clocks */ 993 /* Take care to skip the registered input clocks */
790 for (i = AUD_CLKID_DDR_ARB; i < axg_audio_hw_onecell_data.num; i++) { 994 for (i = AUD_CLKID_DDR_ARB; i < data->hw_onecell_data->num; i++) {
791 hw = axg_audio_hw_onecell_data.hws[i]; 995 hw = data->hw_onecell_data->hws[i];
792 /* array might be sparse */ 996 /* array might be sparse */
793 if (!hw) 997 if (!hw)
794 continue; 998 continue;
@@ -802,12 +1006,25 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
802 } 1006 }
803 1007
804 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, 1008 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
805 &axg_audio_hw_onecell_data); 1009 data->hw_onecell_data);
806} 1010}
807 1011
1012static const struct audioclk_data axg_audioclk_data = {
1013 .hw_onecell_data = &axg_audio_hw_onecell_data,
1014};
1015
1016static const struct audioclk_data g12a_audioclk_data = {
1017 .hw_onecell_data = &g12a_audio_hw_onecell_data,
1018};
1019
808static const struct of_device_id clkc_match_table[] = { 1020static const struct of_device_id clkc_match_table[] = {
809 { .compatible = "amlogic,axg-audio-clkc" }, 1021 {
810 {} 1022 .compatible = "amlogic,axg-audio-clkc",
1023 .data = &axg_audioclk_data
1024 }, {
1025 .compatible = "amlogic,g12a-audio-clkc",
1026 .data = &g12a_audioclk_data
1027 }, {}
811}; 1028};
812MODULE_DEVICE_TABLE(of, clkc_match_table); 1029MODULE_DEVICE_TABLE(of, clkc_match_table);
813 1030
@@ -820,6 +1037,6 @@ static struct platform_driver axg_audio_driver = {
820}; 1037};
821module_platform_driver(axg_audio_driver); 1038module_platform_driver(axg_audio_driver);
822 1039
823MODULE_DESCRIPTION("Amlogic A113x Audio Clock driver"); 1040MODULE_DESCRIPTION("Amlogic AXG/G12A Audio Clock driver");
824MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 1041MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
825MODULE_LICENSE("GPL v2"); 1042MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/axg-audio.h b/drivers/clk/meson/axg-audio.h
index 7191b39c9d65..5d972d55d6c7 100644
--- a/drivers/clk/meson/axg-audio.h
+++ b/drivers/clk/meson/axg-audio.h
@@ -20,6 +20,8 @@
20#define AUDIO_MCLK_D_CTRL 0x010 20#define AUDIO_MCLK_D_CTRL 0x010
21#define AUDIO_MCLK_E_CTRL 0x014 21#define AUDIO_MCLK_E_CTRL 0x014
22#define AUDIO_MCLK_F_CTRL 0x018 22#define AUDIO_MCLK_F_CTRL 0x018
23#define AUDIO_MST_PAD_CTRL0 0x01c
24#define AUDIO_MST_PAD_CTRL1 0x020
23#define AUDIO_MST_A_SCLK_CTRL0 0x040 25#define AUDIO_MST_A_SCLK_CTRL0 0x040
24#define AUDIO_MST_A_SCLK_CTRL1 0x044 26#define AUDIO_MST_A_SCLK_CTRL1 0x044
25#define AUDIO_MST_B_SCLK_CTRL0 0x048 27#define AUDIO_MST_B_SCLK_CTRL0 0x048
@@ -45,21 +47,13 @@
45#define AUDIO_CLK_LOCKER_CTRL 0x0A8 47#define AUDIO_CLK_LOCKER_CTRL 0x0A8
46#define AUDIO_CLK_PDMIN_CTRL0 0x0AC 48#define AUDIO_CLK_PDMIN_CTRL0 0x0AC
47#define AUDIO_CLK_PDMIN_CTRL1 0x0B0 49#define AUDIO_CLK_PDMIN_CTRL1 0x0B0
50#define AUDIO_CLK_SPDIFOUT_B_CTRL 0x0B4
48 51
49/* 52/*
50 * CLKID index values 53 * CLKID index values
51 * These indices are entirely contrived and do not map onto the hardware. 54 * These indices are entirely contrived and do not map onto the hardware.
52 */ 55 */
53 56
54#define AUD_CLKID_PCLK 0
55#define AUD_CLKID_MST0 1
56#define AUD_CLKID_MST1 2
57#define AUD_CLKID_MST2 3
58#define AUD_CLKID_MST3 4
59#define AUD_CLKID_MST4 5
60#define AUD_CLKID_MST5 6
61#define AUD_CLKID_MST6 7
62#define AUD_CLKID_MST7 8
63#define AUD_CLKID_MST_A_MCLK_SEL 59 57#define AUD_CLKID_MST_A_MCLK_SEL 59
64#define AUD_CLKID_MST_B_MCLK_SEL 60 58#define AUD_CLKID_MST_B_MCLK_SEL 60
65#define AUD_CLKID_MST_C_MCLK_SEL 61 59#define AUD_CLKID_MST_C_MCLK_SEL 61
@@ -118,10 +112,12 @@
118#define AUD_CLKID_TDMOUT_A_SCLK_POST_EN 148 112#define AUD_CLKID_TDMOUT_A_SCLK_POST_EN 148
119#define AUD_CLKID_TDMOUT_B_SCLK_POST_EN 149 113#define AUD_CLKID_TDMOUT_B_SCLK_POST_EN 149
120#define AUD_CLKID_TDMOUT_C_SCLK_POST_EN 150 114#define AUD_CLKID_TDMOUT_C_SCLK_POST_EN 150
115#define AUD_CLKID_SPDIFOUT_B_CLK_SEL 153
116#define AUD_CLKID_SPDIFOUT_B_CLK_DIV 154
121 117
122/* include the CLKIDs which are part of the DT bindings */ 118/* include the CLKIDs which are part of the DT bindings */
123#include <dt-bindings/clock/axg-audio-clkc.h> 119#include <dt-bindings/clock/axg-audio-clkc.h>
124 120
125#define NR_CLKS 151 121#define NR_CLKS 163
126 122
127#endif /*__AXG_AUDIO_CLKC_H */ 123#endif /*__AXG_AUDIO_CLKC_H */
diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index 7a14ac9b2fec..ddb1e5634739 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -303,6 +303,16 @@ static int meson_clk_pll_is_enabled(struct clk_hw *hw)
303 return 1; 303 return 1;
304} 304}
305 305
306static int meson_clk_pcie_pll_enable(struct clk_hw *hw)
307{
308 meson_clk_pll_init(hw);
309
310 if (meson_clk_pll_wait_lock(hw))
311 return -EIO;
312
313 return 0;
314}
315
306static int meson_clk_pll_enable(struct clk_hw *hw) 316static int meson_clk_pll_enable(struct clk_hw *hw)
307{ 317{
308 struct clk_regmap *clk = to_clk_regmap(hw); 318 struct clk_regmap *clk = to_clk_regmap(hw);
@@ -387,6 +397,22 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
387 return 0; 397 return 0;
388} 398}
389 399
400/*
401 * The Meson G12A PCIE PLL is fined tuned to deliver a very precise
402 * 100MHz reference clock for the PCIe Analog PHY, and thus requires
403 * a strict register sequence to enable the PLL.
404 * To simplify, re-use the _init() op to enable the PLL and keep
405 * the other ops except set_rate since the rate is fixed.
406 */
407const struct clk_ops meson_clk_pcie_pll_ops = {
408 .recalc_rate = meson_clk_pll_recalc_rate,
409 .round_rate = meson_clk_pll_round_rate,
410 .is_enabled = meson_clk_pll_is_enabled,
411 .enable = meson_clk_pcie_pll_enable,
412 .disable = meson_clk_pll_disable
413};
414EXPORT_SYMBOL_GPL(meson_clk_pcie_pll_ops);
415
390const struct clk_ops meson_clk_pll_ops = { 416const struct clk_ops meson_clk_pll_ops = {
391 .init = meson_clk_pll_init, 417 .init = meson_clk_pll_init,
392 .recalc_rate = meson_clk_pll_recalc_rate, 418 .recalc_rate = meson_clk_pll_recalc_rate,
diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h
index 55af2e285b1b..367efd0f6410 100644
--- a/drivers/clk/meson/clk-pll.h
+++ b/drivers/clk/meson/clk-pll.h
@@ -45,5 +45,6 @@ struct meson_clk_pll_data {
45 45
46extern const struct clk_ops meson_clk_pll_ro_ops; 46extern const struct clk_ops meson_clk_pll_ro_ops;
47extern const struct clk_ops meson_clk_pll_ops; 47extern const struct clk_ops meson_clk_pll_ops;
48extern const struct clk_ops meson_clk_pcie_pll_ops;
48 49
49#endif /* __MESON_CLK_PLL_H */ 50#endif /* __MESON_CLK_PLL_H */
diff --git a/drivers/clk/meson/g12a-aoclk.h b/drivers/clk/meson/g12a-aoclk.h
index 04b0d5506641..a67c8a7cd7c4 100644
--- a/drivers/clk/meson/g12a-aoclk.h
+++ b/drivers/clk/meson/g12a-aoclk.h
@@ -16,9 +16,7 @@
16 * to expose, such as the internal muxes and dividers of composite clocks, 16 * to expose, such as the internal muxes and dividers of composite clocks,
17 * will remain defined here. 17 * will remain defined here.
18 */ 18 */
19#define CLKID_AO_SAR_ADC_SEL 16
20#define CLKID_AO_SAR_ADC_DIV 17 19#define CLKID_AO_SAR_ADC_DIV 17
21#define CLKID_AO_CTS_OSCIN 19
22#define CLKID_AO_32K_PRE 20 20#define CLKID_AO_32K_PRE 20
23#define CLKID_AO_32K_DIV 21 21#define CLKID_AO_32K_DIV 21
24#define CLKID_AO_32K_SEL 22 22#define CLKID_AO_32K_SEL 22
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index f7b11e1eeebe..739f64fdf1e3 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -150,6 +150,318 @@ static struct clk_regmap g12a_sys_pll = {
150 }, 150 },
151}; 151};
152 152
153static struct clk_regmap g12a_sys_pll_div16_en = {
154 .data = &(struct clk_regmap_gate_data){
155 .offset = HHI_SYS_CPU_CLK_CNTL1,
156 .bit_idx = 24,
157 },
158 .hw.init = &(struct clk_init_data) {
159 .name = "sys_pll_div16_en",
160 .ops = &clk_regmap_gate_ro_ops,
161 .parent_names = (const char *[]){ "sys_pll" },
162 .num_parents = 1,
163 /*
164 * This clock is used to debug the sys_pll range
165 * Linux should not change it at runtime
166 */
167 },
168};
169
170static struct clk_fixed_factor g12a_sys_pll_div16 = {
171 .mult = 1,
172 .div = 16,
173 .hw.init = &(struct clk_init_data){
174 .name = "sys_pll_div16",
175 .ops = &clk_fixed_factor_ops,
176 .parent_names = (const char *[]){ "sys_pll_div16_en" },
177 .num_parents = 1,
178 },
179};
180
181/* Datasheet names this field as "premux0" */
182static struct clk_regmap g12a_cpu_clk_premux0 = {
183 .data = &(struct clk_regmap_mux_data){
184 .offset = HHI_SYS_CPU_CLK_CNTL0,
185 .mask = 0x3,
186 .shift = 0,
187 },
188 .hw.init = &(struct clk_init_data){
189 .name = "cpu_clk_dyn0_sel",
190 .ops = &clk_regmap_mux_ro_ops,
191 .parent_names = (const char *[]){ IN_PREFIX "xtal",
192 "fclk_div2",
193 "fclk_div3" },
194 .num_parents = 3,
195 },
196};
197
198/* Datasheet names this field as "mux0_divn_tcnt" */
199static struct clk_regmap g12a_cpu_clk_mux0_div = {
200 .data = &(struct clk_regmap_div_data){
201 .offset = HHI_SYS_CPU_CLK_CNTL0,
202 .shift = 4,
203 .width = 6,
204 },
205 .hw.init = &(struct clk_init_data){
206 .name = "cpu_clk_dyn0_div",
207 .ops = &clk_regmap_divider_ro_ops,
208 .parent_names = (const char *[]){ "cpu_clk_dyn0_sel" },
209 .num_parents = 1,
210 },
211};
212
213/* Datasheet names this field as "postmux0" */
214static struct clk_regmap g12a_cpu_clk_postmux0 = {
215 .data = &(struct clk_regmap_mux_data){
216 .offset = HHI_SYS_CPU_CLK_CNTL0,
217 .mask = 0x1,
218 .shift = 2,
219 },
220 .hw.init = &(struct clk_init_data){
221 .name = "cpu_clk_dyn0",
222 .ops = &clk_regmap_mux_ro_ops,
223 .parent_names = (const char *[]){ "cpu_clk_dyn0_sel",
224 "cpu_clk_dyn0_div" },
225 .num_parents = 2,
226 },
227};
228
229/* Datasheet names this field as "premux1" */
230static struct clk_regmap g12a_cpu_clk_premux1 = {
231 .data = &(struct clk_regmap_mux_data){
232 .offset = HHI_SYS_CPU_CLK_CNTL0,
233 .mask = 0x3,
234 .shift = 16,
235 },
236 .hw.init = &(struct clk_init_data){
237 .name = "cpu_clk_dyn1_sel",
238 .ops = &clk_regmap_mux_ro_ops,
239 .parent_names = (const char *[]){ IN_PREFIX "xtal",
240 "fclk_div2",
241 "fclk_div3" },
242 .num_parents = 3,
243 },
244};
245
246/* Datasheet names this field as "Mux1_divn_tcnt" */
247static struct clk_regmap g12a_cpu_clk_mux1_div = {
248 .data = &(struct clk_regmap_div_data){
249 .offset = HHI_SYS_CPU_CLK_CNTL0,
250 .shift = 20,
251 .width = 6,
252 },
253 .hw.init = &(struct clk_init_data){
254 .name = "cpu_clk_dyn1_div",
255 .ops = &clk_regmap_divider_ro_ops,
256 .parent_names = (const char *[]){ "cpu_clk_dyn1_sel" },
257 .num_parents = 1,
258 },
259};
260
261/* Datasheet names this field as "postmux1" */
262static struct clk_regmap g12a_cpu_clk_postmux1 = {
263 .data = &(struct clk_regmap_mux_data){
264 .offset = HHI_SYS_CPU_CLK_CNTL0,
265 .mask = 0x1,
266 .shift = 18,
267 },
268 .hw.init = &(struct clk_init_data){
269 .name = "cpu_clk_dyn1",
270 .ops = &clk_regmap_mux_ro_ops,
271 .parent_names = (const char *[]){ "cpu_clk_dyn1_sel",
272 "cpu_clk_dyn1_div" },
273 .num_parents = 2,
274 },
275};
276
277/* Datasheet names this field as "Final_dyn_mux_sel" */
278static struct clk_regmap g12a_cpu_clk_dyn = {
279 .data = &(struct clk_regmap_mux_data){
280 .offset = HHI_SYS_CPU_CLK_CNTL0,
281 .mask = 0x1,
282 .shift = 10,
283 },
284 .hw.init = &(struct clk_init_data){
285 .name = "cpu_clk_dyn",
286 .ops = &clk_regmap_mux_ro_ops,
287 .parent_names = (const char *[]){ "cpu_clk_dyn0",
288 "cpu_clk_dyn1" },
289 .num_parents = 2,
290 },
291};
292
293/* Datasheet names this field as "Final_mux_sel" */
294static struct clk_regmap g12a_cpu_clk = {
295 .data = &(struct clk_regmap_mux_data){
296 .offset = HHI_SYS_CPU_CLK_CNTL0,
297 .mask = 0x1,
298 .shift = 11,
299 },
300 .hw.init = &(struct clk_init_data){
301 .name = "cpu_clk",
302 .ops = &clk_regmap_mux_ro_ops,
303 .parent_names = (const char *[]){ "cpu_clk_dyn",
304 "sys_pll" },
305 .num_parents = 2,
306 },
307};
308
309static struct clk_regmap g12a_cpu_clk_div16_en = {
310 .data = &(struct clk_regmap_gate_data){
311 .offset = HHI_SYS_CPU_CLK_CNTL1,
312 .bit_idx = 1,
313 },
314 .hw.init = &(struct clk_init_data) {
315 .name = "cpu_clk_div16_en",
316 .ops = &clk_regmap_gate_ro_ops,
317 .parent_names = (const char *[]){ "cpu_clk" },
318 .num_parents = 1,
319 /*
320 * This clock is used to debug the cpu_clk range
321 * Linux should not change it at runtime
322 */
323 },
324};
325
326static struct clk_fixed_factor g12a_cpu_clk_div16 = {
327 .mult = 1,
328 .div = 16,
329 .hw.init = &(struct clk_init_data){
330 .name = "cpu_clk_div16",
331 .ops = &clk_fixed_factor_ops,
332 .parent_names = (const char *[]){ "cpu_clk_div16_en" },
333 .num_parents = 1,
334 },
335};
336
337static struct clk_regmap g12a_cpu_clk_apb_div = {
338 .data = &(struct clk_regmap_div_data){
339 .offset = HHI_SYS_CPU_CLK_CNTL1,
340 .shift = 3,
341 .width = 3,
342 .flags = CLK_DIVIDER_POWER_OF_TWO,
343 },
344 .hw.init = &(struct clk_init_data){
345 .name = "cpu_clk_apb_div",
346 .ops = &clk_regmap_divider_ro_ops,
347 .parent_names = (const char *[]){ "cpu_clk" },
348 .num_parents = 1,
349 },
350};
351
352static struct clk_regmap g12a_cpu_clk_apb = {
353 .data = &(struct clk_regmap_gate_data){
354 .offset = HHI_SYS_CPU_CLK_CNTL1,
355 .bit_idx = 1,
356 },
357 .hw.init = &(struct clk_init_data) {
358 .name = "cpu_clk_apb",
359 .ops = &clk_regmap_gate_ro_ops,
360 .parent_names = (const char *[]){ "cpu_clk_apb_div" },
361 .num_parents = 1,
362 /*
363 * This clock is set by the ROM monitor code,
364 * Linux should not change it at runtime
365 */
366 },
367};
368
369static struct clk_regmap g12a_cpu_clk_atb_div = {
370 .data = &(struct clk_regmap_div_data){
371 .offset = HHI_SYS_CPU_CLK_CNTL1,
372 .shift = 6,
373 .width = 3,
374 .flags = CLK_DIVIDER_POWER_OF_TWO,
375 },
376 .hw.init = &(struct clk_init_data){
377 .name = "cpu_clk_atb_div",
378 .ops = &clk_regmap_divider_ro_ops,
379 .parent_names = (const char *[]){ "cpu_clk" },
380 .num_parents = 1,
381 },
382};
383
384static struct clk_regmap g12a_cpu_clk_atb = {
385 .data = &(struct clk_regmap_gate_data){
386 .offset = HHI_SYS_CPU_CLK_CNTL1,
387 .bit_idx = 17,
388 },
389 .hw.init = &(struct clk_init_data) {
390 .name = "cpu_clk_atb",
391 .ops = &clk_regmap_gate_ro_ops,
392 .parent_names = (const char *[]){ "cpu_clk_atb_div" },
393 .num_parents = 1,
394 /*
395 * This clock is set by the ROM monitor code,
396 * Linux should not change it at runtime
397 */
398 },
399};
400
401static struct clk_regmap g12a_cpu_clk_axi_div = {
402 .data = &(struct clk_regmap_div_data){
403 .offset = HHI_SYS_CPU_CLK_CNTL1,
404 .shift = 9,
405 .width = 3,
406 .flags = CLK_DIVIDER_POWER_OF_TWO,
407 },
408 .hw.init = &(struct clk_init_data){
409 .name = "cpu_clk_axi_div",
410 .ops = &clk_regmap_divider_ro_ops,
411 .parent_names = (const char *[]){ "cpu_clk" },
412 .num_parents = 1,
413 },
414};
415
416static struct clk_regmap g12a_cpu_clk_axi = {
417 .data = &(struct clk_regmap_gate_data){
418 .offset = HHI_SYS_CPU_CLK_CNTL1,
419 .bit_idx = 18,
420 },
421 .hw.init = &(struct clk_init_data) {
422 .name = "cpu_clk_axi",
423 .ops = &clk_regmap_gate_ro_ops,
424 .parent_names = (const char *[]){ "cpu_clk_axi_div" },
425 .num_parents = 1,
426 /*
427 * This clock is set by the ROM monitor code,
428 * Linux should not change it at runtime
429 */
430 },
431};
432
433static struct clk_regmap g12a_cpu_clk_trace_div = {
434 .data = &(struct clk_regmap_div_data){
435 .offset = HHI_SYS_CPU_CLK_CNTL1,
436 .shift = 20,
437 .width = 3,
438 .flags = CLK_DIVIDER_POWER_OF_TWO,
439 },
440 .hw.init = &(struct clk_init_data){
441 .name = "cpu_clk_trace_div",
442 .ops = &clk_regmap_divider_ro_ops,
443 .parent_names = (const char *[]){ "cpu_clk" },
444 .num_parents = 1,
445 },
446};
447
448static struct clk_regmap g12a_cpu_clk_trace = {
449 .data = &(struct clk_regmap_gate_data){
450 .offset = HHI_SYS_CPU_CLK_CNTL1,
451 .bit_idx = 23,
452 },
453 .hw.init = &(struct clk_init_data) {
454 .name = "cpu_clk_trace",
455 .ops = &clk_regmap_gate_ro_ops,
456 .parent_names = (const char *[]){ "cpu_clk_trace_div" },
457 .num_parents = 1,
458 /*
459 * This clock is set by the ROM monitor code,
460 * Linux should not change it at runtime
461 */
462 },
463};
464
153static const struct pll_mult_range g12a_gp0_pll_mult_range = { 465static const struct pll_mult_range g12a_gp0_pll_mult_range = {
154 .min = 55, 466 .min = 55,
155 .max = 255, 467 .max = 255,
@@ -302,6 +614,118 @@ static struct clk_regmap g12a_hifi_pll = {
302 }, 614 },
303}; 615};
304 616
617/*
618 * The Meson G12A PCIE PLL is fined tuned to deliver a very precise
619 * 100MHz reference clock for the PCIe Analog PHY, and thus requires
620 * a strict register sequence to enable the PLL.
621 */
622static const struct reg_sequence g12a_pcie_pll_init_regs[] = {
623 { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x20090496 },
624 { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x30090496 },
625 { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x00000000 },
626 { .reg = HHI_PCIE_PLL_CNTL2, .def = 0x00001100 },
627 { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x10058e00 },
628 { .reg = HHI_PCIE_PLL_CNTL4, .def = 0x000100c0 },
629 { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x68000048 },
630 { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x68000068, .delay_us = 20 },
631 { .reg = HHI_PCIE_PLL_CNTL4, .def = 0x008100c0, .delay_us = 10 },
632 { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x34090496 },
633 { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x14090496, .delay_us = 10 },
634 { .reg = HHI_PCIE_PLL_CNTL2, .def = 0x00001000 },
635};
636
637/* Keep a single entry table for recalc/round_rate() ops */
638static const struct pll_params_table g12a_pcie_pll_table[] = {
639 PLL_PARAMS(150, 1),
640 {0, 0},
641};
642
643static struct clk_regmap g12a_pcie_pll_dco = {
644 .data = &(struct meson_clk_pll_data){
645 .en = {
646 .reg_off = HHI_PCIE_PLL_CNTL0,
647 .shift = 28,
648 .width = 1,
649 },
650 .m = {
651 .reg_off = HHI_PCIE_PLL_CNTL0,
652 .shift = 0,
653 .width = 8,
654 },
655 .n = {
656 .reg_off = HHI_PCIE_PLL_CNTL0,
657 .shift = 10,
658 .width = 5,
659 },
660 .frac = {
661 .reg_off = HHI_PCIE_PLL_CNTL1,
662 .shift = 0,
663 .width = 12,
664 },
665 .l = {
666 .reg_off = HHI_PCIE_PLL_CNTL0,
667 .shift = 31,
668 .width = 1,
669 },
670 .rst = {
671 .reg_off = HHI_PCIE_PLL_CNTL0,
672 .shift = 29,
673 .width = 1,
674 },
675 .table = g12a_pcie_pll_table,
676 .init_regs = g12a_pcie_pll_init_regs,
677 .init_count = ARRAY_SIZE(g12a_pcie_pll_init_regs),
678 },
679 .hw.init = &(struct clk_init_data){
680 .name = "pcie_pll_dco",
681 .ops = &meson_clk_pcie_pll_ops,
682 .parent_names = (const char *[]){ IN_PREFIX "xtal" },
683 .num_parents = 1,
684 },
685};
686
687static struct clk_fixed_factor g12a_pcie_pll_dco_div2 = {
688 .mult = 1,
689 .div = 2,
690 .hw.init = &(struct clk_init_data){
691 .name = "pcie_pll_dco_div2",
692 .ops = &clk_fixed_factor_ops,
693 .parent_names = (const char *[]){ "pcie_pll_dco" },
694 .num_parents = 1,
695 .flags = CLK_SET_RATE_PARENT,
696 },
697};
698
699static struct clk_regmap g12a_pcie_pll_od = {
700 .data = &(struct clk_regmap_div_data){
701 .offset = HHI_PCIE_PLL_CNTL0,
702 .shift = 16,
703 .width = 5,
704 .flags = CLK_DIVIDER_ROUND_CLOSEST |
705 CLK_DIVIDER_ONE_BASED |
706 CLK_DIVIDER_ALLOW_ZERO,
707 },
708 .hw.init = &(struct clk_init_data){
709 .name = "pcie_pll_od",
710 .ops = &clk_regmap_divider_ops,
711 .parent_names = (const char *[]){ "pcie_pll_dco_div2" },
712 .num_parents = 1,
713 .flags = CLK_SET_RATE_PARENT,
714 },
715};
716
717static struct clk_fixed_factor g12a_pcie_pll = {
718 .mult = 1,
719 .div = 2,
720 .hw.init = &(struct clk_init_data){
721 .name = "pcie_pll_pll",
722 .ops = &clk_fixed_factor_ops,
723 .parent_names = (const char *[]){ "pcie_pll_od" },
724 .num_parents = 1,
725 .flags = CLK_SET_RATE_PARENT,
726 },
727};
728
305static struct clk_regmap g12a_hdmi_pll_dco = { 729static struct clk_regmap g12a_hdmi_pll_dco = {
306 .data = &(struct meson_clk_pll_data){ 730 .data = &(struct meson_clk_pll_data){
307 .en = { 731 .en = {
@@ -1071,6 +1495,151 @@ static struct clk_regmap g12a_vpu = {
1071 }, 1495 },
1072}; 1496};
1073 1497
1498/* VDEC clocks */
1499
1500static const char * const g12a_vdec_parent_names[] = {
1501 "fclk_div2p5", "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7",
1502 "hifi_pll", "gp0_pll",
1503};
1504
1505static struct clk_regmap g12a_vdec_1_sel = {
1506 .data = &(struct clk_regmap_mux_data){
1507 .offset = HHI_VDEC_CLK_CNTL,
1508 .mask = 0x7,
1509 .shift = 9,
1510 .flags = CLK_MUX_ROUND_CLOSEST,
1511 },
1512 .hw.init = &(struct clk_init_data){
1513 .name = "vdec_1_sel",
1514 .ops = &clk_regmap_mux_ops,
1515 .parent_names = g12a_vdec_parent_names,
1516 .num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
1517 .flags = CLK_SET_RATE_PARENT,
1518 },
1519};
1520
1521static struct clk_regmap g12a_vdec_1_div = {
1522 .data = &(struct clk_regmap_div_data){
1523 .offset = HHI_VDEC_CLK_CNTL,
1524 .shift = 0,
1525 .width = 7,
1526 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1527 },
1528 .hw.init = &(struct clk_init_data){
1529 .name = "vdec_1_div",
1530 .ops = &clk_regmap_divider_ops,
1531 .parent_names = (const char *[]){ "vdec_1_sel" },
1532 .num_parents = 1,
1533 .flags = CLK_SET_RATE_PARENT,
1534 },
1535};
1536
1537static struct clk_regmap g12a_vdec_1 = {
1538 .data = &(struct clk_regmap_gate_data){
1539 .offset = HHI_VDEC_CLK_CNTL,
1540 .bit_idx = 8,
1541 },
1542 .hw.init = &(struct clk_init_data) {
1543 .name = "vdec_1",
1544 .ops = &clk_regmap_gate_ops,
1545 .parent_names = (const char *[]){ "vdec_1_div" },
1546 .num_parents = 1,
1547 .flags = CLK_SET_RATE_PARENT,
1548 },
1549};
1550
1551static struct clk_regmap g12a_vdec_hevcf_sel = {
1552 .data = &(struct clk_regmap_mux_data){
1553 .offset = HHI_VDEC2_CLK_CNTL,
1554 .mask = 0x7,
1555 .shift = 9,
1556 .flags = CLK_MUX_ROUND_CLOSEST,
1557 },
1558 .hw.init = &(struct clk_init_data){
1559 .name = "vdec_hevcf_sel",
1560 .ops = &clk_regmap_mux_ops,
1561 .parent_names = g12a_vdec_parent_names,
1562 .num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
1563 .flags = CLK_SET_RATE_PARENT,
1564 },
1565};
1566
1567static struct clk_regmap g12a_vdec_hevcf_div = {
1568 .data = &(struct clk_regmap_div_data){
1569 .offset = HHI_VDEC2_CLK_CNTL,
1570 .shift = 0,
1571 .width = 7,
1572 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1573 },
1574 .hw.init = &(struct clk_init_data){
1575 .name = "vdec_hevcf_div",
1576 .ops = &clk_regmap_divider_ops,
1577 .parent_names = (const char *[]){ "vdec_hevcf_sel" },
1578 .num_parents = 1,
1579 .flags = CLK_SET_RATE_PARENT,
1580 },
1581};
1582
1583static struct clk_regmap g12a_vdec_hevcf = {
1584 .data = &(struct clk_regmap_gate_data){
1585 .offset = HHI_VDEC2_CLK_CNTL,
1586 .bit_idx = 8,
1587 },
1588 .hw.init = &(struct clk_init_data) {
1589 .name = "vdec_hevcf",
1590 .ops = &clk_regmap_gate_ops,
1591 .parent_names = (const char *[]){ "vdec_hevcf_div" },
1592 .num_parents = 1,
1593 .flags = CLK_SET_RATE_PARENT,
1594 },
1595};
1596
1597static struct clk_regmap g12a_vdec_hevc_sel = {
1598 .data = &(struct clk_regmap_mux_data){
1599 .offset = HHI_VDEC2_CLK_CNTL,
1600 .mask = 0x7,
1601 .shift = 25,
1602 .flags = CLK_MUX_ROUND_CLOSEST,
1603 },
1604 .hw.init = &(struct clk_init_data){
1605 .name = "vdec_hevc_sel",
1606 .ops = &clk_regmap_mux_ops,
1607 .parent_names = g12a_vdec_parent_names,
1608 .num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
1609 .flags = CLK_SET_RATE_PARENT,
1610 },
1611};
1612
1613static struct clk_regmap g12a_vdec_hevc_div = {
1614 .data = &(struct clk_regmap_div_data){
1615 .offset = HHI_VDEC2_CLK_CNTL,
1616 .shift = 16,
1617 .width = 7,
1618 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1619 },
1620 .hw.init = &(struct clk_init_data){
1621 .name = "vdec_hevc_div",
1622 .ops = &clk_regmap_divider_ops,
1623 .parent_names = (const char *[]){ "vdec_hevc_sel" },
1624 .num_parents = 1,
1625 .flags = CLK_SET_RATE_PARENT,
1626 },
1627};
1628
1629static struct clk_regmap g12a_vdec_hevc = {
1630 .data = &(struct clk_regmap_gate_data){
1631 .offset = HHI_VDEC2_CLK_CNTL,
1632 .bit_idx = 24,
1633 },
1634 .hw.init = &(struct clk_init_data) {
1635 .name = "vdec_hevc",
1636 .ops = &clk_regmap_gate_ops,
1637 .parent_names = (const char *[]){ "vdec_hevc_div" },
1638 .num_parents = 1,
1639 .flags = CLK_SET_RATE_PARENT,
1640 },
1641};
1642
1074/* VAPB Clock */ 1643/* VAPB Clock */
1075 1644
1076static const char * const g12a_vapb_parent_names[] = { 1645static const char * const g12a_vapb_parent_names[] = {
@@ -2167,6 +2736,39 @@ static struct clk_hw_onecell_data g12a_hw_onecell_data = {
2167 [CLKID_MALI] = &g12a_mali.hw, 2736 [CLKID_MALI] = &g12a_mali.hw,
2168 [CLKID_MPLL_5OM_DIV] = &g12a_mpll_50m_div.hw, 2737 [CLKID_MPLL_5OM_DIV] = &g12a_mpll_50m_div.hw,
2169 [CLKID_MPLL_5OM] = &g12a_mpll_50m.hw, 2738 [CLKID_MPLL_5OM] = &g12a_mpll_50m.hw,
2739 [CLKID_SYS_PLL_DIV16_EN] = &g12a_sys_pll_div16_en.hw,
2740 [CLKID_SYS_PLL_DIV16] = &g12a_sys_pll_div16.hw,
2741 [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_premux0.hw,
2742 [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_mux0_div.hw,
2743 [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_postmux0.hw,
2744 [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_premux1.hw,
2745 [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_mux1_div.hw,
2746 [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_postmux1.hw,
2747 [CLKID_CPU_CLK_DYN] = &g12a_cpu_clk_dyn.hw,
2748 [CLKID_CPU_CLK] = &g12a_cpu_clk.hw,
2749 [CLKID_CPU_CLK_DIV16_EN] = &g12a_cpu_clk_div16_en.hw,
2750 [CLKID_CPU_CLK_DIV16] = &g12a_cpu_clk_div16.hw,
2751 [CLKID_CPU_CLK_APB_DIV] = &g12a_cpu_clk_apb_div.hw,
2752 [CLKID_CPU_CLK_APB] = &g12a_cpu_clk_apb.hw,
2753 [CLKID_CPU_CLK_ATB_DIV] = &g12a_cpu_clk_atb_div.hw,
2754 [CLKID_CPU_CLK_ATB] = &g12a_cpu_clk_atb.hw,
2755 [CLKID_CPU_CLK_AXI_DIV] = &g12a_cpu_clk_axi_div.hw,
2756 [CLKID_CPU_CLK_AXI] = &g12a_cpu_clk_axi.hw,
2757 [CLKID_CPU_CLK_TRACE_DIV] = &g12a_cpu_clk_trace_div.hw,
2758 [CLKID_CPU_CLK_TRACE] = &g12a_cpu_clk_trace.hw,
2759 [CLKID_PCIE_PLL_DCO] = &g12a_pcie_pll_dco.hw,
2760 [CLKID_PCIE_PLL_DCO_DIV2] = &g12a_pcie_pll_dco_div2.hw,
2761 [CLKID_PCIE_PLL_OD] = &g12a_pcie_pll_od.hw,
2762 [CLKID_PCIE_PLL] = &g12a_pcie_pll.hw,
2763 [CLKID_VDEC_1_SEL] = &g12a_vdec_1_sel.hw,
2764 [CLKID_VDEC_1_DIV] = &g12a_vdec_1_div.hw,
2765 [CLKID_VDEC_1] = &g12a_vdec_1.hw,
2766 [CLKID_VDEC_HEVC_SEL] = &g12a_vdec_hevc_sel.hw,
2767 [CLKID_VDEC_HEVC_DIV] = &g12a_vdec_hevc_div.hw,
2768 [CLKID_VDEC_HEVC] = &g12a_vdec_hevc.hw,
2769 [CLKID_VDEC_HEVCF_SEL] = &g12a_vdec_hevcf_sel.hw,
2770 [CLKID_VDEC_HEVCF_DIV] = &g12a_vdec_hevcf_div.hw,
2771 [CLKID_VDEC_HEVCF] = &g12a_vdec_hevcf.hw,
2170 [NR_CLKS] = NULL, 2772 [NR_CLKS] = NULL,
2171 }, 2773 },
2172 .num = NR_CLKS, 2774 .num = NR_CLKS,
@@ -2335,6 +2937,35 @@ static struct clk_regmap *const g12a_clk_regmaps[] = {
2335 &g12a_mali_1, 2937 &g12a_mali_1,
2336 &g12a_mali, 2938 &g12a_mali,
2337 &g12a_mpll_50m, 2939 &g12a_mpll_50m,
2940 &g12a_sys_pll_div16_en,
2941 &g12a_cpu_clk_premux0,
2942 &g12a_cpu_clk_mux0_div,
2943 &g12a_cpu_clk_postmux0,
2944 &g12a_cpu_clk_premux1,
2945 &g12a_cpu_clk_mux1_div,
2946 &g12a_cpu_clk_postmux1,
2947 &g12a_cpu_clk_dyn,
2948 &g12a_cpu_clk,
2949 &g12a_cpu_clk_div16_en,
2950 &g12a_cpu_clk_apb_div,
2951 &g12a_cpu_clk_apb,
2952 &g12a_cpu_clk_atb_div,
2953 &g12a_cpu_clk_atb,
2954 &g12a_cpu_clk_axi_div,
2955 &g12a_cpu_clk_axi,
2956 &g12a_cpu_clk_trace_div,
2957 &g12a_cpu_clk_trace,
2958 &g12a_pcie_pll_od,
2959 &g12a_pcie_pll_dco,
2960 &g12a_vdec_1_sel,
2961 &g12a_vdec_1_div,
2962 &g12a_vdec_1,
2963 &g12a_vdec_hevc_sel,
2964 &g12a_vdec_hevc_div,
2965 &g12a_vdec_hevc,
2966 &g12a_vdec_hevcf_sel,
2967 &g12a_vdec_hevcf_div,
2968 &g12a_vdec_hevcf,
2338}; 2969};
2339 2970
2340static const struct meson_eeclkc_data g12a_clkc_data = { 2971static const struct meson_eeclkc_data g12a_clkc_data = {
diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h
index f399dfe1401c..39c41af70804 100644
--- a/drivers/clk/meson/g12a.h
+++ b/drivers/clk/meson/g12a.h
@@ -50,6 +50,7 @@
50#define HHI_GCLK_MPEG2 0x148 50#define HHI_GCLK_MPEG2 0x148
51#define HHI_GCLK_OTHER 0x150 51#define HHI_GCLK_OTHER 0x150
52#define HHI_GCLK_OTHER2 0x154 52#define HHI_GCLK_OTHER2 0x154
53#define HHI_SYS_CPU_CLK_CNTL1 0x15c
53#define HHI_VID_CLK_DIV 0x164 54#define HHI_VID_CLK_DIV 0x164
54#define HHI_MPEG_CLK_CNTL 0x174 55#define HHI_MPEG_CLK_CNTL 0x174
55#define HHI_AUD_CLK_CNTL 0x178 56#define HHI_AUD_CLK_CNTL 0x178
@@ -166,8 +167,36 @@
166#define CLKID_MALI_0_DIV 170 167#define CLKID_MALI_0_DIV 170
167#define CLKID_MALI_1_DIV 173 168#define CLKID_MALI_1_DIV 173
168#define CLKID_MPLL_5OM_DIV 176 169#define CLKID_MPLL_5OM_DIV 176
170#define CLKID_SYS_PLL_DIV16_EN 178
171#define CLKID_SYS_PLL_DIV16 179
172#define CLKID_CPU_CLK_DYN0_SEL 180
173#define CLKID_CPU_CLK_DYN0_DIV 181
174#define CLKID_CPU_CLK_DYN0 182
175#define CLKID_CPU_CLK_DYN1_SEL 183
176#define CLKID_CPU_CLK_DYN1_DIV 184
177#define CLKID_CPU_CLK_DYN1 185
178#define CLKID_CPU_CLK_DYN 186
179#define CLKID_CPU_CLK_DIV16_EN 188
180#define CLKID_CPU_CLK_DIV16 189
181#define CLKID_CPU_CLK_APB_DIV 190
182#define CLKID_CPU_CLK_APB 191
183#define CLKID_CPU_CLK_ATB_DIV 192
184#define CLKID_CPU_CLK_ATB 193
185#define CLKID_CPU_CLK_AXI_DIV 194
186#define CLKID_CPU_CLK_AXI 195
187#define CLKID_CPU_CLK_TRACE_DIV 196
188#define CLKID_CPU_CLK_TRACE 197
189#define CLKID_PCIE_PLL_DCO 198
190#define CLKID_PCIE_PLL_DCO_DIV2 199
191#define CLKID_PCIE_PLL_OD 200
192#define CLKID_VDEC_1_SEL 202
193#define CLKID_VDEC_1_DIV 203
194#define CLKID_VDEC_HEVC_SEL 205
195#define CLKID_VDEC_HEVC_DIV 206
196#define CLKID_VDEC_HEVCF_SEL 208
197#define CLKID_VDEC_HEVCF_DIV 209
169 198
170#define NR_CLKS 178 199#define NR_CLKS 211
171 200
172/* include the CLKIDs that have been made part of the DT binding */ 201/* include the CLKIDs that have been made part of the DT binding */
173#include <dt-bindings/clock/g12a-clkc.h> 202#include <dt-bindings/clock/g12a-clkc.h>
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 576ad42252d0..37cf0f01bb5d 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -1703,6 +1703,456 @@ static struct clk_regmap meson8b_mali = {
1703 }, 1703 },
1704}; 1704};
1705 1705
1706static const struct pll_params_table meson8m2_gp_pll_params_table[] = {
1707 PLL_PARAMS(182, 3),
1708 { /* sentinel */ },
1709};
1710
1711static struct clk_regmap meson8m2_gp_pll_dco = {
1712 .data = &(struct meson_clk_pll_data){
1713 .en = {
1714 .reg_off = HHI_GP_PLL_CNTL,
1715 .shift = 30,
1716 .width = 1,
1717 },
1718 .m = {
1719 .reg_off = HHI_GP_PLL_CNTL,
1720 .shift = 0,
1721 .width = 9,
1722 },
1723 .n = {
1724 .reg_off = HHI_GP_PLL_CNTL,
1725 .shift = 9,
1726 .width = 5,
1727 },
1728 .l = {
1729 .reg_off = HHI_GP_PLL_CNTL,
1730 .shift = 31,
1731 .width = 1,
1732 },
1733 .rst = {
1734 .reg_off = HHI_GP_PLL_CNTL,
1735 .shift = 29,
1736 .width = 1,
1737 },
1738 .table = meson8m2_gp_pll_params_table,
1739 },
1740 .hw.init = &(struct clk_init_data){
1741 .name = "gp_pll_dco",
1742 .ops = &meson_clk_pll_ops,
1743 .parent_names = (const char *[]){ "xtal" },
1744 .num_parents = 1,
1745 },
1746};
1747
1748static struct clk_regmap meson8m2_gp_pll = {
1749 .data = &(struct clk_regmap_div_data){
1750 .offset = HHI_GP_PLL_CNTL,
1751 .shift = 16,
1752 .width = 2,
1753 .flags = CLK_DIVIDER_POWER_OF_TWO,
1754 },
1755 .hw.init = &(struct clk_init_data){
1756 .name = "gp_pll",
1757 .ops = &clk_regmap_divider_ops,
1758 .parent_names = (const char *[]){ "gp_pll_dco" },
1759 .num_parents = 1,
1760 .flags = CLK_SET_RATE_PARENT,
1761 },
1762};
1763
1764static const char * const mmeson8b_vpu_0_1_parent_names[] = {
1765 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
1766};
1767
1768static const char * const mmeson8m2_vpu_0_1_parent_names[] = {
1769 "fclk_div4", "fclk_div3", "fclk_div5", "gp_pll"
1770};
1771
1772static struct clk_regmap meson8b_vpu_0_sel = {
1773 .data = &(struct clk_regmap_mux_data){
1774 .offset = HHI_VPU_CLK_CNTL,
1775 .mask = 0x3,
1776 .shift = 9,
1777 },
1778 .hw.init = &(struct clk_init_data){
1779 .name = "vpu_0_sel",
1780 .ops = &clk_regmap_mux_ops,
1781 .parent_names = mmeson8b_vpu_0_1_parent_names,
1782 .num_parents = ARRAY_SIZE(mmeson8b_vpu_0_1_parent_names),
1783 .flags = CLK_SET_RATE_PARENT,
1784 },
1785};
1786
1787static struct clk_regmap meson8m2_vpu_0_sel = {
1788 .data = &(struct clk_regmap_mux_data){
1789 .offset = HHI_VPU_CLK_CNTL,
1790 .mask = 0x3,
1791 .shift = 9,
1792 },
1793 .hw.init = &(struct clk_init_data){
1794 .name = "vpu_0_sel",
1795 .ops = &clk_regmap_mux_ops,
1796 .parent_names = mmeson8m2_vpu_0_1_parent_names,
1797 .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names),
1798 .flags = CLK_SET_RATE_PARENT,
1799 },
1800};
1801
1802static struct clk_regmap meson8b_vpu_0_div = {
1803 .data = &(struct clk_regmap_div_data){
1804 .offset = HHI_VPU_CLK_CNTL,
1805 .shift = 0,
1806 .width = 7,
1807 },
1808 .hw.init = &(struct clk_init_data){
1809 .name = "vpu_0_div",
1810 .ops = &clk_regmap_divider_ops,
1811 .parent_names = (const char *[]){ "vpu_0_sel" },
1812 .num_parents = 1,
1813 .flags = CLK_SET_RATE_PARENT,
1814 },
1815};
1816
1817static struct clk_regmap meson8b_vpu_0 = {
1818 .data = &(struct clk_regmap_gate_data){
1819 .offset = HHI_VPU_CLK_CNTL,
1820 .bit_idx = 8,
1821 },
1822 .hw.init = &(struct clk_init_data) {
1823 .name = "vpu_0",
1824 .ops = &clk_regmap_gate_ops,
1825 .parent_names = (const char *[]){ "vpu_0_div" },
1826 .num_parents = 1,
1827 .flags = CLK_SET_RATE_PARENT,
1828 },
1829};
1830
1831static struct clk_regmap meson8b_vpu_1_sel = {
1832 .data = &(struct clk_regmap_mux_data){
1833 .offset = HHI_VPU_CLK_CNTL,
1834 .mask = 0x3,
1835 .shift = 25,
1836 },
1837 .hw.init = &(struct clk_init_data){
1838 .name = "vpu_1_sel",
1839 .ops = &clk_regmap_mux_ops,
1840 .parent_names = mmeson8b_vpu_0_1_parent_names,
1841 .num_parents = ARRAY_SIZE(mmeson8b_vpu_0_1_parent_names),
1842 .flags = CLK_SET_RATE_PARENT,
1843 },
1844};
1845
1846static struct clk_regmap meson8m2_vpu_1_sel = {
1847 .data = &(struct clk_regmap_mux_data){
1848 .offset = HHI_VPU_CLK_CNTL,
1849 .mask = 0x3,
1850 .shift = 25,
1851 },
1852 .hw.init = &(struct clk_init_data){
1853 .name = "vpu_1_sel",
1854 .ops = &clk_regmap_mux_ops,
1855 .parent_names = mmeson8m2_vpu_0_1_parent_names,
1856 .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names),
1857 .flags = CLK_SET_RATE_PARENT,
1858 },
1859};
1860
1861static struct clk_regmap meson8b_vpu_1_div = {
1862 .data = &(struct clk_regmap_div_data){
1863 .offset = HHI_VPU_CLK_CNTL,
1864 .shift = 16,
1865 .width = 7,
1866 },
1867 .hw.init = &(struct clk_init_data){
1868 .name = "vpu_1_div",
1869 .ops = &clk_regmap_divider_ops,
1870 .parent_names = (const char *[]){ "vpu_1_sel" },
1871 .num_parents = 1,
1872 .flags = CLK_SET_RATE_PARENT,
1873 },
1874};
1875
1876static struct clk_regmap meson8b_vpu_1 = {
1877 .data = &(struct clk_regmap_gate_data){
1878 .offset = HHI_VPU_CLK_CNTL,
1879 .bit_idx = 24,
1880 },
1881 .hw.init = &(struct clk_init_data) {
1882 .name = "vpu_1",
1883 .ops = &clk_regmap_gate_ops,
1884 .parent_names = (const char *[]){ "vpu_1_div" },
1885 .num_parents = 1,
1886 .flags = CLK_SET_RATE_PARENT,
1887 },
1888};
1889
1890static struct clk_regmap meson8b_vpu = {
1891 .data = &(struct clk_regmap_mux_data){
1892 .offset = HHI_VPU_CLK_CNTL,
1893 .mask = 1,
1894 .shift = 31,
1895 },
1896 .hw.init = &(struct clk_init_data){
1897 .name = "vpu",
1898 .ops = &clk_regmap_mux_ops,
1899 .parent_names = (const char *[]){ "vpu_0", "vpu_1" },
1900 .num_parents = 2,
1901 .flags = CLK_SET_RATE_NO_REPARENT,
1902 },
1903};
1904
1905static const char * const meson8b_vdec_parent_names[] = {
1906 "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "mpll2", "mpll1"
1907};
1908
1909static struct clk_regmap meson8b_vdec_1_sel = {
1910 .data = &(struct clk_regmap_mux_data){
1911 .offset = HHI_VDEC_CLK_CNTL,
1912 .mask = 0x3,
1913 .shift = 9,
1914 .flags = CLK_MUX_ROUND_CLOSEST,
1915 },
1916 .hw.init = &(struct clk_init_data){
1917 .name = "vdec_1_sel",
1918 .ops = &clk_regmap_mux_ops,
1919 .parent_names = meson8b_vdec_parent_names,
1920 .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
1921 .flags = CLK_SET_RATE_PARENT,
1922 },
1923};
1924
1925static struct clk_regmap meson8b_vdec_1_1_div = {
1926 .data = &(struct clk_regmap_div_data){
1927 .offset = HHI_VDEC_CLK_CNTL,
1928 .shift = 0,
1929 .width = 7,
1930 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1931 },
1932 .hw.init = &(struct clk_init_data){
1933 .name = "vdec_1_1_div",
1934 .ops = &clk_regmap_divider_ops,
1935 .parent_names = (const char *[]){ "vdec_1_sel" },
1936 .num_parents = 1,
1937 .flags = CLK_SET_RATE_PARENT,
1938 },
1939};
1940
1941static struct clk_regmap meson8b_vdec_1_1 = {
1942 .data = &(struct clk_regmap_gate_data){
1943 .offset = HHI_VDEC_CLK_CNTL,
1944 .bit_idx = 8,
1945 },
1946 .hw.init = &(struct clk_init_data) {
1947 .name = "vdec_1_1",
1948 .ops = &clk_regmap_gate_ops,
1949 .parent_names = (const char *[]){ "vdec_1_1_div" },
1950 .num_parents = 1,
1951 .flags = CLK_SET_RATE_PARENT,
1952 },
1953};
1954
1955static struct clk_regmap meson8b_vdec_1_2_div = {
1956 .data = &(struct clk_regmap_div_data){
1957 .offset = HHI_VDEC3_CLK_CNTL,
1958 .shift = 0,
1959 .width = 7,
1960 .flags = CLK_DIVIDER_ROUND_CLOSEST,
1961 },
1962 .hw.init = &(struct clk_init_data){
1963 .name = "vdec_1_2_div",
1964 .ops = &clk_regmap_divider_ops,
1965 .parent_names = (const char *[]){ "vdec_1_sel" },
1966 .num_parents = 1,
1967 .flags = CLK_SET_RATE_PARENT,
1968 },
1969};
1970
1971static struct clk_regmap meson8b_vdec_1_2 = {
1972 .data = &(struct clk_regmap_gate_data){
1973 .offset = HHI_VDEC3_CLK_CNTL,
1974 .bit_idx = 8,
1975 },
1976 .hw.init = &(struct clk_init_data) {
1977 .name = "vdec_1_2",
1978 .ops = &clk_regmap_gate_ops,
1979 .parent_names = (const char *[]){ "vdec_1_2_div" },
1980 .num_parents = 1,
1981 .flags = CLK_SET_RATE_PARENT,
1982 },
1983};
1984
1985static struct clk_regmap meson8b_vdec_1 = {
1986 .data = &(struct clk_regmap_mux_data){
1987 .offset = HHI_VDEC3_CLK_CNTL,
1988 .mask = 0x1,
1989 .shift = 15,
1990 .flags = CLK_MUX_ROUND_CLOSEST,
1991 },
1992 .hw.init = &(struct clk_init_data){
1993 .name = "vdec_1",
1994 .ops = &clk_regmap_mux_ops,
1995 .parent_names = (const char *[]){ "vdec_1_1", "vdec_1_2" },
1996 .num_parents = 2,
1997 .flags = CLK_SET_RATE_PARENT,
1998 },
1999};
2000
2001static struct clk_regmap meson8b_vdec_hcodec_sel = {
2002 .data = &(struct clk_regmap_mux_data){
2003 .offset = HHI_VDEC_CLK_CNTL,
2004 .mask = 0x3,
2005 .shift = 25,
2006 .flags = CLK_MUX_ROUND_CLOSEST,
2007 },
2008 .hw.init = &(struct clk_init_data){
2009 .name = "vdec_hcodec_sel",
2010 .ops = &clk_regmap_mux_ops,
2011 .parent_names = meson8b_vdec_parent_names,
2012 .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
2013 .flags = CLK_SET_RATE_PARENT,
2014 },
2015};
2016
2017static struct clk_regmap meson8b_vdec_hcodec_div = {
2018 .data = &(struct clk_regmap_div_data){
2019 .offset = HHI_VDEC_CLK_CNTL,
2020 .shift = 16,
2021 .width = 7,
2022 .flags = CLK_DIVIDER_ROUND_CLOSEST,
2023 },
2024 .hw.init = &(struct clk_init_data){
2025 .name = "vdec_hcodec_div",
2026 .ops = &clk_regmap_divider_ops,
2027 .parent_names = (const char *[]){ "vdec_hcodec_sel" },
2028 .num_parents = 1,
2029 .flags = CLK_SET_RATE_PARENT,
2030 },
2031};
2032
2033static struct clk_regmap meson8b_vdec_hcodec = {
2034 .data = &(struct clk_regmap_gate_data){
2035 .offset = HHI_VDEC_CLK_CNTL,
2036 .bit_idx = 24,
2037 },
2038 .hw.init = &(struct clk_init_data) {
2039 .name = "vdec_hcodec",
2040 .ops = &clk_regmap_gate_ops,
2041 .parent_names = (const char *[]){ "vdec_hcodec_div" },
2042 .num_parents = 1,
2043 .flags = CLK_SET_RATE_PARENT,
2044 },
2045};
2046
2047static struct clk_regmap meson8b_vdec_2_sel = {
2048 .data = &(struct clk_regmap_mux_data){
2049 .offset = HHI_VDEC2_CLK_CNTL,
2050 .mask = 0x3,
2051 .shift = 9,
2052 .flags = CLK_MUX_ROUND_CLOSEST,
2053 },
2054 .hw.init = &(struct clk_init_data){
2055 .name = "vdec_2_sel",
2056 .ops = &clk_regmap_mux_ops,
2057 .parent_names = meson8b_vdec_parent_names,
2058 .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
2059 .flags = CLK_SET_RATE_PARENT,
2060 },
2061};
2062
2063static struct clk_regmap meson8b_vdec_2_div = {
2064 .data = &(struct clk_regmap_div_data){
2065 .offset = HHI_VDEC2_CLK_CNTL,
2066 .shift = 0,
2067 .width = 7,
2068 .flags = CLK_DIVIDER_ROUND_CLOSEST,
2069 },
2070 .hw.init = &(struct clk_init_data){
2071 .name = "vdec_2_div",
2072 .ops = &clk_regmap_divider_ops,
2073 .parent_names = (const char *[]){ "vdec_2_sel" },
2074 .num_parents = 1,
2075 .flags = CLK_SET_RATE_PARENT,
2076 },
2077};
2078
2079static struct clk_regmap meson8b_vdec_2 = {
2080 .data = &(struct clk_regmap_gate_data){
2081 .offset = HHI_VDEC2_CLK_CNTL,
2082 .bit_idx = 8,
2083 },
2084 .hw.init = &(struct clk_init_data) {
2085 .name = "vdec_2",
2086 .ops = &clk_regmap_gate_ops,
2087 .parent_names = (const char *[]){ "vdec_2_div" },
2088 .num_parents = 1,
2089 .flags = CLK_SET_RATE_PARENT,
2090 },
2091};
2092
2093static struct clk_regmap meson8b_vdec_hevc_sel = {
2094 .data = &(struct clk_regmap_mux_data){
2095 .offset = HHI_VDEC2_CLK_CNTL,
2096 .mask = 0x3,
2097 .shift = 25,
2098 .flags = CLK_MUX_ROUND_CLOSEST,
2099 },
2100 .hw.init = &(struct clk_init_data){
2101 .name = "vdec_hevc_sel",
2102 .ops = &clk_regmap_mux_ops,
2103 .parent_names = meson8b_vdec_parent_names,
2104 .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
2105 .flags = CLK_SET_RATE_PARENT,
2106 },
2107};
2108
2109static struct clk_regmap meson8b_vdec_hevc_div = {
2110 .data = &(struct clk_regmap_div_data){
2111 .offset = HHI_VDEC2_CLK_CNTL,
2112 .shift = 16,
2113 .width = 7,
2114 .flags = CLK_DIVIDER_ROUND_CLOSEST,
2115 },
2116 .hw.init = &(struct clk_init_data){
2117 .name = "vdec_hevc_div",
2118 .ops = &clk_regmap_divider_ops,
2119 .parent_names = (const char *[]){ "vdec_hevc_sel" },
2120 .num_parents = 1,
2121 .flags = CLK_SET_RATE_PARENT,
2122 },
2123};
2124
2125static struct clk_regmap meson8b_vdec_hevc_en = {
2126 .data = &(struct clk_regmap_gate_data){
2127 .offset = HHI_VDEC2_CLK_CNTL,
2128 .bit_idx = 24,
2129 },
2130 .hw.init = &(struct clk_init_data) {
2131 .name = "vdec_hevc_en",
2132 .ops = &clk_regmap_gate_ops,
2133 .parent_names = (const char *[]){ "vdec_hevc_div" },
2134 .num_parents = 1,
2135 .flags = CLK_SET_RATE_PARENT,
2136 },
2137};
2138
2139static struct clk_regmap meson8b_vdec_hevc = {
2140 .data = &(struct clk_regmap_mux_data){
2141 .offset = HHI_VDEC2_CLK_CNTL,
2142 .mask = 0x1,
2143 .shift = 31,
2144 .flags = CLK_MUX_ROUND_CLOSEST,
2145 },
2146 .hw.init = &(struct clk_init_data){
2147 .name = "vdec_hevc",
2148 .ops = &clk_regmap_mux_ops,
2149 /* TODO: The second parent is currently unknown */
2150 .parent_names = (const char *[]){ "vdec_hevc_en" },
2151 .num_parents = 1,
2152 .flags = CLK_SET_RATE_PARENT,
2153 },
2154};
2155
1706/* Everything Else (EE) domain gates */ 2156/* Everything Else (EE) domain gates */
1707 2157
1708static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); 2158static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
@@ -1966,6 +2416,22 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = {
1966 [CLKID_MALI_0_SEL] = &meson8b_mali_0_sel.hw, 2416 [CLKID_MALI_0_SEL] = &meson8b_mali_0_sel.hw,
1967 [CLKID_MALI_0_DIV] = &meson8b_mali_0_div.hw, 2417 [CLKID_MALI_0_DIV] = &meson8b_mali_0_div.hw,
1968 [CLKID_MALI] = &meson8b_mali_0.hw, 2418 [CLKID_MALI] = &meson8b_mali_0.hw,
2419 [CLKID_VPU_0_SEL] = &meson8b_vpu_0_sel.hw,
2420 [CLKID_VPU_0_DIV] = &meson8b_vpu_0_div.hw,
2421 [CLKID_VPU] = &meson8b_vpu_0.hw,
2422 [CLKID_VDEC_1_SEL] = &meson8b_vdec_1_sel.hw,
2423 [CLKID_VDEC_1_1_DIV] = &meson8b_vdec_1_1_div.hw,
2424 [CLKID_VDEC_1] = &meson8b_vdec_1_1.hw,
2425 [CLKID_VDEC_HCODEC_SEL] = &meson8b_vdec_hcodec_sel.hw,
2426 [CLKID_VDEC_HCODEC_DIV] = &meson8b_vdec_hcodec_div.hw,
2427 [CLKID_VDEC_HCODEC] = &meson8b_vdec_hcodec.hw,
2428 [CLKID_VDEC_2_SEL] = &meson8b_vdec_2_sel.hw,
2429 [CLKID_VDEC_2_DIV] = &meson8b_vdec_2_div.hw,
2430 [CLKID_VDEC_2] = &meson8b_vdec_2.hw,
2431 [CLKID_VDEC_HEVC_SEL] = &meson8b_vdec_hevc_sel.hw,
2432 [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw,
2433 [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw,
2434 [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw,
1969 [CLK_NR_CLKS] = NULL, 2435 [CLK_NR_CLKS] = NULL,
1970 }, 2436 },
1971 .num = CLK_NR_CLKS, 2437 .num = CLK_NR_CLKS,
@@ -2152,6 +2618,240 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
2152 [CLKID_MALI_1_DIV] = &meson8b_mali_1_div.hw, 2618 [CLKID_MALI_1_DIV] = &meson8b_mali_1_div.hw,
2153 [CLKID_MALI_1] = &meson8b_mali_1.hw, 2619 [CLKID_MALI_1] = &meson8b_mali_1.hw,
2154 [CLKID_MALI] = &meson8b_mali.hw, 2620 [CLKID_MALI] = &meson8b_mali.hw,
2621 [CLKID_VPU_0_SEL] = &meson8b_vpu_0_sel.hw,
2622 [CLKID_VPU_0_DIV] = &meson8b_vpu_0_div.hw,
2623 [CLKID_VPU_0] = &meson8b_vpu_0.hw,
2624 [CLKID_VPU_1_SEL] = &meson8b_vpu_1_sel.hw,
2625 [CLKID_VPU_1_DIV] = &meson8b_vpu_1_div.hw,
2626 [CLKID_VPU_1] = &meson8b_vpu_1.hw,
2627 [CLKID_VPU] = &meson8b_vpu.hw,
2628 [CLKID_VDEC_1_SEL] = &meson8b_vdec_1_sel.hw,
2629 [CLKID_VDEC_1_1_DIV] = &meson8b_vdec_1_1_div.hw,
2630 [CLKID_VDEC_1_1] = &meson8b_vdec_1_1.hw,
2631 [CLKID_VDEC_1_2_DIV] = &meson8b_vdec_1_2_div.hw,
2632 [CLKID_VDEC_1_2] = &meson8b_vdec_1_2.hw,
2633 [CLKID_VDEC_1] = &meson8b_vdec_1.hw,
2634 [CLKID_VDEC_HCODEC_SEL] = &meson8b_vdec_hcodec_sel.hw,
2635 [CLKID_VDEC_HCODEC_DIV] = &meson8b_vdec_hcodec_div.hw,
2636 [CLKID_VDEC_HCODEC] = &meson8b_vdec_hcodec.hw,
2637 [CLKID_VDEC_2_SEL] = &meson8b_vdec_2_sel.hw,
2638 [CLKID_VDEC_2_DIV] = &meson8b_vdec_2_div.hw,
2639 [CLKID_VDEC_2] = &meson8b_vdec_2.hw,
2640 [CLKID_VDEC_HEVC_SEL] = &meson8b_vdec_hevc_sel.hw,
2641 [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw,
2642 [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw,
2643 [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw,
2644 [CLK_NR_CLKS] = NULL,
2645 },
2646 .num = CLK_NR_CLKS,
2647};
2648
2649static struct clk_hw_onecell_data meson8m2_hw_onecell_data = {
2650 .hws = {
2651 [CLKID_XTAL] = &meson8b_xtal.hw,
2652 [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
2653 [CLKID_PLL_VID] = &meson8b_vid_pll.hw,
2654 [CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
2655 [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
2656 [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
2657 [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
2658 [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
2659 [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
2660 [CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
2661 [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
2662 [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
2663 [CLKID_CLK81] = &meson8b_clk81.hw,
2664 [CLKID_DDR] = &meson8b_ddr.hw,
2665 [CLKID_DOS] = &meson8b_dos.hw,
2666 [CLKID_ISA] = &meson8b_isa.hw,
2667 [CLKID_PL301] = &meson8b_pl301.hw,
2668 [CLKID_PERIPHS] = &meson8b_periphs.hw,
2669 [CLKID_SPICC] = &meson8b_spicc.hw,
2670 [CLKID_I2C] = &meson8b_i2c.hw,
2671 [CLKID_SAR_ADC] = &meson8b_sar_adc.hw,
2672 [CLKID_SMART_CARD] = &meson8b_smart_card.hw,
2673 [CLKID_RNG0] = &meson8b_rng0.hw,
2674 [CLKID_UART0] = &meson8b_uart0.hw,
2675 [CLKID_SDHC] = &meson8b_sdhc.hw,
2676 [CLKID_STREAM] = &meson8b_stream.hw,
2677 [CLKID_ASYNC_FIFO] = &meson8b_async_fifo.hw,
2678 [CLKID_SDIO] = &meson8b_sdio.hw,
2679 [CLKID_ABUF] = &meson8b_abuf.hw,
2680 [CLKID_HIU_IFACE] = &meson8b_hiu_iface.hw,
2681 [CLKID_ASSIST_MISC] = &meson8b_assist_misc.hw,
2682 [CLKID_SPI] = &meson8b_spi.hw,
2683 [CLKID_I2S_SPDIF] = &meson8b_i2s_spdif.hw,
2684 [CLKID_ETH] = &meson8b_eth.hw,
2685 [CLKID_DEMUX] = &meson8b_demux.hw,
2686 [CLKID_AIU_GLUE] = &meson8b_aiu_glue.hw,
2687 [CLKID_IEC958] = &meson8b_iec958.hw,
2688 [CLKID_I2S_OUT] = &meson8b_i2s_out.hw,
2689 [CLKID_AMCLK] = &meson8b_amclk.hw,
2690 [CLKID_AIFIFO2] = &meson8b_aififo2.hw,
2691 [CLKID_MIXER] = &meson8b_mixer.hw,
2692 [CLKID_MIXER_IFACE] = &meson8b_mixer_iface.hw,
2693 [CLKID_ADC] = &meson8b_adc.hw,
2694 [CLKID_BLKMV] = &meson8b_blkmv.hw,
2695 [CLKID_AIU] = &meson8b_aiu.hw,
2696 [CLKID_UART1] = &meson8b_uart1.hw,
2697 [CLKID_G2D] = &meson8b_g2d.hw,
2698 [CLKID_USB0] = &meson8b_usb0.hw,
2699 [CLKID_USB1] = &meson8b_usb1.hw,
2700 [CLKID_RESET] = &meson8b_reset.hw,
2701 [CLKID_NAND] = &meson8b_nand.hw,
2702 [CLKID_DOS_PARSER] = &meson8b_dos_parser.hw,
2703 [CLKID_USB] = &meson8b_usb.hw,
2704 [CLKID_VDIN1] = &meson8b_vdin1.hw,
2705 [CLKID_AHB_ARB0] = &meson8b_ahb_arb0.hw,
2706 [CLKID_EFUSE] = &meson8b_efuse.hw,
2707 [CLKID_BOOT_ROM] = &meson8b_boot_rom.hw,
2708 [CLKID_AHB_DATA_BUS] = &meson8b_ahb_data_bus.hw,
2709 [CLKID_AHB_CTRL_BUS] = &meson8b_ahb_ctrl_bus.hw,
2710 [CLKID_HDMI_INTR_SYNC] = &meson8b_hdmi_intr_sync.hw,
2711 [CLKID_HDMI_PCLK] = &meson8b_hdmi_pclk.hw,
2712 [CLKID_USB1_DDR_BRIDGE] = &meson8b_usb1_ddr_bridge.hw,
2713 [CLKID_USB0_DDR_BRIDGE] = &meson8b_usb0_ddr_bridge.hw,
2714 [CLKID_MMC_PCLK] = &meson8b_mmc_pclk.hw,
2715 [CLKID_DVIN] = &meson8b_dvin.hw,
2716 [CLKID_UART2] = &meson8b_uart2.hw,
2717 [CLKID_SANA] = &meson8b_sana.hw,
2718 [CLKID_VPU_INTR] = &meson8b_vpu_intr.hw,
2719 [CLKID_SEC_AHB_AHB3_BRIDGE] = &meson8b_sec_ahb_ahb3_bridge.hw,
2720 [CLKID_CLK81_A9] = &meson8b_clk81_a9.hw,
2721 [CLKID_VCLK2_VENCI0] = &meson8b_vclk2_venci0.hw,
2722 [CLKID_VCLK2_VENCI1] = &meson8b_vclk2_venci1.hw,
2723 [CLKID_VCLK2_VENCP0] = &meson8b_vclk2_vencp0.hw,
2724 [CLKID_VCLK2_VENCP1] = &meson8b_vclk2_vencp1.hw,
2725 [CLKID_GCLK_VENCI_INT] = &meson8b_gclk_venci_int.hw,
2726 [CLKID_GCLK_VENCP_INT] = &meson8b_gclk_vencp_int.hw,
2727 [CLKID_DAC_CLK] = &meson8b_dac_clk.hw,
2728 [CLKID_AOCLK_GATE] = &meson8b_aoclk_gate.hw,
2729 [CLKID_IEC958_GATE] = &meson8b_iec958_gate.hw,
2730 [CLKID_ENC480P] = &meson8b_enc480p.hw,
2731 [CLKID_RNG1] = &meson8b_rng1.hw,
2732 [CLKID_GCLK_VENCL_INT] = &meson8b_gclk_vencl_int.hw,
2733 [CLKID_VCLK2_VENCLMCC] = &meson8b_vclk2_venclmcc.hw,
2734 [CLKID_VCLK2_VENCL] = &meson8b_vclk2_vencl.hw,
2735 [CLKID_VCLK2_OTHER] = &meson8b_vclk2_other.hw,
2736 [CLKID_EDP] = &meson8b_edp.hw,
2737 [CLKID_AO_MEDIA_CPU] = &meson8b_ao_media_cpu.hw,
2738 [CLKID_AO_AHB_SRAM] = &meson8b_ao_ahb_sram.hw,
2739 [CLKID_AO_AHB_BUS] = &meson8b_ao_ahb_bus.hw,
2740 [CLKID_AO_IFACE] = &meson8b_ao_iface.hw,
2741 [CLKID_MPLL0] = &meson8b_mpll0.hw,
2742 [CLKID_MPLL1] = &meson8b_mpll1.hw,
2743 [CLKID_MPLL2] = &meson8b_mpll2.hw,
2744 [CLKID_MPLL0_DIV] = &meson8b_mpll0_div.hw,
2745 [CLKID_MPLL1_DIV] = &meson8b_mpll1_div.hw,
2746 [CLKID_MPLL2_DIV] = &meson8b_mpll2_div.hw,
2747 [CLKID_CPU_IN_SEL] = &meson8b_cpu_in_sel.hw,
2748 [CLKID_CPU_IN_DIV2] = &meson8b_cpu_in_div2.hw,
2749 [CLKID_CPU_IN_DIV3] = &meson8b_cpu_in_div3.hw,
2750 [CLKID_CPU_SCALE_DIV] = &meson8b_cpu_scale_div.hw,
2751 [CLKID_CPU_SCALE_OUT_SEL] = &meson8b_cpu_scale_out_sel.hw,
2752 [CLKID_MPLL_PREDIV] = &meson8b_mpll_prediv.hw,
2753 [CLKID_FCLK_DIV2_DIV] = &meson8b_fclk_div2_div.hw,
2754 [CLKID_FCLK_DIV3_DIV] = &meson8b_fclk_div3_div.hw,
2755 [CLKID_FCLK_DIV4_DIV] = &meson8b_fclk_div4_div.hw,
2756 [CLKID_FCLK_DIV5_DIV] = &meson8b_fclk_div5_div.hw,
2757 [CLKID_FCLK_DIV7_DIV] = &meson8b_fclk_div7_div.hw,
2758 [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw,
2759 [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw,
2760 [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw,
2761 [CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw,
2762 [CLKID_HDMI_PLL_DCO] = &meson8b_hdmi_pll_dco.hw,
2763 [CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw,
2764 [CLKID_CPU_CLK_DIV2] = &meson8b_cpu_clk_div2.hw,
2765 [CLKID_CPU_CLK_DIV3] = &meson8b_cpu_clk_div3.hw,
2766 [CLKID_CPU_CLK_DIV4] = &meson8b_cpu_clk_div4.hw,
2767 [CLKID_CPU_CLK_DIV5] = &meson8b_cpu_clk_div5.hw,
2768 [CLKID_CPU_CLK_DIV6] = &meson8b_cpu_clk_div6.hw,
2769 [CLKID_CPU_CLK_DIV7] = &meson8b_cpu_clk_div7.hw,
2770 [CLKID_CPU_CLK_DIV8] = &meson8b_cpu_clk_div8.hw,
2771 [CLKID_APB_SEL] = &meson8b_apb_clk_sel.hw,
2772 [CLKID_APB] = &meson8b_apb_clk_gate.hw,
2773 [CLKID_PERIPH_SEL] = &meson8b_periph_clk_sel.hw,
2774 [CLKID_PERIPH] = &meson8b_periph_clk_gate.hw,
2775 [CLKID_AXI_SEL] = &meson8b_axi_clk_sel.hw,
2776 [CLKID_AXI] = &meson8b_axi_clk_gate.hw,
2777 [CLKID_L2_DRAM_SEL] = &meson8b_l2_dram_clk_sel.hw,
2778 [CLKID_L2_DRAM] = &meson8b_l2_dram_clk_gate.hw,
2779 [CLKID_HDMI_PLL_LVDS_OUT] = &meson8b_hdmi_pll_lvds_out.hw,
2780 [CLKID_HDMI_PLL_HDMI_OUT] = &meson8b_hdmi_pll_hdmi_out.hw,
2781 [CLKID_VID_PLL_IN_SEL] = &meson8b_vid_pll_in_sel.hw,
2782 [CLKID_VID_PLL_IN_EN] = &meson8b_vid_pll_in_en.hw,
2783 [CLKID_VID_PLL_PRE_DIV] = &meson8b_vid_pll_pre_div.hw,
2784 [CLKID_VID_PLL_POST_DIV] = &meson8b_vid_pll_post_div.hw,
2785 [CLKID_VID_PLL_FINAL_DIV] = &meson8b_vid_pll_final_div.hw,
2786 [CLKID_VCLK_IN_SEL] = &meson8b_vclk_in_sel.hw,
2787 [CLKID_VCLK_IN_EN] = &meson8b_vclk_in_en.hw,
2788 [CLKID_VCLK_DIV1] = &meson8b_vclk_div1_gate.hw,
2789 [CLKID_VCLK_DIV2_DIV] = &meson8b_vclk_div2_div.hw,
2790 [CLKID_VCLK_DIV2] = &meson8b_vclk_div2_div_gate.hw,
2791 [CLKID_VCLK_DIV4_DIV] = &meson8b_vclk_div4_div.hw,
2792 [CLKID_VCLK_DIV4] = &meson8b_vclk_div4_div_gate.hw,
2793 [CLKID_VCLK_DIV6_DIV] = &meson8b_vclk_div6_div.hw,
2794 [CLKID_VCLK_DIV6] = &meson8b_vclk_div6_div_gate.hw,
2795 [CLKID_VCLK_DIV12_DIV] = &meson8b_vclk_div12_div.hw,
2796 [CLKID_VCLK_DIV12] = &meson8b_vclk_div12_div_gate.hw,
2797 [CLKID_VCLK2_IN_SEL] = &meson8b_vclk2_in_sel.hw,
2798 [CLKID_VCLK2_IN_EN] = &meson8b_vclk2_clk_in_en.hw,
2799 [CLKID_VCLK2_DIV1] = &meson8b_vclk2_div1_gate.hw,
2800 [CLKID_VCLK2_DIV2_DIV] = &meson8b_vclk2_div2_div.hw,
2801 [CLKID_VCLK2_DIV2] = &meson8b_vclk2_div2_div_gate.hw,
2802 [CLKID_VCLK2_DIV4_DIV] = &meson8b_vclk2_div4_div.hw,
2803 [CLKID_VCLK2_DIV4] = &meson8b_vclk2_div4_div_gate.hw,
2804 [CLKID_VCLK2_DIV6_DIV] = &meson8b_vclk2_div6_div.hw,
2805 [CLKID_VCLK2_DIV6] = &meson8b_vclk2_div6_div_gate.hw,
2806 [CLKID_VCLK2_DIV12_DIV] = &meson8b_vclk2_div12_div.hw,
2807 [CLKID_VCLK2_DIV12] = &meson8b_vclk2_div12_div_gate.hw,
2808 [CLKID_CTS_ENCT_SEL] = &meson8b_cts_enct_sel.hw,
2809 [CLKID_CTS_ENCT] = &meson8b_cts_enct.hw,
2810 [CLKID_CTS_ENCP_SEL] = &meson8b_cts_encp_sel.hw,
2811 [CLKID_CTS_ENCP] = &meson8b_cts_encp.hw,
2812 [CLKID_CTS_ENCI_SEL] = &meson8b_cts_enci_sel.hw,
2813 [CLKID_CTS_ENCI] = &meson8b_cts_enci.hw,
2814 [CLKID_HDMI_TX_PIXEL_SEL] = &meson8b_hdmi_tx_pixel_sel.hw,
2815 [CLKID_HDMI_TX_PIXEL] = &meson8b_hdmi_tx_pixel.hw,
2816 [CLKID_CTS_ENCL_SEL] = &meson8b_cts_encl_sel.hw,
2817 [CLKID_CTS_ENCL] = &meson8b_cts_encl.hw,
2818 [CLKID_CTS_VDAC0_SEL] = &meson8b_cts_vdac0_sel.hw,
2819 [CLKID_CTS_VDAC0] = &meson8b_cts_vdac0.hw,
2820 [CLKID_HDMI_SYS_SEL] = &meson8b_hdmi_sys_sel.hw,
2821 [CLKID_HDMI_SYS_DIV] = &meson8b_hdmi_sys_div.hw,
2822 [CLKID_HDMI_SYS] = &meson8b_hdmi_sys.hw,
2823 [CLKID_MALI_0_SEL] = &meson8b_mali_0_sel.hw,
2824 [CLKID_MALI_0_DIV] = &meson8b_mali_0_div.hw,
2825 [CLKID_MALI_0] = &meson8b_mali_0.hw,
2826 [CLKID_MALI_1_SEL] = &meson8b_mali_1_sel.hw,
2827 [CLKID_MALI_1_DIV] = &meson8b_mali_1_div.hw,
2828 [CLKID_MALI_1] = &meson8b_mali_1.hw,
2829 [CLKID_MALI] = &meson8b_mali.hw,
2830 [CLKID_GP_PLL_DCO] = &meson8m2_gp_pll_dco.hw,
2831 [CLKID_GP_PLL] = &meson8m2_gp_pll.hw,
2832 [CLKID_VPU_0_SEL] = &meson8m2_vpu_0_sel.hw,
2833 [CLKID_VPU_0_DIV] = &meson8b_vpu_0_div.hw,
2834 [CLKID_VPU_0] = &meson8b_vpu_0.hw,
2835 [CLKID_VPU_1_SEL] = &meson8m2_vpu_1_sel.hw,
2836 [CLKID_VPU_1_DIV] = &meson8b_vpu_1_div.hw,
2837 [CLKID_VPU_1] = &meson8b_vpu_1.hw,
2838 [CLKID_VPU] = &meson8b_vpu.hw,
2839 [CLKID_VDEC_1_SEL] = &meson8b_vdec_1_sel.hw,
2840 [CLKID_VDEC_1_1_DIV] = &meson8b_vdec_1_1_div.hw,
2841 [CLKID_VDEC_1_1] = &meson8b_vdec_1_1.hw,
2842 [CLKID_VDEC_1_2_DIV] = &meson8b_vdec_1_2_div.hw,
2843 [CLKID_VDEC_1_2] = &meson8b_vdec_1_2.hw,
2844 [CLKID_VDEC_1] = &meson8b_vdec_1.hw,
2845 [CLKID_VDEC_HCODEC_SEL] = &meson8b_vdec_hcodec_sel.hw,
2846 [CLKID_VDEC_HCODEC_DIV] = &meson8b_vdec_hcodec_div.hw,
2847 [CLKID_VDEC_HCODEC] = &meson8b_vdec_hcodec.hw,
2848 [CLKID_VDEC_2_SEL] = &meson8b_vdec_2_sel.hw,
2849 [CLKID_VDEC_2_DIV] = &meson8b_vdec_2_div.hw,
2850 [CLKID_VDEC_2] = &meson8b_vdec_2.hw,
2851 [CLKID_VDEC_HEVC_SEL] = &meson8b_vdec_hevc_sel.hw,
2852 [CLKID_VDEC_HEVC_DIV] = &meson8b_vdec_hevc_div.hw,
2853 [CLKID_VDEC_HEVC_EN] = &meson8b_vdec_hevc_en.hw,
2854 [CLKID_VDEC_HEVC] = &meson8b_vdec_hevc.hw,
2155 [CLK_NR_CLKS] = NULL, 2855 [CLK_NR_CLKS] = NULL,
2156 }, 2856 },
2157 .num = CLK_NR_CLKS, 2857 .num = CLK_NR_CLKS,
@@ -2314,6 +3014,33 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
2314 &meson8b_mali_1_div, 3014 &meson8b_mali_1_div,
2315 &meson8b_mali_1, 3015 &meson8b_mali_1,
2316 &meson8b_mali, 3016 &meson8b_mali,
3017 &meson8m2_gp_pll_dco,
3018 &meson8m2_gp_pll,
3019 &meson8b_vpu_0_sel,
3020 &meson8m2_vpu_0_sel,
3021 &meson8b_vpu_0_div,
3022 &meson8b_vpu_0,
3023 &meson8b_vpu_1_sel,
3024 &meson8m2_vpu_1_sel,
3025 &meson8b_vpu_1_div,
3026 &meson8b_vpu_1,
3027 &meson8b_vpu,
3028 &meson8b_vdec_1_sel,
3029 &meson8b_vdec_1_1_div,
3030 &meson8b_vdec_1_1,
3031 &meson8b_vdec_1_2_div,
3032 &meson8b_vdec_1_2,
3033 &meson8b_vdec_1,
3034 &meson8b_vdec_hcodec_sel,
3035 &meson8b_vdec_hcodec_div,
3036 &meson8b_vdec_hcodec,
3037 &meson8b_vdec_2_sel,
3038 &meson8b_vdec_2_div,
3039 &meson8b_vdec_2,
3040 &meson8b_vdec_hevc_sel,
3041 &meson8b_vdec_hevc_div,
3042 &meson8b_vdec_hevc_en,
3043 &meson8b_vdec_hevc,
2317}; 3044};
2318 3045
2319static const struct meson8b_clk_reset_line { 3046static const struct meson8b_clk_reset_line {
@@ -2558,9 +3285,14 @@ static void __init meson8b_clkc_init(struct device_node *np)
2558 return meson8b_clkc_init_common(np, &meson8b_hw_onecell_data); 3285 return meson8b_clkc_init_common(np, &meson8b_hw_onecell_data);
2559} 3286}
2560 3287
3288static void __init meson8m2_clkc_init(struct device_node *np)
3289{
3290 return meson8b_clkc_init_common(np, &meson8m2_hw_onecell_data);
3291}
3292
2561CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc", 3293CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
2562 meson8_clkc_init); 3294 meson8_clkc_init);
2563CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc", 3295CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
2564 meson8b_clkc_init); 3296 meson8b_clkc_init);
2565CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc", 3297CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
2566 meson8b_clkc_init); 3298 meson8m2_clkc_init);
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index b8c58faeae52..ed37196187e6 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -19,6 +19,7 @@
19 * 19 *
20 * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf 20 * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
21 */ 21 */
22#define HHI_GP_PLL_CNTL 0x40 /* 0x10 offset in data sheet */
22#define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */ 23#define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */
23#define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */ 24#define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */
24#define HHI_GCLK_MPEG0 0x140 /* 0x50 offset in data sheet */ 25#define HHI_GCLK_MPEG0 0x140 /* 0x50 offset in data sheet */
@@ -34,7 +35,11 @@
34#define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */ 35#define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */
35#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */ 36#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */
36#define HHI_MALI_CLK_CNTL 0x1b0 /* 0x6c offset in data sheet */ 37#define HHI_MALI_CLK_CNTL 0x1b0 /* 0x6c offset in data sheet */
38#define HHI_VPU_CLK_CNTL 0x1bc /* 0x6f offset in data sheet */
37#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */ 39#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */
40#define HHI_VDEC_CLK_CNTL 0x1e0 /* 0x78 offset in data sheet */
41#define HHI_VDEC2_CLK_CNTL 0x1e4 /* 0x79 offset in data sheet */
42#define HHI_VDEC3_CLK_CNTL 0x1e8 /* 0x7a offset in data sheet */
38#define HHI_NAND_CLK_CNTL 0x25c /* 0x97 offset in data sheet */ 43#define HHI_NAND_CLK_CNTL 0x25c /* 0x97 offset in data sheet */
39#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ 44#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
40#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */ 45#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
@@ -146,8 +151,28 @@
146#define CLKID_MALI_1_SEL 178 151#define CLKID_MALI_1_SEL 178
147#define CLKID_MALI_1_DIV 179 152#define CLKID_MALI_1_DIV 179
148#define CLKID_MALI_1 180 153#define CLKID_MALI_1 180
154#define CLKID_GP_PLL_DCO 181
155#define CLKID_GP_PLL 182
156#define CLKID_VPU_0_SEL 183
157#define CLKID_VPU_0_DIV 184
158#define CLKID_VPU_0 185
159#define CLKID_VPU_1_SEL 186
160#define CLKID_VPU_1_DIV 187
161#define CLKID_VPU_1 189
162#define CLKID_VDEC_1_SEL 191
163#define CLKID_VDEC_1_1_DIV 192
164#define CLKID_VDEC_1_1 193
165#define CLKID_VDEC_1_2_DIV 194
166#define CLKID_VDEC_1_2 195
167#define CLKID_VDEC_HCODEC_SEL 197
168#define CLKID_VDEC_HCODEC_DIV 198
169#define CLKID_VDEC_2_SEL 200
170#define CLKID_VDEC_2_DIV 201
171#define CLKID_VDEC_HEVC_SEL 203
172#define CLKID_VDEC_HEVC_DIV 204
173#define CLKID_VDEC_HEVC_EN 205
149 174
150#define CLK_NR_CLKS 181 175#define CLK_NR_CLKS 207
151 176
152/* 177/*
153 * include the CLKID and RESETID that have 178 * include the CLKID and RESETID that have
diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c
index 7355595c42e2..1755916ddef2 100644
--- a/drivers/clk/mmp/clk-gate.c
+++ b/drivers/clk/mmp/clk-gate.c
@@ -108,7 +108,7 @@ struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
108 108
109 init.name = name; 109 init.name = name;
110 init.ops = &mmp_clk_gate_ops; 110 init.ops = &mmp_clk_gate_ops;
111 init.flags = flags | CLK_IS_BASIC; 111 init.flags = flags;
112 init.parent_names = (parent_name ? &parent_name : NULL); 112 init.parent_names = (parent_name ? &parent_name : NULL);
113 init.num_parents = (parent_name ? 1 : 0); 113 init.num_parents = (parent_name ? 1 : 0);
114 114
diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c
index 6ab3c2e627c7..785dbede4835 100644
--- a/drivers/clk/mvebu/common.c
+++ b/drivers/clk/mvebu/common.c
@@ -240,7 +240,7 @@ void __init mvebu_clk_gating_setup(struct device_node *np,
240 int n; 240 int n;
241 241
242 if (ctrl) { 242 if (ctrl) {
243 pr_err("mvebu-clk-gating: cannot instantiate more than one gatable clock device\n"); 243 pr_err("mvebu-clk-gating: cannot instantiate more than one gateable clock device\n");
244 return; 244 return;
245 } 245 }
246 246
diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
index 9235a331b588..b6de283f45e3 100644
--- a/drivers/clk/mvebu/cp110-system-controller.c
+++ b/drivers/clk/mvebu/cp110-system-controller.c
@@ -21,7 +21,7 @@
21 * - Equal to SDIO clock 21 * - Equal to SDIO clock
22 * - 2/5 PLL0 22 * - 2/5 PLL0
23 * 23 *
24 * CP110 has 32 gatable clocks, for the various peripherals in the IP. 24 * CP110 has 32 gateable clocks, for the various peripherals in the IP.
25 */ 25 */
26 26
27#define pr_fmt(fmt) "cp110-system-controller: " fmt 27#define pr_fmt(fmt) "cp110-system-controller: " fmt
@@ -57,7 +57,7 @@ enum {
57#define CP110_CORE_NAND 4 57#define CP110_CORE_NAND 4
58#define CP110_CORE_SDIO 5 58#define CP110_CORE_SDIO 5
59 59
60/* A number of gatable clocks need special handling */ 60/* A number of gateable clocks need special handling */
61#define CP110_GATE_AUDIO 0 61#define CP110_GATE_AUDIO 0
62#define CP110_GATE_COMM_UNIT 1 62#define CP110_GATE_COMM_UNIT 1
63#define CP110_GATE_NAND 2 63#define CP110_GATE_NAND 2
diff --git a/drivers/clk/nxp/clk-lpc18xx-ccu.c b/drivers/clk/nxp/clk-lpc18xx-ccu.c
index 27781b49eb82..5969f620607a 100644
--- a/drivers/clk/nxp/clk-lpc18xx-ccu.c
+++ b/drivers/clk/nxp/clk-lpc18xx-ccu.c
@@ -142,7 +142,7 @@ static int lpc18xx_ccu_gate_endisable(struct clk_hw *hw, bool enable)
142 * Divider field is write only, so divider stat field must 142 * Divider field is write only, so divider stat field must
143 * be read so divider field can be set accordingly. 143 * be read so divider field can be set accordingly.
144 */ 144 */
145 val = clk_readl(gate->reg); 145 val = readl(gate->reg);
146 if (val & LPC18XX_CCU_DIVSTAT) 146 if (val & LPC18XX_CCU_DIVSTAT)
147 val |= LPC18XX_CCU_DIV; 147 val |= LPC18XX_CCU_DIV;
148 148
@@ -155,12 +155,12 @@ static int lpc18xx_ccu_gate_endisable(struct clk_hw *hw, bool enable)
155 * and the next write should clear the RUN bit. 155 * and the next write should clear the RUN bit.
156 */ 156 */
157 val |= LPC18XX_CCU_AUTO; 157 val |= LPC18XX_CCU_AUTO;
158 clk_writel(val, gate->reg); 158 writel(val, gate->reg);
159 159
160 val &= ~LPC18XX_CCU_RUN; 160 val &= ~LPC18XX_CCU_RUN;
161 } 161 }
162 162
163 clk_writel(val, gate->reg); 163 writel(val, gate->reg);
164 164
165 return 0; 165 return 0;
166} 166}
diff --git a/drivers/clk/nxp/clk-lpc18xx-cgu.c b/drivers/clk/nxp/clk-lpc18xx-cgu.c
index 2531174b399e..f5bc8bd192b7 100644
--- a/drivers/clk/nxp/clk-lpc18xx-cgu.c
+++ b/drivers/clk/nxp/clk-lpc18xx-cgu.c
@@ -352,9 +352,9 @@ static unsigned long lpc18xx_pll0_recalc_rate(struct clk_hw *hw,
352 struct lpc18xx_pll *pll = to_lpc_pll(hw); 352 struct lpc18xx_pll *pll = to_lpc_pll(hw);
353 u32 ctrl, mdiv, msel, npdiv; 353 u32 ctrl, mdiv, msel, npdiv;
354 354
355 ctrl = clk_readl(pll->reg + LPC18XX_CGU_PLL0USB_CTRL); 355 ctrl = readl(pll->reg + LPC18XX_CGU_PLL0USB_CTRL);
356 mdiv = clk_readl(pll->reg + LPC18XX_CGU_PLL0USB_MDIV); 356 mdiv = readl(pll->reg + LPC18XX_CGU_PLL0USB_MDIV);
357 npdiv = clk_readl(pll->reg + LPC18XX_CGU_PLL0USB_NP_DIV); 357 npdiv = readl(pll->reg + LPC18XX_CGU_PLL0USB_NP_DIV);
358 358
359 if (ctrl & LPC18XX_PLL0_CTRL_BYPASS) 359 if (ctrl & LPC18XX_PLL0_CTRL_BYPASS)
360 return parent_rate; 360 return parent_rate;
@@ -415,25 +415,25 @@ static int lpc18xx_pll0_set_rate(struct clk_hw *hw, unsigned long rate,
415 m |= lpc18xx_pll0_msel2seli(m) << LPC18XX_PLL0_MDIV_SELI_SHIFT; 415 m |= lpc18xx_pll0_msel2seli(m) << LPC18XX_PLL0_MDIV_SELI_SHIFT;
416 416
417 /* Power down PLL, disable clk output and dividers */ 417 /* Power down PLL, disable clk output and dividers */
418 ctrl = clk_readl(pll->reg + LPC18XX_CGU_PLL0USB_CTRL); 418 ctrl = readl(pll->reg + LPC18XX_CGU_PLL0USB_CTRL);
419 ctrl |= LPC18XX_PLL0_CTRL_PD; 419 ctrl |= LPC18XX_PLL0_CTRL_PD;
420 ctrl &= ~(LPC18XX_PLL0_CTRL_BYPASS | LPC18XX_PLL0_CTRL_DIRECTI | 420 ctrl &= ~(LPC18XX_PLL0_CTRL_BYPASS | LPC18XX_PLL0_CTRL_DIRECTI |
421 LPC18XX_PLL0_CTRL_DIRECTO | LPC18XX_PLL0_CTRL_CLKEN); 421 LPC18XX_PLL0_CTRL_DIRECTO | LPC18XX_PLL0_CTRL_CLKEN);
422 clk_writel(ctrl, pll->reg + LPC18XX_CGU_PLL0USB_CTRL); 422 writel(ctrl, pll->reg + LPC18XX_CGU_PLL0USB_CTRL);
423 423
424 /* Configure new PLL settings */ 424 /* Configure new PLL settings */
425 clk_writel(m, pll->reg + LPC18XX_CGU_PLL0USB_MDIV); 425 writel(m, pll->reg + LPC18XX_CGU_PLL0USB_MDIV);
426 clk_writel(LPC18XX_PLL0_NP_DIVS_1, pll->reg + LPC18XX_CGU_PLL0USB_NP_DIV); 426 writel(LPC18XX_PLL0_NP_DIVS_1, pll->reg + LPC18XX_CGU_PLL0USB_NP_DIV);
427 427
428 /* Power up PLL and wait for lock */ 428 /* Power up PLL and wait for lock */
429 ctrl &= ~LPC18XX_PLL0_CTRL_PD; 429 ctrl &= ~LPC18XX_PLL0_CTRL_PD;
430 clk_writel(ctrl, pll->reg + LPC18XX_CGU_PLL0USB_CTRL); 430 writel(ctrl, pll->reg + LPC18XX_CGU_PLL0USB_CTRL);
431 do { 431 do {
432 udelay(10); 432 udelay(10);
433 stat = clk_readl(pll->reg + LPC18XX_CGU_PLL0USB_STAT); 433 stat = readl(pll->reg + LPC18XX_CGU_PLL0USB_STAT);
434 if (stat & LPC18XX_PLL0_STAT_LOCK) { 434 if (stat & LPC18XX_PLL0_STAT_LOCK) {
435 ctrl |= LPC18XX_PLL0_CTRL_CLKEN; 435 ctrl |= LPC18XX_PLL0_CTRL_CLKEN;
436 clk_writel(ctrl, pll->reg + LPC18XX_CGU_PLL0USB_CTRL); 436 writel(ctrl, pll->reg + LPC18XX_CGU_PLL0USB_CTRL);
437 437
438 return 0; 438 return 0;
439 } 439 }
@@ -458,8 +458,8 @@ static unsigned long lpc18xx_pll1_recalc_rate(struct clk_hw *hw,
458 bool direct, fbsel; 458 bool direct, fbsel;
459 u32 stat, ctrl; 459 u32 stat, ctrl;
460 460
461 stat = clk_readl(pll->reg + LPC18XX_CGU_PLL1_STAT); 461 stat = readl(pll->reg + LPC18XX_CGU_PLL1_STAT);
462 ctrl = clk_readl(pll->reg + LPC18XX_CGU_PLL1_CTRL); 462 ctrl = readl(pll->reg + LPC18XX_CGU_PLL1_CTRL);
463 463
464 direct = (ctrl & LPC18XX_PLL1_CTRL_DIRECT) ? true : false; 464 direct = (ctrl & LPC18XX_PLL1_CTRL_DIRECT) ? true : false;
465 fbsel = (ctrl & LPC18XX_PLL1_CTRL_FBSEL) ? true : false; 465 fbsel = (ctrl & LPC18XX_PLL1_CTRL_FBSEL) ? true : false;
diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c
index 5eeecee17b69..7524d19fe60b 100644
--- a/drivers/clk/nxp/clk-lpc32xx.c
+++ b/drivers/clk/nxp/clk-lpc32xx.c
@@ -1085,13 +1085,12 @@ struct clk_hw_proto {
1085 }; 1085 };
1086}; 1086};
1087 1087
1088#define LPC32XX_DEFINE_FIXED(_idx, _rate, _flags) \ 1088#define LPC32XX_DEFINE_FIXED(_idx, _rate) \
1089[CLK_PREFIX(_idx)] = { \ 1089[CLK_PREFIX(_idx)] = { \
1090 .type = CLK_FIXED, \ 1090 .type = CLK_FIXED, \
1091 { \ 1091 { \
1092 .f = { \ 1092 .f = { \
1093 .fixed_rate = (_rate), \ 1093 .fixed_rate = (_rate), \
1094 .flags = (_flags), \
1095 }, \ 1094 }, \
1096 }, \ 1095 }, \
1097} 1096}
@@ -1225,7 +1224,7 @@ struct clk_hw_proto {
1225} 1224}
1226 1225
1227static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = { 1226static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = {
1228 LPC32XX_DEFINE_FIXED(RTC, 32768, 0), 1227 LPC32XX_DEFINE_FIXED(RTC, 32768),
1229 LPC32XX_DEFINE_PLL(PLL397X, pll_397x, HCLKPLL_CTRL, BIT(1)), 1228 LPC32XX_DEFINE_PLL(PLL397X, pll_397x, HCLKPLL_CTRL, BIT(1)),
1230 LPC32XX_DEFINE_PLL(HCLK_PLL, hclk_pll, HCLKPLL_CTRL, PLL_CTRL_ENABLE), 1229 LPC32XX_DEFINE_PLL(HCLK_PLL, hclk_pll, HCLKPLL_CTRL, PLL_CTRL_ENABLE),
1231 LPC32XX_DEFINE_PLL(USB_PLL, usb_pll, USB_CTRL, PLL_CTRL_ENABLE), 1230 LPC32XX_DEFINE_PLL(USB_PLL, usb_pll, USB_CTRL, PLL_CTRL_ENABLE),
@@ -1468,7 +1467,7 @@ static struct clk * __init lpc32xx_clk_register(u32 id)
1468 struct clk_fixed_rate *fixed = &clk_hw->f; 1467 struct clk_fixed_rate *fixed = &clk_hw->f;
1469 1468
1470 clk = clk_register_fixed_rate(NULL, lpc32xx_clk->name, 1469 clk = clk_register_fixed_rate(NULL, lpc32xx_clk->name,
1471 parents[0], fixed->flags, fixed->fixed_rate); 1470 parents[0], 0, fixed->fixed_rate);
1472 break; 1471 break;
1473 } 1472 }
1474 default: 1473 default:
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 1c04575c118f..18bdf34d5e64 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -243,6 +243,12 @@ config SDM_GCC_660
243 Say Y if you want to use peripheral devices such as UART, SPI, 243 Say Y if you want to use peripheral devices such as UART, SPI,
244 i2C, USB, UFS, SDDC, PCIe, etc. 244 i2C, USB, UFS, SDDC, PCIe, etc.
245 245
246config QCS_TURING_404
247 tristate "QCS404 Turing Clock Controller"
248 help
249 Support for the Turing Clock Controller on QCS404, provides clocks
250 and resets for the Turing subsystem.
251
246config SDM_GCC_845 252config SDM_GCC_845
247 tristate "SDM845 Global Clock Controller" 253 tristate "SDM845 Global Clock Controller"
248 select QCOM_GDSC 254 select QCOM_GDSC
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index ee8d0698e370..f0768fb1f037 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
42obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o 42obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o
43obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o 43obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
44obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o 44obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o
45obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o
45obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o 46obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
46obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o 47obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
47obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o 48obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c
index 99446bf630aa..f869fc6aaed6 100644
--- a/drivers/clk/qcom/clk-branch.c
+++ b/drivers/clk/qcom/clk-branch.c
@@ -146,6 +146,12 @@ const struct clk_ops clk_branch2_ops = {
146}; 146};
147EXPORT_SYMBOL_GPL(clk_branch2_ops); 147EXPORT_SYMBOL_GPL(clk_branch2_ops);
148 148
149const struct clk_ops clk_branch2_aon_ops = {
150 .enable = clk_branch2_enable,
151 .is_enabled = clk_is_enabled_regmap,
152};
153EXPORT_SYMBOL_GPL(clk_branch2_aon_ops);
154
149const struct clk_ops clk_branch_simple_ops = { 155const struct clk_ops clk_branch_simple_ops = {
150 .enable = clk_enable_regmap, 156 .enable = clk_enable_regmap,
151 .disable = clk_disable_regmap, 157 .disable = clk_disable_regmap,
diff --git a/drivers/clk/qcom/clk-branch.h b/drivers/clk/qcom/clk-branch.h
index b3561e0a3984..17a58119165e 100644
--- a/drivers/clk/qcom/clk-branch.h
+++ b/drivers/clk/qcom/clk-branch.h
@@ -40,6 +40,7 @@ struct clk_branch {
40extern const struct clk_ops clk_branch_ops; 40extern const struct clk_ops clk_branch_ops;
41extern const struct clk_ops clk_branch2_ops; 41extern const struct clk_ops clk_branch2_ops;
42extern const struct clk_ops clk_branch_simple_ops; 42extern const struct clk_ops clk_branch_simple_ops;
43extern const struct clk_ops clk_branch2_aon_ops;
43 44
44#define to_clk_branch(_hw) \ 45#define to_clk_branch(_hw) \
45 container_of(to_clk_regmap(_hw), struct clk_branch, clkr) 46 container_of(to_clk_regmap(_hw), struct clk_branch, clkr)
diff --git a/drivers/clk/qcom/clk-regmap-mux-div.h b/drivers/clk/qcom/clk-regmap-mux-div.h
index 6cd6261be7ac..4df6c8d24c24 100644
--- a/drivers/clk/qcom/clk-regmap-mux-div.h
+++ b/drivers/clk/qcom/clk-regmap-mux-div.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2/* 2/*
3 * Copyright (c) 2017, Linaro Limited 3 * Copyright (c) 2017, Linaro Limited
4 * Author: Georgi Djakov <georgi.djakov@linaro.org> 4 * Author: Georgi Djakov <georgi.djakov@linaro.org>
diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c
index c240fba794c7..033688264c7b 100644
--- a/drivers/clk/qcom/gcc-msm8998.c
+++ b/drivers/clk/qcom/gcc-msm8998.c
@@ -2161,7 +2161,7 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
2161 2161
2162static struct clk_branch gcc_pcie_0_pipe_clk = { 2162static struct clk_branch gcc_pcie_0_pipe_clk = {
2163 .halt_reg = 0x6b018, 2163 .halt_reg = 0x6b018,
2164 .halt_check = BRANCH_HALT, 2164 .halt_check = BRANCH_HALT_SKIP,
2165 .clkr = { 2165 .clkr = {
2166 .enable_reg = 0x6b018, 2166 .enable_reg = 0x6b018,
2167 .enable_mask = BIT(0), 2167 .enable_mask = BIT(0),
diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c
index 5a62f64ada93..a54807eb3b28 100644
--- a/drivers/clk/qcom/gcc-qcs404.c
+++ b/drivers/clk/qcom/gcc-qcs404.c
@@ -260,6 +260,20 @@ static const char * const gcc_parent_names_15[] = {
260 "core_bi_pll_test_se", 260 "core_bi_pll_test_se",
261}; 261};
262 262
263static const struct parent_map gcc_parent_map_16[] = {
264 { P_XO, 0 },
265 { P_GPLL0_OUT_MAIN, 1 },
266 { P_GPLL0_OUT_AUX, 2 },
267 { P_CORE_BI_PLL_TEST_SE, 7 },
268};
269
270static const char * const gcc_parent_names_16[] = {
271 "cxo",
272 "gpll0_out_main",
273 "gpll0_out_aux",
274 "core_bi_pll_test_se",
275};
276
263static struct clk_fixed_factor cxo = { 277static struct clk_fixed_factor cxo = {
264 .mult = 1, 278 .mult = 1,
265 .div = 1, 279 .div = 1,
@@ -1194,6 +1208,28 @@ static struct clk_rcg2 vsync_clk_src = {
1194 }, 1208 },
1195}; 1209};
1196 1210
1211static const struct freq_tbl ftbl_cdsp_bimc_clk_src[] = {
1212 F(19200000, P_XO, 1, 0, 0),
1213 F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0),
1214 F(266666667, P_GPLL0_OUT_MAIN, 3, 0, 0),
1215 F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
1216 { }
1217};
1218
1219static struct clk_rcg2 cdsp_bimc_clk_src = {
1220 .cmd_rcgr = 0x5e010,
1221 .mnd_width = 0,
1222 .hid_width = 5,
1223 .parent_map = gcc_parent_map_16,
1224 .freq_tbl = ftbl_cdsp_bimc_clk_src,
1225 .clkr.hw.init = &(struct clk_init_data) {
1226 .name = "cdsp_bimc_clk_src",
1227 .parent_names = gcc_parent_names_16,
1228 .num_parents = 4,
1229 .ops = &clk_rcg2_ops,
1230 },
1231};
1232
1197static struct clk_branch gcc_apss_ahb_clk = { 1233static struct clk_branch gcc_apss_ahb_clk = {
1198 .halt_reg = 0x4601c, 1234 .halt_reg = 0x4601c,
1199 .halt_check = BRANCH_HALT_VOTED, 1235 .halt_check = BRANCH_HALT_VOTED,
@@ -1255,6 +1291,24 @@ static struct clk_branch gcc_bimc_gpu_clk = {
1255 }, 1291 },
1256}; 1292};
1257 1293
1294static struct clk_branch gcc_bimc_cdsp_clk = {
1295 .halt_reg = 0x31030,
1296 .halt_check = BRANCH_HALT,
1297 .clkr = {
1298 .enable_reg = 0x31030,
1299 .enable_mask = BIT(0),
1300 .hw.init = &(struct clk_init_data) {
1301 .name = "gcc_bimc_cdsp_clk",
1302 .parent_names = (const char *[]) {
1303 "cdsp_bimc_clk_src",
1304 },
1305 .num_parents = 1,
1306 .flags = CLK_SET_RATE_PARENT,
1307 .ops = &clk_branch2_ops,
1308 },
1309 },
1310};
1311
1258static struct clk_branch gcc_bimc_mdss_clk = { 1312static struct clk_branch gcc_bimc_mdss_clk = {
1259 .halt_reg = 0x31038, 1313 .halt_reg = 0x31038,
1260 .halt_check = BRANCH_HALT, 1314 .halt_check = BRANCH_HALT,
@@ -1792,6 +1846,24 @@ static struct clk_branch gcc_gfx_tbu_clk = {
1792 }, 1846 },
1793}; 1847};
1794 1848
1849static struct clk_branch gcc_cdsp_tbu_clk = {
1850 .halt_reg = 0x1203c,
1851 .halt_check = BRANCH_VOTED,
1852 .clkr = {
1853 .enable_reg = 0x13020,
1854 .enable_mask = BIT(9),
1855 .hw.init = &(struct clk_init_data) {
1856 .name = "gcc_cdsp_tbu_clk",
1857 .parent_names = (const char *[]) {
1858 "cdsp_bimc_clk_src",
1859 },
1860 .num_parents = 1,
1861 .flags = CLK_SET_RATE_PARENT,
1862 .ops = &clk_branch2_ops,
1863 },
1864 },
1865};
1866
1795static struct clk_branch gcc_gp1_clk = { 1867static struct clk_branch gcc_gp1_clk = {
1796 .halt_reg = 0x8000, 1868 .halt_reg = 0x8000,
1797 .halt_check = BRANCH_HALT, 1869 .halt_check = BRANCH_HALT,
@@ -2304,6 +2376,19 @@ static struct clk_branch gcc_sdcc1_ice_core_clk = {
2304 }, 2376 },
2305}; 2377};
2306 2378
2379static struct clk_branch gcc_cdsp_cfg_ahb_clk = {
2380 .halt_reg = 0x5e004,
2381 .halt_check = BRANCH_HALT,
2382 .clkr = {
2383 .enable_reg = 0x5e004,
2384 .enable_mask = BIT(0),
2385 .hw.init = &(struct clk_init_data) {
2386 .name = "gcc_cdsp_cfg_ahb_cbcr",
2387 .ops = &clk_branch2_ops,
2388 },
2389 },
2390};
2391
2307static struct clk_branch gcc_sdcc2_ahb_clk = { 2392static struct clk_branch gcc_sdcc2_ahb_clk = {
2308 .halt_reg = 0x4301c, 2393 .halt_reg = 0x4301c,
2309 .halt_check = BRANCH_HALT, 2394 .halt_check = BRANCH_HALT,
@@ -2548,6 +2633,7 @@ static struct clk_regmap *gcc_qcs404_clocks[] = {
2548 [GCC_ESC0_CLK_SRC] = &esc0_clk_src.clkr, 2633 [GCC_ESC0_CLK_SRC] = &esc0_clk_src.clkr,
2549 [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr, 2634 [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr,
2550 [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, 2635 [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
2636 [GCC_BIMC_CDSP_CLK] = &gcc_bimc_cdsp_clk.clkr,
2551 [GCC_BIMC_MDSS_CLK] = &gcc_bimc_mdss_clk.clkr, 2637 [GCC_BIMC_MDSS_CLK] = &gcc_bimc_mdss_clk.clkr,
2552 [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, 2638 [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
2553 [GCC_BLSP1_QUP0_I2C_APPS_CLK] = &gcc_blsp1_qup0_i2c_apps_clk.clkr, 2639 [GCC_BLSP1_QUP0_I2C_APPS_CLK] = &gcc_blsp1_qup0_i2c_apps_clk.clkr,
@@ -2605,6 +2691,7 @@ static struct clk_regmap *gcc_qcs404_clocks[] = {
2605 [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, 2691 [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
2606 [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, 2692 [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
2607 [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, 2693 [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
2694 [GCC_CDSP_CFG_AHB_CLK] = &gcc_cdsp_cfg_ahb_clk.clkr,
2608 [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, 2695 [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
2609 [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, 2696 [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
2610 [GCC_SYS_NOC_USB3_CLK] = &gcc_sys_noc_usb3_clk.clkr, 2697 [GCC_SYS_NOC_USB3_CLK] = &gcc_sys_noc_usb3_clk.clkr,
@@ -2645,6 +2732,7 @@ static struct clk_regmap *gcc_qcs404_clocks[] = {
2645 [GCC_USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr, 2732 [GCC_USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr,
2646 [GCC_USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr, 2733 [GCC_USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr,
2647 [GCC_VSYNC_CLK_SRC] = &vsync_clk_src.clkr, 2734 [GCC_VSYNC_CLK_SRC] = &vsync_clk_src.clkr,
2735 [GCC_CDSP_BIMC_CLK_SRC] = &cdsp_bimc_clk_src.clkr,
2648 [GCC_USB_HS_INACTIVITY_TIMERS_CLK] = 2736 [GCC_USB_HS_INACTIVITY_TIMERS_CLK] =
2649 &gcc_usb_hs_inactivity_timers_clk.clkr, 2737 &gcc_usb_hs_inactivity_timers_clk.clkr,
2650 [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr, 2738 [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr,
@@ -2653,6 +2741,7 @@ static struct clk_regmap *gcc_qcs404_clocks[] = {
2653 [GCC_GFX_TBU_CLK] = &gcc_gfx_tbu_clk.clkr, 2741 [GCC_GFX_TBU_CLK] = &gcc_gfx_tbu_clk.clkr,
2654 [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr, 2742 [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr,
2655 [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr, 2743 [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr,
2744 [GCC_CDSP_TBU_CLK] = &gcc_cdsp_tbu_clk.clkr,
2656 [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr, 2745 [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
2657 [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr, 2746 [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
2658 [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr, 2747 [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
@@ -2664,6 +2753,7 @@ static struct clk_regmap *gcc_qcs404_clocks[] = {
2664 2753
2665static const struct qcom_reset_map gcc_qcs404_resets[] = { 2754static const struct qcom_reset_map gcc_qcs404_resets[] = {
2666 [GCC_GENI_IR_BCR] = { 0x0F000 }, 2755 [GCC_GENI_IR_BCR] = { 0x0F000 },
2756 [GCC_CDSP_RESTART] = { 0x18000 },
2667 [GCC_USB_HS_BCR] = { 0x41000 }, 2757 [GCC_USB_HS_BCR] = { 0x41000 },
2668 [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, 2758 [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 },
2669 [GCC_QUSB2_PHY_BCR] = { 0x4103c }, 2759 [GCC_QUSB2_PHY_BCR] = { 0x4103c },
diff --git a/drivers/clk/qcom/turingcc-qcs404.c b/drivers/clk/qcom/turingcc-qcs404.c
new file mode 100644
index 000000000000..aa859e6ec9bd
--- /dev/null
+++ b/drivers/clk/qcom/turingcc-qcs404.c
@@ -0,0 +1,170 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019, Linaro Ltd.
4 */
5
6#include <linux/bitops.h>
7#include <linux/err.h>
8#include <linux/platform_device.h>
9#include <linux/module.h>
10#include <linux/of_address.h>
11#include <linux/pm_clock.h>
12#include <linux/pm_runtime.h>
13#include <linux/regmap.h>
14
15#include <dt-bindings/clock/qcom,turingcc-qcs404.h>
16
17#include "clk-regmap.h"
18#include "clk-branch.h"
19#include "common.h"
20#include "reset.h"
21
22static struct clk_branch turing_wrapper_aon_cbcr = {
23 .halt_reg = 0x5098,
24 .halt_check = BRANCH_HALT,
25 .clkr = {
26 .enable_reg = 0x5098,
27 .enable_mask = BIT(0),
28 .hw.init = &(struct clk_init_data) {
29 .name = "turing_wrapper_aon_clk",
30 .ops = &clk_branch2_aon_ops,
31 },
32 },
33};
34
35static struct clk_branch turing_q6ss_ahbm_aon_cbcr = {
36 .halt_reg = 0x9000,
37 .halt_check = BRANCH_HALT,
38 .clkr = {
39 .enable_reg = 0x9000,
40 .enable_mask = BIT(0),
41 .hw.init = &(struct clk_init_data) {
42 .name = "turing_q6ss_ahbm_aon_cbcr",
43 .ops = &clk_branch2_ops,
44 },
45 },
46};
47
48static struct clk_branch turing_q6ss_q6_axim_clk = {
49 .halt_reg = 0xb000,
50 .halt_check = BRANCH_HALT,
51 .clkr = {
52 .enable_reg = 0xb000,
53 .enable_mask = BIT(0),
54 .hw.init = &(struct clk_init_data) {
55 .name = "turing_q6ss_q6_axim_clk",
56 .ops = &clk_branch2_aon_ops,
57 },
58 },
59};
60
61static struct clk_branch turing_q6ss_ahbs_aon_cbcr = {
62 .halt_reg = 0x10000,
63 .halt_check = BRANCH_HALT,
64 .clkr = {
65 .enable_reg = 0x10000,
66 .enable_mask = BIT(0),
67 .hw.init = &(struct clk_init_data) {
68 .name = "turing_q6ss_ahbs_aon_clk",
69 .ops = &clk_branch2_aon_ops,
70 },
71 },
72};
73
74static struct clk_branch turing_wrapper_qos_ahbs_aon_cbcr = {
75 .halt_reg = 0x11014,
76 .halt_check = BRANCH_HALT,
77 .clkr = {
78 .enable_reg = 0x11014,
79 .enable_mask = BIT(0),
80 .hw.init = &(struct clk_init_data) {
81 .name = "turing_wrapper_qos_ahbs_aon_clk",
82 .ops = &clk_branch2_aon_ops,
83 },
84 },
85};
86
87static struct clk_regmap *turingcc_clocks[] = {
88 [TURING_WRAPPER_AON_CLK] = &turing_wrapper_aon_cbcr.clkr,
89 [TURING_Q6SS_AHBM_AON_CLK] = &turing_q6ss_ahbm_aon_cbcr.clkr,
90 [TURING_Q6SS_Q6_AXIM_CLK] = &turing_q6ss_q6_axim_clk.clkr,
91 [TURING_Q6SS_AHBS_AON_CLK] = &turing_q6ss_ahbs_aon_cbcr.clkr,
92 [TURING_WRAPPER_QOS_AHBS_AON_CLK] = &turing_wrapper_qos_ahbs_aon_cbcr.clkr,
93};
94
95static const struct regmap_config turingcc_regmap_config = {
96 .reg_bits = 32,
97 .reg_stride = 4,
98 .val_bits = 32,
99 .max_register = 0x30000,
100 .fast_io = true,
101};
102
103static const struct qcom_cc_desc turingcc_desc = {
104 .config = &turingcc_regmap_config,
105 .clks = turingcc_clocks,
106 .num_clks = ARRAY_SIZE(turingcc_clocks),
107};
108
109static int turingcc_probe(struct platform_device *pdev)
110{
111 int ret;
112
113 pm_runtime_enable(&pdev->dev);
114 ret = pm_clk_create(&pdev->dev);
115 if (ret)
116 goto disable_pm_runtime;
117
118 ret = pm_clk_add(&pdev->dev, NULL);
119 if (ret < 0) {
120 dev_err(&pdev->dev, "failed to acquire iface clock\n");
121 goto destroy_pm_clk;
122 }
123
124 ret = qcom_cc_probe(pdev, &turingcc_desc);
125 if (ret < 0)
126 goto destroy_pm_clk;
127
128 return 0;
129
130destroy_pm_clk:
131 pm_clk_destroy(&pdev->dev);
132
133disable_pm_runtime:
134 pm_runtime_disable(&pdev->dev);
135
136 return ret;
137}
138
139static int turingcc_remove(struct platform_device *pdev)
140{
141 pm_clk_destroy(&pdev->dev);
142 pm_runtime_disable(&pdev->dev);
143
144 return 0;
145}
146
147static const struct dev_pm_ops turingcc_pm_ops = {
148 SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
149};
150
151static const struct of_device_id turingcc_match_table[] = {
152 { .compatible = "qcom,qcs404-turingcc" },
153 { }
154};
155MODULE_DEVICE_TABLE(of, turingcc_match_table);
156
157static struct platform_driver turingcc_driver = {
158 .probe = turingcc_probe,
159 .remove = turingcc_remove,
160 .driver = {
161 .name = "qcs404-turingcc",
162 .of_match_table = turingcc_match_table,
163 .pm = &turingcc_pm_ops,
164 },
165};
166
167module_platform_driver(turingcc_driver);
168
169MODULE_DESCRIPTION("Qualcomm QCS404 Turing Clock Controller");
170MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c
index 57c49fe88295..cf65d4e0e116 100644
--- a/drivers/clk/renesas/r7s9210-cpg-mssr.c
+++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/clk-provider.h> 13#include <linux/clk-provider.h>
14#include <linux/io.h>
14#include <dt-bindings/clock/r7s9210-cpg-mssr.h> 15#include <dt-bindings/clock/r7s9210-cpg-mssr.h>
15#include "renesas-cpg-mssr.h" 16#include "renesas-cpg-mssr.h"
16 17
@@ -119,7 +120,7 @@ static void __init r7s9210_update_clk_table(struct clk *extal_clk,
119 if (clk_get_rate(extal_clk) > 12000000) 120 if (clk_get_rate(extal_clk) > 12000000)
120 cpg_mode = 1; 121 cpg_mode = 1;
121 122
122 frqcr = clk_readl(base + CPG_FRQCR) & 0xFFF; 123 frqcr = readl(base + CPG_FRQCR) & 0xFFF;
123 if (frqcr == 0x012) 124 if (frqcr == 0x012)
124 index = 0; 125 index = 0;
125 else if (frqcr == 0x112) 126 else if (frqcr == 0x112)
diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c
index 4d92b27a6153..76ed7d1bae36 100644
--- a/drivers/clk/renesas/r8a774a1-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c
@@ -71,8 +71,8 @@ static const struct cpg_core_clk r8a774a1_core_clks[] __initconst = {
71 DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), 71 DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
72 72
73 /* Core Clock Outputs */ 73 /* Core Clock Outputs */
74 DEF_BASE("z", R8A774A1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), 74 DEF_GEN3_Z("z", R8A774A1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8),
75 DEF_BASE("z2", R8A774A1_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2), 75 DEF_GEN3_Z("z2", R8A774A1_CLK_Z2, CLK_TYPE_GEN3_Z, CLK_PLL2, 2, 0),
76 DEF_FIXED("ztr", R8A774A1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), 76 DEF_FIXED("ztr", R8A774A1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
77 DEF_FIXED("ztrd2", R8A774A1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), 77 DEF_FIXED("ztrd2", R8A774A1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
78 DEF_FIXED("zt", R8A774A1_CLK_ZT, CLK_PLL1_DIV2, 4, 1), 78 DEF_FIXED("zt", R8A774A1_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
@@ -123,8 +123,8 @@ static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = {
123 DEF_MOD("msiof2", 209, R8A774A1_CLK_MSO), 123 DEF_MOD("msiof2", 209, R8A774A1_CLK_MSO),
124 DEF_MOD("msiof1", 210, R8A774A1_CLK_MSO), 124 DEF_MOD("msiof1", 210, R8A774A1_CLK_MSO),
125 DEF_MOD("msiof0", 211, R8A774A1_CLK_MSO), 125 DEF_MOD("msiof0", 211, R8A774A1_CLK_MSO),
126 DEF_MOD("sys-dmac2", 217, R8A774A1_CLK_S0D3), 126 DEF_MOD("sys-dmac2", 217, R8A774A1_CLK_S3D1),
127 DEF_MOD("sys-dmac1", 218, R8A774A1_CLK_S0D3), 127 DEF_MOD("sys-dmac1", 218, R8A774A1_CLK_S3D1),
128 DEF_MOD("sys-dmac0", 219, R8A774A1_CLK_S0D3), 128 DEF_MOD("sys-dmac0", 219, R8A774A1_CLK_S0D3),
129 DEF_MOD("cmt3", 300, R8A774A1_CLK_R), 129 DEF_MOD("cmt3", 300, R8A774A1_CLK_R),
130 DEF_MOD("cmt2", 301, R8A774A1_CLK_R), 130 DEF_MOD("cmt2", 301, R8A774A1_CLK_R),
@@ -143,8 +143,8 @@ static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = {
143 DEF_MOD("rwdt", 402, R8A774A1_CLK_R), 143 DEF_MOD("rwdt", 402, R8A774A1_CLK_R),
144 DEF_MOD("intc-ex", 407, R8A774A1_CLK_CP), 144 DEF_MOD("intc-ex", 407, R8A774A1_CLK_CP),
145 DEF_MOD("intc-ap", 408, R8A774A1_CLK_S0D3), 145 DEF_MOD("intc-ap", 408, R8A774A1_CLK_S0D3),
146 DEF_MOD("audmac1", 501, R8A774A1_CLK_S0D3), 146 DEF_MOD("audmac1", 501, R8A774A1_CLK_S1D2),
147 DEF_MOD("audmac0", 502, R8A774A1_CLK_S0D3), 147 DEF_MOD("audmac0", 502, R8A774A1_CLK_S1D2),
148 DEF_MOD("hscif4", 516, R8A774A1_CLK_S3D1), 148 DEF_MOD("hscif4", 516, R8A774A1_CLK_S3D1),
149 DEF_MOD("hscif3", 517, R8A774A1_CLK_S3D1), 149 DEF_MOD("hscif3", 517, R8A774A1_CLK_S3D1),
150 DEF_MOD("hscif2", 518, R8A774A1_CLK_S3D1), 150 DEF_MOD("hscif2", 518, R8A774A1_CLK_S3D1),
@@ -165,9 +165,9 @@ static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = {
165 DEF_MOD("vspd0", 623, R8A774A1_CLK_S0D2), 165 DEF_MOD("vspd0", 623, R8A774A1_CLK_S0D2),
166 DEF_MOD("vspb", 626, R8A774A1_CLK_S0D1), 166 DEF_MOD("vspb", 626, R8A774A1_CLK_S0D1),
167 DEF_MOD("vspi0", 631, R8A774A1_CLK_S0D1), 167 DEF_MOD("vspi0", 631, R8A774A1_CLK_S0D1),
168 DEF_MOD("ehci1", 702, R8A774A1_CLK_S3D4), 168 DEF_MOD("ehci1", 702, R8A774A1_CLK_S3D2),
169 DEF_MOD("ehci0", 703, R8A774A1_CLK_S3D4), 169 DEF_MOD("ehci0", 703, R8A774A1_CLK_S3D2),
170 DEF_MOD("hsusb", 704, R8A774A1_CLK_S3D4), 170 DEF_MOD("hsusb", 704, R8A774A1_CLK_S3D2),
171 DEF_MOD("csi20", 714, R8A774A1_CLK_CSI0), 171 DEF_MOD("csi20", 714, R8A774A1_CLK_CSI0),
172 DEF_MOD("csi40", 716, R8A774A1_CLK_CSI0), 172 DEF_MOD("csi40", 716, R8A774A1_CLK_CSI0),
173 DEF_MOD("du2", 722, R8A774A1_CLK_S2D1), 173 DEF_MOD("du2", 722, R8A774A1_CLK_S2D1),
diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
index 34e274f2a273..f91e7a484753 100644
--- a/drivers/clk/renesas/r8a774c0-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c
@@ -81,6 +81,7 @@ static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = {
81 /* Core Clock Outputs */ 81 /* Core Clock Outputs */
82 DEF_FIXED("za2", R8A774C0_CLK_ZA2, CLK_PLL0D24, 1, 1), 82 DEF_FIXED("za2", R8A774C0_CLK_ZA2, CLK_PLL0D24, 1, 1),
83 DEF_FIXED("za8", R8A774C0_CLK_ZA8, CLK_PLL0D8, 1, 1), 83 DEF_FIXED("za8", R8A774C0_CLK_ZA8, CLK_PLL0D8, 1, 1),
84 DEF_GEN3_Z("z2", R8A774C0_CLK_Z2, CLK_TYPE_GEN3_Z, CLK_PLL0, 4, 8),
84 DEF_FIXED("ztr", R8A774C0_CLK_ZTR, CLK_PLL1, 6, 1), 85 DEF_FIXED("ztr", R8A774C0_CLK_ZTR, CLK_PLL1, 6, 1),
85 DEF_FIXED("zt", R8A774C0_CLK_ZT, CLK_PLL1, 4, 1), 86 DEF_FIXED("zt", R8A774C0_CLK_ZT, CLK_PLL1, 4, 1),
86 DEF_FIXED("zx", R8A774C0_CLK_ZX, CLK_PLL1, 3, 1), 87 DEF_FIXED("zx", R8A774C0_CLK_ZX, CLK_PLL1, 3, 1),
@@ -157,7 +158,7 @@ static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = {
157 DEF_MOD("intc-ex", 407, R8A774C0_CLK_CP), 158 DEF_MOD("intc-ex", 407, R8A774C0_CLK_CP),
158 DEF_MOD("intc-ap", 408, R8A774C0_CLK_S0D3), 159 DEF_MOD("intc-ap", 408, R8A774C0_CLK_S0D3),
159 160
160 DEF_MOD("audmac0", 502, R8A774C0_CLK_S3D4), 161 DEF_MOD("audmac0", 502, R8A774C0_CLK_S1D2),
161 DEF_MOD("hscif4", 516, R8A774C0_CLK_S3D1C), 162 DEF_MOD("hscif4", 516, R8A774C0_CLK_S3D1C),
162 DEF_MOD("hscif3", 517, R8A774C0_CLK_S3D1C), 163 DEF_MOD("hscif3", 517, R8A774C0_CLK_S3D1C),
163 DEF_MOD("hscif2", 518, R8A774C0_CLK_S3D1C), 164 DEF_MOD("hscif2", 518, R8A774C0_CLK_S3D1C),
@@ -177,8 +178,8 @@ static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = {
177 DEF_MOD("vspb", 626, R8A774C0_CLK_S0D1), 178 DEF_MOD("vspb", 626, R8A774C0_CLK_S0D1),
178 DEF_MOD("vspi0", 631, R8A774C0_CLK_S0D1), 179 DEF_MOD("vspi0", 631, R8A774C0_CLK_S0D1),
179 180
180 DEF_MOD("ehci0", 703, R8A774C0_CLK_S3D4), 181 DEF_MOD("ehci0", 703, R8A774C0_CLK_S3D2),
181 DEF_MOD("hsusb", 704, R8A774C0_CLK_S3D4), 182 DEF_MOD("hsusb", 704, R8A774C0_CLK_S3D2),
182 DEF_MOD("csi40", 716, R8A774C0_CLK_CSI0), 183 DEF_MOD("csi40", 716, R8A774C0_CLK_CSI0),
183 DEF_MOD("du1", 723, R8A774C0_CLK_S1D1), 184 DEF_MOD("du1", 723, R8A774C0_CLK_S1D1),
184 DEF_MOD("du0", 724, R8A774C0_CLK_S1D1), 185 DEF_MOD("du0", 724, R8A774C0_CLK_S1D1),
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
index 86842c9fd314..9e9a6f2c31e8 100644
--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
@@ -3,6 +3,7 @@
3 * r8a7795 Clock Pulse Generator / Module Standby and Software Reset 3 * r8a7795 Clock Pulse Generator / Module Standby and Software Reset
4 * 4 *
5 * Copyright (C) 2015 Glider bvba 5 * Copyright (C) 2015 Glider bvba
6 * Copyright (C) 2018-2019 Renesas Electronics Corp.
6 * 7 *
7 * Based on clk-rcar-gen3.c 8 * Based on clk-rcar-gen3.c
8 * 9 *
@@ -73,8 +74,8 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = {
73 DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), 74 DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
74 75
75 /* Core Clock Outputs */ 76 /* Core Clock Outputs */
76 DEF_BASE("z", R8A7795_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), 77 DEF_GEN3_Z("z", R8A7795_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8),
77 DEF_BASE("z2", R8A7795_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2), 78 DEF_GEN3_Z("z2", R8A7795_CLK_Z2, CLK_TYPE_GEN3_Z, CLK_PLL2, 2, 0),
78 DEF_FIXED("ztr", R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), 79 DEF_FIXED("ztr", R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
79 DEF_FIXED("ztrd2", R8A7795_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), 80 DEF_FIXED("ztrd2", R8A7795_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
80 DEF_FIXED("zt", R8A7795_CLK_ZT, CLK_PLL1_DIV2, 4, 1), 81 DEF_FIXED("zt", R8A7795_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
@@ -129,8 +130,8 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
129 DEF_MOD("msiof2", 209, R8A7795_CLK_MSO), 130 DEF_MOD("msiof2", 209, R8A7795_CLK_MSO),
130 DEF_MOD("msiof1", 210, R8A7795_CLK_MSO), 131 DEF_MOD("msiof1", 210, R8A7795_CLK_MSO),
131 DEF_MOD("msiof0", 211, R8A7795_CLK_MSO), 132 DEF_MOD("msiof0", 211, R8A7795_CLK_MSO),
132 DEF_MOD("sys-dmac2", 217, R8A7795_CLK_S0D3), 133 DEF_MOD("sys-dmac2", 217, R8A7795_CLK_S3D1),
133 DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S0D3), 134 DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S3D1),
134 DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S0D3), 135 DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S0D3),
135 DEF_MOD("sceg-pub", 229, R8A7795_CLK_CR), 136 DEF_MOD("sceg-pub", 229, R8A7795_CLK_CR),
136 DEF_MOD("cmt3", 300, R8A7795_CLK_R), 137 DEF_MOD("cmt3", 300, R8A7795_CLK_R),
@@ -153,16 +154,16 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
153 DEF_MOD("rwdt", 402, R8A7795_CLK_R), 154 DEF_MOD("rwdt", 402, R8A7795_CLK_R),
154 DEF_MOD("intc-ex", 407, R8A7795_CLK_CP), 155 DEF_MOD("intc-ex", 407, R8A7795_CLK_CP),
155 DEF_MOD("intc-ap", 408, R8A7795_CLK_S0D3), 156 DEF_MOD("intc-ap", 408, R8A7795_CLK_S0D3),
156 DEF_MOD("audmac1", 501, R8A7795_CLK_S0D3), 157 DEF_MOD("audmac1", 501, R8A7795_CLK_S1D2),
157 DEF_MOD("audmac0", 502, R8A7795_CLK_S0D3), 158 DEF_MOD("audmac0", 502, R8A7795_CLK_S1D2),
158 DEF_MOD("drif7", 508, R8A7795_CLK_S3D2), 159 DEF_MOD("drif31", 508, R8A7795_CLK_S3D2),
159 DEF_MOD("drif6", 509, R8A7795_CLK_S3D2), 160 DEF_MOD("drif30", 509, R8A7795_CLK_S3D2),
160 DEF_MOD("drif5", 510, R8A7795_CLK_S3D2), 161 DEF_MOD("drif21", 510, R8A7795_CLK_S3D2),
161 DEF_MOD("drif4", 511, R8A7795_CLK_S3D2), 162 DEF_MOD("drif20", 511, R8A7795_CLK_S3D2),
162 DEF_MOD("drif3", 512, R8A7795_CLK_S3D2), 163 DEF_MOD("drif11", 512, R8A7795_CLK_S3D2),
163 DEF_MOD("drif2", 513, R8A7795_CLK_S3D2), 164 DEF_MOD("drif10", 513, R8A7795_CLK_S3D2),
164 DEF_MOD("drif1", 514, R8A7795_CLK_S3D2), 165 DEF_MOD("drif01", 514, R8A7795_CLK_S3D2),
165 DEF_MOD("drif0", 515, R8A7795_CLK_S3D2), 166 DEF_MOD("drif00", 515, R8A7795_CLK_S3D2),
166 DEF_MOD("hscif4", 516, R8A7795_CLK_S3D1), 167 DEF_MOD("hscif4", 516, R8A7795_CLK_S3D1),
167 DEF_MOD("hscif3", 517, R8A7795_CLK_S3D1), 168 DEF_MOD("hscif3", 517, R8A7795_CLK_S3D1),
168 DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1), 169 DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1),
@@ -194,12 +195,12 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
194 DEF_MOD("vspi2", 629, R8A7795_CLK_S2D1), /* ES1.x */ 195 DEF_MOD("vspi2", 629, R8A7795_CLK_S2D1), /* ES1.x */
195 DEF_MOD("vspi1", 630, R8A7795_CLK_S0D1), 196 DEF_MOD("vspi1", 630, R8A7795_CLK_S0D1),
196 DEF_MOD("vspi0", 631, R8A7795_CLK_S0D1), 197 DEF_MOD("vspi0", 631, R8A7795_CLK_S0D1),
197 DEF_MOD("ehci3", 700, R8A7795_CLK_S3D4), 198 DEF_MOD("ehci3", 700, R8A7795_CLK_S3D2),
198 DEF_MOD("ehci2", 701, R8A7795_CLK_S3D4), 199 DEF_MOD("ehci2", 701, R8A7795_CLK_S3D2),
199 DEF_MOD("ehci1", 702, R8A7795_CLK_S3D4), 200 DEF_MOD("ehci1", 702, R8A7795_CLK_S3D2),
200 DEF_MOD("ehci0", 703, R8A7795_CLK_S3D4), 201 DEF_MOD("ehci0", 703, R8A7795_CLK_S3D2),
201 DEF_MOD("hsusb", 704, R8A7795_CLK_S3D4), 202 DEF_MOD("hsusb", 704, R8A7795_CLK_S3D2),
202 DEF_MOD("hsusb3", 705, R8A7795_CLK_S3D4), 203 DEF_MOD("hsusb3", 705, R8A7795_CLK_S3D2),
203 DEF_MOD("csi21", 713, R8A7795_CLK_CSI0), /* ES1.x */ 204 DEF_MOD("csi21", 713, R8A7795_CLK_CSI0), /* ES1.x */
204 DEF_MOD("csi20", 714, R8A7795_CLK_CSI0), 205 DEF_MOD("csi20", 714, R8A7795_CLK_CSI0),
205 DEF_MOD("csi41", 715, R8A7795_CLK_CSI0), 206 DEF_MOD("csi41", 715, R8A7795_CLK_CSI0),
diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c
index 12c455859f2c..d8e9af5d9ae9 100644
--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
@@ -3,6 +3,7 @@
3 * r8a7796 Clock Pulse Generator / Module Standby and Software Reset 3 * r8a7796 Clock Pulse Generator / Module Standby and Software Reset
4 * 4 *
5 * Copyright (C) 2016 Glider bvba 5 * Copyright (C) 2016 Glider bvba
6 * Copyright (C) 2018 Renesas Electronics Corp.
6 * 7 *
7 * Based on r8a7795-cpg-mssr.c 8 * Based on r8a7795-cpg-mssr.c
8 * 9 *
@@ -73,8 +74,8 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
73 DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), 74 DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
74 75
75 /* Core Clock Outputs */ 76 /* Core Clock Outputs */
76 DEF_BASE("z", R8A7796_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), 77 DEF_GEN3_Z("z", R8A7796_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8),
77 DEF_BASE("z2", R8A7796_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2), 78 DEF_GEN3_Z("z2", R8A7796_CLK_Z2, CLK_TYPE_GEN3_Z, CLK_PLL2, 2, 0),
78 DEF_FIXED("ztr", R8A7796_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), 79 DEF_FIXED("ztr", R8A7796_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
79 DEF_FIXED("ztrd2", R8A7796_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), 80 DEF_FIXED("ztrd2", R8A7796_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
80 DEF_FIXED("zt", R8A7796_CLK_ZT, CLK_PLL1_DIV2, 4, 1), 81 DEF_FIXED("zt", R8A7796_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
@@ -126,8 +127,8 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
126 DEF_MOD("msiof2", 209, R8A7796_CLK_MSO), 127 DEF_MOD("msiof2", 209, R8A7796_CLK_MSO),
127 DEF_MOD("msiof1", 210, R8A7796_CLK_MSO), 128 DEF_MOD("msiof1", 210, R8A7796_CLK_MSO),
128 DEF_MOD("msiof0", 211, R8A7796_CLK_MSO), 129 DEF_MOD("msiof0", 211, R8A7796_CLK_MSO),
129 DEF_MOD("sys-dmac2", 217, R8A7796_CLK_S0D3), 130 DEF_MOD("sys-dmac2", 217, R8A7796_CLK_S3D1),
130 DEF_MOD("sys-dmac1", 218, R8A7796_CLK_S0D3), 131 DEF_MOD("sys-dmac1", 218, R8A7796_CLK_S3D1),
131 DEF_MOD("sys-dmac0", 219, R8A7796_CLK_S0D3), 132 DEF_MOD("sys-dmac0", 219, R8A7796_CLK_S0D3),
132 DEF_MOD("cmt3", 300, R8A7796_CLK_R), 133 DEF_MOD("cmt3", 300, R8A7796_CLK_R),
133 DEF_MOD("cmt2", 301, R8A7796_CLK_R), 134 DEF_MOD("cmt2", 301, R8A7796_CLK_R),
@@ -146,16 +147,16 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
146 DEF_MOD("rwdt", 402, R8A7796_CLK_R), 147 DEF_MOD("rwdt", 402, R8A7796_CLK_R),
147 DEF_MOD("intc-ex", 407, R8A7796_CLK_CP), 148 DEF_MOD("intc-ex", 407, R8A7796_CLK_CP),
148 DEF_MOD("intc-ap", 408, R8A7796_CLK_S0D3), 149 DEF_MOD("intc-ap", 408, R8A7796_CLK_S0D3),
149 DEF_MOD("audmac1", 501, R8A7796_CLK_S0D3), 150 DEF_MOD("audmac1", 501, R8A7796_CLK_S1D2),
150 DEF_MOD("audmac0", 502, R8A7796_CLK_S0D3), 151 DEF_MOD("audmac0", 502, R8A7796_CLK_S1D2),
151 DEF_MOD("drif7", 508, R8A7796_CLK_S3D2), 152 DEF_MOD("drif31", 508, R8A7796_CLK_S3D2),
152 DEF_MOD("drif6", 509, R8A7796_CLK_S3D2), 153 DEF_MOD("drif30", 509, R8A7796_CLK_S3D2),
153 DEF_MOD("drif5", 510, R8A7796_CLK_S3D2), 154 DEF_MOD("drif21", 510, R8A7796_CLK_S3D2),
154 DEF_MOD("drif4", 511, R8A7796_CLK_S3D2), 155 DEF_MOD("drif20", 511, R8A7796_CLK_S3D2),
155 DEF_MOD("drif3", 512, R8A7796_CLK_S3D2), 156 DEF_MOD("drif11", 512, R8A7796_CLK_S3D2),
156 DEF_MOD("drif2", 513, R8A7796_CLK_S3D2), 157 DEF_MOD("drif10", 513, R8A7796_CLK_S3D2),
157 DEF_MOD("drif1", 514, R8A7796_CLK_S3D2), 158 DEF_MOD("drif01", 514, R8A7796_CLK_S3D2),
158 DEF_MOD("drif0", 515, R8A7796_CLK_S3D2), 159 DEF_MOD("drif00", 515, R8A7796_CLK_S3D2),
159 DEF_MOD("hscif4", 516, R8A7796_CLK_S3D1), 160 DEF_MOD("hscif4", 516, R8A7796_CLK_S3D1),
160 DEF_MOD("hscif3", 517, R8A7796_CLK_S3D1), 161 DEF_MOD("hscif3", 517, R8A7796_CLK_S3D1),
161 DEF_MOD("hscif2", 518, R8A7796_CLK_S3D1), 162 DEF_MOD("hscif2", 518, R8A7796_CLK_S3D1),
@@ -176,9 +177,9 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
176 DEF_MOD("vspd0", 623, R8A7796_CLK_S0D2), 177 DEF_MOD("vspd0", 623, R8A7796_CLK_S0D2),
177 DEF_MOD("vspb", 626, R8A7796_CLK_S0D1), 178 DEF_MOD("vspb", 626, R8A7796_CLK_S0D1),
178 DEF_MOD("vspi0", 631, R8A7796_CLK_S0D1), 179 DEF_MOD("vspi0", 631, R8A7796_CLK_S0D1),
179 DEF_MOD("ehci1", 702, R8A7796_CLK_S3D4), 180 DEF_MOD("ehci1", 702, R8A7796_CLK_S3D2),
180 DEF_MOD("ehci0", 703, R8A7796_CLK_S3D4), 181 DEF_MOD("ehci0", 703, R8A7796_CLK_S3D2),
181 DEF_MOD("hsusb", 704, R8A7796_CLK_S3D4), 182 DEF_MOD("hsusb", 704, R8A7796_CLK_S3D2),
182 DEF_MOD("csi20", 714, R8A7796_CLK_CSI0), 183 DEF_MOD("csi20", 714, R8A7796_CLK_CSI0),
183 DEF_MOD("csi40", 716, R8A7796_CLK_CSI0), 184 DEF_MOD("csi40", 716, R8A7796_CLK_CSI0),
184 DEF_MOD("du2", 722, R8A7796_CLK_S2D1), 185 DEF_MOD("du2", 722, R8A7796_CLK_S2D1),
diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c
index eb1cca58a1e1..8f87e314d949 100644
--- a/drivers/clk/renesas/r8a77965-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c
@@ -3,6 +3,7 @@
3 * r8a77965 Clock Pulse Generator / Module Standby and Software Reset 3 * r8a77965 Clock Pulse Generator / Module Standby and Software Reset
4 * 4 *
5 * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org> 5 * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
6 * Copyright (C) 2019 Renesas Electronics Corp.
6 * 7 *
7 * Based on r8a7795-cpg-mssr.c 8 * Based on r8a7795-cpg-mssr.c
8 * 9 *
@@ -71,7 +72,7 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = {
71 DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), 72 DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
72 73
73 /* Core Clock Outputs */ 74 /* Core Clock Outputs */
74 DEF_BASE("z", R8A77965_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), 75 DEF_GEN3_Z("z", R8A77965_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0, 2, 8),
75 DEF_FIXED("ztr", R8A77965_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), 76 DEF_FIXED("ztr", R8A77965_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
76 DEF_FIXED("ztrd2", R8A77965_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), 77 DEF_FIXED("ztrd2", R8A77965_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
77 DEF_FIXED("zt", R8A77965_CLK_ZT, CLK_PLL1_DIV2, 4, 1), 78 DEF_FIXED("zt", R8A77965_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
@@ -123,8 +124,8 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = {
123 DEF_MOD("msiof2", 209, R8A77965_CLK_MSO), 124 DEF_MOD("msiof2", 209, R8A77965_CLK_MSO),
124 DEF_MOD("msiof1", 210, R8A77965_CLK_MSO), 125 DEF_MOD("msiof1", 210, R8A77965_CLK_MSO),
125 DEF_MOD("msiof0", 211, R8A77965_CLK_MSO), 126 DEF_MOD("msiof0", 211, R8A77965_CLK_MSO),
126 DEF_MOD("sys-dmac2", 217, R8A77965_CLK_S0D3), 127 DEF_MOD("sys-dmac2", 217, R8A77965_CLK_S3D1),
127 DEF_MOD("sys-dmac1", 218, R8A77965_CLK_S0D3), 128 DEF_MOD("sys-dmac1", 218, R8A77965_CLK_S3D1),
128 DEF_MOD("sys-dmac0", 219, R8A77965_CLK_S0D3), 129 DEF_MOD("sys-dmac0", 219, R8A77965_CLK_S0D3),
129 130
130 DEF_MOD("cmt3", 300, R8A77965_CLK_R), 131 DEF_MOD("cmt3", 300, R8A77965_CLK_R),
@@ -146,16 +147,16 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = {
146 DEF_MOD("intc-ex", 407, R8A77965_CLK_CP), 147 DEF_MOD("intc-ex", 407, R8A77965_CLK_CP),
147 DEF_MOD("intc-ap", 408, R8A77965_CLK_S0D3), 148 DEF_MOD("intc-ap", 408, R8A77965_CLK_S0D3),
148 149
149 DEF_MOD("audmac1", 501, R8A77965_CLK_S0D3), 150 DEF_MOD("audmac1", 501, R8A77965_CLK_S1D2),
150 DEF_MOD("audmac0", 502, R8A77965_CLK_S0D3), 151 DEF_MOD("audmac0", 502, R8A77965_CLK_S1D2),
151 DEF_MOD("drif7", 508, R8A77965_CLK_S3D2), 152 DEF_MOD("drif31", 508, R8A77965_CLK_S3D2),
152 DEF_MOD("drif6", 509, R8A77965_CLK_S3D2), 153 DEF_MOD("drif30", 509, R8A77965_CLK_S3D2),
153 DEF_MOD("drif5", 510, R8A77965_CLK_S3D2), 154 DEF_MOD("drif21", 510, R8A77965_CLK_S3D2),
154 DEF_MOD("drif4", 511, R8A77965_CLK_S3D2), 155 DEF_MOD("drif20", 511, R8A77965_CLK_S3D2),
155 DEF_MOD("drif3", 512, R8A77965_CLK_S3D2), 156 DEF_MOD("drif11", 512, R8A77965_CLK_S3D2),
156 DEF_MOD("drif2", 513, R8A77965_CLK_S3D2), 157 DEF_MOD("drif10", 513, R8A77965_CLK_S3D2),
157 DEF_MOD("drif1", 514, R8A77965_CLK_S3D2), 158 DEF_MOD("drif01", 514, R8A77965_CLK_S3D2),
158 DEF_MOD("drif0", 515, R8A77965_CLK_S3D2), 159 DEF_MOD("drif00", 515, R8A77965_CLK_S3D2),
159 DEF_MOD("hscif4", 516, R8A77965_CLK_S3D1), 160 DEF_MOD("hscif4", 516, R8A77965_CLK_S3D1),
160 DEF_MOD("hscif3", 517, R8A77965_CLK_S3D1), 161 DEF_MOD("hscif3", 517, R8A77965_CLK_S3D1),
161 DEF_MOD("hscif2", 518, R8A77965_CLK_S3D1), 162 DEF_MOD("hscif2", 518, R8A77965_CLK_S3D1),
@@ -175,9 +176,9 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = {
175 DEF_MOD("vspb", 626, R8A77965_CLK_S0D1), 176 DEF_MOD("vspb", 626, R8A77965_CLK_S0D1),
176 DEF_MOD("vspi0", 631, R8A77965_CLK_S0D1), 177 DEF_MOD("vspi0", 631, R8A77965_CLK_S0D1),
177 178
178 DEF_MOD("ehci1", 702, R8A77965_CLK_S3D4), 179 DEF_MOD("ehci1", 702, R8A77965_CLK_S3D2),
179 DEF_MOD("ehci0", 703, R8A77965_CLK_S3D4), 180 DEF_MOD("ehci0", 703, R8A77965_CLK_S3D2),
180 DEF_MOD("hsusb", 704, R8A77965_CLK_S3D4), 181 DEF_MOD("hsusb", 704, R8A77965_CLK_S3D2),
181 DEF_MOD("csi20", 714, R8A77965_CLK_CSI0), 182 DEF_MOD("csi20", 714, R8A77965_CLK_CSI0),
182 DEF_MOD("csi40", 716, R8A77965_CLK_CSI0), 183 DEF_MOD("csi40", 716, R8A77965_CLK_CSI0),
183 DEF_MOD("du3", 721, R8A77965_CLK_S2D1), 184 DEF_MOD("du3", 721, R8A77965_CLK_S2D1),
diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
index f9e07fcc0d96..7227f675e61f 100644
--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
@@ -171,7 +171,7 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
171 DEF_MOD("gpio1", 911, R8A77980_CLK_CP), 171 DEF_MOD("gpio1", 911, R8A77980_CLK_CP),
172 DEF_MOD("gpio0", 912, R8A77980_CLK_CP), 172 DEF_MOD("gpio0", 912, R8A77980_CLK_CP),
173 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), 174 DEF_MOD("rpc-if", 917, R8A77980_CLK_RPCD2),
175 DEF_MOD("i2c4", 927, R8A77980_CLK_S0D6), 175 DEF_MOD("i2c4", 927, R8A77980_CLK_S0D6),
176 DEF_MOD("i2c3", 928, R8A77980_CLK_S0D6), 176 DEF_MOD("i2c3", 928, R8A77980_CLK_S0D6),
177 DEF_MOD("i2c2", 929, R8A77980_CLK_S3D2), 177 DEF_MOD("i2c2", 929, R8A77980_CLK_S3D2),
diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c
index 9a278c75c918..9570404baa58 100644
--- a/drivers/clk/renesas/r8a77990-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c
@@ -2,7 +2,7 @@
2/* 2/*
3 * r8a77990 Clock Pulse Generator / Module Standby and Software Reset 3 * r8a77990 Clock Pulse Generator / Module Standby and Software Reset
4 * 4 *
5 * Copyright (C) 2018 Renesas Electronics Corp. 5 * Copyright (C) 2018-2019 Renesas Electronics Corp.
6 * 6 *
7 * Based on r8a7795-cpg-mssr.c 7 * Based on r8a7795-cpg-mssr.c
8 * 8 *
@@ -81,6 +81,7 @@ static const struct cpg_core_clk r8a77990_core_clks[] __initconst = {
81 /* Core Clock Outputs */ 81 /* Core Clock Outputs */
82 DEF_FIXED("za2", R8A77990_CLK_ZA2, CLK_PLL0D24, 1, 1), 82 DEF_FIXED("za2", R8A77990_CLK_ZA2, CLK_PLL0D24, 1, 1),
83 DEF_FIXED("za8", R8A77990_CLK_ZA8, CLK_PLL0D8, 1, 1), 83 DEF_FIXED("za8", R8A77990_CLK_ZA8, CLK_PLL0D8, 1, 1),
84 DEF_GEN3_Z("z2", R8A77990_CLK_Z2, CLK_TYPE_GEN3_Z, CLK_PLL0, 4, 8),
84 DEF_FIXED("ztr", R8A77990_CLK_ZTR, CLK_PLL1, 6, 1), 85 DEF_FIXED("ztr", R8A77990_CLK_ZTR, CLK_PLL1, 6, 1),
85 DEF_FIXED("zt", R8A77990_CLK_ZT, CLK_PLL1, 4, 1), 86 DEF_FIXED("zt", R8A77990_CLK_ZT, CLK_PLL1, 4, 1),
86 DEF_FIXED("zx", R8A77990_CLK_ZX, CLK_PLL1, 3, 1), 87 DEF_FIXED("zx", R8A77990_CLK_ZX, CLK_PLL1, 3, 1),
@@ -152,15 +153,15 @@ static const struct mssr_mod_clk r8a77990_mod_clks[] __initconst = {
152 DEF_MOD("intc-ex", 407, R8A77990_CLK_CP), 153 DEF_MOD("intc-ex", 407, R8A77990_CLK_CP),
153 DEF_MOD("intc-ap", 408, R8A77990_CLK_S0D3), 154 DEF_MOD("intc-ap", 408, R8A77990_CLK_S0D3),
154 155
155 DEF_MOD("audmac0", 502, R8A77990_CLK_S3D4), 156 DEF_MOD("audmac0", 502, R8A77990_CLK_S1D2),
156 DEF_MOD("drif7", 508, R8A77990_CLK_S3D2), 157 DEF_MOD("drif31", 508, R8A77990_CLK_S3D2),
157 DEF_MOD("drif6", 509, R8A77990_CLK_S3D2), 158 DEF_MOD("drif30", 509, R8A77990_CLK_S3D2),
158 DEF_MOD("drif5", 510, R8A77990_CLK_S3D2), 159 DEF_MOD("drif21", 510, R8A77990_CLK_S3D2),
159 DEF_MOD("drif4", 511, R8A77990_CLK_S3D2), 160 DEF_MOD("drif20", 511, R8A77990_CLK_S3D2),
160 DEF_MOD("drif3", 512, R8A77990_CLK_S3D2), 161 DEF_MOD("drif11", 512, R8A77990_CLK_S3D2),
161 DEF_MOD("drif2", 513, R8A77990_CLK_S3D2), 162 DEF_MOD("drif10", 513, R8A77990_CLK_S3D2),
162 DEF_MOD("drif1", 514, R8A77990_CLK_S3D2), 163 DEF_MOD("drif01", 514, R8A77990_CLK_S3D2),
163 DEF_MOD("drif0", 515, R8A77990_CLK_S3D2), 164 DEF_MOD("drif00", 515, R8A77990_CLK_S3D2),
164 DEF_MOD("hscif4", 516, R8A77990_CLK_S3D1C), 165 DEF_MOD("hscif4", 516, R8A77990_CLK_S3D1C),
165 DEF_MOD("hscif3", 517, R8A77990_CLK_S3D1C), 166 DEF_MOD("hscif3", 517, R8A77990_CLK_S3D1C),
166 DEF_MOD("hscif2", 518, R8A77990_CLK_S3D1C), 167 DEF_MOD("hscif2", 518, R8A77990_CLK_S3D1C),
@@ -180,8 +181,8 @@ static const struct mssr_mod_clk r8a77990_mod_clks[] __initconst = {
180 DEF_MOD("vspb", 626, R8A77990_CLK_S0D1), 181 DEF_MOD("vspb", 626, R8A77990_CLK_S0D1),
181 DEF_MOD("vspi0", 631, R8A77990_CLK_S0D1), 182 DEF_MOD("vspi0", 631, R8A77990_CLK_S0D1),
182 183
183 DEF_MOD("ehci0", 703, R8A77990_CLK_S3D4), 184 DEF_MOD("ehci0", 703, R8A77990_CLK_S3D2),
184 DEF_MOD("hsusb", 704, R8A77990_CLK_S3D4), 185 DEF_MOD("hsusb", 704, R8A77990_CLK_S3D2),
185 DEF_MOD("csi40", 716, R8A77990_CLK_CSI0), 186 DEF_MOD("csi40", 716, R8A77990_CLK_CSI0),
186 DEF_MOD("du1", 723, R8A77990_CLK_S1D1), 187 DEF_MOD("du1", 723, R8A77990_CLK_S1D1),
187 DEF_MOD("du0", 724, R8A77990_CLK_S1D1), 188 DEF_MOD("du0", 724, R8A77990_CLK_S1D1),
diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c
index eee3874865a9..68707277b17b 100644
--- a/drivers/clk/renesas/r8a77995-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c
@@ -133,7 +133,7 @@ static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = {
133 DEF_MOD("rwdt", 402, R8A77995_CLK_R), 133 DEF_MOD("rwdt", 402, R8A77995_CLK_R),
134 DEF_MOD("intc-ex", 407, R8A77995_CLK_CP), 134 DEF_MOD("intc-ex", 407, R8A77995_CLK_CP),
135 DEF_MOD("intc-ap", 408, R8A77995_CLK_S1D2), 135 DEF_MOD("intc-ap", 408, R8A77995_CLK_S1D2),
136 DEF_MOD("audmac0", 502, R8A77995_CLK_S3D1), 136 DEF_MOD("audmac0", 502, R8A77995_CLK_S1D2),
137 DEF_MOD("hscif3", 517, R8A77995_CLK_S3D1C), 137 DEF_MOD("hscif3", 517, R8A77995_CLK_S3D1C),
138 DEF_MOD("hscif0", 520, R8A77995_CLK_S3D1C), 138 DEF_MOD("hscif0", 520, R8A77995_CLK_S3D1C),
139 DEF_MOD("thermal", 522, R8A77995_CLK_CP), 139 DEF_MOD("thermal", 522, R8A77995_CLK_CP),
diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
index 658cb11b6f55..97c72477cd54 100644
--- a/drivers/clk/renesas/r9a06g032-clocks.c
+++ b/drivers/clk/renesas/r9a06g032-clocks.c
@@ -170,6 +170,7 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] __initconst = {
170 D_GATE(CLK_P6_PG2, "clk_p6_pg2", DIV_P6_PG, 0x8a3, 0x8a4, 0x8a5, 0, 0xb61, 0, 0), 170 D_GATE(CLK_P6_PG2, "clk_p6_pg2", DIV_P6_PG, 0x8a3, 0x8a4, 0x8a5, 0, 0xb61, 0, 0),
171 D_GATE(CLK_P6_PG3, "clk_p6_pg3", DIV_P6_PG, 0x8a6, 0x8a7, 0x8a8, 0, 0xb62, 0, 0), 171 D_GATE(CLK_P6_PG3, "clk_p6_pg3", DIV_P6_PG, 0x8a6, 0x8a7, 0x8a8, 0, 0xb62, 0, 0),
172 D_GATE(CLK_P6_PG4, "clk_p6_pg4", DIV_P6_PG, 0x8a9, 0x8aa, 0x8ab, 0, 0xb63, 0, 0), 172 D_GATE(CLK_P6_PG4, "clk_p6_pg4", DIV_P6_PG, 0x8a9, 0x8aa, 0x8ab, 0, 0xb63, 0, 0),
173 D_GATE(CLK_PCI_USB, "clk_pci_usb", CLKOUT_D40, 0xe6, 0, 0, 0, 0, 0, 0),
173 D_GATE(CLK_QSPI0, "clk_qspi0", DIV_QSPI0, 0x2a4, 0x2a5, 0, 0, 0, 0, 0), 174 D_GATE(CLK_QSPI0, "clk_qspi0", DIV_QSPI0, 0x2a4, 0x2a5, 0, 0, 0, 0, 0),
174 D_GATE(CLK_QSPI1, "clk_qspi1", DIV_QSPI1, 0x484, 0x485, 0, 0, 0, 0, 0), 175 D_GATE(CLK_QSPI1, "clk_qspi1", DIV_QSPI1, 0x484, 0x485, 0, 0, 0, 0, 0),
175 D_GATE(CLK_RGMII_REF, "clk_rgmii_ref", CLKOUT_D8, 0x340, 0, 0, 0, 0, 0, 0), 176 D_GATE(CLK_RGMII_REF, "clk_rgmii_ref", CLKOUT_D8, 0x340, 0, 0, 0, 0, 0, 0),
diff --git a/drivers/clk/renesas/rcar-gen2-cpg.h b/drivers/clk/renesas/rcar-gen2-cpg.h
index bff9551c7a38..db2f57ef2f99 100644
--- a/drivers/clk/renesas/rcar-gen2-cpg.h
+++ b/drivers/clk/renesas/rcar-gen2-cpg.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2 * 2/*
3 * R-Car Gen2 Clock Pulse Generator 3 * R-Car Gen2 Clock Pulse Generator
4 * 4 *
5 * Copyright (C) 2016 Cogent Embedded Inc. 5 * Copyright (C) 2016 Cogent Embedded Inc.
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index 9a8071a8114d..d25c8ba00a65 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -3,6 +3,7 @@
3 * R-Car Gen3 Clock Pulse Generator 3 * R-Car Gen3 Clock Pulse Generator
4 * 4 *
5 * Copyright (C) 2015-2018 Glider bvba 5 * Copyright (C) 2015-2018 Glider bvba
6 * Copyright (C) 2019 Renesas Electronics Corp.
6 * 7 *
7 * Based on clk-rcar-gen3.c 8 * Based on clk-rcar-gen3.c
8 * 9 *
@@ -88,14 +89,13 @@ static void cpg_simple_notifier_register(struct raw_notifier_head *notifiers,
88#define CPG_FRQCRB 0x00000004 89#define CPG_FRQCRB 0x00000004
89#define CPG_FRQCRB_KICK BIT(31) 90#define CPG_FRQCRB_KICK BIT(31)
90#define CPG_FRQCRC 0x000000e0 91#define CPG_FRQCRC 0x000000e0
91#define CPG_FRQCRC_ZFC_MASK GENMASK(12, 8)
92#define CPG_FRQCRC_Z2FC_MASK GENMASK(4, 0)
93 92
94struct cpg_z_clk { 93struct cpg_z_clk {
95 struct clk_hw hw; 94 struct clk_hw hw;
96 void __iomem *reg; 95 void __iomem *reg;
97 void __iomem *kick_reg; 96 void __iomem *kick_reg;
98 unsigned long mask; 97 unsigned long mask;
98 unsigned int fixed_div;
99}; 99};
100 100
101#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) 101#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw)
@@ -110,17 +110,18 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
110 val = readl(zclk->reg) & zclk->mask; 110 val = readl(zclk->reg) & zclk->mask;
111 mult = 32 - (val >> __ffs(zclk->mask)); 111 mult = 32 - (val >> __ffs(zclk->mask));
112 112
113 /* Factor of 2 is for fixed divider */ 113 return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult,
114 return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, 32 * 2); 114 32 * zclk->fixed_div);
115} 115}
116 116
117static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, 117static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate,
118 unsigned long *parent_rate) 118 unsigned long *parent_rate)
119{ 119{
120 /* Factor of 2 is for fixed divider */ 120 struct cpg_z_clk *zclk = to_z_clk(hw);
121 unsigned long prate = *parent_rate / 2; 121 unsigned long prate;
122 unsigned int mult; 122 unsigned int mult;
123 123
124 prate = *parent_rate / zclk->fixed_div;
124 mult = div_u64(rate * 32ULL, prate); 125 mult = div_u64(rate * 32ULL, prate);
125 mult = clamp(mult, 1U, 32U); 126 mult = clamp(mult, 1U, 32U);
126 127
@@ -134,8 +135,8 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
134 unsigned int mult; 135 unsigned int mult;
135 unsigned int i; 136 unsigned int i;
136 137
137 /* Factor of 2 is for fixed divider */ 138 mult = DIV64_U64_ROUND_CLOSEST(rate * 32ULL * zclk->fixed_div,
138 mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL * 2, parent_rate); 139 parent_rate);
139 mult = clamp(mult, 1U, 32U); 140 mult = clamp(mult, 1U, 32U);
140 141
141 if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) 142 if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
@@ -178,7 +179,8 @@ static const struct clk_ops cpg_z_clk_ops = {
178static struct clk * __init cpg_z_clk_register(const char *name, 179static struct clk * __init cpg_z_clk_register(const char *name,
179 const char *parent_name, 180 const char *parent_name,
180 void __iomem *reg, 181 void __iomem *reg,
181 unsigned long mask) 182 unsigned int div,
183 unsigned int offset)
182{ 184{
183 struct clk_init_data init; 185 struct clk_init_data init;
184 struct cpg_z_clk *zclk; 186 struct cpg_z_clk *zclk;
@@ -197,7 +199,8 @@ static struct clk * __init cpg_z_clk_register(const char *name,
197 zclk->reg = reg + CPG_FRQCRC; 199 zclk->reg = reg + CPG_FRQCRC;
198 zclk->kick_reg = reg + CPG_FRQCRB; 200 zclk->kick_reg = reg + CPG_FRQCRB;
199 zclk->hw.init = &init; 201 zclk->hw.init = &init;
200 zclk->mask = mask; 202 zclk->mask = GENMASK(offset + 4, offset);
203 zclk->fixed_div = div; /* PLLVCO x 1/div x SYS-CPU divider */
201 204
202 clk = clk_register(NULL, &zclk->hw); 205 clk = clk_register(NULL, &zclk->hw);
203 if (IS_ERR(clk)) 206 if (IS_ERR(clk))
@@ -234,8 +237,6 @@ struct sd_clock {
234 const struct sd_div_table *div_table; 237 const struct sd_div_table *div_table;
235 struct cpg_simple_notifier csn; 238 struct cpg_simple_notifier csn;
236 unsigned int div_num; 239 unsigned int div_num;
237 unsigned int div_min;
238 unsigned int div_max;
239 unsigned int cur_div_idx; 240 unsigned int cur_div_idx;
240}; 241};
241 242
@@ -312,14 +313,20 @@ static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock,
312 unsigned long rate, 313 unsigned long rate,
313 unsigned long parent_rate) 314 unsigned long parent_rate)
314{ 315{
315 unsigned int div; 316 unsigned long calc_rate, diff, diff_min = ULONG_MAX;
316 317 unsigned int i, best_div = 0;
317 if (!rate) 318
318 rate = 1; 319 for (i = 0; i < clock->div_num; i++) {
319 320 calc_rate = DIV_ROUND_CLOSEST(parent_rate,
320 div = DIV_ROUND_CLOSEST(parent_rate, rate); 321 clock->div_table[i].div);
322 diff = calc_rate > rate ? calc_rate - rate : rate - calc_rate;
323 if (diff < diff_min) {
324 best_div = clock->div_table[i].div;
325 diff_min = diff;
326 }
327 }
321 328
322 return clamp_t(unsigned int, div, clock->div_min, clock->div_max); 329 return best_div;
323} 330}
324 331
325static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, 332static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -369,27 +376,26 @@ static u32 cpg_quirks __initdata;
369#define RCKCR_CKSEL BIT(1) /* Manual RCLK parent selection */ 376#define RCKCR_CKSEL BIT(1) /* Manual RCLK parent selection */
370#define SD_SKIP_FIRST BIT(2) /* Skip first clock in SD table */ 377#define SD_SKIP_FIRST BIT(2) /* Skip first clock in SD table */
371 378
372static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, 379static struct clk * __init cpg_sd_clk_register(const char *name,
373 void __iomem *base, const char *parent_name, 380 void __iomem *base, unsigned int offset, const char *parent_name,
374 struct raw_notifier_head *notifiers) 381 struct raw_notifier_head *notifiers)
375{ 382{
376 struct clk_init_data init; 383 struct clk_init_data init;
377 struct sd_clock *clock; 384 struct sd_clock *clock;
378 struct clk *clk; 385 struct clk *clk;
379 unsigned int i;
380 u32 val; 386 u32 val;
381 387
382 clock = kzalloc(sizeof(*clock), GFP_KERNEL); 388 clock = kzalloc(sizeof(*clock), GFP_KERNEL);
383 if (!clock) 389 if (!clock)
384 return ERR_PTR(-ENOMEM); 390 return ERR_PTR(-ENOMEM);
385 391
386 init.name = core->name; 392 init.name = name;
387 init.ops = &cpg_sd_clock_ops; 393 init.ops = &cpg_sd_clock_ops;
388 init.flags = CLK_SET_RATE_PARENT; 394 init.flags = CLK_SET_RATE_PARENT;
389 init.parent_names = &parent_name; 395 init.parent_names = &parent_name;
390 init.num_parents = 1; 396 init.num_parents = 1;
391 397
392 clock->csn.reg = base + core->offset; 398 clock->csn.reg = base + offset;
393 clock->hw.init = &init; 399 clock->hw.init = &init;
394 clock->div_table = cpg_sd_div_table; 400 clock->div_table = cpg_sd_div_table;
395 clock->div_num = ARRAY_SIZE(cpg_sd_div_table); 401 clock->div_num = ARRAY_SIZE(cpg_sd_div_table);
@@ -403,13 +409,6 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
403 val |= CPG_SD_STP_MASK | (clock->div_table[0].val & CPG_SD_FC_MASK); 409 val |= CPG_SD_STP_MASK | (clock->div_table[0].val & CPG_SD_FC_MASK);
404 writel(val, clock->csn.reg); 410 writel(val, clock->csn.reg);
405 411
406 clock->div_max = clock->div_table[0].div;
407 clock->div_min = clock->div_max;
408 for (i = 1; i < clock->div_num; i++) {
409 clock->div_max = max(clock->div_max, clock->div_table[i].div);
410 clock->div_min = min(clock->div_min, clock->div_table[i].div);
411 }
412
413 clk = clk_register(NULL, &clock->hw); 412 clk = clk_register(NULL, &clock->hw);
414 if (IS_ERR(clk)) 413 if (IS_ERR(clk))
415 goto free_clock; 414 goto free_clock;
@@ -606,8 +605,8 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
606 break; 605 break;
607 606
608 case CLK_TYPE_GEN3_SD: 607 case CLK_TYPE_GEN3_SD:
609 return cpg_sd_clk_register(core, base, __clk_get_name(parent), 608 return cpg_sd_clk_register(core->name, base, core->offset,
610 notifiers); 609 __clk_get_name(parent), notifiers);
611 610
612 case CLK_TYPE_GEN3_R: 611 case CLK_TYPE_GEN3_R:
613 if (cpg_quirks & RCKCR_CKSEL) { 612 if (cpg_quirks & RCKCR_CKSEL) {
@@ -658,11 +657,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
658 657
659 case CLK_TYPE_GEN3_Z: 658 case CLK_TYPE_GEN3_Z:
660 return cpg_z_clk_register(core->name, __clk_get_name(parent), 659 return cpg_z_clk_register(core->name, __clk_get_name(parent),
661 base, CPG_FRQCRC_ZFC_MASK); 660 base, core->div, core->offset);
662
663 case CLK_TYPE_GEN3_Z2:
664 return cpg_z_clk_register(core->name, __clk_get_name(parent),
665 base, CPG_FRQCRC_Z2FC_MASK);
666 661
667 case CLK_TYPE_GEN3_OSC: 662 case CLK_TYPE_GEN3_OSC:
668 /* 663 /*
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
index eac1b057455a..c4ac80cac6a0 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.h
+++ b/drivers/clk/renesas/rcar-gen3-cpg.h
@@ -1,8 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2 * 2/*
3 * R-Car Gen3 Clock Pulse Generator 3 * R-Car Gen3 Clock Pulse Generator
4 * 4 *
5 * Copyright (C) 2015-2018 Glider bvba 5 * Copyright (C) 2015-2018 Glider bvba
6 * Copyright (C) 2018 Renesas Electronics Corp.
6 * 7 *
7 */ 8 */
8 9
@@ -20,7 +21,6 @@ enum rcar_gen3_clk_types {
20 CLK_TYPE_GEN3_R, 21 CLK_TYPE_GEN3_R,
21 CLK_TYPE_GEN3_MDSEL, /* Select parent/divider using mode pin */ 22 CLK_TYPE_GEN3_MDSEL, /* Select parent/divider using mode pin */
22 CLK_TYPE_GEN3_Z, 23 CLK_TYPE_GEN3_Z,
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, 26 CLK_TYPE_GEN3_RPCSRC,
@@ -51,6 +51,9 @@ enum rcar_gen3_clk_types {
51 DEF_BASE(_name, _id, CLK_TYPE_GEN3_RCKSEL, \ 51 DEF_BASE(_name, _id, CLK_TYPE_GEN3_RCKSEL, \
52 (_parent0) << 16 | (_parent1), .div = (_div0) << 16 | (_div1)) 52 (_parent0) << 16 | (_parent1), .div = (_div0) << 16 | (_div1))
53 53
54#define DEF_GEN3_Z(_name, _id, _type, _parent, _div, _offset) \
55 DEF_BASE(_name, _id, _type, _parent, .div = _div, .offset = _offset)
56
54struct rcar_gen3_cpg_pll_config { 57struct rcar_gen3_cpg_pll_config {
55 u8 extal_div; 58 u8 extal_div;
56 u8 pll1_mult; 59 u8 pll1_mult;
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
index c4ec9df146fd..4ddcdf3bfb95 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.h
+++ b/drivers/clk/renesas/renesas-cpg-mssr.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2 * 2/*
3 * Renesas Clock Pulse Generator / Module Standby and Software Reset 3 * Renesas Clock Pulse Generator / Module Standby and Software Reset
4 * 4 *
5 * Copyright (C) 2015 Glider bvba 5 * Copyright (C) 2015 Glider bvba
diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
index ebce5260068b..09ede6920593 100644
--- a/drivers/clk/rockchip/clk-ddr.c
+++ b/drivers/clk/rockchip/clk-ddr.c
@@ -82,7 +82,7 @@ static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw)
82 struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw); 82 struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
83 u32 val; 83 u32 val;
84 84
85 val = clk_readl(ddrclk->reg_base + 85 val = readl(ddrclk->reg_base +
86 ddrclk->mux_offset) >> ddrclk->mux_shift; 86 ddrclk->mux_offset) >> ddrclk->mux_shift;
87 val &= GENMASK(ddrclk->mux_width - 1, 0); 87 val &= GENMASK(ddrclk->mux_width - 1, 0);
88 88
diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c
index b8da6e799423..784b81e1ea7c 100644
--- a/drivers/clk/rockchip/clk-half-divider.c
+++ b/drivers/clk/rockchip/clk-half-divider.c
@@ -24,7 +24,7 @@ static unsigned long clk_half_divider_recalc_rate(struct clk_hw *hw,
24 struct clk_divider *divider = to_clk_divider(hw); 24 struct clk_divider *divider = to_clk_divider(hw);
25 unsigned int val; 25 unsigned int val;
26 26
27 val = clk_readl(divider->reg) >> divider->shift; 27 val = readl(divider->reg) >> divider->shift;
28 val &= div_mask(divider->width); 28 val &= div_mask(divider->width);
29 val = val * 2 + 3; 29 val = val * 2 + 3;
30 30
@@ -124,11 +124,11 @@ static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate,
124 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { 124 if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
125 val = div_mask(divider->width) << (divider->shift + 16); 125 val = div_mask(divider->width) << (divider->shift + 16);
126 } else { 126 } else {
127 val = clk_readl(divider->reg); 127 val = readl(divider->reg);
128 val &= ~(div_mask(divider->width) << divider->shift); 128 val &= ~(div_mask(divider->width) << divider->shift);
129 } 129 }
130 val |= value << divider->shift; 130 val |= value << divider->shift;
131 clk_writel(val, divider->reg); 131 writel(val, divider->reg);
132 132
133 if (divider->lock) 133 if (divider->lock)
134 spin_unlock_irqrestore(divider->lock, flags); 134 spin_unlock_irqrestore(divider->lock, flags);
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 5a67b7869960..24baeb56a1b3 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -200,8 +200,8 @@ PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" };
200PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; 200PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" };
201PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" }; 201PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" };
202PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" }; 202PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" };
203PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usbphy480m_src" }; 203PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "unstable:usbphy480m_src" };
204PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "usbphy480m_src", "npll" }; 204PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "unstable:usbphy480m_src", "npll" };
205 205
206PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" }; 206PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" };
207PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; 207PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
@@ -219,7 +219,7 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" };
219PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; 219PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" };
220PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; 220PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" };
221 221
222PNAME(mux_aclk_vcodec_pre_p) = { "aclk_vepu", "aclk_vdpu" }; 222PNAME(mux_aclk_vcodec_pre_p) = { "aclk_vdpu", "aclk_vepu" };
223PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m", 223PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m",
224 "sclk_otgphy0_480m" }; 224 "sclk_otgphy0_480m" };
225PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; 225PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" };
@@ -313,13 +313,13 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
313 COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED, 313 COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED,
314 RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, 314 RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
315 RK3288_CLKGATE_CON(12), 6, GFLAGS), 315 RK3288_CLKGATE_CON(12), 6, GFLAGS),
316 COMPOSITE_NOMUX(0, "atclk", "armclk", CLK_IGNORE_UNUSED, 316 COMPOSITE_NOMUX(0, "atclk", "armclk", 0,
317 RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 317 RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
318 RK3288_CLKGATE_CON(12), 7, GFLAGS), 318 RK3288_CLKGATE_CON(12), 7, GFLAGS),
319 COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED, 319 COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED,
320 RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 320 RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
321 RK3288_CLKGATE_CON(12), 8, GFLAGS), 321 RK3288_CLKGATE_CON(12), 8, GFLAGS),
322 GATE(0, "pclk_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED, 322 GATE(0, "pclk_dbg", "pclk_dbg_pre", 0,
323 RK3288_CLKGATE_CON(12), 9, GFLAGS), 323 RK3288_CLKGATE_CON(12), 9, GFLAGS),
324 GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED, 324 GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED,
325 RK3288_CLKGATE_CON(12), 10, GFLAGS), 325 RK3288_CLKGATE_CON(12), 10, GFLAGS),
@@ -420,7 +420,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
420 COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0, 420 COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0,
421 RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, 421 RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
422 RK3288_CLKGATE_CON(3), 11, GFLAGS), 422 RK3288_CLKGATE_CON(3), 11, GFLAGS),
423 MUXGRF(0, "aclk_vcodec_pre", mux_aclk_vcodec_pre_p, 0, 423 MUXGRF(0, "aclk_vcodec_pre", mux_aclk_vcodec_pre_p, CLK_SET_RATE_PARENT,
424 RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS), 424 RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS),
425 GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0, 425 GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0,
426 RK3288_CLKGATE_CON(9), 0, GFLAGS), 426 RK3288_CLKGATE_CON(9), 0, GFLAGS),
@@ -647,7 +647,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
647 INVERTER(SCLK_HSADC, "sclk_hsadc", "sclk_hsadc_out", 647 INVERTER(SCLK_HSADC, "sclk_hsadc", "sclk_hsadc_out",
648 RK3288_CLKSEL_CON(22), 7, IFLAGS), 648 RK3288_CLKSEL_CON(22), 7, IFLAGS),
649 649
650 GATE(0, "jtag", "ext_jtag", CLK_IGNORE_UNUSED, 650 GATE(0, "jtag", "ext_jtag", 0,
651 RK3288_CLKGATE_CON(4), 14, GFLAGS), 651 RK3288_CLKGATE_CON(4), 14, GFLAGS),
652 652
653 COMPOSITE_NODIV(SCLK_USBPHY480M_SRC, "usbphy480m_src", mux_usbphy480m_p, 0, 653 COMPOSITE_NODIV(SCLK_USBPHY480M_SRC, "usbphy480m_src", mux_usbphy480m_p, 0,
@@ -656,7 +656,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
656 COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0, 656 COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0,
657 RK3288_CLKSEL_CON(29), 0, 2, MFLAGS, 657 RK3288_CLKSEL_CON(29), 0, 2, MFLAGS,
658 RK3288_CLKGATE_CON(3), 6, GFLAGS), 658 RK3288_CLKGATE_CON(3), 6, GFLAGS),
659 GATE(0, "hsicphy12m_xin12m", "xin12m", CLK_IGNORE_UNUSED, 659 GATE(0, "hsicphy12m_xin12m", "xin12m", 0,
660 RK3288_CLKGATE_CON(13), 9, GFLAGS), 660 RK3288_CLKGATE_CON(13), 9, GFLAGS),
661 DIV(0, "hsicphy12m_usbphy", "sclk_hsicphy480m", 0, 661 DIV(0, "hsicphy12m_usbphy", "sclk_hsicphy480m", 0,
662 RK3288_CLKSEL_CON(11), 8, 6, DFLAGS), 662 RK3288_CLKSEL_CON(11), 8, 6, DFLAGS),
@@ -697,7 +697,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
697 GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS), 697 GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS),
698 GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS), 698 GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS),
699 GATE(PCLK_EFUSE256, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS), 699 GATE(PCLK_EFUSE256, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS),
700 GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 11, GFLAGS), 700 GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS),
701 701
702 /* ddrctrl [DDR Controller PHY clock] gates */ 702 /* ddrctrl [DDR Controller PHY clock] gates */
703 GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS), 703 GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS),
@@ -837,12 +837,9 @@ static const char *const rk3288_critical_clocks[] __initconst = {
837 "pclk_alive_niu", 837 "pclk_alive_niu",
838 "pclk_pd_pmu", 838 "pclk_pd_pmu",
839 "pclk_pmu_niu", 839 "pclk_pmu_niu",
840 "pclk_core_niu",
841 "pclk_ddrupctl0",
842 "pclk_publ0",
843 "pclk_ddrupctl1",
844 "pclk_publ1",
845 "pmu_hclk_otg0", 840 "pmu_hclk_otg0",
841 /* pwm-regulators on some boards, so handoff-critical later */
842 "pclk_rkpwm",
846}; 843};
847 844
848static void __iomem *rk3288_cru_base; 845static void __iomem *rk3288_cru_base;
@@ -859,6 +856,9 @@ static const int rk3288_saved_cru_reg_ids[] = {
859 RK3288_CLKSEL_CON(10), 856 RK3288_CLKSEL_CON(10),
860 RK3288_CLKSEL_CON(33), 857 RK3288_CLKSEL_CON(33),
861 RK3288_CLKSEL_CON(37), 858 RK3288_CLKSEL_CON(37),
859
860 /* We turn aclk_dmac1 on for suspend; this will restore it */
861 RK3288_CLKGATE_CON(10),
862}; 862};
863 863
864static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)]; 864static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)];
@@ -875,6 +875,14 @@ static int rk3288_clk_suspend(void)
875 } 875 }
876 876
877 /* 877 /*
878 * Going into deep sleep (specifically setting PMU_CLR_DMA in
879 * RK3288_PMU_PWRMODE_CON1) appears to fail unless
880 * "aclk_dmac1" is on.
881 */
882 writel_relaxed(1 << (12 + 16),
883 rk3288_cru_base + RK3288_CLKGATE_CON(10));
884
885 /*
878 * Switch PLLs other than DPLL (for SDRAM) to slow mode to 886 * Switch PLLs other than DPLL (for SDRAM) to slow mode to
879 * avoid crashes on resume. The Mask ROM on the system will 887 * avoid crashes on resume. The Mask ROM on the system will
880 * put APLL, CPLL, and GPLL into slow mode at resume time 888 * put APLL, CPLL, and GPLL into slow mode at resume time
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
index 65ab5c2f48b0..f12142d9cea2 100644
--- a/drivers/clk/rockchip/clk-rk3328.c
+++ b/drivers/clk/rockchip/clk-rk3328.c
@@ -458,7 +458,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
458 RK3328_CLKSEL_CON(35), 15, 1, MFLAGS, 8, 7, DFLAGS, 458 RK3328_CLKSEL_CON(35), 15, 1, MFLAGS, 8, 7, DFLAGS,
459 RK3328_CLKGATE_CON(2), 12, GFLAGS), 459 RK3328_CLKGATE_CON(2), 12, GFLAGS),
460 COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_2plls_p, 0, 460 COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_2plls_p, 0,
461 RK3328_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 7, DFLAGS, 461 RK3328_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 5, DFLAGS,
462 RK3328_CLKGATE_CON(2), 4, GFLAGS), 462 RK3328_CLKGATE_CON(2), 4, GFLAGS),
463 COMPOSITE_NOMUX(SCLK_TSADC, "clk_tsadc", "clk_24m", 0, 463 COMPOSITE_NOMUX(SCLK_TSADC, "clk_tsadc", "clk_24m", 0,
464 RK3328_CLKSEL_CON(22), 0, 10, DFLAGS, 464 RK3328_CLKSEL_CON(22), 0, 10, DFLAGS,
@@ -550,15 +550,15 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
550 GATE(0, "hclk_rkvenc_niu", "hclk_rkvenc", 0, 550 GATE(0, "hclk_rkvenc_niu", "hclk_rkvenc", 0,
551 RK3328_CLKGATE_CON(25), 1, GFLAGS), 551 RK3328_CLKGATE_CON(25), 1, GFLAGS),
552 GATE(ACLK_H265, "aclk_h265", "aclk_rkvenc", 0, 552 GATE(ACLK_H265, "aclk_h265", "aclk_rkvenc", 0,
553 RK3328_CLKGATE_CON(25), 0, GFLAGS), 553 RK3328_CLKGATE_CON(25), 2, GFLAGS),
554 GATE(PCLK_H265, "pclk_h265", "hclk_rkvenc", 0, 554 GATE(PCLK_H265, "pclk_h265", "hclk_rkvenc", 0,
555 RK3328_CLKGATE_CON(25), 1, GFLAGS), 555 RK3328_CLKGATE_CON(25), 3, GFLAGS),
556 GATE(ACLK_H264, "aclk_h264", "aclk_rkvenc", 0, 556 GATE(ACLK_H264, "aclk_h264", "aclk_rkvenc", 0,
557 RK3328_CLKGATE_CON(25), 0, GFLAGS), 557 RK3328_CLKGATE_CON(25), 4, GFLAGS),
558 GATE(HCLK_H264, "hclk_h264", "hclk_rkvenc", 0, 558 GATE(HCLK_H264, "hclk_h264", "hclk_rkvenc", 0,
559 RK3328_CLKGATE_CON(25), 1, GFLAGS), 559 RK3328_CLKGATE_CON(25), 5, GFLAGS),
560 GATE(ACLK_AXISRAM, "aclk_axisram", "aclk_rkvenc", CLK_IGNORE_UNUSED, 560 GATE(ACLK_AXISRAM, "aclk_axisram", "aclk_rkvenc", CLK_IGNORE_UNUSED,
561 RK3328_CLKGATE_CON(25), 0, GFLAGS), 561 RK3328_CLKGATE_CON(25), 6, GFLAGS),
562 562
563 COMPOSITE(SCLK_VENC_CORE, "sclk_venc_core", mux_4plls_p, 0, 563 COMPOSITE(SCLK_VENC_CORE, "sclk_venc_core", mux_4plls_p, 0,
564 RK3328_CLKSEL_CON(51), 14, 2, MFLAGS, 8, 5, DFLAGS, 564 RK3328_CLKSEL_CON(51), 14, 2, MFLAGS, 8, 5, DFLAGS,
@@ -663,7 +663,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
663 663
664 /* PD_GMAC */ 664 /* PD_GMAC */
665 COMPOSITE(ACLK_GMAC, "aclk_gmac", mux_2plls_hdmiphy_p, 0, 665 COMPOSITE(ACLK_GMAC, "aclk_gmac", mux_2plls_hdmiphy_p, 0,
666 RK3328_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, 666 RK3328_CLKSEL_CON(25), 6, 2, MFLAGS, 0, 5, DFLAGS,
667 RK3328_CLKGATE_CON(3), 2, GFLAGS), 667 RK3328_CLKGATE_CON(3), 2, GFLAGS),
668 COMPOSITE_NOMUX(PCLK_GMAC, "pclk_gmac", "aclk_gmac", 0, 668 COMPOSITE_NOMUX(PCLK_GMAC, "pclk_gmac", "aclk_gmac", 0,
669 RK3328_CLKSEL_CON(25), 8, 3, DFLAGS, 669 RK3328_CLKSEL_CON(25), 8, 3, DFLAGS,
@@ -733,7 +733,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
733 733
734 /* PD_PERI */ 734 /* PD_PERI */
735 GATE(0, "aclk_peri_noc", "aclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 11, GFLAGS), 735 GATE(0, "aclk_peri_noc", "aclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 11, GFLAGS),
736 GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri", 0, RK3328_CLKGATE_CON(19), 4, GFLAGS), 736 GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri", 0, RK3328_CLKGATE_CON(19), 14, GFLAGS),
737 737
738 GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 0, GFLAGS), 738 GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 0, GFLAGS),
739 GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 1, GFLAGS), 739 GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 1, GFLAGS),
@@ -913,7 +913,7 @@ static void __init rk3328_clk_init(struct device_node *np)
913 &rk3328_cpuclk_data, rk3328_cpuclk_rates, 913 &rk3328_cpuclk_data, rk3328_cpuclk_rates,
914 ARRAY_SIZE(rk3328_cpuclk_rates)); 914 ARRAY_SIZE(rk3328_cpuclk_rates));
915 915
916 rockchip_register_softrst(np, 11, reg_base + RK3328_SOFTRST_CON(0), 916 rockchip_register_softrst(np, 12, reg_base + RK3328_SOFTRST_CON(0),
917 ROCKCHIP_SOFTRST_HIWORD_MASK); 917 ROCKCHIP_SOFTRST_HIWORD_MASK);
918 918
919 rockchip_register_restart_notifier(ctx, RK3328_GLB_SRST_FST, NULL); 919 rockchip_register_restart_notifier(ctx, RK3328_GLB_SRST_FST, NULL);
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index c3ad92965823..0ea8e8080d1a 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -46,7 +46,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
46 const char *const *parent_names, u8 num_parents, 46 const char *const *parent_names, u8 num_parents,
47 void __iomem *base, 47 void __iomem *base,
48 int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags, 48 int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
49 u8 div_shift, u8 div_width, u8 div_flags, 49 int div_offset, u8 div_shift, u8 div_width, u8 div_flags,
50 struct clk_div_table *div_table, int gate_offset, 50 struct clk_div_table *div_table, int gate_offset,
51 u8 gate_shift, u8 gate_flags, unsigned long flags, 51 u8 gate_shift, u8 gate_flags, unsigned long flags,
52 spinlock_t *lock) 52 spinlock_t *lock)
@@ -95,7 +95,10 @@ static struct clk *rockchip_clk_register_branch(const char *name,
95 } 95 }
96 96
97 div->flags = div_flags; 97 div->flags = div_flags;
98 div->reg = base + muxdiv_offset; 98 if (div_offset)
99 div->reg = base + div_offset;
100 else
101 div->reg = base + muxdiv_offset;
99 div->shift = div_shift; 102 div->shift = div_shift;
100 div->width = div_width; 103 div->width = div_width;
101 div->lock = lock; 104 div->lock = lock;
@@ -516,7 +519,7 @@ void __init rockchip_clk_register_branches(
516 ctx->reg_base, list->muxdiv_offset, 519 ctx->reg_base, list->muxdiv_offset,
517 list->mux_shift, 520 list->mux_shift,
518 list->mux_width, list->mux_flags, 521 list->mux_width, list->mux_flags,
519 list->div_shift, list->div_width, 522 list->div_offset, list->div_shift, list->div_width,
520 list->div_flags, list->div_table, 523 list->div_flags, list->div_table,
521 list->gate_offset, list->gate_shift, 524 list->gate_offset, list->gate_shift,
522 list->gate_flags, flags, &ctx->lock); 525 list->gate_flags, flags, &ctx->lock);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 6b53fff4cc96..1b5270755431 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -407,6 +407,7 @@ struct rockchip_clk_branch {
407 u8 mux_shift; 407 u8 mux_shift;
408 u8 mux_width; 408 u8 mux_width;
409 u8 mux_flags; 409 u8 mux_flags;
410 int div_offset;
410 u8 div_shift; 411 u8 div_shift;
411 u8 div_width; 412 u8 div_width;
412 u8 div_flags; 413 u8 div_flags;
@@ -438,6 +439,28 @@ struct rockchip_clk_branch {
438 .gate_flags = gf, \ 439 .gate_flags = gf, \
439 } 440 }
440 441
442#define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, \
443 mf, do, ds, dw, df, go, gs, gf) \
444 { \
445 .id = _id, \
446 .branch_type = branch_composite, \
447 .name = cname, \
448 .parent_names = pnames, \
449 .num_parents = ARRAY_SIZE(pnames), \
450 .flags = f, \
451 .muxdiv_offset = mo, \
452 .mux_shift = ms, \
453 .mux_width = mw, \
454 .mux_flags = mf, \
455 .div_offset = do, \
456 .div_shift = ds, \
457 .div_width = dw, \
458 .div_flags = df, \
459 .gate_offset = go, \
460 .gate_shift = gs, \
461 .gate_flags = gf, \
462 }
463
441#define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, \ 464#define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, \
442 go, gs, gf) \ 465 go, gs, gf) \
443 { \ 466 { \
diff --git a/drivers/clk/samsung/clk-exynos5410.c b/drivers/clk/samsung/clk-exynos5410.c
index 0a0b09591e6f..b2da2c8fa0c7 100644
--- a/drivers/clk/samsung/clk-exynos5410.c
+++ b/drivers/clk/samsung/clk-exynos5410.c
@@ -209,6 +209,7 @@ static const struct samsung_gate_clock exynos5410_gate_clks[] __initconst = {
209 GATE(CLK_USI1, "usi1", "aclk66", GATE_IP_PERIC, 11, 0, 0), 209 GATE(CLK_USI1, "usi1", "aclk66", GATE_IP_PERIC, 11, 0, 0),
210 GATE(CLK_USI2, "usi2", "aclk66", GATE_IP_PERIC, 12, 0, 0), 210 GATE(CLK_USI2, "usi2", "aclk66", GATE_IP_PERIC, 12, 0, 0),
211 GATE(CLK_USI3, "usi3", "aclk66", GATE_IP_PERIC, 13, 0, 0), 211 GATE(CLK_USI3, "usi3", "aclk66", GATE_IP_PERIC, 13, 0, 0),
212 GATE(CLK_TSADC, "tsadc", "aclk66", GATE_IP_PERIC, 15, 0, 0),
212 GATE(CLK_PWM, "pwm", "aclk66", GATE_IP_PERIC, 24, 0, 0), 213 GATE(CLK_PWM, "pwm", "aclk66", GATE_IP_PERIC, 24, 0, 0),
213 214
214 GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0", 215 GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0",
diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
new file mode 100644
index 000000000000..8db4a3eb4782
--- /dev/null
+++ b/drivers/clk/sifive/Kconfig
@@ -0,0 +1,18 @@
1# SPDX-License-Identifier: GPL-2.0
2
3menuconfig CLK_SIFIVE
4 bool "SiFive SoC driver support"
5 help
6 SoC drivers for SiFive Linux-capable SoCs.
7
8if CLK_SIFIVE
9
10config CLK_SIFIVE_FU540_PRCI
11 bool "PRCI driver for SiFive FU540 SoCs"
12 select CLK_ANALOGBITS_WRPLL_CLN28HPC
13 help
14 Supports the Power Reset Clock interface (PRCI) IP block found in
15 FU540 SoCs. If this kernel is meant to run on a SiFive FU540 SoC,
16 enable this driver.
17
18endif
diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
new file mode 100644
index 000000000000..74d58a4c0756
--- /dev/null
+++ b/drivers/clk/sifive/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI) += fu540-prci.o
diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
new file mode 100644
index 000000000000..0ec8bf7b4b28
--- /dev/null
+++ b/drivers/clk/sifive/fu540-prci.c
@@ -0,0 +1,626 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2018-2019 SiFive, Inc.
4 * Wesley Terpstra
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * The FU540 PRCI implements clock and reset control for the SiFive
17 * FU540-C000 chip. This driver assumes that it has sole control
18 * over all PRCI resources.
19 *
20 * This driver is based on the PRCI driver written by Wesley Terpstra:
21 * https://github.com/riscv/riscv-linux/commit/999529edf517ed75b56659d456d221b2ee56bb60
22 *
23 * References:
24 * - SiFive FU540-C000 manual v1p0, Chapter 7 "Clocking and Reset"
25 */
26
27#include <dt-bindings/clock/sifive-fu540-prci.h>
28#include <linux/clkdev.h>
29#include <linux/clk-provider.h>
30#include <linux/clk/analogbits-wrpll-cln28hpc.h>
31#include <linux/delay.h>
32#include <linux/err.h>
33#include <linux/module.h>
34#include <linux/of.h>
35#include <linux/of_clk.h>
36#include <linux/platform_device.h>
37#include <linux/slab.h>
38
39/*
40 * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
41 * hfclk and rtcclk
42 */
43#define EXPECTED_CLK_PARENT_COUNT 2
44
45/*
46 * Register offsets and bitmasks
47 */
48
49/* COREPLLCFG0 */
50#define PRCI_COREPLLCFG0_OFFSET 0x4
51# define PRCI_COREPLLCFG0_DIVR_SHIFT 0
52# define PRCI_COREPLLCFG0_DIVR_MASK (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT)
53# define PRCI_COREPLLCFG0_DIVF_SHIFT 6
54# define PRCI_COREPLLCFG0_DIVF_MASK (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT)
55# define PRCI_COREPLLCFG0_DIVQ_SHIFT 15
56# define PRCI_COREPLLCFG0_DIVQ_MASK (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT)
57# define PRCI_COREPLLCFG0_RANGE_SHIFT 18
58# define PRCI_COREPLLCFG0_RANGE_MASK (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT)
59# define PRCI_COREPLLCFG0_BYPASS_SHIFT 24
60# define PRCI_COREPLLCFG0_BYPASS_MASK (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT)
61# define PRCI_COREPLLCFG0_FSE_SHIFT 25
62# define PRCI_COREPLLCFG0_FSE_MASK (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT)
63# define PRCI_COREPLLCFG0_LOCK_SHIFT 31
64# define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
65
66/* DDRPLLCFG0 */
67#define PRCI_DDRPLLCFG0_OFFSET 0xc
68# define PRCI_DDRPLLCFG0_DIVR_SHIFT 0
69# define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT)
70# define PRCI_DDRPLLCFG0_DIVF_SHIFT 6
71# define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT)
72# define PRCI_DDRPLLCFG0_DIVQ_SHIFT 15
73# define PRCI_DDRPLLCFG0_DIVQ_MASK (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT)
74# define PRCI_DDRPLLCFG0_RANGE_SHIFT 18
75# define PRCI_DDRPLLCFG0_RANGE_MASK (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT)
76# define PRCI_DDRPLLCFG0_BYPASS_SHIFT 24
77# define PRCI_DDRPLLCFG0_BYPASS_MASK (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT)
78# define PRCI_DDRPLLCFG0_FSE_SHIFT 25
79# define PRCI_DDRPLLCFG0_FSE_MASK (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT)
80# define PRCI_DDRPLLCFG0_LOCK_SHIFT 31
81# define PRCI_DDRPLLCFG0_LOCK_MASK (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT)
82
83/* DDRPLLCFG1 */
84#define PRCI_DDRPLLCFG1_OFFSET 0x10
85# define PRCI_DDRPLLCFG1_CKE_SHIFT 24
86# define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
87
88/* GEMGXLPLLCFG0 */
89#define PRCI_GEMGXLPLLCFG0_OFFSET 0x1c
90# define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0
91# define PRCI_GEMGXLPLLCFG0_DIVR_MASK (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT)
92# define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT 6
93# define PRCI_GEMGXLPLLCFG0_DIVF_MASK (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT)
94# define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT 15
95# define PRCI_GEMGXLPLLCFG0_DIVQ_MASK (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT)
96# define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT 18
97# define PRCI_GEMGXLPLLCFG0_RANGE_MASK (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT)
98# define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT 24
99# define PRCI_GEMGXLPLLCFG0_BYPASS_MASK (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT)
100# define PRCI_GEMGXLPLLCFG0_FSE_SHIFT 25
101# define PRCI_GEMGXLPLLCFG0_FSE_MASK (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT)
102# define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT 31
103# define PRCI_GEMGXLPLLCFG0_LOCK_MASK (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT)
104
105/* GEMGXLPLLCFG1 */
106#define PRCI_GEMGXLPLLCFG1_OFFSET 0x20
107# define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 24
108# define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
109
110/* CORECLKSEL */
111#define PRCI_CORECLKSEL_OFFSET 0x24
112# define PRCI_CORECLKSEL_CORECLKSEL_SHIFT 0
113# define PRCI_CORECLKSEL_CORECLKSEL_MASK (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT)
114
115/* DEVICESRESETREG */
116#define PRCI_DEVICESRESETREG_OFFSET 0x28
117# define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT 0
118# define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT)
119# define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT 1
120# define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT)
121# define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT 2
122# define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT)
123# define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT 3
124# define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT)
125# define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT 5
126# define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
127
128/* CLKMUXSTATUSREG */
129#define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c
130# define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
131# define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
132
133/*
134 * Private structures
135 */
136
137/**
138 * struct __prci_data - per-device-instance data
139 * @va: base virtual address of the PRCI IP block
140 * @hw_clks: encapsulates struct clk_hw records
141 *
142 * PRCI per-device instance data
143 */
144struct __prci_data {
145 void __iomem *va;
146 struct clk_hw_onecell_data hw_clks;
147};
148
149/**
150 * struct __prci_wrpll_data - WRPLL configuration and integration data
151 * @c: WRPLL current configuration record
152 * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
153 * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
154 * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
155 *
156 * @enable_bypass and @disable_bypass are used for WRPLL instances
157 * that contain a separate external glitchless clock mux downstream
158 * from the PLL. The WRPLL internal bypass mux is not glitchless.
159 */
160struct __prci_wrpll_data {
161 struct wrpll_cfg c;
162 void (*enable_bypass)(struct __prci_data *pd);
163 void (*disable_bypass)(struct __prci_data *pd);
164 u8 cfg0_offs;
165};
166
167/**
168 * struct __prci_clock - describes a clock device managed by PRCI
169 * @name: user-readable clock name string - should match the manual
170 * @parent_name: parent name for this clock
171 * @ops: struct clk_ops for the Linux clock framework to use for control
172 * @hw: Linux-private clock data
173 * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
174 * @pd: PRCI-specific data associated with this clock (if not NULL)
175 *
176 * PRCI clock data. Used by the PRCI driver to register PRCI-provided
177 * clocks to the Linux clock infrastructure.
178 */
179struct __prci_clock {
180 const char *name;
181 const char *parent_name;
182 const struct clk_ops *ops;
183 struct clk_hw hw;
184 struct __prci_wrpll_data *pwd;
185 struct __prci_data *pd;
186};
187
188#define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw)
189
190/*
191 * Private functions
192 */
193
194/**
195 * __prci_readl() - read from a PRCI register
196 * @pd: PRCI context
197 * @offs: register offset to read from (in bytes, from PRCI base address)
198 *
199 * Read the register located at offset @offs from the base virtual
200 * address of the PRCI register target described by @pd, and return
201 * the value to the caller.
202 *
203 * Context: Any context.
204 *
205 * Return: the contents of the register described by @pd and @offs.
206 */
207static u32 __prci_readl(struct __prci_data *pd, u32 offs)
208{
209 return readl_relaxed(pd->va + offs);
210}
211
212static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd)
213{
214 writel_relaxed(v, pd->va + offs);
215}
216
217/* WRPLL-related private functions */
218
219/**
220 * __prci_wrpll_unpack() - unpack WRPLL configuration registers into parameters
221 * @c: ptr to a struct wrpll_cfg record to write config into
222 * @r: value read from the PRCI PLL configuration register
223 *
224 * Given a value @r read from an FU540 PRCI PLL configuration register,
225 * split it into fields and populate it into the WRPLL configuration record
226 * pointed to by @c.
227 *
228 * The COREPLLCFG0 macros are used below, but the other *PLLCFG0 macros
229 * have the same register layout.
230 *
231 * Context: Any context.
232 */
233static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r)
234{
235 u32 v;
236
237 v = r & PRCI_COREPLLCFG0_DIVR_MASK;
238 v >>= PRCI_COREPLLCFG0_DIVR_SHIFT;
239 c->divr = v;
240
241 v = r & PRCI_COREPLLCFG0_DIVF_MASK;
242 v >>= PRCI_COREPLLCFG0_DIVF_SHIFT;
243 c->divf = v;
244
245 v = r & PRCI_COREPLLCFG0_DIVQ_MASK;
246 v >>= PRCI_COREPLLCFG0_DIVQ_SHIFT;
247 c->divq = v;
248
249 v = r & PRCI_COREPLLCFG0_RANGE_MASK;
250 v >>= PRCI_COREPLLCFG0_RANGE_SHIFT;
251 c->range = v;
252
253 c->flags &= (WRPLL_FLAGS_INT_FEEDBACK_MASK |
254 WRPLL_FLAGS_EXT_FEEDBACK_MASK);
255
256 /* external feedback mode not supported */
257 c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK;
258}
259
260/**
261 * __prci_wrpll_pack() - pack PLL configuration parameters into a register value
262 * @c: pointer to a struct wrpll_cfg record containing the PLL's cfg
263 *
264 * Using a set of WRPLL configuration values pointed to by @c,
265 * assemble a PRCI PLL configuration register value, and return it to
266 * the caller.
267 *
268 * Context: Any context. Caller must ensure that the contents of the
269 * record pointed to by @c do not change during the execution
270 * of this function.
271 *
272 * Returns: a value suitable for writing into a PRCI PLL configuration
273 * register
274 */
275static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
276{
277 u32 r = 0;
278
279 r |= c->divr << PRCI_COREPLLCFG0_DIVR_SHIFT;
280 r |= c->divf << PRCI_COREPLLCFG0_DIVF_SHIFT;
281 r |= c->divq << PRCI_COREPLLCFG0_DIVQ_SHIFT;
282 r |= c->range << PRCI_COREPLLCFG0_RANGE_SHIFT;
283
284 /* external feedback mode not supported */
285 r |= PRCI_COREPLLCFG0_FSE_MASK;
286
287 return r;
288}
289
290/**
291 * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI
292 * @pd: PRCI context
293 * @pwd: PRCI WRPLL metadata
294 *
295 * Read the current configuration of the PLL identified by @pwd from
296 * the PRCI identified by @pd, and store it into the local configuration
297 * cache in @pwd.
298 *
299 * Context: Any context. Caller must prevent the records pointed to by
300 * @pd and @pwd from changing during execution.
301 */
302static void __prci_wrpll_read_cfg(struct __prci_data *pd,
303 struct __prci_wrpll_data *pwd)
304{
305 __prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs));
306}
307
308/**
309 * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI
310 * @pd: PRCI context
311 * @pwd: PRCI WRPLL metadata
312 * @c: WRPLL configuration record to write
313 *
314 * Write the WRPLL configuration described by @c into the WRPLL
315 * configuration register identified by @pwd in the PRCI instance
316 * described by @c. Make a cached copy of the WRPLL's current
317 * configuration so it can be used by other code.
318 *
319 * Context: Any context. Caller must prevent the records pointed to by
320 * @pd and @pwd from changing during execution.
321 */
322static void __prci_wrpll_write_cfg(struct __prci_data *pd,
323 struct __prci_wrpll_data *pwd,
324 struct wrpll_cfg *c)
325{
326 __prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd);
327
328 memcpy(&pwd->c, c, sizeof(*c));
329}
330
331/* Core clock mux control */
332
333/**
334 * __prci_coreclksel_use_hfclk() - switch the CORECLK mux to output HFCLK
335 * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
336 *
337 * Switch the CORECLK mux to the HFCLK input source; return once complete.
338 *
339 * Context: Any context. Caller must prevent concurrent changes to the
340 * PRCI_CORECLKSEL_OFFSET register.
341 */
342static void __prci_coreclksel_use_hfclk(struct __prci_data *pd)
343{
344 u32 r;
345
346 r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
347 r |= PRCI_CORECLKSEL_CORECLKSEL_MASK;
348 __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
349
350 r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
351}
352
353/**
354 * __prci_coreclksel_use_corepll() - switch the CORECLK mux to output COREPLL
355 * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
356 *
357 * Switch the CORECLK mux to the PLL output clock; return once complete.
358 *
359 * Context: Any context. Caller must prevent concurrent changes to the
360 * PRCI_CORECLKSEL_OFFSET register.
361 */
362static void __prci_coreclksel_use_corepll(struct __prci_data *pd)
363{
364 u32 r;
365
366 r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
367 r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK;
368 __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
369
370 r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
371}
372
373/*
374 * Linux clock framework integration
375 *
376 * See the Linux clock framework documentation for more information on
377 * these functions.
378 */
379
380static unsigned long sifive_fu540_prci_wrpll_recalc_rate(struct clk_hw *hw,
381 unsigned long parent_rate)
382{
383 struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
384 struct __prci_wrpll_data *pwd = pc->pwd;
385
386 return wrpll_calc_output_rate(&pwd->c, parent_rate);
387}
388
389static long sifive_fu540_prci_wrpll_round_rate(struct clk_hw *hw,
390 unsigned long rate,
391 unsigned long *parent_rate)
392{
393 struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
394 struct __prci_wrpll_data *pwd = pc->pwd;
395 struct wrpll_cfg c;
396
397 memcpy(&c, &pwd->c, sizeof(c));
398
399 wrpll_configure_for_rate(&c, rate, *parent_rate);
400
401 return wrpll_calc_output_rate(&c, *parent_rate);
402}
403
404static int sifive_fu540_prci_wrpll_set_rate(struct clk_hw *hw,
405 unsigned long rate,
406 unsigned long parent_rate)
407{
408 struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
409 struct __prci_wrpll_data *pwd = pc->pwd;
410 struct __prci_data *pd = pc->pd;
411 int r;
412
413 r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate);
414 if (r)
415 return r;
416
417 if (pwd->enable_bypass)
418 pwd->enable_bypass(pd);
419
420 __prci_wrpll_write_cfg(pd, pwd, &pwd->c);
421
422 udelay(wrpll_calc_max_lock_us(&pwd->c));
423
424 if (pwd->disable_bypass)
425 pwd->disable_bypass(pd);
426
427 return 0;
428}
429
430static const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = {
431 .set_rate = sifive_fu540_prci_wrpll_set_rate,
432 .round_rate = sifive_fu540_prci_wrpll_round_rate,
433 .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate,
434};
435
436static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = {
437 .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate,
438};
439
440/* TLCLKSEL clock integration */
441
442static unsigned long sifive_fu540_prci_tlclksel_recalc_rate(struct clk_hw *hw,
443 unsigned long parent_rate)
444{
445 struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
446 struct __prci_data *pd = pc->pd;
447 u32 v;
448 u8 div;
449
450 v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET);
451 v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK;
452 div = v ? 1 : 2;
453
454 return div_u64(parent_rate, div);
455}
456
457static const struct clk_ops sifive_fu540_prci_tlclksel_clk_ops = {
458 .recalc_rate = sifive_fu540_prci_tlclksel_recalc_rate,
459};
460
461/*
462 * PRCI integration data for each WRPLL instance
463 */
464
465static struct __prci_wrpll_data __prci_corepll_data = {
466 .cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
467 .enable_bypass = __prci_coreclksel_use_hfclk,
468 .disable_bypass = __prci_coreclksel_use_corepll,
469};
470
471static struct __prci_wrpll_data __prci_ddrpll_data = {
472 .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
473};
474
475static struct __prci_wrpll_data __prci_gemgxlpll_data = {
476 .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
477};
478
479/*
480 * List of clock controls provided by the PRCI
481 */
482
483static struct __prci_clock __prci_init_clocks[] = {
484 [PRCI_CLK_COREPLL] = {
485 .name = "corepll",
486 .parent_name = "hfclk",
487 .ops = &sifive_fu540_prci_wrpll_clk_ops,
488 .pwd = &__prci_corepll_data,
489 },
490 [PRCI_CLK_DDRPLL] = {
491 .name = "ddrpll",
492 .parent_name = "hfclk",
493 .ops = &sifive_fu540_prci_wrpll_ro_clk_ops,
494 .pwd = &__prci_ddrpll_data,
495 },
496 [PRCI_CLK_GEMGXLPLL] = {
497 .name = "gemgxlpll",
498 .parent_name = "hfclk",
499 .ops = &sifive_fu540_prci_wrpll_clk_ops,
500 .pwd = &__prci_gemgxlpll_data,
501 },
502 [PRCI_CLK_TLCLK] = {
503 .name = "tlclk",
504 .parent_name = "corepll",
505 .ops = &sifive_fu540_prci_tlclksel_clk_ops,
506 },
507};
508
509/**
510 * __prci_register_clocks() - register clock controls in the PRCI with Linux
511 * @dev: Linux struct device *
512 *
513 * Register the list of clock controls described in __prci_init_plls[] with
514 * the Linux clock framework.
515 *
516 * Return: 0 upon success or a negative error code upon failure.
517 */
518static int __prci_register_clocks(struct device *dev, struct __prci_data *pd)
519{
520 struct clk_init_data init = { };
521 struct __prci_clock *pic;
522 int parent_count, i, r;
523
524 parent_count = of_clk_get_parent_count(dev->of_node);
525 if (parent_count != EXPECTED_CLK_PARENT_COUNT) {
526 dev_err(dev, "expected only two parent clocks, found %d\n",
527 parent_count);
528 return -EINVAL;
529 }
530
531 /* Register PLLs */
532 for (i = 0; i < ARRAY_SIZE(__prci_init_clocks); ++i) {
533 pic = &__prci_init_clocks[i];
534
535 init.name = pic->name;
536 init.parent_names = &pic->parent_name;
537 init.num_parents = 1;
538 init.ops = pic->ops;
539 pic->hw.init = &init;
540
541 pic->pd = pd;
542
543 if (pic->pwd)
544 __prci_wrpll_read_cfg(pd, pic->pwd);
545
546 r = devm_clk_hw_register(dev, &pic->hw);
547 if (r) {
548 dev_warn(dev, "Failed to register clock %s: %d\n",
549 init.name, r);
550 return r;
551 }
552
553 r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev));
554 if (r) {
555 dev_warn(dev, "Failed to register clkdev for %s: %d\n",
556 init.name, r);
557 return r;
558 }
559
560 pd->hw_clks.hws[i] = &pic->hw;
561 }
562
563 pd->hw_clks.num = i;
564
565 r = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
566 &pd->hw_clks);
567 if (r) {
568 dev_err(dev, "could not add hw_provider: %d\n", r);
569 return r;
570 }
571
572 return 0;
573}
574
575/*
576 * Linux device model integration
577 *
578 * See the Linux device model documentation for more information about
579 * these functions.
580 */
581static int sifive_fu540_prci_probe(struct platform_device *pdev)
582{
583 struct device *dev = &pdev->dev;
584 struct resource *res;
585 struct __prci_data *pd;
586 int r;
587
588 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
589 if (!pd)
590 return -ENOMEM;
591
592 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
593 pd->va = devm_ioremap_resource(dev, res);
594 if (IS_ERR(pd->va))
595 return PTR_ERR(pd->va);
596
597 r = __prci_register_clocks(dev, pd);
598 if (r) {
599 dev_err(dev, "could not register clocks: %d\n", r);
600 return r;
601 }
602
603 dev_dbg(dev, "SiFive FU540 PRCI probed\n");
604
605 return 0;
606}
607
608static const struct of_device_id sifive_fu540_prci_of_match[] = {
609 { .compatible = "sifive,fu540-c000-prci", },
610 {}
611};
612MODULE_DEVICE_TABLE(of, sifive_fu540_prci_of_match);
613
614static struct platform_driver sifive_fu540_prci_driver = {
615 .driver = {
616 .name = "sifive-fu540-prci",
617 .of_match_table = sifive_fu540_prci_of_match,
618 },
619 .probe = sifive_fu540_prci_probe,
620};
621
622static int __init sifive_fu540_prci_init(void)
623{
624 return platform_driver_register(&sifive_fu540_prci_driver);
625}
626core_initcall(sifive_fu540_prci_init);
diff --git a/drivers/clk/sprd/common.h b/drivers/clk/sprd/common.h
index abd9ff5ef448..1d077b39cef6 100644
--- a/drivers/clk/sprd/common.h
+++ b/drivers/clk/sprd/common.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2// 2//
3// Spreadtrum clock infrastructure 3// Spreadtrum clock infrastructure
4// 4//
diff --git a/drivers/clk/sprd/composite.h b/drivers/clk/sprd/composite.h
index 0984e9e252dc..04ab3f587ee2 100644
--- a/drivers/clk/sprd/composite.h
+++ b/drivers/clk/sprd/composite.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2// 2//
3// Spreadtrum composite clock driver 3// Spreadtrum composite clock driver
4// 4//
diff --git a/drivers/clk/sprd/div.h b/drivers/clk/sprd/div.h
index b3033d24d431..87510e3d0e14 100644
--- a/drivers/clk/sprd/div.h
+++ b/drivers/clk/sprd/div.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2// 2//
3// Spreadtrum divider clock driver 3// Spreadtrum divider clock driver
4// 4//
diff --git a/drivers/clk/sprd/gate.h b/drivers/clk/sprd/gate.h
index 2e582c68a08b..dc352ea55e1f 100644
--- a/drivers/clk/sprd/gate.h
+++ b/drivers/clk/sprd/gate.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2// 2//
3// Spreadtrum gate clock driver 3// Spreadtrum gate clock driver
4// 4//
diff --git a/drivers/clk/sprd/mux.h b/drivers/clk/sprd/mux.h
index 548cfa0f145c..892e4191cc7f 100644
--- a/drivers/clk/sprd/mux.h
+++ b/drivers/clk/sprd/mux.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2// 2//
3// Spreadtrum multiplexer clock driver 3// Spreadtrum multiplexer clock driver
4// 4//
diff --git a/drivers/clk/sprd/pll.h b/drivers/clk/sprd/pll.h
index 514175621099..e95f11e91ffe 100644
--- a/drivers/clk/sprd/pll.h
+++ b/drivers/clk/sprd/pll.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2// 2//
3// Spreadtrum pll clock driver 3// Spreadtrum pll clock driver
4// 4//
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 932836d26e2b..be0deee70182 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -531,7 +531,8 @@ static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "dram",
531 531
532static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" }; 532static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
533static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, 533static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
534 0x104, 0, 4, 24, 3, BIT(31), 0); 534 0x104, 0, 4, 24, 3, BIT(31),
535 CLK_SET_RATE_PARENT);
535 536
536static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" }; 537static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
537static const u8 tcon0_table[] = { 0, 2, }; 538static const u8 tcon0_table[] = { 0, 2, };
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
index 139e8389615c..3c32d7798f27 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
@@ -266,7 +266,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, 0x600,
266 0, 4, /* M */ 266 0, 4, /* M */
267 24, 1, /* mux */ 267 24, 1, /* mux */
268 BIT(31), /* gate */ 268 BIT(31), /* gate */
269 0); 269 CLK_SET_RATE_PARENT);
270 270
271static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "psi-ahb1-ahb2", 271static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "psi-ahb1-ahb2",
272 0x60c, BIT(0), 0); 272 0x60c, BIT(0), 0);
@@ -311,7 +311,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690,
311 0, 3, /* M */ 311 0, 3, /* M */
312 24, 1, /* mux */ 312 24, 1, /* mux */
313 BIT(31), /* gate */ 313 BIT(31), /* gate */
314 0); 314 CLK_SET_RATE_PARENT);
315 315
316static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "psi-ahb1-ahb2", 316static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "psi-ahb1-ahb2",
317 0x69c, BIT(0), 0); 317 0x69c, BIT(0), 0);
@@ -656,6 +656,8 @@ static const char * const hdmi_cec_parents[] = { "osc32k", "pll-periph0-2x" };
656static const struct ccu_mux_fixed_prediv hdmi_cec_predivs[] = { 656static const struct ccu_mux_fixed_prediv hdmi_cec_predivs[] = {
657 { .index = 1, .div = 36621 }, 657 { .index = 1, .div = 36621 },
658}; 658};
659
660#define SUN50I_H6_HDMI_CEC_CLK_REG 0xb10
659static struct ccu_mux hdmi_cec_clk = { 661static struct ccu_mux hdmi_cec_clk = {
660 .enable = BIT(31), 662 .enable = BIT(31),
661 663
@@ -689,7 +691,7 @@ static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0",
689 tcon_lcd0_parents, 0xb60, 691 tcon_lcd0_parents, 0xb60,
690 24, 3, /* mux */ 692 24, 3, /* mux */
691 BIT(31), /* gate */ 693 BIT(31), /* gate */
692 0); 694 CLK_SET_RATE_PARENT);
693 695
694static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb3", 696static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb3",
695 0xb7c, BIT(0), 0); 697 0xb7c, BIT(0), 0);
@@ -704,7 +706,7 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0",
704 8, 2, /* P */ 706 8, 2, /* P */
705 24, 3, /* mux */ 707 24, 3, /* mux */
706 BIT(31), /* gate */ 708 BIT(31), /* gate */
707 0); 709 CLK_SET_RATE_PARENT);
708 710
709static SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0", "ahb3", 711static SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0", "ahb3",
710 0xb9c, BIT(0), 0); 712 0xb9c, BIT(0), 0);
@@ -1200,6 +1202,15 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
1200 val &= ~(GENMASK(21, 16) | BIT(0)); 1202 val &= ~(GENMASK(21, 16) | BIT(0));
1201 writel(val | (7 << 16), reg + SUN50I_H6_PLL_AUDIO_REG); 1203 writel(val | (7 << 16), reg + SUN50I_H6_PLL_AUDIO_REG);
1202 1204
1205 /*
1206 * First clock parent (osc32K) is unusable for CEC. But since there
1207 * is no good way to force parent switch (both run with same frequency),
1208 * just set second clock parent here.
1209 */
1210 val = readl(reg + SUN50I_H6_HDMI_CEC_CLK_REG);
1211 val |= BIT(24);
1212 writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
1213
1203 return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); 1214 return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc);
1204} 1215}
1205 1216
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.h b/drivers/clk/sunxi-ng/ccu-sun50i-h6.h
index 2ccfe4428260..9406f9a6a8aa 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.h
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1/* SPDX-License-Identifier: GPL-2.0 */
2/* 2/*
3 * Copyright 2016 Icenowy Zheng <icenowy@aosc.io> 3 * Copyright 2016 Icenowy Zheng <icenowy@aosc.io>
4 */ 4 */
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.h b/drivers/clk/sunxi-ng/ccu-sun5i.h
index 93a275fbd9a9..b66abd4fd0bf 100644
--- a/drivers/clk/sunxi-ng/ccu-sun5i.h
+++ b/drivers/clk/sunxi-ng/ccu-sun5i.h
@@ -60,10 +60,6 @@
60 60
61/* The rest of the module clocks are exported */ 61/* The rest of the module clocks are exported */
62 62
63#define CLK_MBUS 99
64
65/* And finally the IEP clock */
66
67#define CLK_NUMBER (CLK_IEP + 1) 63#define CLK_NUMBER (CLK_IEP + 1)
68 64
69#endif /* _CCU_SUN5I_H_ */ 65#endif /* _CCU_SUN5I_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
index 2d6555d73170..5f714b4d8ee4 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
@@ -513,8 +513,9 @@ static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M", 0x130, BIT(16), 0);
513 513
514static SUNXI_CCU_GATE(mipi_csi_clk, "mipi-csi", "osc24M", 0x130, BIT(31), 0); 514static SUNXI_CCU_GATE(mipi_csi_clk, "mipi-csi", "osc24M", 0x130, BIT(31), 0);
515 515
516static const char * const csi_mclk_parents[] = { "pll-de", "osc24M" }; 516static const char * const csi_mclk_parents[] = { "pll-video0", "pll-de",
517static const u8 csi_mclk_table[] = { 3, 5 }; 517 "osc24M" };
518static const u8 csi_mclk_table[] = { 0, 3, 5 };
518static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk", 519static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk",
519 csi_mclk_parents, csi_mclk_table, 520 csi_mclk_parents, csi_mclk_table,
520 0x134, 521 0x134,
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
index ac12f261f8ca..eada0e291859 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
@@ -325,7 +325,8 @@ static SUNXI_CCU_GATE(dram_ohci_clk, "dram-ohci", "dram",
325 325
326static const char * const de_parents[] = { "pll-video", "pll-periph0" }; 326static const char * const de_parents[] = { "pll-video", "pll-periph0" };
327static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, 327static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
328 0x104, 0, 4, 24, 2, BIT(31), 0); 328 0x104, 0, 4, 24, 2, BIT(31),
329 CLK_SET_RATE_PARENT);
329 330
330static const char * const tcon_parents[] = { "pll-video" }; 331static const char * const tcon_parents[] = { "pll-video" };
331static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents, 332static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents,
diff --git a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
index a09dfbe36402..dc9f0a365664 100644
--- a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
+++ b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
@@ -240,7 +240,7 @@ static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", i2s_spdif_parents,
240/* The BSP header file has a CIR_CFG, but no mod clock uses this definition */ 240/* The BSP header file has a CIR_CFG, but no mod clock uses this definition */
241 241
242static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 242static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
243 0x0cc, BIT(8), 0); 243 0x0cc, BIT(1), 0);
244 244
245static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr", 245static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr",
246 0x100, BIT(0), 0); 246 0x100, BIT(0), 0);
diff --git a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.h b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.h
index 39d06fed55b2..b22484f1bb9a 100644
--- a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.h
+++ b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.h
@@ -1,5 +1,5 @@
1/* SPDX-License-Identifier: GPL-2.0+ 1/* SPDX-License-Identifier: GPL-2.0+ */
2 * 2/*
3 * Copyright 2017 Icenowy Zheng <icenowy@aosc.io> 3 * Copyright 2017 Icenowy Zheng <icenowy@aosc.io>
4 * 4 *
5 */ 5 */
diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig
new file mode 100644
index 000000000000..2b6207cc4eda
--- /dev/null
+++ b/drivers/clk/sunxi/Kconfig
@@ -0,0 +1,43 @@
1menuconfig CLK_SUNXI
2 bool "Legacy clock support for Allwinner SoCs"
3 depends on ARCH_SUNXI || COMPILE_TEST
4 default y
5
6if CLK_SUNXI
7
8config CLK_SUNXI_CLOCKS
9 bool "Legacy clock drivers"
10 default y
11 help
12 Legacy clock drivers being used on older (A10, A13, A20,
13 A23, A31, A80) SoCs. These drivers are kept around for
14 Device Tree backward compatibility issues, in case one would
15 still use a Device Tree with one clock provider by
16 node. Newer Device Trees and newer SoCs use the drivers
17 controlled by CONFIG_SUNXI_CCU.
18
19config CLK_SUNXI_PRCM_SUN6I
20 bool "Legacy A31 PRCM driver"
21 select MFD_SUN6I_PRCM
22 default y
23 help
24 Legacy clock driver for the A31 PRCM clocks. Those are
25 usually needed for the PMIC communication, mostly.
26
27config CLK_SUNXI_PRCM_SUN8I
28 bool "Legacy sun8i PRCM driver"
29 select MFD_SUN6I_PRCM
30 default y
31 help
32 Legacy clock driver for the sun8i family PRCM clocks.
33 Those are usually needed for the PMIC communication,
34 mostly.
35
36config CLK_SUNXI_PRCM_SUN9I
37 bool "Legacy A80 PRCM driver"
38 default y
39 help
40 Legacy clock driver for the A80 PRCM clocks. Those are
41 usually needed for the PMIC communication, mostly.
42
43endif
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index be88368b48a1..e10824c76ae9 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -3,27 +3,32 @@
3# Makefile for sunxi specific clk 3# Makefile for sunxi specific clk
4# 4#
5 5
6obj-y += clk-sunxi.o clk-factors.o 6obj-$(CONFIG_CLK_SUNXI) += clk-factors.o
7obj-y += clk-a10-codec.o
8obj-y += clk-a10-hosc.o
9obj-y += clk-a10-mod1.o
10obj-y += clk-a10-pll2.o
11obj-y += clk-a10-ve.o
12obj-y += clk-a20-gmac.o
13obj-y += clk-mod0.o
14obj-y += clk-simple-gates.o
15obj-y += clk-sun4i-display.o
16obj-y += clk-sun4i-pll3.o
17obj-y += clk-sun4i-tcon-ch1.o
18obj-y += clk-sun8i-bus-gates.o
19obj-y += clk-sun8i-mbus.o
20obj-y += clk-sun9i-core.o
21obj-y += clk-sun9i-mmc.o
22obj-y += clk-usb.o
23 7
24obj-$(CONFIG_MACH_SUN9I) += clk-sun8i-apb0.o 8obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sunxi.o
25obj-$(CONFIG_MACH_SUN9I) += clk-sun9i-cpus.o 9obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a10-codec.o
10obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a10-hosc.o
11obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a10-mod1.o
12obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a10-pll2.o
13obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a10-ve.o
14obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-a20-gmac.o
15obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-mod0.o
16obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-simple-gates.o
17obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun4i-display.o
18obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun4i-pll3.o
19obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun4i-tcon-ch1.o
20obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun8i-bus-gates.o
21obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun8i-mbus.o
22obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun9i-core.o
23obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun9i-mmc.o
24obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-usb.o
26 25
27obj-$(CONFIG_MFD_SUN6I_PRCM) += \ 26obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun8i-apb0.o
28 clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \ 27obj-$(CONFIG_CLK_SUNXI_CLOCKS) += clk-sun9i-cpus.o
29 clk-sun8i-apb0.o 28
29obj-$(CONFIG_CLK_SUNXI_PRCM_SUN6I) += clk-sun6i-apb0.o
30obj-$(CONFIG_CLK_SUNXI_PRCM_SUN6I) += clk-sun6i-apb0-gates.o
31obj-$(CONFIG_CLK_SUNXI_PRCM_SUN6I) += clk-sun6i-ar100.o
32
33obj-$(CONFIG_CLK_SUNXI_PRCM_SUN8I) += clk-sun8i-apb0.o
34obj-$(CONFIG_CLK_SUNXI_PRCM_SUN8I) += clk-sun6i-apb0-gates.o
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c
index 205fe8ff63f0..2a1822a22740 100644
--- a/drivers/clk/tegra/clk-divider.c
+++ b/drivers/clk/tegra/clk-divider.c
@@ -175,6 +175,7 @@ struct clk *tegra_clk_register_mc(const char *name, const char *parent_name,
175 void __iomem *reg, spinlock_t *lock) 175 void __iomem *reg, spinlock_t *lock)
176{ 176{
177 return clk_register_divider_table(NULL, name, parent_name, 177 return clk_register_divider_table(NULL, name, parent_name,
178 CLK_IS_CRITICAL, reg, 16, 1, 0, 178 CLK_IS_CRITICAL,
179 reg, 16, 1, CLK_DIVIDER_READ_ONLY,
179 mc_div_table, lock); 180 mc_div_table, lock);
180} 181}
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c
index 0621a3a82ea6..93ecb538e59b 100644
--- a/drivers/clk/tegra/clk-emc.c
+++ b/drivers/clk/tegra/clk-emc.c
@@ -121,18 +121,28 @@ static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
121 struct tegra_clk_emc *tegra; 121 struct tegra_clk_emc *tegra;
122 u8 ram_code = tegra_read_ram_code(); 122 u8 ram_code = tegra_read_ram_code();
123 struct emc_timing *timing = NULL; 123 struct emc_timing *timing = NULL;
124 int i; 124 int i, k, t;
125 125
126 tegra = container_of(hw, struct tegra_clk_emc, hw); 126 tegra = container_of(hw, struct tegra_clk_emc, hw);
127 127
128 for (i = 0; i < tegra->num_timings; i++) { 128 for (k = 0; k < tegra->num_timings; k++) {
129 if (tegra->timings[i].ram_code != ram_code) 129 if (tegra->timings[k].ram_code == ram_code)
130 continue; 130 break;
131 }
132
133 for (t = k; t < tegra->num_timings; t++) {
134 if (tegra->timings[t].ram_code != ram_code)
135 break;
136 }
131 137
138 for (i = k; i < t; i++) {
132 timing = tegra->timings + i; 139 timing = tegra->timings + i;
133 140
141 if (timing->rate < req->rate && i != t - 1)
142 continue;
143
134 if (timing->rate > req->max_rate) { 144 if (timing->rate > req->max_rate) {
135 i = max(i, 1); 145 i = max(i, k + 1);
136 req->rate = tegra->timings[i - 1].rate; 146 req->rate = tegra->timings[i - 1].rate;
137 return 0; 147 return 0;
138 } 148 }
@@ -140,10 +150,8 @@ static int emc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
140 if (timing->rate < req->min_rate) 150 if (timing->rate < req->min_rate)
141 continue; 151 continue;
142 152
143 if (timing->rate >= req->rate) { 153 req->rate = timing->rate;
144 req->rate = timing->rate; 154 return 0;
145 return 0;
146 }
147 } 155 }
148 156
149 if (timing) { 157 if (timing) {
@@ -214,7 +222,10 @@ static int emc_set_timing(struct tegra_clk_emc *tegra,
214 222
215 if (emc_get_parent(&tegra->hw) == timing->parent_index && 223 if (emc_get_parent(&tegra->hw) == timing->parent_index &&
216 clk_get_rate(timing->parent) != timing->parent_rate) { 224 clk_get_rate(timing->parent) != timing->parent_rate) {
217 BUG(); 225 WARN_ONCE(1, "parent %s rate mismatch %lu %lu\n",
226 __clk_get_name(timing->parent),
227 clk_get_rate(timing->parent),
228 timing->parent_rate);
218 return -EINVAL; 229 return -EINVAL;
219 } 230 }
220 231
@@ -282,7 +293,7 @@ static struct emc_timing *get_backup_timing(struct tegra_clk_emc *tegra,
282 for (i = timing_index+1; i < tegra->num_timings; i++) { 293 for (i = timing_index+1; i < tegra->num_timings; i++) {
283 timing = tegra->timings + i; 294 timing = tegra->timings + i;
284 if (timing->ram_code != ram_code) 295 if (timing->ram_code != ram_code)
285 continue; 296 break;
286 297
287 if (emc_parent_clk_sources[timing->parent_index] != 298 if (emc_parent_clk_sources[timing->parent_index] !=
288 emc_parent_clk_sources[ 299 emc_parent_clk_sources[
@@ -293,7 +304,7 @@ static struct emc_timing *get_backup_timing(struct tegra_clk_emc *tegra,
293 for (i = timing_index-1; i >= 0; --i) { 304 for (i = timing_index-1; i >= 0; --i) {
294 timing = tegra->timings + i; 305 timing = tegra->timings + i;
295 if (timing->ram_code != ram_code) 306 if (timing->ram_code != ram_code)
296 continue; 307 break;
297 308
298 if (emc_parent_clk_sources[timing->parent_index] != 309 if (emc_parent_clk_sources[timing->parent_index] !=
299 emc_parent_clk_sources[ 310 emc_parent_clk_sources[
@@ -433,19 +444,23 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
433 struct device_node *node, 444 struct device_node *node,
434 u32 ram_code) 445 u32 ram_code)
435{ 446{
447 struct emc_timing *timings_ptr;
436 struct device_node *child; 448 struct device_node *child;
437 int child_count = of_get_child_count(node); 449 int child_count = of_get_child_count(node);
438 int i = 0, err; 450 int i = 0, err;
451 size_t size;
439 452
440 tegra->timings = kcalloc(child_count, sizeof(struct emc_timing), 453 size = (tegra->num_timings + child_count) * sizeof(struct emc_timing);
441 GFP_KERNEL); 454
455 tegra->timings = krealloc(tegra->timings, size, GFP_KERNEL);
442 if (!tegra->timings) 456 if (!tegra->timings)
443 return -ENOMEM; 457 return -ENOMEM;
444 458
445 tegra->num_timings = child_count; 459 timings_ptr = tegra->timings + tegra->num_timings;
460 tegra->num_timings += child_count;
446 461
447 for_each_child_of_node(node, child) { 462 for_each_child_of_node(node, child) {
448 struct emc_timing *timing = tegra->timings + (i++); 463 struct emc_timing *timing = timings_ptr + (i++);
449 464
450 err = load_one_timing_from_dt(tegra, timing, child); 465 err = load_one_timing_from_dt(tegra, timing, child);
451 if (err) { 466 if (err) {
@@ -456,7 +471,7 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
456 timing->ram_code = ram_code; 471 timing->ram_code = ram_code;
457 } 472 }
458 473
459 sort(tegra->timings, tegra->num_timings, sizeof(struct emc_timing), 474 sort(timings_ptr, child_count, sizeof(struct emc_timing),
460 cmp_timings, NULL); 475 cmp_timings, NULL);
461 476
462 return 0; 477 return 0;
@@ -499,10 +514,10 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
499 * fuses until the apbmisc driver is loaded. 514 * fuses until the apbmisc driver is loaded.
500 */ 515 */
501 err = load_timings_from_dt(tegra, node, node_ram_code); 516 err = load_timings_from_dt(tegra, node, node_ram_code);
502 of_node_put(node); 517 if (err) {
503 if (err) 518 of_node_put(node);
504 return ERR_PTR(err); 519 return ERR_PTR(err);
505 break; 520 }
506 } 521 }
507 522
508 if (tegra->num_timings == 0) 523 if (tegra->num_timings == 0)
@@ -532,7 +547,5 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
532 /* Allow debugging tools to see the EMC clock */ 547 /* Allow debugging tools to see the EMC clock */
533 clk_register_clkdev(clk, "emc", "tegra-clk-debug"); 548 clk_register_clkdev(clk, "emc", "tegra-clk-debug");
534 549
535 clk_prepare_enable(clk);
536
537 return clk; 550 return clk;
538}; 551};
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index b50b7460014b..6b976b2514f7 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -444,6 +444,9 @@ static int clk_pll_enable(struct clk_hw *hw)
444 unsigned long flags = 0; 444 unsigned long flags = 0;
445 int ret; 445 int ret;
446 446
447 if (clk_pll_is_enabled(hw))
448 return 0;
449
447 if (pll->lock) 450 if (pll->lock)
448 spin_lock_irqsave(pll->lock, flags); 451 spin_lock_irqsave(pll->lock, flags);
449 452
@@ -663,8 +666,8 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll,
663 pll_override_writel(val, params->pmc_divp_reg, pll); 666 pll_override_writel(val, params->pmc_divp_reg, pll);
664 667
665 val = pll_override_readl(params->pmc_divnm_reg, pll); 668 val = pll_override_readl(params->pmc_divnm_reg, pll);
666 val &= ~(divm_mask(pll) << div_nmp->override_divm_shift) | 669 val &= ~((divm_mask(pll) << div_nmp->override_divm_shift) |
667 ~(divn_mask(pll) << div_nmp->override_divn_shift); 670 (divn_mask(pll) << div_nmp->override_divn_shift));
668 val |= (cfg->m << div_nmp->override_divm_shift) | 671 val |= (cfg->m << div_nmp->override_divm_shift) |
669 (cfg->n << div_nmp->override_divn_shift); 672 (cfg->n << div_nmp->override_divn_shift);
670 pll_override_writel(val, params->pmc_divnm_reg, pll); 673 pll_override_writel(val, params->pmc_divnm_reg, pll);
@@ -940,11 +943,16 @@ static int clk_plle_training(struct tegra_clk_pll *pll)
940static int clk_plle_enable(struct clk_hw *hw) 943static int clk_plle_enable(struct clk_hw *hw)
941{ 944{
942 struct tegra_clk_pll *pll = to_clk_pll(hw); 945 struct tegra_clk_pll *pll = to_clk_pll(hw);
943 unsigned long input_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
944 struct tegra_clk_pll_freq_table sel; 946 struct tegra_clk_pll_freq_table sel;
947 unsigned long input_rate;
945 u32 val; 948 u32 val;
946 int err; 949 int err;
947 950
951 if (clk_pll_is_enabled(hw))
952 return 0;
953
954 input_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
955
948 if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) 956 if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate))
949 return -EINVAL; 957 return -EINVAL;
950 958
@@ -1355,6 +1363,9 @@ static int clk_pllc_enable(struct clk_hw *hw)
1355 int ret; 1363 int ret;
1356 unsigned long flags = 0; 1364 unsigned long flags = 0;
1357 1365
1366 if (clk_pll_is_enabled(hw))
1367 return 0;
1368
1358 if (pll->lock) 1369 if (pll->lock)
1359 spin_lock_irqsave(pll->lock, flags); 1370 spin_lock_irqsave(pll->lock, flags);
1360 1371
@@ -1567,7 +1578,12 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw)
1567 u32 val; 1578 u32 val;
1568 int ret; 1579 int ret;
1569 unsigned long flags = 0; 1580 unsigned long flags = 0;
1570 unsigned long input_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); 1581 unsigned long input_rate;
1582
1583 if (clk_pll_is_enabled(hw))
1584 return 0;
1585
1586 input_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
1571 1587
1572 if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) 1588 if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate))
1573 return -EINVAL; 1589 return -EINVAL;
@@ -1704,6 +1720,9 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw)
1704 return -EINVAL; 1720 return -EINVAL;
1705 } 1721 }
1706 1722
1723 if (clk_pll_is_enabled(hw))
1724 return 0;
1725
1707 input_rate = clk_hw_get_rate(__clk_get_hw(osc)); 1726 input_rate = clk_hw_get_rate(__clk_get_hw(osc));
1708 1727
1709 if (pll->lock) 1728 if (pll->lock)
@@ -2379,6 +2398,16 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name,
2379 return clk; 2398 return clk;
2380} 2399}
2381 2400
2401static int clk_plle_tegra210_is_enabled(struct clk_hw *hw)
2402{
2403 struct tegra_clk_pll *pll = to_clk_pll(hw);
2404 u32 val;
2405
2406 val = pll_readl_base(pll);
2407
2408 return val & PLLE_BASE_ENABLE ? 1 : 0;
2409}
2410
2382static int clk_plle_tegra210_enable(struct clk_hw *hw) 2411static int clk_plle_tegra210_enable(struct clk_hw *hw)
2383{ 2412{
2384 struct tegra_clk_pll *pll = to_clk_pll(hw); 2413 struct tegra_clk_pll *pll = to_clk_pll(hw);
@@ -2386,7 +2415,12 @@ static int clk_plle_tegra210_enable(struct clk_hw *hw)
2386 u32 val; 2415 u32 val;
2387 int ret = 0; 2416 int ret = 0;
2388 unsigned long flags = 0; 2417 unsigned long flags = 0;
2389 unsigned long input_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); 2418 unsigned long input_rate;
2419
2420 if (clk_plle_tegra210_is_enabled(hw))
2421 return 0;
2422
2423 input_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
2390 2424
2391 if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) 2425 if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate))
2392 return -EINVAL; 2426 return -EINVAL;
@@ -2497,16 +2531,6 @@ out:
2497 spin_unlock_irqrestore(pll->lock, flags); 2531 spin_unlock_irqrestore(pll->lock, flags);
2498} 2532}
2499 2533
2500static int clk_plle_tegra210_is_enabled(struct clk_hw *hw)
2501{
2502 struct tegra_clk_pll *pll = to_clk_pll(hw);
2503 u32 val;
2504
2505 val = pll_readl_base(pll);
2506
2507 return val & PLLE_BASE_ENABLE ? 1 : 0;
2508}
2509
2510static const struct clk_ops tegra_clk_plle_tegra210_ops = { 2534static const struct clk_ops tegra_clk_plle_tegra210_ops = {
2511 .is_enabled = clk_plle_tegra210_is_enabled, 2535 .is_enabled = clk_plle_tegra210_is_enabled,
2512 .enable = clk_plle_tegra210_enable, 2536 .enable = clk_plle_tegra210_enable,
diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
index 84267cfc4433..b5ff76c663f8 100644
--- a/drivers/clk/tegra/clk-super.c
+++ b/drivers/clk/tegra/clk-super.c
@@ -121,7 +121,7 @@ out:
121 return err; 121 return err;
122} 122}
123 123
124const struct clk_ops tegra_clk_super_mux_ops = { 124static const struct clk_ops tegra_clk_super_mux_ops = {
125 .get_parent = clk_super_get_parent, 125 .get_parent = clk_super_get_parent,
126 .set_parent = clk_super_set_parent, 126 .set_parent = clk_super_set_parent,
127}; 127};
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index df0018f7bf7e..d7bee144f4b7 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -413,7 +413,6 @@ static struct tegra_clk_pll_params pll_m_params = {
413 .base_reg = PLLM_BASE, 413 .base_reg = PLLM_BASE,
414 .misc_reg = PLLM_MISC, 414 .misc_reg = PLLM_MISC,
415 .lock_mask = PLL_BASE_LOCK, 415 .lock_mask = PLL_BASE_LOCK,
416 .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
417 .lock_delay = 300, 416 .lock_delay = 300,
418 .max_p = 5, 417 .max_p = 5,
419 .pdiv_tohw = pllm_p, 418 .pdiv_tohw = pllm_p,
@@ -421,7 +420,7 @@ static struct tegra_clk_pll_params pll_m_params = {
421 .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, 420 .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE,
422 .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, 421 .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2,
423 .freq_table = pll_m_freq_table, 422 .freq_table = pll_m_freq_table,
424 .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, 423 .flags = TEGRA_PLL_USE_LOCK,
425}; 424};
426 425
427static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { 426static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
@@ -1466,9 +1465,9 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
1466 tegra_pmc_clk_init(pmc_base, tegra124_clks); 1465 tegra_pmc_clk_init(pmc_base, tegra124_clks);
1467 1466
1468 /* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */ 1467 /* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */
1469 plld_base = clk_readl(clk_base + PLLD_BASE); 1468 plld_base = readl(clk_base + PLLD_BASE);
1470 plld_base &= ~BIT(25); 1469 plld_base &= ~BIT(25);
1471 clk_writel(plld_base, clk_base + PLLD_BASE); 1470 writel(plld_base, clk_base + PLLD_BASE);
1472} 1471}
1473 1472
1474/** 1473/**
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 7545af763d7a..ed3c7df75d1e 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -3557,7 +3557,7 @@ static void __init tegra210_clock_init(struct device_node *np)
3557 if (!clks) 3557 if (!clks)
3558 return; 3558 return;
3559 3559
3560 value = clk_readl(clk_base + SPARE_REG0) >> CLK_M_DIVISOR_SHIFT; 3560 value = readl(clk_base + SPARE_REG0) >> CLK_M_DIVISOR_SHIFT;
3561 clk_m_div = (value & CLK_M_DIVISOR_MASK) + 1; 3561 clk_m_div = (value & CLK_M_DIVISOR_MASK) + 1;
3562 3562
3563 if (tegra_osc_clk_init(clk_base, tegra210_clks, tegra210_input_freq, 3563 if (tegra_osc_clk_init(clk_base, tegra210_clks, tegra210_input_freq,
@@ -3574,9 +3574,9 @@ static void __init tegra210_clock_init(struct device_node *np)
3574 tegra_pmc_clk_init(pmc_base, tegra210_clks); 3574 tegra_pmc_clk_init(pmc_base, tegra210_clks);
3575 3575
3576 /* For Tegra210, PLLD is the only source for DSIA & DSIB */ 3576 /* For Tegra210, PLLD is the only source for DSIA & DSIB */
3577 value = clk_readl(clk_base + PLLD_BASE); 3577 value = readl(clk_base + PLLD_BASE);
3578 value &= ~BIT(25); 3578 value &= ~BIT(25);
3579 clk_writel(value, clk_base + PLLD_BASE); 3579 writel(value, clk_base + PLLD_BASE);
3580 3580
3581 tegra_clk_apply_init_table = tegra210_clock_apply_init_table; 3581 tegra_clk_apply_init_table = tegra210_clock_apply_init_table;
3582 3582
diff --git a/drivers/clk/ti/clk-7xx-compat.c b/drivers/clk/ti/clk-7xx-compat.c
index e3cb7f0b03ae..b3cd2296f84b 100644
--- a/drivers/clk/ti/clk-7xx-compat.c
+++ b/drivers/clk/ti/clk-7xx-compat.c
@@ -362,7 +362,7 @@ static const struct omap_clkctrl_reg_data dra7_l3init_clkctrl_regs[] __initconst
362 { DRA7_MMC2_CLKCTRL, dra7_mmc2_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0010:25" }, 362 { DRA7_MMC2_CLKCTRL, dra7_mmc2_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0010:25" },
363 { DRA7_USB_OTG_SS2_CLKCTRL, dra7_usb_otg_ss2_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, 363 { DRA7_USB_OTG_SS2_CLKCTRL, dra7_usb_otg_ss2_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
364 { DRA7_USB_OTG_SS3_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, 364 { DRA7_USB_OTG_SS3_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
365 { DRA7_USB_OTG_SS4_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, 365 { DRA7_USB_OTG_SS4_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_DRA74 | CLKF_SOC_DRA76, "dpll_core_h13x2_ck" },
366 { DRA7_SATA_CLKCTRL, dra7_sata_bit_data, CLKF_SW_SUP, "func_48m_fclk" }, 366 { DRA7_SATA_CLKCTRL, dra7_sata_bit_data, CLKF_SW_SUP, "func_48m_fclk" },
367 { DRA7_PCIE1_CLKCTRL, dra7_pcie1_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" }, 367 { DRA7_PCIE1_CLKCTRL, dra7_pcie1_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" },
368 { DRA7_PCIE2_CLKCTRL, dra7_pcie2_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" }, 368 { DRA7_PCIE2_CLKCTRL, dra7_pcie2_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" },
@@ -662,7 +662,7 @@ static const struct omap_clkctrl_reg_data dra7_l4per_clkctrl_regs[] __initconst
662 { DRA7_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, 662 { DRA7_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
663 { DRA7_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, 663 { DRA7_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
664 { DRA7_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, 664 { DRA7_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
665 { DRA7_RNG_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, 665 { DRA7_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "l3_iclk_div", "l4sec_clkdm" },
666 { DRA7_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, 666 { DRA7_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" },
667 { DRA7_UART7_CLKCTRL, dra7_uart7_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01d0:24", "l4per2_clkdm" }, 667 { DRA7_UART7_CLKCTRL, dra7_uart7_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01d0:24", "l4per2_clkdm" },
668 { DRA7_UART8_CLKCTRL, dra7_uart8_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01e0:24", "l4per2_clkdm" }, 668 { DRA7_UART8_CLKCTRL, dra7_uart8_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01e0:24", "l4per2_clkdm" },
@@ -704,7 +704,7 @@ static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initcons
704 { DRA7_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, 704 { DRA7_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
705 { DRA7_GPIO1_CLKCTRL, dra7_gpio1_bit_data, CLKF_HW_SUP, "wkupaon_iclk_mux" }, 705 { DRA7_GPIO1_CLKCTRL, dra7_gpio1_bit_data, CLKF_HW_SUP, "wkupaon_iclk_mux" },
706 { DRA7_TIMER1_CLKCTRL, dra7_timer1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0020:24" }, 706 { DRA7_TIMER1_CLKCTRL, dra7_timer1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0020:24" },
707 { DRA7_TIMER12_CLKCTRL, NULL, 0, "secure_32k_clk_src_ck" }, 707 { DRA7_TIMER12_CLKCTRL, NULL, CLKF_SOC_NONSEC, "secure_32k_clk_src_ck" },
708 { DRA7_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" }, 708 { DRA7_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
709 { DRA7_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0060:24" }, 709 { DRA7_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0060:24" },
710 { DRA7_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0068:24" }, 710 { DRA7_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0068:24" },
diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c
index 597fb4a59318..79186b918d87 100644
--- a/drivers/clk/ti/clk-7xx.c
+++ b/drivers/clk/ti/clk-7xx.c
@@ -348,7 +348,7 @@ static const struct omap_clkctrl_reg_data dra7_l3init_clkctrl_regs[] __initconst
348 { DRA7_L3INIT_MMC2_CLKCTRL, dra7_mmc2_bit_data, CLKF_SW_SUP, "l3init-clkctrl:0010:25" }, 348 { DRA7_L3INIT_MMC2_CLKCTRL, dra7_mmc2_bit_data, CLKF_SW_SUP, "l3init-clkctrl:0010:25" },
349 { DRA7_L3INIT_USB_OTG_SS2_CLKCTRL, dra7_usb_otg_ss2_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, 349 { DRA7_L3INIT_USB_OTG_SS2_CLKCTRL, dra7_usb_otg_ss2_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
350 { DRA7_L3INIT_USB_OTG_SS3_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, 350 { DRA7_L3INIT_USB_OTG_SS3_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" },
351 { DRA7_L3INIT_USB_OTG_SS4_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, 351 { DRA7_L3INIT_USB_OTG_SS4_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_DRA74 | CLKF_SOC_DRA76, "dpll_core_h13x2_ck" },
352 { DRA7_L3INIT_SATA_CLKCTRL, dra7_sata_bit_data, CLKF_SW_SUP, "func_48m_fclk" }, 352 { DRA7_L3INIT_SATA_CLKCTRL, dra7_sata_bit_data, CLKF_SW_SUP, "func_48m_fclk" },
353 { DRA7_L3INIT_OCP2SCP1_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" }, 353 { DRA7_L3INIT_OCP2SCP1_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" },
354 { DRA7_L3INIT_OCP2SCP3_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" }, 354 { DRA7_L3INIT_OCP2SCP3_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" },
@@ -590,7 +590,7 @@ static const struct omap_clkctrl_reg_data dra7_l4sec_clkctrl_regs[] __initconst
590 { DRA7_L4SEC_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, 590 { DRA7_L4SEC_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
591 { DRA7_L4SEC_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, 591 { DRA7_L4SEC_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
592 { DRA7_L4SEC_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, 592 { DRA7_L4SEC_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
593 { DRA7_L4SEC_RNG_CLKCTRL, NULL, CLKF_HW_SUP, "" }, 593 { DRA7_L4SEC_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
594 { DRA7_L4SEC_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, 594 { DRA7_L4SEC_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
595 { 0 }, 595 { 0 },
596}; 596};
@@ -757,7 +757,7 @@ static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initcons
757 { DRA7_WKUPAON_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, 757 { DRA7_WKUPAON_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
758 { DRA7_WKUPAON_GPIO1_CLKCTRL, dra7_gpio1_bit_data, CLKF_HW_SUP, "wkupaon_iclk_mux" }, 758 { DRA7_WKUPAON_GPIO1_CLKCTRL, dra7_gpio1_bit_data, CLKF_HW_SUP, "wkupaon_iclk_mux" },
759 { DRA7_WKUPAON_TIMER1_CLKCTRL, dra7_timer1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0020:24" }, 759 { DRA7_WKUPAON_TIMER1_CLKCTRL, dra7_timer1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0020:24" },
760 { DRA7_WKUPAON_TIMER12_CLKCTRL, NULL, 0, "secure_32k_clk_src_ck" }, 760 { DRA7_WKUPAON_TIMER12_CLKCTRL, NULL, CLKF_SOC_NONSEC, "secure_32k_clk_src_ck" },
761 { DRA7_WKUPAON_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" }, 761 { DRA7_WKUPAON_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
762 { DRA7_WKUPAON_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0060:24" }, 762 { DRA7_WKUPAON_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0060:24" },
763 { DRA7_WKUPAON_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0068:24" }, 763 { DRA7_WKUPAON_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0068:24" },
diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c
index 639f515e08f0..96d65a1cf7be 100644
--- a/drivers/clk/ti/clkctrl.c
+++ b/drivers/clk/ti/clkctrl.c
@@ -446,6 +446,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
446 u32 addr; 446 u32 addr;
447 int ret; 447 int ret;
448 char *c; 448 char *c;
449 u16 soc_mask = 0;
449 450
450 if (!(ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) && 451 if (!(ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) &&
451 of_node_name_eq(node, "clk")) 452 of_node_name_eq(node, "clk"))
@@ -469,6 +470,13 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
469 else 470 else
470 data = dra7_clkctrl_data; 471 data = dra7_clkctrl_data;
471 } 472 }
473
474 if (of_machine_is_compatible("ti,dra72"))
475 soc_mask = CLKF_SOC_DRA72;
476 if (of_machine_is_compatible("ti,dra74"))
477 soc_mask = CLKF_SOC_DRA74;
478 if (of_machine_is_compatible("ti,dra76"))
479 soc_mask = CLKF_SOC_DRA76;
472#endif 480#endif
473#ifdef CONFIG_SOC_AM33XX 481#ifdef CONFIG_SOC_AM33XX
474 if (of_machine_is_compatible("ti,am33xx")) { 482 if (of_machine_is_compatible("ti,am33xx")) {
@@ -501,6 +509,9 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
501 data = dm816_clkctrl_data; 509 data = dm816_clkctrl_data;
502#endif 510#endif
503 511
512 if (ti_clk_get_features()->flags & TI_CLK_DEVICE_TYPE_GP)
513 soc_mask |= CLKF_SOC_NONSEC;
514
504 while (data->addr) { 515 while (data->addr) {
505 if (addr == data->addr) 516 if (addr == data->addr)
506 break; 517 break;
@@ -562,6 +573,12 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
562 reg_data = data->regs; 573 reg_data = data->regs;
563 574
564 while (reg_data->parent) { 575 while (reg_data->parent) {
576 if ((reg_data->flags & CLKF_SOC_MASK) &&
577 (reg_data->flags & soc_mask) == 0) {
578 reg_data++;
579 continue;
580 }
581
565 hw = kzalloc(sizeof(*hw), GFP_KERNEL); 582 hw = kzalloc(sizeof(*hw), GFP_KERNEL);
566 if (!hw) 583 if (!hw)
567 return; 584 return;
diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index 1c0fac59d809..e4b8392ff63c 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -83,6 +83,13 @@ enum {
83#define CLKF_HW_SUP BIT(6) 83#define CLKF_HW_SUP BIT(6)
84#define CLKF_NO_IDLEST BIT(7) 84#define CLKF_NO_IDLEST BIT(7)
85 85
86#define CLKF_SOC_MASK GENMASK(11, 8)
87
88#define CLKF_SOC_NONSEC BIT(8)
89#define CLKF_SOC_DRA72 BIT(9)
90#define CLKF_SOC_DRA74 BIT(10)
91#define CLKF_SOC_DRA76 BIT(11)
92
86#define CLK(dev, con, ck) \ 93#define CLK(dev, con, ck) \
87 { \ 94 { \
88 .lk = { \ 95 .lk = { \
@@ -303,7 +310,6 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
303int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, 310int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw,
304 struct clk_rate_request *req); 311 struct clk_rate_request *req);
305int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw)); 312int omap2_clk_for_each(int (*fn)(struct clk_hw_omap *hw));
306bool omap2_clk_is_hw_omap(struct clk_hw *hw);
307 313
308extern struct ti_clk_ll_ops *ti_clk_ll_ops; 314extern struct ti_clk_ll_ops *ti_clk_ll_ops;
309 315
diff --git a/drivers/clk/ux500/clk-sysctrl.c b/drivers/clk/ux500/clk-sysctrl.c
index 7c0403b733ae..698306f4801f 100644
--- a/drivers/clk/ux500/clk-sysctrl.c
+++ b/drivers/clk/ux500/clk-sysctrl.c
@@ -42,7 +42,8 @@ static int clk_sysctrl_prepare(struct clk_hw *hw)
42 clk->reg_bits[0]); 42 clk->reg_bits[0]);
43 43
44 if (!ret && clk->enable_delay_us) 44 if (!ret && clk->enable_delay_us)
45 usleep_range(clk->enable_delay_us, clk->enable_delay_us); 45 usleep_range(clk->enable_delay_us, clk->enable_delay_us +
46 (clk->enable_delay_us >> 2));
46 47
47 return ret; 48 return ret;
48} 49}
diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c
index d7b53ac8ad11..4b9d5c14c400 100644
--- a/drivers/clk/zynq/clkc.c
+++ b/drivers/clk/zynq/clkc.c
@@ -158,7 +158,7 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
158 clks[fclk] = clk_register_gate(NULL, clk_name, 158 clks[fclk] = clk_register_gate(NULL, clk_name,
159 div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg, 159 div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg,
160 0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock); 160 0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock);
161 enable_reg = clk_readl(fclk_gate_reg) & 1; 161 enable_reg = readl(fclk_gate_reg) & 1;
162 if (enable && !enable_reg) { 162 if (enable && !enable_reg) {
163 if (clk_prepare_enable(clks[fclk])) 163 if (clk_prepare_enable(clks[fclk]))
164 pr_warn("%s: FCLK%u enable failed\n", __func__, 164 pr_warn("%s: FCLK%u enable failed\n", __func__,
@@ -287,7 +287,7 @@ static void __init zynq_clk_setup(struct device_node *np)
287 SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock); 287 SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock);
288 288
289 /* CPU clocks */ 289 /* CPU clocks */
290 tmp = clk_readl(SLCR_621_TRUE) & 1; 290 tmp = readl(SLCR_621_TRUE) & 1;
291 clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, 291 clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4,
292 CLK_SET_RATE_NO_REPARENT, SLCR_ARM_CLK_CTRL, 4, 2, 0, 292 CLK_SET_RATE_NO_REPARENT, SLCR_ARM_CLK_CTRL, 4, 2, 0,
293 &armclk_lock); 293 &armclk_lock);
@@ -510,7 +510,7 @@ static void __init zynq_clk_setup(struct device_node *np)
510 &dbgclk_lock); 510 &dbgclk_lock);
511 511
512 /* leave debug clocks in the state the bootloader set them up to */ 512 /* leave debug clocks in the state the bootloader set them up to */
513 tmp = clk_readl(SLCR_DBG_CLK_CTRL); 513 tmp = readl(SLCR_DBG_CLK_CTRL);
514 if (tmp & DBG_CLK_CTRL_CLKACT_TRC) 514 if (tmp & DBG_CLK_CTRL_CLKACT_TRC)
515 if (clk_prepare_enable(clks[dbg_trc])) 515 if (clk_prepare_enable(clks[dbg_trc]))
516 pr_warn("%s: trace clk enable failed\n", __func__); 516 pr_warn("%s: trace clk enable failed\n", __func__);
diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c
index 00d72fb5c036..800b70ee19b3 100644
--- a/drivers/clk/zynq/pll.c
+++ b/drivers/clk/zynq/pll.c
@@ -90,7 +90,7 @@ static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
90 * makes probably sense to redundantly save fbdiv in the struct 90 * makes probably sense to redundantly save fbdiv in the struct
91 * zynq_pll to save the IO access. 91 * zynq_pll to save the IO access.
92 */ 92 */
93 fbdiv = (clk_readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >> 93 fbdiv = (readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >>
94 PLLCTRL_FBDIV_SHIFT; 94 PLLCTRL_FBDIV_SHIFT;
95 95
96 return parent_rate * fbdiv; 96 return parent_rate * fbdiv;
@@ -112,7 +112,7 @@ static int zynq_pll_is_enabled(struct clk_hw *hw)
112 112
113 spin_lock_irqsave(clk->lock, flags); 113 spin_lock_irqsave(clk->lock, flags);
114 114
115 reg = clk_readl(clk->pll_ctrl); 115 reg = readl(clk->pll_ctrl);
116 116
117 spin_unlock_irqrestore(clk->lock, flags); 117 spin_unlock_irqrestore(clk->lock, flags);
118 118
@@ -138,10 +138,10 @@ static int zynq_pll_enable(struct clk_hw *hw)
138 /* Power up PLL and wait for lock */ 138 /* Power up PLL and wait for lock */
139 spin_lock_irqsave(clk->lock, flags); 139 spin_lock_irqsave(clk->lock, flags);
140 140
141 reg = clk_readl(clk->pll_ctrl); 141 reg = readl(clk->pll_ctrl);
142 reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK); 142 reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK);
143 clk_writel(reg, clk->pll_ctrl); 143 writel(reg, clk->pll_ctrl);
144 while (!(clk_readl(clk->pll_status) & (1 << clk->lockbit))) 144 while (!(readl(clk->pll_status) & (1 << clk->lockbit)))
145 ; 145 ;
146 146
147 spin_unlock_irqrestore(clk->lock, flags); 147 spin_unlock_irqrestore(clk->lock, flags);
@@ -168,9 +168,9 @@ static void zynq_pll_disable(struct clk_hw *hw)
168 /* shut down PLL */ 168 /* shut down PLL */
169 spin_lock_irqsave(clk->lock, flags); 169 spin_lock_irqsave(clk->lock, flags);
170 170
171 reg = clk_readl(clk->pll_ctrl); 171 reg = readl(clk->pll_ctrl);
172 reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK; 172 reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK;
173 clk_writel(reg, clk->pll_ctrl); 173 writel(reg, clk->pll_ctrl);
174 174
175 spin_unlock_irqrestore(clk->lock, flags); 175 spin_unlock_irqrestore(clk->lock, flags);
176} 176}
@@ -223,9 +223,9 @@ struct clk *clk_register_zynq_pll(const char *name, const char *parent,
223 223
224 spin_lock_irqsave(pll->lock, flags); 224 spin_lock_irqsave(pll->lock, flags);
225 225
226 reg = clk_readl(pll->pll_ctrl); 226 reg = readl(pll->pll_ctrl);
227 reg &= ~PLLCTRL_BPQUAL_MASK; 227 reg &= ~PLLCTRL_BPQUAL_MASK;
228 clk_writel(reg, pll->pll_ctrl); 228 writel(reg, pll->pll_ctrl);
229 229
230 spin_unlock_irqrestore(pll->lock, flags); 230 spin_unlock_irqrestore(pll->lock, flags);
231 231
diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c
index 4143f560c28d..0af8f74c5fa5 100644
--- a/drivers/clk/zynqmp/clk-mux-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c
@@ -138,4 +138,3 @@ struct clk_hw *zynqmp_clk_register_mux(const char *name, u32 clk_id,
138 138
139 return hw; 139 return hw;
140} 140}
141EXPORT_SYMBOL_GPL(zynqmp_clk_register_mux);
diff --git a/drivers/clk/zynqmp/clk-zynqmp.h b/drivers/clk/zynqmp/clk-zynqmp.h
index 7ab163b67249..fec9a15c8786 100644
--- a/drivers/clk/zynqmp/clk-zynqmp.h
+++ b/drivers/clk/zynqmp/clk-zynqmp.h
@@ -10,12 +10,6 @@
10 10
11#include <linux/firmware/xlnx-zynqmp.h> 11#include <linux/firmware/xlnx-zynqmp.h>
12 12
13/* Clock APIs payload parameters */
14#define CLK_GET_NAME_RESP_LEN 16
15#define CLK_GET_TOPOLOGY_RESP_WORDS 3
16#define CLK_GET_PARENTS_RESP_WORDS 3
17#define CLK_GET_ATTR_RESP_WORDS 1
18
19enum topology_type { 13enum topology_type {
20 TYPE_INVALID, 14 TYPE_INVALID,
21 TYPE_MUX, 15 TYPE_MUX,
diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c
index b0908ec62f73..8febd2431545 100644
--- a/drivers/clk/zynqmp/clkc.c
+++ b/drivers/clk/zynqmp/clkc.c
@@ -21,24 +21,6 @@
21#define MAX_NODES 6 21#define MAX_NODES 6
22#define MAX_NAME_LEN 50 22#define MAX_NAME_LEN 50
23 23
24#define CLK_TYPE_SHIFT 2
25
26#define PM_API_PAYLOAD_LEN 3
27
28#define NA_PARENT 0xFFFFFFFF
29#define DUMMY_PARENT 0xFFFFFFFE
30
31#define CLK_TYPE_FIELD_LEN 4
32#define CLK_TOPOLOGY_NODE_OFFSET 16
33#define NODES_PER_RESP 3
34
35#define CLK_TYPE_FIELD_MASK 0xF
36#define CLK_FLAG_FIELD_MASK GENMASK(21, 8)
37#define CLK_TYPE_FLAG_FIELD_MASK GENMASK(31, 24)
38
39#define CLK_PARENTS_ID_LEN 16
40#define CLK_PARENTS_ID_MASK 0xFFFF
41
42/* Flags for parents */ 24/* Flags for parents */
43#define PARENT_CLK_SELF 0 25#define PARENT_CLK_SELF 0
44#define PARENT_CLK_NODE1 1 26#define PARENT_CLK_NODE1 1
@@ -52,7 +34,10 @@
52#define END_OF_PARENTS 1 34#define END_OF_PARENTS 1
53#define RESERVED_CLK_NAME "" 35#define RESERVED_CLK_NAME ""
54 36
55#define CLK_VALID_MASK 0x1 37#define CLK_GET_NAME_RESP_LEN 16
38#define CLK_GET_TOPOLOGY_RESP_WORDS 3
39#define CLK_GET_PARENTS_RESP_WORDS 3
40#define CLK_GET_ATTR_RESP_WORDS 1
56 41
57enum clk_type { 42enum clk_type {
58 CLK_TYPE_OUTPUT, 43 CLK_TYPE_OUTPUT,
@@ -80,6 +65,7 @@ struct clock_parent {
80 * @num_nodes: Number of nodes present in topology 65 * @num_nodes: Number of nodes present in topology
81 * @parent: Parent of clock 66 * @parent: Parent of clock
82 * @num_parents: Number of parents of clock 67 * @num_parents: Number of parents of clock
68 * @clk_id: Clock id
83 */ 69 */
84struct zynqmp_clock { 70struct zynqmp_clock {
85 char clk_name[MAX_NAME_LEN]; 71 char clk_name[MAX_NAME_LEN];
@@ -89,6 +75,36 @@ struct zynqmp_clock {
89 u32 num_nodes; 75 u32 num_nodes;
90 struct clock_parent parent[MAX_PARENT]; 76 struct clock_parent parent[MAX_PARENT];
91 u32 num_parents; 77 u32 num_parents;
78 u32 clk_id;
79};
80
81struct name_resp {
82 char name[CLK_GET_NAME_RESP_LEN];
83};
84
85struct topology_resp {
86#define CLK_TOPOLOGY_TYPE GENMASK(3, 0)
87#define CLK_TOPOLOGY_FLAGS GENMASK(23, 8)
88#define CLK_TOPOLOGY_TYPE_FLAGS GENMASK(31, 24)
89 u32 topology[CLK_GET_TOPOLOGY_RESP_WORDS];
90};
91
92struct parents_resp {
93#define NA_PARENT 0xFFFFFFFF
94#define DUMMY_PARENT 0xFFFFFFFE
95#define CLK_PARENTS_ID GENMASK(15, 0)
96#define CLK_PARENTS_FLAGS GENMASK(31, 16)
97 u32 parents[CLK_GET_PARENTS_RESP_WORDS];
98};
99
100struct attr_resp {
101#define CLK_ATTR_VALID BIT(0)
102#define CLK_ATTR_TYPE BIT(2)
103#define CLK_ATTR_NODE_INDEX GENMASK(13, 0)
104#define CLK_ATTR_NODE_TYPE GENMASK(19, 14)
105#define CLK_ATTR_NODE_SUBCLASS GENMASK(25, 20)
106#define CLK_ATTR_NODE_CLASS GENMASK(31, 26)
107 u32 attr[CLK_GET_ATTR_RESP_WORDS];
92}; 108};
93 109
94static const char clk_type_postfix[][10] = { 110static const char clk_type_postfix[][10] = {
@@ -199,14 +215,15 @@ static int zynqmp_pm_clock_get_num_clocks(u32 *nclocks)
199/** 215/**
200 * zynqmp_pm_clock_get_name() - Get the name of clock for given id 216 * zynqmp_pm_clock_get_name() - Get the name of clock for given id
201 * @clock_id: ID of the clock to be queried 217 * @clock_id: ID of the clock to be queried
202 * @name: Name of given clock 218 * @response: Name of the clock with the given id
203 * 219 *
204 * This function is used to get name of clock specified by given 220 * This function is used to get name of clock specified by given
205 * clock ID. 221 * clock ID.
206 * 222 *
207 * Return: Returns 0, in case of error name would be 0 223 * Return: Returns 0
208 */ 224 */
209static int zynqmp_pm_clock_get_name(u32 clock_id, char *name) 225static int zynqmp_pm_clock_get_name(u32 clock_id,
226 struct name_resp *response)
210{ 227{
211 struct zynqmp_pm_query_data qdata = {0}; 228 struct zynqmp_pm_query_data qdata = {0};
212 u32 ret_payload[PAYLOAD_ARG_CNT]; 229 u32 ret_payload[PAYLOAD_ARG_CNT];
@@ -215,7 +232,7 @@ static int zynqmp_pm_clock_get_name(u32 clock_id, char *name)
215 qdata.arg1 = clock_id; 232 qdata.arg1 = clock_id;
216 233
217 eemi_ops->query_data(qdata, ret_payload); 234 eemi_ops->query_data(qdata, ret_payload);
218 memcpy(name, ret_payload, CLK_GET_NAME_RESP_LEN); 235 memcpy(response, ret_payload, sizeof(*response));
219 236
220 return 0; 237 return 0;
221} 238}
@@ -224,7 +241,7 @@ static int zynqmp_pm_clock_get_name(u32 clock_id, char *name)
224 * zynqmp_pm_clock_get_topology() - Get the topology of clock for given id 241 * zynqmp_pm_clock_get_topology() - Get the topology of clock for given id
225 * @clock_id: ID of the clock to be queried 242 * @clock_id: ID of the clock to be queried
226 * @index: Node index of clock topology 243 * @index: Node index of clock topology
227 * @topology: Buffer to store nodes in topology and flags 244 * @response: Buffer used for the topology response
228 * 245 *
229 * This function is used to get topology information for the clock 246 * This function is used to get topology information for the clock
230 * specified by given clock ID. 247 * specified by given clock ID.
@@ -237,7 +254,8 @@ static int zynqmp_pm_clock_get_name(u32 clock_id, char *name)
237 * 254 *
238 * Return: 0 on success else error+reason 255 * Return: 0 on success else error+reason
239 */ 256 */
240static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index, u32 *topology) 257static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index,
258 struct topology_resp *response)
241{ 259{
242 struct zynqmp_pm_query_data qdata = {0}; 260 struct zynqmp_pm_query_data qdata = {0};
243 u32 ret_payload[PAYLOAD_ARG_CNT]; 261 u32 ret_payload[PAYLOAD_ARG_CNT];
@@ -248,7 +266,7 @@ static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index, u32 *topology)
248 qdata.arg2 = index; 266 qdata.arg2 = index;
249 267
250 ret = eemi_ops->query_data(qdata, ret_payload); 268 ret = eemi_ops->query_data(qdata, ret_payload);
251 memcpy(topology, &ret_payload[1], CLK_GET_TOPOLOGY_RESP_WORDS * 4); 269 memcpy(response, &ret_payload[1], sizeof(*response));
252 270
253 return ret; 271 return ret;
254} 272}
@@ -297,7 +315,7 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id,
297 * zynqmp_pm_clock_get_parents() - Get the first 3 parents of clock for given id 315 * zynqmp_pm_clock_get_parents() - Get the first 3 parents of clock for given id
298 * @clock_id: Clock ID 316 * @clock_id: Clock ID
299 * @index: Parent index 317 * @index: Parent index
300 * @parents: 3 parents of the given clock 318 * @response: Parents of the given clock
301 * 319 *
302 * This function is used to get 3 parents for the clock specified by 320 * This function is used to get 3 parents for the clock specified by
303 * given clock ID. 321 * given clock ID.
@@ -310,7 +328,8 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id,
310 * 328 *
311 * Return: 0 on success else error+reason 329 * Return: 0 on success else error+reason
312 */ 330 */
313static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index, u32 *parents) 331static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index,
332 struct parents_resp *response)
314{ 333{
315 struct zynqmp_pm_query_data qdata = {0}; 334 struct zynqmp_pm_query_data qdata = {0};
316 u32 ret_payload[PAYLOAD_ARG_CNT]; 335 u32 ret_payload[PAYLOAD_ARG_CNT];
@@ -321,7 +340,7 @@ static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index, u32 *parents)
321 qdata.arg2 = index; 340 qdata.arg2 = index;
322 341
323 ret = eemi_ops->query_data(qdata, ret_payload); 342 ret = eemi_ops->query_data(qdata, ret_payload);
324 memcpy(parents, &ret_payload[1], CLK_GET_PARENTS_RESP_WORDS * 4); 343 memcpy(response, &ret_payload[1], sizeof(*response));
325 344
326 return ret; 345 return ret;
327} 346}
@@ -329,13 +348,14 @@ static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index, u32 *parents)
329/** 348/**
330 * zynqmp_pm_clock_get_attributes() - Get the attributes of clock for given id 349 * zynqmp_pm_clock_get_attributes() - Get the attributes of clock for given id
331 * @clock_id: Clock ID 350 * @clock_id: Clock ID
332 * @attr: Clock attributes 351 * @response: Clock attributes response
333 * 352 *
334 * This function is used to get clock's attributes(e.g. valid, clock type, etc). 353 * This function is used to get clock's attributes(e.g. valid, clock type, etc).
335 * 354 *
336 * Return: 0 on success else error+reason 355 * Return: 0 on success else error+reason
337 */ 356 */
338static int zynqmp_pm_clock_get_attributes(u32 clock_id, u32 *attr) 357static int zynqmp_pm_clock_get_attributes(u32 clock_id,
358 struct attr_resp *response)
339{ 359{
340 struct zynqmp_pm_query_data qdata = {0}; 360 struct zynqmp_pm_query_data qdata = {0};
341 u32 ret_payload[PAYLOAD_ARG_CNT]; 361 u32 ret_payload[PAYLOAD_ARG_CNT];
@@ -345,7 +365,7 @@ static int zynqmp_pm_clock_get_attributes(u32 clock_id, u32 *attr)
345 qdata.arg1 = clock_id; 365 qdata.arg1 = clock_id;
346 366
347 ret = eemi_ops->query_data(qdata, ret_payload); 367 ret = eemi_ops->query_data(qdata, ret_payload);
348 memcpy(attr, &ret_payload[1], CLK_GET_ATTR_RESP_WORDS * 4); 368 memcpy(response, &ret_payload[1], sizeof(*response));
349 369
350 return ret; 370 return ret;
351} 371}
@@ -354,24 +374,28 @@ static int zynqmp_pm_clock_get_attributes(u32 clock_id, u32 *attr)
354 * __zynqmp_clock_get_topology() - Get topology data of clock from firmware 374 * __zynqmp_clock_get_topology() - Get topology data of clock from firmware
355 * response data 375 * response data
356 * @topology: Clock topology 376 * @topology: Clock topology
357 * @data: Clock topology data received from firmware 377 * @response: Clock topology data received from firmware
358 * @nnodes: Number of nodes 378 * @nnodes: Number of nodes
359 * 379 *
360 * Return: 0 on success else error+reason 380 * Return: 0 on success else error+reason
361 */ 381 */
362static int __zynqmp_clock_get_topology(struct clock_topology *topology, 382static int __zynqmp_clock_get_topology(struct clock_topology *topology,
363 u32 *data, u32 *nnodes) 383 struct topology_resp *response,
384 u32 *nnodes)
364{ 385{
365 int i; 386 int i;
387 u32 type;
366 388
367 for (i = 0; i < PM_API_PAYLOAD_LEN; i++) { 389 for (i = 0; i < ARRAY_SIZE(response->topology); i++) {
368 if (!(data[i] & CLK_TYPE_FIELD_MASK)) 390 type = FIELD_GET(CLK_TOPOLOGY_TYPE, response->topology[i]);
391 if (type == TYPE_INVALID)
369 return END_OF_TOPOLOGY_NODE; 392 return END_OF_TOPOLOGY_NODE;
370 topology[*nnodes].type = data[i] & CLK_TYPE_FIELD_MASK; 393 topology[*nnodes].type = type;
371 topology[*nnodes].flag = FIELD_GET(CLK_FLAG_FIELD_MASK, 394 topology[*nnodes].flag = FIELD_GET(CLK_TOPOLOGY_FLAGS,
372 data[i]); 395 response->topology[i]);
373 topology[*nnodes].type_flag = 396 topology[*nnodes].type_flag =
374 FIELD_GET(CLK_TYPE_FLAG_FIELD_MASK, data[i]); 397 FIELD_GET(CLK_TOPOLOGY_TYPE_FLAGS,
398 response->topology[i]);
375 (*nnodes)++; 399 (*nnodes)++;
376 } 400 }
377 401
@@ -392,14 +416,16 @@ static int zynqmp_clock_get_topology(u32 clk_id,
392 u32 *num_nodes) 416 u32 *num_nodes)
393{ 417{
394 int j, ret; 418 int j, ret;
395 u32 pm_resp[PM_API_PAYLOAD_LEN] = {0}; 419 struct topology_resp response = { };
396 420
397 *num_nodes = 0; 421 *num_nodes = 0;
398 for (j = 0; j <= MAX_NODES; j += 3) { 422 for (j = 0; j <= MAX_NODES; j += ARRAY_SIZE(response.topology)) {
399 ret = zynqmp_pm_clock_get_topology(clk_id, j, pm_resp); 423 ret = zynqmp_pm_clock_get_topology(clock[clk_id].clk_id, j,
424 &response);
400 if (ret) 425 if (ret)
401 return ret; 426 return ret;
402 ret = __zynqmp_clock_get_topology(topology, pm_resp, num_nodes); 427 ret = __zynqmp_clock_get_topology(topology, &response,
428 num_nodes);
403 if (ret == END_OF_TOPOLOGY_NODE) 429 if (ret == END_OF_TOPOLOGY_NODE)
404 return 0; 430 return 0;
405 } 431 }
@@ -408,31 +434,33 @@ static int zynqmp_clock_get_topology(u32 clk_id,
408} 434}
409 435
410/** 436/**
411 * __zynqmp_clock_get_topology() - Get parents info of clock from firmware 437 * __zynqmp_clock_get_parents() - Get parents info of clock from firmware
412 * response data 438 * response data
413 * @parents: Clock parents 439 * @parents: Clock parents
414 * @data: Clock parents data received from firmware 440 * @response: Clock parents data received from firmware
415 * @nparent: Number of parent 441 * @nparent: Number of parent
416 * 442 *
417 * Return: 0 on success else error+reason 443 * Return: 0 on success else error+reason
418 */ 444 */
419static int __zynqmp_clock_get_parents(struct clock_parent *parents, u32 *data, 445static int __zynqmp_clock_get_parents(struct clock_parent *parents,
446 struct parents_resp *response,
420 u32 *nparent) 447 u32 *nparent)
421{ 448{
422 int i; 449 int i;
423 struct clock_parent *parent; 450 struct clock_parent *parent;
424 451
425 for (i = 0; i < PM_API_PAYLOAD_LEN; i++) { 452 for (i = 0; i < ARRAY_SIZE(response->parents); i++) {
426 if (data[i] == NA_PARENT) 453 if (response->parents[i] == NA_PARENT)
427 return END_OF_PARENTS; 454 return END_OF_PARENTS;
428 455
429 parent = &parents[i]; 456 parent = &parents[i];
430 parent->id = data[i] & CLK_PARENTS_ID_MASK; 457 parent->id = FIELD_GET(CLK_PARENTS_ID, response->parents[i]);
431 if (data[i] == DUMMY_PARENT) { 458 if (response->parents[i] == DUMMY_PARENT) {
432 strcpy(parent->name, "dummy_name"); 459 strcpy(parent->name, "dummy_name");
433 parent->flag = 0; 460 parent->flag = 0;
434 } else { 461 } else {
435 parent->flag = data[i] >> CLK_PARENTS_ID_LEN; 462 parent->flag = FIELD_GET(CLK_PARENTS_FLAGS,
463 response->parents[i]);
436 if (zynqmp_get_clock_name(parent->id, parent->name)) 464 if (zynqmp_get_clock_name(parent->id, parent->name))
437 continue; 465 continue;
438 } 466 }
@@ -454,20 +482,21 @@ static int zynqmp_clock_get_parents(u32 clk_id, struct clock_parent *parents,
454 u32 *num_parents) 482 u32 *num_parents)
455{ 483{
456 int j = 0, ret; 484 int j = 0, ret;
457 u32 pm_resp[PM_API_PAYLOAD_LEN] = {0}; 485 struct parents_resp response = { };
458 486
459 *num_parents = 0; 487 *num_parents = 0;
460 do { 488 do {
461 /* Get parents from firmware */ 489 /* Get parents from firmware */
462 ret = zynqmp_pm_clock_get_parents(clk_id, j, pm_resp); 490 ret = zynqmp_pm_clock_get_parents(clock[clk_id].clk_id, j,
491 &response);
463 if (ret) 492 if (ret)
464 return ret; 493 return ret;
465 494
466 ret = __zynqmp_clock_get_parents(&parents[j], pm_resp, 495 ret = __zynqmp_clock_get_parents(&parents[j], &response,
467 num_parents); 496 num_parents);
468 if (ret == END_OF_PARENTS) 497 if (ret == END_OF_PARENTS)
469 return 0; 498 return 0;
470 j += PM_API_PAYLOAD_LEN; 499 j += ARRAY_SIZE(response.parents);
471 } while (*num_parents <= MAX_PARENT); 500 } while (*num_parents <= MAX_PARENT);
472 501
473 return 0; 502 return 0;
@@ -528,13 +557,14 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
528 const char **parent_names) 557 const char **parent_names)
529{ 558{
530 int j; 559 int j;
531 u32 num_nodes; 560 u32 num_nodes, clk_dev_id;
532 char *clk_out = NULL; 561 char *clk_out = NULL;
533 struct clock_topology *nodes; 562 struct clock_topology *nodes;
534 struct clk_hw *hw = NULL; 563 struct clk_hw *hw = NULL;
535 564
536 nodes = clock[clk_id].node; 565 nodes = clock[clk_id].node;
537 num_nodes = clock[clk_id].num_nodes; 566 num_nodes = clock[clk_id].num_nodes;
567 clk_dev_id = clock[clk_id].clk_id;
538 568
539 for (j = 0; j < num_nodes; j++) { 569 for (j = 0; j < num_nodes; j++) {
540 /* 570 /*
@@ -551,13 +581,14 @@ static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
551 if (!clk_topology[nodes[j].type]) 581 if (!clk_topology[nodes[j].type])
552 continue; 582 continue;
553 583
554 hw = (*clk_topology[nodes[j].type])(clk_out, clk_id, 584 hw = (*clk_topology[nodes[j].type])(clk_out, clk_dev_id,
555 parent_names, 585 parent_names,
556 num_parents, 586 num_parents,
557 &nodes[j]); 587 &nodes[j]);
558 if (IS_ERR(hw)) 588 if (IS_ERR(hw))
559 pr_warn_once("%s() %s register fail with %ld\n", 589 pr_warn_once("%s() 0x%x: %s register fail with %ld\n",
560 __func__, clk_name, PTR_ERR(hw)); 590 __func__, clk_dev_id, clk_name,
591 PTR_ERR(hw));
561 592
562 parent_names[0] = clk_out; 593 parent_names[0] = clk_out;
563 } 594 }
@@ -621,20 +652,33 @@ static int zynqmp_register_clocks(struct device_node *np)
621static void zynqmp_get_clock_info(void) 652static void zynqmp_get_clock_info(void)
622{ 653{
623 int i, ret; 654 int i, ret;
624 u32 attr, type = 0; 655 u32 type = 0;
656 u32 nodetype, subclass, class;
657 struct attr_resp attr;
658 struct name_resp name;
625 659
626 for (i = 0; i < clock_max_idx; i++) { 660 for (i = 0; i < clock_max_idx; i++) {
627 zynqmp_pm_clock_get_name(i, clock[i].clk_name);
628 if (!strcmp(clock[i].clk_name, RESERVED_CLK_NAME))
629 continue;
630
631 ret = zynqmp_pm_clock_get_attributes(i, &attr); 661 ret = zynqmp_pm_clock_get_attributes(i, &attr);
632 if (ret) 662 if (ret)
633 continue; 663 continue;
634 664
635 clock[i].valid = attr & CLK_VALID_MASK; 665 clock[i].valid = FIELD_GET(CLK_ATTR_VALID, attr.attr[0]);
636 clock[i].type = attr >> CLK_TYPE_SHIFT ? CLK_TYPE_EXTERNAL : 666 clock[i].type = FIELD_GET(CLK_ATTR_TYPE, attr.attr[0]) ?
637 CLK_TYPE_OUTPUT; 667 CLK_TYPE_EXTERNAL : CLK_TYPE_OUTPUT;
668
669 nodetype = FIELD_GET(CLK_ATTR_NODE_TYPE, attr.attr[0]);
670 subclass = FIELD_GET(CLK_ATTR_NODE_SUBCLASS, attr.attr[0]);
671 class = FIELD_GET(CLK_ATTR_NODE_CLASS, attr.attr[0]);
672
673 clock[i].clk_id = FIELD_PREP(CLK_ATTR_NODE_CLASS, class) |
674 FIELD_PREP(CLK_ATTR_NODE_SUBCLASS, subclass) |
675 FIELD_PREP(CLK_ATTR_NODE_TYPE, nodetype) |
676 FIELD_PREP(CLK_ATTR_NODE_INDEX, i);
677
678 zynqmp_pm_clock_get_name(clock[i].clk_id, &name);
679 if (!strcmp(name.name, RESERVED_CLK_NAME))
680 continue;
681 strncpy(clock[i].clk_name, name.name, MAX_NAME_LEN);
638 } 682 }
639 683
640 /* Get topology of all clock */ 684 /* Get topology of all clock */
diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
index a371c66e72ef..d8f5b70d2709 100644
--- a/drivers/clk/zynqmp/divider.c
+++ b/drivers/clk/zynqmp/divider.c
@@ -31,12 +31,14 @@
31 * struct zynqmp_clk_divider - adjustable divider clock 31 * struct zynqmp_clk_divider - adjustable divider clock
32 * @hw: handle between common and hardware-specific interfaces 32 * @hw: handle between common and hardware-specific interfaces
33 * @flags: Hardware specific flags 33 * @flags: Hardware specific flags
34 * @is_frac: The divider is a fractional divider
34 * @clk_id: Id of clock 35 * @clk_id: Id of clock
35 * @div_type: divisor type (TYPE_DIV1 or TYPE_DIV2) 36 * @div_type: divisor type (TYPE_DIV1 or TYPE_DIV2)
36 */ 37 */
37struct zynqmp_clk_divider { 38struct zynqmp_clk_divider {
38 struct clk_hw hw; 39 struct clk_hw hw;
39 u8 flags; 40 u8 flags;
41 bool is_frac;
40 u32 clk_id; 42 u32 clk_id;
41 u32 div_type; 43 u32 div_type;
42}; 44};
@@ -76,6 +78,13 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
76 else 78 else
77 value = div >> 16; 79 value = div >> 16;
78 80
81 if (!value) {
82 WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO),
83 "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
84 clk_name);
85 return parent_rate;
86 }
87
79 return DIV_ROUND_UP_ULL(parent_rate, value); 88 return DIV_ROUND_UP_ULL(parent_rate, value);
80} 89}
81 90
@@ -116,8 +125,7 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
116 125
117 bestdiv = zynqmp_divider_get_val(*prate, rate); 126 bestdiv = zynqmp_divider_get_val(*prate, rate);
118 127
119 if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && 128 if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac)
120 (divider->flags & CLK_FRAC))
121 bestdiv = rate % *prate ? 1 : bestdiv; 129 bestdiv = rate % *prate ? 1 : bestdiv;
122 *prate = rate * bestdiv; 130 *prate = rate * bestdiv;
123 131
@@ -195,11 +203,13 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name,
195 203
196 init.name = name; 204 init.name = name;
197 init.ops = &zynqmp_clk_divider_ops; 205 init.ops = &zynqmp_clk_divider_ops;
198 init.flags = nodes->flag; 206 /* CLK_FRAC is not defined in the common clk framework */
207 init.flags = nodes->flag & ~CLK_FRAC;
199 init.parent_names = parents; 208 init.parent_names = parents;
200 init.num_parents = 1; 209 init.num_parents = 1;
201 210
202 /* struct clk_divider assignments */ 211 /* struct clk_divider assignments */
212 div->is_frac = !!(nodes->flag & CLK_FRAC);
203 div->flags = nodes->type_flag; 213 div->flags = nodes->type_flag;
204 div->hw.init = &init; 214 div->hw.init = &init;
205 div->clk_id = clk_id; 215 div->clk_id = clk_id;
@@ -214,4 +224,3 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name,
214 224
215 return hw; 225 return hw;
216} 226}
217EXPORT_SYMBOL_GPL(zynqmp_clk_register_divider);
diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index c1ed641b3e26..4ae5d774443e 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -470,7 +470,7 @@ static int meson_pwm_init_channels(struct meson_pwm *meson,
470 470
471 init.name = name; 471 init.name = name;
472 init.ops = &clk_mux_ops; 472 init.ops = &clk_mux_ops;
473 init.flags = CLK_IS_BASIC; 473 init.flags = 0;
474 init.parent_names = meson->data->parent_names; 474 init.parent_names = meson->data->parent_names;
475 init.num_parents = meson->data->num_parents; 475 init.num_parents = meson->data->num_parents;
476 476
diff --git a/include/dt-bindings/clock/axg-audio-clkc.h b/include/dt-bindings/clock/axg-audio-clkc.h
index fd9c362099d9..75901c636893 100644
--- a/include/dt-bindings/clock/axg-audio-clkc.h
+++ b/include/dt-bindings/clock/axg-audio-clkc.h
@@ -7,26 +7,6 @@
7#ifndef __AXG_AUDIO_CLKC_BINDINGS_H 7#ifndef __AXG_AUDIO_CLKC_BINDINGS_H
8#define __AXG_AUDIO_CLKC_BINDINGS_H 8#define __AXG_AUDIO_CLKC_BINDINGS_H
9 9
10#define AUD_CLKID_SLV_SCLK0 9
11#define AUD_CLKID_SLV_SCLK1 10
12#define AUD_CLKID_SLV_SCLK2 11
13#define AUD_CLKID_SLV_SCLK3 12
14#define AUD_CLKID_SLV_SCLK4 13
15#define AUD_CLKID_SLV_SCLK5 14
16#define AUD_CLKID_SLV_SCLK6 15
17#define AUD_CLKID_SLV_SCLK7 16
18#define AUD_CLKID_SLV_SCLK8 17
19#define AUD_CLKID_SLV_SCLK9 18
20#define AUD_CLKID_SLV_LRCLK0 19
21#define AUD_CLKID_SLV_LRCLK1 20
22#define AUD_CLKID_SLV_LRCLK2 21
23#define AUD_CLKID_SLV_LRCLK3 22
24#define AUD_CLKID_SLV_LRCLK4 23
25#define AUD_CLKID_SLV_LRCLK5 24
26#define AUD_CLKID_SLV_LRCLK6 25
27#define AUD_CLKID_SLV_LRCLK7 26
28#define AUD_CLKID_SLV_LRCLK8 27
29#define AUD_CLKID_SLV_LRCLK9 28
30#define AUD_CLKID_DDR_ARB 29 10#define AUD_CLKID_DDR_ARB 29
31#define AUD_CLKID_PDM 30 11#define AUD_CLKID_PDM 30
32#define AUD_CLKID_TDMIN_A 31 12#define AUD_CLKID_TDMIN_A 31
@@ -90,5 +70,15 @@
90#define AUD_CLKID_TDMOUT_A_LRCLK 134 70#define AUD_CLKID_TDMOUT_A_LRCLK 134
91#define AUD_CLKID_TDMOUT_B_LRCLK 135 71#define AUD_CLKID_TDMOUT_B_LRCLK 135
92#define AUD_CLKID_TDMOUT_C_LRCLK 136 72#define AUD_CLKID_TDMOUT_C_LRCLK 136
73#define AUD_CLKID_SPDIFOUT_B 151
74#define AUD_CLKID_SPDIFOUT_B_CLK 152
75#define AUD_CLKID_TDM_MCLK_PAD0 155
76#define AUD_CLKID_TDM_MCLK_PAD1 156
77#define AUD_CLKID_TDM_LRCLK_PAD0 157
78#define AUD_CLKID_TDM_LRCLK_PAD1 158
79#define AUD_CLKID_TDM_LRCLK_PAD2 159
80#define AUD_CLKID_TDM_SCLK_PAD0 160
81#define AUD_CLKID_TDM_SCLK_PAD1 161
82#define AUD_CLKID_TDM_SCLK_PAD2 162
93 83
94#endif /* __AXG_AUDIO_CLKC_BINDINGS_H */ 84#endif /* __AXG_AUDIO_CLKC_BINDINGS_H */
diff --git a/include/dt-bindings/clock/exynos5410.h b/include/dt-bindings/clock/exynos5410.h
index f179eabbcdb7..86c2ad56c5ef 100644
--- a/include/dt-bindings/clock/exynos5410.h
+++ b/include/dt-bindings/clock/exynos5410.h
@@ -36,6 +36,7 @@
36#define CLK_UART0 257 36#define CLK_UART0 257
37#define CLK_UART1 258 37#define CLK_UART1 258
38#define CLK_UART2 259 38#define CLK_UART2 259
39#define CLK_UART3 260
39#define CLK_I2C0 261 40#define CLK_I2C0 261
40#define CLK_I2C1 262 41#define CLK_I2C1 262
41#define CLK_I2C2 263 42#define CLK_I2C2 263
@@ -44,7 +45,7 @@
44#define CLK_USI1 266 45#define CLK_USI1 266
45#define CLK_USI2 267 46#define CLK_USI2 267
46#define CLK_USI3 268 47#define CLK_USI3 268
47#define CLK_UART3 260 48#define CLK_TSADC 270
48#define CLK_PWM 279 49#define CLK_PWM 279
49#define CLK_MCT 315 50#define CLK_MCT 315
50#define CLK_WDT 316 51#define CLK_WDT 316
diff --git a/include/dt-bindings/clock/g12a-aoclkc.h b/include/dt-bindings/clock/g12a-aoclkc.h
index 8db01ffbeb06..e916e49ff288 100644
--- a/include/dt-bindings/clock/g12a-aoclkc.h
+++ b/include/dt-bindings/clock/g12a-aoclkc.h
@@ -26,7 +26,9 @@
26#define CLKID_AO_M4_FCLK 13 26#define CLKID_AO_M4_FCLK 13
27#define CLKID_AO_M4_HCLK 14 27#define CLKID_AO_M4_HCLK 14
28#define CLKID_AO_CLK81 15 28#define CLKID_AO_CLK81 15
29#define CLKID_AO_SAR_ADC_SEL 16
29#define CLKID_AO_SAR_ADC_CLK 18 30#define CLKID_AO_SAR_ADC_CLK 18
31#define CLKID_AO_CTS_OSCIN 19
30#define CLKID_AO_32K 23 32#define CLKID_AO_32K 23
31#define CLKID_AO_CEC 27 33#define CLKID_AO_CEC 27
32#define CLKID_AO_CTS_RTC_OSCIN 28 34#define CLKID_AO_CTS_RTC_OSCIN 28
diff --git a/include/dt-bindings/clock/g12a-clkc.h b/include/dt-bindings/clock/g12a-clkc.h
index 83b657038d1e..82c9e0c020b2 100644
--- a/include/dt-bindings/clock/g12a-clkc.h
+++ b/include/dt-bindings/clock/g12a-clkc.h
@@ -131,5 +131,10 @@
131#define CLKID_MALI_1 174 131#define CLKID_MALI_1 174
132#define CLKID_MALI 175 132#define CLKID_MALI 175
133#define CLKID_MPLL_5OM 177 133#define CLKID_MPLL_5OM 177
134#define CLKID_CPU_CLK 187
135#define CLKID_PCIE_PLL 201
136#define CLKID_VDEC_1 204
137#define CLKID_VDEC_HEVC 207
138#define CLKID_VDEC_HEVCF 210
134 139
135#endif /* __G12A_CLKC_H */ 140#endif /* __G12A_CLKC_H */
diff --git a/include/dt-bindings/clock/imx7ulp-clock.h b/include/dt-bindings/clock/imx7ulp-clock.h
index 21d872e69cb1..6f66f9005c81 100644
--- a/include/dt-bindings/clock/imx7ulp-clock.h
+++ b/include/dt-bindings/clock/imx7ulp-clock.h
@@ -65,7 +65,6 @@
65#define IMX7ULP_CLK_FLEXBUS 2 65#define IMX7ULP_CLK_FLEXBUS 2
66#define IMX7ULP_CLK_SEMA42_1 3 66#define IMX7ULP_CLK_SEMA42_1 3
67#define IMX7ULP_CLK_DMA_MUX1 4 67#define IMX7ULP_CLK_DMA_MUX1 4
68#define IMX7ULP_CLK_SNVS 5
69#define IMX7ULP_CLK_CAAM 6 68#define IMX7ULP_CLK_CAAM 6
70#define IMX7ULP_CLK_LPTPM4 7 69#define IMX7ULP_CLK_LPTPM4 7
71#define IMX7ULP_CLK_LPTPM5 8 70#define IMX7ULP_CLK_LPTPM5 8
diff --git a/include/dt-bindings/clock/jz4725b-cgu.h b/include/dt-bindings/clock/jz4725b-cgu.h
index 460bbeff6ab8..31f1ab0fe42c 100644
--- a/include/dt-bindings/clock/jz4725b-cgu.h
+++ b/include/dt-bindings/clock/jz4725b-cgu.h
@@ -31,5 +31,6 @@
31#define JZ4725B_CLK_TCU 22 31#define JZ4725B_CLK_TCU 22
32#define JZ4725B_CLK_EXT512 23 32#define JZ4725B_CLK_EXT512 23
33#define JZ4725B_CLK_RTC 24 33#define JZ4725B_CLK_RTC 24
34#define JZ4725B_CLK_UDC_PHY 25
34 35
35#endif /* __DT_BINDINGS_CLOCK_JZ4725B_CGU_H__ */ 36#endif /* __DT_BINDINGS_CLOCK_JZ4725B_CGU_H__ */
diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h
index 8067077a62ca..47556539f0ee 100644
--- a/include/dt-bindings/clock/meson8b-clkc.h
+++ b/include/dt-bindings/clock/meson8b-clkc.h
@@ -103,10 +103,14 @@
103#define CLKID_MPLL1 94 103#define CLKID_MPLL1 94
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
107#define CLKID_APB 124 106#define CLKID_APB 124
108#define CLKID_PERIPH 126 107#define CLKID_PERIPH 126
109#define CLKID_AXI 128 108#define CLKID_AXI 128
110#define CLKID_L2_DRAM 130 109#define CLKID_L2_DRAM 130
110#define CLKID_VPU 190
111#define CLKID_VDEC_1 196
112#define CLKID_VDEC_HCODEC 199
113#define CLKID_VDEC_2 202
114#define CLKID_VDEC_HEVC 206
111 115
112#endif /* __MESON8B_CLKC_H */ 116#endif /* __MESON8B_CLKC_H */
diff --git a/include/dt-bindings/clock/mt8183-clk.h b/include/dt-bindings/clock/mt8183-clk.h
new file mode 100644
index 000000000000..0046506eb24c
--- /dev/null
+++ b/include/dt-bindings/clock/mt8183-clk.h
@@ -0,0 +1,422 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2018 MediaTek Inc.
4 * Author: Weiyi Lu <weiyi.lu@mediatek.com>
5 */
6
7#ifndef _DT_BINDINGS_CLK_MT8183_H
8#define _DT_BINDINGS_CLK_MT8183_H
9
10/* APMIXED */
11#define CLK_APMIXED_ARMPLL_LL 0
12#define CLK_APMIXED_ARMPLL_L 1
13#define CLK_APMIXED_CCIPLL 2
14#define CLK_APMIXED_MAINPLL 3
15#define CLK_APMIXED_UNIV2PLL 4
16#define CLK_APMIXED_MSDCPLL 5
17#define CLK_APMIXED_MMPLL 6
18#define CLK_APMIXED_MFGPLL 7
19#define CLK_APMIXED_TVDPLL 8
20#define CLK_APMIXED_APLL1 9
21#define CLK_APMIXED_APLL2 10
22#define CLK_APMIXED_SSUSB_26M 11
23#define CLK_APMIXED_APPLL_26M 12
24#define CLK_APMIXED_MIPIC0_26M 13
25#define CLK_APMIXED_MDPLLGP_26M 14
26#define CLK_APMIXED_MMSYS_26M 15
27#define CLK_APMIXED_UFS_26M 16
28#define CLK_APMIXED_MIPIC1_26M 17
29#define CLK_APMIXED_MEMPLL_26M 18
30#define CLK_APMIXED_CLKSQ_LVPLL_26M 19
31#define CLK_APMIXED_MIPID0_26M 20
32#define CLK_APMIXED_MIPID1_26M 21
33#define CLK_APMIXED_NR_CLK 22
34
35/* TOPCKGEN */
36#define CLK_TOP_MUX_AXI 0
37#define CLK_TOP_MUX_MM 1
38#define CLK_TOP_MUX_CAM 2
39#define CLK_TOP_MUX_MFG 3
40#define CLK_TOP_MUX_CAMTG 4
41#define CLK_TOP_MUX_UART 5
42#define CLK_TOP_MUX_SPI 6
43#define CLK_TOP_MUX_MSDC50_0_HCLK 7
44#define CLK_TOP_MUX_MSDC50_0 8
45#define CLK_TOP_MUX_MSDC30_1 9
46#define CLK_TOP_MUX_MSDC30_2 10
47#define CLK_TOP_MUX_AUDIO 11
48#define CLK_TOP_MUX_AUD_INTBUS 12
49#define CLK_TOP_MUX_FPWRAP_ULPOSC 13
50#define CLK_TOP_MUX_SCP 14
51#define CLK_TOP_MUX_ATB 15
52#define CLK_TOP_MUX_SSPM 16
53#define CLK_TOP_MUX_DPI0 17
54#define CLK_TOP_MUX_SCAM 18
55#define CLK_TOP_MUX_AUD_1 19
56#define CLK_TOP_MUX_AUD_2 20
57#define CLK_TOP_MUX_DISP_PWM 21
58#define CLK_TOP_MUX_SSUSB_TOP_XHCI 22
59#define CLK_TOP_MUX_USB_TOP 23
60#define CLK_TOP_MUX_SPM 24
61#define CLK_TOP_MUX_I2C 25
62#define CLK_TOP_MUX_F52M_MFG 26
63#define CLK_TOP_MUX_SENINF 27
64#define CLK_TOP_MUX_DXCC 28
65#define CLK_TOP_MUX_CAMTG2 29
66#define CLK_TOP_MUX_AUD_ENG1 30
67#define CLK_TOP_MUX_AUD_ENG2 31
68#define CLK_TOP_MUX_FAES_UFSFDE 32
69#define CLK_TOP_MUX_FUFS 33
70#define CLK_TOP_MUX_IMG 34
71#define CLK_TOP_MUX_DSP 35
72#define CLK_TOP_MUX_DSP1 36
73#define CLK_TOP_MUX_DSP2 37
74#define CLK_TOP_MUX_IPU_IF 38
75#define CLK_TOP_MUX_CAMTG3 39
76#define CLK_TOP_MUX_CAMTG4 40
77#define CLK_TOP_MUX_PMICSPI 41
78#define CLK_TOP_SYSPLL_CK 42
79#define CLK_TOP_SYSPLL_D2 43
80#define CLK_TOP_SYSPLL_D3 44
81#define CLK_TOP_SYSPLL_D5 45
82#define CLK_TOP_SYSPLL_D7 46
83#define CLK_TOP_SYSPLL_D2_D2 47
84#define CLK_TOP_SYSPLL_D2_D4 48
85#define CLK_TOP_SYSPLL_D2_D8 49
86#define CLK_TOP_SYSPLL_D2_D16 50
87#define CLK_TOP_SYSPLL_D3_D2 51
88#define CLK_TOP_SYSPLL_D3_D4 52
89#define CLK_TOP_SYSPLL_D3_D8 53
90#define CLK_TOP_SYSPLL_D5_D2 54
91#define CLK_TOP_SYSPLL_D5_D4 55
92#define CLK_TOP_SYSPLL_D7_D2 56
93#define CLK_TOP_SYSPLL_D7_D4 57
94#define CLK_TOP_UNIVPLL_CK 58
95#define CLK_TOP_UNIVPLL_D2 59
96#define CLK_TOP_UNIVPLL_D3 60
97#define CLK_TOP_UNIVPLL_D5 61
98#define CLK_TOP_UNIVPLL_D7 62
99#define CLK_TOP_UNIVPLL_D2_D2 63
100#define CLK_TOP_UNIVPLL_D2_D4 64
101#define CLK_TOP_UNIVPLL_D2_D8 65
102#define CLK_TOP_UNIVPLL_D3_D2 66
103#define CLK_TOP_UNIVPLL_D3_D4 67
104#define CLK_TOP_UNIVPLL_D3_D8 68
105#define CLK_TOP_UNIVPLL_D5_D2 69
106#define CLK_TOP_UNIVPLL_D5_D4 70
107#define CLK_TOP_UNIVPLL_D5_D8 71
108#define CLK_TOP_APLL1_CK 72
109#define CLK_TOP_APLL1_D2 73
110#define CLK_TOP_APLL1_D4 74
111#define CLK_TOP_APLL1_D8 75
112#define CLK_TOP_APLL2_CK 76
113#define CLK_TOP_APLL2_D2 77
114#define CLK_TOP_APLL2_D4 78
115#define CLK_TOP_APLL2_D8 79
116#define CLK_TOP_TVDPLL_CK 80
117#define CLK_TOP_TVDPLL_D2 81
118#define CLK_TOP_TVDPLL_D4 82
119#define CLK_TOP_TVDPLL_D8 83
120#define CLK_TOP_TVDPLL_D16 84
121#define CLK_TOP_MSDCPLL_CK 85
122#define CLK_TOP_MSDCPLL_D2 86
123#define CLK_TOP_MSDCPLL_D4 87
124#define CLK_TOP_MSDCPLL_D8 88
125#define CLK_TOP_MSDCPLL_D16 89
126#define CLK_TOP_AD_OSC_CK 90
127#define CLK_TOP_OSC_D2 91
128#define CLK_TOP_OSC_D4 92
129#define CLK_TOP_OSC_D8 93
130#define CLK_TOP_OSC_D16 94
131#define CLK_TOP_F26M_CK_D2 95
132#define CLK_TOP_MFGPLL_CK 96
133#define CLK_TOP_UNIVP_192M_CK 97
134#define CLK_TOP_UNIVP_192M_D2 98
135#define CLK_TOP_UNIVP_192M_D4 99
136#define CLK_TOP_UNIVP_192M_D8 100
137#define CLK_TOP_UNIVP_192M_D16 101
138#define CLK_TOP_UNIVP_192M_D32 102
139#define CLK_TOP_MMPLL_CK 103
140#define CLK_TOP_MMPLL_D4 104
141#define CLK_TOP_MMPLL_D4_D2 105
142#define CLK_TOP_MMPLL_D4_D4 106
143#define CLK_TOP_MMPLL_D5 107
144#define CLK_TOP_MMPLL_D5_D2 108
145#define CLK_TOP_MMPLL_D5_D4 109
146#define CLK_TOP_MMPLL_D6 110
147#define CLK_TOP_MMPLL_D7 111
148#define CLK_TOP_CLK26M 112
149#define CLK_TOP_CLK13M 113
150#define CLK_TOP_ULPOSC 114
151#define CLK_TOP_UNIVP_192M 115
152#define CLK_TOP_MUX_APLL_I2S0 116
153#define CLK_TOP_MUX_APLL_I2S1 117
154#define CLK_TOP_MUX_APLL_I2S2 118
155#define CLK_TOP_MUX_APLL_I2S3 119
156#define CLK_TOP_MUX_APLL_I2S4 120
157#define CLK_TOP_MUX_APLL_I2S5 121
158#define CLK_TOP_APLL12_DIV0 122
159#define CLK_TOP_APLL12_DIV1 123
160#define CLK_TOP_APLL12_DIV2 124
161#define CLK_TOP_APLL12_DIV3 125
162#define CLK_TOP_APLL12_DIV4 126
163#define CLK_TOP_APLL12_DIVB 127
164#define CLK_TOP_UNIVPLL 128
165#define CLK_TOP_ARMPLL_DIV_PLL1 129
166#define CLK_TOP_ARMPLL_DIV_PLL2 130
167#define CLK_TOP_UNIVPLL_D3_D16 131
168#define CLK_TOP_NR_CLK 132
169
170/* CAMSYS */
171#define CLK_CAM_LARB6 0
172#define CLK_CAM_DFP_VAD 1
173#define CLK_CAM_CAM 2
174#define CLK_CAM_CAMTG 3
175#define CLK_CAM_SENINF 4
176#define CLK_CAM_CAMSV0 5
177#define CLK_CAM_CAMSV1 6
178#define CLK_CAM_CAMSV2 7
179#define CLK_CAM_CCU 8
180#define CLK_CAM_LARB3 9
181#define CLK_CAM_NR_CLK 10
182
183/* INFRACFG_AO */
184#define CLK_INFRA_PMIC_TMR 0
185#define CLK_INFRA_PMIC_AP 1
186#define CLK_INFRA_PMIC_MD 2
187#define CLK_INFRA_PMIC_CONN 3
188#define CLK_INFRA_SCPSYS 4
189#define CLK_INFRA_SEJ 5
190#define CLK_INFRA_APXGPT 6
191#define CLK_INFRA_ICUSB 7
192#define CLK_INFRA_GCE 8
193#define CLK_INFRA_THERM 9
194#define CLK_INFRA_I2C0 10
195#define CLK_INFRA_I2C1 11
196#define CLK_INFRA_I2C2 12
197#define CLK_INFRA_I2C3 13
198#define CLK_INFRA_PWM_HCLK 14
199#define CLK_INFRA_PWM1 15
200#define CLK_INFRA_PWM2 16
201#define CLK_INFRA_PWM3 17
202#define CLK_INFRA_PWM4 18
203#define CLK_INFRA_PWM 19
204#define CLK_INFRA_UART0 20
205#define CLK_INFRA_UART1 21
206#define CLK_INFRA_UART2 22
207#define CLK_INFRA_UART3 23
208#define CLK_INFRA_GCE_26M 24
209#define CLK_INFRA_CQ_DMA_FPC 25
210#define CLK_INFRA_BTIF 26
211#define CLK_INFRA_SPI0 27
212#define CLK_INFRA_MSDC0 28
213#define CLK_INFRA_MSDC1 29
214#define CLK_INFRA_MSDC2 30
215#define CLK_INFRA_MSDC0_SCK 31
216#define CLK_INFRA_DVFSRC 32
217#define CLK_INFRA_GCPU 33
218#define CLK_INFRA_TRNG 34
219#define CLK_INFRA_AUXADC 35
220#define CLK_INFRA_CPUM 36
221#define CLK_INFRA_CCIF1_AP 37
222#define CLK_INFRA_CCIF1_MD 38
223#define CLK_INFRA_AUXADC_MD 39
224#define CLK_INFRA_MSDC1_SCK 40
225#define CLK_INFRA_MSDC2_SCK 41
226#define CLK_INFRA_AP_DMA 42
227#define CLK_INFRA_XIU 43
228#define CLK_INFRA_DEVICE_APC 44
229#define CLK_INFRA_CCIF_AP 45
230#define CLK_INFRA_DEBUGSYS 46
231#define CLK_INFRA_AUDIO 47
232#define CLK_INFRA_CCIF_MD 48
233#define CLK_INFRA_DXCC_SEC_CORE 49
234#define CLK_INFRA_DXCC_AO 50
235#define CLK_INFRA_DRAMC_F26M 51
236#define CLK_INFRA_IRTX 52
237#define CLK_INFRA_DISP_PWM 53
238#define CLK_INFRA_CLDMA_BCLK 54
239#define CLK_INFRA_AUDIO_26M_BCLK 55
240#define CLK_INFRA_SPI1 56
241#define CLK_INFRA_I2C4 57
242#define CLK_INFRA_MODEM_TEMP_SHARE 58
243#define CLK_INFRA_SPI2 59
244#define CLK_INFRA_SPI3 60
245#define CLK_INFRA_UNIPRO_SCK 61
246#define CLK_INFRA_UNIPRO_TICK 62
247#define CLK_INFRA_UFS_MP_SAP_BCLK 63
248#define CLK_INFRA_MD32_BCLK 64
249#define CLK_INFRA_SSPM 65
250#define CLK_INFRA_UNIPRO_MBIST 66
251#define CLK_INFRA_SSPM_BUS_HCLK 67
252#define CLK_INFRA_I2C5 68
253#define CLK_INFRA_I2C5_ARBITER 69
254#define CLK_INFRA_I2C5_IMM 70
255#define CLK_INFRA_I2C1_ARBITER 71
256#define CLK_INFRA_I2C1_IMM 72
257#define CLK_INFRA_I2C2_ARBITER 73
258#define CLK_INFRA_I2C2_IMM 74
259#define CLK_INFRA_SPI4 75
260#define CLK_INFRA_SPI5 76
261#define CLK_INFRA_CQ_DMA 77
262#define CLK_INFRA_UFS 78
263#define CLK_INFRA_AES_UFSFDE 79
264#define CLK_INFRA_UFS_TICK 80
265#define CLK_INFRA_MSDC0_SELF 81
266#define CLK_INFRA_MSDC1_SELF 82
267#define CLK_INFRA_MSDC2_SELF 83
268#define CLK_INFRA_SSPM_26M_SELF 84
269#define CLK_INFRA_SSPM_32K_SELF 85
270#define CLK_INFRA_UFS_AXI 86
271#define CLK_INFRA_I2C6 87
272#define CLK_INFRA_AP_MSDC0 88
273#define CLK_INFRA_MD_MSDC0 89
274#define CLK_INFRA_USB 90
275#define CLK_INFRA_DEVMPU_BCLK 91
276#define CLK_INFRA_CCIF2_AP 92
277#define CLK_INFRA_CCIF2_MD 93
278#define CLK_INFRA_CCIF3_AP 94
279#define CLK_INFRA_CCIF3_MD 95
280#define CLK_INFRA_SEJ_F13M 96
281#define CLK_INFRA_AES_BCLK 97
282#define CLK_INFRA_I2C7 98
283#define CLK_INFRA_I2C8 99
284#define CLK_INFRA_FBIST2FPC 100
285#define CLK_INFRA_NR_CLK 101
286
287/* MFGCFG */
288#define CLK_MFG_BG3D 0
289#define CLK_MFG_NR_CLK 1
290
291/* IMG */
292#define CLK_IMG_OWE 0
293#define CLK_IMG_WPE_B 1
294#define CLK_IMG_WPE_A 2
295#define CLK_IMG_MFB 3
296#define CLK_IMG_RSC 4
297#define CLK_IMG_DPE 5
298#define CLK_IMG_FDVT 6
299#define CLK_IMG_DIP 7
300#define CLK_IMG_LARB2 8
301#define CLK_IMG_LARB5 9
302#define CLK_IMG_NR_CLK 10
303
304/* MMSYS_CONFIG */
305#define CLK_MM_SMI_COMMON 0
306#define CLK_MM_SMI_LARB0 1
307#define CLK_MM_SMI_LARB1 2
308#define CLK_MM_GALS_COMM0 3
309#define CLK_MM_GALS_COMM1 4
310#define CLK_MM_GALS_CCU2MM 5
311#define CLK_MM_GALS_IPU12MM 6
312#define CLK_MM_GALS_IMG2MM 7
313#define CLK_MM_GALS_CAM2MM 8
314#define CLK_MM_GALS_IPU2MM 9
315#define CLK_MM_MDP_DL_TXCK 10
316#define CLK_MM_IPU_DL_TXCK 11
317#define CLK_MM_MDP_RDMA0 12
318#define CLK_MM_MDP_RDMA1 13
319#define CLK_MM_MDP_RSZ0 14
320#define CLK_MM_MDP_RSZ1 15
321#define CLK_MM_MDP_TDSHP 16
322#define CLK_MM_MDP_WROT0 17
323#define CLK_MM_FAKE_ENG 18
324#define CLK_MM_DISP_OVL0 19
325#define CLK_MM_DISP_OVL0_2L 20
326#define CLK_MM_DISP_OVL1_2L 21
327#define CLK_MM_DISP_RDMA0 22
328#define CLK_MM_DISP_RDMA1 23
329#define CLK_MM_DISP_WDMA0 24
330#define CLK_MM_DISP_COLOR0 25
331#define CLK_MM_DISP_CCORR0 26
332#define CLK_MM_DISP_AAL0 27
333#define CLK_MM_DISP_GAMMA0 28
334#define CLK_MM_DISP_DITHER0 29
335#define CLK_MM_DISP_SPLIT 30
336#define CLK_MM_DSI0_MM 31
337#define CLK_MM_DSI0_IF 32
338#define CLK_MM_DPI_MM 33
339#define CLK_MM_DPI_IF 34
340#define CLK_MM_FAKE_ENG2 35
341#define CLK_MM_MDP_DL_RX 36
342#define CLK_MM_IPU_DL_RX 37
343#define CLK_MM_26M 38
344#define CLK_MM_MMSYS_R2Y 39
345#define CLK_MM_DISP_RSZ 40
346#define CLK_MM_MDP_WDMA0 41
347#define CLK_MM_MDP_AAL 42
348#define CLK_MM_MDP_CCORR 43
349#define CLK_MM_DBI_MM 44
350#define CLK_MM_DBI_IF 45
351#define CLK_MM_NR_CLK 46
352
353/* VDEC_GCON */
354#define CLK_VDEC_VDEC 0
355#define CLK_VDEC_LARB1 1
356#define CLK_VDEC_NR_CLK 2
357
358/* VENC_GCON */
359#define CLK_VENC_LARB 0
360#define CLK_VENC_VENC 1
361#define CLK_VENC_JPGENC 2
362#define CLK_VENC_NR_CLK 3
363
364/* AUDIO */
365#define CLK_AUDIO_TML 0
366#define CLK_AUDIO_DAC_PREDIS 1
367#define CLK_AUDIO_DAC 2
368#define CLK_AUDIO_ADC 3
369#define CLK_AUDIO_APLL_TUNER 4
370#define CLK_AUDIO_APLL2_TUNER 5
371#define CLK_AUDIO_24M 6
372#define CLK_AUDIO_22M 7
373#define CLK_AUDIO_AFE 8
374#define CLK_AUDIO_I2S4 9
375#define CLK_AUDIO_I2S3 10
376#define CLK_AUDIO_I2S2 11
377#define CLK_AUDIO_I2S1 12
378#define CLK_AUDIO_PDN_ADDA6_ADC 13
379#define CLK_AUDIO_TDM 14
380#define CLK_AUDIO_NR_CLK 15
381
382/* IPU_CONN */
383#define CLK_IPU_CONN_IPU 0
384#define CLK_IPU_CONN_AHB 1
385#define CLK_IPU_CONN_AXI 2
386#define CLK_IPU_CONN_ISP 3
387#define CLK_IPU_CONN_CAM_ADL 4
388#define CLK_IPU_CONN_IMG_ADL 5
389#define CLK_IPU_CONN_DAP_RX 6
390#define CLK_IPU_CONN_APB2AXI 7
391#define CLK_IPU_CONN_APB2AHB 8
392#define CLK_IPU_CONN_IPU_CAB1TO2 9
393#define CLK_IPU_CONN_IPU1_CAB1TO2 10
394#define CLK_IPU_CONN_IPU2_CAB1TO2 11
395#define CLK_IPU_CONN_CAB3TO3 12
396#define CLK_IPU_CONN_CAB2TO1 13
397#define CLK_IPU_CONN_CAB3TO1_SLICE 14
398#define CLK_IPU_CONN_NR_CLK 15
399
400/* IPU_ADL */
401#define CLK_IPU_ADL_CABGEN 0
402#define CLK_IPU_ADL_NR_CLK 1
403
404/* IPU_CORE0 */
405#define CLK_IPU_CORE0_JTAG 0
406#define CLK_IPU_CORE0_AXI 1
407#define CLK_IPU_CORE0_IPU 2
408#define CLK_IPU_CORE0_NR_CLK 3
409
410/* IPU_CORE1 */
411#define CLK_IPU_CORE1_JTAG 0
412#define CLK_IPU_CORE1_AXI 1
413#define CLK_IPU_CORE1_IPU 2
414#define CLK_IPU_CORE1_NR_CLK 3
415
416/* MCUCFG */
417#define CLK_MCU_MP0_SEL 0
418#define CLK_MCU_MP2_SEL 1
419#define CLK_MCU_BUS_SEL 2
420#define CLK_MCU_NR_CLK 3
421
422#endif /* _DT_BINDINGS_CLK_MT8183_H */
diff --git a/include/dt-bindings/clock/mt8516-clk.h b/include/dt-bindings/clock/mt8516-clk.h
new file mode 100644
index 000000000000..9cfca53cd78d
--- /dev/null
+++ b/include/dt-bindings/clock/mt8516-clk.h
@@ -0,0 +1,211 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2019 MediaTek Inc.
4 * Copyright (c) 2019 BayLibre, SAS.
5 * Author: James Liao <jamesjj.liao@mediatek.com>
6 */
7
8#ifndef _DT_BINDINGS_CLK_MT8516_H
9#define _DT_BINDINGS_CLK_MT8516_H
10
11/* APMIXEDSYS */
12
13#define CLK_APMIXED_ARMPLL 0
14#define CLK_APMIXED_MAINPLL 1
15#define CLK_APMIXED_UNIVPLL 2
16#define CLK_APMIXED_MMPLL 3
17#define CLK_APMIXED_APLL1 4
18#define CLK_APMIXED_APLL2 5
19#define CLK_APMIXED_NR_CLK 6
20
21/* INFRACFG */
22
23#define CLK_IFR_MUX1_SEL 0
24#define CLK_IFR_ETH_25M_SEL 1
25#define CLK_IFR_I2C0_SEL 2
26#define CLK_IFR_I2C1_SEL 3
27#define CLK_IFR_I2C2_SEL 4
28#define CLK_IFR_NR_CLK 5
29
30/* TOPCKGEN */
31
32#define CLK_TOP_CLK_NULL 0
33#define CLK_TOP_I2S_INFRA_BCK 1
34#define CLK_TOP_MEMPLL 2
35#define CLK_TOP_DMPLL 3
36#define CLK_TOP_MAINPLL_D2 4
37#define CLK_TOP_MAINPLL_D4 5
38#define CLK_TOP_MAINPLL_D8 6
39#define CLK_TOP_MAINPLL_D16 7
40#define CLK_TOP_MAINPLL_D11 8
41#define CLK_TOP_MAINPLL_D22 9
42#define CLK_TOP_MAINPLL_D3 10
43#define CLK_TOP_MAINPLL_D6 11
44#define CLK_TOP_MAINPLL_D12 12
45#define CLK_TOP_MAINPLL_D5 13
46#define CLK_TOP_MAINPLL_D10 14
47#define CLK_TOP_MAINPLL_D20 15
48#define CLK_TOP_MAINPLL_D40 16
49#define CLK_TOP_MAINPLL_D7 17
50#define CLK_TOP_MAINPLL_D14 18
51#define CLK_TOP_UNIVPLL_D2 19
52#define CLK_TOP_UNIVPLL_D4 20
53#define CLK_TOP_UNIVPLL_D8 21
54#define CLK_TOP_UNIVPLL_D16 22
55#define CLK_TOP_UNIVPLL_D3 23
56#define CLK_TOP_UNIVPLL_D6 24
57#define CLK_TOP_UNIVPLL_D12 25
58#define CLK_TOP_UNIVPLL_D24 26
59#define CLK_TOP_UNIVPLL_D5 27
60#define CLK_TOP_UNIVPLL_D20 28
61#define CLK_TOP_MMPLL380M 29
62#define CLK_TOP_MMPLL_D2 30
63#define CLK_TOP_MMPLL_200M 31
64#define CLK_TOP_USB_PHY48M 32
65#define CLK_TOP_APLL1 33
66#define CLK_TOP_APLL1_D2 34
67#define CLK_TOP_APLL1_D4 35
68#define CLK_TOP_APLL1_D8 36
69#define CLK_TOP_APLL2 37
70#define CLK_TOP_APLL2_D2 38
71#define CLK_TOP_APLL2_D4 39
72#define CLK_TOP_APLL2_D8 40
73#define CLK_TOP_CLK26M 41
74#define CLK_TOP_CLK26M_D2 42
75#define CLK_TOP_AHB_INFRA_D2 43
76#define CLK_TOP_NFI1X 44
77#define CLK_TOP_ETH_D2 45
78#define CLK_TOP_THEM 46
79#define CLK_TOP_APDMA 47
80#define CLK_TOP_I2C0 48
81#define CLK_TOP_I2C1 49
82#define CLK_TOP_AUXADC1 50
83#define CLK_TOP_NFI 51
84#define CLK_TOP_NFIECC 52
85#define CLK_TOP_DEBUGSYS 53
86#define CLK_TOP_PWM 54
87#define CLK_TOP_UART0 55
88#define CLK_TOP_UART1 56
89#define CLK_TOP_BTIF 57
90#define CLK_TOP_USB 58
91#define CLK_TOP_FLASHIF_26M 59
92#define CLK_TOP_AUXADC2 60
93#define CLK_TOP_I2C2 61
94#define CLK_TOP_MSDC0 62
95#define CLK_TOP_MSDC1 63
96#define CLK_TOP_NFI2X 64
97#define CLK_TOP_PMICWRAP_AP 65
98#define CLK_TOP_SEJ 66
99#define CLK_TOP_MEMSLP_DLYER 67
100#define CLK_TOP_SPI 68
101#define CLK_TOP_APXGPT 69
102#define CLK_TOP_AUDIO 70
103#define CLK_TOP_PMICWRAP_MD 71
104#define CLK_TOP_PMICWRAP_CONN 72
105#define CLK_TOP_PMICWRAP_26M 73
106#define CLK_TOP_AUX_ADC 74
107#define CLK_TOP_AUX_TP 75
108#define CLK_TOP_MSDC2 76
109#define CLK_TOP_RBIST 77
110#define CLK_TOP_NFI_BUS 78
111#define CLK_TOP_GCE 79
112#define CLK_TOP_TRNG 80
113#define CLK_TOP_SEJ_13M 81
114#define CLK_TOP_AES 82
115#define CLK_TOP_PWM_B 83
116#define CLK_TOP_PWM1_FB 84
117#define CLK_TOP_PWM2_FB 85
118#define CLK_TOP_PWM3_FB 86
119#define CLK_TOP_PWM4_FB 87
120#define CLK_TOP_PWM5_FB 88
121#define CLK_TOP_USB_1P 89
122#define CLK_TOP_FLASHIF_FREERUN 90
123#define CLK_TOP_66M_ETH 91
124#define CLK_TOP_133M_ETH 92
125#define CLK_TOP_FETH_25M 93
126#define CLK_TOP_FETH_50M 94
127#define CLK_TOP_FLASHIF_AXI 95
128#define CLK_TOP_USBIF 96
129#define CLK_TOP_UART2 97
130#define CLK_TOP_BSI 98
131#define CLK_TOP_RG_SPINOR 99
132#define CLK_TOP_RG_MSDC2 100
133#define CLK_TOP_RG_ETH 101
134#define CLK_TOP_RG_AUD1 102
135#define CLK_TOP_RG_AUD2 103
136#define CLK_TOP_RG_AUD_ENGEN1 104
137#define CLK_TOP_RG_AUD_ENGEN2 105
138#define CLK_TOP_RG_I2C 106
139#define CLK_TOP_RG_PWM_INFRA 107
140#define CLK_TOP_RG_AUD_SPDIF_IN 108
141#define CLK_TOP_RG_UART2 109
142#define CLK_TOP_RG_BSI 110
143#define CLK_TOP_RG_DBG_ATCLK 111
144#define CLK_TOP_RG_NFIECC 112
145#define CLK_TOP_RG_APLL1_D2_EN 113
146#define CLK_TOP_RG_APLL1_D4_EN 114
147#define CLK_TOP_RG_APLL1_D8_EN 115
148#define CLK_TOP_RG_APLL2_D2_EN 116
149#define CLK_TOP_RG_APLL2_D4_EN 117
150#define CLK_TOP_RG_APLL2_D8_EN 118
151#define CLK_TOP_APLL12_DIV0 119
152#define CLK_TOP_APLL12_DIV1 120
153#define CLK_TOP_APLL12_DIV2 121
154#define CLK_TOP_APLL12_DIV3 122
155#define CLK_TOP_APLL12_DIV4 123
156#define CLK_TOP_APLL12_DIV4B 124
157#define CLK_TOP_APLL12_DIV5 125
158#define CLK_TOP_APLL12_DIV5B 126
159#define CLK_TOP_APLL12_DIV6 127
160#define CLK_TOP_UART0_SEL 128
161#define CLK_TOP_EMI_DDRPHY_SEL 129
162#define CLK_TOP_AHB_INFRA_SEL 130
163#define CLK_TOP_MSDC0_SEL 131
164#define CLK_TOP_UART1_SEL 132
165#define CLK_TOP_MSDC1_SEL 133
166#define CLK_TOP_PMICSPI_SEL 134
167#define CLK_TOP_QAXI_AUD26M_SEL 135
168#define CLK_TOP_AUD_INTBUS_SEL 136
169#define CLK_TOP_NFI2X_PAD_SEL 137
170#define CLK_TOP_NFI1X_PAD_SEL 138
171#define CLK_TOP_DDRPHYCFG_SEL 139
172#define CLK_TOP_USB_78M_SEL 140
173#define CLK_TOP_SPINOR_SEL 141
174#define CLK_TOP_MSDC2_SEL 142
175#define CLK_TOP_ETH_SEL 143
176#define CLK_TOP_AUD1_SEL 144
177#define CLK_TOP_AUD2_SEL 145
178#define CLK_TOP_AUD_ENGEN1_SEL 146
179#define CLK_TOP_AUD_ENGEN2_SEL 147
180#define CLK_TOP_I2C_SEL 148
181#define CLK_TOP_AUD_I2S0_M_SEL 149
182#define CLK_TOP_AUD_I2S1_M_SEL 150
183#define CLK_TOP_AUD_I2S2_M_SEL 151
184#define CLK_TOP_AUD_I2S3_M_SEL 152
185#define CLK_TOP_AUD_I2S4_M_SEL 153
186#define CLK_TOP_AUD_I2S5_M_SEL 154
187#define CLK_TOP_AUD_SPDIF_B_SEL 155
188#define CLK_TOP_PWM_SEL 156
189#define CLK_TOP_SPI_SEL 157
190#define CLK_TOP_AUD_SPDIFIN_SEL 158
191#define CLK_TOP_UART2_SEL 159
192#define CLK_TOP_BSI_SEL 160
193#define CLK_TOP_DBG_ATCLK_SEL 161
194#define CLK_TOP_CSW_NFIECC_SEL 162
195#define CLK_TOP_NFIECC_SEL 163
196#define CLK_TOP_APLL12_CK_DIV0 164
197#define CLK_TOP_APLL12_CK_DIV1 165
198#define CLK_TOP_APLL12_CK_DIV2 166
199#define CLK_TOP_APLL12_CK_DIV3 167
200#define CLK_TOP_APLL12_CK_DIV4 168
201#define CLK_TOP_APLL12_CK_DIV4B 169
202#define CLK_TOP_APLL12_CK_DIV5 170
203#define CLK_TOP_APLL12_CK_DIV5B 171
204#define CLK_TOP_APLL12_CK_DIV6 172
205#define CLK_TOP_USB_78M 173
206#define CLK_TOP_MSDC0_INFRA 174
207#define CLK_TOP_MSDC1_INFRA 175
208#define CLK_TOP_MSDC2_INFRA 176
209#define CLK_TOP_NR_CLK 177
210
211#endif /* _DT_BINDINGS_CLK_MT8516_H */
diff --git a/include/dt-bindings/clock/qcom,gcc-qcs404.h b/include/dt-bindings/clock/qcom,gcc-qcs404.h
index 6ceb55ed72c6..454b3f43f538 100644
--- a/include/dt-bindings/clock/qcom,gcc-qcs404.h
+++ b/include/dt-bindings/clock/qcom,gcc-qcs404.h
@@ -146,6 +146,10 @@
146#define GCC_MDP_TBU_CLK 138 146#define GCC_MDP_TBU_CLK 138
147#define GCC_QDSS_DAP_CLK 139 147#define GCC_QDSS_DAP_CLK 139
148#define GCC_DCC_XO_CLK 140 148#define GCC_DCC_XO_CLK 140
149#define GCC_CDSP_CFG_AHB_CLK 143
150#define GCC_BIMC_CDSP_CLK 144
151#define GCC_CDSP_TBU_CLK 145
152#define GCC_CDSP_BIMC_CLK_SRC 146
149 153
150#define GCC_GENI_IR_BCR 0 154#define GCC_GENI_IR_BCR 0
151#define GCC_USB_HS_BCR 1 155#define GCC_USB_HS_BCR 1
@@ -161,5 +165,6 @@
161#define GCC_PCIE_0_LINK_DOWN_BCR 11 165#define GCC_PCIE_0_LINK_DOWN_BCR 11
162#define GCC_PCIEPHY_0_PHY_BCR 12 166#define GCC_PCIEPHY_0_PHY_BCR 12
163#define GCC_EMAC_BCR 13 167#define GCC_EMAC_BCR 13
168#define GCC_CDSP_RESTART 14
164 169
165#endif 170#endif
diff --git a/include/dt-bindings/clock/qcom,turingcc-qcs404.h b/include/dt-bindings/clock/qcom,turingcc-qcs404.h
new file mode 100644
index 000000000000..838faef57c67
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,turingcc-qcs404.h
@@ -0,0 +1,15 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2019, Linaro Ltd
4 */
5
6#ifndef _DT_BINDINGS_CLK_TURING_QCS404_H
7#define _DT_BINDINGS_CLK_TURING_QCS404_H
8
9#define TURING_Q6SS_Q6_AXIM_CLK 0
10#define TURING_Q6SS_AHBM_AON_CLK 1
11#define TURING_WRAPPER_AON_CLK 2
12#define TURING_Q6SS_AHBS_AON_CLK 3
13#define TURING_WRAPPER_QOS_AHBS_AON_CLK 4
14
15#endif
diff --git a/include/dt-bindings/clock/stm32fx-clock.h b/include/dt-bindings/clock/stm32fx-clock.h
index 58d8b515be55..7d34e297049c 100644
--- a/include/dt-bindings/clock/stm32fx-clock.h
+++ b/include/dt-bindings/clock/stm32fx-clock.h
@@ -54,7 +54,10 @@
54#define CLK_I2C3 28 54#define CLK_I2C3 28
55#define CLK_I2C4 29 55#define CLK_I2C4 29
56#define CLK_LPTIMER 30 56#define CLK_LPTIMER 30
57 57#define CLK_PLL_SRC 31
58#define END_PRIMARY_CLK_F7 31 58#define CLK_DFSDM1 32
59#define CLK_ADFSDM1 33
60#define CLK_F769_DSI 34
61#define END_PRIMARY_CLK_F7 35
59 62
60#endif 63#endif
diff --git a/include/dt-bindings/clock/sun5i-ccu.h b/include/dt-bindings/clock/sun5i-ccu.h
index 81f34d477aeb..2e6b9ddcc24e 100644
--- a/include/dt-bindings/clock/sun5i-ccu.h
+++ b/include/dt-bindings/clock/sun5i-ccu.h
@@ -100,7 +100,7 @@
100#define CLK_AVS 96 100#define CLK_AVS 96
101#define CLK_HDMI 97 101#define CLK_HDMI 97
102#define CLK_GPU 98 102#define CLK_GPU 98
103 103#define CLK_MBUS 99
104#define CLK_IEP 100 104#define CLK_IEP 100
105 105
106#endif /* _DT_BINDINGS_CLK_SUN5I_H_ */ 106#endif /* _DT_BINDINGS_CLK_SUN5I_H_ */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index b7cf80a71293..491d992d045d 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -24,7 +24,7 @@
24#define CLK_SET_RATE_PARENT BIT(2) /* propagate rate change up one level */ 24#define CLK_SET_RATE_PARENT BIT(2) /* propagate rate change up one level */
25#define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */ 25#define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */
26 /* unused */ 26 /* unused */
27#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */ 27 /* unused */
28#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */ 28#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */
29#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ 29#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
30#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */ 30#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
@@ -251,19 +251,40 @@ struct clk_ops {
251}; 251};
252 252
253/** 253/**
254 * struct clk_parent_data - clk parent information
255 * @hw: parent clk_hw pointer (used for clk providers with internal clks)
256 * @fw_name: parent name local to provider registering clk
257 * @name: globally unique parent name (used as a fallback)
258 * @index: parent index local to provider registering clk (if @fw_name absent)
259 */
260struct clk_parent_data {
261 const struct clk_hw *hw;
262 const char *fw_name;
263 const char *name;
264 int index;
265};
266
267/**
254 * struct clk_init_data - holds init data that's common to all clocks and is 268 * struct clk_init_data - holds init data that's common to all clocks and is
255 * shared between the clock provider and the common clock framework. 269 * shared between the clock provider and the common clock framework.
256 * 270 *
257 * @name: clock name 271 * @name: clock name
258 * @ops: operations this clock supports 272 * @ops: operations this clock supports
259 * @parent_names: array of string names for all possible parents 273 * @parent_names: array of string names for all possible parents
274 * @parent_data: array of parent data for all possible parents (when some
275 * parents are external to the clk controller)
276 * @parent_hws: array of pointers to all possible parents (when all parents
277 * are internal to the clk controller)
260 * @num_parents: number of possible parents 278 * @num_parents: number of possible parents
261 * @flags: framework-level hints and quirks 279 * @flags: framework-level hints and quirks
262 */ 280 */
263struct clk_init_data { 281struct clk_init_data {
264 const char *name; 282 const char *name;
265 const struct clk_ops *ops; 283 const struct clk_ops *ops;
284 /* Only one of the following three should be assigned */
266 const char * const *parent_names; 285 const char * const *parent_names;
286 const struct clk_parent_data *parent_data;
287 const struct clk_hw **parent_hws;
267 u8 num_parents; 288 u8 num_parents;
268 unsigned long flags; 289 unsigned long flags;
269}; 290};
@@ -307,7 +328,6 @@ struct clk_fixed_rate {
307 struct clk_hw hw; 328 struct clk_hw hw;
308 unsigned long fixed_rate; 329 unsigned long fixed_rate;
309 unsigned long fixed_accuracy; 330 unsigned long fixed_accuracy;
310 u8 flags;
311}; 331};
312 332
313#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw) 333#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw)
@@ -349,6 +369,9 @@ void of_fixed_clk_setup(struct device_node *np);
349 * of this register, and mask of gate bits are in higher 16-bit of this 369 * of this register, and mask of gate bits are in higher 16-bit of this
350 * register. While setting the gate bits, higher 16-bit should also be 370 * register. While setting the gate bits, higher 16-bit should also be
351 * updated to indicate changing gate bits. 371 * updated to indicate changing gate bits.
372 * CLK_GATE_BIG_ENDIAN - by default little endian register accesses are used for
373 * the gate register. Setting this flag makes the register accesses big
374 * endian.
352 */ 375 */
353struct clk_gate { 376struct clk_gate {
354 struct clk_hw hw; 377 struct clk_hw hw;
@@ -362,6 +385,7 @@ struct clk_gate {
362 385
363#define CLK_GATE_SET_TO_DISABLE BIT(0) 386#define CLK_GATE_SET_TO_DISABLE BIT(0)
364#define CLK_GATE_HIWORD_MASK BIT(1) 387#define CLK_GATE_HIWORD_MASK BIT(1)
388#define CLK_GATE_BIG_ENDIAN BIT(2)
365 389
366extern const struct clk_ops clk_gate_ops; 390extern const struct clk_ops clk_gate_ops;
367struct clk *clk_register_gate(struct device *dev, const char *name, 391struct clk *clk_register_gate(struct device *dev, const char *name,
@@ -417,6 +441,9 @@ struct clk_div_table {
417 * CLK_DIVIDER_MAX_AT_ZERO - For dividers which are like CLK_DIVIDER_ONE_BASED 441 * CLK_DIVIDER_MAX_AT_ZERO - For dividers which are like CLK_DIVIDER_ONE_BASED
418 * except when the value read from the register is zero, the divisor is 442 * except when the value read from the register is zero, the divisor is
419 * 2^width of the field. 443 * 2^width of the field.
444 * CLK_DIVIDER_BIG_ENDIAN - By default little endian register accesses are used
445 * for the divider register. Setting this flag makes the register accesses
446 * big endian.
420 */ 447 */
421struct clk_divider { 448struct clk_divider {
422 struct clk_hw hw; 449 struct clk_hw hw;
@@ -438,6 +465,7 @@ struct clk_divider {
438#define CLK_DIVIDER_ROUND_CLOSEST BIT(4) 465#define CLK_DIVIDER_ROUND_CLOSEST BIT(4)
439#define CLK_DIVIDER_READ_ONLY BIT(5) 466#define CLK_DIVIDER_READ_ONLY BIT(5)
440#define CLK_DIVIDER_MAX_AT_ZERO BIT(6) 467#define CLK_DIVIDER_MAX_AT_ZERO BIT(6)
468#define CLK_DIVIDER_BIG_ENDIAN BIT(7)
441 469
442extern const struct clk_ops clk_divider_ops; 470extern const struct clk_ops clk_divider_ops;
443extern const struct clk_ops clk_divider_ro_ops; 471extern const struct clk_ops clk_divider_ro_ops;
@@ -499,8 +527,13 @@ void clk_hw_unregister_divider(struct clk_hw *hw);
499 * register, and mask of mux bits are in higher 16-bit of this register. 527 * register, and mask of mux bits are in higher 16-bit of this register.
500 * While setting the mux bits, higher 16-bit should also be updated to 528 * While setting the mux bits, higher 16-bit should also be updated to
501 * indicate changing mux bits. 529 * indicate changing mux bits.
530 * CLK_MUX_READ_ONLY - The mux registers can't be written, only read in the
531 * .get_parent clk_op.
502 * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired 532 * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired
503 * frequency. 533 * frequency.
534 * CLK_MUX_BIG_ENDIAN - By default little endian register accesses are used for
535 * the mux register. Setting this flag makes the register accesses big
536 * endian.
504 */ 537 */
505struct clk_mux { 538struct clk_mux {
506 struct clk_hw hw; 539 struct clk_hw hw;
@@ -519,6 +552,7 @@ struct clk_mux {
519#define CLK_MUX_HIWORD_MASK BIT(2) 552#define CLK_MUX_HIWORD_MASK BIT(2)
520#define CLK_MUX_READ_ONLY BIT(3) /* mux can't be changed */ 553#define CLK_MUX_READ_ONLY BIT(3) /* mux can't be changed */
521#define CLK_MUX_ROUND_CLOSEST BIT(4) 554#define CLK_MUX_ROUND_CLOSEST BIT(4)
555#define CLK_MUX_BIG_ENDIAN BIT(5)
522 556
523extern const struct clk_ops clk_mux_ops; 557extern const struct clk_ops clk_mux_ops;
524extern const struct clk_ops clk_mux_ro_ops; 558extern const struct clk_ops clk_mux_ro_ops;
@@ -602,6 +636,9 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
602 * is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED 636 * is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED
603 * is set then the numerator and denominator are both the value read 637 * is set then the numerator and denominator are both the value read
604 * plus one. 638 * plus one.
639 * CLK_FRAC_DIVIDER_BIG_ENDIAN - By default little endian register accesses are
640 * used for the divider register. Setting this flag makes the register
641 * accesses big endian.
605 */ 642 */
606struct clk_fractional_divider { 643struct clk_fractional_divider {
607 struct clk_hw hw; 644 struct clk_hw hw;
@@ -622,6 +659,7 @@ struct clk_fractional_divider {
622#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) 659#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
623 660
624#define CLK_FRAC_DIVIDER_ZERO_BASED BIT(0) 661#define CLK_FRAC_DIVIDER_ZERO_BASED BIT(0)
662#define CLK_FRAC_DIVIDER_BIG_ENDIAN BIT(1)
625 663
626extern const struct clk_ops clk_fractional_divider_ops; 664extern const struct clk_ops clk_fractional_divider_ops;
627struct clk *clk_register_fractional_divider(struct device *dev, 665struct clk *clk_register_fractional_divider(struct device *dev,
@@ -654,6 +692,9 @@ void clk_hw_unregister_fractional_divider(struct clk_hw *hw);
654 * leaving the parent rate unmodified. 692 * leaving the parent rate unmodified.
655 * CLK_MULTIPLIER_ROUND_CLOSEST - Makes the best calculated divider to be 693 * CLK_MULTIPLIER_ROUND_CLOSEST - Makes the best calculated divider to be
656 * rounded to the closest integer instead of the down one. 694 * rounded to the closest integer instead of the down one.
695 * CLK_MULTIPLIER_BIG_ENDIAN - By default little endian register accesses are
696 * used for the multiplier register. Setting this flag makes the register
697 * accesses big endian.
657 */ 698 */
658struct clk_multiplier { 699struct clk_multiplier {
659 struct clk_hw hw; 700 struct clk_hw hw;
@@ -668,6 +709,7 @@ struct clk_multiplier {
668 709
669#define CLK_MULTIPLIER_ZERO_BYPASS BIT(0) 710#define CLK_MULTIPLIER_ZERO_BYPASS BIT(0)
670#define CLK_MULTIPLIER_ROUND_CLOSEST BIT(1) 711#define CLK_MULTIPLIER_ROUND_CLOSEST BIT(1)
712#define CLK_MULTIPLIER_BIG_ENDIAN BIT(2)
671 713
672extern const struct clk_ops clk_multiplier_ops; 714extern const struct clk_ops clk_multiplier_ops;
673 715
@@ -712,16 +754,19 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
712 unsigned long flags); 754 unsigned long flags);
713void clk_hw_unregister_composite(struct clk_hw *hw); 755void clk_hw_unregister_composite(struct clk_hw *hw);
714 756
715/*** 757/**
716 * struct clk_gpio_gate - gpio gated clock 758 * struct clk_gpio - gpio gated clock
717 * 759 *
718 * @hw: handle between common and hardware-specific interfaces 760 * @hw: handle between common and hardware-specific interfaces
719 * @gpiod: gpio descriptor 761 * @gpiod: gpio descriptor
720 * 762 *
721 * Clock with a gpio control for enabling and disabling the parent clock. 763 * Clock with a gpio control for enabling and disabling the parent clock
722 * Implements .enable, .disable and .is_enabled 764 * or switching between two parents by asserting or deasserting the gpio.
765 *
766 * Implements .enable, .disable and .is_enabled or
767 * .get_parent, .set_parent and .determine_rate depending on which clk_ops
768 * is used.
723 */ 769 */
724
725struct clk_gpio { 770struct clk_gpio {
726 struct clk_hw hw; 771 struct clk_hw hw;
727 struct gpio_desc *gpiod; 772 struct gpio_desc *gpiod;
@@ -738,16 +783,6 @@ struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
738 unsigned long flags); 783 unsigned long flags);
739void clk_hw_unregister_gpio_gate(struct clk_hw *hw); 784void clk_hw_unregister_gpio_gate(struct clk_hw *hw);
740 785
741/**
742 * struct clk_gpio_mux - gpio controlled clock multiplexer
743 *
744 * @hw: see struct clk_gpio
745 * @gpiod: gpio descriptor to select the parent of this clock multiplexer
746 *
747 * Clock with a gpio control for selecting the parent clock.
748 * Implements .get_parent, .set_parent and .determine_rate
749 */
750
751extern const struct clk_ops clk_gpio_mux_ops; 786extern const struct clk_ops clk_gpio_mux_ops;
752struct clk *clk_register_gpio_mux(struct device *dev, const char *name, 787struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
753 const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod, 788 const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
@@ -757,22 +792,12 @@ struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
757 unsigned long flags); 792 unsigned long flags);
758void clk_hw_unregister_gpio_mux(struct clk_hw *hw); 793void clk_hw_unregister_gpio_mux(struct clk_hw *hw);
759 794
760/**
761 * clk_register - allocate a new clock, register it and return an opaque cookie
762 * @dev: device that is registering this clock
763 * @hw: link to hardware-specific clock data
764 *
765 * clk_register is the primary interface for populating the clock tree with new
766 * clock nodes. It returns a pointer to the newly allocated struct clk which
767 * cannot be dereferenced by driver code but may be used in conjuction with the
768 * rest of the clock API. In the event of an error clk_register will return an
769 * error code; drivers must test for an error code after calling clk_register.
770 */
771struct clk *clk_register(struct device *dev, struct clk_hw *hw); 795struct clk *clk_register(struct device *dev, struct clk_hw *hw);
772struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw); 796struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);
773 797
774int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw); 798int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw);
775int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw); 799int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw);
800int __must_check of_clk_hw_register(struct device_node *node, struct clk_hw *hw);
776 801
777void clk_unregister(struct clk *clk); 802void clk_unregister(struct clk *clk);
778void devm_clk_unregister(struct device *dev, struct clk *clk); 803void devm_clk_unregister(struct device *dev, struct clk *clk);
@@ -993,37 +1018,6 @@ static inline int of_clk_detect_critical(struct device_node *np, int index,
993} 1018}
994#endif /* CONFIG_OF */ 1019#endif /* CONFIG_OF */
995 1020
996/*
997 * wrap access to peripherals in accessor routines
998 * for improved portability across platforms
999 */
1000
1001#if IS_ENABLED(CONFIG_PPC)
1002
1003static inline u32 clk_readl(u32 __iomem *reg)
1004{
1005 return ioread32be(reg);
1006}
1007
1008static inline void clk_writel(u32 val, u32 __iomem *reg)
1009{
1010 iowrite32be(val, reg);
1011}
1012
1013#else /* platform dependent I/O accessors */
1014
1015static inline u32 clk_readl(u32 __iomem *reg)
1016{
1017 return readl(reg);
1018}
1019
1020static inline void clk_writel(u32 val, u32 __iomem *reg)
1021{
1022 writel(val, reg);
1023}
1024
1025#endif /* platform dependent I/O accessors */
1026
1027void clk_gate_restore_context(struct clk_hw *hw); 1021void clk_gate_restore_context(struct clk_hw *hw);
1028 1022
1029#endif /* CONFIG_COMMON_CLK */ 1023#endif /* CONFIG_COMMON_CLK */
diff --git a/include/linux/clk/analogbits-wrpll-cln28hpc.h b/include/linux/clk/analogbits-wrpll-cln28hpc.h
new file mode 100644
index 000000000000..03279097e138
--- /dev/null
+++ b/include/linux/clk/analogbits-wrpll-cln28hpc.h
@@ -0,0 +1,79 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2018-2019 SiFive, Inc.
4 * Wesley Terpstra
5 * Paul Walmsley
6 */
7
8#ifndef __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H
9#define __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H
10
11#include <linux/types.h>
12
13/* DIVQ_VALUES: number of valid DIVQ values */
14#define DIVQ_VALUES 6
15
16/*
17 * Bit definitions for struct wrpll_cfg.flags
18 *
19 * WRPLL_FLAGS_BYPASS_FLAG: if set, the PLL is either in bypass, or should be
20 * programmed to enter bypass
21 * WRPLL_FLAGS_RESET_FLAG: if set, the PLL is in reset
22 * WRPLL_FLAGS_INT_FEEDBACK_FLAG: if set, the PLL is configured for internal
23 * feedback mode
24 * WRPLL_FLAGS_EXT_FEEDBACK_FLAG: if set, the PLL is configured for external
25 * feedback mode (not yet supported by this driver)
26 */
27#define WRPLL_FLAGS_BYPASS_SHIFT 0
28#define WRPLL_FLAGS_BYPASS_MASK BIT(WRPLL_FLAGS_BYPASS_SHIFT)
29#define WRPLL_FLAGS_RESET_SHIFT 1
30#define WRPLL_FLAGS_RESET_MASK BIT(WRPLL_FLAGS_RESET_SHIFT)
31#define WRPLL_FLAGS_INT_FEEDBACK_SHIFT 2
32#define WRPLL_FLAGS_INT_FEEDBACK_MASK BIT(WRPLL_FLAGS_INT_FEEDBACK_SHIFT)
33#define WRPLL_FLAGS_EXT_FEEDBACK_SHIFT 3
34#define WRPLL_FLAGS_EXT_FEEDBACK_MASK BIT(WRPLL_FLAGS_EXT_FEEDBACK_SHIFT)
35
36/**
37 * struct wrpll_cfg - WRPLL configuration values
38 * @divr: reference divider value (6 bits), as presented to the PLL signals
39 * @divf: feedback divider value (9 bits), as presented to the PLL signals
40 * @divq: output divider value (3 bits), as presented to the PLL signals
41 * @flags: PLL configuration flags. See above for more information
42 * @range: PLL loop filter range. See below for more information
43 * @output_rate_cache: cached output rates, swept across DIVQ
44 * @parent_rate: PLL refclk rate for which values are valid
45 * @max_r: maximum possible R divider value, given @parent_rate
46 * @init_r: initial R divider value to start the search from
47 *
48 * @divr, @divq, @divq, @range represent what the PLL expects to see
49 * on its input signals. Thus @divr and @divf are the actual divisors
50 * minus one. @divq is a power-of-two divider; for example, 1 =
51 * divide-by-2 and 6 = divide-by-64. 0 is an invalid @divq value.
52 *
53 * When initially passing a struct wrpll_cfg record, the
54 * record should be zero-initialized with the exception of the @flags
55 * field. The only flag bits that need to be set are either
56 * WRPLL_FLAGS_INT_FEEDBACK or WRPLL_FLAGS_EXT_FEEDBACK.
57 */
58struct wrpll_cfg {
59 u8 divr;
60 u8 divq;
61 u8 range;
62 u8 flags;
63 u16 divf;
64/* private: */
65 u32 output_rate_cache[DIVQ_VALUES];
66 unsigned long parent_rate;
67 u8 max_r;
68 u8 init_r;
69};
70
71int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate,
72 unsigned long parent_rate);
73
74unsigned int wrpll_calc_max_lock_us(const struct wrpll_cfg *c);
75
76unsigned long wrpll_calc_output_rate(const struct wrpll_cfg *c,
77 unsigned long parent_rate);
78
79#endif /* __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H */
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index 931ab05f771d..0c53f26ae3d3 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -74,6 +74,8 @@
74#define AT91_PMC_USBDIV_4 (2 << 28) 74#define AT91_PMC_USBDIV_4 (2 << 28)
75#define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */ 75#define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */
76 76
77#define AT91_PMC_CPU_CKR 0x28 /* CPU Clock Register */
78
77#define AT91_PMC_MCKR 0x30 /* Master Clock Register */ 79#define AT91_PMC_MCKR 0x30 /* Master Clock Register */
78#define AT91_PMC_CSS (3 << 0) /* Master Clock Selection */ 80#define AT91_PMC_CSS (3 << 0) /* Master Clock Selection */
79#define AT91_PMC_CSS_SLOW (0 << 0) 81#define AT91_PMC_CSS_SLOW (0 << 0)
@@ -187,16 +189,8 @@
187 189
188#define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9 and SAMA5] */ 190#define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9 and SAMA5] */
189#define AT91_PMC_PCR_PID_MASK 0x3f 191#define AT91_PMC_PCR_PID_MASK 0x3f
190#define AT91_PMC_PCR_GCKCSS_OFFSET 8
191#define AT91_PMC_PCR_GCKCSS_MASK (0x7 << AT91_PMC_PCR_GCKCSS_OFFSET)
192#define AT91_PMC_PCR_GCKCSS(n) ((n) << AT91_PMC_PCR_GCKCSS_OFFSET) /* GCK Clock Source Selection */
193#define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */ 192#define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */
194#define AT91_PMC_PCR_DIV_OFFSET 16 193#define AT91_PMC_PCR_GCKDIV_MASK GENMASK(27, 20)
195#define AT91_PMC_PCR_DIV_MASK (0x3 << AT91_PMC_PCR_DIV_OFFSET)
196#define AT91_PMC_PCR_DIV(n) ((n) << AT91_PMC_PCR_DIV_OFFSET) /* Divisor Value */
197#define AT91_PMC_PCR_GCKDIV_OFFSET 20
198#define AT91_PMC_PCR_GCKDIV_MASK (0xff << AT91_PMC_PCR_GCKDIV_OFFSET)
199#define AT91_PMC_PCR_GCKDIV(n) ((n) << AT91_PMC_PCR_GCKDIV_OFFSET) /* Generated Clock Divisor Value */
200#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ 194#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */
201#define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */ 195#define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */
202 196
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 78872efc7be0..1e8ef96555ce 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -243,6 +243,7 @@ struct ti_clk_ll_ops {
243 243
244#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw) 244#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
245 245
246bool omap2_clk_is_hw_omap(struct clk_hw *hw);
246int omap2_clk_disable_autoidle_all(void); 247int omap2_clk_disable_autoidle_all(void);
247int omap2_clk_enable_autoidle_all(void); 248int omap2_clk_enable_autoidle_all(void);
248int omap2_clk_allow_idle(struct clk *clk); 249int omap2_clk_allow_idle(struct clk *clk);
@@ -293,6 +294,7 @@ struct ti_clk_features {
293#define TI_CLK_DISABLE_CLKDM_CONTROL BIT(2) 294#define TI_CLK_DISABLE_CLKDM_CONTROL BIT(2)
294#define TI_CLK_ERRATA_I810 BIT(3) 295#define TI_CLK_ERRATA_I810 BIT(3)
295#define TI_CLK_CLKCTRL_COMPAT BIT(4) 296#define TI_CLK_CLKCTRL_COMPAT BIT(4)
297#define TI_CLK_DEVICE_TYPE_GP BIT(5)
296 298
297void ti_clk_setup_features(struct ti_clk_features *features); 299void ti_clk_setup_features(struct ti_clk_features *features);
298const struct ti_clk_features *ti_clk_get_features(void); 300const struct ti_clk_features *ti_clk_get_features(void);
diff --git a/include/linux/device.h b/include/linux/device.h
index 4457e560bc2b..e85264fb6616 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1229,7 +1229,7 @@ static inline void device_lock_assert(struct device *dev)
1229 1229
1230static inline struct device_node *dev_of_node(struct device *dev) 1230static inline struct device_node *dev_of_node(struct device *dev)
1231{ 1231{
1232 if (!IS_ENABLED(CONFIG_OF)) 1232 if (!IS_ENABLED(CONFIG_OF) || !dev)
1233 return NULL; 1233 return NULL;
1234 return dev->of_node; 1234 return dev->of_node;
1235} 1235}
diff --git a/include/linux/math64.h b/include/linux/math64.h
index bb2c84afb80c..65bef21cdddb 100644
--- a/include/linux/math64.h
+++ b/include/linux/math64.h
@@ -284,4 +284,17 @@ static inline u64 mul_u64_u32_div(u64 a, u32 mul, u32 divisor)
284#define DIV64_U64_ROUND_UP(ll, d) \ 284#define DIV64_U64_ROUND_UP(ll, d) \
285 ({ u64 _tmp = (d); div64_u64((ll) + _tmp - 1, _tmp); }) 285 ({ u64 _tmp = (d); div64_u64((ll) + _tmp - 1, _tmp); })
286 286
287/**
288 * DIV64_U64_ROUND_CLOSEST - unsigned 64bit divide with 64bit divisor rounded to nearest integer
289 * @dividend: unsigned 64bit dividend
290 * @divisor: unsigned 64bit divisor
291 *
292 * Divide unsigned 64bit dividend by unsigned 64bit divisor
293 * and round to closest integer.
294 *
295 * Return: dividend / divisor rounded to nearest integer
296 */
297#define DIV64_U64_ROUND_CLOSEST(dividend, divisor) \
298 ({ u64 _tmp = (divisor); div64_u64((dividend) + _tmp / 2, _tmp); })
299
287#endif /* _LINUX_MATH64_H */ 300#endif /* _LINUX_MATH64_H */