aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-02-25 17:28:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-25 17:28:06 -0500
commit5d8a00eee2ed2e548a5d21b0edf495f3f7bf8bb4 (patch)
treefdc6c7754a5ea2a8a31df53e181e632e6e84b44f
parent7067739df23ffd641ca99c967830e0ed2ba39eab (diff)
parentf59de563358eb9351b7f8f0ba2d3be2ebb70b93d (diff)
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd: "The usual collection of new drivers, non-critical fixes, and updates to existing clk drivers. The bulk of the work is on Allwinner and Rockchip SoCs, but there's also an Intel Atom driver in here too. New Drivers: - Tegra BPMP firmware - Hisilicon hi3660 SoCs - Rockchip rk3328 SoCs - Intel Atom PMC - STM32F746 - IDT VersaClock 5P49V5923 and 5P49V5933 - Marvell mv98dx3236 SoCs - Allwinner V3s SoCs Removed Drivers: - Samsung Exynos4415 SoCs Updates: - Migrate ABx500 to OF - Qualcomm IPQ4019 CPU clks and general PLL support - Qualcomm MSM8974 RPM - Rockchip non-critical fixes and clk id additions - Samsung Exynos4412 CPUs - Socionext UniPhier NAND and eMMC support - ZTE zx296718 i2s and other audio clks - Renesas CAN and MSIOF clks for R-Car M3-W - Renesas resets for R-Car Gen2 and Gen3 and RZ/G1 - TI CDCE913, CDCE937, and CDCE949 clk generators - Marvell Armada ap806 CPU frequencies - STM32F4* I2S/SAI support - Broadcom BCM2835 DSI support - Allwinner sun5i and A80 conversion to new style clk bindings" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (130 commits) clk: renesas: mstp: ensure register writes complete clk: qcom: Do not drop device node twice clk: mvebu: adjust clock handling for the CP110 system controller clk: mvebu: Expand mv98dx3236-core-clock support clk: zte: add i2s clocks for zx296718 clk: sunxi-ng: sun9i-a80: Fix wrong pointer passed to PTR_ERR() clk: sunxi-ng: select SUNXI_CCU_MULT for sun5i clk: sunxi-ng: Check kzalloc() for errors and cleanup error path clk: tegra: Add BPMP clock driver clk: uniphier: add eMMC clock for LD11 and LD20 SoCs clk: uniphier: add NAND clock for all UniPhier SoCs ARM: dts: sun9i: Switch to new clock bindings clk: sunxi-ng: Add A80 Display Engine CCU clk: sunxi-ng: Add A80 USB CCU clk: sunxi-ng: Add A80 CCU clk: sunxi-ng: Support separately grouped PLL lock status register clk: sunxi-ng: mux: Get closest parent rate possible with CLK_SET_RATE_PARENT clk: sunxi-ng: mux: honor CLK_SET_RATE_NO_REPARENT flag clk: sunxi-ng: mux: Fix determine_rate for mux clocks with pre-dividers clk: qcom: SDHCI enablement on Nexus 5X / 6P ...
-rw-r--r--Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt15
-rw-r--r--Documentation/devicetree/bindings/clock/exynos4415-clock.txt38
-rw-r--r--Documentation/devicetree/bindings/clock/hi3660-clock.txt42
-rw-r--r--Documentation/devicetree/bindings/clock/idt,versaclock5.txt65
-rw-r--r--Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt1
-rw-r--r--Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt1
-rw-r--r--Documentation/devicetree/bindings/clock/qcom,rpmcc.txt1
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt6
-rw-r--r--Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt57
-rw-r--r--Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt6
-rw-r--r--Documentation/devicetree/bindings/clock/st,stm32-rcc.txt20
-rw-r--r--Documentation/devicetree/bindings/clock/stericsson,abx500.txt20
-rw-r--r--Documentation/devicetree/bindings/clock/sun9i-de.txt28
-rw-r--r--Documentation/devicetree/bindings/clock/sun9i-usb.txt24
-rw-r--r--Documentation/devicetree/bindings/clock/sunxi-ccu.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/ti,cdce925.txt15
-rw-r--r--Documentation/devicetree/bindings/clock/zx296718-clk.txt3
-rw-r--r--MAINTAINERS5
-rw-r--r--arch/arm/boot/dts/sun5i-a10s.dtsi85
-rw-r--r--arch/arm/boot/dts/sun5i-a13.dtsi140
-rw-r--r--arch/arm/boot/dts/sun5i-gr8.dtsi520
-rw-r--r--arch/arm/boot/dts/sun5i-r8.dtsi10
-rw-r--r--arch/arm/boot/dts/sun5i.dtsi353
-rw-r--r--arch/arm/boot/dts/sun9i-a80.dtsi404
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--arch/x86/platform/atom/Makefile1
-rw-r--r--drivers/acpi/acpi_lpss.c2
-rw-r--r--drivers/clk/Kconfig21
-rw-r--r--drivers/clk/Makefile3
-rw-r--r--drivers/clk/axs10x/i2s_pll_clock.c1
-rw-r--r--drivers/clk/bcm/clk-bcm2835.c303
-rw-r--r--drivers/clk/clk-cdce925.c108
-rw-r--r--drivers/clk/clk-conf.c15
-rw-r--r--drivers/clk/clk-cs2000-cp.c22
-rw-r--r--drivers/clk/clk-scpi.c14
-rw-r--r--drivers/clk/clk-stm32f4.c872
-rw-r--r--drivers/clk/clk-versaclock5.c791
-rw-r--r--drivers/clk/clk-wm831x.c3
-rw-r--r--drivers/clk/hisilicon/Kconfig7
-rw-r--r--drivers/clk/hisilicon/Makefile1
-rw-r--r--drivers/clk/hisilicon/clk-hi3660.c567
-rw-r--r--drivers/clk/hisilicon/clkgate-separated.c1
-rw-r--r--drivers/clk/imx/clk-imx6q.c21
-rw-r--r--drivers/clk/imx/clk-imx7d.c1
-rw-r--r--drivers/clk/imx/clk-pllv3.c99
-rw-r--r--drivers/clk/imx/clk-vf610.c4
-rw-r--r--drivers/clk/imx/clk.h1
-rw-r--r--drivers/clk/mediatek/Kconfig19
-rw-r--r--drivers/clk/meson/meson8b.c1
-rw-r--r--drivers/clk/mvebu/Makefile2
-rw-r--r--drivers/clk/mvebu/ap806-system-controller.c28
-rw-r--r--drivers/clk/mvebu/armada-xp.c26
-rw-r--r--drivers/clk/mvebu/clk-corediv.c23
-rw-r--r--drivers/clk/mvebu/clk-cpu.c8
-rw-r--r--drivers/clk/mvebu/cp110-system-controller.c13
-rw-r--r--drivers/clk/mvebu/mv98dx3236.c180
-rw-r--r--drivers/clk/qcom/clk-smd-rpm.c71
-rw-r--r--drivers/clk/qcom/common.c1
-rw-r--r--drivers/clk/qcom/gcc-ipq4019.c479
-rw-r--r--drivers/clk/qcom/gcc-mdm9615.c30
-rw-r--r--drivers/clk/qcom/gcc-msm8994.c18
-rw-r--r--drivers/clk/qcom/gcc-msm8996.c1
-rw-r--r--drivers/clk/qcom/gdsc.c58
-rw-r--r--drivers/clk/renesas/clk-mstp.c17
-rw-r--r--drivers/clk/renesas/r8a7795-cpg-mssr.c1
-rw-r--r--drivers/clk/renesas/r8a7796-cpg-mssr.c10
-rw-r--r--drivers/clk/renesas/renesas-cpg-mssr.c149
-rw-r--r--drivers/clk/rockchip/Makefile2
-rw-r--r--drivers/clk/rockchip/clk-muxgrf.c102
-rw-r--r--drivers/clk/rockchip/clk-pll.c16
-rw-r--r--drivers/clk/rockchip/clk-rk3188.c4
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c36
-rw-r--r--drivers/clk/rockchip/clk-rk3328.c895
-rw-r--r--drivers/clk/rockchip/clk-rk3399.c2
-rw-r--r--drivers/clk/rockchip/clk.c8
-rw-r--r--drivers/clk/rockchip/clk.h40
-rw-r--r--drivers/clk/samsung/Makefile1
-rw-r--r--drivers/clk/samsung/clk-exynos-audss.c24
-rw-r--r--drivers/clk/samsung/clk-exynos4415.c1022
-rw-r--r--drivers/clk/samsung/clk-exynos5433.c44
-rw-r--r--drivers/clk/samsung/clk-pll.c45
-rw-r--r--drivers/clk/samsung/clk-s3c2410.c4
-rw-r--r--drivers/clk/samsung/clk-s3c2412.c4
-rw-r--r--drivers/clk/samsung/clk-s3c2443.c4
-rw-r--r--drivers/clk/samsung/clk-s3c64xx.c4
-rw-r--r--drivers/clk/sunxi-ng/Kconfig32
-rw-r--r--drivers/clk/sunxi-ng/Makefile5
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun5i.c1022
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun5i.h67
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun6i-a31.c4
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a33.c16
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-h3.c10
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-v3s.c591
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-v3s.h63
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c283
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun9i-a80-de.h33
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c144
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.h25
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun9i-a80.c1223
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun9i-a80.h57
-rw-r--r--drivers/clk/sunxi-ng/ccu_common.c24
-rw-r--r--drivers/clk/sunxi-ng/ccu_common.h4
-rw-r--r--drivers/clk/sunxi-ng/ccu_div.c12
-rw-r--r--drivers/clk/sunxi-ng/ccu_div.h10
-rw-r--r--drivers/clk/sunxi-ng/ccu_mp.c10
-rw-r--r--drivers/clk/sunxi-ng/ccu_mult.c30
-rw-r--r--drivers/clk/sunxi-ng/ccu_mult.h24
-rw-r--r--drivers/clk/sunxi-ng/ccu_mux.c43
-rw-r--r--drivers/clk/sunxi-ng/ccu_nk.c22
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkm.c26
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkmp.c25
-rw-r--r--drivers/clk/sunxi-ng/ccu_nm.c17
-rw-r--r--drivers/clk/tegra/Kconfig4
-rw-r--r--drivers/clk/tegra/Makefile1
-rw-r--r--drivers/clk/tegra/clk-bpmp.c620
-rw-r--r--drivers/clk/ti/divider.c31
-rw-r--r--drivers/clk/uniphier/clk-uniphier-core.c7
-rw-r--r--drivers/clk/uniphier/clk-uniphier-cpugear.c1
-rw-r--r--drivers/clk/uniphier/clk-uniphier-sys.c21
-rw-r--r--drivers/clk/ux500/abx500-clk.c44
-rw-r--r--drivers/clk/ux500/u8500_of_clk.c3
-rw-r--r--drivers/clk/x86/Makefile1
-rw-r--r--drivers/clk/x86/clk-pmc-atom.c371
-rw-r--r--drivers/clk/zte/clk-zx296718.c158
-rw-r--r--drivers/clk/zte/clk.c127
-rw-r--r--drivers/clk/zte/clk.h21
-rw-r--r--drivers/platform/x86/Kconfig5
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/pmc_atom.c (renamed from arch/x86/platform/atom/pmc_atom.c)88
-rw-r--r--include/dt-bindings/clock/bcm2835.h2
-rw-r--r--include/dt-bindings/clock/exynos4415.h360
-rw-r--r--include/dt-bindings/clock/exynos5433.h5
-rw-r--r--include/dt-bindings/clock/hi3660-clock.h194
-rw-r--r--include/dt-bindings/clock/imx7d-clock.h3
-rw-r--r--include/dt-bindings/clock/qcom,gcc-ipq4019.h11
-rw-r--r--include/dt-bindings/clock/qcom,gcc-mdm9615.h2
-rw-r--r--include/dt-bindings/clock/qcom,gcc-msm8994.h1
-rw-r--r--include/dt-bindings/clock/qcom,gcc-msm8996.h1
-rw-r--r--include/dt-bindings/clock/qcom,rpmcc.h40
-rw-r--r--include/dt-bindings/clock/rk3188-cru-common.h2
-rw-r--r--include/dt-bindings/clock/rk3288-cru.h2
-rw-r--r--include/dt-bindings/clock/rk3328-cru.h400
-rw-r--r--include/dt-bindings/clock/ste-ab8500.h11
-rw-r--r--include/dt-bindings/clock/stm32fx-clock.h20
-rw-r--r--include/dt-bindings/clock/sun5i-ccu.h103
-rw-r--r--include/dt-bindings/clock/sun8i-v3s-ccu.h107
-rw-r--r--include/dt-bindings/clock/sun9i-a80-ccu.h162
-rw-r--r--include/dt-bindings/clock/sun9i-a80-de.h80
-rw-r--r--include/dt-bindings/clock/sun9i-a80-usb.h59
-rw-r--r--include/dt-bindings/reset/sun5i-ccu.h32
-rw-r--r--include/dt-bindings/reset/sun8i-v3s-ccu.h78
-rw-r--r--include/dt-bindings/reset/sun9i-a80-ccu.h102
-rw-r--r--include/dt-bindings/reset/sun9i-a80-de.h58
-rw-r--r--include/dt-bindings/reset/sun9i-a80-usb.h56
-rw-r--r--include/linux/platform_data/x86/clk-pmc-atom.h44
-rw-r--r--include/linux/platform_data/x86/pmc_atom.h (renamed from arch/x86/include/asm/pmc_atom.h)2
156 files changed, 12306 insertions, 3072 deletions
diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
index e56a1df3a9d3..dd906db34b32 100644
--- a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
+++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
@@ -16,7 +16,20 @@ Required properties:
16- #clock-cells: Should be <1>. The permitted clock-specifier values can be 16- #clock-cells: Should be <1>. The permitted clock-specifier values can be
17 found in include/dt-bindings/clock/bcm2835.h 17 found in include/dt-bindings/clock/bcm2835.h
18- reg: Specifies base physical address and size of the registers 18- reg: Specifies base physical address and size of the registers
19- clocks: The external oscillator clock phandle 19- clocks: phandles to the parent clocks used as input to the module, in
20 the following order:
21
22 - External oscillator
23 - DSI0 byte clock
24 - DSI0 DDR2 clock
25 - DSI0 DDR clock
26 - DSI1 byte clock
27 - DSI1 DDR2 clock
28 - DSI1 DDR clock
29
30 Only external oscillator is required. The DSI clocks may
31 not be present, in which case their children will be
32 unusable.
20 33
21Example: 34Example:
22 35
diff --git a/Documentation/devicetree/bindings/clock/exynos4415-clock.txt b/Documentation/devicetree/bindings/clock/exynos4415-clock.txt
deleted file mode 100644
index 847d98bae8cf..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos4415-clock.txt
+++ /dev/null
@@ -1,38 +0,0 @@
1* Samsung Exynos4415 Clock Controller
2
3The Exynos4415 clock controller generates and supplies clock to various
4consumer devices within the Exynos4415 SoC.
5
6Required properties:
7
8- compatible: should be one of the following:
9 - "samsung,exynos4415-cmu" - for the main system clocks controller
10 (CMU_LEFTBUS, CMU_RIGHTBUS, CMU_TOP, CMU_CPU clock domains).
11 - "samsung,exynos4415-cmu-dmc" - for the Exynos4415 SoC DRAM Memory
12 Controller (DMC) domain clock controller.
13
14- reg: physical base address of the controller and length of memory mapped
15 region.
16
17- #clock-cells: should be 1.
18
19Each clock is assigned an identifier and client nodes can use this identifier
20to specify the clock which they consume.
21
22All available clocks are defined as preprocessor macros in
23dt-bindings/clock/exynos4415.h header and can be used in device
24tree sources.
25
26Example 1: An example of a clock controller node is listed below.
27
28 cmu: clock-controller@10030000 {
29 compatible = "samsung,exynos4415-cmu";
30 reg = <0x10030000 0x18000>;
31 #clock-cells = <1>;
32 };
33
34 cmu-dmc: clock-controller@105C0000 {
35 compatible = "samsung,exynos4415-cmu-dmc";
36 reg = <0x105C0000 0x3000>;
37 #clock-cells = <1>;
38 };
diff --git a/Documentation/devicetree/bindings/clock/hi3660-clock.txt b/Documentation/devicetree/bindings/clock/hi3660-clock.txt
new file mode 100644
index 000000000000..cc9b86c35758
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hi3660-clock.txt
@@ -0,0 +1,42 @@
1* Hisilicon Hi3660 Clock Controller
2
3The Hi3660 clock controller generates and supplies clock to various
4controllers within the Hi3660 SoC.
5
6Required Properties:
7
8- compatible: the compatible should be one of the following strings to
9 indicate the clock controller functionality.
10
11 - "hisilicon,hi3660-crgctrl"
12 - "hisilicon,hi3660-pctrl"
13 - "hisilicon,hi3660-pmuctrl"
14 - "hisilicon,hi3660-sctrl"
15 - "hisilicon,hi3660-iomcu"
16
17- reg: physical base address of the controller and length of memory mapped
18 region.
19
20- #clock-cells: should be 1.
21
22Each clock is assigned an identifier and client nodes use this identifier
23to specify the clock which they consume.
24
25All these identifier could be found in <dt-bindings/clock/hi3660-clock.h>.
26
27Examples:
28 crg_ctrl: clock-controller@fff35000 {
29 compatible = "hisilicon,hi3660-crgctrl", "syscon";
30 reg = <0x0 0xfff35000 0x0 0x1000>;
31 #clock-cells = <1>;
32 };
33
34 uart0: serial@fdf02000 {
35 compatible = "arm,pl011", "arm,primecell";
36 reg = <0x0 0xfdf02000 0x0 0x1000>;
37 interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
38 clocks = <&crg_ctrl HI3660_CLK_MUX_UART0>,
39 <&crg_ctrl HI3660_PCLK>;
40 clock-names = "uartclk", "apb_pclk";
41 status = "disabled";
42 };
diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
new file mode 100644
index 000000000000..87e9c47a89a3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt
@@ -0,0 +1,65 @@
1Binding for IDT VersaClock5 programmable i2c clock generator.
2
3The IDT VersaClock5 are programmable i2c clock generators providing
4from 3 to 12 output clocks.
5
6==I2C device node==
7
8Required properties:
9- compatible: shall be one of "idt,5p49v5923" , "idt,5p49v5933".
10- reg: i2c device address, shall be 0x68 or 0x6a.
11- #clock-cells: from common clock binding; shall be set to 1.
12- clocks: from common clock binding; list of parent clock handles,
13 - 5p49v5923: (required) either or both of XTAL or CLKIN
14 reference clock.
15 - 5p49v5933: (optional) property not present (internal
16 Xtal used) or CLKIN reference
17 clock.
18- clock-names: from common clock binding; clock input names, can be
19 - 5p49v5923: (required) either or both of "xin", "clkin".
20 - 5p49v5933: (optional) property not present or "clkin".
21
22==Mapping between clock specifier and physical pins==
23
24When referencing the provided clock in the DT using phandle and
25clock specifier, the following mapping applies:
26
275P49V5923:
28 0 -- OUT0_SEL_I2CB
29 1 -- OUT1
30 2 -- OUT2
31
325P49V5933:
33 0 -- OUT0_SEL_I2CB
34 1 -- OUT1
35 2 -- OUT4
36
37==Example==
38
39/* 25MHz reference crystal */
40ref25: ref25m {
41 compatible = "fixed-clock";
42 #clock-cells = <0>;
43 clock-frequency = <25000000>;
44};
45
46i2c-master-node {
47
48 /* IDT 5P49V5923 i2c clock generator */
49 vc5: clock-generator@6a {
50 compatible = "idt,5p49v5923";
51 reg = <0x6a>;
52 #clock-cells = <1>;
53
54 /* Connect XIN input to 25MHz reference */
55 clocks = <&ref25m>;
56 clock-names = "xin";
57 };
58};
59
60/* Consumer referencing the 5P49V5923 pin OUT1 */
61consumer {
62 ...
63 clocks = <&vc5 1>;
64 ...
65}
diff --git a/Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt
index 520562a7dc2a..c7b4e3a6b2c6 100644
--- a/Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt
+++ b/Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt
@@ -7,6 +7,7 @@ Required properties:
7- compatible : must be "marvell,armada-370-corediv-clock", 7- compatible : must be "marvell,armada-370-corediv-clock",
8 "marvell,armada-375-corediv-clock", 8 "marvell,armada-375-corediv-clock",
9 "marvell,armada-380-corediv-clock", 9 "marvell,armada-380-corediv-clock",
10 "marvell,mv98dx3236-corediv-clock",
10 11
11- reg : must be the register address of Core Divider control register 12- reg : must be the register address of Core Divider control register
12- #clock-cells : from common clock binding; shall be set to 1 13- #clock-cells : from common clock binding; shall be set to 1
diff --git a/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
index 99c214660bdc..7f28506eaee7 100644
--- a/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
+++ b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
@@ -3,6 +3,7 @@ Device Tree Clock bindings for cpu clock of Marvell EBU platforms
3Required properties: 3Required properties:
4- compatible : shall be one of the following: 4- compatible : shall be one of the following:
5 "marvell,armada-xp-cpu-clock" - cpu clocks for Armada XP 5 "marvell,armada-xp-cpu-clock" - cpu clocks for Armada XP
6 "marvell,mv98dx3236-cpu-clock" - cpu clocks for 98DX3236 SoC
6- reg : Address and length of the clock complex register set, followed 7- reg : Address and length of the clock complex register set, followed
7 by address and length of the PMU DFS registers 8 by address and length of the PMU DFS registers
8- #clock-cells : should be set to 1. 9- #clock-cells : should be set to 1.
diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
index 87d3714b956a..a7235e9e1c97 100644
--- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
@@ -11,6 +11,7 @@ Required properties :
11 compatible "qcom,rpmcc" should be also included. 11 compatible "qcom,rpmcc" should be also included.
12 12
13 "qcom,rpmcc-msm8916", "qcom,rpmcc" 13 "qcom,rpmcc-msm8916", "qcom,rpmcc"
14 "qcom,rpmcc-msm8974", "qcom,rpmcc"
14 "qcom,rpmcc-apq8064", "qcom,rpmcc" 15 "qcom,rpmcc-apq8064", "qcom,rpmcc"
15 16
16- #clock-cells : shall contain 1 17- #clock-cells : shall contain 1
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
index c46919412953..f4f944d81308 100644
--- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
@@ -42,6 +42,10 @@ Required Properties:
42 Domain bindings in 42 Domain bindings in
43 Documentation/devicetree/bindings/power/power_domain.txt. 43 Documentation/devicetree/bindings/power/power_domain.txt.
44 44
45 - #reset-cells: Must be 1
46 - The single reset specifier cell must be the module number, as defined
47 in the datasheet.
48
45 49
46Examples 50Examples
47-------- 51--------
@@ -55,6 +59,7 @@ Examples
55 clock-names = "extal", "extalr"; 59 clock-names = "extal", "extalr";
56 #clock-cells = <2>; 60 #clock-cells = <2>;
57 #power-domain-cells = <0>; 61 #power-domain-cells = <0>;
62 #reset-cells = <1>;
58 }; 63 };
59 64
60 65
@@ -69,5 +74,6 @@ Examples
69 dmas = <&dmac1 0x13>, <&dmac1 0x12>; 74 dmas = <&dmac1 0x13>, <&dmac1 0x12>;
70 dma-names = "tx", "rx"; 75 dma-names = "tx", "rx";
71 power-domains = <&cpg>; 76 power-domains = <&cpg>;
77 resets = <&cpg 310>;
72 status = "disabled"; 78 status = "disabled";
73 }; 79 };
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt
new file mode 100644
index 000000000000..e71c675ba5da
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt
@@ -0,0 +1,57 @@
1* Rockchip RK3328 Clock and Reset Unit
2
3The RK3328 clock controller generates and supplies clock to various
4controllers within the SoC and also implements a reset controller for SoC
5peripherals.
6
7Required Properties:
8
9- compatible: should be "rockchip,rk3328-cru"
10- reg: physical base address of the controller and length of memory mapped
11 region.
12- #clock-cells: should be 1.
13- #reset-cells: should be 1.
14
15Optional Properties:
16
17- rockchip,grf: phandle to the syscon managing the "general register files"
18 If missing pll rates are not changeable, due to the missing pll lock status.
19
20Each clock is assigned an identifier and client nodes can use this identifier
21to specify the clock which they consume. All available clocks are defined as
22preprocessor macros in the dt-bindings/clock/rk3328-cru.h headers and can be
23used in device tree sources. Similar macros exist for the reset sources in
24these files.
25
26External clocks:
27
28There are several clocks that are generated outside the SoC. It is expected
29that they are defined using standard clock bindings with following
30clock-output-names:
31 - "xin24m" - crystal input - required,
32 - "clkin_i2s" - external I2S clock - optional,
33 - "gmac_clkin" - external GMAC clock - optional
34 - "phy_50m_out" - output clock of the pll in the mac phy
35
36Example: Clock controller node:
37
38 cru: clock-controller@ff440000 {
39 compatible = "rockchip,rk3328-cru";
40 reg = <0x0 0xff440000 0x0 0x1000>;
41 rockchip,grf = <&grf>;
42
43 #clock-cells = <1>;
44 #reset-cells = <1>;
45 };
46
47Example: UART controller node that consumes the clock generated by the clock
48 controller:
49
50 uart0: serial@ff120000 {
51 compatible = "snps,dw-apb-uart";
52 reg = <0xff120000 0x100>;
53 interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
54 reg-shift = <2>;
55 reg-io-width = <4>;
56 clocks = <&cru SCLK_UART0>;
57 };
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt
index 3888dd33fcbd..3bc56fae90ac 100644
--- a/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt
@@ -13,6 +13,12 @@ Required Properties:
13- #clock-cells: should be 1. 13- #clock-cells: should be 1.
14- #reset-cells: should be 1. 14- #reset-cells: should be 1.
15 15
16Optional Properties:
17
18- rockchip,grf: phandle to the syscon managing the "general register files".
19 It is used for GRF muxes, if missing any muxes present in the GRF will not
20 be available.
21
16Each clock is assigned an identifier and client nodes can use this identifier 22Each clock is assigned an identifier and client nodes can use this identifier
17to specify the clock which they consume. All available clocks are defined as 23to specify the clock which they consume. All available clocks are defined as
18preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be 24preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be
diff --git a/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt b/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt
index 8f19d87cbf24..b240121d2ac9 100644
--- a/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt
+++ b/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt
@@ -10,6 +10,7 @@ Required properties:
10- compatible: Should be: 10- compatible: Should be:
11 "st,stm32f42xx-rcc" 11 "st,stm32f42xx-rcc"
12 "st,stm32f469-rcc" 12 "st,stm32f469-rcc"
13 "st,stm32f746-rcc"
13- reg: should be register base and length as documented in the 14- reg: should be register base and length as documented in the
14 datasheet 15 datasheet
15- #reset-cells: 1, see below 16- #reset-cells: 1, see below
@@ -84,6 +85,25 @@ The secondary index is bound with the following magic numbers:
84 12 CLK_I2SQ_PDIV (post divisor of pll i2s q divisor) 85 12 CLK_I2SQ_PDIV (post divisor of pll i2s q divisor)
85 13 CLK_SAIQ_PDIV (post divisor of pll sai q divisor) 86 13 CLK_SAIQ_PDIV (post divisor of pll sai q divisor)
86 87
88 14 CLK_HSI (Internal ocscillator clock)
89 15 CLK_SYSCLK (System Clock)
90 16 CLK_HDMI_CEC (HDMI-CEC clock)
91 17 CLK_SPDIF (SPDIF-Rx clock)
92 18 CLK_USART1 (U(s)arts clocks)
93 19 CLK_USART2
94 20 CLK_USART3
95 21 CLK_UART4
96 22 CLK_UART5
97 23 CLK_USART6
98 24 CLK_UART7
99 25 CLK_UART8
100 26 CLK_I2C1 (I2S clocks)
101 27 CLK_I2C2
102 28 CLK_I2C3
103 29 CLK_I2C4
104 30 CLK_LPTIMER (LPTimer1 clock)
105)
106
87Example: 107Example:
88 108
89 /* Misc clock, FCLK */ 109 /* Misc clock, FCLK */
diff --git a/Documentation/devicetree/bindings/clock/stericsson,abx500.txt b/Documentation/devicetree/bindings/clock/stericsson,abx500.txt
new file mode 100644
index 000000000000..dbaa886b223e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/stericsson,abx500.txt
@@ -0,0 +1,20 @@
1Clock bindings for ST-Ericsson ABx500 clocks
2
3Required properties :
4- compatible : shall contain the following:
5 "stericsson,ab8500-clk"
6- #clock-cells should be <1>
7
8The ABx500 clocks need to be placed as a subnode of an AB8500
9device node, see mfd/ab8500.txt
10
11All available clocks are defined as preprocessor macros in
12dt-bindings/clock/ste-ab8500.h header and can be used in device
13tree sources.
14
15Example:
16
17clock-controller {
18 compatible = "stericsson,ab8500-clk";
19 #clock-cells = <1>;
20};
diff --git a/Documentation/devicetree/bindings/clock/sun9i-de.txt b/Documentation/devicetree/bindings/clock/sun9i-de.txt
new file mode 100644
index 000000000000..fb18f327b97a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sun9i-de.txt
@@ -0,0 +1,28 @@
1Allwinner A80 Display Engine Clock Control Binding
2--------------------------------------------------
3
4Required properties :
5- compatible: must contain one of the following compatibles:
6 - "allwinner,sun9i-a80-de-clks"
7
8- reg: Must contain the registers base address and length
9- clocks: phandle to the clocks feeding the display engine subsystem.
10 Three are needed:
11 - "mod": the display engine module clock
12 - "dram": the DRAM bus clock for the system
13 - "bus": the bus clock for the whole display engine subsystem
14- clock-names: Must contain the clock names described just above
15- resets: phandle to the reset control for the display engine subsystem.
16- #clock-cells : must contain 1
17- #reset-cells : must contain 1
18
19Example:
20de_clocks: clock@3000000 {
21 compatible = "allwinner,sun9i-a80-de-clks";
22 reg = <0x03000000 0x30>;
23 clocks = <&ccu CLK_DE>, <&ccu CLK_SDRAM>, <&ccu CLK_BUS_DE>;
24 clock-names = "mod", "dram", "bus";
25 resets = <&ccu RST_BUS_DE>;
26 #clock-cells = <1>;
27 #reset-cells = <1>;
28};
diff --git a/Documentation/devicetree/bindings/clock/sun9i-usb.txt b/Documentation/devicetree/bindings/clock/sun9i-usb.txt
new file mode 100644
index 000000000000..3564bd4f2a20
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sun9i-usb.txt
@@ -0,0 +1,24 @@
1Allwinner A80 USB Clock Control Binding
2---------------------------------------
3
4Required properties :
5- compatible: must contain one of the following compatibles:
6 - "allwinner,sun9i-a80-usb-clocks"
7
8- reg: Must contain the registers base address and length
9- clocks: phandle to the clocks feeding the USB subsystem. Two are needed:
10 - "bus": the bus clock for the whole USB subsystem
11 - "hosc": the high frequency oscillator (usually at 24MHz)
12- clock-names: Must contain the clock names described just above
13- #clock-cells : must contain 1
14- #reset-cells : must contain 1
15
16Example:
17usb_clocks: clock@a08000 {
18 compatible = "allwinner,sun9i-a80-usb-clks";
19 reg = <0x00a08000 0x8>;
20 clocks = <&ccu CLK_BUS_USB>, <&osc24M>;
21 clock-names = "bus", "hosc";
22 #clock-cells = <1>;
23 #reset-cells = <1>;
24};
diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
index 74d44a4273f2..bae5668cf427 100644
--- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
@@ -7,6 +7,8 @@ Required properties :
7 - "allwinner,sun8i-a23-ccu" 7 - "allwinner,sun8i-a23-ccu"
8 - "allwinner,sun8i-a33-ccu" 8 - "allwinner,sun8i-a33-ccu"
9 - "allwinner,sun8i-h3-ccu" 9 - "allwinner,sun8i-h3-ccu"
10 - "allwinner,sun8i-v3s-ccu"
11 - "allwinner,sun9i-a80-ccu"
10 - "allwinner,sun50i-a64-ccu" 12 - "allwinner,sun50i-a64-ccu"
11 13
12- reg: Must contain the registers base address and length 14- reg: Must contain the registers base address and length
diff --git a/Documentation/devicetree/bindings/clock/ti,cdce925.txt b/Documentation/devicetree/bindings/clock/ti,cdce925.txt
index 4c7669ad681b..0d01f2d5cc36 100644
--- a/Documentation/devicetree/bindings/clock/ti,cdce925.txt
+++ b/Documentation/devicetree/bindings/clock/ti,cdce925.txt
@@ -1,15 +1,22 @@
1Binding for TO CDCE925 programmable I2C clock synthesizers. 1Binding for TI CDCE913/925/937/949 programmable I2C clock synthesizers.
2 2
3Reference 3Reference
4This binding uses the common clock binding[1]. 4This binding uses the common clock binding[1].
5 5
6[1] Documentation/devicetree/bindings/clock/clock-bindings.txt 6[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
7[2] http://www.ti.com/product/cdce925 7[2] http://www.ti.com/product/cdce913
8[3] http://www.ti.com/product/cdce925
9[4] http://www.ti.com/product/cdce937
10[5] http://www.ti.com/product/cdce949
8 11
9The driver provides clock sources for each output Y1 through Y5. 12The driver provides clock sources for each output Y1 through Y5.
10 13
11Required properties: 14Required properties:
12 - compatible: Shall be "ti,cdce925" 15 - compatible: Shall be one of the following:
16 - "ti,cdce913": 1-PLL, 3 Outputs
17 - "ti,cdce925": 2-PLL, 5 Outputs
18 - "ti,cdce937": 3-PLL, 7 Outputs
19 - "ti,cdce949": 4-PLL, 9 Outputs
13 - reg: I2C device address. 20 - reg: I2C device address.
14 - clocks: Points to a fixed parent clock that provides the input frequency. 21 - clocks: Points to a fixed parent clock that provides the input frequency.
15 - #clock-cells: From common clock bindings: Shall be 1. 22 - #clock-cells: From common clock bindings: Shall be 1.
@@ -18,7 +25,7 @@ Optional properties:
18 - xtal-load-pf: Crystal load-capacitor value to fine-tune performance on a 25 - xtal-load-pf: Crystal load-capacitor value to fine-tune performance on a
19 board, or to compensate for external influences. 26 board, or to compensate for external influences.
20 27
21For both PLL1 and PLL2 an optional child node can be used to specify spread 28For all PLL1, PLL2, ... an optional child node can be used to specify spread
22spectrum clocking parameters for a board. 29spectrum clocking parameters for a board.
23 - spread-spectrum: SSC mode as defined in the data sheet. 30 - spread-spectrum: SSC mode as defined in the data sheet.
24 - spread-spectrum-center: Use "centered" mode instead of "max" mode. When 31 - spread-spectrum-center: Use "centered" mode instead of "max" mode. When
diff --git a/Documentation/devicetree/bindings/clock/zx296718-clk.txt b/Documentation/devicetree/bindings/clock/zx296718-clk.txt
index 8c18b7b237bf..4ad703808407 100644
--- a/Documentation/devicetree/bindings/clock/zx296718-clk.txt
+++ b/Documentation/devicetree/bindings/clock/zx296718-clk.txt
@@ -13,6 +13,9 @@ Required properties:
13 "zte,zx296718-lsp1crm": 13 "zte,zx296718-lsp1crm":
14 zx296718 device level clock selection and gating 14 zx296718 device level clock selection and gating
15 15
16 "zte,zx296718-audiocrm":
17 zx296718 audio clock selection, divider and gating
18
16- reg: Address and length of the register set 19- reg: Address and length of the register set
17 20
18The clock consumer should specify the desired clock by having the clock 21The clock consumer should specify the desired clock by having the clock
diff --git a/MAINTAINERS b/MAINTAINERS
index 8f05facab3b5..dedc66c265c9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6270,6 +6270,11 @@ S: Maintained
6270F: drivers/mfd/lpc_ich.c 6270F: drivers/mfd/lpc_ich.c
6271F: drivers/gpio/gpio-ich.c 6271F: drivers/gpio/gpio-ich.c
6272 6272
6273IDT VersaClock 5 CLOCK DRIVER
6274M: Marek Vasut <marek.vasut@gmail.com>
6275S: Maintained
6276F: drivers/clk/clk-versaclock5.c
6277
6273IDE SUBSYSTEM 6278IDE SUBSYSTEM
6274M: "David S. Miller" <davem@davemloft.net> 6279M: "David S. Miller" <davem@davemloft.net>
6275L: linux-ide@vger.kernel.org 6280L: linux-ide@vger.kernel.org
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 62b3ffe62df2..24b0f5f556f8 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -65,8 +65,9 @@
65 compatible = "allwinner,simple-framebuffer", 65 compatible = "allwinner,simple-framebuffer",
66 "simple-framebuffer"; 66 "simple-framebuffer";
67 allwinner,pipeline = "de_be0-lcd0-hdmi"; 67 allwinner,pipeline = "de_be0-lcd0-hdmi";
68 clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>, 68 clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_HDMI>,
69 <&ahb_gates 43>, <&ahb_gates 44>; 69 <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DRAM_DE_BE>,
70 <&ccu CLK_DE_BE>, <&ccu CLK_HDMI>;
70 status = "disabled"; 71 status = "disabled";
71 }; 72 };
72 73
@@ -74,8 +75,8 @@
74 compatible = "allwinner,simple-framebuffer", 75 compatible = "allwinner,simple-framebuffer",
75 "simple-framebuffer"; 76 "simple-framebuffer";
76 allwinner,pipeline = "de_be0-lcd0"; 77 allwinner,pipeline = "de_be0-lcd0";
77 clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>, 78 clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
78 <&ahb_gates 44>; 79 <&ccu CLK_TCON_CH0>, <&ccu CLK_DRAM_DE_BE>;
79 status = "disabled"; 80 status = "disabled";
80 }; 81 };
81 82
@@ -83,77 +84,19 @@
83 compatible = "allwinner,simple-framebuffer", 84 compatible = "allwinner,simple-framebuffer",
84 "simple-framebuffer"; 85 "simple-framebuffer";
85 allwinner,pipeline = "de_be0-lcd0-tve0"; 86 allwinner,pipeline = "de_be0-lcd0-tve0";
86 clocks = <&pll3>, <&pll5 1>, <&ahb_gates 34>, 87 clocks = <&ccu CLK_AHB_TVE>, <&ccu CLK_AHB_LCD>,
87 <&ahb_gates 36>, <&ahb_gates 44>; 88 <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
89 <&ccu CLK_TCON_CH1>, <&ccu CLK_DRAM_DE_BE>;
88 status = "disabled"; 90 status = "disabled";
89 }; 91 };
90 }; 92 };
91 93
92 clocks {
93 ahb_gates: clk@01c20060 {
94 #clock-cells = <1>;
95 compatible = "allwinner,sun5i-a10s-ahb-gates-clk";
96 reg = <0x01c20060 0x8>;
97 clocks = <&ahb>;
98 clock-indices = <0>, <1>,
99 <2>, <5>, <6>,
100 <7>, <8>, <9>,
101 <10>, <13>,
102 <14>, <17>, <18>,
103 <20>, <21>, <22>,
104 <26>, <28>, <32>,
105 <34>, <36>, <40>,
106 <43>, <44>,
107 <46>, <51>,
108 <52>;
109 clock-output-names = "ahb_usbotg", "ahb_ehci",
110 "ahb_ohci", "ahb_ss", "ahb_dma",
111 "ahb_bist", "ahb_mmc0", "ahb_mmc1",
112 "ahb_mmc2", "ahb_nand",
113 "ahb_sdram", "ahb_emac", "ahb_ts",
114 "ahb_spi0", "ahb_spi1", "ahb_spi2",
115 "ahb_gps", "ahb_stimer", "ahb_ve",
116 "ahb_tve", "ahb_lcd", "ahb_csi",
117 "ahb_hdmi", "ahb_de_be",
118 "ahb_de_fe", "ahb_iep",
119 "ahb_mali400";
120 };
121
122 apb0_gates: clk@01c20068 {
123 #clock-cells = <1>;
124 compatible = "allwinner,sun5i-a10s-apb0-gates-clk";
125 reg = <0x01c20068 0x4>;
126 clocks = <&apb0>;
127 clock-indices = <0>, <3>,
128 <5>, <6>,
129 <10>;
130 clock-output-names = "apb0_codec", "apb0_iis",
131 "apb0_pio", "apb0_ir",
132 "apb0_keypad";
133 };
134
135 apb1_gates: clk@01c2006c {
136 #clock-cells = <1>;
137 compatible = "allwinner,sun5i-a10s-apb1-gates-clk";
138 reg = <0x01c2006c 0x4>;
139 clocks = <&apb1>;
140 clock-indices = <0>, <1>,
141 <2>, <16>,
142 <17>, <18>,
143 <19>;
144 clock-output-names = "apb1_i2c0", "apb1_i2c1",
145 "apb1_i2c2", "apb1_uart0",
146 "apb1_uart1", "apb1_uart2",
147 "apb1_uart3";
148 };
149 };
150
151 soc@01c00000 { 94 soc@01c00000 {
152 emac: ethernet@01c0b000 { 95 emac: ethernet@01c0b000 {
153 compatible = "allwinner,sun4i-a10-emac"; 96 compatible = "allwinner,sun4i-a10-emac";
154 reg = <0x01c0b000 0x1000>; 97 reg = <0x01c0b000 0x1000>;
155 interrupts = <55>; 98 interrupts = <55>;
156 clocks = <&ahb_gates 17>; 99 clocks = <&ccu CLK_AHB_EMAC>;
157 allwinner,sram = <&emac_sram 1>; 100 allwinner,sram = <&emac_sram 1>;
158 status = "disabled"; 101 status = "disabled";
159 }; 102 };
@@ -169,7 +112,7 @@
169 pwm: pwm@01c20e00 { 112 pwm: pwm@01c20e00 {
170 compatible = "allwinner,sun5i-a10s-pwm"; 113 compatible = "allwinner,sun5i-a10s-pwm";
171 reg = <0x01c20e00 0xc>; 114 reg = <0x01c20e00 0xc>;
172 clocks = <&osc24M>; 115 clocks = <&ccu CLK_HOSC>;
173 #pwm-cells = <3>; 116 #pwm-cells = <3>;
174 status = "disabled"; 117 status = "disabled";
175 }; 118 };
@@ -180,7 +123,7 @@
180 interrupts = <1>; 123 interrupts = <1>;
181 reg-shift = <2>; 124 reg-shift = <2>;
182 reg-io-width = <4>; 125 reg-io-width = <4>;
183 clocks = <&apb1_gates 16>; 126 clocks = <&ccu CLK_APB1_UART0>;
184 status = "disabled"; 127 status = "disabled";
185 }; 128 };
186 129
@@ -190,12 +133,16 @@
190 interrupts = <3>; 133 interrupts = <3>;
191 reg-shift = <2>; 134 reg-shift = <2>;
192 reg-io-width = <4>; 135 reg-io-width = <4>;
193 clocks = <&apb1_gates 18>; 136 clocks = <&ccu CLK_APB1_UART2>;
194 status = "disabled"; 137 status = "disabled";
195 }; 138 };
196 }; 139 };
197}; 140};
198 141
142&ccu {
143 compatible = "allwinner,sun5i-a10s-ccu";
144};
145
199&pio { 146&pio {
200 compatible = "allwinner,sun5i-a10s-pinctrl"; 147 compatible = "allwinner,sun5i-a10s-pinctrl";
201 148
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 4131ab44558b..fb2ddb9a04c9 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -61,8 +61,8 @@
61 compatible = "allwinner,simple-framebuffer", 61 compatible = "allwinner,simple-framebuffer",
62 "simple-framebuffer"; 62 "simple-framebuffer";
63 allwinner,pipeline = "de_be0-lcd0"; 63 allwinner,pipeline = "de_be0-lcd0";
64 clocks = <&ahb_gates 36>, <&ahb_gates 44>, <&de_be_clk>, 64 clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
65 <&tcon_ch0_clk>, <&dram_gates 26>; 65 <&ccu CLK_TCON_CH0>, <&ccu CLK_DRAM_DE_BE>;
66 status = "disabled"; 66 status = "disabled";
67 }; 67 };
68 }; 68 };
@@ -99,114 +99,6 @@
99 }; 99 };
100 }; 100 };
101 101
102 clocks {
103 ahb_gates: clk@01c20060 {
104 #clock-cells = <1>;
105 compatible = "allwinner,sun5i-a13-ahb-gates-clk";
106 reg = <0x01c20060 0x8>;
107 clocks = <&ahb>;
108 clock-indices = <0>, <1>,
109 <2>, <5>, <6>,
110 <7>, <8>, <9>,
111 <10>, <13>,
112 <14>, <20>,
113 <21>, <22>,
114 <28>, <32>, <34>,
115 <36>, <40>, <44>,
116 <46>, <51>,
117 <52>;
118 clock-output-names = "ahb_usbotg", "ahb_ehci",
119 "ahb_ohci", "ahb_ss", "ahb_dma",
120 "ahb_bist", "ahb_mmc0", "ahb_mmc1",
121 "ahb_mmc2", "ahb_nand",
122 "ahb_sdram", "ahb_spi0",
123 "ahb_spi1", "ahb_spi2",
124 "ahb_stimer", "ahb_ve", "ahb_tve",
125 "ahb_lcd", "ahb_csi", "ahb_de_be",
126 "ahb_de_fe", "ahb_iep",
127 "ahb_mali400";
128 };
129
130 apb0_gates: clk@01c20068 {
131 #clock-cells = <1>;
132 compatible = "allwinner,sun5i-a13-apb0-gates-clk";
133 reg = <0x01c20068 0x4>;
134 clocks = <&apb0>;
135 clock-indices = <0>, <5>,
136 <6>;
137 clock-output-names = "apb0_codec", "apb0_pio",
138 "apb0_ir";
139 };
140
141 apb1_gates: clk@01c2006c {
142 #clock-cells = <1>;
143 compatible = "allwinner,sun5i-a13-apb1-gates-clk";
144 reg = <0x01c2006c 0x4>;
145 clocks = <&apb1>;
146 clock-indices = <0>, <1>,
147 <2>, <17>,
148 <19>;
149 clock-output-names = "apb1_i2c0", "apb1_i2c1",
150 "apb1_i2c2", "apb1_uart1",
151 "apb1_uart3";
152 };
153
154 dram_gates: clk@01c20100 {
155 #clock-cells = <1>;
156 compatible = "allwinner,sun5i-a13-dram-gates-clk",
157 "allwinner,sun4i-a10-gates-clk";
158 reg = <0x01c20100 0x4>;
159 clocks = <&pll5 0>;
160 clock-indices = <0>,
161 <1>,
162 <25>,
163 <26>,
164 <29>,
165 <31>;
166 clock-output-names = "dram_ve",
167 "dram_csi",
168 "dram_de_fe",
169 "dram_de_be",
170 "dram_ace",
171 "dram_iep";
172 };
173
174 de_be_clk: clk@01c20104 {
175 #clock-cells = <0>;
176 #reset-cells = <0>;
177 compatible = "allwinner,sun4i-a10-display-clk";
178 reg = <0x01c20104 0x4>;
179 clocks = <&pll3>, <&pll7>, <&pll5 1>;
180 clock-output-names = "de-be";
181 };
182
183 de_fe_clk: clk@01c2010c {
184 #clock-cells = <0>;
185 #reset-cells = <0>;
186 compatible = "allwinner,sun4i-a10-display-clk";
187 reg = <0x01c2010c 0x4>;
188 clocks = <&pll3>, <&pll7>, <&pll5 1>;
189 clock-output-names = "de-fe";
190 };
191
192 tcon_ch0_clk: clk@01c20118 {
193 #clock-cells = <0>;
194 #reset-cells = <1>;
195 compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
196 reg = <0x01c20118 0x4>;
197 clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
198 clock-output-names = "tcon-ch0-sclk";
199 };
200
201 tcon_ch1_clk: clk@01c2012c {
202 #clock-cells = <0>;
203 compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
204 reg = <0x01c2012c 0x4>;
205 clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
206 clock-output-names = "tcon-ch1-sclk";
207 };
208 };
209
210 display-engine { 102 display-engine {
211 compatible = "allwinner,sun5i-a13-display-engine"; 103 compatible = "allwinner,sun5i-a13-display-engine";
212 allwinner,pipelines = <&fe0>; 104 allwinner,pipelines = <&fe0>;
@@ -217,11 +109,11 @@
217 compatible = "allwinner,sun5i-a13-tcon"; 109 compatible = "allwinner,sun5i-a13-tcon";
218 reg = <0x01c0c000 0x1000>; 110 reg = <0x01c0c000 0x1000>;
219 interrupts = <44>; 111 interrupts = <44>;
220 resets = <&tcon_ch0_clk 1>; 112 resets = <&ccu RST_LCD>;
221 reset-names = "lcd"; 113 reset-names = "lcd";
222 clocks = <&ahb_gates 36>, 114 clocks = <&ccu CLK_AHB_LCD>,
223 <&tcon_ch0_clk>, 115 <&ccu CLK_TCON_CH0>,
224 <&tcon_ch1_clk>; 116 <&ccu CLK_TCON_CH1>;
225 clock-names = "ahb", 117 clock-names = "ahb",
226 "tcon-ch0", 118 "tcon-ch0",
227 "tcon-ch1"; 119 "tcon-ch1";
@@ -254,7 +146,7 @@
254 pwm: pwm@01c20e00 { 146 pwm: pwm@01c20e00 {
255 compatible = "allwinner,sun5i-a13-pwm"; 147 compatible = "allwinner,sun5i-a13-pwm";
256 reg = <0x01c20e00 0xc>; 148 reg = <0x01c20e00 0xc>;
257 clocks = <&osc24M>; 149 clocks = <&ccu CLK_HOSC>;
258 #pwm-cells = <3>; 150 #pwm-cells = <3>;
259 status = "disabled"; 151 status = "disabled";
260 }; 152 };
@@ -263,11 +155,11 @@
263 compatible = "allwinner,sun5i-a13-display-frontend"; 155 compatible = "allwinner,sun5i-a13-display-frontend";
264 reg = <0x01e00000 0x20000>; 156 reg = <0x01e00000 0x20000>;
265 interrupts = <47>; 157 interrupts = <47>;
266 clocks = <&ahb_gates 46>, <&de_fe_clk>, 158 clocks = <&ccu CLK_DE_FE>, <&ccu CLK_DE_FE>,
267 <&dram_gates 25>; 159 <&ccu CLK_DRAM_DE_FE>;
268 clock-names = "ahb", "mod", 160 clock-names = "ahb", "mod",
269 "ram"; 161 "ram";
270 resets = <&de_fe_clk>; 162 resets = <&ccu RST_DE_FE>;
271 status = "disabled"; 163 status = "disabled";
272 164
273 ports { 165 ports {
@@ -290,14 +182,14 @@
290 be0: display-backend@01e60000 { 182 be0: display-backend@01e60000 {
291 compatible = "allwinner,sun5i-a13-display-backend"; 183 compatible = "allwinner,sun5i-a13-display-backend";
292 reg = <0x01e60000 0x10000>; 184 reg = <0x01e60000 0x10000>;
293 clocks = <&ahb_gates 44>, <&de_be_clk>, 185 clocks = <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
294 <&dram_gates 26>; 186 <&ccu CLK_DRAM_DE_BE>;
295 clock-names = "ahb", "mod", 187 clock-names = "ahb", "mod",
296 "ram"; 188 "ram";
297 resets = <&de_be_clk>; 189 resets = <&ccu RST_DE_BE>;
298 status = "disabled"; 190 status = "disabled";
299 191
300 assigned-clocks = <&de_be_clk>; 192 assigned-clocks = <&ccu CLK_DE_BE>;
301 assigned-clock-rates = <300000000>; 193 assigned-clock-rates = <300000000>;
302 194
303 ports { 195 ports {
@@ -330,6 +222,10 @@
330 }; 222 };
331}; 223};
332 224
225&ccu {
226 compatible = "allwinner,sun5i-a13-ccu";
227};
228
333&cpu0 { 229&cpu0 {
334 clock-latency = <244144>; /* 8 32k periods */ 230 clock-latency = <244144>; /* 8 32k periods */
335 operating-points = < 231 operating-points = <
diff --git a/arch/arm/boot/dts/sun5i-gr8.dtsi b/arch/arm/boot/dts/sun5i-gr8.dtsi
index f83ae3fc6329..cb9b2aaf7297 100644
--- a/arch/arm/boot/dts/sun5i-gr8.dtsi
+++ b/arch/arm/boot/dts/sun5i-gr8.dtsi
@@ -42,9 +42,10 @@
42 * OTHER DEALINGS IN THE SOFTWARE. 42 * OTHER DEALINGS IN THE SOFTWARE.
43 */ 43 */
44 44
45#include <dt-bindings/clock/sun4i-a10-pll2.h> 45#include <dt-bindings/clock/sun5i-ccu.h>
46#include <dt-bindings/dma/sun4i-a10.h> 46#include <dt-bindings/dma/sun4i-a10.h>
47#include <dt-bindings/pinctrl/sun4i-a10.h> 47#include <dt-bindings/pinctrl/sun4i-a10.h>
48#include <dt-bindings/reset/sun5i-ccu.h>
48 49
49/ { 50/ {
50 interrupt-parent = <&intc>; 51 interrupt-parent = <&intc>;
@@ -59,7 +60,7 @@
59 device_type = "cpu"; 60 device_type = "cpu";
60 compatible = "arm,cortex-a8"; 61 compatible = "arm,cortex-a8";
61 reg = <0x0>; 62 reg = <0x0>;
62 clocks = <&cpu>; 63 clocks = <&ccu CLK_CPU>;
63 }; 64 };
64 }; 65 };
65 66
@@ -68,419 +69,19 @@
68 #size-cells = <1>; 69 #size-cells = <1>;
69 ranges; 70 ranges;
70 71
71 /*
72 * This is a dummy clock, to be used as placeholder on
73 * other mux clocks when a specific parent clock is not
74 * yet implemented. It should be dropped when the driver
75 * is complete.
76 */
77 dummy: dummy {
78 #clock-cells = <0>;
79 compatible = "fixed-clock";
80 clock-frequency = <0>;
81 };
82
83 osc24M: clk@01c20050 { 72 osc24M: clk@01c20050 {
84 #clock-cells = <0>; 73 #clock-cells = <0>;
85 compatible = "allwinner,sun4i-a10-osc-clk"; 74 compatible = "fixed-clock";
86 reg = <0x01c20050 0x4>;
87 clock-frequency = <24000000>; 75 clock-frequency = <24000000>;
88 clock-output-names = "osc24M"; 76 clock-output-names = "osc24M";
89 }; 77 };
90 78
91 osc3M: osc3M-clk {
92 compatible = "fixed-factor-clock";
93 #clock-cells = <0>;
94 clock-div = <8>;
95 clock-mult = <1>;
96 clocks = <&osc24M>;
97 clock-output-names = "osc3M";
98 };
99
100 osc32k: clk@0 { 79 osc32k: clk@0 {
101 #clock-cells = <0>; 80 #clock-cells = <0>;
102 compatible = "fixed-clock"; 81 compatible = "fixed-clock";
103 clock-frequency = <32768>; 82 clock-frequency = <32768>;
104 clock-output-names = "osc32k"; 83 clock-output-names = "osc32k";
105 }; 84 };
106
107 pll1: clk@01c20000 {
108 #clock-cells = <0>;
109 compatible = "allwinner,sun4i-a10-pll1-clk";
110 reg = <0x01c20000 0x4>;
111 clocks = <&osc24M>;
112 clock-output-names = "pll1";
113 };
114
115 pll2: clk@01c20008 {
116 #clock-cells = <1>;
117 compatible = "allwinner,sun5i-a13-pll2-clk";
118 reg = <0x01c20008 0x8>;
119 clocks = <&osc24M>;
120 clock-output-names = "pll2-1x", "pll2-2x",
121 "pll2-4x", "pll2-8x";
122 };
123
124 pll3: clk@01c20010 {
125 #clock-cells = <0>;
126 compatible = "allwinner,sun4i-a10-pll3-clk";
127 reg = <0x01c20010 0x4>;
128 clocks = <&osc3M>;
129 clock-output-names = "pll3";
130 };
131
132 pll3x2: pll3x2-clk {
133 compatible = "allwinner,sun4i-a10-pll3-2x-clk";
134 #clock-cells = <0>;
135 clock-div = <1>;
136 clock-mult = <2>;
137 clocks = <&pll3>;
138 clock-output-names = "pll3-2x";
139 };
140
141 pll4: clk@01c20018 {
142 #clock-cells = <0>;
143 compatible = "allwinner,sun4i-a10-pll1-clk";
144 reg = <0x01c20018 0x4>;
145 clocks = <&osc24M>;
146 clock-output-names = "pll4";
147 };
148
149 pll5: clk@01c20020 {
150 #clock-cells = <1>;
151 compatible = "allwinner,sun4i-a10-pll5-clk";
152 reg = <0x01c20020 0x4>;
153 clocks = <&osc24M>;
154 clock-output-names = "pll5_ddr", "pll5_other";
155 };
156
157 pll6: clk@01c20028 {
158 #clock-cells = <1>;
159 compatible = "allwinner,sun4i-a10-pll6-clk";
160 reg = <0x01c20028 0x4>;
161 clocks = <&osc24M>;
162 clock-output-names = "pll6_sata", "pll6_other", "pll6";
163 };
164
165 pll7: clk@01c20030 {
166 #clock-cells = <0>;
167 compatible = "allwinner,sun4i-a10-pll3-clk";
168 reg = <0x01c20030 0x4>;
169 clocks = <&osc3M>;
170 clock-output-names = "pll7";
171 };
172
173 pll7x2: pll7x2-clk {
174 compatible = "allwinner,sun4i-a10-pll3-2x-clk";
175 #clock-cells = <0>;
176 clock-div = <1>;
177 clock-mult = <2>;
178 clocks = <&pll7>;
179 clock-output-names = "pll7-2x";
180 };
181
182 /* dummy is 200M */
183 cpu: cpu@01c20054 {
184 #clock-cells = <0>;
185 compatible = "allwinner,sun4i-a10-cpu-clk";
186 reg = <0x01c20054 0x4>;
187 clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
188 clock-output-names = "cpu";
189 };
190
191 axi: axi@01c20054 {
192 #clock-cells = <0>;
193 compatible = "allwinner,sun4i-a10-axi-clk";
194 reg = <0x01c20054 0x4>;
195 clocks = <&cpu>;
196 clock-output-names = "axi";
197 };
198
199 ahb: ahb@01c20054 {
200 #clock-cells = <0>;
201 compatible = "allwinner,sun5i-a13-ahb-clk";
202 reg = <0x01c20054 0x4>;
203 clocks = <&axi>, <&cpu>, <&pll6 1>;
204 clock-output-names = "ahb";
205 /*
206 * Use PLL6 as parent, instead of CPU/AXI
207 * which has rate changes due to cpufreq
208 */
209 assigned-clocks = <&ahb>;
210 assigned-clock-parents = <&pll6 1>;
211 };
212
213 apb0: apb0@01c20054 {
214 #clock-cells = <0>;
215 compatible = "allwinner,sun4i-a10-apb0-clk";
216 reg = <0x01c20054 0x4>;
217 clocks = <&ahb>;
218 clock-output-names = "apb0";
219 };
220
221 apb1: clk@01c20058 {
222 #clock-cells = <0>;
223 compatible = "allwinner,sun4i-a10-apb1-clk";
224 reg = <0x01c20058 0x4>;
225 clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
226 clock-output-names = "apb1";
227 };
228
229 axi_gates: clk@01c2005c {
230 #clock-cells = <1>;
231 compatible = "allwinner,sun4i-a10-gates-clk";
232 reg = <0x01c2005c 0x4>;
233 clocks = <&axi>;
234 clock-indices = <0>;
235 clock-output-names = "axi_dram";
236 };
237
238 ahb_gates: clk@01c20060 {
239 #clock-cells = <1>;
240 compatible = "allwinner,sun5i-a13-ahb-gates-clk";
241 reg = <0x01c20060 0x8>;
242 clocks = <&ahb>;
243 clock-indices = <0>, <1>,
244 <2>, <5>, <6>,
245 <7>, <8>, <9>,
246 <10>, <13>,
247 <14>, <17>, <20>,
248 <21>, <22>,
249 <28>, <32>, <34>,
250 <36>, <40>, <44>,
251 <46>, <51>,
252 <52>;
253 clock-output-names = "ahb_usbotg", "ahb_ehci",
254 "ahb_ohci", "ahb_ss", "ahb_dma",
255 "ahb_bist", "ahb_mmc0", "ahb_mmc1",
256 "ahb_mmc2", "ahb_nand",
257 "ahb_sdram", "ahb_emac", "ahb_spi0",
258 "ahb_spi1", "ahb_spi2",
259 "ahb_hstimer", "ahb_ve", "ahb_tve",
260 "ahb_lcd", "ahb_csi", "ahb_de_be",
261 "ahb_de_fe", "ahb_iep",
262 "ahb_mali400";
263 };
264
265 apb0_gates: clk@01c20068 {
266 #clock-cells = <1>;
267 compatible = "allwinner,sun4i-a10-gates-clk";
268 reg = <0x01c20068 0x4>;
269 clocks = <&apb0>;
270 clock-indices = <0>, <3>,
271 <5>, <6>;
272 clock-output-names = "apb0_codec", "apb0_i2s0",
273 "apb0_pio", "apb0_ir";
274 };
275
276 apb1_gates: clk@01c2006c {
277 #clock-cells = <1>;
278 compatible = "allwinner,sun4i-a10-gates-clk";
279 reg = <0x01c2006c 0x4>;
280 clocks = <&apb1>;
281 clock-indices = <0>, <1>,
282 <2>, <17>,
283 <18>, <19>;
284 clock-output-names = "apb1_i2c0", "apb1_i2c1",
285 "apb1_i2c2", "apb1_uart1",
286 "apb1_uart2", "apb1_uart3";
287 };
288
289 nand_clk: clk@01c20080 {
290 #clock-cells = <0>;
291 compatible = "allwinner,sun4i-a10-mod0-clk";
292 reg = <0x01c20080 0x4>;
293 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
294 clock-output-names = "nand";
295 };
296
297 ms_clk: clk@01c20084 {
298 #clock-cells = <0>;
299 compatible = "allwinner,sun4i-a10-mod0-clk";
300 reg = <0x01c20084 0x4>;
301 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
302 clock-output-names = "ms";
303 };
304
305 mmc0_clk: clk@01c20088 {
306 #clock-cells = <1>;
307 compatible = "allwinner,sun4i-a10-mmc-clk";
308 reg = <0x01c20088 0x4>;
309 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
310 clock-output-names = "mmc0",
311 "mmc0_output",
312 "mmc0_sample";
313 };
314
315 mmc1_clk: clk@01c2008c {
316 #clock-cells = <1>;
317 compatible = "allwinner,sun4i-a10-mmc-clk";
318 reg = <0x01c2008c 0x4>;
319 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
320 clock-output-names = "mmc1",
321 "mmc1_output",
322 "mmc1_sample";
323 };
324
325 mmc2_clk: clk@01c20090 {
326 #clock-cells = <1>;
327 compatible = "allwinner,sun4i-a10-mmc-clk";
328 reg = <0x01c20090 0x4>;
329 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
330 clock-output-names = "mmc2",
331 "mmc2_output",
332 "mmc2_sample";
333 };
334
335 ts_clk: clk@01c20098 {
336 #clock-cells = <0>;
337 compatible = "allwinner,sun4i-a10-mod0-clk";
338 reg = <0x01c20098 0x4>;
339 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
340 clock-output-names = "ts";
341 };
342
343 ss_clk: clk@01c2009c {
344 #clock-cells = <0>;
345 compatible = "allwinner,sun4i-a10-mod0-clk";
346 reg = <0x01c2009c 0x4>;
347 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
348 clock-output-names = "ss";
349 };
350
351 spi0_clk: clk@01c200a0 {
352 #clock-cells = <0>;
353 compatible = "allwinner,sun4i-a10-mod0-clk";
354 reg = <0x01c200a0 0x4>;
355 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
356 clock-output-names = "spi0";
357 };
358
359 spi1_clk: clk@01c200a4 {
360 #clock-cells = <0>;
361 compatible = "allwinner,sun4i-a10-mod0-clk";
362 reg = <0x01c200a4 0x4>;
363 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
364 clock-output-names = "spi1";
365 };
366
367 spi2_clk: clk@01c200a8 {
368 #clock-cells = <0>;
369 compatible = "allwinner,sun4i-a10-mod0-clk";
370 reg = <0x01c200a8 0x4>;
371 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
372 clock-output-names = "spi2";
373 };
374
375 ir0_clk: clk@01c200b0 {
376 #clock-cells = <0>;
377 compatible = "allwinner,sun4i-a10-mod0-clk";
378 reg = <0x01c200b0 0x4>;
379 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
380 clock-output-names = "ir0";
381 };
382
383 i2s0_clk: clk@01c200b8 {
384 #clock-cells = <0>;
385 compatible = "allwinner,sun4i-a10-mod1-clk";
386 reg = <0x01c200b8 0x4>;
387 clocks = <&pll2 SUN4I_A10_PLL2_8X>,
388 <&pll2 SUN4I_A10_PLL2_4X>,
389 <&pll2 SUN4I_A10_PLL2_2X>,
390 <&pll2 SUN4I_A10_PLL2_1X>;
391 clock-output-names = "i2s0";
392 };
393
394 spdif_clk: clk@01c200c0 {
395 #clock-cells = <0>;
396 compatible = "allwinner,sun4i-a10-mod1-clk";
397 reg = <0x01c200c0 0x4>;
398 clocks = <&pll2 SUN4I_A10_PLL2_8X>,
399 <&pll2 SUN4I_A10_PLL2_4X>,
400 <&pll2 SUN4I_A10_PLL2_2X>,
401 <&pll2 SUN4I_A10_PLL2_1X>;
402 clock-output-names = "spdif";
403 };
404
405 usb_clk: clk@01c200cc {
406 #clock-cells = <1>;
407 #reset-cells = <1>;
408 compatible = "allwinner,sun5i-a13-usb-clk";
409 reg = <0x01c200cc 0x4>;
410 clocks = <&pll6 1>;
411 clock-output-names = "usb_ohci0", "usb_phy";
412 };
413
414 dram_gates: clk@01c20100 {
415 #clock-cells = <1>;
416 compatible = "nextthing,gr8-dram-gates-clk",
417 "allwinner,sun4i-a10-gates-clk";
418 reg = <0x01c20100 0x4>;
419 clocks = <&pll5 0>;
420 clock-indices = <0>,
421 <1>,
422 <25>,
423 <26>,
424 <29>,
425 <31>;
426 clock-output-names = "dram_ve",
427 "dram_csi",
428 "dram_de_fe",
429 "dram_de_be",
430 "dram_ace",
431 "dram_iep";
432 };
433
434 de_be_clk: clk@01c20104 {
435 #clock-cells = <0>;
436 #reset-cells = <0>;
437 compatible = "allwinner,sun4i-a10-display-clk";
438 reg = <0x01c20104 0x4>;
439 clocks = <&pll3>, <&pll7>, <&pll5 1>;
440 clock-output-names = "de-be";
441 };
442
443 de_fe_clk: clk@01c2010c {
444 #clock-cells = <0>;
445 #reset-cells = <0>;
446 compatible = "allwinner,sun4i-a10-display-clk";
447 reg = <0x01c2010c 0x4>;
448 clocks = <&pll3>, <&pll7>, <&pll5 1>;
449 clock-output-names = "de-fe";
450 };
451
452 tcon_ch0_clk: clk@01c20118 {
453 #clock-cells = <0>;
454 #reset-cells = <1>;
455 compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
456 reg = <0x01c20118 0x4>;
457 clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
458 clock-output-names = "tcon-ch0-sclk";
459 };
460
461 tcon_ch1_clk: clk@01c2012c {
462 #clock-cells = <0>;
463 compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
464 reg = <0x01c2012c 0x4>;
465 clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
466 clock-output-names = "tcon-ch1-sclk";
467 };
468
469 codec_clk: clk@01c20140 {
470 #clock-cells = <0>;
471 compatible = "allwinner,sun4i-a10-codec-clk";
472 reg = <0x01c20140 0x4>;
473 clocks = <&pll2 SUN4I_A10_PLL2_1X>;
474 clock-output-names = "codec";
475 };
476
477 mbus_clk: clk@01c2015c {
478 #clock-cells = <0>;
479 compatible = "allwinner,sun5i-a13-mbus-clk";
480 reg = <0x01c2015c 0x4>;
481 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
482 clock-output-names = "mbus";
483 };
484 }; 85 };
485 86
486 display-engine { 87 display-engine {
@@ -528,7 +129,7 @@
528 compatible = "allwinner,sun4i-a10-dma"; 129 compatible = "allwinner,sun4i-a10-dma";
529 reg = <0x01c02000 0x1000>; 130 reg = <0x01c02000 0x1000>;
530 interrupts = <27>; 131 interrupts = <27>;
531 clocks = <&ahb_gates 6>; 132 clocks = <&ccu CLK_AHB_DMA>;
532 #dma-cells = <2>; 133 #dma-cells = <2>;
533 }; 134 };
534 135
@@ -536,7 +137,7 @@
536 compatible = "allwinner,sun4i-a10-nand"; 137 compatible = "allwinner,sun4i-a10-nand";
537 reg = <0x01c03000 0x1000>; 138 reg = <0x01c03000 0x1000>;
538 interrupts = <37>; 139 interrupts = <37>;
539 clocks = <&ahb_gates 13>, <&nand_clk>; 140 clocks = <&ccu CLK_AHB_NAND>, <&ccu CLK_NAND>;
540 clock-names = "ahb", "mod"; 141 clock-names = "ahb", "mod";
541 dmas = <&dma SUN4I_DMA_DEDICATED 3>; 142 dmas = <&dma SUN4I_DMA_DEDICATED 3>;
542 dma-names = "rxtx"; 143 dma-names = "rxtx";
@@ -549,7 +150,7 @@
549 compatible = "allwinner,sun4i-a10-spi"; 150 compatible = "allwinner,sun4i-a10-spi";
550 reg = <0x01c05000 0x1000>; 151 reg = <0x01c05000 0x1000>;
551 interrupts = <10>; 152 interrupts = <10>;
552 clocks = <&ahb_gates 20>, <&spi0_clk>; 153 clocks = <&ccu CLK_AHB_SPI0>, <&ccu CLK_SPI0>;
553 clock-names = "ahb", "mod"; 154 clock-names = "ahb", "mod";
554 dmas = <&dma SUN4I_DMA_DEDICATED 27>, 155 dmas = <&dma SUN4I_DMA_DEDICATED 27>,
555 <&dma SUN4I_DMA_DEDICATED 26>; 156 <&dma SUN4I_DMA_DEDICATED 26>;
@@ -563,7 +164,7 @@
563 compatible = "allwinner,sun4i-a10-spi"; 164 compatible = "allwinner,sun4i-a10-spi";
564 reg = <0x01c06000 0x1000>; 165 reg = <0x01c06000 0x1000>;
565 interrupts = <11>; 166 interrupts = <11>;
566 clocks = <&ahb_gates 21>, <&spi1_clk>; 167 clocks = <&ccu CLK_AHB_SPI1>, <&ccu CLK_SPI1>;
567 clock-names = "ahb", "mod"; 168 clock-names = "ahb", "mod";
568 dmas = <&dma SUN4I_DMA_DEDICATED 9>, 169 dmas = <&dma SUN4I_DMA_DEDICATED 9>,
569 <&dma SUN4I_DMA_DEDICATED 8>; 170 <&dma SUN4I_DMA_DEDICATED 8>;
@@ -576,8 +177,8 @@
576 tve0: tv-encoder@01c0a000 { 177 tve0: tv-encoder@01c0a000 {
577 compatible = "allwinner,sun4i-a10-tv-encoder"; 178 compatible = "allwinner,sun4i-a10-tv-encoder";
578 reg = <0x01c0a000 0x1000>; 179 reg = <0x01c0a000 0x1000>;
579 clocks = <&ahb_gates 34>; 180 clocks = <&ccu CLK_AHB_TVE>;
580 resets = <&tcon_ch0_clk 0>; 181 resets = <&ccu RST_TVE>;
581 status = "disabled"; 182 status = "disabled";
582 183
583 port { 184 port {
@@ -595,11 +196,11 @@
595 compatible = "allwinner,sun5i-a13-tcon"; 196 compatible = "allwinner,sun5i-a13-tcon";
596 reg = <0x01c0c000 0x1000>; 197 reg = <0x01c0c000 0x1000>;
597 interrupts = <44>; 198 interrupts = <44>;
598 resets = <&tcon_ch0_clk 1>; 199 resets = <&ccu RST_LCD>;
599 reset-names = "lcd"; 200 reset-names = "lcd";
600 clocks = <&ahb_gates 36>, 201 clocks = <&ccu CLK_AHB_LCD>,
601 <&tcon_ch0_clk>, 202 <&ccu CLK_TCON_CH0>,
602 <&tcon_ch1_clk>; 203 <&ccu CLK_TCON_CH1>;
603 clock-names = "ahb", 204 clock-names = "ahb",
604 "tcon-ch0", 205 "tcon-ch0",
605 "tcon-ch1"; 206 "tcon-ch1";
@@ -637,14 +238,8 @@
637 mmc0: mmc@01c0f000 { 238 mmc0: mmc@01c0f000 {
638 compatible = "allwinner,sun5i-a13-mmc"; 239 compatible = "allwinner,sun5i-a13-mmc";
639 reg = <0x01c0f000 0x1000>; 240 reg = <0x01c0f000 0x1000>;
640 clocks = <&ahb_gates 8>, 241 clocks = <&ccu CLK_AHB_MMC0>, <&ccu CLK_MMC0>;
641 <&mmc0_clk 0>, 242 clock-names = "ahb", "mmc";
642 <&mmc0_clk 1>,
643 <&mmc0_clk 2>;
644 clock-names = "ahb",
645 "mmc",
646 "output",
647 "sample";
648 interrupts = <32>; 243 interrupts = <32>;
649 status = "disabled"; 244 status = "disabled";
650 #address-cells = <1>; 245 #address-cells = <1>;
@@ -654,14 +249,8 @@
654 mmc1: mmc@01c10000 { 249 mmc1: mmc@01c10000 {
655 compatible = "allwinner,sun5i-a13-mmc"; 250 compatible = "allwinner,sun5i-a13-mmc";
656 reg = <0x01c10000 0x1000>; 251 reg = <0x01c10000 0x1000>;
657 clocks = <&ahb_gates 9>, 252 clocks = <&ccu CLK_AHB_MMC1>, <&ccu CLK_MMC1>;
658 <&mmc1_clk 0>, 253 clock-names = "ahb", "mmc";
659 <&mmc1_clk 1>,
660 <&mmc1_clk 2>;
661 clock-names = "ahb",
662 "mmc",
663 "output",
664 "sample";
665 interrupts = <33>; 254 interrupts = <33>;
666 status = "disabled"; 255 status = "disabled";
667 #address-cells = <1>; 256 #address-cells = <1>;
@@ -671,14 +260,8 @@
671 mmc2: mmc@01c11000 { 260 mmc2: mmc@01c11000 {
672 compatible = "allwinner,sun5i-a13-mmc"; 261 compatible = "allwinner,sun5i-a13-mmc";
673 reg = <0x01c11000 0x1000>; 262 reg = <0x01c11000 0x1000>;
674 clocks = <&ahb_gates 10>, 263 clocks = <&ccu CLK_AHB_MMC2>, <&ccu CLK_MMC2>;
675 <&mmc2_clk 0>, 264 clock-names = "ahb", "mmc";
676 <&mmc2_clk 1>,
677 <&mmc2_clk 2>;
678 clock-names = "ahb",
679 "mmc",
680 "output",
681 "sample";
682 interrupts = <34>; 265 interrupts = <34>;
683 status = "disabled"; 266 status = "disabled";
684 #address-cells = <1>; 267 #address-cells = <1>;
@@ -688,7 +271,7 @@
688 usb_otg: usb@01c13000 { 271 usb_otg: usb@01c13000 {
689 compatible = "allwinner,sun4i-a10-musb"; 272 compatible = "allwinner,sun4i-a10-musb";
690 reg = <0x01c13000 0x0400>; 273 reg = <0x01c13000 0x0400>;
691 clocks = <&ahb_gates 0>; 274 clocks = <&ccu CLK_AHB_OTG>;
692 interrupts = <38>; 275 interrupts = <38>;
693 interrupt-names = "mc"; 276 interrupt-names = "mc";
694 phys = <&usbphy 0>; 277 phys = <&usbphy 0>;
@@ -705,9 +288,9 @@
705 compatible = "allwinner,sun5i-a13-usb-phy"; 288 compatible = "allwinner,sun5i-a13-usb-phy";
706 reg = <0x01c13400 0x10 0x01c14800 0x4>; 289 reg = <0x01c13400 0x10 0x01c14800 0x4>;
707 reg-names = "phy_ctrl", "pmu1"; 290 reg-names = "phy_ctrl", "pmu1";
708 clocks = <&usb_clk 8>; 291 clocks = <&ccu CLK_USB_PHY0>;
709 clock-names = "usb_phy"; 292 clock-names = "usb_phy";
710 resets = <&usb_clk 0>, <&usb_clk 1>; 293 resets = <&ccu RST_USB_PHY0>, <&ccu RST_USB_PHY1>;
711 reset-names = "usb0_reset", "usb1_reset"; 294 reset-names = "usb0_reset", "usb1_reset";
712 status = "disabled"; 295 status = "disabled";
713 }; 296 };
@@ -716,7 +299,7 @@
716 compatible = "allwinner,sun5i-a13-ehci", "generic-ehci"; 299 compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
717 reg = <0x01c14000 0x100>; 300 reg = <0x01c14000 0x100>;
718 interrupts = <39>; 301 interrupts = <39>;
719 clocks = <&ahb_gates 1>; 302 clocks = <&ccu CLK_AHB_EHCI>;
720 phys = <&usbphy 1>; 303 phys = <&usbphy 1>;
721 phy-names = "usb"; 304 phy-names = "usb";
722 status = "disabled"; 305 status = "disabled";
@@ -726,7 +309,7 @@
726 compatible = "allwinner,sun5i-a13-ohci", "generic-ohci"; 309 compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
727 reg = <0x01c14400 0x100>; 310 reg = <0x01c14400 0x100>;
728 interrupts = <40>; 311 interrupts = <40>;
729 clocks = <&usb_clk 6>, <&ahb_gates 2>; 312 clocks = <&ccu CLK_USB_OHCI>, <&ccu CLK_AHB_OHCI>;
730 phys = <&usbphy 1>; 313 phys = <&usbphy 1>;
731 phy-names = "usb"; 314 phy-names = "usb";
732 status = "disabled"; 315 status = "disabled";
@@ -736,7 +319,7 @@
736 compatible = "allwinner,sun4i-a10-spi"; 319 compatible = "allwinner,sun4i-a10-spi";
737 reg = <0x01c17000 0x1000>; 320 reg = <0x01c17000 0x1000>;
738 interrupts = <12>; 321 interrupts = <12>;
739 clocks = <&ahb_gates 22>, <&spi2_clk>; 322 clocks = <&ccu CLK_AHB_SPI2>, <&ccu CLK_SPI2>;
740 clock-names = "ahb", "mod"; 323 clock-names = "ahb", "mod";
741 dmas = <&dma SUN4I_DMA_DEDICATED 29>, 324 dmas = <&dma SUN4I_DMA_DEDICATED 29>,
742 <&dma SUN4I_DMA_DEDICATED 28>; 325 <&dma SUN4I_DMA_DEDICATED 28>;
@@ -746,6 +329,15 @@
746 #size-cells = <0>; 329 #size-cells = <0>;
747 }; 330 };
748 331
332 ccu: clock@01c20000 {
333 compatible = "nextthing,gr8-ccu";
334 reg = <0x01c20000 0x400>;
335 clocks = <&osc24M>, <&osc32k>;
336 clock-names = "hosc", "losc";
337 #clock-cells = <1>;
338 #reset-cells = <1>;
339 };
340
749 intc: interrupt-controller@01c20400 { 341 intc: interrupt-controller@01c20400 {
750 compatible = "allwinner,sun4i-a10-ic"; 342 compatible = "allwinner,sun4i-a10-ic";
751 reg = <0x01c20400 0x400>; 343 reg = <0x01c20400 0x400>;
@@ -757,7 +349,7 @@
757 compatible = "nextthing,gr8-pinctrl"; 349 compatible = "nextthing,gr8-pinctrl";
758 reg = <0x01c20800 0x400>; 350 reg = <0x01c20800 0x400>;
759 interrupts = <28>; 351 interrupts = <28>;
760 clocks = <&apb0_gates 5>; 352 clocks = <&ccu CLK_APB0_PIO>;
761 gpio-controller; 353 gpio-controller;
762 interrupt-controller; 354 interrupt-controller;
763 #interrupt-cells = <3>; 355 #interrupt-cells = <3>;
@@ -876,7 +468,7 @@
876 pwm: pwm@01c20e00 { 468 pwm: pwm@01c20e00 {
877 compatible = "allwinner,sun5i-a10s-pwm"; 469 compatible = "allwinner,sun5i-a10s-pwm";
878 reg = <0x01c20e00 0xc>; 470 reg = <0x01c20e00 0xc>;
879 clocks = <&osc24M>; 471 clocks = <&ccu CLK_HOSC>;
880 #pwm-cells = <3>; 472 #pwm-cells = <3>;
881 status = "disabled"; 473 status = "disabled";
882 }; 474 };
@@ -885,7 +477,7 @@
885 compatible = "allwinner,sun4i-a10-timer"; 477 compatible = "allwinner,sun4i-a10-timer";
886 reg = <0x01c20c00 0x90>; 478 reg = <0x01c20c00 0x90>;
887 interrupts = <22>; 479 interrupts = <22>;
888 clocks = <&osc24M>; 480 clocks = <&ccu CLK_HOSC>;
889 }; 481 };
890 482
891 wdt: watchdog@01c20c90 { 483 wdt: watchdog@01c20c90 {
@@ -898,7 +490,7 @@
898 compatible = "allwinner,sun4i-a10-spdif"; 490 compatible = "allwinner,sun4i-a10-spdif";
899 reg = <0x01c21000 0x400>; 491 reg = <0x01c21000 0x400>;
900 interrupts = <13>; 492 interrupts = <13>;
901 clocks = <&apb0_gates 1>, <&spdif_clk>; 493 clocks = <&ccu CLK_APB0_SPDIF>, <&ccu CLK_SPDIF>;
902 clock-names = "apb", "spdif"; 494 clock-names = "apb", "spdif";
903 dmas = <&dma SUN4I_DMA_NORMAL 2>, 495 dmas = <&dma SUN4I_DMA_NORMAL 2>,
904 <&dma SUN4I_DMA_NORMAL 2>; 496 <&dma SUN4I_DMA_NORMAL 2>;
@@ -908,7 +500,7 @@
908 500
909 ir0: ir@01c21800 { 501 ir0: ir@01c21800 {
910 compatible = "allwinner,sun4i-a10-ir"; 502 compatible = "allwinner,sun4i-a10-ir";
911 clocks = <&apb0_gates 6>, <&ir0_clk>; 503 clocks = <&ccu CLK_APB0_IR>, <&ccu CLK_IR>;
912 clock-names = "apb", "ir"; 504 clock-names = "apb", "ir";
913 interrupts = <5>; 505 interrupts = <5>;
914 reg = <0x01c21800 0x40>; 506 reg = <0x01c21800 0x40>;
@@ -920,7 +512,7 @@
920 compatible = "allwinner,sun4i-a10-i2s"; 512 compatible = "allwinner,sun4i-a10-i2s";
921 reg = <0x01c22400 0x400>; 513 reg = <0x01c22400 0x400>;
922 interrupts = <16>; 514 interrupts = <16>;
923 clocks = <&apb0_gates 3>, <&i2s0_clk>; 515 clocks = <&ccu CLK_APB0_I2S>, <&ccu CLK_I2S>;
924 clock-names = "apb", "mod"; 516 clock-names = "apb", "mod";
925 dmas = <&dma SUN4I_DMA_NORMAL 3>, 517 dmas = <&dma SUN4I_DMA_NORMAL 3>,
926 <&dma SUN4I_DMA_NORMAL 3>; 518 <&dma SUN4I_DMA_NORMAL 3>;
@@ -940,7 +532,7 @@
940 compatible = "allwinner,sun4i-a10-codec"; 532 compatible = "allwinner,sun4i-a10-codec";
941 reg = <0x01c22c00 0x40>; 533 reg = <0x01c22c00 0x40>;
942 interrupts = <30>; 534 interrupts = <30>;
943 clocks = <&apb0_gates 0>, <&codec_clk>; 535 clocks = <&ccu CLK_APB0_CODEC>, <&ccu CLK_CODEC>;
944 clock-names = "apb", "codec"; 536 clock-names = "apb", "codec";
945 dmas = <&dma SUN4I_DMA_NORMAL 19>, 537 dmas = <&dma SUN4I_DMA_NORMAL 19>,
946 <&dma SUN4I_DMA_NORMAL 19>; 538 <&dma SUN4I_DMA_NORMAL 19>;
@@ -961,7 +553,7 @@
961 interrupts = <2>; 553 interrupts = <2>;
962 reg-shift = <2>; 554 reg-shift = <2>;
963 reg-io-width = <4>; 555 reg-io-width = <4>;
964 clocks = <&apb1_gates 17>; 556 clocks = <&ccu CLK_APB1_UART1>;
965 status = "disabled"; 557 status = "disabled";
966 }; 558 };
967 559
@@ -971,7 +563,7 @@
971 interrupts = <3>; 563 interrupts = <3>;
972 reg-shift = <2>; 564 reg-shift = <2>;
973 reg-io-width = <4>; 565 reg-io-width = <4>;
974 clocks = <&apb1_gates 18>; 566 clocks = <&ccu CLK_APB1_UART2>;
975 status = "disabled"; 567 status = "disabled";
976 }; 568 };
977 569
@@ -981,7 +573,7 @@
981 interrupts = <4>; 573 interrupts = <4>;
982 reg-shift = <2>; 574 reg-shift = <2>;
983 reg-io-width = <4>; 575 reg-io-width = <4>;
984 clocks = <&apb1_gates 19>; 576 clocks = <&ccu CLK_APB1_UART3>;
985 status = "disabled"; 577 status = "disabled";
986 }; 578 };
987 579
@@ -989,7 +581,7 @@
989 compatible = "allwinner,sun4i-a10-i2c"; 581 compatible = "allwinner,sun4i-a10-i2c";
990 reg = <0x01c2ac00 0x400>; 582 reg = <0x01c2ac00 0x400>;
991 interrupts = <7>; 583 interrupts = <7>;
992 clocks = <&apb1_gates 0>; 584 clocks = <&ccu CLK_APB1_I2C0>;
993 status = "disabled"; 585 status = "disabled";
994 #address-cells = <1>; 586 #address-cells = <1>;
995 #size-cells = <0>; 587 #size-cells = <0>;
@@ -999,7 +591,7 @@
999 compatible = "allwinner,sun4i-a10-i2c"; 591 compatible = "allwinner,sun4i-a10-i2c";
1000 reg = <0x01c2b000 0x400>; 592 reg = <0x01c2b000 0x400>;
1001 interrupts = <8>; 593 interrupts = <8>;
1002 clocks = <&apb1_gates 1>; 594 clocks = <&ccu CLK_APB1_I2C1>;
1003 status = "disabled"; 595 status = "disabled";
1004 #address-cells = <1>; 596 #address-cells = <1>;
1005 #size-cells = <0>; 597 #size-cells = <0>;
@@ -1009,7 +601,7 @@
1009 compatible = "allwinner,sun4i-a10-i2c"; 601 compatible = "allwinner,sun4i-a10-i2c";
1010 reg = <0x01c2b400 0x400>; 602 reg = <0x01c2b400 0x400>;
1011 interrupts = <9>; 603 interrupts = <9>;
1012 clocks = <&apb1_gates 2>; 604 clocks = <&ccu CLK_APB1_I2C2>;
1013 status = "disabled"; 605 status = "disabled";
1014 #address-cells = <1>; 606 #address-cells = <1>;
1015 #size-cells = <0>; 607 #size-cells = <0>;
@@ -1019,18 +611,18 @@
1019 compatible = "allwinner,sun5i-a13-hstimer"; 611 compatible = "allwinner,sun5i-a13-hstimer";
1020 reg = <0x01c60000 0x1000>; 612 reg = <0x01c60000 0x1000>;
1021 interrupts = <82>, <83>; 613 interrupts = <82>, <83>;
1022 clocks = <&ahb_gates 28>; 614 clocks = <&ccu CLK_AHB_HSTIMER>;
1023 }; 615 };
1024 616
1025 fe0: display-frontend@01e00000 { 617 fe0: display-frontend@01e00000 {
1026 compatible = "allwinner,sun5i-a13-display-frontend"; 618 compatible = "allwinner,sun5i-a13-display-frontend";
1027 reg = <0x01e00000 0x20000>; 619 reg = <0x01e00000 0x20000>;
1028 interrupts = <47>; 620 interrupts = <47>;
1029 clocks = <&ahb_gates 46>, <&de_fe_clk>, 621 clocks = <&ccu CLK_AHB_DE_FE>, <&ccu CLK_DE_FE>,
1030 <&dram_gates 25>; 622 <&ccu CLK_DRAM_DE_FE>;
1031 clock-names = "ahb", "mod", 623 clock-names = "ahb", "mod",
1032 "ram"; 624 "ram";
1033 resets = <&de_fe_clk>; 625 resets = <&ccu RST_DE_FE>;
1034 status = "disabled"; 626 status = "disabled";
1035 627
1036 ports { 628 ports {
@@ -1053,14 +645,14 @@
1053 be0: display-backend@01e60000 { 645 be0: display-backend@01e60000 {
1054 compatible = "allwinner,sun5i-a13-display-backend"; 646 compatible = "allwinner,sun5i-a13-display-backend";
1055 reg = <0x01e60000 0x10000>; 647 reg = <0x01e60000 0x10000>;
1056 clocks = <&ahb_gates 44>, <&de_be_clk>, 648 clocks = <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
1057 <&dram_gates 26>; 649 <&ccu CLK_DRAM_DE_BE>;
1058 clock-names = "ahb", "mod", 650 clock-names = "ahb", "mod",
1059 "ram"; 651 "ram";
1060 resets = <&de_be_clk>; 652 resets = <&ccu RST_DE_BE>;
1061 status = "disabled"; 653 status = "disabled";
1062 654
1063 assigned-clocks = <&de_be_clk>; 655 assigned-clocks = <&ccu CLK_DE_BE>;
1064 assigned-clock-rates = <300000000>; 656 assigned-clock-rates = <300000000>;
1065 657
1066 ports { 658 ports {
diff --git a/arch/arm/boot/dts/sun5i-r8.dtsi b/arch/arm/boot/dts/sun5i-r8.dtsi
index 8b058f53b7dc..4c1141396c99 100644
--- a/arch/arm/boot/dts/sun5i-r8.dtsi
+++ b/arch/arm/boot/dts/sun5i-r8.dtsi
@@ -51,9 +51,9 @@
51 compatible = "allwinner,simple-framebuffer", 51 compatible = "allwinner,simple-framebuffer",
52 "simple-framebuffer"; 52 "simple-framebuffer";
53 allwinner,pipeline = "de_be0-lcd0-tve0"; 53 allwinner,pipeline = "de_be0-lcd0-tve0";
54 clocks = <&ahb_gates 34>, <&ahb_gates 36>, 54 clocks = <&ccu CLK_AHB_TVE>, <&ccu CLK_AHB_LCD>,
55 <&ahb_gates 44>, <&de_be_clk>, 55 <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
56 <&tcon_ch1_clk>, <&dram_gates 26>; 56 <&ccu CLK_TCON_CH1>, <&ccu CLK_DRAM_DE_BE>;
57 status = "disabled"; 57 status = "disabled";
58 }; 58 };
59 }; 59 };
@@ -62,8 +62,8 @@
62 tve0: tv-encoder@01c0a000 { 62 tve0: tv-encoder@01c0a000 {
63 compatible = "allwinner,sun4i-a10-tv-encoder"; 63 compatible = "allwinner,sun4i-a10-tv-encoder";
64 reg = <0x01c0a000 0x1000>; 64 reg = <0x01c0a000 0x1000>;
65 clocks = <&ahb_gates 34>; 65 clocks = <&ccu CLK_AHB_TVE>;
66 resets = <&tcon_ch0_clk 0>; 66 resets = <&ccu RST_TVE>;
67 status = "disabled"; 67 status = "disabled";
68 68
69 port { 69 port {
diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index c058d37d5433..a9574a6cd95c 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -44,9 +44,10 @@
44 44
45#include "skeleton.dtsi" 45#include "skeleton.dtsi"
46 46
47#include <dt-bindings/clock/sun4i-a10-pll2.h> 47#include <dt-bindings/clock/sun5i-ccu.h>
48#include <dt-bindings/dma/sun4i-a10.h> 48#include <dt-bindings/dma/sun4i-a10.h>
49#include <dt-bindings/pinctrl/sun4i-a10.h> 49#include <dt-bindings/pinctrl/sun4i-a10.h>
50#include <dt-bindings/reset/sun5i-ccu.h>
50 51
51/ { 52/ {
52 interrupt-parent = <&intc>; 53 interrupt-parent = <&intc>;
@@ -59,7 +60,7 @@
59 device_type = "cpu"; 60 device_type = "cpu";
60 compatible = "arm,cortex-a8"; 61 compatible = "arm,cortex-a8";
61 reg = <0x0>; 62 reg = <0x0>;
62 clocks = <&cpu>; 63 clocks = <&ccu CLK_CPU>;
63 }; 64 };
64 }; 65 };
65 66
@@ -68,291 +69,19 @@
68 #size-cells = <1>; 69 #size-cells = <1>;
69 ranges; 70 ranges;
70 71
71 /*
72 * This is a dummy clock, to be used as placeholder on
73 * other mux clocks when a specific parent clock is not
74 * yet implemented. It should be dropped when the driver
75 * is complete.
76 */
77 dummy: dummy {
78 #clock-cells = <0>;
79 compatible = "fixed-clock";
80 clock-frequency = <0>;
81 };
82
83 osc24M: clk@01c20050 { 72 osc24M: clk@01c20050 {
84 #clock-cells = <0>; 73 #clock-cells = <0>;
85 compatible = "allwinner,sun4i-a10-osc-clk"; 74 compatible = "fixed-clock";
86 reg = <0x01c20050 0x4>;
87 clock-frequency = <24000000>; 75 clock-frequency = <24000000>;
88 clock-output-names = "osc24M"; 76 clock-output-names = "osc24M";
89 }; 77 };
90 78
91 osc3M: osc3M_clk {
92 compatible = "fixed-factor-clock";
93 #clock-cells = <0>;
94 clock-div = <8>;
95 clock-mult = <1>;
96 clocks = <&osc24M>;
97 clock-output-names = "osc3M";
98 };
99
100 osc32k: clk@0 { 79 osc32k: clk@0 {
101 #clock-cells = <0>; 80 #clock-cells = <0>;
102 compatible = "fixed-clock"; 81 compatible = "fixed-clock";
103 clock-frequency = <32768>; 82 clock-frequency = <32768>;
104 clock-output-names = "osc32k"; 83 clock-output-names = "osc32k";
105 }; 84 };
106
107 pll1: clk@01c20000 {
108 #clock-cells = <0>;
109 compatible = "allwinner,sun4i-a10-pll1-clk";
110 reg = <0x01c20000 0x4>;
111 clocks = <&osc24M>;
112 clock-output-names = "pll1";
113 };
114
115 pll2: clk@01c20008 {
116 #clock-cells = <1>;
117 compatible = "allwinner,sun5i-a13-pll2-clk";
118 reg = <0x01c20008 0x8>;
119 clocks = <&osc24M>;
120 clock-output-names = "pll2-1x", "pll2-2x",
121 "pll2-4x", "pll2-8x";
122 };
123
124 pll3: clk@01c20010 {
125 #clock-cells = <0>;
126 compatible = "allwinner,sun4i-a10-pll3-clk";
127 reg = <0x01c20010 0x4>;
128 clocks = <&osc3M>;
129 clock-output-names = "pll3";
130 };
131
132 pll3x2: pll3x2_clk {
133 compatible = "allwinner,sun4i-a10-pll3-2x-clk", "fixed-factor-clock";
134 #clock-cells = <0>;
135 clock-div = <1>;
136 clock-mult = <2>;
137 clocks = <&pll3>;
138 clock-output-names = "pll3-2x";
139 };
140
141 pll4: clk@01c20018 {
142 #clock-cells = <0>;
143 compatible = "allwinner,sun4i-a10-pll1-clk";
144 reg = <0x01c20018 0x4>;
145 clocks = <&osc24M>;
146 clock-output-names = "pll4";
147 };
148
149 pll5: clk@01c20020 {
150 #clock-cells = <1>;
151 compatible = "allwinner,sun4i-a10-pll5-clk";
152 reg = <0x01c20020 0x4>;
153 clocks = <&osc24M>;
154 clock-output-names = "pll5_ddr", "pll5_other";
155 };
156
157 pll6: clk@01c20028 {
158 #clock-cells = <1>;
159 compatible = "allwinner,sun4i-a10-pll6-clk";
160 reg = <0x01c20028 0x4>;
161 clocks = <&osc24M>;
162 clock-output-names = "pll6_sata", "pll6_other", "pll6";
163 };
164
165 pll7: clk@01c20030 {
166 #clock-cells = <0>;
167 compatible = "allwinner,sun4i-a10-pll3-clk";
168 reg = <0x01c20030 0x4>;
169 clocks = <&osc3M>;
170 clock-output-names = "pll7";
171 };
172
173 pll7x2: pll7x2_clk {
174 compatible = "fixed-factor-clock";
175 #clock-cells = <0>;
176 clock-div = <1>;
177 clock-mult = <2>;
178 clocks = <&pll7>;
179 clock-output-names = "pll7-2x";
180 };
181
182 /* dummy is 200M */
183 cpu: cpu@01c20054 {
184 #clock-cells = <0>;
185 compatible = "allwinner,sun4i-a10-cpu-clk";
186 reg = <0x01c20054 0x4>;
187 clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
188 clock-output-names = "cpu";
189 };
190
191 axi: axi@01c20054 {
192 #clock-cells = <0>;
193 compatible = "allwinner,sun4i-a10-axi-clk";
194 reg = <0x01c20054 0x4>;
195 clocks = <&cpu>;
196 clock-output-names = "axi";
197 };
198
199 ahb: ahb@01c20054 {
200 #clock-cells = <0>;
201 compatible = "allwinner,sun5i-a13-ahb-clk";
202 reg = <0x01c20054 0x4>;
203 clocks = <&axi>, <&cpu>, <&pll6 1>;
204 clock-output-names = "ahb";
205 /*
206 * Use PLL6 as parent, instead of CPU/AXI
207 * which has rate changes due to cpufreq
208 */
209 assigned-clocks = <&ahb>;
210 assigned-clock-parents = <&pll6 1>;
211 };
212
213 apb0: apb0@01c20054 {
214 #clock-cells = <0>;
215 compatible = "allwinner,sun4i-a10-apb0-clk";
216 reg = <0x01c20054 0x4>;
217 clocks = <&ahb>;
218 clock-output-names = "apb0";
219 };
220
221 apb1: clk@01c20058 {
222 #clock-cells = <0>;
223 compatible = "allwinner,sun4i-a10-apb1-clk";
224 reg = <0x01c20058 0x4>;
225 clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
226 clock-output-names = "apb1";
227 };
228
229 axi_gates: clk@01c2005c {
230 #clock-cells = <1>;
231 compatible = "allwinner,sun4i-a10-axi-gates-clk";
232 reg = <0x01c2005c 0x4>;
233 clocks = <&axi>;
234 clock-indices = <0>;
235 clock-output-names = "axi_dram";
236 };
237
238 nand_clk: clk@01c20080 {
239 #clock-cells = <0>;
240 compatible = "allwinner,sun4i-a10-mod0-clk";
241 reg = <0x01c20080 0x4>;
242 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
243 clock-output-names = "nand";
244 };
245
246 ms_clk: clk@01c20084 {
247 #clock-cells = <0>;
248 compatible = "allwinner,sun4i-a10-mod0-clk";
249 reg = <0x01c20084 0x4>;
250 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
251 clock-output-names = "ms";
252 };
253
254 mmc0_clk: clk@01c20088 {
255 #clock-cells = <1>;
256 compatible = "allwinner,sun4i-a10-mmc-clk";
257 reg = <0x01c20088 0x4>;
258 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
259 clock-output-names = "mmc0",
260 "mmc0_output",
261 "mmc0_sample";
262 };
263
264 mmc1_clk: clk@01c2008c {
265 #clock-cells = <1>;
266 compatible = "allwinner,sun4i-a10-mmc-clk";
267 reg = <0x01c2008c 0x4>;
268 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
269 clock-output-names = "mmc1",
270 "mmc1_output",
271 "mmc1_sample";
272 };
273
274 mmc2_clk: clk@01c20090 {
275 #clock-cells = <1>;
276 compatible = "allwinner,sun4i-a10-mmc-clk";
277 reg = <0x01c20090 0x4>;
278 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
279 clock-output-names = "mmc2",
280 "mmc2_output",
281 "mmc2_sample";
282 };
283
284 ts_clk: clk@01c20098 {
285 #clock-cells = <0>;
286 compatible = "allwinner,sun4i-a10-mod0-clk";
287 reg = <0x01c20098 0x4>;
288 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
289 clock-output-names = "ts";
290 };
291
292 ss_clk: clk@01c2009c {
293 #clock-cells = <0>;
294 compatible = "allwinner,sun4i-a10-mod0-clk";
295 reg = <0x01c2009c 0x4>;
296 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
297 clock-output-names = "ss";
298 };
299
300 spi0_clk: clk@01c200a0 {
301 #clock-cells = <0>;
302 compatible = "allwinner,sun4i-a10-mod0-clk";
303 reg = <0x01c200a0 0x4>;
304 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
305 clock-output-names = "spi0";
306 };
307
308 spi1_clk: clk@01c200a4 {
309 #clock-cells = <0>;
310 compatible = "allwinner,sun4i-a10-mod0-clk";
311 reg = <0x01c200a4 0x4>;
312 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
313 clock-output-names = "spi1";
314 };
315
316 spi2_clk: clk@01c200a8 {
317 #clock-cells = <0>;
318 compatible = "allwinner,sun4i-a10-mod0-clk";
319 reg = <0x01c200a8 0x4>;
320 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
321 clock-output-names = "spi2";
322 };
323
324 ir0_clk: clk@01c200b0 {
325 #clock-cells = <0>;
326 compatible = "allwinner,sun4i-a10-mod0-clk";
327 reg = <0x01c200b0 0x4>;
328 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
329 clock-output-names = "ir0";
330 };
331
332 usb_clk: clk@01c200cc {
333 #clock-cells = <1>;
334 #reset-cells = <1>;
335 compatible = "allwinner,sun5i-a13-usb-clk";
336 reg = <0x01c200cc 0x4>;
337 clocks = <&pll6 1>;
338 clock-output-names = "usb_ohci0", "usb_phy";
339 };
340
341 codec_clk: clk@01c20140 {
342 #clock-cells = <0>;
343 compatible = "allwinner,sun4i-a10-codec-clk";
344 reg = <0x01c20140 0x4>;
345 clocks = <&pll2 SUN4I_A10_PLL2_1X>;
346 clock-output-names = "codec";
347 };
348
349 mbus_clk: clk@01c2015c {
350 #clock-cells = <0>;
351 compatible = "allwinner,sun5i-a13-mbus-clk";
352 reg = <0x01c2015c 0x4>;
353 clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
354 clock-output-names = "mbus";
355 };
356 }; 85 };
357 86
358 soc@01c00000 { 87 soc@01c00000 {
@@ -395,7 +124,7 @@
395 compatible = "allwinner,sun4i-a10-dma"; 124 compatible = "allwinner,sun4i-a10-dma";
396 reg = <0x01c02000 0x1000>; 125 reg = <0x01c02000 0x1000>;
397 interrupts = <27>; 126 interrupts = <27>;
398 clocks = <&ahb_gates 6>; 127 clocks = <&ccu CLK_AHB_DMA>;
399 #dma-cells = <2>; 128 #dma-cells = <2>;
400 }; 129 };
401 130
@@ -403,7 +132,7 @@
403 compatible = "allwinner,sun4i-a10-spi"; 132 compatible = "allwinner,sun4i-a10-spi";
404 reg = <0x01c05000 0x1000>; 133 reg = <0x01c05000 0x1000>;
405 interrupts = <10>; 134 interrupts = <10>;
406 clocks = <&ahb_gates 20>, <&spi0_clk>; 135 clocks = <&ccu CLK_AHB_SPI0>, <&ccu CLK_SPI0>;
407 clock-names = "ahb", "mod"; 136 clock-names = "ahb", "mod";
408 dmas = <&dma SUN4I_DMA_DEDICATED 27>, 137 dmas = <&dma SUN4I_DMA_DEDICATED 27>,
409 <&dma SUN4I_DMA_DEDICATED 26>; 138 <&dma SUN4I_DMA_DEDICATED 26>;
@@ -417,7 +146,7 @@
417 compatible = "allwinner,sun4i-a10-spi"; 146 compatible = "allwinner,sun4i-a10-spi";
418 reg = <0x01c06000 0x1000>; 147 reg = <0x01c06000 0x1000>;
419 interrupts = <11>; 148 interrupts = <11>;
420 clocks = <&ahb_gates 21>, <&spi1_clk>; 149 clocks = <&ccu CLK_AHB_SPI1>, <&ccu CLK_SPI1>;
421 clock-names = "ahb", "mod"; 150 clock-names = "ahb", "mod";
422 dmas = <&dma SUN4I_DMA_DEDICATED 9>, 151 dmas = <&dma SUN4I_DMA_DEDICATED 9>,
423 <&dma SUN4I_DMA_DEDICATED 8>; 152 <&dma SUN4I_DMA_DEDICATED 8>;
@@ -430,14 +159,8 @@
430 mmc0: mmc@01c0f000 { 159 mmc0: mmc@01c0f000 {
431 compatible = "allwinner,sun5i-a13-mmc"; 160 compatible = "allwinner,sun5i-a13-mmc";
432 reg = <0x01c0f000 0x1000>; 161 reg = <0x01c0f000 0x1000>;
433 clocks = <&ahb_gates 8>, 162 clocks = <&ccu CLK_AHB_MMC0>, <&ccu CLK_MMC0>;
434 <&mmc0_clk 0>, 163 clock-names = "ahb", "mmc";
435 <&mmc0_clk 1>,
436 <&mmc0_clk 2>;
437 clock-names = "ahb",
438 "mmc",
439 "output",
440 "sample";
441 interrupts = <32>; 164 interrupts = <32>;
442 status = "disabled"; 165 status = "disabled";
443 #address-cells = <1>; 166 #address-cells = <1>;
@@ -447,14 +170,8 @@
447 mmc1: mmc@01c10000 { 170 mmc1: mmc@01c10000 {
448 compatible = "allwinner,sun5i-a13-mmc"; 171 compatible = "allwinner,sun5i-a13-mmc";
449 reg = <0x01c10000 0x1000>; 172 reg = <0x01c10000 0x1000>;
450 clocks = <&ahb_gates 9>, 173 clocks = <&ccu CLK_AHB_MMC1>, <&ccu CLK_MMC1>;
451 <&mmc1_clk 0>, 174 clock-names = "ahb", "mmc";
452 <&mmc1_clk 1>,
453 <&mmc1_clk 2>;
454 clock-names = "ahb",
455 "mmc",
456 "output",
457 "sample";
458 interrupts = <33>; 175 interrupts = <33>;
459 status = "disabled"; 176 status = "disabled";
460 #address-cells = <1>; 177 #address-cells = <1>;
@@ -464,14 +181,8 @@
464 mmc2: mmc@01c11000 { 181 mmc2: mmc@01c11000 {
465 compatible = "allwinner,sun5i-a13-mmc"; 182 compatible = "allwinner,sun5i-a13-mmc";
466 reg = <0x01c11000 0x1000>; 183 reg = <0x01c11000 0x1000>;
467 clocks = <&ahb_gates 10>, 184 clocks = <&ccu CLK_AHB_MMC2>, <&ccu CLK_MMC2>;
468 <&mmc2_clk 0>, 185 clock-names = "ahb", "mmc";
469 <&mmc2_clk 1>,
470 <&mmc2_clk 2>;
471 clock-names = "ahb",
472 "mmc",
473 "output",
474 "sample";
475 interrupts = <34>; 186 interrupts = <34>;
476 status = "disabled"; 187 status = "disabled";
477 #address-cells = <1>; 188 #address-cells = <1>;
@@ -481,7 +192,7 @@
481 usb_otg: usb@01c13000 { 192 usb_otg: usb@01c13000 {
482 compatible = "allwinner,sun4i-a10-musb"; 193 compatible = "allwinner,sun4i-a10-musb";
483 reg = <0x01c13000 0x0400>; 194 reg = <0x01c13000 0x0400>;
484 clocks = <&ahb_gates 0>; 195 clocks = <&ccu CLK_AHB_OTG>;
485 interrupts = <38>; 196 interrupts = <38>;
486 interrupt-names = "mc"; 197 interrupt-names = "mc";
487 phys = <&usbphy 0>; 198 phys = <&usbphy 0>;
@@ -496,9 +207,9 @@
496 compatible = "allwinner,sun5i-a13-usb-phy"; 207 compatible = "allwinner,sun5i-a13-usb-phy";
497 reg = <0x01c13400 0x10 0x01c14800 0x4>; 208 reg = <0x01c13400 0x10 0x01c14800 0x4>;
498 reg-names = "phy_ctrl", "pmu1"; 209 reg-names = "phy_ctrl", "pmu1";
499 clocks = <&usb_clk 8>; 210 clocks = <&ccu CLK_USB_PHY0>;
500 clock-names = "usb_phy"; 211 clock-names = "usb_phy";
501 resets = <&usb_clk 0>, <&usb_clk 1>; 212 resets = <&ccu RST_USB_PHY0>, <&ccu RST_USB_PHY1>;
502 reset-names = "usb0_reset", "usb1_reset"; 213 reset-names = "usb0_reset", "usb1_reset";
503 status = "disabled"; 214 status = "disabled";
504 }; 215 };
@@ -507,7 +218,7 @@
507 compatible = "allwinner,sun5i-a13-ehci", "generic-ehci"; 218 compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
508 reg = <0x01c14000 0x100>; 219 reg = <0x01c14000 0x100>;
509 interrupts = <39>; 220 interrupts = <39>;
510 clocks = <&ahb_gates 1>; 221 clocks = <&ccu CLK_AHB_EHCI>;
511 phys = <&usbphy 1>; 222 phys = <&usbphy 1>;
512 phy-names = "usb"; 223 phy-names = "usb";
513 status = "disabled"; 224 status = "disabled";
@@ -517,7 +228,7 @@
517 compatible = "allwinner,sun5i-a13-ohci", "generic-ohci"; 228 compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
518 reg = <0x01c14400 0x100>; 229 reg = <0x01c14400 0x100>;
519 interrupts = <40>; 230 interrupts = <40>;
520 clocks = <&usb_clk 6>, <&ahb_gates 2>; 231 clocks = <&ccu CLK_USB_OHCI>, <&ccu CLK_AHB_OHCI>;
521 phys = <&usbphy 1>; 232 phys = <&usbphy 1>;
522 phy-names = "usb"; 233 phy-names = "usb";
523 status = "disabled"; 234 status = "disabled";
@@ -527,7 +238,7 @@
527 compatible = "allwinner,sun4i-a10-spi"; 238 compatible = "allwinner,sun4i-a10-spi";
528 reg = <0x01c17000 0x1000>; 239 reg = <0x01c17000 0x1000>;
529 interrupts = <12>; 240 interrupts = <12>;
530 clocks = <&ahb_gates 22>, <&spi2_clk>; 241 clocks = <&ccu CLK_AHB_SPI2>, <&ccu CLK_SPI2>;
531 clock-names = "ahb", "mod"; 242 clock-names = "ahb", "mod";
532 dmas = <&dma SUN4I_DMA_DEDICATED 29>, 243 dmas = <&dma SUN4I_DMA_DEDICATED 29>,
533 <&dma SUN4I_DMA_DEDICATED 28>; 244 <&dma SUN4I_DMA_DEDICATED 28>;
@@ -537,6 +248,14 @@
537 #size-cells = <0>; 248 #size-cells = <0>;
538 }; 249 };
539 250
251 ccu: clock@01c20000 {
252 reg = <0x01c20000 0x400>;
253 clocks = <&osc24M>, <&osc32k>;
254 clock-names = "hosc", "losc";
255 #clock-cells = <1>;
256 #reset-cells = <1>;
257 };
258
540 intc: interrupt-controller@01c20400 { 259 intc: interrupt-controller@01c20400 {
541 compatible = "allwinner,sun4i-a10-ic"; 260 compatible = "allwinner,sun4i-a10-ic";
542 reg = <0x01c20400 0x400>; 261 reg = <0x01c20400 0x400>;
@@ -547,7 +266,7 @@
547 pio: pinctrl@01c20800 { 266 pio: pinctrl@01c20800 {
548 reg = <0x01c20800 0x400>; 267 reg = <0x01c20800 0x400>;
549 interrupts = <28>; 268 interrupts = <28>;
550 clocks = <&apb0_gates 5>, <&osc24M>, <&osc32k>; 269 clocks = <&ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
551 clock-names = "apb", "hosc", "losc"; 270 clock-names = "apb", "hosc", "losc";
552 gpio-controller; 271 gpio-controller;
553 interrupt-controller; 272 interrupt-controller;
@@ -632,7 +351,7 @@
632 compatible = "allwinner,sun4i-a10-timer"; 351 compatible = "allwinner,sun4i-a10-timer";
633 reg = <0x01c20c00 0x90>; 352 reg = <0x01c20c00 0x90>;
634 interrupts = <22>; 353 interrupts = <22>;
635 clocks = <&osc24M>; 354 clocks = <&ccu CLK_HOSC>;
636 }; 355 };
637 356
638 wdt: watchdog@01c20c90 { 357 wdt: watchdog@01c20c90 {
@@ -652,7 +371,7 @@
652 compatible = "allwinner,sun4i-a10-codec"; 371 compatible = "allwinner,sun4i-a10-codec";
653 reg = <0x01c22c00 0x40>; 372 reg = <0x01c22c00 0x40>;
654 interrupts = <30>; 373 interrupts = <30>;
655 clocks = <&apb0_gates 0>, <&codec_clk>; 374 clocks = <&ccu CLK_APB0_CODEC>, <&ccu CLK_CODEC>;
656 clock-names = "apb", "codec"; 375 clock-names = "apb", "codec";
657 dmas = <&dma SUN4I_DMA_NORMAL 19>, 376 dmas = <&dma SUN4I_DMA_NORMAL 19>,
658 <&dma SUN4I_DMA_NORMAL 19>; 377 <&dma SUN4I_DMA_NORMAL 19>;
@@ -678,7 +397,7 @@
678 interrupts = <2>; 397 interrupts = <2>;
679 reg-shift = <2>; 398 reg-shift = <2>;
680 reg-io-width = <4>; 399 reg-io-width = <4>;
681 clocks = <&apb1_gates 17>; 400 clocks = <&ccu CLK_APB1_UART1>;
682 status = "disabled"; 401 status = "disabled";
683 }; 402 };
684 403
@@ -688,7 +407,7 @@
688 interrupts = <4>; 407 interrupts = <4>;
689 reg-shift = <2>; 408 reg-shift = <2>;
690 reg-io-width = <4>; 409 reg-io-width = <4>;
691 clocks = <&apb1_gates 19>; 410 clocks = <&ccu CLK_APB1_UART3>;
692 status = "disabled"; 411 status = "disabled";
693 }; 412 };
694 413
@@ -696,7 +415,7 @@
696 compatible = "allwinner,sun4i-a10-i2c"; 415 compatible = "allwinner,sun4i-a10-i2c";
697 reg = <0x01c2ac00 0x400>; 416 reg = <0x01c2ac00 0x400>;
698 interrupts = <7>; 417 interrupts = <7>;
699 clocks = <&apb1_gates 0>; 418 clocks = <&ccu CLK_APB1_I2C0>;
700 status = "disabled"; 419 status = "disabled";
701 #address-cells = <1>; 420 #address-cells = <1>;
702 #size-cells = <0>; 421 #size-cells = <0>;
@@ -706,7 +425,7 @@
706 compatible = "allwinner,sun4i-a10-i2c"; 425 compatible = "allwinner,sun4i-a10-i2c";
707 reg = <0x01c2b000 0x400>; 426 reg = <0x01c2b000 0x400>;
708 interrupts = <8>; 427 interrupts = <8>;
709 clocks = <&apb1_gates 1>; 428 clocks = <&ccu CLK_APB1_I2C1>;
710 status = "disabled"; 429 status = "disabled";
711 #address-cells = <1>; 430 #address-cells = <1>;
712 #size-cells = <0>; 431 #size-cells = <0>;
@@ -716,7 +435,7 @@
716 compatible = "allwinner,sun4i-a10-i2c"; 435 compatible = "allwinner,sun4i-a10-i2c";
717 reg = <0x01c2b400 0x400>; 436 reg = <0x01c2b400 0x400>;
718 interrupts = <9>; 437 interrupts = <9>;
719 clocks = <&apb1_gates 2>; 438 clocks = <&ccu CLK_APB1_I2C2>;
720 status = "disabled"; 439 status = "disabled";
721 #address-cells = <1>; 440 #address-cells = <1>;
722 #size-cells = <0>; 441 #size-cells = <0>;
@@ -726,7 +445,7 @@
726 compatible = "allwinner,sun5i-a13-hstimer"; 445 compatible = "allwinner,sun5i-a13-hstimer";
727 reg = <0x01c60000 0x1000>; 446 reg = <0x01c60000 0x1000>;
728 interrupts = <82>, <83>; 447 interrupts = <82>, <83>;
729 clocks = <&ahb_gates 28>; 448 clocks = <&ccu CLK_AHB_HSTIMER>;
730 }; 449 };
731 }; 450 };
732}; 451};
diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index 03f2ab47ece0..15b6d122f878 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -48,6 +48,13 @@
48 48
49#include <dt-bindings/pinctrl/sun4i-a10.h> 49#include <dt-bindings/pinctrl/sun4i-a10.h>
50 50
51#include <dt-bindings/clock/sun9i-a80-ccu.h>
52#include <dt-bindings/clock/sun9i-a80-de.h>
53#include <dt-bindings/clock/sun9i-a80-usb.h>
54#include <dt-bindings/reset/sun9i-a80-ccu.h>
55#include <dt-bindings/reset/sun9i-a80-de.h>
56#include <dt-bindings/reset/sun9i-a80-usb.h>
57
51/ { 58/ {
52 interrupt-parent = <&gic>; 59 interrupt-parent = <&gic>;
53 60
@@ -159,228 +166,13 @@
159 clock-output-names = "osc32k"; 166 clock-output-names = "osc32k";
160 }; 167 };
161 168
162 usb_mod_clk: clk@00a08000 {
163 #clock-cells = <1>;
164 #reset-cells = <1>;
165 compatible = "allwinner,sun9i-a80-usb-mod-clk";
166 reg = <0x00a08000 0x4>;
167 clocks = <&ahb1_gates 1>;
168 clock-output-names = "usb0_ahb", "usb_ohci0",
169 "usb1_ahb", "usb_ohci1",
170 "usb2_ahb", "usb_ohci2";
171 };
172
173 usb_phy_clk: clk@00a08004 {
174 #clock-cells = <1>;
175 #reset-cells = <1>;
176 compatible = "allwinner,sun9i-a80-usb-phy-clk";
177 reg = <0x00a08004 0x4>;
178 clocks = <&ahb1_gates 1>;
179 clock-output-names = "usb_phy0", "usb_hsic1_480M",
180 "usb_phy1", "usb_hsic2_480M",
181 "usb_phy2", "usb_hsic_12M";
182 };
183
184 pll3: clk@06000008 {
185 /* placeholder until implemented */
186 #clock-cells = <0>;
187 compatible = "fixed-clock";
188 clock-rate = <0>;
189 clock-output-names = "pll3";
190 };
191
192 pll4: clk@0600000c {
193 #clock-cells = <0>;
194 compatible = "allwinner,sun9i-a80-pll4-clk";
195 reg = <0x0600000c 0x4>;
196 clocks = <&osc24M>;
197 clock-output-names = "pll4";
198 };
199
200 pll12: clk@0600002c {
201 #clock-cells = <0>;
202 compatible = "allwinner,sun9i-a80-pll4-clk";
203 reg = <0x0600002c 0x4>;
204 clocks = <&osc24M>;
205 clock-output-names = "pll12";
206 };
207
208 gt_clk: clk@0600005c {
209 #clock-cells = <0>;
210 compatible = "allwinner,sun9i-a80-gt-clk";
211 reg = <0x0600005c 0x4>;
212 clocks = <&osc24M>, <&pll4>, <&pll12>, <&pll12>;
213 clock-output-names = "gt";
214 };
215
216 ahb0: clk@06000060 {
217 #clock-cells = <0>;
218 compatible = "allwinner,sun9i-a80-ahb-clk";
219 reg = <0x06000060 0x4>;
220 clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
221 clock-output-names = "ahb0";
222 };
223
224 ahb1: clk@06000064 {
225 #clock-cells = <0>;
226 compatible = "allwinner,sun9i-a80-ahb-clk";
227 reg = <0x06000064 0x4>;
228 clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
229 clock-output-names = "ahb1";
230 };
231
232 ahb2: clk@06000068 {
233 #clock-cells = <0>;
234 compatible = "allwinner,sun9i-a80-ahb-clk";
235 reg = <0x06000068 0x4>;
236 clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
237 clock-output-names = "ahb2";
238 };
239
240 apb0: clk@06000070 {
241 #clock-cells = <0>;
242 compatible = "allwinner,sun9i-a80-apb0-clk";
243 reg = <0x06000070 0x4>;
244 clocks = <&osc24M>, <&pll4>;
245 clock-output-names = "apb0";
246 };
247
248 apb1: clk@06000074 {
249 #clock-cells = <0>;
250 compatible = "allwinner,sun9i-a80-apb1-clk";
251 reg = <0x06000074 0x4>;
252 clocks = <&osc24M>, <&pll4>;
253 clock-output-names = "apb1";
254 };
255
256 cci400_clk: clk@06000078 {
257 #clock-cells = <0>;
258 compatible = "allwinner,sun9i-a80-gt-clk";
259 reg = <0x06000078 0x4>;
260 clocks = <&osc24M>, <&pll4>, <&pll12>, <&pll12>;
261 clock-output-names = "cci400";
262 };
263
264 mmc0_clk: clk@06000410 {
265 #clock-cells = <1>;
266 compatible = "allwinner,sun9i-a80-mmc-clk";
267 reg = <0x06000410 0x4>;
268 clocks = <&osc24M>, <&pll4>;
269 clock-output-names = "mmc0", "mmc0_output",
270 "mmc0_sample";
271 };
272
273 mmc1_clk: clk@06000414 {
274 #clock-cells = <1>;
275 compatible = "allwinner,sun9i-a80-mmc-clk";
276 reg = <0x06000414 0x4>;
277 clocks = <&osc24M>, <&pll4>;
278 clock-output-names = "mmc1", "mmc1_output",
279 "mmc1_sample";
280 };
281
282 mmc2_clk: clk@06000418 {
283 #clock-cells = <1>;
284 compatible = "allwinner,sun9i-a80-mmc-clk";
285 reg = <0x06000418 0x4>;
286 clocks = <&osc24M>, <&pll4>;
287 clock-output-names = "mmc2", "mmc2_output",
288 "mmc2_sample";
289 };
290
291 mmc3_clk: clk@0600041c {
292 #clock-cells = <1>;
293 compatible = "allwinner,sun9i-a80-mmc-clk";
294 reg = <0x0600041c 0x4>;
295 clocks = <&osc24M>, <&pll4>;
296 clock-output-names = "mmc3", "mmc3_output",
297 "mmc3_sample";
298 };
299
300 ahb0_gates: clk@06000580 {
301 #clock-cells = <1>;
302 compatible = "allwinner,sun9i-a80-ahb0-gates-clk";
303 reg = <0x06000580 0x4>;
304 clocks = <&ahb0>;
305 clock-indices = <0>, <1>, <3>,
306 <5>, <8>, <12>,
307 <13>, <14>,
308 <15>, <16>, <18>,
309 <20>, <21>, <22>,
310 <23>;
311 clock-output-names = "ahb0_fd", "ahb0_ve", "ahb0_gpu",
312 "ahb0_ss", "ahb0_sd", "ahb0_nand1",
313 "ahb0_nand0", "ahb0_sdram",
314 "ahb0_mipi_hsi", "ahb0_sata", "ahb0_ts",
315 "ahb0_spi0", "ahb0_spi1", "ahb0_spi2",
316 "ahb0_spi3";
317 };
318
319 ahb1_gates: clk@06000584 {
320 #clock-cells = <1>;
321 compatible = "allwinner,sun9i-a80-ahb1-gates-clk";
322 reg = <0x06000584 0x4>;
323 clocks = <&ahb1>;
324 clock-indices = <0>, <1>,
325 <17>, <21>,
326 <22>, <23>,
327 <24>;
328 clock-output-names = "ahb1_usbotg", "ahb1_usbhci",
329 "ahb1_gmac", "ahb1_msgbox",
330 "ahb1_spinlock", "ahb1_hstimer",
331 "ahb1_dma";
332 };
333
334 ahb2_gates: clk@06000588 {
335 #clock-cells = <1>;
336 compatible = "allwinner,sun9i-a80-ahb2-gates-clk";
337 reg = <0x06000588 0x4>;
338 clocks = <&ahb2>;
339 clock-indices = <0>, <1>,
340 <2>, <4>, <5>,
341 <7>, <8>, <11>;
342 clock-output-names = "ahb2_lcd0", "ahb2_lcd1",
343 "ahb2_edp", "ahb2_csi", "ahb2_hdmi",
344 "ahb2_de", "ahb2_mp", "ahb2_mipi_dsi";
345 };
346
347 apb0_gates: clk@06000590 {
348 #clock-cells = <1>;
349 compatible = "allwinner,sun9i-a80-apb0-gates-clk";
350 reg = <0x06000590 0x4>;
351 clocks = <&apb0>;
352 clock-indices = <1>, <5>,
353 <11>, <12>, <13>,
354 <15>, <17>, <18>,
355 <19>;
356 clock-output-names = "apb0_spdif", "apb0_pio",
357 "apb0_ac97", "apb0_i2s0", "apb0_i2s1",
358 "apb0_lradc", "apb0_gpadc", "apb0_twd",
359 "apb0_cirtx";
360 };
361
362 apb1_gates: clk@06000594 {
363 #clock-cells = <1>;
364 compatible = "allwinner,sun9i-a80-apb1-gates-clk";
365 reg = <0x06000594 0x4>;
366 clocks = <&apb1>;
367 clock-indices = <0>, <1>,
368 <2>, <3>, <4>,
369 <16>, <17>,
370 <18>, <19>,
371 <20>, <21>;
372 clock-output-names = "apb1_i2c0", "apb1_i2c1",
373 "apb1_i2c2", "apb1_i2c3", "apb1_i2c4",
374 "apb1_uart0", "apb1_uart1",
375 "apb1_uart2", "apb1_uart3",
376 "apb1_uart4", "apb1_uart5";
377 };
378
379 cpus_clk: clk@08001410 { 169 cpus_clk: clk@08001410 {
380 compatible = "allwinner,sun9i-a80-cpus-clk"; 170 compatible = "allwinner,sun9i-a80-cpus-clk";
381 reg = <0x08001410 0x4>; 171 reg = <0x08001410 0x4>;
382 #clock-cells = <0>; 172 #clock-cells = <0>;
383 clocks = <&osc32k>, <&osc24M>, <&pll4>, <&pll3>; 173 clocks = <&osc32k>, <&osc24M>,
174 <&ccu CLK_PLL_PERIPH0>,
175 <&ccu CLK_PLL_AUDIO>;
384 clock-output-names = "cpus"; 176 clock-output-names = "cpus";
385 }; 177 };
386 178
@@ -453,8 +245,8 @@
453 compatible = "allwinner,sun9i-a80-ehci", "generic-ehci"; 245 compatible = "allwinner,sun9i-a80-ehci", "generic-ehci";
454 reg = <0x00a00000 0x100>; 246 reg = <0x00a00000 0x100>;
455 interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; 247 interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
456 clocks = <&usb_mod_clk 1>; 248 clocks = <&usb_clocks CLK_BUS_HCI0>;
457 resets = <&usb_mod_clk 17>; 249 resets = <&usb_clocks RST_USB0_HCI>;
458 phys = <&usbphy1>; 250 phys = <&usbphy1>;
459 phy-names = "usb"; 251 phy-names = "usb";
460 status = "disabled"; 252 status = "disabled";
@@ -464,8 +256,9 @@
464 compatible = "allwinner,sun9i-a80-ohci", "generic-ohci"; 256 compatible = "allwinner,sun9i-a80-ohci", "generic-ohci";
465 reg = <0x00a00400 0x100>; 257 reg = <0x00a00400 0x100>;
466 interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; 258 interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
467 clocks = <&usb_mod_clk 1>, <&usb_mod_clk 2>; 259 clocks = <&usb_clocks CLK_BUS_HCI0>,
468 resets = <&usb_mod_clk 17>; 260 <&usb_clocks CLK_USB_OHCI0>;
261 resets = <&usb_clocks RST_USB0_HCI>;
469 phys = <&usbphy1>; 262 phys = <&usbphy1>;
470 phy-names = "usb"; 263 phy-names = "usb";
471 status = "disabled"; 264 status = "disabled";
@@ -474,9 +267,9 @@
474 usbphy1: phy@00a00800 { 267 usbphy1: phy@00a00800 {
475 compatible = "allwinner,sun9i-a80-usb-phy"; 268 compatible = "allwinner,sun9i-a80-usb-phy";
476 reg = <0x00a00800 0x4>; 269 reg = <0x00a00800 0x4>;
477 clocks = <&usb_phy_clk 1>; 270 clocks = <&usb_clocks CLK_USB0_PHY>;
478 clock-names = "phy"; 271 clock-names = "phy";
479 resets = <&usb_phy_clk 17>; 272 resets = <&usb_clocks RST_USB0_PHY>;
480 reset-names = "phy"; 273 reset-names = "phy";
481 status = "disabled"; 274 status = "disabled";
482 #phy-cells = <0>; 275 #phy-cells = <0>;
@@ -486,8 +279,8 @@
486 compatible = "allwinner,sun9i-a80-ehci", "generic-ehci"; 279 compatible = "allwinner,sun9i-a80-ehci", "generic-ehci";
487 reg = <0x00a01000 0x100>; 280 reg = <0x00a01000 0x100>;
488 interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; 281 interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
489 clocks = <&usb_mod_clk 3>; 282 clocks = <&usb_clocks CLK_BUS_HCI1>;
490 resets = <&usb_mod_clk 18>; 283 resets = <&usb_clocks RST_USB1_HCI>;
491 phys = <&usbphy2>; 284 phys = <&usbphy2>;
492 phy-names = "usb"; 285 phy-names = "usb";
493 status = "disabled"; 286 status = "disabled";
@@ -496,11 +289,16 @@
496 usbphy2: phy@00a01800 { 289 usbphy2: phy@00a01800 {
497 compatible = "allwinner,sun9i-a80-usb-phy"; 290 compatible = "allwinner,sun9i-a80-usb-phy";
498 reg = <0x00a01800 0x4>; 291 reg = <0x00a01800 0x4>;
499 clocks = <&usb_phy_clk 2>, <&usb_phy_clk 10>, 292 clocks = <&usb_clocks CLK_USB1_HSIC>,
500 <&usb_phy_clk 3>; 293 <&usb_clocks CLK_USB_HSIC>,
501 clock-names = "hsic_480M", "hsic_12M", "phy"; 294 <&usb_clocks CLK_USB1_PHY>;
502 resets = <&usb_phy_clk 18>, <&usb_phy_clk 19>; 295 clock-names = "hsic_480M",
503 reset-names = "hsic", "phy"; 296 "hsic_12M",
297 "phy";
298 resets = <&usb_clocks RST_USB1_HSIC>,
299 <&usb_clocks RST_USB1_PHY>;
300 reset-names = "hsic",
301 "phy";
504 status = "disabled"; 302 status = "disabled";
505 #phy-cells = <0>; 303 #phy-cells = <0>;
506 /* usb1 is always used with HSIC */ 304 /* usb1 is always used with HSIC */
@@ -511,8 +309,8 @@
511 compatible = "allwinner,sun9i-a80-ehci", "generic-ehci"; 309 compatible = "allwinner,sun9i-a80-ehci", "generic-ehci";
512 reg = <0x00a02000 0x100>; 310 reg = <0x00a02000 0x100>;
513 interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; 311 interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
514 clocks = <&usb_mod_clk 5>; 312 clocks = <&usb_clocks CLK_BUS_HCI2>;
515 resets = <&usb_mod_clk 19>; 313 resets = <&usb_clocks RST_USB2_HCI>;
516 phys = <&usbphy3>; 314 phys = <&usbphy3>;
517 phy-names = "usb"; 315 phy-names = "usb";
518 status = "disabled"; 316 status = "disabled";
@@ -522,8 +320,9 @@
522 compatible = "allwinner,sun9i-a80-ohci", "generic-ohci"; 320 compatible = "allwinner,sun9i-a80-ohci", "generic-ohci";
523 reg = <0x00a02400 0x100>; 321 reg = <0x00a02400 0x100>;
524 interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; 322 interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
525 clocks = <&usb_mod_clk 5>, <&usb_mod_clk 6>; 323 clocks = <&usb_clocks CLK_BUS_HCI2>,
526 resets = <&usb_mod_clk 19>; 324 <&usb_clocks CLK_USB_OHCI2>;
325 resets = <&usb_clocks RST_USB2_HCI>;
527 phys = <&usbphy3>; 326 phys = <&usbphy3>;
528 phy-names = "usb"; 327 phy-names = "usb";
529 status = "disabled"; 328 status = "disabled";
@@ -532,20 +331,35 @@
532 usbphy3: phy@00a02800 { 331 usbphy3: phy@00a02800 {
533 compatible = "allwinner,sun9i-a80-usb-phy"; 332 compatible = "allwinner,sun9i-a80-usb-phy";
534 reg = <0x00a02800 0x4>; 333 reg = <0x00a02800 0x4>;
535 clocks = <&usb_phy_clk 4>, <&usb_phy_clk 10>, 334 clocks = <&usb_clocks CLK_USB2_HSIC>,
536 <&usb_phy_clk 5>; 335 <&usb_clocks CLK_USB_HSIC>,
537 clock-names = "hsic_480M", "hsic_12M", "phy"; 336 <&usb_clocks CLK_USB2_PHY>;
538 resets = <&usb_phy_clk 20>, <&usb_phy_clk 21>; 337 clock-names = "hsic_480M",
539 reset-names = "hsic", "phy"; 338 "hsic_12M",
339 "phy";
340 resets = <&usb_clocks RST_USB2_HSIC>,
341 <&usb_clocks RST_USB2_PHY>;
342 reset-names = "hsic",
343 "phy";
540 status = "disabled"; 344 status = "disabled";
541 #phy-cells = <0>; 345 #phy-cells = <0>;
542 }; 346 };
543 347
348 usb_clocks: clock@00a08000 {
349 compatible = "allwinner,sun9i-a80-usb-clks";
350 reg = <0x00a08000 0x8>;
351 clocks = <&ccu CLK_BUS_USB>, <&osc24M>;
352 clock-names = "bus", "hosc";
353 #clock-cells = <1>;
354 #reset-cells = <1>;
355 };
356
544 mmc0: mmc@01c0f000 { 357 mmc0: mmc@01c0f000 {
545 compatible = "allwinner,sun9i-a80-mmc"; 358 compatible = "allwinner,sun9i-a80-mmc";
546 reg = <0x01c0f000 0x1000>; 359 reg = <0x01c0f000 0x1000>;
547 clocks = <&mmc_config_clk 0>, <&mmc0_clk 0>, 360 clocks = <&mmc_config_clk 0>, <&ccu CLK_MMC0>,
548 <&mmc0_clk 1>, <&mmc0_clk 2>; 361 <&ccu CLK_MMC0_OUTPUT>,
362 <&ccu CLK_MMC0_SAMPLE>;
549 clock-names = "ahb", "mmc", "output", "sample"; 363 clock-names = "ahb", "mmc", "output", "sample";
550 resets = <&mmc_config_clk 0>; 364 resets = <&mmc_config_clk 0>;
551 reset-names = "ahb"; 365 reset-names = "ahb";
@@ -558,8 +372,9 @@
558 mmc1: mmc@01c10000 { 372 mmc1: mmc@01c10000 {
559 compatible = "allwinner,sun9i-a80-mmc"; 373 compatible = "allwinner,sun9i-a80-mmc";
560 reg = <0x01c10000 0x1000>; 374 reg = <0x01c10000 0x1000>;
561 clocks = <&mmc_config_clk 1>, <&mmc1_clk 0>, 375 clocks = <&mmc_config_clk 1>, <&ccu CLK_MMC1>,
562 <&mmc1_clk 1>, <&mmc1_clk 2>; 376 <&ccu CLK_MMC1_OUTPUT>,
377 <&ccu CLK_MMC1_SAMPLE>;
563 clock-names = "ahb", "mmc", "output", "sample"; 378 clock-names = "ahb", "mmc", "output", "sample";
564 resets = <&mmc_config_clk 1>; 379 resets = <&mmc_config_clk 1>;
565 reset-names = "ahb"; 380 reset-names = "ahb";
@@ -572,8 +387,9 @@
572 mmc2: mmc@01c11000 { 387 mmc2: mmc@01c11000 {
573 compatible = "allwinner,sun9i-a80-mmc"; 388 compatible = "allwinner,sun9i-a80-mmc";
574 reg = <0x01c11000 0x1000>; 389 reg = <0x01c11000 0x1000>;
575 clocks = <&mmc_config_clk 2>, <&mmc2_clk 0>, 390 clocks = <&mmc_config_clk 2>, <&ccu CLK_MMC2>,
576 <&mmc2_clk 1>, <&mmc2_clk 2>; 391 <&ccu CLK_MMC2_OUTPUT>,
392 <&ccu CLK_MMC2_SAMPLE>;
577 clock-names = "ahb", "mmc", "output", "sample"; 393 clock-names = "ahb", "mmc", "output", "sample";
578 resets = <&mmc_config_clk 2>; 394 resets = <&mmc_config_clk 2>;
579 reset-names = "ahb"; 395 reset-names = "ahb";
@@ -586,8 +402,9 @@
586 mmc3: mmc@01c12000 { 402 mmc3: mmc@01c12000 {
587 compatible = "allwinner,sun9i-a80-mmc"; 403 compatible = "allwinner,sun9i-a80-mmc";
588 reg = <0x01c12000 0x1000>; 404 reg = <0x01c12000 0x1000>;
589 clocks = <&mmc_config_clk 3>, <&mmc3_clk 0>, 405 clocks = <&mmc_config_clk 3>, <&ccu CLK_MMC3>,
590 <&mmc3_clk 1>, <&mmc3_clk 2>; 406 <&ccu CLK_MMC3_OUTPUT>,
407 <&ccu CLK_MMC3_SAMPLE>;
591 clock-names = "ahb", "mmc", "output", "sample"; 408 clock-names = "ahb", "mmc", "output", "sample";
592 resets = <&mmc_config_clk 3>; 409 resets = <&mmc_config_clk 3>;
593 reset-names = "ahb"; 410 reset-names = "ahb";
@@ -600,9 +417,9 @@
600 mmc_config_clk: clk@01c13000 { 417 mmc_config_clk: clk@01c13000 {
601 compatible = "allwinner,sun9i-a80-mmc-config-clk"; 418 compatible = "allwinner,sun9i-a80-mmc-config-clk";
602 reg = <0x01c13000 0x10>; 419 reg = <0x01c13000 0x10>;
603 clocks = <&ahb0_gates 8>; 420 clocks = <&ccu CLK_BUS_MMC>;
604 clock-names = "ahb"; 421 clock-names = "ahb";
605 resets = <&ahb0_resets 8>; 422 resets = <&ccu RST_BUS_MMC>;
606 reset-names = "ahb"; 423 reset-names = "ahb";
607 #clock-cells = <1>; 424 #clock-cells = <1>;
608 #reset-cells = <1>; 425 #reset-cells = <1>;
@@ -621,34 +438,27 @@
621 interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; 438 interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
622 }; 439 };
623 440
624 ahb0_resets: reset@060005a0 { 441 de_clocks: clock@03000000 {
625 #reset-cells = <1>; 442 compatible = "allwinner,sun9i-a80-de-clks";
626 compatible = "allwinner,sun6i-a31-clock-reset"; 443 reg = <0x03000000 0x30>;
627 reg = <0x060005a0 0x4>; 444 clocks = <&ccu CLK_DE>,
628 }; 445 <&ccu CLK_SDRAM>,
629 446 <&ccu CLK_BUS_DE>;
630 ahb1_resets: reset@060005a4 { 447 clock-names = "mod",
631 #reset-cells = <1>; 448 "dram",
632 compatible = "allwinner,sun6i-a31-clock-reset"; 449 "bus";
633 reg = <0x060005a4 0x4>; 450 resets = <&ccu RST_BUS_DE>;
634 }; 451 #clock-cells = <1>;
635
636 ahb2_resets: reset@060005a8 {
637 #reset-cells = <1>;
638 compatible = "allwinner,sun6i-a31-clock-reset";
639 reg = <0x060005a8 0x4>;
640 };
641
642 apb0_resets: reset@060005b0 {
643 #reset-cells = <1>; 452 #reset-cells = <1>;
644 compatible = "allwinner,sun6i-a31-clock-reset";
645 reg = <0x060005b0 0x4>;
646 }; 453 };
647 454
648 apb1_resets: reset@060005b4 { 455 ccu: clock@06000000 {
456 compatible = "allwinner,sun9i-a80-ccu";
457 reg = <0x06000000 0x800>;
458 clocks = <&osc24M>, <&osc32k>;
459 clock-names = "hosc", "losc";
460 #clock-cells = <1>;
649 #reset-cells = <1>; 461 #reset-cells = <1>;
650 compatible = "allwinner,sun6i-a31-clock-reset";
651 reg = <0x060005b4 0x4>;
652 }; 462 };
653 463
654 timer@06000c00 { 464 timer@06000c00 {
@@ -678,7 +488,7 @@
678 <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>, 488 <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
679 <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>, 489 <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
680 <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; 490 <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
681 clocks = <&apb0_gates 5>, <&osc24M>, <&osc32k>; 491 clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
682 clock-names = "apb", "hosc", "losc"; 492 clock-names = "apb", "hosc", "losc";
683 gpio-controller; 493 gpio-controller;
684 interrupt-controller; 494 interrupt-controller;
@@ -734,8 +544,8 @@
734 interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; 544 interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
735 reg-shift = <2>; 545 reg-shift = <2>;
736 reg-io-width = <4>; 546 reg-io-width = <4>;
737 clocks = <&apb1_gates 16>; 547 clocks = <&ccu CLK_BUS_UART0>;
738 resets = <&apb1_resets 16>; 548 resets = <&ccu RST_BUS_UART0>;
739 status = "disabled"; 549 status = "disabled";
740 }; 550 };
741 551
@@ -745,8 +555,8 @@
745 interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>; 555 interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
746 reg-shift = <2>; 556 reg-shift = <2>;
747 reg-io-width = <4>; 557 reg-io-width = <4>;
748 clocks = <&apb1_gates 17>; 558 clocks = <&ccu CLK_BUS_UART1>;
749 resets = <&apb1_resets 17>; 559 resets = <&ccu RST_BUS_UART1>;
750 status = "disabled"; 560 status = "disabled";
751 }; 561 };
752 562
@@ -756,8 +566,8 @@
756 interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; 566 interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
757 reg-shift = <2>; 567 reg-shift = <2>;
758 reg-io-width = <4>; 568 reg-io-width = <4>;
759 clocks = <&apb1_gates 18>; 569 clocks = <&ccu CLK_BUS_UART2>;
760 resets = <&apb1_resets 18>; 570 resets = <&ccu RST_BUS_UART2>;
761 status = "disabled"; 571 status = "disabled";
762 }; 572 };
763 573
@@ -767,8 +577,8 @@
767 interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; 577 interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
768 reg-shift = <2>; 578 reg-shift = <2>;
769 reg-io-width = <4>; 579 reg-io-width = <4>;
770 clocks = <&apb1_gates 19>; 580 clocks = <&ccu CLK_BUS_UART3>;
771 resets = <&apb1_resets 19>; 581 resets = <&ccu RST_BUS_UART3>;
772 status = "disabled"; 582 status = "disabled";
773 }; 583 };
774 584
@@ -778,8 +588,8 @@
778 interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; 588 interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
779 reg-shift = <2>; 589 reg-shift = <2>;
780 reg-io-width = <4>; 590 reg-io-width = <4>;
781 clocks = <&apb1_gates 20>; 591 clocks = <&ccu CLK_BUS_UART4>;
782 resets = <&apb1_resets 20>; 592 resets = <&ccu RST_BUS_UART4>;
783 status = "disabled"; 593 status = "disabled";
784 }; 594 };
785 595
@@ -789,8 +599,8 @@
789 interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; 599 interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
790 reg-shift = <2>; 600 reg-shift = <2>;
791 reg-io-width = <4>; 601 reg-io-width = <4>;
792 clocks = <&apb1_gates 21>; 602 clocks = <&ccu CLK_BUS_UART5>;
793 resets = <&apb1_resets 21>; 603 resets = <&ccu RST_BUS_UART5>;
794 status = "disabled"; 604 status = "disabled";
795 }; 605 };
796 606
@@ -798,8 +608,8 @@
798 compatible = "allwinner,sun6i-a31-i2c"; 608 compatible = "allwinner,sun6i-a31-i2c";
799 reg = <0x07002800 0x400>; 609 reg = <0x07002800 0x400>;
800 interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; 610 interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
801 clocks = <&apb1_gates 0>; 611 clocks = <&ccu CLK_BUS_I2C0>;
802 resets = <&apb1_resets 0>; 612 resets = <&ccu RST_BUS_I2C0>;
803 status = "disabled"; 613 status = "disabled";
804 #address-cells = <1>; 614 #address-cells = <1>;
805 #size-cells = <0>; 615 #size-cells = <0>;
@@ -809,8 +619,8 @@
809 compatible = "allwinner,sun6i-a31-i2c"; 619 compatible = "allwinner,sun6i-a31-i2c";
810 reg = <0x07002c00 0x400>; 620 reg = <0x07002c00 0x400>;
811 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; 621 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
812 clocks = <&apb1_gates 1>; 622 clocks = <&ccu CLK_BUS_I2C1>;
813 resets = <&apb1_resets 1>; 623 resets = <&ccu RST_BUS_I2C1>;
814 status = "disabled"; 624 status = "disabled";
815 #address-cells = <1>; 625 #address-cells = <1>;
816 #size-cells = <0>; 626 #size-cells = <0>;
@@ -820,8 +630,8 @@
820 compatible = "allwinner,sun6i-a31-i2c"; 630 compatible = "allwinner,sun6i-a31-i2c";
821 reg = <0x07003000 0x400>; 631 reg = <0x07003000 0x400>;
822 interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; 632 interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
823 clocks = <&apb1_gates 2>; 633 clocks = <&ccu CLK_BUS_I2C2>;
824 resets = <&apb1_resets 2>; 634 resets = <&ccu RST_BUS_I2C2>;
825 status = "disabled"; 635 status = "disabled";
826 #address-cells = <1>; 636 #address-cells = <1>;
827 #size-cells = <0>; 637 #size-cells = <0>;
@@ -831,8 +641,8 @@
831 compatible = "allwinner,sun6i-a31-i2c"; 641 compatible = "allwinner,sun6i-a31-i2c";
832 reg = <0x07003400 0x400>; 642 reg = <0x07003400 0x400>;
833 interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; 643 interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
834 clocks = <&apb1_gates 3>; 644 clocks = <&ccu CLK_BUS_I2C3>;
835 resets = <&apb1_resets 3>; 645 resets = <&ccu RST_BUS_I2C3>;
836 status = "disabled"; 646 status = "disabled";
837 #address-cells = <1>; 647 #address-cells = <1>;
838 #size-cells = <0>; 648 #size-cells = <0>;
@@ -842,8 +652,8 @@
842 compatible = "allwinner,sun6i-a31-i2c"; 652 compatible = "allwinner,sun6i-a31-i2c";
843 reg = <0x07003800 0x400>; 653 reg = <0x07003800 0x400>;
844 interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; 654 interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
845 clocks = <&apb1_gates 4>; 655 clocks = <&ccu CLK_BUS_I2C4>;
846 resets = <&apb1_resets 4>; 656 resets = <&ccu RST_BUS_I2C4>;
847 status = "disabled"; 657 status = "disabled";
848 #address-cells = <1>; 658 #address-cells = <1>;
849 #size-cells = <0>; 659 #size-cells = <0>;
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 33007aa74111..cc98d5a294ee 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2787,10 +2787,6 @@ config X86_DMA_REMAP
2787 bool 2787 bool
2788 depends on STA2X11 2788 depends on STA2X11
2789 2789
2790config PMC_ATOM
2791 def_bool y
2792 depends on PCI
2793
2794source "net/Kconfig" 2790source "net/Kconfig"
2795 2791
2796source "drivers/Kconfig" 2792source "drivers/Kconfig"
diff --git a/arch/x86/platform/atom/Makefile b/arch/x86/platform/atom/Makefile
index 40983f5b0858..57be88fa34bb 100644
--- a/arch/x86/platform/atom/Makefile
+++ b/arch/x86/platform/atom/Makefile
@@ -1,2 +1 @@
1obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
2obj-$(CONFIG_PUNIT_ATOM_DEBUG) += punit_atom_debug.o obj-$(CONFIG_PUNIT_ATOM_DEBUG) += punit_atom_debug.o
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 8ea836c046f8..90d112a3063a 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -18,6 +18,7 @@
18#include <linux/mutex.h> 18#include <linux/mutex.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/platform_data/clk-lpss.h> 20#include <linux/platform_data/clk-lpss.h>
21#include <linux/platform_data/x86/pmc_atom.h>
21#include <linux/pm_domain.h> 22#include <linux/pm_domain.h>
22#include <linux/pm_runtime.h> 23#include <linux/pm_runtime.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
@@ -31,7 +32,6 @@ ACPI_MODULE_NAME("acpi_lpss");
31#include <asm/cpu_device_id.h> 32#include <asm/cpu_device_id.h>
32#include <asm/intel-family.h> 33#include <asm/intel-family.h>
33#include <asm/iosf_mbi.h> 34#include <asm/iosf_mbi.h>
34#include <asm/pmc_atom.h>
35 35
36#define LPSS_ADDR(desc) ((unsigned long)&desc) 36#define LPSS_ADDR(desc) ((unsigned long)&desc)
37 37
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 56c1998ced3e..9356ab4b7d76 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -95,16 +95,17 @@ config COMMON_CLK_CDCE706
95 This driver supports TI CDCE706 programmable 3-PLL clock synthesizer. 95 This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
96 96
97config COMMON_CLK_CDCE925 97config COMMON_CLK_CDCE925
98 tristate "Clock driver for TI CDCE925 devices" 98 tristate "Clock driver for TI CDCE913/925/937/949 devices"
99 depends on I2C 99 depends on I2C
100 depends on OF 100 depends on OF
101 select REGMAP_I2C 101 select REGMAP_I2C
102 help 102 help
103 ---help--- 103 ---help---
104 This driver supports the TI CDCE925 programmable clock synthesizer. 104 This driver supports the TI CDCE913/925/937/949 programmable clock
105 The chip contains two PLLs with spread-spectrum clocking support and 105 synthesizer. Each chip has different number of PLLs and outputs.
106 five output dividers. The driver only supports the following setup, 106 For example, the CDCE925 contains two PLLs with spread-spectrum
107 and uses a fixed setting for the output muxes. 107 clocking support and five output dividers. The driver only supports
108 the following setup, and uses a fixed setting for the output muxes.
108 Y1 is derived from the input clock 109 Y1 is derived from the input clock
109 Y2 and Y3 derive from PLL1 110 Y2 and Y3 derive from PLL1
110 Y4 and Y5 derive from PLL2 111 Y4 and Y5 derive from PLL2
@@ -198,6 +199,16 @@ config COMMON_CLK_OXNAS
198 ---help--- 199 ---help---
199 Support for the OXNAS SoC Family clocks. 200 Support for the OXNAS SoC Family clocks.
200 201
202config COMMON_CLK_VC5
203 tristate "Clock driver for IDT VersaClock5 devices"
204 depends on I2C
205 depends on OF
206 select REGMAP_I2C
207 help
208 ---help---
209 This driver supports the IDT VersaClock5 programmable clock
210 generator.
211
201source "drivers/clk/bcm/Kconfig" 212source "drivers/clk/bcm/Kconfig"
202source "drivers/clk/hisilicon/Kconfig" 213source "drivers/clk/hisilicon/Kconfig"
203source "drivers/clk/mediatek/Kconfig" 214source "drivers/clk/mediatek/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 925081ec14c0..92c12b86c2e8 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o
46obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o 46obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
47obj-$(CONFIG_ARCH_U300) += clk-u300.o 47obj-$(CONFIG_ARCH_U300) += clk-u300.o
48obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o 48obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
49obj-$(CONFIG_COMMON_CLK_VC5) += clk-versaclock5.o
49obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o 50obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
50obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o 51obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
51 52
@@ -87,6 +88,8 @@ obj-y += ti/
87obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ 88obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
88obj-$(CONFIG_ARCH_U8500) += ux500/ 89obj-$(CONFIG_ARCH_U8500) += ux500/
89obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ 90obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
91ifeq ($(CONFIG_COMMON_CLK), y)
90obj-$(CONFIG_X86) += x86/ 92obj-$(CONFIG_X86) += x86/
93endif
91obj-$(CONFIG_ARCH_ZX) += zte/ 94obj-$(CONFIG_ARCH_ZX) += zte/
92obj-$(CONFIG_ARCH_ZYNQ) += zynq/ 95obj-$(CONFIG_ARCH_ZYNQ) += zynq/
diff --git a/drivers/clk/axs10x/i2s_pll_clock.c b/drivers/clk/axs10x/i2s_pll_clock.c
index 411310d29581..02d3bcd6216c 100644
--- a/drivers/clk/axs10x/i2s_pll_clock.c
+++ b/drivers/clk/axs10x/i2s_pll_clock.c
@@ -182,6 +182,7 @@ static int i2s_pll_clk_probe(struct platform_device *pdev)
182 if (IS_ERR(pll_clk->base)) 182 if (IS_ERR(pll_clk->base))
183 return PTR_ERR(pll_clk->base); 183 return PTR_ERR(pll_clk->base);
184 184
185 memset(&init, 0, sizeof(init));
185 clk_name = node->name; 186 clk_name = node->name;
186 init.name = clk_name; 187 init.name = clk_name;
187 init.ops = &i2s_pll_ops; 188 init.ops = &i2s_pll_ops;
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 0d14409097e7..025853870619 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -39,6 +39,7 @@
39#include <linux/clk.h> 39#include <linux/clk.h>
40#include <linux/clk/bcm2835.h> 40#include <linux/clk/bcm2835.h>
41#include <linux/debugfs.h> 41#include <linux/debugfs.h>
42#include <linux/delay.h>
42#include <linux/module.h> 43#include <linux/module.h>
43#include <linux/of.h> 44#include <linux/of.h>
44#include <linux/platform_device.h> 45#include <linux/platform_device.h>
@@ -98,7 +99,8 @@
98#define CM_SMIDIV 0x0b4 99#define CM_SMIDIV 0x0b4
99/* no definition for 0x0b8 and 0x0bc */ 100/* no definition for 0x0b8 and 0x0bc */
100#define CM_TCNTCTL 0x0c0 101#define CM_TCNTCTL 0x0c0
101#define CM_TCNTDIV 0x0c4 102# define CM_TCNT_SRC1_SHIFT 12
103#define CM_TCNTCNT 0x0c4
102#define CM_TECCTL 0x0c8 104#define CM_TECCTL 0x0c8
103#define CM_TECDIV 0x0cc 105#define CM_TECDIV 0x0cc
104#define CM_TD0CTL 0x0d0 106#define CM_TD0CTL 0x0d0
@@ -297,11 +299,32 @@
297#define LOCK_TIMEOUT_NS 100000000 299#define LOCK_TIMEOUT_NS 100000000
298#define BCM2835_MAX_FB_RATE 1750000000u 300#define BCM2835_MAX_FB_RATE 1750000000u
299 301
302/*
303 * Names of clocks used within the driver that need to be replaced
304 * with an external parent's name. This array is in the order that
305 * the clocks node in the DT references external clocks.
306 */
307static const char *const cprman_parent_names[] = {
308 "xosc",
309 "dsi0_byte",
310 "dsi0_ddr2",
311 "dsi0_ddr",
312 "dsi1_byte",
313 "dsi1_ddr2",
314 "dsi1_ddr",
315};
316
300struct bcm2835_cprman { 317struct bcm2835_cprman {
301 struct device *dev; 318 struct device *dev;
302 void __iomem *regs; 319 void __iomem *regs;
303 spinlock_t regs_lock; /* spinlock for all clocks */ 320 spinlock_t regs_lock; /* spinlock for all clocks */
304 const char *osc_name; 321
322 /*
323 * Real names of cprman clock parents looked up through
324 * of_clk_get_parent_name(), which will be used in the
325 * parent_names[] arrays for clock registration.
326 */
327 const char *real_parent_names[ARRAY_SIZE(cprman_parent_names)];
305 328
306 /* Must be last */ 329 /* Must be last */
307 struct clk_hw_onecell_data onecell; 330 struct clk_hw_onecell_data onecell;
@@ -317,6 +340,61 @@ static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg)
317 return readl(cprman->regs + reg); 340 return readl(cprman->regs + reg);
318} 341}
319 342
343/* Does a cycle of measuring a clock through the TCNT clock, which may
344 * source from many other clocks in the system.
345 */
346static unsigned long bcm2835_measure_tcnt_mux(struct bcm2835_cprman *cprman,
347 u32 tcnt_mux)
348{
349 u32 osccount = 19200; /* 1ms */
350 u32 count;
351 ktime_t timeout;
352
353 spin_lock(&cprman->regs_lock);
354
355 cprman_write(cprman, CM_TCNTCTL, CM_KILL);
356
357 cprman_write(cprman, CM_TCNTCTL,
358 (tcnt_mux & CM_SRC_MASK) |
359 (tcnt_mux >> CM_SRC_BITS) << CM_TCNT_SRC1_SHIFT);
360
361 cprman_write(cprman, CM_OSCCOUNT, osccount);
362
363 /* do a kind delay at the start */
364 mdelay(1);
365
366 /* Finish off whatever is left of OSCCOUNT */
367 timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
368 while (cprman_read(cprman, CM_OSCCOUNT)) {
369 if (ktime_after(ktime_get(), timeout)) {
370 dev_err(cprman->dev, "timeout waiting for OSCCOUNT\n");
371 count = 0;
372 goto out;
373 }
374 cpu_relax();
375 }
376
377 /* Wait for BUSY to clear. */
378 timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
379 while (cprman_read(cprman, CM_TCNTCTL) & CM_BUSY) {
380 if (ktime_after(ktime_get(), timeout)) {
381 dev_err(cprman->dev, "timeout waiting for !BUSY\n");
382 count = 0;
383 goto out;
384 }
385 cpu_relax();
386 }
387
388 count = cprman_read(cprman, CM_TCNTCNT);
389
390 cprman_write(cprman, CM_TCNTCTL, 0);
391
392out:
393 spin_unlock(&cprman->regs_lock);
394
395 return count * 1000;
396}
397
320static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base, 398static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
321 struct debugfs_reg32 *regs, size_t nregs, 399 struct debugfs_reg32 *regs, size_t nregs,
322 struct dentry *dentry) 400 struct dentry *dentry)
@@ -428,6 +506,7 @@ struct bcm2835_pll_divider_data {
428 u32 load_mask; 506 u32 load_mask;
429 u32 hold_mask; 507 u32 hold_mask;
430 u32 fixed_divider; 508 u32 fixed_divider;
509 u32 flags;
431}; 510};
432 511
433struct bcm2835_clock_data { 512struct bcm2835_clock_data {
@@ -451,6 +530,8 @@ struct bcm2835_clock_data {
451 530
452 bool is_vpu_clock; 531 bool is_vpu_clock;
453 bool is_mash_clock; 532 bool is_mash_clock;
533
534 u32 tcnt_mux;
454}; 535};
455 536
456struct bcm2835_gate_data { 537struct bcm2835_gate_data {
@@ -906,6 +987,9 @@ static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
906 const struct bcm2835_clock_data *data = clock->data; 987 const struct bcm2835_clock_data *data = clock->data;
907 u64 temp; 988 u64 temp;
908 989
990 if (data->int_bits == 0 && data->frac_bits == 0)
991 return parent_rate;
992
909 /* 993 /*
910 * The divisor is a 12.12 fixed point field, but only some of 994 * The divisor is a 12.12 fixed point field, but only some of
911 * the bits are populated in any given clock. 995 * the bits are populated in any given clock.
@@ -929,7 +1013,12 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw,
929 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); 1013 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
930 struct bcm2835_cprman *cprman = clock->cprman; 1014 struct bcm2835_cprman *cprman = clock->cprman;
931 const struct bcm2835_clock_data *data = clock->data; 1015 const struct bcm2835_clock_data *data = clock->data;
932 u32 div = cprman_read(cprman, data->div_reg); 1016 u32 div;
1017
1018 if (data->int_bits == 0 && data->frac_bits == 0)
1019 return parent_rate;
1020
1021 div = cprman_read(cprman, data->div_reg);
933 1022
934 return bcm2835_clock_rate_from_divisor(clock, parent_rate, div); 1023 return bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
935} 1024}
@@ -978,6 +1067,17 @@ static int bcm2835_clock_on(struct clk_hw *hw)
978 CM_GATE); 1067 CM_GATE);
979 spin_unlock(&cprman->regs_lock); 1068 spin_unlock(&cprman->regs_lock);
980 1069
1070 /* Debug code to measure the clock once it's turned on to see
1071 * if it's ticking at the rate we expect.
1072 */
1073 if (data->tcnt_mux && false) {
1074 dev_info(cprman->dev,
1075 "clk %s: rate %ld, measure %ld\n",
1076 data->name,
1077 clk_hw_get_rate(hw),
1078 bcm2835_measure_tcnt_mux(cprman, data->tcnt_mux));
1079 }
1080
981 return 0; 1081 return 0;
982} 1082}
983 1083
@@ -1208,7 +1308,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
1208 memset(&init, 0, sizeof(init)); 1308 memset(&init, 0, sizeof(init));
1209 1309
1210 /* All of the PLLs derive from the external oscillator. */ 1310 /* All of the PLLs derive from the external oscillator. */
1211 init.parent_names = &cprman->osc_name; 1311 init.parent_names = &cprman->real_parent_names[0];
1212 init.num_parents = 1; 1312 init.num_parents = 1;
1213 init.name = data->name; 1313 init.name = data->name;
1214 init.ops = &bcm2835_pll_clk_ops; 1314 init.ops = &bcm2835_pll_clk_ops;
@@ -1252,7 +1352,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
1252 init.num_parents = 1; 1352 init.num_parents = 1;
1253 init.name = divider_name; 1353 init.name = divider_name;
1254 init.ops = &bcm2835_pll_divider_clk_ops; 1354 init.ops = &bcm2835_pll_divider_clk_ops;
1255 init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED; 1355 init.flags = data->flags | CLK_IGNORE_UNUSED;
1256 1356
1257 divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL); 1357 divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL);
1258 if (!divider) 1358 if (!divider)
@@ -1294,18 +1394,22 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
1294 struct bcm2835_clock *clock; 1394 struct bcm2835_clock *clock;
1295 struct clk_init_data init; 1395 struct clk_init_data init;
1296 const char *parents[1 << CM_SRC_BITS]; 1396 const char *parents[1 << CM_SRC_BITS];
1297 size_t i; 1397 size_t i, j;
1298 int ret; 1398 int ret;
1299 1399
1300 /* 1400 /*
1301 * Replace our "xosc" references with the oscillator's 1401 * Replace our strings referencing parent clocks with the
1302 * actual name. 1402 * actual clock-output-name of the parent.
1303 */ 1403 */
1304 for (i = 0; i < data->num_mux_parents; i++) { 1404 for (i = 0; i < data->num_mux_parents; i++) {
1305 if (strcmp(data->parents[i], "xosc") == 0) 1405 parents[i] = data->parents[i];
1306 parents[i] = cprman->osc_name; 1406
1307 else 1407 for (j = 0; j < ARRAY_SIZE(cprman_parent_names); j++) {
1308 parents[i] = data->parents[i]; 1408 if (strcmp(parents[i], cprman_parent_names[j]) == 0) {
1409 parents[i] = cprman->real_parent_names[j];
1410 break;
1411 }
1412 }
1309 } 1413 }
1310 1414
1311 memset(&init, 0, sizeof(init)); 1415 memset(&init, 0, sizeof(init));
@@ -1432,6 +1536,47 @@ static const char *const bcm2835_clock_vpu_parents[] = {
1432 __VA_ARGS__) 1536 __VA_ARGS__)
1433 1537
1434/* 1538/*
1539 * DSI parent clocks. The DSI byte/DDR/DDR2 clocks come from the DSI
1540 * analog PHY. The _inv variants are generated internally to cprman,
1541 * but we don't use them so they aren't hooked up.
1542 */
1543static const char *const bcm2835_clock_dsi0_parents[] = {
1544 "gnd",
1545 "xosc",
1546 "testdebug0",
1547 "testdebug1",
1548 "dsi0_ddr",
1549 "dsi0_ddr_inv",
1550 "dsi0_ddr2",
1551 "dsi0_ddr2_inv",
1552 "dsi0_byte",
1553 "dsi0_byte_inv",
1554};
1555
1556static const char *const bcm2835_clock_dsi1_parents[] = {
1557 "gnd",
1558 "xosc",
1559 "testdebug0",
1560 "testdebug1",
1561 "dsi1_ddr",
1562 "dsi1_ddr_inv",
1563 "dsi1_ddr2",
1564 "dsi1_ddr2_inv",
1565 "dsi1_byte",
1566 "dsi1_byte_inv",
1567};
1568
1569#define REGISTER_DSI0_CLK(...) REGISTER_CLK( \
1570 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi0_parents), \
1571 .parents = bcm2835_clock_dsi0_parents, \
1572 __VA_ARGS__)
1573
1574#define REGISTER_DSI1_CLK(...) REGISTER_CLK( \
1575 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents), \
1576 .parents = bcm2835_clock_dsi1_parents, \
1577 __VA_ARGS__)
1578
1579/*
1435 * the real definition of all the pll, pll_dividers and clocks 1580 * the real definition of all the pll, pll_dividers and clocks
1436 * these make use of the above REGISTER_* macros 1581 * these make use of the above REGISTER_* macros
1437 */ 1582 */
@@ -1466,7 +1611,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1466 .a2w_reg = A2W_PLLA_CORE, 1611 .a2w_reg = A2W_PLLA_CORE,
1467 .load_mask = CM_PLLA_LOADCORE, 1612 .load_mask = CM_PLLA_LOADCORE,
1468 .hold_mask = CM_PLLA_HOLDCORE, 1613 .hold_mask = CM_PLLA_HOLDCORE,
1469 .fixed_divider = 1), 1614 .fixed_divider = 1,
1615 .flags = CLK_SET_RATE_PARENT),
1470 [BCM2835_PLLA_PER] = REGISTER_PLL_DIV( 1616 [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(
1471 .name = "plla_per", 1617 .name = "plla_per",
1472 .source_pll = "plla", 1618 .source_pll = "plla",
@@ -1474,7 +1620,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1474 .a2w_reg = A2W_PLLA_PER, 1620 .a2w_reg = A2W_PLLA_PER,
1475 .load_mask = CM_PLLA_LOADPER, 1621 .load_mask = CM_PLLA_LOADPER,
1476 .hold_mask = CM_PLLA_HOLDPER, 1622 .hold_mask = CM_PLLA_HOLDPER,
1477 .fixed_divider = 1), 1623 .fixed_divider = 1,
1624 .flags = CLK_SET_RATE_PARENT),
1478 [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV( 1625 [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV(
1479 .name = "plla_dsi0", 1626 .name = "plla_dsi0",
1480 .source_pll = "plla", 1627 .source_pll = "plla",
@@ -1490,7 +1637,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1490 .a2w_reg = A2W_PLLA_CCP2, 1637 .a2w_reg = A2W_PLLA_CCP2,
1491 .load_mask = CM_PLLA_LOADCCP2, 1638 .load_mask = CM_PLLA_LOADCCP2,
1492 .hold_mask = CM_PLLA_HOLDCCP2, 1639 .hold_mask = CM_PLLA_HOLDCCP2,
1493 .fixed_divider = 1), 1640 .fixed_divider = 1,
1641 .flags = CLK_SET_RATE_PARENT),
1494 1642
1495 /* PLLB is used for the ARM's clock. */ 1643 /* PLLB is used for the ARM's clock. */
1496 [BCM2835_PLLB] = REGISTER_PLL( 1644 [BCM2835_PLLB] = REGISTER_PLL(
@@ -1514,7 +1662,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1514 .a2w_reg = A2W_PLLB_ARM, 1662 .a2w_reg = A2W_PLLB_ARM,
1515 .load_mask = CM_PLLB_LOADARM, 1663 .load_mask = CM_PLLB_LOADARM,
1516 .hold_mask = CM_PLLB_HOLDARM, 1664 .hold_mask = CM_PLLB_HOLDARM,
1517 .fixed_divider = 1), 1665 .fixed_divider = 1,
1666 .flags = CLK_SET_RATE_PARENT),
1518 1667
1519 /* 1668 /*
1520 * PLLC is the core PLL, used to drive the core VPU clock. 1669 * PLLC is the core PLL, used to drive the core VPU clock.
@@ -1543,7 +1692,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1543 .a2w_reg = A2W_PLLC_CORE0, 1692 .a2w_reg = A2W_PLLC_CORE0,
1544 .load_mask = CM_PLLC_LOADCORE0, 1693 .load_mask = CM_PLLC_LOADCORE0,
1545 .hold_mask = CM_PLLC_HOLDCORE0, 1694 .hold_mask = CM_PLLC_HOLDCORE0,
1546 .fixed_divider = 1), 1695 .fixed_divider = 1,
1696 .flags = CLK_SET_RATE_PARENT),
1547 [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV( 1697 [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(
1548 .name = "pllc_core1", 1698 .name = "pllc_core1",
1549 .source_pll = "pllc", 1699 .source_pll = "pllc",
@@ -1551,7 +1701,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1551 .a2w_reg = A2W_PLLC_CORE1, 1701 .a2w_reg = A2W_PLLC_CORE1,
1552 .load_mask = CM_PLLC_LOADCORE1, 1702 .load_mask = CM_PLLC_LOADCORE1,
1553 .hold_mask = CM_PLLC_HOLDCORE1, 1703 .hold_mask = CM_PLLC_HOLDCORE1,
1554 .fixed_divider = 1), 1704 .fixed_divider = 1,
1705 .flags = CLK_SET_RATE_PARENT),
1555 [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV( 1706 [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(
1556 .name = "pllc_core2", 1707 .name = "pllc_core2",
1557 .source_pll = "pllc", 1708 .source_pll = "pllc",
@@ -1559,7 +1710,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1559 .a2w_reg = A2W_PLLC_CORE2, 1710 .a2w_reg = A2W_PLLC_CORE2,
1560 .load_mask = CM_PLLC_LOADCORE2, 1711 .load_mask = CM_PLLC_LOADCORE2,
1561 .hold_mask = CM_PLLC_HOLDCORE2, 1712 .hold_mask = CM_PLLC_HOLDCORE2,
1562 .fixed_divider = 1), 1713 .fixed_divider = 1,
1714 .flags = CLK_SET_RATE_PARENT),
1563 [BCM2835_PLLC_PER] = REGISTER_PLL_DIV( 1715 [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(
1564 .name = "pllc_per", 1716 .name = "pllc_per",
1565 .source_pll = "pllc", 1717 .source_pll = "pllc",
@@ -1567,7 +1719,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1567 .a2w_reg = A2W_PLLC_PER, 1719 .a2w_reg = A2W_PLLC_PER,
1568 .load_mask = CM_PLLC_LOADPER, 1720 .load_mask = CM_PLLC_LOADPER,
1569 .hold_mask = CM_PLLC_HOLDPER, 1721 .hold_mask = CM_PLLC_HOLDPER,
1570 .fixed_divider = 1), 1722 .fixed_divider = 1,
1723 .flags = CLK_SET_RATE_PARENT),
1571 1724
1572 /* 1725 /*
1573 * PLLD is the display PLL, used to drive DSI display panels. 1726 * PLLD is the display PLL, used to drive DSI display panels.
@@ -1596,7 +1749,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1596 .a2w_reg = A2W_PLLD_CORE, 1749 .a2w_reg = A2W_PLLD_CORE,
1597 .load_mask = CM_PLLD_LOADCORE, 1750 .load_mask = CM_PLLD_LOADCORE,
1598 .hold_mask = CM_PLLD_HOLDCORE, 1751 .hold_mask = CM_PLLD_HOLDCORE,
1599 .fixed_divider = 1), 1752 .fixed_divider = 1,
1753 .flags = CLK_SET_RATE_PARENT),
1600 [BCM2835_PLLD_PER] = REGISTER_PLL_DIV( 1754 [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(
1601 .name = "plld_per", 1755 .name = "plld_per",
1602 .source_pll = "plld", 1756 .source_pll = "plld",
@@ -1604,7 +1758,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1604 .a2w_reg = A2W_PLLD_PER, 1758 .a2w_reg = A2W_PLLD_PER,
1605 .load_mask = CM_PLLD_LOADPER, 1759 .load_mask = CM_PLLD_LOADPER,
1606 .hold_mask = CM_PLLD_HOLDPER, 1760 .hold_mask = CM_PLLD_HOLDPER,
1607 .fixed_divider = 1), 1761 .fixed_divider = 1,
1762 .flags = CLK_SET_RATE_PARENT),
1608 [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV( 1763 [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV(
1609 .name = "plld_dsi0", 1764 .name = "plld_dsi0",
1610 .source_pll = "plld", 1765 .source_pll = "plld",
@@ -1649,7 +1804,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1649 .a2w_reg = A2W_PLLH_RCAL, 1804 .a2w_reg = A2W_PLLH_RCAL,
1650 .load_mask = CM_PLLH_LOADRCAL, 1805 .load_mask = CM_PLLH_LOADRCAL,
1651 .hold_mask = 0, 1806 .hold_mask = 0,
1652 .fixed_divider = 10), 1807 .fixed_divider = 10,
1808 .flags = CLK_SET_RATE_PARENT),
1653 [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV( 1809 [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(
1654 .name = "pllh_aux", 1810 .name = "pllh_aux",
1655 .source_pll = "pllh", 1811 .source_pll = "pllh",
@@ -1657,7 +1813,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1657 .a2w_reg = A2W_PLLH_AUX, 1813 .a2w_reg = A2W_PLLH_AUX,
1658 .load_mask = CM_PLLH_LOADAUX, 1814 .load_mask = CM_PLLH_LOADAUX,
1659 .hold_mask = 0, 1815 .hold_mask = 0,
1660 .fixed_divider = 1), 1816 .fixed_divider = 1,
1817 .flags = CLK_SET_RATE_PARENT),
1661 [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV( 1818 [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(
1662 .name = "pllh_pix", 1819 .name = "pllh_pix",
1663 .source_pll = "pllh", 1820 .source_pll = "pllh",
@@ -1665,7 +1822,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1665 .a2w_reg = A2W_PLLH_PIX, 1822 .a2w_reg = A2W_PLLH_PIX,
1666 .load_mask = CM_PLLH_LOADPIX, 1823 .load_mask = CM_PLLH_LOADPIX,
1667 .hold_mask = 0, 1824 .hold_mask = 0,
1668 .fixed_divider = 10), 1825 .fixed_divider = 10,
1826 .flags = CLK_SET_RATE_PARENT),
1669 1827
1670 /* the clocks */ 1828 /* the clocks */
1671 1829
@@ -1677,7 +1835,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1677 .ctl_reg = CM_OTPCTL, 1835 .ctl_reg = CM_OTPCTL,
1678 .div_reg = CM_OTPDIV, 1836 .div_reg = CM_OTPDIV,
1679 .int_bits = 4, 1837 .int_bits = 4,
1680 .frac_bits = 0), 1838 .frac_bits = 0,
1839 .tcnt_mux = 6),
1681 /* 1840 /*
1682 * Used for a 1Mhz clock for the system clocksource, and also used 1841 * Used for a 1Mhz clock for the system clocksource, and also used
1683 * bythe watchdog timer and the camera pulse generator. 1842 * bythe watchdog timer and the camera pulse generator.
@@ -1711,13 +1870,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1711 .ctl_reg = CM_H264CTL, 1870 .ctl_reg = CM_H264CTL,
1712 .div_reg = CM_H264DIV, 1871 .div_reg = CM_H264DIV,
1713 .int_bits = 4, 1872 .int_bits = 4,
1714 .frac_bits = 8), 1873 .frac_bits = 8,
1874 .tcnt_mux = 1),
1715 [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK( 1875 [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK(
1716 .name = "isp", 1876 .name = "isp",
1717 .ctl_reg = CM_ISPCTL, 1877 .ctl_reg = CM_ISPCTL,
1718 .div_reg = CM_ISPDIV, 1878 .div_reg = CM_ISPDIV,
1719 .int_bits = 4, 1879 .int_bits = 4,
1720 .frac_bits = 8), 1880 .frac_bits = 8,
1881 .tcnt_mux = 2),
1721 1882
1722 /* 1883 /*
1723 * Secondary SDRAM clock. Used for low-voltage modes when the PLL 1884 * Secondary SDRAM clock. Used for low-voltage modes when the PLL
@@ -1728,13 +1889,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1728 .ctl_reg = CM_SDCCTL, 1889 .ctl_reg = CM_SDCCTL,
1729 .div_reg = CM_SDCDIV, 1890 .div_reg = CM_SDCDIV,
1730 .int_bits = 6, 1891 .int_bits = 6,
1731 .frac_bits = 0), 1892 .frac_bits = 0,
1893 .tcnt_mux = 3),
1732 [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK( 1894 [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK(
1733 .name = "v3d", 1895 .name = "v3d",
1734 .ctl_reg = CM_V3DCTL, 1896 .ctl_reg = CM_V3DCTL,
1735 .div_reg = CM_V3DDIV, 1897 .div_reg = CM_V3DDIV,
1736 .int_bits = 4, 1898 .int_bits = 4,
1737 .frac_bits = 8), 1899 .frac_bits = 8,
1900 .tcnt_mux = 4),
1738 /* 1901 /*
1739 * VPU clock. This doesn't have an enable bit, since it drives 1902 * VPU clock. This doesn't have an enable bit, since it drives
1740 * the bus for everything else, and is special so it doesn't need 1903 * the bus for everything else, and is special so it doesn't need
@@ -1748,7 +1911,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1748 .int_bits = 12, 1911 .int_bits = 12,
1749 .frac_bits = 8, 1912 .frac_bits = 8,
1750 .flags = CLK_IS_CRITICAL, 1913 .flags = CLK_IS_CRITICAL,
1751 .is_vpu_clock = true), 1914 .is_vpu_clock = true,
1915 .tcnt_mux = 5),
1752 1916
1753 /* clocks with per parent mux */ 1917 /* clocks with per parent mux */
1754 [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK( 1918 [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK(
@@ -1756,19 +1920,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1756 .ctl_reg = CM_AVEOCTL, 1920 .ctl_reg = CM_AVEOCTL,
1757 .div_reg = CM_AVEODIV, 1921 .div_reg = CM_AVEODIV,
1758 .int_bits = 4, 1922 .int_bits = 4,
1759 .frac_bits = 0), 1923 .frac_bits = 0,
1924 .tcnt_mux = 38),
1760 [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK( 1925 [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK(
1761 .name = "cam0", 1926 .name = "cam0",
1762 .ctl_reg = CM_CAM0CTL, 1927 .ctl_reg = CM_CAM0CTL,
1763 .div_reg = CM_CAM0DIV, 1928 .div_reg = CM_CAM0DIV,
1764 .int_bits = 4, 1929 .int_bits = 4,
1765 .frac_bits = 8), 1930 .frac_bits = 8,
1931 .tcnt_mux = 14),
1766 [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK( 1932 [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK(
1767 .name = "cam1", 1933 .name = "cam1",
1768 .ctl_reg = CM_CAM1CTL, 1934 .ctl_reg = CM_CAM1CTL,
1769 .div_reg = CM_CAM1DIV, 1935 .div_reg = CM_CAM1DIV,
1770 .int_bits = 4, 1936 .int_bits = 4,
1771 .frac_bits = 8), 1937 .frac_bits = 8,
1938 .tcnt_mux = 15),
1772 [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK( 1939 [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK(
1773 .name = "dft", 1940 .name = "dft",
1774 .ctl_reg = CM_DFTCTL, 1941 .ctl_reg = CM_DFTCTL,
@@ -1780,7 +1947,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1780 .ctl_reg = CM_DPICTL, 1947 .ctl_reg = CM_DPICTL,
1781 .div_reg = CM_DPIDIV, 1948 .div_reg = CM_DPIDIV,
1782 .int_bits = 4, 1949 .int_bits = 4,
1783 .frac_bits = 8), 1950 .frac_bits = 8,
1951 .tcnt_mux = 17),
1784 1952
1785 /* Arasan EMMC clock */ 1953 /* Arasan EMMC clock */
1786 [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK( 1954 [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK(
@@ -1788,7 +1956,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1788 .ctl_reg = CM_EMMCCTL, 1956 .ctl_reg = CM_EMMCCTL,
1789 .div_reg = CM_EMMCDIV, 1957 .div_reg = CM_EMMCDIV,
1790 .int_bits = 4, 1958 .int_bits = 4,
1791 .frac_bits = 8), 1959 .frac_bits = 8,
1960 .tcnt_mux = 39),
1792 1961
1793 /* General purpose (GPIO) clocks */ 1962 /* General purpose (GPIO) clocks */
1794 [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK( 1963 [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK(
@@ -1797,7 +1966,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1797 .div_reg = CM_GP0DIV, 1966 .div_reg = CM_GP0DIV,
1798 .int_bits = 12, 1967 .int_bits = 12,
1799 .frac_bits = 12, 1968 .frac_bits = 12,
1800 .is_mash_clock = true), 1969 .is_mash_clock = true,
1970 .tcnt_mux = 20),
1801 [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK( 1971 [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK(
1802 .name = "gp1", 1972 .name = "gp1",
1803 .ctl_reg = CM_GP1CTL, 1973 .ctl_reg = CM_GP1CTL,
@@ -1805,7 +1975,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1805 .int_bits = 12, 1975 .int_bits = 12,
1806 .frac_bits = 12, 1976 .frac_bits = 12,
1807 .flags = CLK_IS_CRITICAL, 1977 .flags = CLK_IS_CRITICAL,
1808 .is_mash_clock = true), 1978 .is_mash_clock = true,
1979 .tcnt_mux = 21),
1809 [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK( 1980 [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK(
1810 .name = "gp2", 1981 .name = "gp2",
1811 .ctl_reg = CM_GP2CTL, 1982 .ctl_reg = CM_GP2CTL,
@@ -1820,40 +1991,46 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1820 .ctl_reg = CM_HSMCTL, 1991 .ctl_reg = CM_HSMCTL,
1821 .div_reg = CM_HSMDIV, 1992 .div_reg = CM_HSMDIV,
1822 .int_bits = 4, 1993 .int_bits = 4,
1823 .frac_bits = 8), 1994 .frac_bits = 8,
1995 .tcnt_mux = 22),
1824 [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK( 1996 [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK(
1825 .name = "pcm", 1997 .name = "pcm",
1826 .ctl_reg = CM_PCMCTL, 1998 .ctl_reg = CM_PCMCTL,
1827 .div_reg = CM_PCMDIV, 1999 .div_reg = CM_PCMDIV,
1828 .int_bits = 12, 2000 .int_bits = 12,
1829 .frac_bits = 12, 2001 .frac_bits = 12,
1830 .is_mash_clock = true), 2002 .is_mash_clock = true,
2003 .tcnt_mux = 23),
1831 [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK( 2004 [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK(
1832 .name = "pwm", 2005 .name = "pwm",
1833 .ctl_reg = CM_PWMCTL, 2006 .ctl_reg = CM_PWMCTL,
1834 .div_reg = CM_PWMDIV, 2007 .div_reg = CM_PWMDIV,
1835 .int_bits = 12, 2008 .int_bits = 12,
1836 .frac_bits = 12, 2009 .frac_bits = 12,
1837 .is_mash_clock = true), 2010 .is_mash_clock = true,
2011 .tcnt_mux = 24),
1838 [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK( 2012 [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK(
1839 .name = "slim", 2013 .name = "slim",
1840 .ctl_reg = CM_SLIMCTL, 2014 .ctl_reg = CM_SLIMCTL,
1841 .div_reg = CM_SLIMDIV, 2015 .div_reg = CM_SLIMDIV,
1842 .int_bits = 12, 2016 .int_bits = 12,
1843 .frac_bits = 12, 2017 .frac_bits = 12,
1844 .is_mash_clock = true), 2018 .is_mash_clock = true,
2019 .tcnt_mux = 25),
1845 [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK( 2020 [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK(
1846 .name = "smi", 2021 .name = "smi",
1847 .ctl_reg = CM_SMICTL, 2022 .ctl_reg = CM_SMICTL,
1848 .div_reg = CM_SMIDIV, 2023 .div_reg = CM_SMIDIV,
1849 .int_bits = 4, 2024 .int_bits = 4,
1850 .frac_bits = 8), 2025 .frac_bits = 8,
2026 .tcnt_mux = 27),
1851 [BCM2835_CLOCK_UART] = REGISTER_PER_CLK( 2027 [BCM2835_CLOCK_UART] = REGISTER_PER_CLK(
1852 .name = "uart", 2028 .name = "uart",
1853 .ctl_reg = CM_UARTCTL, 2029 .ctl_reg = CM_UARTCTL,
1854 .div_reg = CM_UARTDIV, 2030 .div_reg = CM_UARTDIV,
1855 .int_bits = 10, 2031 .int_bits = 10,
1856 .frac_bits = 12), 2032 .frac_bits = 12,
2033 .tcnt_mux = 28),
1857 2034
1858 /* TV encoder clock. Only operating frequency is 108Mhz. */ 2035 /* TV encoder clock. Only operating frequency is 108Mhz. */
1859 [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( 2036 [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
@@ -1866,7 +2043,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1866 * Allow rate change propagation only on PLLH_AUX which is 2043 * Allow rate change propagation only on PLLH_AUX which is
1867 * assigned index 7 in the parent array. 2044 * assigned index 7 in the parent array.
1868 */ 2045 */
1869 .set_rate_parent = BIT(7)), 2046 .set_rate_parent = BIT(7),
2047 .tcnt_mux = 29),
1870 2048
1871 /* dsi clocks */ 2049 /* dsi clocks */
1872 [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK( 2050 [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK(
@@ -1874,13 +2052,29 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
1874 .ctl_reg = CM_DSI0ECTL, 2052 .ctl_reg = CM_DSI0ECTL,
1875 .div_reg = CM_DSI0EDIV, 2053 .div_reg = CM_DSI0EDIV,
1876 .int_bits = 4, 2054 .int_bits = 4,
1877 .frac_bits = 8), 2055 .frac_bits = 8,
2056 .tcnt_mux = 18),
1878 [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK( 2057 [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK(
1879 .name = "dsi1e", 2058 .name = "dsi1e",
1880 .ctl_reg = CM_DSI1ECTL, 2059 .ctl_reg = CM_DSI1ECTL,
1881 .div_reg = CM_DSI1EDIV, 2060 .div_reg = CM_DSI1EDIV,
1882 .int_bits = 4, 2061 .int_bits = 4,
1883 .frac_bits = 8), 2062 .frac_bits = 8,
2063 .tcnt_mux = 19),
2064 [BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK(
2065 .name = "dsi0p",
2066 .ctl_reg = CM_DSI0PCTL,
2067 .div_reg = CM_DSI0PDIV,
2068 .int_bits = 0,
2069 .frac_bits = 0,
2070 .tcnt_mux = 12),
2071 [BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK(
2072 .name = "dsi1p",
2073 .ctl_reg = CM_DSI1PCTL,
2074 .div_reg = CM_DSI1PDIV,
2075 .int_bits = 0,
2076 .frac_bits = 0,
2077 .tcnt_mux = 13),
1884 2078
1885 /* the gates */ 2079 /* the gates */
1886 2080
@@ -1939,8 +2133,19 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
1939 if (IS_ERR(cprman->regs)) 2133 if (IS_ERR(cprman->regs))
1940 return PTR_ERR(cprman->regs); 2134 return PTR_ERR(cprman->regs);
1941 2135
1942 cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0); 2136 memcpy(cprman->real_parent_names, cprman_parent_names,
1943 if (!cprman->osc_name) 2137 sizeof(cprman_parent_names));
2138 of_clk_parent_fill(dev->of_node, cprman->real_parent_names,
2139 ARRAY_SIZE(cprman_parent_names));
2140
2141 /*
2142 * Make sure the external oscillator has been registered.
2143 *
2144 * The other (DSI) clocks are not present on older device
2145 * trees, which we still need to support for backwards
2146 * compatibility.
2147 */
2148 if (!cprman->real_parent_names[0])
1944 return -ENODEV; 2149 return -ENODEV;
1945 2150
1946 platform_set_drvdata(pdev, cprman); 2151 platform_set_drvdata(pdev, cprman);
diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c
index f793b2d9238c..c933be01c7db 100644
--- a/drivers/clk/clk-cdce925.c
+++ b/drivers/clk/clk-cdce925.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Driver for TI Dual PLL CDCE925 clock synthesizer 2 * Driver for TI Multi PLL CDCE913/925/937/949 clock synthesizer
3 * 3 *
4 * This driver always connects the Y1 to the input clock, Y2/Y3 to PLL1 4 * This driver always connects the Y1 to the input clock, Y2/Y3 to PLL1,
5 * and Y4/Y5 to PLL2. PLL frequency is set on a first-come-first-serve 5 * Y4/Y5 to PLL2, and so on. PLL frequency is set on a first-come-first-serve
6 * basis. Clients can directly request any frequency that the chip can 6 * basis. Clients can directly request any frequency that the chip can
7 * deliver using the standard clk framework. In addition, the device can 7 * deliver using the standard clk framework. In addition, the device can
8 * be configured and activated via the devicetree. 8 * be configured and activated via the devicetree.
@@ -19,11 +19,32 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/gcd.h> 20#include <linux/gcd.h>
21 21
22/* The chip has 2 PLLs which can be routed through dividers to 5 outputs. 22/* Each chip has different number of PLLs and outputs, for example:
23 * The CECE925 has 2 PLLs which can be routed through dividers to 5 outputs.
23 * Model this as 2 PLL clocks which are parents to the outputs. 24 * Model this as 2 PLL clocks which are parents to the outputs.
24 */ 25 */
25#define NUMBER_OF_PLLS 2 26
26#define NUMBER_OF_OUTPUTS 5 27enum {
28 CDCE913,
29 CDCE925,
30 CDCE937,
31 CDCE949,
32};
33
34struct clk_cdce925_chip_info {
35 int num_plls;
36 int num_outputs;
37};
38
39static const struct clk_cdce925_chip_info clk_cdce925_chip_info_tbl[] = {
40 [CDCE913] = { .num_plls = 1, .num_outputs = 3 },
41 [CDCE925] = { .num_plls = 2, .num_outputs = 5 },
42 [CDCE937] = { .num_plls = 3, .num_outputs = 7 },
43 [CDCE949] = { .num_plls = 4, .num_outputs = 9 },
44};
45
46#define MAX_NUMBER_OF_PLLS 4
47#define MAX_NUMBER_OF_OUTPUTS 9
27 48
28#define CDCE925_REG_GLOBAL1 0x01 49#define CDCE925_REG_GLOBAL1 0x01
29#define CDCE925_REG_Y1SPIPDIVH 0x02 50#define CDCE925_REG_Y1SPIPDIVH 0x02
@@ -43,7 +64,7 @@ struct clk_cdce925_output {
43 struct clk_hw hw; 64 struct clk_hw hw;
44 struct clk_cdce925_chip *chip; 65 struct clk_cdce925_chip *chip;
45 u8 index; 66 u8 index;
46 u16 pdiv; /* 1..127 for Y2-Y5; 1..1023 for Y1 */ 67 u16 pdiv; /* 1..127 for Y2-Y9; 1..1023 for Y1 */
47}; 68};
48#define to_clk_cdce925_output(_hw) \ 69#define to_clk_cdce925_output(_hw) \
49 container_of(_hw, struct clk_cdce925_output, hw) 70 container_of(_hw, struct clk_cdce925_output, hw)
@@ -60,8 +81,9 @@ struct clk_cdce925_pll {
60struct clk_cdce925_chip { 81struct clk_cdce925_chip {
61 struct regmap *regmap; 82 struct regmap *regmap;
62 struct i2c_client *i2c_client; 83 struct i2c_client *i2c_client;
63 struct clk_cdce925_pll pll[NUMBER_OF_PLLS]; 84 const struct clk_cdce925_chip_info *chip_info;
64 struct clk_cdce925_output clk[NUMBER_OF_OUTPUTS]; 85 struct clk_cdce925_pll pll[MAX_NUMBER_OF_PLLS];
86 struct clk_cdce925_output clk[MAX_NUMBER_OF_OUTPUTS];
65}; 87};
66 88
67/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ 89/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
@@ -284,6 +306,18 @@ static void cdce925_clk_set_pdiv(struct clk_cdce925_output *data, u16 pdiv)
284 case 4: 306 case 4:
285 regmap_update_bits(data->chip->regmap, 0x27, 0x7F, pdiv); 307 regmap_update_bits(data->chip->regmap, 0x27, 0x7F, pdiv);
286 break; 308 break;
309 case 5:
310 regmap_update_bits(data->chip->regmap, 0x36, 0x7F, pdiv);
311 break;
312 case 6:
313 regmap_update_bits(data->chip->regmap, 0x37, 0x7F, pdiv);
314 break;
315 case 7:
316 regmap_update_bits(data->chip->regmap, 0x46, 0x7F, pdiv);
317 break;
318 case 8:
319 regmap_update_bits(data->chip->regmap, 0x47, 0x7F, pdiv);
320 break;
287 } 321 }
288} 322}
289 323
@@ -302,6 +336,14 @@ static void cdce925_clk_activate(struct clk_cdce925_output *data)
302 case 4: 336 case 4:
303 regmap_update_bits(data->chip->regmap, 0x24, 0x03, 0x03); 337 regmap_update_bits(data->chip->regmap, 0x24, 0x03, 0x03);
304 break; 338 break;
339 case 5:
340 case 6:
341 regmap_update_bits(data->chip->regmap, 0x34, 0x03, 0x03);
342 break;
343 case 7:
344 case 8:
345 regmap_update_bits(data->chip->regmap, 0x44, 0x03, 0x03);
346 break;
305 } 347 }
306} 348}
307 349
@@ -474,15 +516,6 @@ static const struct clk_ops cdce925_clk_y1_ops = {
474 .set_rate = cdce925_clk_y1_set_rate, 516 .set_rate = cdce925_clk_y1_set_rate,
475}; 517};
476 518
477
478static struct regmap_config cdce925_regmap_config = {
479 .name = "configuration0",
480 .reg_bits = 8,
481 .val_bits = 8,
482 .cache_type = REGCACHE_RBTREE,
483 .max_register = 0x2F,
484};
485
486#define CDCE925_I2C_COMMAND_BLOCK_TRANSFER 0x00 519#define CDCE925_I2C_COMMAND_BLOCK_TRANSFER 0x00
487#define CDCE925_I2C_COMMAND_BYTE_TRANSFER 0x80 520#define CDCE925_I2C_COMMAND_BYTE_TRANSFER 0x80
488 521
@@ -582,13 +615,19 @@ static int cdce925_probe(struct i2c_client *client,
582 struct clk_cdce925_chip *data; 615 struct clk_cdce925_chip *data;
583 struct device_node *node = client->dev.of_node; 616 struct device_node *node = client->dev.of_node;
584 const char *parent_name; 617 const char *parent_name;
585 const char *pll_clk_name[NUMBER_OF_PLLS] = {NULL,}; 618 const char *pll_clk_name[MAX_NUMBER_OF_PLLS] = {NULL,};
586 struct clk_init_data init; 619 struct clk_init_data init;
587 u32 value; 620 u32 value;
588 int i; 621 int i;
589 int err; 622 int err;
590 struct device_node *np_output; 623 struct device_node *np_output;
591 char child_name[6]; 624 char child_name[6];
625 struct regmap_config config = {
626 .name = "configuration0",
627 .reg_bits = 8,
628 .val_bits = 8,
629 .cache_type = REGCACHE_RBTREE,
630 };
592 631
593 dev_dbg(&client->dev, "%s\n", __func__); 632 dev_dbg(&client->dev, "%s\n", __func__);
594 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); 633 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
@@ -596,8 +635,11 @@ static int cdce925_probe(struct i2c_client *client,
596 return -ENOMEM; 635 return -ENOMEM;
597 636
598 data->i2c_client = client; 637 data->i2c_client = client;
638 data->chip_info = &clk_cdce925_chip_info_tbl[id->driver_data];
639 config.max_register = CDCE925_OFFSET_PLL +
640 data->chip_info->num_plls * 0x10 - 1;
599 data->regmap = devm_regmap_init(&client->dev, &regmap_cdce925_bus, 641 data->regmap = devm_regmap_init(&client->dev, &regmap_cdce925_bus,
600 &client->dev, &cdce925_regmap_config); 642 &client->dev, &config);
601 if (IS_ERR(data->regmap)) { 643 if (IS_ERR(data->regmap)) {
602 dev_err(&client->dev, "failed to allocate register map\n"); 644 dev_err(&client->dev, "failed to allocate register map\n");
603 return PTR_ERR(data->regmap); 645 return PTR_ERR(data->regmap);
@@ -626,7 +668,7 @@ static int cdce925_probe(struct i2c_client *client,
626 init.num_parents = parent_name ? 1 : 0; 668 init.num_parents = parent_name ? 1 : 0;
627 669
628 /* Register PLL clocks */ 670 /* Register PLL clocks */
629 for (i = 0; i < NUMBER_OF_PLLS; ++i) { 671 for (i = 0; i < data->chip_info->num_plls; ++i) {
630 pll_clk_name[i] = kasprintf(GFP_KERNEL, "%s.pll%d", 672 pll_clk_name[i] = kasprintf(GFP_KERNEL, "%s.pll%d",
631 client->dev.of_node->name, i); 673 client->dev.of_node->name, i);
632 init.name = pll_clk_name[i]; 674 init.name = pll_clk_name[i];
@@ -684,7 +726,7 @@ static int cdce925_probe(struct i2c_client *client,
684 init.ops = &cdce925_clk_ops; 726 init.ops = &cdce925_clk_ops;
685 init.flags = CLK_SET_RATE_PARENT; 727 init.flags = CLK_SET_RATE_PARENT;
686 init.num_parents = 1; 728 init.num_parents = 1;
687 for (i = 1; i < NUMBER_OF_OUTPUTS; ++i) { 729 for (i = 1; i < data->chip_info->num_outputs; ++i) {
688 init.name = kasprintf(GFP_KERNEL, "%s.Y%d", 730 init.name = kasprintf(GFP_KERNEL, "%s.Y%d",
689 client->dev.of_node->name, i+1); 731 client->dev.of_node->name, i+1);
690 data->clk[i].chip = data; 732 data->clk[i].chip = data;
@@ -702,6 +744,16 @@ static int cdce925_probe(struct i2c_client *client,
702 /* Mux Y4/5 to PLL2 */ 744 /* Mux Y4/5 to PLL2 */
703 init.parent_names = &pll_clk_name[1]; 745 init.parent_names = &pll_clk_name[1];
704 break; 746 break;
747 case 5:
748 case 6:
749 /* Mux Y6/7 to PLL3 */
750 init.parent_names = &pll_clk_name[2];
751 break;
752 case 7:
753 case 8:
754 /* Mux Y8/9 to PLL4 */
755 init.parent_names = &pll_clk_name[3];
756 break;
705 } 757 }
706 err = devm_clk_hw_register(&client->dev, &data->clk[i].hw); 758 err = devm_clk_hw_register(&client->dev, &data->clk[i].hw);
707 kfree(init.name); /* clock framework made a copy of the name */ 759 kfree(init.name); /* clock framework made a copy of the name */
@@ -720,7 +772,7 @@ static int cdce925_probe(struct i2c_client *client,
720 err = 0; 772 err = 0;
721 773
722error: 774error:
723 for (i = 0; i < NUMBER_OF_PLLS; ++i) 775 for (i = 0; i < data->chip_info->num_plls; ++i)
724 /* clock framework made a copy of the name */ 776 /* clock framework made a copy of the name */
725 kfree(pll_clk_name[i]); 777 kfree(pll_clk_name[i]);
726 778
@@ -728,13 +780,19 @@ error:
728} 780}
729 781
730static const struct i2c_device_id cdce925_id[] = { 782static const struct i2c_device_id cdce925_id[] = {
731 { "cdce925", 0 }, 783 { "cdce913", CDCE913 },
784 { "cdce925", CDCE925 },
785 { "cdce937", CDCE937 },
786 { "cdce949", CDCE949 },
732 { } 787 { }
733}; 788};
734MODULE_DEVICE_TABLE(i2c, cdce925_id); 789MODULE_DEVICE_TABLE(i2c, cdce925_id);
735 790
736static const struct of_device_id clk_cdce925_of_match[] = { 791static const struct of_device_id clk_cdce925_of_match[] = {
792 { .compatible = "ti,cdce913" },
737 { .compatible = "ti,cdce925" }, 793 { .compatible = "ti,cdce925" },
794 { .compatible = "ti,cdce937" },
795 { .compatible = "ti,cdce949" },
738 { }, 796 { },
739}; 797};
740MODULE_DEVICE_TABLE(of, clk_cdce925_of_match); 798MODULE_DEVICE_TABLE(of, clk_cdce925_of_match);
@@ -750,5 +808,5 @@ static struct i2c_driver cdce925_driver = {
750module_i2c_driver(cdce925_driver); 808module_i2c_driver(cdce925_driver);
751 809
752MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>"); 810MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>");
753MODULE_DESCRIPTION("cdce925 driver"); 811MODULE_DESCRIPTION("TI CDCE913/925/937/949 driver");
754MODULE_LICENSE("GPL"); 812MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
index 674785d968a3..e0e02a6e5900 100644
--- a/drivers/clk/clk-conf.c
+++ b/drivers/clk/clk-conf.c
@@ -40,8 +40,9 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
40 return 0; 40 return 0;
41 pclk = of_clk_get_from_provider(&clkspec); 41 pclk = of_clk_get_from_provider(&clkspec);
42 if (IS_ERR(pclk)) { 42 if (IS_ERR(pclk)) {
43 pr_warn("clk: couldn't get parent clock %d for %s\n", 43 if (PTR_ERR(pclk) != -EPROBE_DEFER)
44 index, node->full_name); 44 pr_warn("clk: couldn't get parent clock %d for %s\n",
45 index, node->full_name);
45 return PTR_ERR(pclk); 46 return PTR_ERR(pclk);
46 } 47 }
47 48
@@ -55,8 +56,9 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
55 } 56 }
56 clk = of_clk_get_from_provider(&clkspec); 57 clk = of_clk_get_from_provider(&clkspec);
57 if (IS_ERR(clk)) { 58 if (IS_ERR(clk)) {
58 pr_warn("clk: couldn't get assigned clock %d for %s\n", 59 if (PTR_ERR(clk) != -EPROBE_DEFER)
59 index, node->full_name); 60 pr_warn("clk: couldn't get assigned clock %d for %s\n",
61 index, node->full_name);
60 rc = PTR_ERR(clk); 62 rc = PTR_ERR(clk);
61 goto err; 63 goto err;
62 } 64 }
@@ -99,8 +101,9 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
99 101
100 clk = of_clk_get_from_provider(&clkspec); 102 clk = of_clk_get_from_provider(&clkspec);
101 if (IS_ERR(clk)) { 103 if (IS_ERR(clk)) {
102 pr_warn("clk: couldn't get clock %d for %s\n", 104 if (PTR_ERR(clk) != -EPROBE_DEFER)
103 index, node->full_name); 105 pr_warn("clk: couldn't get clock %d for %s\n",
106 index, node->full_name);
104 return PTR_ERR(clk); 107 return PTR_ERR(clk);
105 } 108 }
106 109
diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c
index 021f3daf34e1..3fca0526d940 100644
--- a/drivers/clk/clk-cs2000-cp.c
+++ b/drivers/clk/clk-cs2000-cp.c
@@ -59,6 +59,10 @@ struct cs2000_priv {
59 struct i2c_client *client; 59 struct i2c_client *client;
60 struct clk *clk_in; 60 struct clk *clk_in;
61 struct clk *ref_clk; 61 struct clk *ref_clk;
62
63 /* suspend/resume */
64 unsigned long saved_rate;
65 unsigned long saved_parent_rate;
62}; 66};
63 67
64static const struct of_device_id cs2000_of_match[] = { 68static const struct of_device_id cs2000_of_match[] = {
@@ -286,6 +290,9 @@ static int __cs2000_set_rate(struct cs2000_priv *priv, int ch,
286 if (ret < 0) 290 if (ret < 0)
287 return ret; 291 return ret;
288 292
293 priv->saved_rate = rate;
294 priv->saved_parent_rate = parent_rate;
295
289 return 0; 296 return 0;
290} 297}
291 298
@@ -489,9 +496,24 @@ probe_err:
489 return ret; 496 return ret;
490} 497}
491 498
499static int cs2000_resume(struct device *dev)
500{
501 struct cs2000_priv *priv = dev_get_drvdata(dev);
502 int ch = 0; /* it uses ch0 only at this point */
503
504 return __cs2000_set_rate(priv, ch,
505 priv->saved_rate,
506 priv->saved_parent_rate);
507}
508
509static const struct dev_pm_ops cs2000_pm_ops = {
510 .resume_early = cs2000_resume,
511};
512
492static struct i2c_driver cs2000_driver = { 513static struct i2c_driver cs2000_driver = {
493 .driver = { 514 .driver = {
494 .name = "cs2000-cp", 515 .name = "cs2000-cp",
516 .pm = &cs2000_pm_ops,
495 .of_match_table = cs2000_of_match, 517 .of_match_table = cs2000_of_match,
496 }, 518 },
497 .probe = cs2000_probe, 519 .probe = cs2000_probe,
diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c
index 2a3e9d8e88b0..96d37175d0ad 100644
--- a/drivers/clk/clk-scpi.c
+++ b/drivers/clk/clk-scpi.c
@@ -290,13 +290,15 @@ static int scpi_clocks_probe(struct platform_device *pdev)
290 of_node_put(child); 290 of_node_put(child);
291 return ret; 291 return ret;
292 } 292 }
293 }
294 /* Add the virtual cpufreq device */
295 cpufreq_dev = platform_device_register_simple("scpi-cpufreq",
296 -1, NULL, 0);
297 if (IS_ERR(cpufreq_dev))
298 pr_warn("unable to register cpufreq device");
299 293
294 if (match->data != &scpi_dvfs_ops)
295 continue;
296 /* Add the virtual cpufreq device if it's DVFS clock provider */
297 cpufreq_dev = platform_device_register_simple("scpi-cpufreq",
298 -1, NULL, 0);
299 if (IS_ERR(cpufreq_dev))
300 pr_warn("unable to register cpufreq device");
301 }
300 return 0; 302 return 0;
301} 303}
302 304
diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index fc585f370549..ab609a76706f 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -28,6 +28,14 @@
28#include <linux/regmap.h> 28#include <linux/regmap.h>
29#include <linux/mfd/syscon.h> 29#include <linux/mfd/syscon.h>
30 30
31/*
32 * Include list of clocks wich are not derived from system clock (SYSCLOCK)
33 * The index of these clocks is the secondary index of DT bindings
34 *
35 */
36#include <dt-bindings/clock/stm32fx-clock.h>
37
38#define STM32F4_RCC_CR 0x00
31#define STM32F4_RCC_PLLCFGR 0x04 39#define STM32F4_RCC_PLLCFGR 0x04
32#define STM32F4_RCC_CFGR 0x08 40#define STM32F4_RCC_CFGR 0x08
33#define STM32F4_RCC_AHB1ENR 0x30 41#define STM32F4_RCC_AHB1ENR 0x30
@@ -37,6 +45,15 @@
37#define STM32F4_RCC_APB2ENR 0x44 45#define STM32F4_RCC_APB2ENR 0x44
38#define STM32F4_RCC_BDCR 0x70 46#define STM32F4_RCC_BDCR 0x70
39#define STM32F4_RCC_CSR 0x74 47#define STM32F4_RCC_CSR 0x74
48#define STM32F4_RCC_PLLI2SCFGR 0x84
49#define STM32F4_RCC_PLLSAICFGR 0x88
50#define STM32F4_RCC_DCKCFGR 0x8c
51#define STM32F7_RCC_DCKCFGR2 0x90
52
53#define NONE -1
54#define NO_IDX NONE
55#define NO_MUX NONE
56#define NO_GATE NONE
40 57
41struct stm32f4_gate_data { 58struct stm32f4_gate_data {
42 u8 offset; 59 u8 offset;
@@ -195,7 +212,7 @@ static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
195 { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" }, 212 { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" },
196 { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" }, 213 { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" },
197 { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" }, 214 { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" },
198 { STM32F4_RCC_APB2ENR, 11, "sdio", "pll48" }, 215 { STM32F4_RCC_APB2ENR, 11, "sdio", "sdmux" },
199 { STM32F4_RCC_APB2ENR, 12, "spi1", "apb2_div" }, 216 { STM32F4_RCC_APB2ENR, 12, "spi1", "apb2_div" },
200 { STM32F4_RCC_APB2ENR, 13, "spi4", "apb2_div" }, 217 { STM32F4_RCC_APB2ENR, 13, "spi4", "apb2_div" },
201 { STM32F4_RCC_APB2ENR, 14, "syscfg", "apb2_div" }, 218 { STM32F4_RCC_APB2ENR, 14, "syscfg", "apb2_div" },
@@ -208,7 +225,79 @@ static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
208 { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, 225 { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" },
209}; 226};
210 227
211enum { SYSTICK, FCLK, CLK_LSI, CLK_LSE, CLK_HSE_RTC, CLK_RTC, END_PRIMARY_CLK }; 228static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
229 { STM32F4_RCC_AHB1ENR, 0, "gpioa", "ahb_div" },
230 { STM32F4_RCC_AHB1ENR, 1, "gpiob", "ahb_div" },
231 { STM32F4_RCC_AHB1ENR, 2, "gpioc", "ahb_div" },
232 { STM32F4_RCC_AHB1ENR, 3, "gpiod", "ahb_div" },
233 { STM32F4_RCC_AHB1ENR, 4, "gpioe", "ahb_div" },
234 { STM32F4_RCC_AHB1ENR, 5, "gpiof", "ahb_div" },
235 { STM32F4_RCC_AHB1ENR, 6, "gpiog", "ahb_div" },
236 { STM32F4_RCC_AHB1ENR, 7, "gpioh", "ahb_div" },
237 { STM32F4_RCC_AHB1ENR, 8, "gpioi", "ahb_div" },
238 { STM32F4_RCC_AHB1ENR, 9, "gpioj", "ahb_div" },
239 { STM32F4_RCC_AHB1ENR, 10, "gpiok", "ahb_div" },
240 { STM32F4_RCC_AHB1ENR, 12, "crc", "ahb_div" },
241 { STM32F4_RCC_AHB1ENR, 18, "bkpsra", "ahb_div" },
242 { STM32F4_RCC_AHB1ENR, 20, "dtcmram", "ahb_div" },
243 { STM32F4_RCC_AHB1ENR, 21, "dma1", "ahb_div" },
244 { STM32F4_RCC_AHB1ENR, 22, "dma2", "ahb_div" },
245 { STM32F4_RCC_AHB1ENR, 23, "dma2d", "ahb_div" },
246 { STM32F4_RCC_AHB1ENR, 25, "ethmac", "ahb_div" },
247 { STM32F4_RCC_AHB1ENR, 26, "ethmactx", "ahb_div" },
248 { STM32F4_RCC_AHB1ENR, 27, "ethmacrx", "ahb_div" },
249 { STM32F4_RCC_AHB1ENR, 28, "ethmacptp", "ahb_div" },
250 { STM32F4_RCC_AHB1ENR, 29, "otghs", "ahb_div" },
251 { STM32F4_RCC_AHB1ENR, 30, "otghsulpi", "ahb_div" },
252
253 { STM32F4_RCC_AHB2ENR, 0, "dcmi", "ahb_div" },
254 { STM32F4_RCC_AHB2ENR, 4, "cryp", "ahb_div" },
255 { STM32F4_RCC_AHB2ENR, 5, "hash", "ahb_div" },
256 { STM32F4_RCC_AHB2ENR, 6, "rng", "pll48" },
257 { STM32F4_RCC_AHB2ENR, 7, "otgfs", "pll48" },
258
259 { STM32F4_RCC_AHB3ENR, 0, "fmc", "ahb_div",
260 CLK_IGNORE_UNUSED },
261 { STM32F4_RCC_AHB3ENR, 1, "qspi", "ahb_div",
262 CLK_IGNORE_UNUSED },
263
264 { STM32F4_RCC_APB1ENR, 0, "tim2", "apb1_mul" },
265 { STM32F4_RCC_APB1ENR, 1, "tim3", "apb1_mul" },
266 { STM32F4_RCC_APB1ENR, 2, "tim4", "apb1_mul" },
267 { STM32F4_RCC_APB1ENR, 3, "tim5", "apb1_mul" },
268 { STM32F4_RCC_APB1ENR, 4, "tim6", "apb1_mul" },
269 { STM32F4_RCC_APB1ENR, 5, "tim7", "apb1_mul" },
270 { STM32F4_RCC_APB1ENR, 6, "tim12", "apb1_mul" },
271 { STM32F4_RCC_APB1ENR, 7, "tim13", "apb1_mul" },
272 { STM32F4_RCC_APB1ENR, 8, "tim14", "apb1_mul" },
273 { STM32F4_RCC_APB1ENR, 11, "wwdg", "apb1_div" },
274 { STM32F4_RCC_APB1ENR, 14, "spi2", "apb1_div" },
275 { STM32F4_RCC_APB1ENR, 15, "spi3", "apb1_div" },
276 { STM32F4_RCC_APB1ENR, 16, "spdifrx", "apb1_div" },
277 { STM32F4_RCC_APB1ENR, 25, "can1", "apb1_div" },
278 { STM32F4_RCC_APB1ENR, 26, "can2", "apb1_div" },
279 { STM32F4_RCC_APB1ENR, 27, "cec", "apb1_div" },
280 { STM32F4_RCC_APB1ENR, 28, "pwr", "apb1_div" },
281 { STM32F4_RCC_APB1ENR, 29, "dac", "apb1_div" },
282
283 { STM32F4_RCC_APB2ENR, 0, "tim1", "apb2_mul" },
284 { STM32F4_RCC_APB2ENR, 1, "tim8", "apb2_mul" },
285 { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" },
286 { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" },
287 { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" },
288 { STM32F4_RCC_APB2ENR, 11, "sdmmc", "sdmux" },
289 { STM32F4_RCC_APB2ENR, 12, "spi1", "apb2_div" },
290 { STM32F4_RCC_APB2ENR, 13, "spi4", "apb2_div" },
291 { STM32F4_RCC_APB2ENR, 14, "syscfg", "apb2_div" },
292 { STM32F4_RCC_APB2ENR, 16, "tim9", "apb2_mul" },
293 { STM32F4_RCC_APB2ENR, 17, "tim10", "apb2_mul" },
294 { STM32F4_RCC_APB2ENR, 18, "tim11", "apb2_mul" },
295 { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" },
296 { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" },
297 { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" },
298 { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" },
299 { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" },
300};
212 301
213/* 302/*
214 * This bitmask tells us which bit offsets (0..192) on STM32F4[23]xxx 303 * This bitmask tells us which bit offsets (0..192) on STM32F4[23]xxx
@@ -224,6 +313,10 @@ static const u64 stm32f46xx_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull,
224 0x0000000000000003ull, 313 0x0000000000000003ull,
225 0x0c777f33f6fec9ffull }; 314 0x0c777f33f6fec9ffull };
226 315
316static const u64 stm32f746_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull,
317 0x0000000000000003ull,
318 0x04f77f033e01c9ffull };
319
227static const u64 *stm32f4_gate_map; 320static const u64 *stm32f4_gate_map;
228 321
229static struct clk_hw **clks; 322static struct clk_hw **clks;
@@ -233,6 +326,8 @@ static void __iomem *base;
233 326
234static struct regmap *pdrm; 327static struct regmap *pdrm;
235 328
329static int stm32fx_end_primary_clk;
330
236/* 331/*
237 * "Multiplier" device for APBx clocks. 332 * "Multiplier" device for APBx clocks.
238 * 333 *
@@ -324,23 +419,342 @@ static struct clk *clk_register_apb_mul(struct device *dev, const char *name,
324 return clk; 419 return clk;
325} 420}
326 421
327/* 422enum {
328 * Decode current PLL state and (statically) model the state we inherit from 423 PLL,
329 * the bootloader. 424 PLL_I2S,
330 */ 425 PLL_SAI,
331static void stm32f4_rcc_register_pll(const char *hse_clk, const char *hsi_clk) 426};
427
428static const struct clk_div_table pll_divp_table[] = {
429 { 0, 2 }, { 1, 4 }, { 2, 6 }, { 3, 8 }, { 0 }
430};
431
432static const struct clk_div_table pll_divr_table[] = {
433 { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 }, { 7, 7 }, { 0 }
434};
435
436struct stm32f4_pll {
437 spinlock_t *lock;
438 struct clk_gate gate;
439 u8 offset;
440 u8 bit_rdy_idx;
441 u8 status;
442 u8 n_start;
443};
444
445#define to_stm32f4_pll(_gate) container_of(_gate, struct stm32f4_pll, gate)
446
447struct stm32f4_pll_post_div_data {
448 int idx;
449 u8 pll_num;
450 const char *name;
451 const char *parent;
452 u8 flag;
453 u8 offset;
454 u8 shift;
455 u8 width;
456 u8 flag_div;
457 const struct clk_div_table *div_table;
458};
459
460struct stm32f4_vco_data {
461 const char *vco_name;
462 u8 offset;
463 u8 bit_idx;
464 u8 bit_rdy_idx;
465};
466
467static const struct stm32f4_vco_data vco_data[] = {
468 { "vco", STM32F4_RCC_PLLCFGR, 24, 25 },
469 { "vco-i2s", STM32F4_RCC_PLLI2SCFGR, 26, 27 },
470 { "vco-sai", STM32F4_RCC_PLLSAICFGR, 28, 29 },
471};
472
473
474static const struct clk_div_table post_divr_table[] = {
475 { 0, 2 }, { 1, 4 }, { 2, 8 }, { 3, 16 }, { 0 }
476};
477
478#define MAX_POST_DIV 3
479static const struct stm32f4_pll_post_div_data post_div_data[MAX_POST_DIV] = {
480 { CLK_I2SQ_PDIV, PLL_I2S, "plli2s-q-div", "plli2s-q",
481 CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL},
482
483 { CLK_SAIQ_PDIV, PLL_SAI, "pllsai-q-div", "pllsai-q",
484 CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL },
485
486 { NO_IDX, PLL_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
487 STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table },
488};
489
490struct stm32f4_div_data {
491 u8 shift;
492 u8 width;
493 u8 flag_div;
494 const struct clk_div_table *div_table;
495};
496
497#define MAX_PLL_DIV 3
498static const struct stm32f4_div_data div_data[MAX_PLL_DIV] = {
499 { 16, 2, 0, pll_divp_table },
500 { 24, 4, CLK_DIVIDER_ONE_BASED, NULL },
501 { 28, 3, 0, pll_divr_table },
502};
503
504struct stm32f4_pll_data {
505 u8 pll_num;
506 u8 n_start;
507 const char *div_name[MAX_PLL_DIV];
508};
509
510static const struct stm32f4_pll_data stm32f429_pll[MAX_PLL_DIV] = {
511 { PLL, 192, { "pll", "pll48", NULL } },
512 { PLL_I2S, 192, { NULL, "plli2s-q", "plli2s-r" } },
513 { PLL_SAI, 49, { NULL, "pllsai-q", "pllsai-r" } },
514};
515
516static const struct stm32f4_pll_data stm32f469_pll[MAX_PLL_DIV] = {
517 { PLL, 50, { "pll", "pll-q", NULL } },
518 { PLL_I2S, 50, { "plli2s-p", "plli2s-q", "plli2s-r" } },
519 { PLL_SAI, 50, { "pllsai-p", "pllsai-q", "pllsai-r" } },
520};
521
522static int stm32f4_pll_is_enabled(struct clk_hw *hw)
523{
524 return clk_gate_ops.is_enabled(hw);
525}
526
527static int stm32f4_pll_enable(struct clk_hw *hw)
528{
529 struct clk_gate *gate = to_clk_gate(hw);
530 struct stm32f4_pll *pll = to_stm32f4_pll(gate);
531 int ret = 0;
532 unsigned long reg;
533
534 ret = clk_gate_ops.enable(hw);
535
536 ret = readl_relaxed_poll_timeout_atomic(base + STM32F4_RCC_CR, reg,
537 reg & (1 << pll->bit_rdy_idx), 0, 10000);
538
539 return ret;
540}
541
542static void stm32f4_pll_disable(struct clk_hw *hw)
543{
544 clk_gate_ops.disable(hw);
545}
546
547static unsigned long stm32f4_pll_recalc(struct clk_hw *hw,
548 unsigned long parent_rate)
549{
550 struct clk_gate *gate = to_clk_gate(hw);
551 struct stm32f4_pll *pll = to_stm32f4_pll(gate);
552 unsigned long n;
553
554 n = (readl(base + pll->offset) >> 6) & 0x1ff;
555
556 return parent_rate * n;
557}
558
559static long stm32f4_pll_round_rate(struct clk_hw *hw, unsigned long rate,
560 unsigned long *prate)
561{
562 struct clk_gate *gate = to_clk_gate(hw);
563 struct stm32f4_pll *pll = to_stm32f4_pll(gate);
564 unsigned long n;
565
566 n = rate / *prate;
567
568 if (n < pll->n_start)
569 n = pll->n_start;
570 else if (n > 432)
571 n = 432;
572
573 return *prate * n;
574}
575
576static int stm32f4_pll_set_rate(struct clk_hw *hw, unsigned long rate,
577 unsigned long parent_rate)
578{
579 struct clk_gate *gate = to_clk_gate(hw);
580 struct stm32f4_pll *pll = to_stm32f4_pll(gate);
581
582 unsigned long n;
583 unsigned long val;
584 int pll_state;
585
586 pll_state = stm32f4_pll_is_enabled(hw);
587
588 if (pll_state)
589 stm32f4_pll_disable(hw);
590
591 n = rate / parent_rate;
592
593 val = readl(base + pll->offset) & ~(0x1ff << 6);
594
595 writel(val | ((n & 0x1ff) << 6), base + pll->offset);
596
597 if (pll_state)
598 stm32f4_pll_enable(hw);
599
600 return 0;
601}
602
603static const struct clk_ops stm32f4_pll_gate_ops = {
604 .enable = stm32f4_pll_enable,
605 .disable = stm32f4_pll_disable,
606 .is_enabled = stm32f4_pll_is_enabled,
607 .recalc_rate = stm32f4_pll_recalc,
608 .round_rate = stm32f4_pll_round_rate,
609 .set_rate = stm32f4_pll_set_rate,
610};
611
612struct stm32f4_pll_div {
613 struct clk_divider div;
614 struct clk_hw *hw_pll;
615};
616
617#define to_pll_div_clk(_div) container_of(_div, struct stm32f4_pll_div, div)
618
619static unsigned long stm32f4_pll_div_recalc_rate(struct clk_hw *hw,
620 unsigned long parent_rate)
621{
622 return clk_divider_ops.recalc_rate(hw, parent_rate);
623}
624
625static long stm32f4_pll_div_round_rate(struct clk_hw *hw, unsigned long rate,
626 unsigned long *prate)
627{
628 return clk_divider_ops.round_rate(hw, rate, prate);
629}
630
631static int stm32f4_pll_div_set_rate(struct clk_hw *hw, unsigned long rate,
632 unsigned long parent_rate)
332{ 633{
333 unsigned long pllcfgr = readl(base + STM32F4_RCC_PLLCFGR); 634 int pll_state, ret;
635
636 struct clk_divider *div = to_clk_divider(hw);
637 struct stm32f4_pll_div *pll_div = to_pll_div_clk(div);
638
639 pll_state = stm32f4_pll_is_enabled(pll_div->hw_pll);
640
641 if (pll_state)
642 stm32f4_pll_disable(pll_div->hw_pll);
643
644 ret = clk_divider_ops.set_rate(hw, rate, parent_rate);
334 645
335 unsigned long pllm = pllcfgr & 0x3f; 646 if (pll_state)
336 unsigned long plln = (pllcfgr >> 6) & 0x1ff; 647 stm32f4_pll_enable(pll_div->hw_pll);
337 unsigned long pllp = BIT(((pllcfgr >> 16) & 3) + 1);
338 const char *pllsrc = pllcfgr & BIT(22) ? hse_clk : hsi_clk;
339 unsigned long pllq = (pllcfgr >> 24) & 0xf;
340 648
341 clk_register_fixed_factor(NULL, "vco", pllsrc, 0, plln, pllm); 649 return ret;
342 clk_register_fixed_factor(NULL, "pll", "vco", 0, 1, pllp); 650}
343 clk_register_fixed_factor(NULL, "pll48", "vco", 0, 1, pllq); 651
652static const struct clk_ops stm32f4_pll_div_ops = {
653 .recalc_rate = stm32f4_pll_div_recalc_rate,
654 .round_rate = stm32f4_pll_div_round_rate,
655 .set_rate = stm32f4_pll_div_set_rate,
656};
657
658static struct clk_hw *clk_register_pll_div(const char *name,
659 const char *parent_name, unsigned long flags,
660 void __iomem *reg, u8 shift, u8 width,
661 u8 clk_divider_flags, const struct clk_div_table *table,
662 struct clk_hw *pll_hw, spinlock_t *lock)
663{
664 struct stm32f4_pll_div *pll_div;
665 struct clk_hw *hw;
666 struct clk_init_data init;
667 int ret;
668
669 /* allocate the divider */
670 pll_div = kzalloc(sizeof(*pll_div), GFP_KERNEL);
671 if (!pll_div)
672 return ERR_PTR(-ENOMEM);
673
674 init.name = name;
675 init.ops = &stm32f4_pll_div_ops;
676 init.flags = flags;
677 init.parent_names = (parent_name ? &parent_name : NULL);
678 init.num_parents = (parent_name ? 1 : 0);
679
680 /* struct clk_divider assignments */
681 pll_div->div.reg = reg;
682 pll_div->div.shift = shift;
683 pll_div->div.width = width;
684 pll_div->div.flags = clk_divider_flags;
685 pll_div->div.lock = lock;
686 pll_div->div.table = table;
687 pll_div->div.hw.init = &init;
688
689 pll_div->hw_pll = pll_hw;
690
691 /* register the clock */
692 hw = &pll_div->div.hw;
693 ret = clk_hw_register(NULL, hw);
694 if (ret) {
695 kfree(pll_div);
696 hw = ERR_PTR(ret);
697 }
698
699 return hw;
700}
701
702static struct clk_hw *stm32f4_rcc_register_pll(const char *pllsrc,
703 const struct stm32f4_pll_data *data, spinlock_t *lock)
704{
705 struct stm32f4_pll *pll;
706 struct clk_init_data init = { NULL };
707 void __iomem *reg;
708 struct clk_hw *pll_hw;
709 int ret;
710 int i;
711 const struct stm32f4_vco_data *vco;
712
713
714 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
715 if (!pll)
716 return ERR_PTR(-ENOMEM);
717
718 vco = &vco_data[data->pll_num];
719
720 init.name = vco->vco_name;
721 init.ops = &stm32f4_pll_gate_ops;
722 init.flags = CLK_SET_RATE_GATE;
723 init.parent_names = &pllsrc;
724 init.num_parents = 1;
725
726 pll->gate.lock = lock;
727 pll->gate.reg = base + STM32F4_RCC_CR;
728 pll->gate.bit_idx = vco->bit_idx;
729 pll->gate.hw.init = &init;
730
731 pll->offset = vco->offset;
732 pll->n_start = data->n_start;
733 pll->bit_rdy_idx = vco->bit_rdy_idx;
734 pll->status = (readl(base + STM32F4_RCC_CR) >> vco->bit_idx) & 0x1;
735
736 reg = base + pll->offset;
737
738 pll_hw = &pll->gate.hw;
739 ret = clk_hw_register(NULL, pll_hw);
740 if (ret) {
741 kfree(pll);
742 return ERR_PTR(ret);
743 }
744
745 for (i = 0; i < MAX_PLL_DIV; i++)
746 if (data->div_name[i])
747 clk_register_pll_div(data->div_name[i],
748 vco->vco_name,
749 0,
750 reg,
751 div_data[i].shift,
752 div_data[i].width,
753 div_data[i].flag_div,
754 div_data[i].div_table,
755 pll_hw,
756 lock);
757 return pll_hw;
344} 758}
345 759
346/* 760/*
@@ -352,7 +766,7 @@ static int stm32f4_rcc_lookup_clk_idx(u8 primary, u8 secondary)
352 u64 table[MAX_GATE_MAP]; 766 u64 table[MAX_GATE_MAP];
353 767
354 if (primary == 1) { 768 if (primary == 1) {
355 if (WARN_ON(secondary >= END_PRIMARY_CLK)) 769 if (WARN_ON(secondary >= stm32fx_end_primary_clk))
356 return -EINVAL; 770 return -EINVAL;
357 return secondary; 771 return secondary;
358 } 772 }
@@ -369,7 +783,7 @@ static int stm32f4_rcc_lookup_clk_idx(u8 primary, u8 secondary)
369 table[BIT_ULL_WORD(secondary)] &= 783 table[BIT_ULL_WORD(secondary)] &=
370 GENMASK_ULL(secondary % BITS_PER_LONG_LONG, 0); 784 GENMASK_ULL(secondary % BITS_PER_LONG_LONG, 0);
371 785
372 return END_PRIMARY_CLK - 1 + hweight64(table[0]) + 786 return stm32fx_end_primary_clk - 1 + hweight64(table[0]) +
373 (BIT_ULL_WORD(secondary) >= 1 ? hweight64(table[1]) : 0) + 787 (BIT_ULL_WORD(secondary) >= 1 ? hweight64(table[1]) : 0) +
374 (BIT_ULL_WORD(secondary) >= 2 ? hweight64(table[2]) : 0); 788 (BIT_ULL_WORD(secondary) >= 2 ? hweight64(table[2]) : 0);
375} 789}
@@ -611,22 +1025,291 @@ static const char *rtc_parents[4] = {
611 "no-clock", "lse", "lsi", "hse-rtc" 1025 "no-clock", "lse", "lsi", "hse-rtc"
612}; 1026};
613 1027
1028static const char *lcd_parent[1] = { "pllsai-r-div" };
1029
1030static const char *i2s_parents[2] = { "plli2s-r", NULL };
1031
1032static const char *sai_parents[4] = { "pllsai-q-div", "plli2s-q-div", NULL,
1033 "no-clock" };
1034
1035static const char *pll48_parents[2] = { "pll-q", "pllsai-p" };
1036
1037static const char *sdmux_parents[2] = { "pll48", "sys" };
1038
1039static const char *hdmi_parents[2] = { "lse", "hsi_div488" };
1040
1041static const char *spdif_parent[1] = { "plli2s-p" };
1042
1043static const char *lptim_parent[4] = { "apb1_mul", "lsi", "hsi", "lse" };
1044
1045static const char *uart_parents1[4] = { "apb2_div", "sys", "hsi", "lse" };
1046static const char *uart_parents2[4] = { "apb1_div", "sys", "hsi", "lse" };
1047
1048static const char *i2c_parents[4] = { "apb1_div", "sys", "hsi", "no-clock" };
1049
1050struct stm32_aux_clk {
1051 int idx;
1052 const char *name;
1053 const char * const *parent_names;
1054 int num_parents;
1055 int offset_mux;
1056 u8 shift;
1057 u8 mask;
1058 int offset_gate;
1059 u8 bit_idx;
1060 unsigned long flags;
1061};
1062
614struct stm32f4_clk_data { 1063struct stm32f4_clk_data {
615 const struct stm32f4_gate_data *gates_data; 1064 const struct stm32f4_gate_data *gates_data;
616 const u64 *gates_map; 1065 const u64 *gates_map;
617 int gates_num; 1066 int gates_num;
1067 const struct stm32f4_pll_data *pll_data;
1068 const struct stm32_aux_clk *aux_clk;
1069 int aux_clk_num;
1070 int end_primary;
1071};
1072
1073static const struct stm32_aux_clk stm32f429_aux_clk[] = {
1074 {
1075 CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent),
1076 NO_MUX, 0, 0,
1077 STM32F4_RCC_APB2ENR, 26,
1078 CLK_SET_RATE_PARENT
1079 },
1080 {
1081 CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents),
1082 STM32F4_RCC_CFGR, 23, 1,
1083 NO_GATE, 0,
1084 CLK_SET_RATE_PARENT
1085 },
1086 {
1087 CLK_SAI1, "sai1-a", sai_parents, ARRAY_SIZE(sai_parents),
1088 STM32F4_RCC_DCKCFGR, 20, 3,
1089 STM32F4_RCC_APB2ENR, 22,
1090 CLK_SET_RATE_PARENT
1091 },
1092 {
1093 CLK_SAI2, "sai1-b", sai_parents, ARRAY_SIZE(sai_parents),
1094 STM32F4_RCC_DCKCFGR, 22, 3,
1095 STM32F4_RCC_APB2ENR, 22,
1096 CLK_SET_RATE_PARENT
1097 },
1098};
1099
1100static const struct stm32_aux_clk stm32f469_aux_clk[] = {
1101 {
1102 CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent),
1103 NO_MUX, 0, 0,
1104 STM32F4_RCC_APB2ENR, 26,
1105 CLK_SET_RATE_PARENT
1106 },
1107 {
1108 CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents),
1109 STM32F4_RCC_CFGR, 23, 1,
1110 NO_GATE, 0,
1111 CLK_SET_RATE_PARENT
1112 },
1113 {
1114 CLK_SAI1, "sai1-a", sai_parents, ARRAY_SIZE(sai_parents),
1115 STM32F4_RCC_DCKCFGR, 20, 3,
1116 STM32F4_RCC_APB2ENR, 22,
1117 CLK_SET_RATE_PARENT
1118 },
1119 {
1120 CLK_SAI2, "sai1-b", sai_parents, ARRAY_SIZE(sai_parents),
1121 STM32F4_RCC_DCKCFGR, 22, 3,
1122 STM32F4_RCC_APB2ENR, 22,
1123 CLK_SET_RATE_PARENT
1124 },
1125 {
1126 NO_IDX, "pll48", pll48_parents, ARRAY_SIZE(pll48_parents),
1127 STM32F4_RCC_DCKCFGR, 27, 1,
1128 NO_GATE, 0,
1129 0
1130 },
1131 {
1132 NO_IDX, "sdmux", sdmux_parents, ARRAY_SIZE(sdmux_parents),
1133 STM32F4_RCC_DCKCFGR, 28, 1,
1134 NO_GATE, 0,
1135 0
1136 },
1137};
1138
1139static const struct stm32_aux_clk stm32f746_aux_clk[] = {
1140 {
1141 CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent),
1142 NO_MUX, 0, 0,
1143 STM32F4_RCC_APB2ENR, 26,
1144 CLK_SET_RATE_PARENT
1145 },
1146 {
1147 CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents),
1148 STM32F4_RCC_CFGR, 23, 1,
1149 NO_GATE, 0,
1150 CLK_SET_RATE_PARENT
1151 },
1152 {
1153 CLK_SAI1, "sai1_clk", sai_parents, ARRAY_SIZE(sai_parents),
1154 STM32F4_RCC_DCKCFGR, 20, 3,
1155 STM32F4_RCC_APB2ENR, 22,
1156 CLK_SET_RATE_PARENT
1157 },
1158 {
1159 CLK_SAI2, "sai2_clk", sai_parents, ARRAY_SIZE(sai_parents),
1160 STM32F4_RCC_DCKCFGR, 22, 3,
1161 STM32F4_RCC_APB2ENR, 23,
1162 CLK_SET_RATE_PARENT
1163 },
1164 {
1165 NO_IDX, "pll48", pll48_parents, ARRAY_SIZE(pll48_parents),
1166 STM32F7_RCC_DCKCFGR2, 27, 1,
1167 NO_GATE, 0,
1168 0
1169 },
1170 {
1171 NO_IDX, "sdmux", sdmux_parents, ARRAY_SIZE(sdmux_parents),
1172 STM32F7_RCC_DCKCFGR2, 28, 1,
1173 NO_GATE, 0,
1174 0
1175 },
1176 {
1177 CLK_HDMI_CEC, "hdmi-cec",
1178 hdmi_parents, ARRAY_SIZE(hdmi_parents),
1179 STM32F7_RCC_DCKCFGR2, 26, 1,
1180 NO_GATE, 0,
1181 0
1182 },
1183 {
1184 CLK_SPDIF, "spdif-rx",
1185 spdif_parent, ARRAY_SIZE(spdif_parent),
1186 STM32F7_RCC_DCKCFGR2, 22, 3,
1187 STM32F4_RCC_APB2ENR, 23,
1188 CLK_SET_RATE_PARENT
1189 },
1190 {
1191 CLK_USART1, "usart1",
1192 uart_parents1, ARRAY_SIZE(uart_parents1),
1193 STM32F7_RCC_DCKCFGR2, 0, 3,
1194 STM32F4_RCC_APB2ENR, 4,
1195 CLK_SET_RATE_PARENT,
1196 },
1197 {
1198 CLK_USART2, "usart2",
1199 uart_parents2, ARRAY_SIZE(uart_parents1),
1200 STM32F7_RCC_DCKCFGR2, 2, 3,
1201 STM32F4_RCC_APB1ENR, 17,
1202 CLK_SET_RATE_PARENT,
1203 },
1204 {
1205 CLK_USART3, "usart3",
1206 uart_parents2, ARRAY_SIZE(uart_parents1),
1207 STM32F7_RCC_DCKCFGR2, 4, 3,
1208 STM32F4_RCC_APB1ENR, 18,
1209 CLK_SET_RATE_PARENT,
1210 },
1211 {
1212 CLK_UART4, "uart4",
1213 uart_parents2, ARRAY_SIZE(uart_parents1),
1214 STM32F7_RCC_DCKCFGR2, 6, 3,
1215 STM32F4_RCC_APB1ENR, 19,
1216 CLK_SET_RATE_PARENT,
1217 },
1218 {
1219 CLK_UART5, "uart5",
1220 uart_parents2, ARRAY_SIZE(uart_parents1),
1221 STM32F7_RCC_DCKCFGR2, 8, 3,
1222 STM32F4_RCC_APB1ENR, 20,
1223 CLK_SET_RATE_PARENT,
1224 },
1225 {
1226 CLK_USART6, "usart6",
1227 uart_parents1, ARRAY_SIZE(uart_parents1),
1228 STM32F7_RCC_DCKCFGR2, 10, 3,
1229 STM32F4_RCC_APB2ENR, 5,
1230 CLK_SET_RATE_PARENT,
1231 },
1232
1233 {
1234 CLK_UART7, "uart7",
1235 uart_parents2, ARRAY_SIZE(uart_parents1),
1236 STM32F7_RCC_DCKCFGR2, 12, 3,
1237 STM32F4_RCC_APB1ENR, 30,
1238 CLK_SET_RATE_PARENT,
1239 },
1240 {
1241 CLK_UART8, "uart8",
1242 uart_parents2, ARRAY_SIZE(uart_parents1),
1243 STM32F7_RCC_DCKCFGR2, 14, 3,
1244 STM32F4_RCC_APB1ENR, 31,
1245 CLK_SET_RATE_PARENT,
1246 },
1247 {
1248 CLK_I2C1, "i2c1",
1249 i2c_parents, ARRAY_SIZE(i2c_parents),
1250 STM32F7_RCC_DCKCFGR2, 16, 3,
1251 STM32F4_RCC_APB1ENR, 21,
1252 CLK_SET_RATE_PARENT,
1253 },
1254 {
1255 CLK_I2C2, "i2c2",
1256 i2c_parents, ARRAY_SIZE(i2c_parents),
1257 STM32F7_RCC_DCKCFGR2, 18, 3,
1258 STM32F4_RCC_APB1ENR, 22,
1259 CLK_SET_RATE_PARENT,
1260 },
1261 {
1262 CLK_I2C3, "i2c3",
1263 i2c_parents, ARRAY_SIZE(i2c_parents),
1264 STM32F7_RCC_DCKCFGR2, 20, 3,
1265 STM32F4_RCC_APB1ENR, 23,
1266 CLK_SET_RATE_PARENT,
1267 },
1268 {
1269 CLK_I2C4, "i2c4",
1270 i2c_parents, ARRAY_SIZE(i2c_parents),
1271 STM32F7_RCC_DCKCFGR2, 22, 3,
1272 STM32F4_RCC_APB1ENR, 24,
1273 CLK_SET_RATE_PARENT,
1274 },
1275
1276 {
1277 CLK_LPTIMER, "lptim1",
1278 lptim_parent, ARRAY_SIZE(lptim_parent),
1279 STM32F7_RCC_DCKCFGR2, 24, 3,
1280 STM32F4_RCC_APB1ENR, 9,
1281 CLK_SET_RATE_PARENT
1282 },
618}; 1283};
619 1284
620static const struct stm32f4_clk_data stm32f429_clk_data = { 1285static const struct stm32f4_clk_data stm32f429_clk_data = {
1286 .end_primary = END_PRIMARY_CLK,
621 .gates_data = stm32f429_gates, 1287 .gates_data = stm32f429_gates,
622 .gates_map = stm32f42xx_gate_map, 1288 .gates_map = stm32f42xx_gate_map,
623 .gates_num = ARRAY_SIZE(stm32f429_gates), 1289 .gates_num = ARRAY_SIZE(stm32f429_gates),
1290 .pll_data = stm32f429_pll,
1291 .aux_clk = stm32f429_aux_clk,
1292 .aux_clk_num = ARRAY_SIZE(stm32f429_aux_clk),
624}; 1293};
625 1294
626static const struct stm32f4_clk_data stm32f469_clk_data = { 1295static const struct stm32f4_clk_data stm32f469_clk_data = {
1296 .end_primary = END_PRIMARY_CLK,
627 .gates_data = stm32f469_gates, 1297 .gates_data = stm32f469_gates,
628 .gates_map = stm32f46xx_gate_map, 1298 .gates_map = stm32f46xx_gate_map,
629 .gates_num = ARRAY_SIZE(stm32f469_gates), 1299 .gates_num = ARRAY_SIZE(stm32f469_gates),
1300 .pll_data = stm32f469_pll,
1301 .aux_clk = stm32f469_aux_clk,
1302 .aux_clk_num = ARRAY_SIZE(stm32f469_aux_clk),
1303};
1304
1305static const struct stm32f4_clk_data stm32f746_clk_data = {
1306 .end_primary = END_PRIMARY_CLK_F7,
1307 .gates_data = stm32f746_gates,
1308 .gates_map = stm32f746_gate_map,
1309 .gates_num = ARRAY_SIZE(stm32f746_gates),
1310 .pll_data = stm32f469_pll,
1311 .aux_clk = stm32f746_aux_clk,
1312 .aux_clk_num = ARRAY_SIZE(stm32f746_aux_clk),
630}; 1313};
631 1314
632static const struct of_device_id stm32f4_of_match[] = { 1315static const struct of_device_id stm32f4_of_match[] = {
@@ -638,15 +1321,84 @@ static const struct of_device_id stm32f4_of_match[] = {
638 .compatible = "st,stm32f469-rcc", 1321 .compatible = "st,stm32f469-rcc",
639 .data = &stm32f469_clk_data 1322 .data = &stm32f469_clk_data
640 }, 1323 },
1324 {
1325 .compatible = "st,stm32f746-rcc",
1326 .data = &stm32f746_clk_data
1327 },
641 {} 1328 {}
642}; 1329};
643 1330
1331static struct clk_hw *stm32_register_aux_clk(const char *name,
1332 const char * const *parent_names, int num_parents,
1333 int offset_mux, u8 shift, u8 mask,
1334 int offset_gate, u8 bit_idx,
1335 unsigned long flags, spinlock_t *lock)
1336{
1337 struct clk_hw *hw;
1338 struct clk_gate *gate = NULL;
1339 struct clk_mux *mux = NULL;
1340 struct clk_hw *mux_hw = NULL, *gate_hw = NULL;
1341 const struct clk_ops *mux_ops = NULL, *gate_ops = NULL;
1342
1343 if (offset_gate != NO_GATE) {
1344 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
1345 if (!gate) {
1346 hw = ERR_PTR(-EINVAL);
1347 goto fail;
1348 }
1349
1350 gate->reg = base + offset_gate;
1351 gate->bit_idx = bit_idx;
1352 gate->flags = 0;
1353 gate->lock = lock;
1354 gate_hw = &gate->hw;
1355 gate_ops = &clk_gate_ops;
1356 }
1357
1358 if (offset_mux != NO_MUX) {
1359 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
1360 if (!mux) {
1361 hw = ERR_PTR(-EINVAL);
1362 goto fail;
1363 }
1364
1365 mux->reg = base + offset_mux;
1366 mux->shift = shift;
1367 mux->mask = mask;
1368 mux->flags = 0;
1369 mux_hw = &mux->hw;
1370 mux_ops = &clk_mux_ops;
1371 }
1372
1373 if (mux_hw == NULL && gate_hw == NULL) {
1374 hw = ERR_PTR(-EINVAL);
1375 goto fail;
1376 }
1377
1378 hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
1379 mux_hw, mux_ops,
1380 NULL, NULL,
1381 gate_hw, gate_ops,
1382 flags);
1383
1384fail:
1385 if (IS_ERR(hw)) {
1386 kfree(gate);
1387 kfree(mux);
1388 }
1389
1390 return hw;
1391}
1392
644static void __init stm32f4_rcc_init(struct device_node *np) 1393static void __init stm32f4_rcc_init(struct device_node *np)
645{ 1394{
646 const char *hse_clk; 1395 const char *hse_clk, *i2s_in_clk;
647 int n; 1396 int n;
648 const struct of_device_id *match; 1397 const struct of_device_id *match;
649 const struct stm32f4_clk_data *data; 1398 const struct stm32f4_clk_data *data;
1399 unsigned long pllcfgr;
1400 const char *pllsrc;
1401 unsigned long pllm;
650 1402
651 base = of_iomap(np, 0); 1403 base = of_iomap(np, 0);
652 if (!base) { 1404 if (!base) {
@@ -666,7 +1418,9 @@ static void __init stm32f4_rcc_init(struct device_node *np)
666 1418
667 data = match->data; 1419 data = match->data;
668 1420
669 clks = kmalloc_array(data->gates_num + END_PRIMARY_CLK, 1421 stm32fx_end_primary_clk = data->end_primary;
1422
1423 clks = kmalloc_array(data->gates_num + stm32fx_end_primary_clk,
670 sizeof(*clks), GFP_KERNEL); 1424 sizeof(*clks), GFP_KERNEL);
671 if (!clks) 1425 if (!clks)
672 goto fail; 1426 goto fail;
@@ -675,12 +1429,54 @@ static void __init stm32f4_rcc_init(struct device_node *np)
675 1429
676 hse_clk = of_clk_get_parent_name(np, 0); 1430 hse_clk = of_clk_get_parent_name(np, 0);
677 1431
678 clk_register_fixed_rate_with_accuracy(NULL, "hsi", NULL, 0, 1432 i2s_in_clk = of_clk_get_parent_name(np, 1);
679 16000000, 160000); 1433
680 stm32f4_rcc_register_pll(hse_clk, "hsi"); 1434 i2s_parents[1] = i2s_in_clk;
1435 sai_parents[2] = i2s_in_clk;
1436
1437 clks[CLK_HSI] = clk_hw_register_fixed_rate_with_accuracy(NULL, "hsi",
1438 NULL, 0, 16000000, 160000);
1439
1440 pllcfgr = readl(base + STM32F4_RCC_PLLCFGR);
1441 pllsrc = pllcfgr & BIT(22) ? hse_clk : "hsi";
1442 pllm = pllcfgr & 0x3f;
1443
1444 clk_hw_register_fixed_factor(NULL, "vco_in", pllsrc,
1445 0, 1, pllm);
1446
1447 stm32f4_rcc_register_pll("vco_in", &data->pll_data[0],
1448 &stm32f4_clk_lock);
1449
1450 clks[PLL_VCO_I2S] = stm32f4_rcc_register_pll("vco_in",
1451 &data->pll_data[1], &stm32f4_clk_lock);
1452
1453 clks[PLL_VCO_SAI] = stm32f4_rcc_register_pll("vco_in",
1454 &data->pll_data[2], &stm32f4_clk_lock);
1455
1456 for (n = 0; n < MAX_POST_DIV; n++) {
1457 const struct stm32f4_pll_post_div_data *post_div;
1458 struct clk_hw *hw;
1459
1460 post_div = &post_div_data[n];
1461
1462 hw = clk_register_pll_div(post_div->name,
1463 post_div->parent,
1464 post_div->flag,
1465 base + post_div->offset,
1466 post_div->shift,
1467 post_div->width,
1468 post_div->flag_div,
1469 post_div->div_table,
1470 clks[post_div->pll_num],
1471 &stm32f4_clk_lock);
1472
1473 if (post_div->idx != NO_IDX)
1474 clks[post_div->idx] = hw;
1475 }
681 1476
682 sys_parents[1] = hse_clk; 1477 sys_parents[1] = hse_clk;
683 clk_register_mux_table( 1478
1479 clks[CLK_SYSCLK] = clk_hw_register_mux_table(
684 NULL, "sys", sys_parents, ARRAY_SIZE(sys_parents), 0, 1480 NULL, "sys", sys_parents, ARRAY_SIZE(sys_parents), 0,
685 base + STM32F4_RCC_CFGR, 0, 3, 0, NULL, &stm32f4_clk_lock); 1481 base + STM32F4_RCC_CFGR, 0, 3, 0, NULL, &stm32f4_clk_lock);
686 1482
@@ -762,6 +1558,33 @@ static void __init stm32f4_rcc_init(struct device_node *np)
762 goto fail; 1558 goto fail;
763 } 1559 }
764 1560
1561 for (n = 0; n < data->aux_clk_num; n++) {
1562 const struct stm32_aux_clk *aux_clk;
1563 struct clk_hw *hw;
1564
1565 aux_clk = &data->aux_clk[n];
1566
1567 hw = stm32_register_aux_clk(aux_clk->name,
1568 aux_clk->parent_names, aux_clk->num_parents,
1569 aux_clk->offset_mux, aux_clk->shift,
1570 aux_clk->mask, aux_clk->offset_gate,
1571 aux_clk->bit_idx, aux_clk->flags,
1572 &stm32f4_clk_lock);
1573
1574 if (IS_ERR(hw)) {
1575 pr_warn("Unable to register %s clk\n", aux_clk->name);
1576 continue;
1577 }
1578
1579 if (aux_clk->idx != NO_IDX)
1580 clks[aux_clk->idx] = hw;
1581 }
1582
1583 if (of_device_is_compatible(np, "st,stm32f746-rcc"))
1584
1585 clk_hw_register_fixed_factor(NULL, "hsi_div488", "hsi", 0,
1586 1, 488);
1587
765 of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL); 1588 of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL);
766 return; 1589 return;
767fail: 1590fail:
@@ -770,3 +1593,4 @@ fail:
770} 1593}
771CLK_OF_DECLARE_DRIVER(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init); 1594CLK_OF_DECLARE_DRIVER(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init);
772CLK_OF_DECLARE_DRIVER(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init); 1595CLK_OF_DECLARE_DRIVER(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init);
1596CLK_OF_DECLARE_DRIVER(stm32f746_rcc, "st,stm32f746-rcc", stm32f4_rcc_init);
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
new file mode 100644
index 000000000000..56741f3cf0a3
--- /dev/null
+++ b/drivers/clk/clk-versaclock5.c
@@ -0,0 +1,791 @@
1/*
2 * Driver for IDT Versaclock 5
3 *
4 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17/*
18 * Possible optimizations:
19 * - Use spread spectrum
20 * - Use integer divider in FOD if applicable
21 */
22
23#include <linux/clk.h>
24#include <linux/clk-provider.h>
25#include <linux/delay.h>
26#include <linux/i2c.h>
27#include <linux/interrupt.h>
28#include <linux/mod_devicetable.h>
29#include <linux/module.h>
30#include <linux/of.h>
31#include <linux/of_platform.h>
32#include <linux/rational.h>
33#include <linux/regmap.h>
34#include <linux/slab.h>
35
36/* VersaClock5 registers */
37#define VC5_OTP_CONTROL 0x00
38
39/* Factory-reserved register block */
40#define VC5_RSVD_DEVICE_ID 0x01
41#define VC5_RSVD_ADC_GAIN_7_0 0x02
42#define VC5_RSVD_ADC_GAIN_15_8 0x03
43#define VC5_RSVD_ADC_OFFSET_7_0 0x04
44#define VC5_RSVD_ADC_OFFSET_15_8 0x05
45#define VC5_RSVD_TEMPY 0x06
46#define VC5_RSVD_OFFSET_TBIN 0x07
47#define VC5_RSVD_GAIN 0x08
48#define VC5_RSVD_TEST_NP 0x09
49#define VC5_RSVD_UNUSED 0x0a
50#define VC5_RSVD_BANDGAP_TRIM_UP 0x0b
51#define VC5_RSVD_BANDGAP_TRIM_DN 0x0c
52#define VC5_RSVD_CLK_R_12_CLK_AMP_4 0x0d
53#define VC5_RSVD_CLK_R_34_CLK_AMP_4 0x0e
54#define VC5_RSVD_CLK_AMP_123 0x0f
55
56/* Configuration register block */
57#define VC5_PRIM_SRC_SHDN 0x10
58#define VC5_PRIM_SRC_SHDN_EN_XTAL BIT(7)
59#define VC5_PRIM_SRC_SHDN_EN_CLKIN BIT(6)
60#define VC5_PRIM_SRC_SHDN_SP BIT(1)
61#define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN BIT(0)
62
63#define VC5_VCO_BAND 0x11
64#define VC5_XTAL_X1_LOAD_CAP 0x12
65#define VC5_XTAL_X2_LOAD_CAP 0x13
66#define VC5_REF_DIVIDER 0x15
67#define VC5_REF_DIVIDER_SEL_PREDIV2 BIT(7)
68#define VC5_REF_DIVIDER_REF_DIV(n) ((n) & 0x3f)
69
70#define VC5_VCO_CTRL_AND_PREDIV 0x16
71#define VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV BIT(7)
72
73#define VC5_FEEDBACK_INT_DIV 0x17
74#define VC5_FEEDBACK_INT_DIV_BITS 0x18
75#define VC5_FEEDBACK_FRAC_DIV(n) (0x19 + (n))
76#define VC5_RC_CONTROL0 0x1e
77#define VC5_RC_CONTROL1 0x1f
78/* Register 0x20 is factory reserved */
79
80/* Output divider control for divider 1,2,3,4 */
81#define VC5_OUT_DIV_CONTROL(idx) (0x21 + ((idx) * 0x10))
82#define VC5_OUT_DIV_CONTROL_RESET BIT(7)
83#define VC5_OUT_DIV_CONTROL_SELB_NORM BIT(3)
84#define VC5_OUT_DIV_CONTROL_SEL_EXT BIT(2)
85#define VC5_OUT_DIV_CONTROL_INT_MODE BIT(1)
86#define VC5_OUT_DIV_CONTROL_EN_FOD BIT(0)
87
88#define VC5_OUT_DIV_FRAC(idx, n) (0x22 + ((idx) * 0x10) + (n))
89#define VC5_OUT_DIV_FRAC4_OD_SCEE BIT(1)
90
91#define VC5_OUT_DIV_STEP_SPREAD(idx, n) (0x26 + ((idx) * 0x10) + (n))
92#define VC5_OUT_DIV_SPREAD_MOD(idx, n) (0x29 + ((idx) * 0x10) + (n))
93#define VC5_OUT_DIV_SKEW_INT(idx, n) (0x2b + ((idx) * 0x10) + (n))
94#define VC5_OUT_DIV_INT(idx, n) (0x2d + ((idx) * 0x10) + (n))
95#define VC5_OUT_DIV_SKEW_FRAC(idx) (0x2f + ((idx) * 0x10))
96/* Registers 0x30, 0x40, 0x50 are factory reserved */
97
98/* Clock control register for clock 1,2 */
99#define VC5_CLK_OUTPUT_CFG(idx, n) (0x60 + ((idx) * 0x2) + (n))
100#define VC5_CLK_OUTPUT_CFG1_EN_CLKBUF BIT(0)
101
102#define VC5_CLK_OE_SHDN 0x68
103#define VC5_CLK_OS_SHDN 0x69
104
105#define VC5_GLOBAL_REGISTER 0x76
106#define VC5_GLOBAL_REGISTER_GLOBAL_RESET BIT(5)
107
108/* PLL/VCO runs between 2.5 GHz and 3.0 GHz */
109#define VC5_PLL_VCO_MIN 2500000000UL
110#define VC5_PLL_VCO_MAX 3000000000UL
111
112/* VC5 Input mux settings */
113#define VC5_MUX_IN_XIN BIT(0)
114#define VC5_MUX_IN_CLKIN BIT(1)
115
116/* Supported IDT VC5 models. */
117enum vc5_model {
118 IDT_VC5_5P49V5923,
119 IDT_VC5_5P49V5933,
120};
121
122struct vc5_driver_data;
123
124struct vc5_hw_data {
125 struct clk_hw hw;
126 struct vc5_driver_data *vc5;
127 u32 div_int;
128 u32 div_frc;
129 unsigned int num;
130};
131
132struct vc5_driver_data {
133 struct i2c_client *client;
134 struct regmap *regmap;
135 enum vc5_model model;
136
137 struct clk *pin_xin;
138 struct clk *pin_clkin;
139 unsigned char clk_mux_ins;
140 struct clk_hw clk_mux;
141 struct vc5_hw_data clk_pll;
142 struct vc5_hw_data clk_fod[2];
143 struct vc5_hw_data clk_out[3];
144};
145
146static const char * const vc5_mux_names[] = {
147 "mux"
148};
149
150static const char * const vc5_pll_names[] = {
151 "pll"
152};
153
154static const char * const vc5_fod_names[] = {
155 "fod0", "fod1", "fod2", "fod3",
156};
157
158static const char * const vc5_clk_out_names[] = {
159 "out0_sel_i2cb", "out1", "out2", "out3", "out4",
160};
161
162/*
163 * VersaClock5 i2c regmap
164 */
165static bool vc5_regmap_is_writeable(struct device *dev, unsigned int reg)
166{
167 /* Factory reserved regs, make them read-only */
168 if (reg <= 0xf)
169 return false;
170
171 /* Factory reserved regs, make them read-only */
172 if (reg == 0x14 || reg == 0x1c || reg == 0x1d)
173 return false;
174
175 return true;
176}
177
178static const struct regmap_config vc5_regmap_config = {
179 .reg_bits = 8,
180 .val_bits = 8,
181 .cache_type = REGCACHE_RBTREE,
182 .max_register = 0x76,
183 .writeable_reg = vc5_regmap_is_writeable,
184};
185
186/*
187 * VersaClock5 input multiplexer between XTAL and CLKIN divider
188 */
189static unsigned char vc5_mux_get_parent(struct clk_hw *hw)
190{
191 struct vc5_driver_data *vc5 =
192 container_of(hw, struct vc5_driver_data, clk_mux);
193 const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
194 unsigned int src;
195
196 regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &src);
197 src &= mask;
198
199 if (src == VC5_PRIM_SRC_SHDN_EN_XTAL)
200 return 0;
201
202 if (src == VC5_PRIM_SRC_SHDN_EN_CLKIN)
203 return 1;
204
205 dev_warn(&vc5->client->dev,
206 "Invalid clock input configuration (%02x)\n", src);
207 return 0;
208}
209
210static int vc5_mux_set_parent(struct clk_hw *hw, u8 index)
211{
212 struct vc5_driver_data *vc5 =
213 container_of(hw, struct vc5_driver_data, clk_mux);
214 const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
215 u8 src;
216
217 if ((index > 1) || !vc5->clk_mux_ins)
218 return -EINVAL;
219
220 if (vc5->clk_mux_ins == (VC5_MUX_IN_CLKIN | VC5_MUX_IN_XIN)) {
221 if (index == 0)
222 src = VC5_PRIM_SRC_SHDN_EN_XTAL;
223 if (index == 1)
224 src = VC5_PRIM_SRC_SHDN_EN_CLKIN;
225 } else {
226 if (index != 0)
227 return -EINVAL;
228
229 if (vc5->clk_mux_ins == VC5_MUX_IN_XIN)
230 src = VC5_PRIM_SRC_SHDN_EN_XTAL;
231 if (vc5->clk_mux_ins == VC5_MUX_IN_CLKIN)
232 src = VC5_PRIM_SRC_SHDN_EN_CLKIN;
233 }
234
235 return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src);
236}
237
238static unsigned long vc5_mux_recalc_rate(struct clk_hw *hw,
239 unsigned long parent_rate)
240{
241 struct vc5_driver_data *vc5 =
242 container_of(hw, struct vc5_driver_data, clk_mux);
243 unsigned int prediv, div;
244
245 regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv);
246
247 /* The bypass_prediv is set, PLL fed from Ref_in directly. */
248 if (prediv & VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV)
249 return parent_rate;
250
251 regmap_read(vc5->regmap, VC5_REF_DIVIDER, &div);
252
253 /* The Sel_prediv2 is set, PLL fed from prediv2 (Ref_in / 2) */
254 if (div & VC5_REF_DIVIDER_SEL_PREDIV2)
255 return parent_rate / 2;
256 else
257 return parent_rate / VC5_REF_DIVIDER_REF_DIV(div);
258}
259
260static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate,
261 unsigned long *parent_rate)
262{
263 unsigned long idiv;
264
265 /* PLL cannot operate with input clock above 50 MHz. */
266 if (rate > 50000000)
267 return -EINVAL;
268
269 /* CLKIN within range of PLL input, feed directly to PLL. */
270 if (*parent_rate <= 50000000)
271 return *parent_rate;
272
273 idiv = DIV_ROUND_UP(*parent_rate, rate);
274 if (idiv > 127)
275 return -EINVAL;
276
277 return *parent_rate / idiv;
278}
279
280static int vc5_mux_set_rate(struct clk_hw *hw, unsigned long rate,
281 unsigned long parent_rate)
282{
283 struct vc5_driver_data *vc5 =
284 container_of(hw, struct vc5_driver_data, clk_mux);
285 unsigned long idiv;
286 u8 div;
287
288 /* CLKIN within range of PLL input, feed directly to PLL. */
289 if (parent_rate <= 50000000) {
290 regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
291 VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV,
292 VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV);
293 regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, 0x00);
294 return 0;
295 }
296
297 idiv = DIV_ROUND_UP(parent_rate, rate);
298
299 /* We have dedicated div-2 predivider. */
300 if (idiv == 2)
301 div = VC5_REF_DIVIDER_SEL_PREDIV2;
302 else
303 div = VC5_REF_DIVIDER_REF_DIV(idiv);
304
305 regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, div);
306 regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
307 VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV, 0);
308
309 return 0;
310}
311
312static const struct clk_ops vc5_mux_ops = {
313 .set_parent = vc5_mux_set_parent,
314 .get_parent = vc5_mux_get_parent,
315 .recalc_rate = vc5_mux_recalc_rate,
316 .round_rate = vc5_mux_round_rate,
317 .set_rate = vc5_mux_set_rate,
318};
319
320/*
321 * VersaClock5 PLL/VCO
322 */
323static unsigned long vc5_pll_recalc_rate(struct clk_hw *hw,
324 unsigned long parent_rate)
325{
326 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
327 struct vc5_driver_data *vc5 = hwdata->vc5;
328 u32 div_int, div_frc;
329 u8 fb[5];
330
331 regmap_bulk_read(vc5->regmap, VC5_FEEDBACK_INT_DIV, fb, 5);
332
333 div_int = (fb[0] << 4) | (fb[1] >> 4);
334 div_frc = (fb[2] << 16) | (fb[3] << 8) | fb[4];
335
336 /* The PLL divider has 12 integer bits and 24 fractional bits */
337 return (parent_rate * div_int) + ((parent_rate * div_frc) >> 24);
338}
339
340static long vc5_pll_round_rate(struct clk_hw *hw, unsigned long rate,
341 unsigned long *parent_rate)
342{
343 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
344 u32 div_int;
345 u64 div_frc;
346
347 if (rate < VC5_PLL_VCO_MIN)
348 rate = VC5_PLL_VCO_MIN;
349 if (rate > VC5_PLL_VCO_MAX)
350 rate = VC5_PLL_VCO_MAX;
351
352 /* Determine integer part, which is 12 bit wide */
353 div_int = rate / *parent_rate;
354 if (div_int > 0xfff)
355 rate = *parent_rate * 0xfff;
356
357 /* Determine best fractional part, which is 24 bit wide */
358 div_frc = rate % *parent_rate;
359 div_frc *= BIT(24) - 1;
360 do_div(div_frc, *parent_rate);
361
362 hwdata->div_int = div_int;
363 hwdata->div_frc = (u32)div_frc;
364
365 return (*parent_rate * div_int) + ((*parent_rate * div_frc) >> 24);
366}
367
368static int vc5_pll_set_rate(struct clk_hw *hw, unsigned long rate,
369 unsigned long parent_rate)
370{
371 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
372 struct vc5_driver_data *vc5 = hwdata->vc5;
373 u8 fb[5];
374
375 fb[0] = hwdata->div_int >> 4;
376 fb[1] = hwdata->div_int << 4;
377 fb[2] = hwdata->div_frc >> 16;
378 fb[3] = hwdata->div_frc >> 8;
379 fb[4] = hwdata->div_frc;
380
381 return regmap_bulk_write(vc5->regmap, VC5_FEEDBACK_INT_DIV, fb, 5);
382}
383
384static const struct clk_ops vc5_pll_ops = {
385 .recalc_rate = vc5_pll_recalc_rate,
386 .round_rate = vc5_pll_round_rate,
387 .set_rate = vc5_pll_set_rate,
388};
389
390static unsigned long vc5_fod_recalc_rate(struct clk_hw *hw,
391 unsigned long parent_rate)
392{
393 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
394 struct vc5_driver_data *vc5 = hwdata->vc5;
395 /* VCO frequency is divided by two before entering FOD */
396 u32 f_in = parent_rate / 2;
397 u32 div_int, div_frc;
398 u8 od_int[2];
399 u8 od_frc[4];
400
401 regmap_bulk_read(vc5->regmap, VC5_OUT_DIV_INT(hwdata->num, 0),
402 od_int, 2);
403 regmap_bulk_read(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
404 od_frc, 4);
405
406 div_int = (od_int[0] << 4) | (od_int[1] >> 4);
407 div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) |
408 (od_frc[2] << 6) | (od_frc[3] >> 2);
409
410 /* The PLL divider has 12 integer bits and 30 fractional bits */
411 return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
412}
413
414static long vc5_fod_round_rate(struct clk_hw *hw, unsigned long rate,
415 unsigned long *parent_rate)
416{
417 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
418 /* VCO frequency is divided by two before entering FOD */
419 u32 f_in = *parent_rate / 2;
420 u32 div_int;
421 u64 div_frc;
422
423 /* Determine integer part, which is 12 bit wide */
424 div_int = f_in / rate;
425 /*
426 * WARNING: The clock chip does not output signal if the integer part
427 * of the divider is 0xfff and fractional part is non-zero.
428 * Clamp the divider at 0xffe to keep the code simple.
429 */
430 if (div_int > 0xffe) {
431 div_int = 0xffe;
432 rate = f_in / div_int;
433 }
434
435 /* Determine best fractional part, which is 30 bit wide */
436 div_frc = f_in % rate;
437 div_frc <<= 24;
438 do_div(div_frc, rate);
439
440 hwdata->div_int = div_int;
441 hwdata->div_frc = (u32)div_frc;
442
443 return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
444}
445
446static int vc5_fod_set_rate(struct clk_hw *hw, unsigned long rate,
447 unsigned long parent_rate)
448{
449 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
450 struct vc5_driver_data *vc5 = hwdata->vc5;
451 u8 data[14] = {
452 hwdata->div_frc >> 22, hwdata->div_frc >> 14,
453 hwdata->div_frc >> 6, hwdata->div_frc << 2,
454 0, 0, 0, 0, 0,
455 0, 0,
456 hwdata->div_int >> 4, hwdata->div_int << 4,
457 0
458 };
459
460 regmap_bulk_write(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
461 data, 14);
462
463 /*
464 * Toggle magic bit in undocumented register for unknown reason.
465 * This is what the IDT timing commander tool does and the chip
466 * datasheet somewhat implies this is needed, but the register
467 * and the bit is not documented.
468 */
469 regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
470 VC5_GLOBAL_REGISTER_GLOBAL_RESET, 0);
471 regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
472 VC5_GLOBAL_REGISTER_GLOBAL_RESET,
473 VC5_GLOBAL_REGISTER_GLOBAL_RESET);
474 return 0;
475}
476
477static const struct clk_ops vc5_fod_ops = {
478 .recalc_rate = vc5_fod_recalc_rate,
479 .round_rate = vc5_fod_round_rate,
480 .set_rate = vc5_fod_set_rate,
481};
482
483static int vc5_clk_out_prepare(struct clk_hw *hw)
484{
485 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
486 struct vc5_driver_data *vc5 = hwdata->vc5;
487
488 /* Enable the clock buffer */
489 regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
490 VC5_CLK_OUTPUT_CFG1_EN_CLKBUF,
491 VC5_CLK_OUTPUT_CFG1_EN_CLKBUF);
492 return 0;
493}
494
495static void vc5_clk_out_unprepare(struct clk_hw *hw)
496{
497 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
498 struct vc5_driver_data *vc5 = hwdata->vc5;
499
500 /* Enable the clock buffer */
501 regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
502 VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0);
503}
504
505static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
506{
507 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
508 struct vc5_driver_data *vc5 = hwdata->vc5;
509 const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
510 VC5_OUT_DIV_CONTROL_SEL_EXT |
511 VC5_OUT_DIV_CONTROL_EN_FOD;
512 const u8 fodclkmask = VC5_OUT_DIV_CONTROL_SELB_NORM |
513 VC5_OUT_DIV_CONTROL_EN_FOD;
514 const u8 extclk = VC5_OUT_DIV_CONTROL_SELB_NORM |
515 VC5_OUT_DIV_CONTROL_SEL_EXT;
516 unsigned int src;
517
518 regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
519 src &= mask;
520
521 if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD)
522 return 0;
523
524 if (src == extclk)
525 return 1;
526
527 dev_warn(&vc5->client->dev,
528 "Invalid clock output configuration (%02x)\n", src);
529 return 0;
530}
531
532static int vc5_clk_out_set_parent(struct clk_hw *hw, u8 index)
533{
534 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
535 struct vc5_driver_data *vc5 = hwdata->vc5;
536 const u8 mask = VC5_OUT_DIV_CONTROL_RESET |
537 VC5_OUT_DIV_CONTROL_SELB_NORM |
538 VC5_OUT_DIV_CONTROL_SEL_EXT |
539 VC5_OUT_DIV_CONTROL_EN_FOD;
540 const u8 extclk = VC5_OUT_DIV_CONTROL_SELB_NORM |
541 VC5_OUT_DIV_CONTROL_SEL_EXT;
542 u8 src = VC5_OUT_DIV_CONTROL_RESET;
543
544 if (index == 0)
545 src |= VC5_OUT_DIV_CONTROL_EN_FOD;
546 else
547 src |= extclk;
548
549 return regmap_update_bits(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num),
550 mask, src);
551}
552
553static const struct clk_ops vc5_clk_out_ops = {
554 .prepare = vc5_clk_out_prepare,
555 .unprepare = vc5_clk_out_unprepare,
556 .set_parent = vc5_clk_out_set_parent,
557 .get_parent = vc5_clk_out_get_parent,
558};
559
560static struct clk_hw *vc5_of_clk_get(struct of_phandle_args *clkspec,
561 void *data)
562{
563 struct vc5_driver_data *vc5 = data;
564 unsigned int idx = clkspec->args[0];
565
566 if (idx > 2)
567 return ERR_PTR(-EINVAL);
568
569 return &vc5->clk_out[idx].hw;
570}
571
572static int vc5_map_index_to_output(const enum vc5_model model,
573 const unsigned int n)
574{
575 switch (model) {
576 case IDT_VC5_5P49V5933:
577 return (n == 0) ? 0 : 3;
578 case IDT_VC5_5P49V5923:
579 default:
580 return n;
581 }
582}
583
584static const struct of_device_id clk_vc5_of_match[];
585
586static int vc5_probe(struct i2c_client *client,
587 const struct i2c_device_id *id)
588{
589 const struct of_device_id *of_id =
590 of_match_device(clk_vc5_of_match, &client->dev);
591 struct vc5_driver_data *vc5;
592 struct clk_init_data init;
593 const char *parent_names[2];
594 unsigned int n, idx;
595 int ret;
596
597 vc5 = devm_kzalloc(&client->dev, sizeof(*vc5), GFP_KERNEL);
598 if (vc5 == NULL)
599 return -ENOMEM;
600
601 i2c_set_clientdata(client, vc5);
602 vc5->client = client;
603 vc5->model = (enum vc5_model)of_id->data;
604
605 vc5->pin_xin = devm_clk_get(&client->dev, "xin");
606 if (PTR_ERR(vc5->pin_xin) == -EPROBE_DEFER)
607 return -EPROBE_DEFER;
608
609 vc5->pin_clkin = devm_clk_get(&client->dev, "clkin");
610 if (PTR_ERR(vc5->pin_clkin) == -EPROBE_DEFER)
611 return -EPROBE_DEFER;
612
613 vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config);
614 if (IS_ERR(vc5->regmap)) {
615 dev_err(&client->dev, "failed to allocate register map\n");
616 return PTR_ERR(vc5->regmap);
617 }
618
619 /* Register clock input mux */
620 memset(&init, 0, sizeof(init));
621
622 if (!IS_ERR(vc5->pin_xin)) {
623 vc5->clk_mux_ins |= VC5_MUX_IN_XIN;
624 parent_names[init.num_parents++] = __clk_get_name(vc5->pin_xin);
625 } else if (vc5->model == IDT_VC5_5P49V5933) {
626 /* IDT VC5 5P49V5933 has built-in oscilator. */
627 vc5->pin_xin = clk_register_fixed_rate(&client->dev,
628 "internal-xtal", NULL,
629 0, 25000000);
630 if (IS_ERR(vc5->pin_xin))
631 return PTR_ERR(vc5->pin_xin);
632 vc5->clk_mux_ins |= VC5_MUX_IN_XIN;
633 parent_names[init.num_parents++] = __clk_get_name(vc5->pin_xin);
634 }
635
636 if (!IS_ERR(vc5->pin_clkin)) {
637 vc5->clk_mux_ins |= VC5_MUX_IN_CLKIN;
638 parent_names[init.num_parents++] =
639 __clk_get_name(vc5->pin_clkin);
640 }
641
642 if (!init.num_parents) {
643 dev_err(&client->dev, "no input clock specified!\n");
644 return -EINVAL;
645 }
646
647 init.name = vc5_mux_names[0];
648 init.ops = &vc5_mux_ops;
649 init.flags = 0;
650 init.parent_names = parent_names;
651 vc5->clk_mux.init = &init;
652 ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux);
653 if (ret) {
654 dev_err(&client->dev, "unable to register %s\n", init.name);
655 goto err_clk;
656 }
657
658 /* Register PLL */
659 memset(&init, 0, sizeof(init));
660 init.name = vc5_pll_names[0];
661 init.ops = &vc5_pll_ops;
662 init.flags = CLK_SET_RATE_PARENT;
663 init.parent_names = vc5_mux_names;
664 init.num_parents = 1;
665 vc5->clk_pll.num = 0;
666 vc5->clk_pll.vc5 = vc5;
667 vc5->clk_pll.hw.init = &init;
668 ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw);
669 if (ret) {
670 dev_err(&client->dev, "unable to register %s\n", init.name);
671 goto err_clk;
672 }
673
674 /* Register FODs */
675 for (n = 0; n < 2; n++) {
676 idx = vc5_map_index_to_output(vc5->model, n);
677 memset(&init, 0, sizeof(init));
678 init.name = vc5_fod_names[idx];
679 init.ops = &vc5_fod_ops;
680 init.flags = CLK_SET_RATE_PARENT;
681 init.parent_names = vc5_pll_names;
682 init.num_parents = 1;
683 vc5->clk_fod[n].num = idx;
684 vc5->clk_fod[n].vc5 = vc5;
685 vc5->clk_fod[n].hw.init = &init;
686 ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw);
687 if (ret) {
688 dev_err(&client->dev, "unable to register %s\n",
689 init.name);
690 goto err_clk;
691 }
692 }
693
694 /* Register MUX-connected OUT0_I2C_SELB output */
695 memset(&init, 0, sizeof(init));
696 init.name = vc5_clk_out_names[0];
697 init.ops = &vc5_clk_out_ops;
698 init.flags = CLK_SET_RATE_PARENT;
699 init.parent_names = vc5_mux_names;
700 init.num_parents = 1;
701 vc5->clk_out[0].num = idx;
702 vc5->clk_out[0].vc5 = vc5;
703 vc5->clk_out[0].hw.init = &init;
704 ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw);
705 if (ret) {
706 dev_err(&client->dev, "unable to register %s\n",
707 init.name);
708 goto err_clk;
709 }
710
711 /* Register FOD-connected OUTx outputs */
712 for (n = 1; n < 3; n++) {
713 idx = vc5_map_index_to_output(vc5->model, n - 1);
714 parent_names[0] = vc5_fod_names[idx];
715 if (n == 1)
716 parent_names[1] = vc5_mux_names[0];
717 else
718 parent_names[1] = vc5_clk_out_names[n - 1];
719
720 memset(&init, 0, sizeof(init));
721 init.name = vc5_clk_out_names[idx + 1];
722 init.ops = &vc5_clk_out_ops;
723 init.flags = CLK_SET_RATE_PARENT;
724 init.parent_names = parent_names;
725 init.num_parents = 2;
726 vc5->clk_out[n].num = idx;
727 vc5->clk_out[n].vc5 = vc5;
728 vc5->clk_out[n].hw.init = &init;
729 ret = devm_clk_hw_register(&client->dev,
730 &vc5->clk_out[n].hw);
731 if (ret) {
732 dev_err(&client->dev, "unable to register %s\n",
733 init.name);
734 goto err_clk;
735 }
736 }
737
738 ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5);
739 if (ret) {
740 dev_err(&client->dev, "unable to add clk provider\n");
741 goto err_clk;
742 }
743
744 return 0;
745
746err_clk:
747 if (vc5->model == IDT_VC5_5P49V5933)
748 clk_unregister_fixed_rate(vc5->pin_xin);
749 return ret;
750}
751
752static int vc5_remove(struct i2c_client *client)
753{
754 struct vc5_driver_data *vc5 = i2c_get_clientdata(client);
755
756 of_clk_del_provider(client->dev.of_node);
757
758 if (vc5->model == IDT_VC5_5P49V5933)
759 clk_unregister_fixed_rate(vc5->pin_xin);
760
761 return 0;
762}
763
764static const struct i2c_device_id vc5_id[] = {
765 { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 },
766 { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 },
767 { }
768};
769MODULE_DEVICE_TABLE(i2c, vc5_id);
770
771static const struct of_device_id clk_vc5_of_match[] = {
772 { .compatible = "idt,5p49v5923", .data = (void *)IDT_VC5_5P49V5923 },
773 { .compatible = "idt,5p49v5933", .data = (void *)IDT_VC5_5P49V5933 },
774 { },
775};
776MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
777
778static struct i2c_driver vc5_driver = {
779 .driver = {
780 .name = "vc5",
781 .of_match_table = clk_vc5_of_match,
782 },
783 .probe = vc5_probe,
784 .remove = vc5_remove,
785 .id_table = vc5_id,
786};
787module_i2c_driver(vc5_driver);
788
789MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
790MODULE_DESCRIPTION("IDT VersaClock 5 driver");
791MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c
index 0621fbfb4beb..a47960aacfa5 100644
--- a/drivers/clk/clk-wm831x.c
+++ b/drivers/clk/clk-wm831x.c
@@ -97,7 +97,8 @@ static int wm831x_fll_prepare(struct clk_hw *hw)
97 if (ret != 0) 97 if (ret != 0)
98 dev_crit(wm831x->dev, "Failed to enable FLL: %d\n", ret); 98 dev_crit(wm831x->dev, "Failed to enable FLL: %d\n", ret);
99 99
100 usleep_range(2000, 2000); 100 /* wait 2-3 ms for new frequency taking effect */
101 usleep_range(2000, 3000);
101 102
102 return ret; 103 return ret;
103} 104}
diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index cbed6602172b..7098bfd32b1b 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -14,6 +14,13 @@ config COMMON_CLK_HI3519
14 help 14 help
15 Build the clock driver for hi3519. 15 Build the clock driver for hi3519.
16 16
17config COMMON_CLK_HI3660
18 bool "Hi3660 Clock Driver"
19 depends on ARCH_HISI || COMPILE_TEST
20 default ARCH_HISI
21 help
22 Build the clock driver for hi3660.
23
17config COMMON_CLK_HI3798CV200 24config COMMON_CLK_HI3798CV200
18 tristate "Hi3798CV200 Clock Driver" 25 tristate "Hi3798CV200 Clock Driver"
19 depends on ARCH_HISI || COMPILE_TEST 26 depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index 4eec5e511e4c..1e4c3ddbad84 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o
9obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o 9obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o
10obj-$(CONFIG_COMMON_CLK_HI3516CV300) += crg-hi3516cv300.o 10obj-$(CONFIG_COMMON_CLK_HI3516CV300) += crg-hi3516cv300.o
11obj-$(CONFIG_COMMON_CLK_HI3519) += clk-hi3519.o 11obj-$(CONFIG_COMMON_CLK_HI3519) += clk-hi3519.o
12obj-$(CONFIG_COMMON_CLK_HI3660) += clk-hi3660.o
12obj-$(CONFIG_COMMON_CLK_HI3798CV200) += crg-hi3798cv200.o 13obj-$(CONFIG_COMMON_CLK_HI3798CV200) += crg-hi3798cv200.o
13obj-$(CONFIG_COMMON_CLK_HI6220) += clk-hi6220.o 14obj-$(CONFIG_COMMON_CLK_HI6220) += clk-hi6220.o
14obj-$(CONFIG_RESET_HISI) += reset.o 15obj-$(CONFIG_RESET_HISI) += reset.o
diff --git a/drivers/clk/hisilicon/clk-hi3660.c b/drivers/clk/hisilicon/clk-hi3660.c
new file mode 100644
index 000000000000..96a9697b06cf
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3660.c
@@ -0,0 +1,567 @@
1/*
2 * Copyright (c) 2016-2017 Linaro Ltd.
3 * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <dt-bindings/clock/hi3660-clock.h>
12#include <linux/clk-provider.h>
13#include <linux/of_device.h>
14#include <linux/platform_device.h>
15#include "clk.h"
16
17static const struct hisi_fixed_rate_clock hi3660_fixed_rate_clks[] = {
18 { HI3660_CLKIN_SYS, "clkin_sys", NULL, 0, 19200000, },
19 { HI3660_CLKIN_REF, "clkin_ref", NULL, 0, 32764, },
20 { HI3660_CLK_FLL_SRC, "clk_fll_src", NULL, 0, 128000000, },
21 { HI3660_CLK_PPLL0, "clk_ppll0", NULL, 0, 1600000000, },
22 { HI3660_CLK_PPLL1, "clk_ppll1", NULL, 0, 1866000000, },
23 { HI3660_CLK_PPLL2, "clk_ppll2", NULL, 0, 960000000, },
24 { HI3660_CLK_PPLL3, "clk_ppll3", NULL, 0, 1290000000, },
25 { HI3660_CLK_SCPLL, "clk_scpll", NULL, 0, 245760000, },
26 { HI3660_PCLK, "pclk", NULL, 0, 20000000, },
27 { HI3660_CLK_UART0_DBG, "clk_uart0_dbg", NULL, 0, 19200000, },
28 { HI3660_CLK_UART6, "clk_uart6", NULL, 0, 19200000, },
29 { HI3660_OSC32K, "osc32k", NULL, 0, 32764, },
30 { HI3660_OSC19M, "osc19m", NULL, 0, 19200000, },
31 { HI3660_CLK_480M, "clk_480m", NULL, 0, 480000000, },
32 { HI3660_CLK_INV, "clk_inv", NULL, 0, 10000000, },
33};
34
35/* crgctrl */
36static const struct hisi_fixed_factor_clock hi3660_crg_fixed_factor_clks[] = {
37 { HI3660_FACTOR_UART3, "clk_factor_uart3", "iomcu_peri0", 1, 8, 0, },
38 { HI3660_CLK_FACTOR_MMC, "clk_factor_mmc", "clkin_sys", 1, 6, 0, },
39 { HI3660_CLK_GATE_I2C0, "clk_gate_i2c0", "clk_i2c0_iomcu", 1, 4, 0, },
40 { HI3660_CLK_GATE_I2C1, "clk_gate_i2c1", "clk_i2c1_iomcu", 1, 4, 0, },
41 { HI3660_CLK_GATE_I2C2, "clk_gate_i2c2", "clk_i2c2_iomcu", 1, 4, 0, },
42 { HI3660_CLK_GATE_I2C6, "clk_gate_i2c6", "clk_i2c6_iomcu", 1, 4, 0, },
43 { HI3660_CLK_DIV_SYSBUS, "clk_div_sysbus", "clk_mux_sysbus", 1, 7, 0, },
44 { HI3660_CLK_DIV_320M, "clk_div_320m", "clk_320m_pll_gt", 1, 5, 0, },
45 { HI3660_CLK_DIV_A53, "clk_div_a53hpm", "clk_a53hpm_andgt", 1, 2, 0, },
46 { HI3660_CLK_GATE_SPI0, "clk_gate_spi0", "clk_ppll0", 1, 8, 0, },
47 { HI3660_CLK_GATE_SPI2, "clk_gate_spi2", "clk_ppll0", 1, 8, 0, },
48 { HI3660_PCIEPHY_REF, "clk_pciephy_ref", "clk_div_pciephy", 1, 1, 0, },
49 { HI3660_CLK_ABB_USB, "clk_abb_usb", "clk_gate_usb_tcxo_en", 1, 1, 0 },
50};
51
52static const struct hisi_gate_clock hi3660_crgctrl_gate_sep_clks[] = {
53 { HI3660_HCLK_GATE_SDIO0, "hclk_gate_sdio0", "clk_div_sysbus",
54 CLK_SET_RATE_PARENT, 0x0, 21, 0, },
55 { HI3660_HCLK_GATE_SD, "hclk_gate_sd", "clk_div_sysbus",
56 CLK_SET_RATE_PARENT, 0x0, 30, 0, },
57 { HI3660_CLK_GATE_AOMM, "clk_gate_aomm", "clk_div_aomm",
58 CLK_SET_RATE_PARENT, 0x0, 31, 0, },
59 { HI3660_PCLK_GPIO0, "pclk_gpio0", "clk_div_cfgbus",
60 CLK_SET_RATE_PARENT, 0x10, 0, 0, },
61 { HI3660_PCLK_GPIO1, "pclk_gpio1", "clk_div_cfgbus",
62 CLK_SET_RATE_PARENT, 0x10, 1, 0, },
63 { HI3660_PCLK_GPIO2, "pclk_gpio2", "clk_div_cfgbus",
64 CLK_SET_RATE_PARENT, 0x10, 2, 0, },
65 { HI3660_PCLK_GPIO3, "pclk_gpio3", "clk_div_cfgbus",
66 CLK_SET_RATE_PARENT, 0x10, 3, 0, },
67 { HI3660_PCLK_GPIO4, "pclk_gpio4", "clk_div_cfgbus",
68 CLK_SET_RATE_PARENT, 0x10, 4, 0, },
69 { HI3660_PCLK_GPIO5, "pclk_gpio5", "clk_div_cfgbus",
70 CLK_SET_RATE_PARENT, 0x10, 5, 0, },
71 { HI3660_PCLK_GPIO6, "pclk_gpio6", "clk_div_cfgbus",
72 CLK_SET_RATE_PARENT, 0x10, 6, 0, },
73 { HI3660_PCLK_GPIO7, "pclk_gpio7", "clk_div_cfgbus",
74 CLK_SET_RATE_PARENT, 0x10, 7, 0, },
75 { HI3660_PCLK_GPIO8, "pclk_gpio8", "clk_div_cfgbus",
76 CLK_SET_RATE_PARENT, 0x10, 8, 0, },
77 { HI3660_PCLK_GPIO9, "pclk_gpio9", "clk_div_cfgbus",
78 CLK_SET_RATE_PARENT, 0x10, 9, 0, },
79 { HI3660_PCLK_GPIO10, "pclk_gpio10", "clk_div_cfgbus",
80 CLK_SET_RATE_PARENT, 0x10, 10, 0, },
81 { HI3660_PCLK_GPIO11, "pclk_gpio11", "clk_div_cfgbus",
82 CLK_SET_RATE_PARENT, 0x10, 11, 0, },
83 { HI3660_PCLK_GPIO12, "pclk_gpio12", "clk_div_cfgbus",
84 CLK_SET_RATE_PARENT, 0x10, 12, 0, },
85 { HI3660_PCLK_GPIO13, "pclk_gpio13", "clk_div_cfgbus",
86 CLK_SET_RATE_PARENT, 0x10, 13, 0, },
87 { HI3660_PCLK_GPIO14, "pclk_gpio14", "clk_div_cfgbus",
88 CLK_SET_RATE_PARENT, 0x10, 14, 0, },
89 { HI3660_PCLK_GPIO15, "pclk_gpio15", "clk_div_cfgbus",
90 CLK_SET_RATE_PARENT, 0x10, 15, 0, },
91 { HI3660_PCLK_GPIO16, "pclk_gpio16", "clk_div_cfgbus",
92 CLK_SET_RATE_PARENT, 0x10, 16, 0, },
93 { HI3660_PCLK_GPIO17, "pclk_gpio17", "clk_div_cfgbus",
94 CLK_SET_RATE_PARENT, 0x10, 17, 0, },
95 { HI3660_PCLK_GPIO18, "pclk_gpio18", "clk_div_ioperi",
96 CLK_SET_RATE_PARENT, 0x10, 18, 0, },
97 { HI3660_PCLK_GPIO19, "pclk_gpio19", "clk_div_ioperi",
98 CLK_SET_RATE_PARENT, 0x10, 19, 0, },
99 { HI3660_PCLK_GPIO20, "pclk_gpio20", "clk_div_cfgbus",
100 CLK_SET_RATE_PARENT, 0x10, 20, 0, },
101 { HI3660_PCLK_GPIO21, "pclk_gpio21", "clk_div_cfgbus",
102 CLK_SET_RATE_PARENT, 0x10, 21, 0, },
103 { HI3660_CLK_GATE_SPI3, "clk_gate_spi3", "clk_div_ioperi",
104 CLK_SET_RATE_PARENT, 0x10, 30, 0, },
105 { HI3660_CLK_GATE_I2C7, "clk_gate_i2c7", "clk_mux_i2c",
106 CLK_SET_RATE_PARENT, 0x10, 31, 0, },
107 { HI3660_CLK_GATE_I2C3, "clk_gate_i2c3", "clk_mux_i2c",
108 CLK_SET_RATE_PARENT, 0x20, 7, 0, },
109 { HI3660_CLK_GATE_SPI1, "clk_gate_spi1", "clk_mux_spi",
110 CLK_SET_RATE_PARENT, 0x20, 9, 0, },
111 { HI3660_CLK_GATE_UART1, "clk_gate_uart1", "clk_mux_uarth",
112 CLK_SET_RATE_PARENT, 0x20, 11, 0, },
113 { HI3660_CLK_GATE_UART2, "clk_gate_uart2", "clk_mux_uart1",
114 CLK_SET_RATE_PARENT, 0x20, 12, 0, },
115 { HI3660_CLK_GATE_UART4, "clk_gate_uart4", "clk_mux_uarth",
116 CLK_SET_RATE_PARENT, 0x20, 14, 0, },
117 { HI3660_CLK_GATE_UART5, "clk_gate_uart5", "clk_mux_uart1",
118 CLK_SET_RATE_PARENT, 0x20, 15, 0, },
119 { HI3660_CLK_GATE_I2C4, "clk_gate_i2c4", "clk_mux_i2c",
120 CLK_SET_RATE_PARENT, 0x20, 27, 0, },
121 { HI3660_CLK_GATE_DMAC, "clk_gate_dmac", "clk_div_sysbus",
122 CLK_SET_RATE_PARENT, 0x30, 1, 0, },
123 { HI3660_PCLK_GATE_DSS, "pclk_gate_dss", "clk_div_cfgbus",
124 CLK_SET_RATE_PARENT, 0x30, 12, 0, },
125 { HI3660_ACLK_GATE_DSS, "aclk_gate_dss", "clk_gate_vivobus",
126 CLK_SET_RATE_PARENT, 0x30, 13, 0, },
127 { HI3660_CLK_GATE_LDI1, "clk_gate_ldi1", "clk_div_ldi1",
128 CLK_SET_RATE_PARENT, 0x30, 14, 0, },
129 { HI3660_CLK_GATE_LDI0, "clk_gate_ldi0", "clk_div_ldi0",
130 CLK_SET_RATE_PARENT, 0x30, 15, 0, },
131 { HI3660_CLK_GATE_VIVOBUS, "clk_gate_vivobus", "clk_div_vivobus",
132 CLK_SET_RATE_PARENT, 0x30, 16, 0, },
133 { HI3660_CLK_GATE_EDC0, "clk_gate_edc0", "clk_div_edc0",
134 CLK_SET_RATE_PARENT, 0x30, 17, 0, },
135 { HI3660_CLK_GATE_TXDPHY0_CFG, "clk_gate_txdphy0_cfg", "clkin_sys",
136 CLK_SET_RATE_PARENT, 0x30, 28, 0, },
137 { HI3660_CLK_GATE_TXDPHY0_REF, "clk_gate_txdphy0_ref", "clkin_sys",
138 CLK_SET_RATE_PARENT, 0x30, 29, 0, },
139 { HI3660_CLK_GATE_TXDPHY1_CFG, "clk_gate_txdphy1_cfg", "clkin_sys",
140 CLK_SET_RATE_PARENT, 0x30, 30, 0, },
141 { HI3660_CLK_GATE_TXDPHY1_REF, "clk_gate_txdphy1_ref", "clkin_sys",
142 CLK_SET_RATE_PARENT, 0x30, 31, 0, },
143 { HI3660_ACLK_GATE_USB3OTG, "aclk_gate_usb3otg", "clk_div_mmc0bus",
144 CLK_SET_RATE_PARENT, 0x40, 1, 0, },
145 { HI3660_CLK_GATE_SPI4, "clk_gate_spi4", "clk_mux_spi",
146 CLK_SET_RATE_PARENT, 0x40, 4, 0, },
147 { HI3660_CLK_GATE_SD, "clk_gate_sd", "clk_mux_sd_sys",
148 CLK_SET_RATE_PARENT, 0x40, 17, 0, },
149 { HI3660_CLK_GATE_SDIO0, "clk_gate_sdio0", "clk_mux_sdio_sys",
150 CLK_SET_RATE_PARENT, 0x40, 19, 0, },
151 { HI3660_CLK_GATE_UFS_SUBSYS, "clk_gate_ufs_subsys", "clk_div_sysbus",
152 CLK_SET_RATE_PARENT, 0x50, 21, 0, },
153 { HI3660_PCLK_GATE_DSI0, "pclk_gate_dsi0", "clk_div_cfgbus",
154 CLK_SET_RATE_PARENT, 0x50, 28, 0, },
155 { HI3660_PCLK_GATE_DSI1, "pclk_gate_dsi1", "clk_div_cfgbus",
156 CLK_SET_RATE_PARENT, 0x50, 29, 0, },
157 { HI3660_ACLK_GATE_PCIE, "aclk_gate_pcie", "clk_div_mmc1bus",
158 CLK_SET_RATE_PARENT, 0x420, 5, 0, },
159 { HI3660_PCLK_GATE_PCIE_SYS, "pclk_gate_pcie_sys", "clk_div_mmc1bus",
160 CLK_SET_RATE_PARENT, 0x420, 7, 0, },
161 { HI3660_CLK_GATE_PCIEAUX, "clk_gate_pcieaux", "clkin_sys",
162 CLK_SET_RATE_PARENT, 0x420, 8, 0, },
163 { HI3660_PCLK_GATE_PCIE_PHY, "pclk_gate_pcie_phy", "clk_div_mmc1bus",
164 CLK_SET_RATE_PARENT, 0x420, 9, 0, },
165};
166
167static const struct hisi_gate_clock hi3660_crgctrl_gate_clks[] = {
168 { HI3660_CLK_ANDGT_LDI0, "clk_andgt_ldi0", "clk_mux_ldi0",
169 CLK_SET_RATE_PARENT, 0xf0, 6, CLK_GATE_HIWORD_MASK, },
170 { HI3660_CLK_ANDGT_LDI1, "clk_andgt_ldi1", "clk_mux_ldi1",
171 CLK_SET_RATE_PARENT, 0xf0, 7, CLK_GATE_HIWORD_MASK, },
172 { HI3660_CLK_ANDGT_EDC0, "clk_andgt_edc0", "clk_mux_edc0",
173 CLK_SET_RATE_PARENT, 0xf0, 8, CLK_GATE_HIWORD_MASK, },
174 { HI3660_CLK_GATE_UFSPHY_GT, "clk_gate_ufsphy_gt", "clk_div_ufsperi",
175 CLK_SET_RATE_PARENT, 0xf4, 1, CLK_GATE_HIWORD_MASK, },
176 { HI3660_CLK_ANDGT_MMC, "clk_andgt_mmc", "clk_mux_mmc_pll",
177 CLK_SET_RATE_PARENT, 0xf4, 2, CLK_GATE_HIWORD_MASK, },
178 { HI3660_CLK_ANDGT_SD, "clk_andgt_sd", "clk_mux_sd_pll",
179 CLK_SET_RATE_PARENT, 0xf4, 3, CLK_GATE_HIWORD_MASK, },
180 { HI3660_CLK_A53HPM_ANDGT, "clk_a53hpm_andgt", "clk_mux_a53hpm",
181 CLK_SET_RATE_PARENT, 0xf4, 7, CLK_GATE_HIWORD_MASK, },
182 { HI3660_CLK_ANDGT_SDIO, "clk_andgt_sdio", "clk_mux_sdio_pll",
183 CLK_SET_RATE_PARENT, 0xf4, 8, CLK_GATE_HIWORD_MASK, },
184 { HI3660_CLK_ANDGT_UART0, "clk_andgt_uart0", "clk_div_320m",
185 CLK_SET_RATE_PARENT, 0xf4, 9, CLK_GATE_HIWORD_MASK, },
186 { HI3660_CLK_ANDGT_UART1, "clk_andgt_uart1", "clk_div_320m",
187 CLK_SET_RATE_PARENT, 0xf4, 10, CLK_GATE_HIWORD_MASK, },
188 { HI3660_CLK_ANDGT_UARTH, "clk_andgt_uarth", "clk_div_320m",
189 CLK_SET_RATE_PARENT, 0xf4, 11, CLK_GATE_HIWORD_MASK, },
190 { HI3660_CLK_ANDGT_SPI, "clk_andgt_spi", "clk_div_320m",
191 CLK_SET_RATE_PARENT, 0xf4, 13, CLK_GATE_HIWORD_MASK, },
192 { HI3660_CLK_VIVOBUS_ANDGT, "clk_vivobus_andgt", "clk_mux_vivobus",
193 CLK_SET_RATE_PARENT, 0xf8, 1, CLK_GATE_HIWORD_MASK, },
194 { HI3660_CLK_AOMM_ANDGT, "clk_aomm_andgt", "clk_ppll2",
195 CLK_SET_RATE_PARENT, 0xf8, 3, CLK_GATE_HIWORD_MASK, },
196 { HI3660_CLK_320M_PLL_GT, "clk_320m_pll_gt", "clk_mux_320m",
197 CLK_SET_RATE_PARENT, 0xf8, 10, 0, },
198 { HI3660_AUTODIV_EMMC0BUS, "autodiv_emmc0bus", "autodiv_sysbus",
199 CLK_SET_RATE_PARENT, 0x404, 1, CLK_GATE_HIWORD_MASK, },
200 { HI3660_AUTODIV_SYSBUS, "autodiv_sysbus", "clk_div_sysbus",
201 CLK_SET_RATE_PARENT, 0x404, 5, CLK_GATE_HIWORD_MASK, },
202 { HI3660_CLK_GATE_UFSPHY_CFG, "clk_gate_ufsphy_cfg",
203 "clk_div_ufsphy_cfg", CLK_SET_RATE_PARENT, 0x420, 12, 0, },
204 { HI3660_CLK_GATE_UFSIO_REF, "clk_gate_ufsio_ref",
205 "clk_gate_ufs_tcxo_en", CLK_SET_RATE_PARENT, 0x420, 14, 0, },
206};
207
208static const char *const
209clk_mux_sdio_sys_p[] = {"clk_factor_mmc", "clk_div_sdio",};
210static const char *const
211clk_mux_sd_sys_p[] = {"clk_factor_mmc", "clk_div_sd",};
212static const char *const
213clk_mux_pll_p[] = {"clk_ppll0", "clk_ppll1", "clk_ppll2", "clk_ppll2",};
214static const char *const
215clk_mux_pll0123_p[] = {"clk_ppll0", "clk_ppll1", "clk_ppll2", "clk_ppll3",};
216static const char *const
217clk_mux_edc0_p[] = {"clk_inv", "clk_ppll0", "clk_ppll1", "clk_inv",
218 "clk_ppll2", "clk_inv", "clk_inv", "clk_inv",
219 "clk_ppll3", "clk_inv", "clk_inv", "clk_inv",
220 "clk_inv", "clk_inv", "clk_inv", "clk_inv",};
221static const char *const
222clk_mux_ldi0_p[] = {"clk_inv", "clk_ppll0", "clk_ppll2", "clk_inv",
223 "clk_ppll1", "clk_inv", "clk_inv", "clk_inv",
224 "clk_ppll3", "clk_inv", "clk_inv", "clk_inv",
225 "clk_inv", "clk_inv", "clk_inv", "clk_inv",};
226static const char *const
227clk_mux_uart0_p[] = {"clkin_sys", "clk_div_uart0",};
228static const char *const
229clk_mux_uart1_p[] = {"clkin_sys", "clk_div_uart1",};
230static const char *const
231clk_mux_uarth_p[] = {"clkin_sys", "clk_div_uarth",};
232static const char *const
233clk_mux_pll02p[] = {"clk_ppll0", "clk_ppll2",};
234static const char *const
235clk_mux_ioperi_p[] = {"clk_div_320m", "clk_div_a53hpm",};
236static const char *const
237clk_mux_spi_p[] = {"clkin_sys", "clk_div_spi",};
238static const char *const
239clk_mux_i2c_p[] = {"clkin_sys", "clk_div_i2c",};
240
241static const struct hisi_mux_clock hi3660_crgctrl_mux_clks[] = {
242 { HI3660_CLK_MUX_SYSBUS, "clk_mux_sysbus", clk_mux_sdio_sys_p,
243 ARRAY_SIZE(clk_mux_sdio_sys_p), CLK_SET_RATE_PARENT, 0xac, 0, 1,
244 CLK_MUX_HIWORD_MASK, },
245 { HI3660_CLK_MUX_UART0, "clk_mux_uart0", clk_mux_uart0_p,
246 ARRAY_SIZE(clk_mux_uart0_p), CLK_SET_RATE_PARENT, 0xac, 2, 1,
247 CLK_MUX_HIWORD_MASK, },
248 { HI3660_CLK_MUX_UART1, "clk_mux_uart1", clk_mux_uart1_p,
249 ARRAY_SIZE(clk_mux_uart1_p), CLK_SET_RATE_PARENT, 0xac, 3, 1,
250 CLK_MUX_HIWORD_MASK, },
251 { HI3660_CLK_MUX_UARTH, "clk_mux_uarth", clk_mux_uarth_p,
252 ARRAY_SIZE(clk_mux_uarth_p), CLK_SET_RATE_PARENT, 0xac, 4, 1,
253 CLK_MUX_HIWORD_MASK, },
254 { HI3660_CLK_MUX_SPI, "clk_mux_spi", clk_mux_spi_p,
255 ARRAY_SIZE(clk_mux_spi_p), CLK_SET_RATE_PARENT, 0xac, 8, 1,
256 CLK_MUX_HIWORD_MASK, },
257 { HI3660_CLK_MUX_I2C, "clk_mux_i2c", clk_mux_i2c_p,
258 ARRAY_SIZE(clk_mux_i2c_p), CLK_SET_RATE_PARENT, 0xac, 13, 1,
259 CLK_MUX_HIWORD_MASK, },
260 { HI3660_CLK_MUX_MMC_PLL, "clk_mux_mmc_pll", clk_mux_pll02p,
261 ARRAY_SIZE(clk_mux_pll02p), CLK_SET_RATE_PARENT, 0xb4, 0, 1,
262 CLK_MUX_HIWORD_MASK, },
263 { HI3660_CLK_MUX_LDI1, "clk_mux_ldi1", clk_mux_ldi0_p,
264 ARRAY_SIZE(clk_mux_ldi0_p), CLK_SET_RATE_PARENT, 0xb4, 8, 4,
265 CLK_MUX_HIWORD_MASK, },
266 { HI3660_CLK_MUX_LDI0, "clk_mux_ldi0", clk_mux_ldi0_p,
267 ARRAY_SIZE(clk_mux_ldi0_p), CLK_SET_RATE_PARENT, 0xb4, 12, 4,
268 CLK_MUX_HIWORD_MASK, },
269 { HI3660_CLK_MUX_SD_PLL, "clk_mux_sd_pll", clk_mux_pll_p,
270 ARRAY_SIZE(clk_mux_pll_p), CLK_SET_RATE_PARENT, 0xb8, 4, 2,
271 CLK_MUX_HIWORD_MASK, },
272 { HI3660_CLK_MUX_SD_SYS, "clk_mux_sd_sys", clk_mux_sd_sys_p,
273 ARRAY_SIZE(clk_mux_sd_sys_p), CLK_SET_RATE_PARENT, 0xb8, 6, 1,
274 CLK_MUX_HIWORD_MASK, },
275 { HI3660_CLK_MUX_EDC0, "clk_mux_edc0", clk_mux_edc0_p,
276 ARRAY_SIZE(clk_mux_edc0_p), CLK_SET_RATE_PARENT, 0xbc, 6, 4,
277 CLK_MUX_HIWORD_MASK, },
278 { HI3660_CLK_MUX_SDIO_SYS, "clk_mux_sdio_sys", clk_mux_sdio_sys_p,
279 ARRAY_SIZE(clk_mux_sdio_sys_p), CLK_SET_RATE_PARENT, 0xc0, 6, 1,
280 CLK_MUX_HIWORD_MASK, },
281 { HI3660_CLK_MUX_SDIO_PLL, "clk_mux_sdio_pll", clk_mux_pll_p,
282 ARRAY_SIZE(clk_mux_pll_p), CLK_SET_RATE_PARENT, 0xc0, 4, 2,
283 CLK_MUX_HIWORD_MASK, },
284 { HI3660_CLK_MUX_VIVOBUS, "clk_mux_vivobus", clk_mux_pll0123_p,
285 ARRAY_SIZE(clk_mux_pll0123_p), CLK_SET_RATE_PARENT, 0xd0, 12, 2,
286 CLK_MUX_HIWORD_MASK, },
287 { HI3660_CLK_MUX_A53HPM, "clk_mux_a53hpm", clk_mux_pll02p,
288 ARRAY_SIZE(clk_mux_pll02p), CLK_SET_RATE_PARENT, 0xd4, 9, 1,
289 CLK_MUX_HIWORD_MASK, },
290 { HI3660_CLK_MUX_320M, "clk_mux_320m", clk_mux_pll02p,
291 ARRAY_SIZE(clk_mux_pll02p), CLK_SET_RATE_PARENT, 0x100, 0, 1,
292 CLK_MUX_HIWORD_MASK, },
293 { HI3660_CLK_MUX_IOPERI, "clk_mux_ioperi", clk_mux_ioperi_p,
294 ARRAY_SIZE(clk_mux_ioperi_p), CLK_SET_RATE_PARENT, 0x108, 10, 1,
295 CLK_MUX_HIWORD_MASK, },
296};
297
298static const struct hisi_divider_clock hi3660_crgctrl_divider_clks[] = {
299 { HI3660_CLK_DIV_UART0, "clk_div_uart0", "clk_andgt_uart0",
300 CLK_SET_RATE_PARENT, 0xb0, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
301 { HI3660_CLK_DIV_UART1, "clk_div_uart1", "clk_andgt_uart1",
302 CLK_SET_RATE_PARENT, 0xb0, 8, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
303 { HI3660_CLK_DIV_UARTH, "clk_div_uarth", "clk_andgt_uarth",
304 CLK_SET_RATE_PARENT, 0xb0, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
305 { HI3660_CLK_DIV_MMC, "clk_div_mmc", "clk_andgt_mmc",
306 CLK_SET_RATE_PARENT, 0xb4, 3, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
307 { HI3660_CLK_DIV_SD, "clk_div_sd", "clk_andgt_sd",
308 CLK_SET_RATE_PARENT, 0xb8, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
309 { HI3660_CLK_DIV_EDC0, "clk_div_edc0", "clk_andgt_edc0",
310 CLK_SET_RATE_PARENT, 0xbc, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
311 { HI3660_CLK_DIV_LDI0, "clk_div_ldi0", "clk_andgt_ldi0",
312 CLK_SET_RATE_PARENT, 0xbc, 10, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
313 { HI3660_CLK_DIV_SDIO, "clk_div_sdio", "clk_andgt_sdio",
314 CLK_SET_RATE_PARENT, 0xc0, 0, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
315 { HI3660_CLK_DIV_LDI1, "clk_div_ldi1", "clk_andgt_ldi1",
316 CLK_SET_RATE_PARENT, 0xc0, 8, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
317 { HI3660_CLK_DIV_SPI, "clk_div_spi", "clk_andgt_spi",
318 CLK_SET_RATE_PARENT, 0xc4, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
319 { HI3660_CLK_DIV_VIVOBUS, "clk_div_vivobus", "clk_vivobus_andgt",
320 CLK_SET_RATE_PARENT, 0xd0, 7, 5, CLK_DIVIDER_HIWORD_MASK, 0, },
321 { HI3660_CLK_DIV_I2C, "clk_div_i2c", "clk_div_320m",
322 CLK_SET_RATE_PARENT, 0xe8, 4, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
323 { HI3660_CLK_DIV_UFSPHY, "clk_div_ufsphy_cfg", "clk_gate_ufsphy_gt",
324 CLK_SET_RATE_PARENT, 0xe8, 9, 2, CLK_DIVIDER_HIWORD_MASK, 0, },
325 { HI3660_CLK_DIV_CFGBUS, "clk_div_cfgbus", "clk_div_sysbus",
326 CLK_SET_RATE_PARENT, 0xec, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, },
327 { HI3660_CLK_DIV_MMC0BUS, "clk_div_mmc0bus", "autodiv_emmc0bus",
328 CLK_SET_RATE_PARENT, 0xec, 2, 1, CLK_DIVIDER_HIWORD_MASK, 0, },
329 { HI3660_CLK_DIV_MMC1BUS, "clk_div_mmc1bus", "clk_div_sysbus",
330 CLK_SET_RATE_PARENT, 0xec, 3, 1, CLK_DIVIDER_HIWORD_MASK, 0, },
331 { HI3660_CLK_DIV_UFSPERI, "clk_div_ufsperi", "clk_gate_ufs_subsys",
332 CLK_SET_RATE_PARENT, 0xec, 14, 1, CLK_DIVIDER_HIWORD_MASK, 0, },
333 { HI3660_CLK_DIV_AOMM, "clk_div_aomm", "clk_aomm_andgt",
334 CLK_SET_RATE_PARENT, 0x100, 7, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
335 { HI3660_CLK_DIV_IOPERI, "clk_div_ioperi", "clk_mux_ioperi",
336 CLK_SET_RATE_PARENT, 0x108, 11, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
337};
338
339/* clk_pmuctrl */
340/* pmu register need shift 2 bits */
341static const struct hisi_gate_clock hi3660_pmu_gate_clks[] = {
342 { HI3660_GATE_ABB_192, "clk_gate_abb_192", "clkin_sys",
343 CLK_SET_RATE_PARENT, (0x10a << 2), 3, 0, },
344};
345
346/* clk_pctrl */
347static const struct hisi_gate_clock hi3660_pctrl_gate_clks[] = {
348 { HI3660_GATE_UFS_TCXO_EN, "clk_gate_ufs_tcxo_en",
349 "clk_gate_abb_192", CLK_SET_RATE_PARENT, 0x10, 0,
350 CLK_GATE_HIWORD_MASK, },
351 { HI3660_GATE_USB_TCXO_EN, "clk_gate_usb_tcxo_en", "clk_gate_abb_192",
352 CLK_SET_RATE_PARENT, 0x10, 1, CLK_GATE_HIWORD_MASK, },
353};
354
355/* clk_sctrl */
356static const struct hisi_gate_clock hi3660_sctrl_gate_sep_clks[] = {
357 { HI3660_PCLK_AO_GPIO0, "pclk_ao_gpio0", "clk_div_aobus",
358 CLK_SET_RATE_PARENT, 0x160, 11, 0, },
359 { HI3660_PCLK_AO_GPIO1, "pclk_ao_gpio1", "clk_div_aobus",
360 CLK_SET_RATE_PARENT, 0x160, 12, 0, },
361 { HI3660_PCLK_AO_GPIO2, "pclk_ao_gpio2", "clk_div_aobus",
362 CLK_SET_RATE_PARENT, 0x160, 13, 0, },
363 { HI3660_PCLK_AO_GPIO3, "pclk_ao_gpio3", "clk_div_aobus",
364 CLK_SET_RATE_PARENT, 0x160, 14, 0, },
365 { HI3660_PCLK_AO_GPIO4, "pclk_ao_gpio4", "clk_div_aobus",
366 CLK_SET_RATE_PARENT, 0x160, 21, 0, },
367 { HI3660_PCLK_AO_GPIO5, "pclk_ao_gpio5", "clk_div_aobus",
368 CLK_SET_RATE_PARENT, 0x160, 22, 0, },
369 { HI3660_PCLK_AO_GPIO6, "pclk_ao_gpio6", "clk_div_aobus",
370 CLK_SET_RATE_PARENT, 0x160, 25, 0, },
371 { HI3660_PCLK_GATE_MMBUF, "pclk_gate_mmbuf", "pclk_div_mmbuf",
372 CLK_SET_RATE_PARENT, 0x170, 23, 0, },
373 { HI3660_CLK_GATE_DSS_AXI_MM, "clk_gate_dss_axi_mm", "aclk_mux_mmbuf",
374 CLK_SET_RATE_PARENT, 0x170, 24, 0, },
375};
376
377static const struct hisi_gate_clock hi3660_sctrl_gate_clks[] = {
378 { HI3660_PCLK_MMBUF_ANDGT, "pclk_mmbuf_andgt", "clk_sw_mmbuf",
379 CLK_SET_RATE_PARENT, 0x258, 7, CLK_GATE_HIWORD_MASK, },
380 { HI3660_CLK_MMBUF_PLL_ANDGT, "clk_mmbuf_pll_andgt", "clk_ppll0",
381 CLK_SET_RATE_PARENT, 0x260, 11, CLK_DIVIDER_HIWORD_MASK, 0, },
382 { HI3660_CLK_FLL_MMBUF_ANDGT, "clk_fll_mmbuf_andgt", "clk_fll_src",
383 CLK_SET_RATE_PARENT, 0x260, 12, CLK_DIVIDER_HIWORD_MASK, 0, },
384 { HI3660_CLK_SYS_MMBUF_ANDGT, "clk_sys_mmbuf_andgt", "clkin_sys",
385 CLK_SET_RATE_PARENT, 0x260, 13, CLK_DIVIDER_HIWORD_MASK, 0, },
386 { HI3660_CLK_GATE_PCIEPHY_GT, "clk_gate_pciephy_gt", "clk_ppll0",
387 CLK_SET_RATE_PARENT, 0x268, 11, CLK_DIVIDER_HIWORD_MASK, 0, },
388};
389
390static const char *const
391aclk_mux_mmbuf_p[] = {"aclk_div_mmbuf", "clk_gate_aomm",};
392static const char *const
393clk_sw_mmbuf_p[] = {"clk_sys_mmbuf_andgt", "clk_fll_mmbuf_andgt",
394 "aclk_mux_mmbuf", "aclk_mux_mmbuf"};
395
396static const struct hisi_mux_clock hi3660_sctrl_mux_clks[] = {
397 { HI3660_ACLK_MUX_MMBUF, "aclk_mux_mmbuf", aclk_mux_mmbuf_p,
398 ARRAY_SIZE(aclk_mux_mmbuf_p), CLK_SET_RATE_PARENT, 0x250, 12, 1,
399 CLK_MUX_HIWORD_MASK, },
400 { HI3660_CLK_SW_MMBUF, "clk_sw_mmbuf", clk_sw_mmbuf_p,
401 ARRAY_SIZE(clk_sw_mmbuf_p), CLK_SET_RATE_PARENT, 0x258, 8, 2,
402 CLK_MUX_HIWORD_MASK, },
403};
404
405static const struct hisi_divider_clock hi3660_sctrl_divider_clks[] = {
406 { HI3660_CLK_DIV_AOBUS, "clk_div_aobus", "clk_ppll0",
407 CLK_SET_RATE_PARENT, 0x254, 0, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
408 { HI3660_PCLK_DIV_MMBUF, "pclk_div_mmbuf", "pclk_mmbuf_andgt",
409 CLK_SET_RATE_PARENT, 0x258, 10, 2, CLK_DIVIDER_HIWORD_MASK, 0, },
410 { HI3660_ACLK_DIV_MMBUF, "aclk_div_mmbuf", "clk_mmbuf_pll_andgt",
411 CLK_SET_RATE_PARENT, 0x258, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
412 { HI3660_CLK_DIV_PCIEPHY, "clk_div_pciephy", "clk_gate_pciephy_gt",
413 CLK_SET_RATE_PARENT, 0x268, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
414};
415
416/* clk_iomcu */
417static const struct hisi_gate_clock hi3660_iomcu_gate_sep_clks[] = {
418 { HI3660_CLK_I2C0_IOMCU, "clk_i2c0_iomcu", "clk_fll_src",
419 CLK_SET_RATE_PARENT, 0x10, 3, 0, },
420 { HI3660_CLK_I2C1_IOMCU, "clk_i2c1_iomcu", "clk_fll_src",
421 CLK_SET_RATE_PARENT, 0x10, 4, 0, },
422 { HI3660_CLK_I2C2_IOMCU, "clk_i2c2_iomcu", "clk_fll_src",
423 CLK_SET_RATE_PARENT, 0x10, 5, 0, },
424 { HI3660_CLK_I2C6_IOMCU, "clk_i2c6_iomcu", "clk_fll_src",
425 CLK_SET_RATE_PARENT, 0x10, 27, 0, },
426 { HI3660_CLK_IOMCU_PERI0, "iomcu_peri0", "clk_ppll0",
427 CLK_SET_RATE_PARENT, 0x90, 0, 0, },
428};
429
430static void hi3660_clk_iomcu_init(struct device_node *np)
431{
432 struct hisi_clock_data *clk_data;
433 int nr = ARRAY_SIZE(hi3660_iomcu_gate_sep_clks);
434
435 clk_data = hisi_clk_init(np, nr);
436 if (!clk_data)
437 return;
438
439 hisi_clk_register_gate_sep(hi3660_iomcu_gate_sep_clks,
440 ARRAY_SIZE(hi3660_iomcu_gate_sep_clks),
441 clk_data);
442}
443
444static void hi3660_clk_pmuctrl_init(struct device_node *np)
445{
446 struct hisi_clock_data *clk_data;
447 int nr = ARRAY_SIZE(hi3660_pmu_gate_clks);
448
449 clk_data = hisi_clk_init(np, nr);
450 if (!clk_data)
451 return;
452
453 hisi_clk_register_gate(hi3660_pmu_gate_clks,
454 ARRAY_SIZE(hi3660_pmu_gate_clks), clk_data);
455}
456
457static void hi3660_clk_pctrl_init(struct device_node *np)
458{
459 struct hisi_clock_data *clk_data;
460 int nr = ARRAY_SIZE(hi3660_pctrl_gate_clks);
461
462 clk_data = hisi_clk_init(np, nr);
463 if (!clk_data)
464 return;
465 hisi_clk_register_gate(hi3660_pctrl_gate_clks,
466 ARRAY_SIZE(hi3660_pctrl_gate_clks), clk_data);
467}
468
469static void hi3660_clk_sctrl_init(struct device_node *np)
470{
471 struct hisi_clock_data *clk_data;
472 int nr = ARRAY_SIZE(hi3660_sctrl_gate_clks) +
473 ARRAY_SIZE(hi3660_sctrl_gate_sep_clks) +
474 ARRAY_SIZE(hi3660_sctrl_mux_clks) +
475 ARRAY_SIZE(hi3660_sctrl_divider_clks);
476
477 clk_data = hisi_clk_init(np, nr);
478 if (!clk_data)
479 return;
480 hisi_clk_register_gate(hi3660_sctrl_gate_clks,
481 ARRAY_SIZE(hi3660_sctrl_gate_clks), clk_data);
482 hisi_clk_register_gate_sep(hi3660_sctrl_gate_sep_clks,
483 ARRAY_SIZE(hi3660_sctrl_gate_sep_clks),
484 clk_data);
485 hisi_clk_register_mux(hi3660_sctrl_mux_clks,
486 ARRAY_SIZE(hi3660_sctrl_mux_clks), clk_data);
487 hisi_clk_register_divider(hi3660_sctrl_divider_clks,
488 ARRAY_SIZE(hi3660_sctrl_divider_clks),
489 clk_data);
490}
491
492static void hi3660_clk_crgctrl_init(struct device_node *np)
493{
494 struct hisi_clock_data *clk_data;
495 int nr = ARRAY_SIZE(hi3660_fixed_rate_clks) +
496 ARRAY_SIZE(hi3660_crgctrl_gate_sep_clks) +
497 ARRAY_SIZE(hi3660_crgctrl_gate_clks) +
498 ARRAY_SIZE(hi3660_crgctrl_mux_clks) +
499 ARRAY_SIZE(hi3660_crg_fixed_factor_clks) +
500 ARRAY_SIZE(hi3660_crgctrl_divider_clks);
501
502 clk_data = hisi_clk_init(np, nr);
503 if (!clk_data)
504 return;
505
506 hisi_clk_register_fixed_rate(hi3660_fixed_rate_clks,
507 ARRAY_SIZE(hi3660_fixed_rate_clks),
508 clk_data);
509 hisi_clk_register_gate_sep(hi3660_crgctrl_gate_sep_clks,
510 ARRAY_SIZE(hi3660_crgctrl_gate_sep_clks),
511 clk_data);
512 hisi_clk_register_gate(hi3660_crgctrl_gate_clks,
513 ARRAY_SIZE(hi3660_crgctrl_gate_clks),
514 clk_data);
515 hisi_clk_register_mux(hi3660_crgctrl_mux_clks,
516 ARRAY_SIZE(hi3660_crgctrl_mux_clks),
517 clk_data);
518 hisi_clk_register_fixed_factor(hi3660_crg_fixed_factor_clks,
519 ARRAY_SIZE(hi3660_crg_fixed_factor_clks),
520 clk_data);
521 hisi_clk_register_divider(hi3660_crgctrl_divider_clks,
522 ARRAY_SIZE(hi3660_crgctrl_divider_clks),
523 clk_data);
524}
525
526static const struct of_device_id hi3660_clk_match_table[] = {
527 { .compatible = "hisilicon,hi3660-crgctrl",
528 .data = hi3660_clk_crgctrl_init },
529 { .compatible = "hisilicon,hi3660-pctrl",
530 .data = hi3660_clk_pctrl_init },
531 { .compatible = "hisilicon,hi3660-pmuctrl",
532 .data = hi3660_clk_pmuctrl_init },
533 { .compatible = "hisilicon,hi3660-sctrl",
534 .data = hi3660_clk_sctrl_init },
535 { .compatible = "hisilicon,hi3660-iomcu",
536 .data = hi3660_clk_iomcu_init },
537 { }
538};
539
540static int hi3660_clk_probe(struct platform_device *pdev)
541{
542 struct device *dev = &pdev->dev;
543 struct device_node *np = pdev->dev.of_node;
544 void (*init_func)(struct device_node *np);
545
546 init_func = of_device_get_match_data(dev);
547 if (!init_func)
548 return -ENODEV;
549
550 init_func(np);
551
552 return 0;
553}
554
555static struct platform_driver hi3660_clk_driver = {
556 .probe = hi3660_clk_probe,
557 .driver = {
558 .name = "hi3660-clk",
559 .of_match_table = hi3660_clk_match_table,
560 },
561};
562
563static int __init hi3660_clk_init(void)
564{
565 return platform_driver_register(&hi3660_clk_driver);
566}
567core_initcall(hi3660_clk_init);
diff --git a/drivers/clk/hisilicon/clkgate-separated.c b/drivers/clk/hisilicon/clkgate-separated.c
index a47812f56a17..7908bc3c9ec7 100644
--- a/drivers/clk/hisilicon/clkgate-separated.c
+++ b/drivers/clk/hisilicon/clkgate-separated.c
@@ -120,6 +120,7 @@ struct clk *hisi_register_clkgate_sep(struct device *dev, const char *name,
120 sclk->bit_idx = bit_idx; 120 sclk->bit_idx = bit_idx;
121 sclk->flags = clk_gate_flags; 121 sclk->flags = clk_gate_flags;
122 sclk->hw.init = &init; 122 sclk->hw.init = &init;
123 sclk->lock = lock;
123 124
124 clk = clk_register(dev, &sclk->hw); 125 clk = clk_register(dev, &sclk->hw);
125 if (IS_ERR(clk)) 126 if (IS_ERR(clk))
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index 42ffc1c92bab..c07df719b8a3 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -592,15 +592,20 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
592 592
593 imx6q_mmdc_ch1_mask_handshake(base); 593 imx6q_mmdc_ch1_mask_handshake(base);
594 594
595 /* 595 if (clk_on_imx6qp()) {
596 * The LDB_DI0/1_SEL muxes are registered read-only due to a hardware 596 clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
597 * bug. Set the muxes to the requested values before registering the 597 clk[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
598 * ldb_di_sel clocks. 598 } else {
599 */ 599 /*
600 init_ldb_clks(np, base); 600 * The LDB_DI0/1_SEL muxes are registered read-only due to a hardware
601 * bug. Set the muxes to the requested values before registering the
602 * ldb_di_sel clocks.
603 */
604 init_ldb_clks(np, base);
601 605
602 clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_ldb("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); 606 clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_ldb("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
603 clk[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_ldb("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); 607 clk[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_ldb("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
608 }
604 clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); 609 clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
605 clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); 610 clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
606 clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); 611 clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT);
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index e7c7353a86fc..ae1d31be906e 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -803,6 +803,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
803 clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0); 803 clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
804 clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0); 804 clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
805 clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0); 805 clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
806 clks[IMX7D_OCOTP_CLK] = imx_clk_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0);
806 clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0); 807 clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
807 clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0); 808 clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0);
808 clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0); 809 clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index ed3a2df536ea..f1099167ba31 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -21,6 +21,9 @@
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 23
24#define PLL_VF610_NUM_OFFSET 0x20
25#define PLL_VF610_DENOM_OFFSET 0x30
26
24#define BM_PLL_POWER (0x1 << 12) 27#define BM_PLL_POWER (0x1 << 12)
25#define BM_PLL_LOCK (0x1 << 31) 28#define BM_PLL_LOCK (0x1 << 31)
26#define IMX7_ENET_PLL_POWER (0x1 << 5) 29#define IMX7_ENET_PLL_POWER (0x1 << 5)
@@ -300,6 +303,99 @@ static const struct clk_ops clk_pllv3_av_ops = {
300 .set_rate = clk_pllv3_av_set_rate, 303 .set_rate = clk_pllv3_av_set_rate,
301}; 304};
302 305
306struct clk_pllv3_vf610_mf {
307 u32 mfi; /* integer part, can be 20 or 22 */
308 u32 mfn; /* numerator, 30-bit value */
309 u32 mfd; /* denominator, 30-bit value, must be less than mfn */
310};
311
312static unsigned long clk_pllv3_vf610_mf_to_rate(unsigned long parent_rate,
313 struct clk_pllv3_vf610_mf mf)
314{
315 u64 temp64;
316
317 temp64 = parent_rate;
318 temp64 *= mf.mfn;
319 do_div(temp64, mf.mfd);
320
321 return (parent_rate * mf.mfi) + temp64;
322}
323
324static struct clk_pllv3_vf610_mf clk_pllv3_vf610_rate_to_mf(
325 unsigned long parent_rate, unsigned long rate)
326{
327 struct clk_pllv3_vf610_mf mf;
328 u64 temp64;
329
330 mf.mfi = (rate >= 22 * parent_rate) ? 22 : 20;
331 mf.mfd = 0x3fffffff; /* use max supported value for best accuracy */
332
333 if (rate <= parent_rate * mf.mfi)
334 mf.mfn = 0;
335 else if (rate >= parent_rate * (mf.mfi + 1))
336 mf.mfn = mf.mfd - 1;
337 else {
338 /* rate = parent_rate * (mfi + mfn/mfd) */
339 temp64 = rate - parent_rate * mf.mfi;
340 temp64 *= mf.mfd;
341 do_div(temp64, parent_rate);
342 mf.mfn = temp64;
343 }
344
345 return mf;
346}
347
348static unsigned long clk_pllv3_vf610_recalc_rate(struct clk_hw *hw,
349 unsigned long parent_rate)
350{
351 struct clk_pllv3 *pll = to_clk_pllv3(hw);
352 struct clk_pllv3_vf610_mf mf;
353
354 mf.mfn = readl_relaxed(pll->base + PLL_VF610_NUM_OFFSET);
355 mf.mfd = readl_relaxed(pll->base + PLL_VF610_DENOM_OFFSET);
356 mf.mfi = (readl_relaxed(pll->base) & pll->div_mask) ? 22 : 20;
357
358 return clk_pllv3_vf610_mf_to_rate(parent_rate, mf);
359}
360
361static long clk_pllv3_vf610_round_rate(struct clk_hw *hw, unsigned long rate,
362 unsigned long *prate)
363{
364 struct clk_pllv3_vf610_mf mf = clk_pllv3_vf610_rate_to_mf(*prate, rate);
365
366 return clk_pllv3_vf610_mf_to_rate(*prate, mf);
367}
368
369static int clk_pllv3_vf610_set_rate(struct clk_hw *hw, unsigned long rate,
370 unsigned long parent_rate)
371{
372 struct clk_pllv3 *pll = to_clk_pllv3(hw);
373 struct clk_pllv3_vf610_mf mf =
374 clk_pllv3_vf610_rate_to_mf(parent_rate, rate);
375 u32 val;
376
377 val = readl_relaxed(pll->base);
378 if (mf.mfi == 20)
379 val &= ~pll->div_mask; /* clear bit for mfi=20 */
380 else
381 val |= pll->div_mask; /* set bit for mfi=22 */
382 writel_relaxed(val, pll->base);
383
384 writel_relaxed(mf.mfn, pll->base + PLL_VF610_NUM_OFFSET);
385 writel_relaxed(mf.mfd, pll->base + PLL_VF610_DENOM_OFFSET);
386
387 return clk_pllv3_wait_lock(pll);
388}
389
390static const struct clk_ops clk_pllv3_vf610_ops = {
391 .prepare = clk_pllv3_prepare,
392 .unprepare = clk_pllv3_unprepare,
393 .is_prepared = clk_pllv3_is_prepared,
394 .recalc_rate = clk_pllv3_vf610_recalc_rate,
395 .round_rate = clk_pllv3_vf610_round_rate,
396 .set_rate = clk_pllv3_vf610_set_rate,
397};
398
303static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw, 399static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
304 unsigned long parent_rate) 400 unsigned long parent_rate)
305{ 401{
@@ -334,6 +430,9 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
334 case IMX_PLLV3_SYS: 430 case IMX_PLLV3_SYS:
335 ops = &clk_pllv3_sys_ops; 431 ops = &clk_pllv3_sys_ops;
336 break; 432 break;
433 case IMX_PLLV3_SYS_VF610:
434 ops = &clk_pllv3_vf610_ops;
435 break;
337 case IMX_PLLV3_USB_VF610: 436 case IMX_PLLV3_USB_VF610:
338 pll->div_shift = 1; 437 pll->div_shift = 1;
339 case IMX_PLLV3_USB: 438 case IMX_PLLV3_USB:
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index 0476353ab423..59b1863deb88 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -219,8 +219,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
219 clk[VF610_CLK_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", PLL6_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); 219 clk[VF610_CLK_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", PLL6_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
220 clk[VF610_CLK_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", PLL7_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); 220 clk[VF610_CLK_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", PLL7_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
221 221
222 clk[VF610_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll1", "pll1_bypass_src", PLL1_CTRL, 0x1); 222 clk[VF610_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS_VF610, "pll1", "pll1_bypass_src", PLL1_CTRL, 0x1);
223 clk[VF610_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", PLL2_CTRL, 0x1); 223 clk[VF610_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_SYS_VF610, "pll2", "pll2_bypass_src", PLL2_CTRL, 0x1);
224 clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll3", "pll3_bypass_src", PLL3_CTRL, 0x2); 224 clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll3", "pll3_bypass_src", PLL3_CTRL, 0x2);
225 clk[VF610_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", PLL4_CTRL, 0x7f); 225 clk[VF610_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", PLL4_CTRL, 0x7f);
226 clk[VF610_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll5", "pll5_bypass_src", PLL5_CTRL, 0x3); 226 clk[VF610_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll5", "pll5_bypass_src", PLL5_CTRL, 0x3);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 4afad3b96a61..e1f5e425db73 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -34,6 +34,7 @@ enum imx_pllv3_type {
34 IMX_PLLV3_AV, 34 IMX_PLLV3_AV,
35 IMX_PLLV3_ENET, 35 IMX_PLLV3_ENET,
36 IMX_PLLV3_ENET_IMX7, 36 IMX_PLLV3_ENET_IMX7,
37 IMX_PLLV3_SYS_VF610,
37}; 38};
38 39
39struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, 40struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 0bd631a41f6a..a01ef7806aed 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -8,52 +8,53 @@ config COMMON_CLK_MEDIATEK
8 8
9config COMMON_CLK_MT2701 9config COMMON_CLK_MT2701
10 bool "Clock driver for Mediatek MT2701" 10 bool "Clock driver for Mediatek MT2701"
11 depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
11 select COMMON_CLK_MEDIATEK 12 select COMMON_CLK_MEDIATEK
12 default ARCH_MEDIATEK 13 default ARCH_MEDIATEK && ARM
13 ---help--- 14 ---help---
14 This driver supports Mediatek MT2701 basic clocks. 15 This driver supports Mediatek MT2701 basic clocks.
15 16
16config COMMON_CLK_MT2701_MMSYS 17config COMMON_CLK_MT2701_MMSYS
17 bool "Clock driver for Mediatek MT2701 mmsys" 18 bool "Clock driver for Mediatek MT2701 mmsys"
18 select COMMON_CLK_MT2701 19 depends on COMMON_CLK_MT2701
19 ---help--- 20 ---help---
20 This driver supports Mediatek MT2701 mmsys clocks. 21 This driver supports Mediatek MT2701 mmsys clocks.
21 22
22config COMMON_CLK_MT2701_IMGSYS 23config COMMON_CLK_MT2701_IMGSYS
23 bool "Clock driver for Mediatek MT2701 imgsys" 24 bool "Clock driver for Mediatek MT2701 imgsys"
24 select COMMON_CLK_MT2701 25 depends on COMMON_CLK_MT2701
25 ---help--- 26 ---help---
26 This driver supports Mediatek MT2701 imgsys clocks. 27 This driver supports Mediatek MT2701 imgsys clocks.
27 28
28config COMMON_CLK_MT2701_VDECSYS 29config COMMON_CLK_MT2701_VDECSYS
29 bool "Clock driver for Mediatek MT2701 vdecsys" 30 bool "Clock driver for Mediatek MT2701 vdecsys"
30 select COMMON_CLK_MT2701 31 depends on COMMON_CLK_MT2701
31 ---help--- 32 ---help---
32 This driver supports Mediatek MT2701 vdecsys clocks. 33 This driver supports Mediatek MT2701 vdecsys clocks.
33 34
34config COMMON_CLK_MT2701_HIFSYS 35config COMMON_CLK_MT2701_HIFSYS
35 bool "Clock driver for Mediatek MT2701 hifsys" 36 bool "Clock driver for Mediatek MT2701 hifsys"
36 select COMMON_CLK_MT2701 37 depends on COMMON_CLK_MT2701
37 ---help--- 38 ---help---
38 This driver supports Mediatek MT2701 hifsys clocks. 39 This driver supports Mediatek MT2701 hifsys clocks.
39 40
40config COMMON_CLK_MT2701_ETHSYS 41config COMMON_CLK_MT2701_ETHSYS
41 bool "Clock driver for Mediatek MT2701 ethsys" 42 bool "Clock driver for Mediatek MT2701 ethsys"
42 select COMMON_CLK_MT2701 43 depends on COMMON_CLK_MT2701
43 ---help--- 44 ---help---
44 This driver supports Mediatek MT2701 ethsys clocks. 45 This driver supports Mediatek MT2701 ethsys clocks.
45 46
46config COMMON_CLK_MT2701_BDPSYS 47config COMMON_CLK_MT2701_BDPSYS
47 bool "Clock driver for Mediatek MT2701 bdpsys" 48 bool "Clock driver for Mediatek MT2701 bdpsys"
48 select COMMON_CLK_MT2701 49 depends on COMMON_CLK_MT2701
49 ---help--- 50 ---help---
50 This driver supports Mediatek MT2701 bdpsys clocks. 51 This driver supports Mediatek MT2701 bdpsys clocks.
51 52
52config COMMON_CLK_MT8135 53config COMMON_CLK_MT8135
53 bool "Clock driver for Mediatek MT8135" 54 bool "Clock driver for Mediatek MT8135"
54 depends on ARCH_MEDIATEK || COMPILE_TEST 55 depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
55 select COMMON_CLK_MEDIATEK 56 select COMMON_CLK_MEDIATEK
56 default ARCH_MEDIATEK 57 default ARCH_MEDIATEK && ARM
57 ---help--- 58 ---help---
58 This driver supports Mediatek MT8135 clocks. 59 This driver supports Mediatek MT8135 clocks.
59 60
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 3f1be46cbb33..888494d4fb8a 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -607,7 +607,6 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
607 /* Populate the base address for the MPEG clks */ 607 /* Populate the base address for the MPEG clks */
608 meson8b_mpeg_clk_sel.reg = clk_base + (u32)meson8b_mpeg_clk_sel.reg; 608 meson8b_mpeg_clk_sel.reg = clk_base + (u32)meson8b_mpeg_clk_sel.reg;
609 meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg; 609 meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg;
610 meson8b_clk81.reg = clk_base + (u32)meson8b_clk81.reg;
611 610
612 /* Populate base address for gates */ 611 /* Populate base address for gates */
613 for (i = 0; i < ARRAY_SIZE(meson8b_clk_gates); i++) 612 for (i = 0; i < ARRAY_SIZE(meson8b_clk_gates); i++)
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
index d9ae97fb43c4..d71c7fd5da16 100644
--- a/drivers/clk/mvebu/Makefile
+++ b/drivers/clk/mvebu/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o
9obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-xtal.o 9obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-xtal.o
10obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-tbg.o 10obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-tbg.o
11obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-periph.o 11obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-periph.o
12obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o 12obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o mv98dx3236.o
13obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o 13obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o
14obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o 14obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o
15obj-$(CONFIG_DOVE_CLK) += dove.o dove-divider.o 15obj-$(CONFIG_DOVE_CLK) += dove.o dove-divider.o
diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c
index 8181b919f062..f17702107ac5 100644
--- a/drivers/clk/mvebu/ap806-system-controller.c
+++ b/drivers/clk/mvebu/ap806-system-controller.c
@@ -55,21 +55,39 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
55 55
56 freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK; 56 freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK;
57 switch (freq_mode) { 57 switch (freq_mode) {
58 case 0x0 ... 0x5: 58 case 0x0:
59 case 0x1:
59 cpuclk_freq = 2000; 60 cpuclk_freq = 2000;
60 break; 61 break;
61 case 0x6 ... 0xB: 62 case 0x6:
63 case 0x7:
62 cpuclk_freq = 1800; 64 cpuclk_freq = 1800;
63 break; 65 break;
64 case 0xC ... 0x11: 66 case 0x4:
67 case 0xB:
68 case 0xD:
65 cpuclk_freq = 1600; 69 cpuclk_freq = 1600;
66 break; 70 break;
67 case 0x12 ... 0x16: 71 case 0x1a:
68 cpuclk_freq = 1400; 72 cpuclk_freq = 1400;
69 break; 73 break;
70 case 0x17 ... 0x19: 74 case 0x14:
75 case 0x17:
71 cpuclk_freq = 1300; 76 cpuclk_freq = 1300;
72 break; 77 break;
78 case 0x19:
79 cpuclk_freq = 1200;
80 break;
81 case 0x13:
82 case 0x1d:
83 cpuclk_freq = 1000;
84 break;
85 case 0x1c:
86 cpuclk_freq = 800;
87 break;
88 case 0x1b:
89 cpuclk_freq = 600;
90 break;
73 default: 91 default:
74 dev_err(&pdev->dev, "invalid SAR value\n"); 92 dev_err(&pdev->dev, "invalid SAR value\n");
75 return -EINVAL; 93 return -EINVAL;
diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c
index b3094315a3c0..0ec44ae9a2a2 100644
--- a/drivers/clk/mvebu/armada-xp.c
+++ b/drivers/clk/mvebu/armada-xp.c
@@ -52,6 +52,12 @@ static u32 __init axp_get_tclk_freq(void __iomem *sar)
52 return 250000000; 52 return 250000000;
53} 53}
54 54
55/* MV98DX3236 TCLK frequency is fixed to 200MHz */
56static u32 __init mv98dx3236_get_tclk_freq(void __iomem *sar)
57{
58 return 200000000;
59}
60
55static const u32 axp_cpu_freqs[] __initconst = { 61static const u32 axp_cpu_freqs[] __initconst = {
56 1000000000, 62 1000000000,
57 1066000000, 63 1066000000,
@@ -89,6 +95,12 @@ static u32 __init axp_get_cpu_freq(void __iomem *sar)
89 return cpu_freq; 95 return cpu_freq;
90} 96}
91 97
98/* MV98DX3236 CLK frequency is fixed to 800MHz */
99static u32 __init mv98dx3236_get_cpu_freq(void __iomem *sar)
100{
101 return 800000000;
102}
103
92static const int axp_nbclk_ratios[32][2] __initconst = { 104static const int axp_nbclk_ratios[32][2] __initconst = {
93 {0, 1}, {1, 2}, {2, 2}, {2, 2}, 105 {0, 1}, {1, 2}, {2, 2}, {2, 2},
94 {1, 2}, {1, 2}, {1, 1}, {2, 3}, 106 {1, 2}, {1, 2}, {1, 1}, {2, 3},
@@ -158,6 +170,11 @@ static const struct coreclk_soc_desc axp_coreclks = {
158 .num_ratios = ARRAY_SIZE(axp_coreclk_ratios), 170 .num_ratios = ARRAY_SIZE(axp_coreclk_ratios),
159}; 171};
160 172
173static const struct coreclk_soc_desc mv98dx3236_coreclks = {
174 .get_tclk_freq = mv98dx3236_get_tclk_freq,
175 .get_cpu_freq = mv98dx3236_get_cpu_freq,
176};
177
161/* 178/*
162 * Clock Gating Control 179 * Clock Gating Control
163 */ 180 */
@@ -195,6 +212,15 @@ static const struct clk_gating_soc_desc axp_gating_desc[] __initconst = {
195 { } 212 { }
196}; 213};
197 214
215static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initconst = {
216 { "ge1", NULL, 3, 0 },
217 { "ge0", NULL, 4, 0 },
218 { "pex00", NULL, 5, 0 },
219 { "sdio", NULL, 17, 0 },
220 { "xor0", NULL, 22, 0 },
221 { }
222};
223
198static void __init axp_clk_init(struct device_node *np) 224static void __init axp_clk_init(struct device_node *np)
199{ 225{
200 struct device_node *cgnp = 226 struct device_node *cgnp =
diff --git a/drivers/clk/mvebu/clk-corediv.c b/drivers/clk/mvebu/clk-corediv.c
index d1e5863d3375..8491979f4096 100644
--- a/drivers/clk/mvebu/clk-corediv.c
+++ b/drivers/clk/mvebu/clk-corediv.c
@@ -71,6 +71,10 @@ static const struct clk_corediv_desc mvebu_corediv_desc[] = {
71 { .mask = 0x3f, .offset = 8, .fieldbit = 1 }, /* NAND clock */ 71 { .mask = 0x3f, .offset = 8, .fieldbit = 1 }, /* NAND clock */
72}; 72};
73 73
74static const struct clk_corediv_desc mv98dx3236_corediv_desc[] = {
75 { .mask = 0x0f, .offset = 6, .fieldbit = 26 }, /* NAND clock */
76};
77
74#define to_corediv_clk(p) container_of(p, struct clk_corediv, hw) 78#define to_corediv_clk(p) container_of(p, struct clk_corediv, hw)
75 79
76static int clk_corediv_is_enabled(struct clk_hw *hwclk) 80static int clk_corediv_is_enabled(struct clk_hw *hwclk)
@@ -232,6 +236,18 @@ static const struct clk_corediv_soc_desc armada375_corediv_soc = {
232 .ratio_offset = 0x4, 236 .ratio_offset = 0x4,
233}; 237};
234 238
239static const struct clk_corediv_soc_desc mv98dx3236_corediv_soc = {
240 .descs = mv98dx3236_corediv_desc,
241 .ndescs = ARRAY_SIZE(mv98dx3236_corediv_desc),
242 .ops = {
243 .recalc_rate = clk_corediv_recalc_rate,
244 .round_rate = clk_corediv_round_rate,
245 .set_rate = clk_corediv_set_rate,
246 },
247 .ratio_reload = BIT(10),
248 .ratio_offset = 0x8,
249};
250
235static void __init 251static void __init
236mvebu_corediv_clk_init(struct device_node *node, 252mvebu_corediv_clk_init(struct device_node *node,
237 const struct clk_corediv_soc_desc *soc_desc) 253 const struct clk_corediv_soc_desc *soc_desc)
@@ -313,3 +329,10 @@ static void __init armada380_corediv_clk_init(struct device_node *node)
313} 329}
314CLK_OF_DECLARE(armada380_corediv_clk, "marvell,armada-380-corediv-clock", 330CLK_OF_DECLARE(armada380_corediv_clk, "marvell,armada-380-corediv-clock",
315 armada380_corediv_clk_init); 331 armada380_corediv_clk_init);
332
333static void __init mv98dx3236_corediv_clk_init(struct device_node *node)
334{
335 return mvebu_corediv_clk_init(node, &mv98dx3236_corediv_soc);
336}
337CLK_OF_DECLARE(mv98dx3236_corediv_clk, "marvell,mv98dx3236-corediv-clock",
338 mv98dx3236_corediv_clk_init);
diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c
index 5837eb8a212f..044892b6534d 100644
--- a/drivers/clk/mvebu/clk-cpu.c
+++ b/drivers/clk/mvebu/clk-cpu.c
@@ -245,3 +245,11 @@ cpuclk_out:
245 245
246CLK_OF_DECLARE(armada_xp_cpu_clock, "marvell,armada-xp-cpu-clock", 246CLK_OF_DECLARE(armada_xp_cpu_clock, "marvell,armada-xp-cpu-clock",
247 of_cpu_clk_setup); 247 of_cpu_clk_setup);
248
249static void __init of_mv98dx3236_cpu_clk_setup(struct device_node *node)
250{
251 of_clk_add_provider(node, of_clk_src_simple_get, NULL);
252}
253
254CLK_OF_DECLARE(mv98dx3236_cpu_clock, "marvell,mv98dx3236-cpu-clock",
255 of_mv98dx3236_cpu_clk_setup);
diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
index 32e5b43c086f..6b11d7b3e0e0 100644
--- a/drivers/clk/mvebu/cp110-system-controller.c
+++ b/drivers/clk/mvebu/cp110-system-controller.c
@@ -64,8 +64,11 @@ enum {
64#define CP110_GATE_NAND 2 64#define CP110_GATE_NAND 2
65#define CP110_GATE_PPV2 3 65#define CP110_GATE_PPV2 3
66#define CP110_GATE_SDIO 4 66#define CP110_GATE_SDIO 4
67#define CP110_GATE_MG 5
68#define CP110_GATE_MG_CORE 6
67#define CP110_GATE_XOR1 7 69#define CP110_GATE_XOR1 7
68#define CP110_GATE_XOR0 8 70#define CP110_GATE_XOR0 8
71#define CP110_GATE_GOP_DP 9
69#define CP110_GATE_PCIE_X1_0 11 72#define CP110_GATE_PCIE_X1_0 11
70#define CP110_GATE_PCIE_X1_1 12 73#define CP110_GATE_PCIE_X1_1 12
71#define CP110_GATE_PCIE_X4 13 74#define CP110_GATE_PCIE_X4 13
@@ -73,7 +76,7 @@ enum {
73#define CP110_GATE_SATA 15 76#define CP110_GATE_SATA 15
74#define CP110_GATE_SATA_USB 16 77#define CP110_GATE_SATA_USB 16
75#define CP110_GATE_MAIN 17 78#define CP110_GATE_MAIN 17
76#define CP110_GATE_SDMMC 18 79#define CP110_GATE_SDMMC_GOP 18
77#define CP110_GATE_SLOW_IO 21 80#define CP110_GATE_SLOW_IO 21
78#define CP110_GATE_USB3H0 22 81#define CP110_GATE_USB3H0 22
79#define CP110_GATE_USB3H1 23 82#define CP110_GATE_USB3H1 23
@@ -296,6 +299,11 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
296 "gate-clock-output-names", 299 "gate-clock-output-names",
297 CP110_GATE_MAIN, &parent); 300 CP110_GATE_MAIN, &parent);
298 break; 301 break;
302 case CP110_GATE_MG:
303 of_property_read_string_index(np,
304 "gate-clock-output-names",
305 CP110_GATE_MG_CORE, &parent);
306 break;
299 case CP110_GATE_NAND: 307 case CP110_GATE_NAND:
300 parent = nand_name; 308 parent = nand_name;
301 break; 309 break;
@@ -303,9 +311,10 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
303 parent = ppv2_name; 311 parent = ppv2_name;
304 break; 312 break;
305 case CP110_GATE_SDIO: 313 case CP110_GATE_SDIO:
314 case CP110_GATE_GOP_DP:
306 of_property_read_string_index(np, 315 of_property_read_string_index(np,
307 "gate-clock-output-names", 316 "gate-clock-output-names",
308 CP110_GATE_SDMMC, &parent); 317 CP110_GATE_SDMMC_GOP, &parent);
309 break; 318 break;
310 case CP110_GATE_XOR1: 319 case CP110_GATE_XOR1:
311 case CP110_GATE_XOR0: 320 case CP110_GATE_XOR0:
diff --git a/drivers/clk/mvebu/mv98dx3236.c b/drivers/clk/mvebu/mv98dx3236.c
new file mode 100644
index 000000000000..6e203af73cac
--- /dev/null
+++ b/drivers/clk/mvebu/mv98dx3236.c
@@ -0,0 +1,180 @@
1/*
2 * Marvell MV98DX3236 SoC clocks
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Gregory CLEMENT <gregory.clement@free-electrons.com>
7 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
8 * Andrew Lunn <andrew@lunn.ch>
9 *
10 * This file is licensed under the terms of the GNU General Public
11 * License version 2. This program is licensed "as is" without any
12 * warranty of any kind, whether express or implied.
13 */
14
15#include <linux/kernel.h>
16#include <linux/clk-provider.h>
17#include <linux/io.h>
18#include <linux/of.h>
19#include "common.h"
20
21
22/*
23 * For 98DX4251 Sample At Reset the CPU, DDR and Main PLL clocks are all
24 * defined at the same time
25 *
26 * SAR1[20:18] : CPU frequency DDR frequency MPLL frequency
27 * 0 = 400 MHz 400 MHz 800 MHz
28 * 2 = 667 MHz 667 MHz 2000 MHz
29 * 3 = 800 MHz 800 MHz 1600 MHz
30 * others reserved.
31 *
32 * For 98DX3236 Sample At Reset the CPU, DDR and Main PLL clocks are all
33 * defined at the same time
34 *
35 * SAR1[20:18] : CPU frequency DDR frequency MPLL frequency
36 * 1 = 667 MHz 667 MHz 2000 MHz
37 * 2 = 400 MHz 400 MHz 400 MHz
38 * 3 = 800 MHz 800 MHz 800 MHz
39 * 5 = 800 MHz 400 MHz 800 MHz
40 * others reserved.
41 */
42
43#define SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT 18
44#define SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT_MASK 0x7
45
46static u32 __init mv98dx3236_get_tclk_freq(void __iomem *sar)
47{
48 /* Tclk = 200MHz, no SaR dependency */
49 return 200000000;
50}
51
52static const u32 mv98dx3236_cpu_frequencies[] __initconst = {
53 0,
54 667000000,
55 400000000,
56 800000000,
57 0,
58 800000000,
59 0, 0,
60};
61
62static const u32 mv98dx4251_cpu_frequencies[] __initconst = {
63 400000000,
64 0,
65 667000000,
66 800000000,
67 0, 0, 0, 0,
68};
69
70static u32 __init mv98dx3236_get_cpu_freq(void __iomem *sar)
71{
72 u32 cpu_freq = 0;
73 u8 cpu_freq_select = 0;
74
75 cpu_freq_select = ((readl(sar) >> SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT) &
76 SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT_MASK);
77
78 if (of_machine_is_compatible("marvell,armadaxp-98dx4251"))
79 cpu_freq = mv98dx4251_cpu_frequencies[cpu_freq_select];
80 else if (of_machine_is_compatible("marvell,armadaxp-98dx3236"))
81 cpu_freq = mv98dx3236_cpu_frequencies[cpu_freq_select];
82
83 if (!cpu_freq)
84 pr_err("CPU freq select unsupported %d\n", cpu_freq_select);
85
86 return cpu_freq;
87}
88
89enum {
90 MV98DX3236_CPU_TO_DDR,
91 MV98DX3236_CPU_TO_MPLL
92};
93
94static const struct coreclk_ratio mv98dx3236_core_ratios[] __initconst = {
95 { .id = MV98DX3236_CPU_TO_DDR, .name = "ddrclk" },
96 { .id = MV98DX3236_CPU_TO_MPLL, .name = "mpll" },
97};
98
99static const int __initconst mv98dx3236_cpu_mpll_ratios[8][2] = {
100 {0, 1}, {3, 1}, {1, 1}, {1, 1},
101 {0, 1}, {1, 1}, {0, 1}, {0, 1},
102};
103
104static const int __initconst mv98dx3236_cpu_ddr_ratios[8][2] = {
105 {0, 1}, {1, 1}, {1, 1}, {1, 1},
106 {0, 1}, {1, 2}, {0, 1}, {0, 1},
107};
108
109static const int __initconst mv98dx4251_cpu_mpll_ratios[8][2] = {
110 {2, 1}, {0, 1}, {3, 1}, {2, 1},
111 {0, 1}, {0, 1}, {0, 1}, {0, 1},
112};
113
114static const int __initconst mv98dx4251_cpu_ddr_ratios[8][2] = {
115 {1, 1}, {0, 1}, {1, 1}, {1, 1},
116 {0, 1}, {0, 1}, {0, 1}, {0, 1},
117};
118
119static void __init mv98dx3236_get_clk_ratio(
120 void __iomem *sar, int id, int *mult, int *div)
121{
122 u32 opt = ((readl(sar) >> SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT) &
123 SAR1_MV98DX3236_CPU_DDR_MPLL_FREQ_OPT_MASK);
124
125 switch (id) {
126 case MV98DX3236_CPU_TO_DDR:
127 if (of_machine_is_compatible("marvell,armadaxp-98dx4251")) {
128 *mult = mv98dx4251_cpu_ddr_ratios[opt][0];
129 *div = mv98dx4251_cpu_ddr_ratios[opt][1];
130 } else if (of_machine_is_compatible("marvell,armadaxp-98dx3236")) {
131 *mult = mv98dx3236_cpu_ddr_ratios[opt][0];
132 *div = mv98dx3236_cpu_ddr_ratios[opt][1];
133 }
134 break;
135 case MV98DX3236_CPU_TO_MPLL:
136 if (of_machine_is_compatible("marvell,armadaxp-98dx4251")) {
137 *mult = mv98dx4251_cpu_mpll_ratios[opt][0];
138 *div = mv98dx4251_cpu_mpll_ratios[opt][1];
139 } else if (of_machine_is_compatible("marvell,armadaxp-98dx3236")) {
140 *mult = mv98dx3236_cpu_mpll_ratios[opt][0];
141 *div = mv98dx3236_cpu_mpll_ratios[opt][1];
142 }
143 break;
144 }
145}
146
147static const struct coreclk_soc_desc mv98dx3236_core_clocks = {
148 .get_tclk_freq = mv98dx3236_get_tclk_freq,
149 .get_cpu_freq = mv98dx3236_get_cpu_freq,
150 .get_clk_ratio = mv98dx3236_get_clk_ratio,
151 .ratios = mv98dx3236_core_ratios,
152 .num_ratios = ARRAY_SIZE(mv98dx3236_core_ratios),
153};
154
155
156/*
157 * Clock Gating Control
158 */
159
160static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initconst = {
161 { "ge1", NULL, 3, 0 },
162 { "ge0", NULL, 4, 0 },
163 { "pex00", NULL, 5, 0 },
164 { "sdio", NULL, 17, 0 },
165 { "usb0", NULL, 18, 0 },
166 { "xor0", NULL, 22, 0 },
167 { }
168};
169
170static void __init mv98dx3236_clk_init(struct device_node *np)
171{
172 struct device_node *cgnp =
173 of_find_compatible_node(NULL, NULL, "marvell,mv98dx3236-gating-clock");
174
175 mvebu_coreclk_setup(np, &mv98dx3236_core_clocks);
176
177 if (cgnp)
178 mvebu_clk_gating_setup(cgnp, mv98dx3236_gating_desc);
179}
180CLK_OF_DECLARE(mv98dx3236_clk, "marvell,mv98dx3236-core-clock", mv98dx3236_clk_init);
diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c
index 07e2cc6ed781..3487c267833e 100644
--- a/drivers/clk/qcom/clk-smd-rpm.c
+++ b/drivers/clk/qcom/clk-smd-rpm.c
@@ -462,8 +462,79 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8916 = {
462 .num_clks = ARRAY_SIZE(msm8916_clks), 462 .num_clks = ARRAY_SIZE(msm8916_clks),
463}; 463};
464 464
465/* msm8974 */
466DEFINE_CLK_SMD_RPM(msm8974, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
467DEFINE_CLK_SMD_RPM(msm8974, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
468DEFINE_CLK_SMD_RPM(msm8974, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
469DEFINE_CLK_SMD_RPM(msm8974, mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, QCOM_SMD_RPM_BUS_CLK, 3);
470DEFINE_CLK_SMD_RPM(msm8974, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
471DEFINE_CLK_SMD_RPM(msm8974, gfx3d_clk_src, gfx3d_a_clk_src, QCOM_SMD_RPM_MEM_CLK, 1);
472DEFINE_CLK_SMD_RPM(msm8974, ocmemgx_clk, ocmemgx_a_clk, QCOM_SMD_RPM_MEM_CLK, 2);
473DEFINE_CLK_SMD_RPM_QDSS(msm8974, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1);
474DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d0, cxo_d0_a, 1);
475DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d1, cxo_d1_a, 2);
476DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a0, cxo_a0_a, 4);
477DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a1, cxo_a1_a, 5);
478DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a2, cxo_a2_a, 6);
479DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, diff_clk, diff_a_clk, 7);
480DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, div_clk1, div_a_clk1, 11);
481DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, div_clk2, div_a_clk2, 12);
482DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_d0_pin, cxo_d0_a_pin, 1);
483DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_d1_pin, cxo_d1_a_pin, 2);
484DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a0_pin, cxo_a0_a_pin, 4);
485DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a1_pin, cxo_a1_a_pin, 5);
486DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a2_pin, cxo_a2_a_pin, 6);
487
488static struct clk_smd_rpm *msm8974_clks[] = {
489 [RPM_SMD_PNOC_CLK] = &msm8974_pnoc_clk,
490 [RPM_SMD_PNOC_A_CLK] = &msm8974_pnoc_a_clk,
491 [RPM_SMD_SNOC_CLK] = &msm8974_snoc_clk,
492 [RPM_SMD_SNOC_A_CLK] = &msm8974_snoc_a_clk,
493 [RPM_SMD_CNOC_CLK] = &msm8974_cnoc_clk,
494 [RPM_SMD_CNOC_A_CLK] = &msm8974_cnoc_a_clk,
495 [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8974_mmssnoc_ahb_clk,
496 [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8974_mmssnoc_ahb_a_clk,
497 [RPM_SMD_BIMC_CLK] = &msm8974_bimc_clk,
498 [RPM_SMD_BIMC_A_CLK] = &msm8974_bimc_a_clk,
499 [RPM_SMD_OCMEMGX_CLK] = &msm8974_ocmemgx_clk,
500 [RPM_SMD_OCMEMGX_A_CLK] = &msm8974_ocmemgx_a_clk,
501 [RPM_SMD_QDSS_CLK] = &msm8974_qdss_clk,
502 [RPM_SMD_QDSS_A_CLK] = &msm8974_qdss_a_clk,
503 [RPM_SMD_CXO_D0] = &msm8974_cxo_d0,
504 [RPM_SMD_CXO_D0_A] = &msm8974_cxo_d0_a,
505 [RPM_SMD_CXO_D1] = &msm8974_cxo_d1,
506 [RPM_SMD_CXO_D1_A] = &msm8974_cxo_d1_a,
507 [RPM_SMD_CXO_A0] = &msm8974_cxo_a0,
508 [RPM_SMD_CXO_A0_A] = &msm8974_cxo_a0_a,
509 [RPM_SMD_CXO_A1] = &msm8974_cxo_a1,
510 [RPM_SMD_CXO_A1_A] = &msm8974_cxo_a1_a,
511 [RPM_SMD_CXO_A2] = &msm8974_cxo_a2,
512 [RPM_SMD_CXO_A2_A] = &msm8974_cxo_a2_a,
513 [RPM_SMD_DIFF_CLK] = &msm8974_diff_clk,
514 [RPM_SMD_DIFF_A_CLK] = &msm8974_diff_a_clk,
515 [RPM_SMD_DIV_CLK1] = &msm8974_div_clk1,
516 [RPM_SMD_DIV_A_CLK1] = &msm8974_div_a_clk1,
517 [RPM_SMD_DIV_CLK2] = &msm8974_div_clk2,
518 [RPM_SMD_DIV_A_CLK2] = &msm8974_div_a_clk2,
519 [RPM_SMD_CXO_D0_PIN] = &msm8974_cxo_d0_pin,
520 [RPM_SMD_CXO_D0_A_PIN] = &msm8974_cxo_d0_a_pin,
521 [RPM_SMD_CXO_D1_PIN] = &msm8974_cxo_d1_pin,
522 [RPM_SMD_CXO_D1_A_PIN] = &msm8974_cxo_d1_a_pin,
523 [RPM_SMD_CXO_A0_PIN] = &msm8974_cxo_a0_pin,
524 [RPM_SMD_CXO_A0_A_PIN] = &msm8974_cxo_a0_a_pin,
525 [RPM_SMD_CXO_A1_PIN] = &msm8974_cxo_a1_pin,
526 [RPM_SMD_CXO_A1_A_PIN] = &msm8974_cxo_a1_a_pin,
527 [RPM_SMD_CXO_A2_PIN] = &msm8974_cxo_a2_pin,
528 [RPM_SMD_CXO_A2_A_PIN] = &msm8974_cxo_a2_a_pin,
529};
530
531static const struct rpm_smd_clk_desc rpm_clk_msm8974 = {
532 .clks = msm8974_clks,
533 .num_clks = ARRAY_SIZE(msm8974_clks),
534};
465static const struct of_device_id rpm_smd_clk_match_table[] = { 535static const struct of_device_id rpm_smd_clk_match_table[] = {
466 { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, 536 { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
537 { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
467 { } 538 { }
468}; 539};
469MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table); 540MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index cfab7b400381..03f9d316f969 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -145,7 +145,6 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
145 clocks_node = of_find_node_by_path("/clocks"); 145 clocks_node = of_find_node_by_path("/clocks");
146 if (clocks_node) 146 if (clocks_node)
147 node = of_find_node_by_name(clocks_node, path); 147 node = of_find_node_by_name(clocks_node, path);
148 of_node_put(clocks_node);
149 148
150 if (!node) { 149 if (!node) {
151 fixed = devm_kzalloc(dev, sizeof(*fixed), GFP_KERNEL); 150 fixed = devm_kzalloc(dev, sizeof(*fixed), GFP_KERNEL);
diff --git a/drivers/clk/qcom/gcc-ipq4019.c b/drivers/clk/qcom/gcc-ipq4019.c
index 33d09138f5e5..46cb256b4aa2 100644
--- a/drivers/clk/qcom/gcc-ipq4019.c
+++ b/drivers/clk/qcom/gcc-ipq4019.c
@@ -20,6 +20,9 @@
20#include <linux/clk-provider.h> 20#include <linux/clk-provider.h>
21#include <linux/regmap.h> 21#include <linux/regmap.h>
22#include <linux/reset-controller.h> 22#include <linux/reset-controller.h>
23#include <linux/math64.h>
24#include <linux/delay.h>
25#include <linux/clk.h>
23 26
24#include <dt-bindings/clock/qcom,gcc-ipq4019.h> 27#include <dt-bindings/clock/qcom,gcc-ipq4019.h>
25 28
@@ -28,6 +31,13 @@
28#include "clk-rcg.h" 31#include "clk-rcg.h"
29#include "clk-branch.h" 32#include "clk-branch.h"
30#include "reset.h" 33#include "reset.h"
34#include "clk-regmap-divider.h"
35
36#define to_clk_regmap_div(_hw) container_of(to_clk_regmap(_hw),\
37 struct clk_regmap_div, clkr)
38
39#define to_clk_fepll(_hw) container_of(to_clk_regmap_div(_hw),\
40 struct clk_fepll, cdiv)
31 41
32enum { 42enum {
33 P_XO, 43 P_XO,
@@ -40,6 +50,41 @@ enum {
40 P_DDRPLLAPSS, 50 P_DDRPLLAPSS,
41}; 51};
42 52
53/*
54 * struct clk_fepll_vco - vco feedback divider corresponds for FEPLL clocks
55 * @fdbkdiv_shift: lowest bit for FDBKDIV
56 * @fdbkdiv_width: number of bits in FDBKDIV
57 * @refclkdiv_shift: lowest bit for REFCLKDIV
58 * @refclkdiv_width: number of bits in REFCLKDIV
59 * @reg: PLL_DIV register address
60 */
61struct clk_fepll_vco {
62 u32 fdbkdiv_shift;
63 u32 fdbkdiv_width;
64 u32 refclkdiv_shift;
65 u32 refclkdiv_width;
66 u32 reg;
67};
68
69/*
70 * struct clk_fepll - clk divider corresponds to FEPLL clocks
71 * @fixed_div: fixed divider value if divider is fixed
72 * @parent_map: map from software's parent index to hardware's src_sel field
73 * @cdiv: divider values for PLL_DIV
74 * @pll_vco: vco feedback divider
75 * @div_table: mapping for actual divider value to register divider value
76 * in case of non fixed divider
77 * @freq_tbl: frequency table
78 */
79struct clk_fepll {
80 u32 fixed_div;
81 const u8 *parent_map;
82 struct clk_regmap_div cdiv;
83 const struct clk_fepll_vco *pll_vco;
84 const struct clk_div_table *div_table;
85 const struct freq_tbl *freq_tbl;
86};
87
43static struct parent_map gcc_xo_200_500_map[] = { 88static struct parent_map gcc_xo_200_500_map[] = {
44 { P_XO, 0 }, 89 { P_XO, 0 },
45 { P_FEPLL200, 1 }, 90 { P_FEPLL200, 1 },
@@ -80,7 +125,7 @@ static struct parent_map gcc_xo_sdcc1_500_map[] = {
80 125
81static const char * const gcc_xo_sdcc1_500[] = { 126static const char * const gcc_xo_sdcc1_500[] = {
82 "xo", 127 "xo",
83 "ddrpll", 128 "ddrpllsdcc",
84 "fepll500", 129 "fepll500",
85}; 130};
86 131
@@ -121,6 +166,12 @@ static struct parent_map gcc_xo_ddr_500_200_map[] = {
121 { P_DDRPLLAPSS, 1 }, 166 { P_DDRPLLAPSS, 1 },
122}; 167};
123 168
169/*
170 * Contains index for safe clock during APSS freq change.
171 * fepll500 is being used as safe clock so initialize it
172 * with its index in parents list gcc_xo_ddr_500_200.
173 */
174static const int gcc_ipq4019_cpu_safe_parent = 2;
124static const char * const gcc_xo_ddr_500_200[] = { 175static const char * const gcc_xo_ddr_500_200[] = {
125 "xo", 176 "xo",
126 "fepll200", 177 "fepll200",
@@ -505,7 +556,7 @@ static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = {
505 F(25000000, P_FEPLL500, 1, 1, 20), 556 F(25000000, P_FEPLL500, 1, 1, 20),
506 F(50000000, P_FEPLL500, 1, 1, 10), 557 F(50000000, P_FEPLL500, 1, 1, 10),
507 F(100000000, P_FEPLL500, 1, 1, 5), 558 F(100000000, P_FEPLL500, 1, 1, 5),
508 F(193000000, P_DDRPLL, 1, 0, 0), 559 F(192000000, P_DDRPLL, 1, 0, 0),
509 { } 560 { }
510}; 561};
511 562
@@ -524,10 +575,20 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
524}; 575};
525 576
526static const struct freq_tbl ftbl_gcc_apps_clk[] = { 577static const struct freq_tbl ftbl_gcc_apps_clk[] = {
527 F(48000000, P_XO, 1, 0, 0), 578 F(48000000, P_XO, 1, 0, 0),
528 F(200000000, P_FEPLL200, 1, 0, 0), 579 F(200000000, P_FEPLL200, 1, 0, 0),
580 F(384000000, P_DDRPLLAPSS, 1, 0, 0),
581 F(413000000, P_DDRPLLAPSS, 1, 0, 0),
582 F(448000000, P_DDRPLLAPSS, 1, 0, 0),
583 F(488000000, P_DDRPLLAPSS, 1, 0, 0),
529 F(500000000, P_FEPLL500, 1, 0, 0), 584 F(500000000, P_FEPLL500, 1, 0, 0),
530 F(626000000, P_DDRPLLAPSS, 1, 0, 0), 585 F(512000000, P_DDRPLLAPSS, 1, 0, 0),
586 F(537000000, P_DDRPLLAPSS, 1, 0, 0),
587 F(565000000, P_DDRPLLAPSS, 1, 0, 0),
588 F(597000000, P_DDRPLLAPSS, 1, 0, 0),
589 F(632000000, P_DDRPLLAPSS, 1, 0, 0),
590 F(672000000, P_DDRPLLAPSS, 1, 0, 0),
591 F(716000000, P_DDRPLLAPSS, 1, 0, 0),
531 { } 592 { }
532}; 593};
533 594
@@ -541,6 +602,7 @@ static struct clk_rcg2 apps_clk_src = {
541 .parent_names = gcc_xo_ddr_500_200, 602 .parent_names = gcc_xo_ddr_500_200,
542 .num_parents = 4, 603 .num_parents = 4,
543 .ops = &clk_rcg2_ops, 604 .ops = &clk_rcg2_ops,
605 .flags = CLK_SET_RATE_PARENT,
544 }, 606 },
545}; 607};
546 608
@@ -1154,6 +1216,364 @@ static struct clk_branch gcc_wcss5g_rtc_clk = {
1154 }, 1216 },
1155}; 1217};
1156 1218
1219/* Calculates the VCO rate for FEPLL. */
1220static u64 clk_fepll_vco_calc_rate(struct clk_fepll *pll_div,
1221 unsigned long parent_rate)
1222{
1223 const struct clk_fepll_vco *pll_vco = pll_div->pll_vco;
1224 u32 fdbkdiv, refclkdiv, cdiv;
1225 u64 vco;
1226
1227 regmap_read(pll_div->cdiv.clkr.regmap, pll_vco->reg, &cdiv);
1228 refclkdiv = (cdiv >> pll_vco->refclkdiv_shift) &
1229 (BIT(pll_vco->refclkdiv_width) - 1);
1230 fdbkdiv = (cdiv >> pll_vco->fdbkdiv_shift) &
1231 (BIT(pll_vco->fdbkdiv_width) - 1);
1232
1233 vco = parent_rate / refclkdiv;
1234 vco *= 2;
1235 vco *= fdbkdiv;
1236
1237 return vco;
1238}
1239
1240static const struct clk_fepll_vco gcc_apss_ddrpll_vco = {
1241 .fdbkdiv_shift = 16,
1242 .fdbkdiv_width = 8,
1243 .refclkdiv_shift = 24,
1244 .refclkdiv_width = 5,
1245 .reg = 0x2e020,
1246};
1247
1248static const struct clk_fepll_vco gcc_fepll_vco = {
1249 .fdbkdiv_shift = 16,
1250 .fdbkdiv_width = 8,
1251 .refclkdiv_shift = 24,
1252 .refclkdiv_width = 5,
1253 .reg = 0x2f020,
1254};
1255
1256/*
1257 * Round rate function for APSS CPU PLL Clock divider.
1258 * It looks up the frequency table and returns the next higher frequency
1259 * supported in hardware.
1260 */
1261static long clk_cpu_div_round_rate(struct clk_hw *hw, unsigned long rate,
1262 unsigned long *p_rate)
1263{
1264 struct clk_fepll *pll = to_clk_fepll(hw);
1265 struct clk_hw *p_hw;
1266 const struct freq_tbl *f;
1267
1268 f = qcom_find_freq(pll->freq_tbl, rate);
1269 if (!f)
1270 return -EINVAL;
1271
1272 p_hw = clk_hw_get_parent_by_index(hw, f->src);
1273 *p_rate = clk_hw_get_rate(p_hw);
1274
1275 return f->freq;
1276};
1277
1278/*
1279 * Clock set rate function for APSS CPU PLL Clock divider.
1280 * It looks up the frequency table and updates the PLL divider to corresponding
1281 * divider value.
1282 */
1283static int clk_cpu_div_set_rate(struct clk_hw *hw, unsigned long rate,
1284 unsigned long parent_rate)
1285{
1286 struct clk_fepll *pll = to_clk_fepll(hw);
1287 const struct freq_tbl *f;
1288 u32 mask;
1289 int ret;
1290
1291 f = qcom_find_freq(pll->freq_tbl, rate);
1292 if (!f)
1293 return -EINVAL;
1294
1295 mask = (BIT(pll->cdiv.width) - 1) << pll->cdiv.shift;
1296 ret = regmap_update_bits(pll->cdiv.clkr.regmap,
1297 pll->cdiv.reg, mask,
1298 f->pre_div << pll->cdiv.shift);
1299 /*
1300 * There is no status bit which can be checked for successful CPU
1301 * divider update operation so using delay for the same.
1302 */
1303 udelay(1);
1304
1305 return 0;
1306};
1307
1308/*
1309 * Clock frequency calculation function for APSS CPU PLL Clock divider.
1310 * This clock divider is nonlinear so this function calculates the actual
1311 * divider and returns the output frequency by dividing VCO Frequency
1312 * with this actual divider value.
1313 */
1314static unsigned long
1315clk_cpu_div_recalc_rate(struct clk_hw *hw,
1316 unsigned long parent_rate)
1317{
1318 struct clk_fepll *pll = to_clk_fepll(hw);
1319 u32 cdiv, pre_div;
1320 u64 rate;
1321
1322 regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv);
1323 cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1);
1324
1325 /*
1326 * Some dividers have value in 0.5 fraction so multiply both VCO
1327 * frequency(parent_rate) and pre_div with 2 to make integer
1328 * calculation.
1329 */
1330 if (cdiv > 10)
1331 pre_div = (cdiv + 1) * 2;
1332 else
1333 pre_div = cdiv + 12;
1334
1335 rate = clk_fepll_vco_calc_rate(pll, parent_rate) * 2;
1336 do_div(rate, pre_div);
1337
1338 return rate;
1339};
1340
1341static const struct clk_ops clk_regmap_cpu_div_ops = {
1342 .round_rate = clk_cpu_div_round_rate,
1343 .set_rate = clk_cpu_div_set_rate,
1344 .recalc_rate = clk_cpu_div_recalc_rate,
1345};
1346
1347static const struct freq_tbl ftbl_apss_ddr_pll[] = {
1348 { 384000000, P_XO, 0xd, 0, 0 },
1349 { 413000000, P_XO, 0xc, 0, 0 },
1350 { 448000000, P_XO, 0xb, 0, 0 },
1351 { 488000000, P_XO, 0xa, 0, 0 },
1352 { 512000000, P_XO, 0x9, 0, 0 },
1353 { 537000000, P_XO, 0x8, 0, 0 },
1354 { 565000000, P_XO, 0x7, 0, 0 },
1355 { 597000000, P_XO, 0x6, 0, 0 },
1356 { 632000000, P_XO, 0x5, 0, 0 },
1357 { 672000000, P_XO, 0x4, 0, 0 },
1358 { 716000000, P_XO, 0x3, 0, 0 },
1359 { 768000000, P_XO, 0x2, 0, 0 },
1360 { 823000000, P_XO, 0x1, 0, 0 },
1361 { 896000000, P_XO, 0x0, 0, 0 },
1362 { }
1363};
1364
1365static struct clk_fepll gcc_apss_cpu_plldiv_clk = {
1366 .cdiv.reg = 0x2e020,
1367 .cdiv.shift = 4,
1368 .cdiv.width = 4,
1369 .cdiv.clkr = {
1370 .enable_reg = 0x2e000,
1371 .enable_mask = BIT(0),
1372 .hw.init = &(struct clk_init_data){
1373 .name = "ddrpllapss",
1374 .parent_names = (const char *[]){
1375 "xo",
1376 },
1377 .num_parents = 1,
1378 .ops = &clk_regmap_cpu_div_ops,
1379 },
1380 },
1381 .freq_tbl = ftbl_apss_ddr_pll,
1382 .pll_vco = &gcc_apss_ddrpll_vco,
1383};
1384
1385/* Calculates the rate for PLL divider.
1386 * If the divider value is not fixed then it gets the actual divider value
1387 * from divider table. Then, it calculate the clock rate by dividing the
1388 * parent rate with actual divider value.
1389 */
1390static unsigned long
1391clk_regmap_clk_div_recalc_rate(struct clk_hw *hw,
1392 unsigned long parent_rate)
1393{
1394 struct clk_fepll *pll = to_clk_fepll(hw);
1395 u32 cdiv, pre_div = 1;
1396 u64 rate;
1397 const struct clk_div_table *clkt;
1398
1399 if (pll->fixed_div) {
1400 pre_div = pll->fixed_div;
1401 } else {
1402 regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv);
1403 cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1);
1404
1405 for (clkt = pll->div_table; clkt->div; clkt++) {
1406 if (clkt->val == cdiv)
1407 pre_div = clkt->div;
1408 }
1409 }
1410
1411 rate = clk_fepll_vco_calc_rate(pll, parent_rate);
1412 do_div(rate, pre_div);
1413
1414 return rate;
1415};
1416
1417static const struct clk_ops clk_fepll_div_ops = {
1418 .recalc_rate = clk_regmap_clk_div_recalc_rate,
1419};
1420
1421static struct clk_fepll gcc_apss_sdcc_clk = {
1422 .fixed_div = 28,
1423 .cdiv.clkr = {
1424 .hw.init = &(struct clk_init_data){
1425 .name = "ddrpllsdcc",
1426 .parent_names = (const char *[]){
1427 "xo",
1428 },
1429 .num_parents = 1,
1430 .ops = &clk_fepll_div_ops,
1431 },
1432 },
1433 .pll_vco = &gcc_apss_ddrpll_vco,
1434};
1435
1436static struct clk_fepll gcc_fepll125_clk = {
1437 .fixed_div = 32,
1438 .cdiv.clkr = {
1439 .hw.init = &(struct clk_init_data){
1440 .name = "fepll125",
1441 .parent_names = (const char *[]){
1442 "xo",
1443 },
1444 .num_parents = 1,
1445 .ops = &clk_fepll_div_ops,
1446 },
1447 },
1448 .pll_vco = &gcc_fepll_vco,
1449};
1450
1451static struct clk_fepll gcc_fepll125dly_clk = {
1452 .fixed_div = 32,
1453 .cdiv.clkr = {
1454 .hw.init = &(struct clk_init_data){
1455 .name = "fepll125dly",
1456 .parent_names = (const char *[]){
1457 "xo",
1458 },
1459 .num_parents = 1,
1460 .ops = &clk_fepll_div_ops,
1461 },
1462 },
1463 .pll_vco = &gcc_fepll_vco,
1464};
1465
1466static struct clk_fepll gcc_fepll200_clk = {
1467 .fixed_div = 20,
1468 .cdiv.clkr = {
1469 .hw.init = &(struct clk_init_data){
1470 .name = "fepll200",
1471 .parent_names = (const char *[]){
1472 "xo",
1473 },
1474 .num_parents = 1,
1475 .ops = &clk_fepll_div_ops,
1476 },
1477 },
1478 .pll_vco = &gcc_fepll_vco,
1479};
1480
1481static struct clk_fepll gcc_fepll500_clk = {
1482 .fixed_div = 8,
1483 .cdiv.clkr = {
1484 .hw.init = &(struct clk_init_data){
1485 .name = "fepll500",
1486 .parent_names = (const char *[]){
1487 "xo",
1488 },
1489 .num_parents = 1,
1490 .ops = &clk_fepll_div_ops,
1491 },
1492 },
1493 .pll_vco = &gcc_fepll_vco,
1494};
1495
1496static const struct clk_div_table fepllwcss_clk_div_table[] = {
1497 { 0, 15 },
1498 { 1, 16 },
1499 { 2, 18 },
1500 { 3, 20 },
1501 { },
1502};
1503
1504static struct clk_fepll gcc_fepllwcss2g_clk = {
1505 .cdiv.reg = 0x2f020,
1506 .cdiv.shift = 8,
1507 .cdiv.width = 2,
1508 .cdiv.clkr = {
1509 .hw.init = &(struct clk_init_data){
1510 .name = "fepllwcss2g",
1511 .parent_names = (const char *[]){
1512 "xo",
1513 },
1514 .num_parents = 1,
1515 .ops = &clk_fepll_div_ops,
1516 },
1517 },
1518 .div_table = fepllwcss_clk_div_table,
1519 .pll_vco = &gcc_fepll_vco,
1520};
1521
1522static struct clk_fepll gcc_fepllwcss5g_clk = {
1523 .cdiv.reg = 0x2f020,
1524 .cdiv.shift = 12,
1525 .cdiv.width = 2,
1526 .cdiv.clkr = {
1527 .hw.init = &(struct clk_init_data){
1528 .name = "fepllwcss5g",
1529 .parent_names = (const char *[]){
1530 "xo",
1531 },
1532 .num_parents = 1,
1533 .ops = &clk_fepll_div_ops,
1534 },
1535 },
1536 .div_table = fepllwcss_clk_div_table,
1537 .pll_vco = &gcc_fepll_vco,
1538};
1539
1540static const struct freq_tbl ftbl_gcc_pcnoc_ahb_clk[] = {
1541 F(48000000, P_XO, 1, 0, 0),
1542 F(100000000, P_FEPLL200, 2, 0, 0),
1543 { }
1544};
1545
1546static struct clk_rcg2 gcc_pcnoc_ahb_clk_src = {
1547 .cmd_rcgr = 0x21024,
1548 .hid_width = 5,
1549 .parent_map = gcc_xo_200_500_map,
1550 .freq_tbl = ftbl_gcc_pcnoc_ahb_clk,
1551 .clkr.hw.init = &(struct clk_init_data){
1552 .name = "gcc_pcnoc_ahb_clk_src",
1553 .parent_names = gcc_xo_200_500,
1554 .num_parents = 3,
1555 .ops = &clk_rcg2_ops,
1556 },
1557};
1558
1559static struct clk_branch pcnoc_clk_src = {
1560 .halt_reg = 0x21030,
1561 .clkr = {
1562 .enable_reg = 0x21030,
1563 .enable_mask = BIT(0),
1564 .hw.init = &(struct clk_init_data){
1565 .name = "pcnoc_clk_src",
1566 .parent_names = (const char *[]){
1567 "gcc_pcnoc_ahb_clk_src",
1568 },
1569 .num_parents = 1,
1570 .ops = &clk_branch2_ops,
1571 .flags = CLK_SET_RATE_PARENT |
1572 CLK_IS_CRITICAL,
1573 },
1574 },
1575};
1576
1157static struct clk_regmap *gcc_ipq4019_clocks[] = { 1577static struct clk_regmap *gcc_ipq4019_clocks[] = {
1158 [AUDIO_CLK_SRC] = &audio_clk_src.clkr, 1578 [AUDIO_CLK_SRC] = &audio_clk_src.clkr,
1159 [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, 1579 [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
@@ -1214,6 +1634,16 @@ static struct clk_regmap *gcc_ipq4019_clocks[] = {
1214 [GCC_WCSS5G_CLK] = &gcc_wcss5g_clk.clkr, 1634 [GCC_WCSS5G_CLK] = &gcc_wcss5g_clk.clkr,
1215 [GCC_WCSS5G_REF_CLK] = &gcc_wcss5g_ref_clk.clkr, 1635 [GCC_WCSS5G_REF_CLK] = &gcc_wcss5g_ref_clk.clkr,
1216 [GCC_WCSS5G_RTC_CLK] = &gcc_wcss5g_rtc_clk.clkr, 1636 [GCC_WCSS5G_RTC_CLK] = &gcc_wcss5g_rtc_clk.clkr,
1637 [GCC_SDCC_PLLDIV_CLK] = &gcc_apss_sdcc_clk.cdiv.clkr,
1638 [GCC_FEPLL125_CLK] = &gcc_fepll125_clk.cdiv.clkr,
1639 [GCC_FEPLL125DLY_CLK] = &gcc_fepll125dly_clk.cdiv.clkr,
1640 [GCC_FEPLL200_CLK] = &gcc_fepll200_clk.cdiv.clkr,
1641 [GCC_FEPLL500_CLK] = &gcc_fepll500_clk.cdiv.clkr,
1642 [GCC_FEPLL_WCSS2G_CLK] = &gcc_fepllwcss2g_clk.cdiv.clkr,
1643 [GCC_FEPLL_WCSS5G_CLK] = &gcc_fepllwcss5g_clk.cdiv.clkr,
1644 [GCC_APSS_CPU_PLLDIV_CLK] = &gcc_apss_cpu_plldiv_clk.cdiv.clkr,
1645 [GCC_PCNOC_AHB_CLK_SRC] = &gcc_pcnoc_ahb_clk_src.clkr,
1646 [GCC_PCNOC_AHB_CLK] = &pcnoc_clk_src.clkr,
1217}; 1647};
1218 1648
1219static const struct qcom_reset_map gcc_ipq4019_resets[] = { 1649static const struct qcom_reset_map gcc_ipq4019_resets[] = {
@@ -1294,7 +1724,7 @@ static const struct regmap_config gcc_ipq4019_regmap_config = {
1294 .reg_bits = 32, 1724 .reg_bits = 32,
1295 .reg_stride = 4, 1725 .reg_stride = 4,
1296 .val_bits = 32, 1726 .val_bits = 32,
1297 .max_register = 0x2dfff, 1727 .max_register = 0x2ffff,
1298 .fast_io = true, 1728 .fast_io = true,
1299}; 1729};
1300 1730
@@ -1312,23 +1742,44 @@ static const struct of_device_id gcc_ipq4019_match_table[] = {
1312}; 1742};
1313MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table); 1743MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table);
1314 1744
1745static int
1746gcc_ipq4019_cpu_clk_notifier_fn(struct notifier_block *nb,
1747 unsigned long action, void *data)
1748{
1749 int err = 0;
1750
1751 if (action == PRE_RATE_CHANGE)
1752 err = clk_rcg2_ops.set_parent(&apps_clk_src.clkr.hw,
1753 gcc_ipq4019_cpu_safe_parent);
1754
1755 return notifier_from_errno(err);
1756}
1757
1758static struct notifier_block gcc_ipq4019_cpu_clk_notifier = {
1759 .notifier_call = gcc_ipq4019_cpu_clk_notifier_fn,
1760};
1761
1315static int gcc_ipq4019_probe(struct platform_device *pdev) 1762static int gcc_ipq4019_probe(struct platform_device *pdev)
1316{ 1763{
1317 struct device *dev = &pdev->dev; 1764 int err;
1318 1765
1319 clk_register_fixed_rate(dev, "fepll125", "xo", 0, 200000000); 1766 err = qcom_cc_probe(pdev, &gcc_ipq4019_desc);
1320 clk_register_fixed_rate(dev, "fepll125dly", "xo", 0, 200000000); 1767 if (err)
1321 clk_register_fixed_rate(dev, "fepllwcss2g", "xo", 0, 200000000); 1768 return err;
1322 clk_register_fixed_rate(dev, "fepllwcss5g", "xo", 0, 200000000);
1323 clk_register_fixed_rate(dev, "fepll200", "xo", 0, 200000000);
1324 clk_register_fixed_rate(dev, "fepll500", "xo", 0, 200000000);
1325 clk_register_fixed_rate(dev, "ddrpllapss", "xo", 0, 666000000);
1326 1769
1327 return qcom_cc_probe(pdev, &gcc_ipq4019_desc); 1770 return clk_notifier_register(apps_clk_src.clkr.hw.clk,
1771 &gcc_ipq4019_cpu_clk_notifier);
1772}
1773
1774static int gcc_ipq4019_remove(struct platform_device *pdev)
1775{
1776 return clk_notifier_unregister(apps_clk_src.clkr.hw.clk,
1777 &gcc_ipq4019_cpu_clk_notifier);
1328} 1778}
1329 1779
1330static struct platform_driver gcc_ipq4019_driver = { 1780static struct platform_driver gcc_ipq4019_driver = {
1331 .probe = gcc_ipq4019_probe, 1781 .probe = gcc_ipq4019_probe,
1782 .remove = gcc_ipq4019_remove,
1332 .driver = { 1783 .driver = {
1333 .name = "qcom,gcc-ipq4019", 1784 .name = "qcom,gcc-ipq4019",
1334 .of_match_table = gcc_ipq4019_match_table, 1785 .of_match_table = gcc_ipq4019_match_table,
diff --git a/drivers/clk/qcom/gcc-mdm9615.c b/drivers/clk/qcom/gcc-mdm9615.c
index 581a17f67379..b99dd406e907 100644
--- a/drivers/clk/qcom/gcc-mdm9615.c
+++ b/drivers/clk/qcom/gcc-mdm9615.c
@@ -1563,6 +1563,34 @@ static struct clk_branch rpm_msg_ram_h_clk = {
1563 }, 1563 },
1564}; 1564};
1565 1565
1566static struct clk_branch ebi2_clk = {
1567 .hwcg_reg = 0x2664,
1568 .hwcg_bit = 6,
1569 .halt_reg = 0x2fcc,
1570 .halt_bit = 24,
1571 .clkr = {
1572 .enable_reg = 0x2664,
1573 .enable_mask = BIT(6) | BIT(4),
1574 .hw.init = &(struct clk_init_data){
1575 .name = "ebi2_clk",
1576 .ops = &clk_branch_ops,
1577 },
1578 },
1579};
1580
1581static struct clk_branch ebi2_aon_clk = {
1582 .halt_reg = 0x2fcc,
1583 .halt_bit = 23,
1584 .clkr = {
1585 .enable_reg = 0x2664,
1586 .enable_mask = BIT(8),
1587 .hw.init = &(struct clk_init_data){
1588 .name = "ebi2_aon_clk",
1589 .ops = &clk_branch_ops,
1590 },
1591 },
1592};
1593
1566static struct clk_hw *gcc_mdm9615_hws[] = { 1594static struct clk_hw *gcc_mdm9615_hws[] = {
1567 &cxo.hw, 1595 &cxo.hw,
1568}; 1596};
@@ -1637,6 +1665,8 @@ static struct clk_regmap *gcc_mdm9615_clks[] = {
1637 [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr, 1665 [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
1638 [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr, 1666 [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
1639 [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr, 1667 [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
1668 [EBI2_CLK] = &ebi2_clk.clkr,
1669 [EBI2_AON_CLK] = &ebi2_aon_clk.clkr,
1640}; 1670};
1641 1671
1642static const struct qcom_reset_map gcc_mdm9615_resets[] = { 1672static const struct qcom_reset_map gcc_mdm9615_resets[] = {
diff --git a/drivers/clk/qcom/gcc-msm8994.c b/drivers/clk/qcom/gcc-msm8994.c
index 8afd8304a070..7983288d9141 100644
--- a/drivers/clk/qcom/gcc-msm8994.c
+++ b/drivers/clk/qcom/gcc-msm8994.c
@@ -1888,6 +1888,23 @@ static struct clk_branch gcc_sdcc1_apps_clk = {
1888 }, 1888 },
1889}; 1889};
1890 1890
1891static struct clk_branch gcc_sdcc1_ahb_clk = {
1892 .halt_reg = 0x04c8,
1893 .clkr = {
1894 .enable_reg = 0x04c8,
1895 .enable_mask = BIT(0),
1896 .hw.init = &(struct clk_init_data)
1897 {
1898 .name = "gcc_sdcc1_ahb_clk",
1899 .parent_names = (const char *[]){
1900 "periph_noc_clk_src",
1901 },
1902 .num_parents = 1,
1903 .ops = &clk_branch2_ops,
1904 },
1905 },
1906};
1907
1891static struct clk_branch gcc_sdcc2_apps_clk = { 1908static struct clk_branch gcc_sdcc2_apps_clk = {
1892 .halt_reg = 0x0504, 1909 .halt_reg = 0x0504,
1893 .clkr = { 1910 .clkr = {
@@ -2231,6 +2248,7 @@ static struct clk_regmap *gcc_msm8994_clocks[] = {
2231 [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, 2248 [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
2232 [GCC_SDCC3_APPS_CLK] = &gcc_sdcc3_apps_clk.clkr, 2249 [GCC_SDCC3_APPS_CLK] = &gcc_sdcc3_apps_clk.clkr,
2233 [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, 2250 [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr,
2251 [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
2234 [GCC_SYS_NOC_UFS_AXI_CLK] = &gcc_sys_noc_ufs_axi_clk.clkr, 2252 [GCC_SYS_NOC_UFS_AXI_CLK] = &gcc_sys_noc_ufs_axi_clk.clkr,
2235 [GCC_SYS_NOC_USB3_AXI_CLK] = &gcc_sys_noc_usb3_axi_clk.clkr, 2253 [GCC_SYS_NOC_USB3_AXI_CLK] = &gcc_sys_noc_usb3_axi_clk.clkr,
2236 [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr, 2254 [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index 4b1fc1730d29..8abc200d4fd3 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -3448,6 +3448,7 @@ static const struct qcom_reset_map gcc_msm8996_resets[] = {
3448 [GCC_MSMPU_BCR] = { 0x8d000 }, 3448 [GCC_MSMPU_BCR] = { 0x8d000 },
3449 [GCC_MSS_Q6_BCR] = { 0x8e000 }, 3449 [GCC_MSS_Q6_BCR] = { 0x8e000 },
3450 [GCC_QREFS_VBG_CAL_BCR] = { 0x88020 }, 3450 [GCC_QREFS_VBG_CAL_BCR] = { 0x88020 },
3451 [GCC_MSS_RESTART] = { 0x8f008 },
3451}; 3452};
3452 3453
3453static const struct regmap_config gcc_msm8996_regmap_config = { 3454static const struct regmap_config gcc_msm8996_regmap_config = {
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index 288186cce0ae..a4f3580587b7 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -63,11 +63,26 @@ static int gdsc_hwctrl(struct gdsc *sc, bool en)
63 return regmap_update_bits(sc->regmap, sc->gdscr, HW_CONTROL_MASK, val); 63 return regmap_update_bits(sc->regmap, sc->gdscr, HW_CONTROL_MASK, val);
64} 64}
65 65
66static int gdsc_poll_status(struct gdsc *sc, unsigned int reg, bool en)
67{
68 ktime_t start;
69
70 start = ktime_get();
71 do {
72 if (gdsc_is_enabled(sc, reg) == en)
73 return 0;
74 } while (ktime_us_delta(ktime_get(), start) < TIMEOUT_US);
75
76 if (gdsc_is_enabled(sc, reg) == en)
77 return 0;
78
79 return -ETIMEDOUT;
80}
81
66static int gdsc_toggle_logic(struct gdsc *sc, bool en) 82static int gdsc_toggle_logic(struct gdsc *sc, bool en)
67{ 83{
68 int ret; 84 int ret;
69 u32 val = en ? 0 : SW_COLLAPSE_MASK; 85 u32 val = en ? 0 : SW_COLLAPSE_MASK;
70 ktime_t start;
71 unsigned int status_reg = sc->gdscr; 86 unsigned int status_reg = sc->gdscr;
72 87
73 ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val); 88 ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
@@ -100,16 +115,7 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en)
100 udelay(1); 115 udelay(1);
101 } 116 }
102 117
103 start = ktime_get(); 118 return gdsc_poll_status(sc, status_reg, en);
104 do {
105 if (gdsc_is_enabled(sc, status_reg) == en)
106 return 0;
107 } while (ktime_us_delta(ktime_get(), start) < TIMEOUT_US);
108
109 if (gdsc_is_enabled(sc, status_reg) == en)
110 return 0;
111
112 return -ETIMEDOUT;
113} 119}
114 120
115static inline int gdsc_deassert_reset(struct gdsc *sc) 121static inline int gdsc_deassert_reset(struct gdsc *sc)
@@ -188,8 +194,20 @@ static int gdsc_enable(struct generic_pm_domain *domain)
188 udelay(1); 194 udelay(1);
189 195
190 /* Turn on HW trigger mode if supported */ 196 /* Turn on HW trigger mode if supported */
191 if (sc->flags & HW_CTRL) 197 if (sc->flags & HW_CTRL) {
192 return gdsc_hwctrl(sc, true); 198 ret = gdsc_hwctrl(sc, true);
199 if (ret)
200 return ret;
201 /*
202 * Wait for the GDSC to go through a power down and
203 * up cycle. In case a firmware ends up polling status
204 * bits for the gdsc, it might read an 'on' status before
205 * the GDSC can finish the power cycle.
206 * We wait 1us before returning to ensure the firmware
207 * can't immediately poll the status bits.
208 */
209 udelay(1);
210 }
193 211
194 return 0; 212 return 0;
195} 213}
@@ -204,9 +222,23 @@ static int gdsc_disable(struct generic_pm_domain *domain)
204 222
205 /* Turn off HW trigger mode if supported */ 223 /* Turn off HW trigger mode if supported */
206 if (sc->flags & HW_CTRL) { 224 if (sc->flags & HW_CTRL) {
225 unsigned int reg;
226
207 ret = gdsc_hwctrl(sc, false); 227 ret = gdsc_hwctrl(sc, false);
208 if (ret < 0) 228 if (ret < 0)
209 return ret; 229 return ret;
230 /*
231 * Wait for the GDSC to go through a power down and
232 * up cycle. In case we end up polling status
233 * bits for the gdsc before the power cycle is completed
234 * it might read an 'on' status wrongly.
235 */
236 udelay(1);
237
238 reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr;
239 ret = gdsc_poll_status(sc, reg, true);
240 if (ret)
241 return ret;
210 } 242 }
211 243
212 if (sc->pwrsts & PWRSTS_OFF) 244 if (sc->pwrsts & PWRSTS_OFF)
diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c
index b533f99550e1..4067216bf31f 100644
--- a/drivers/clk/renesas/clk-mstp.c
+++ b/drivers/clk/renesas/clk-mstp.c
@@ -91,6 +91,12 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
91 value |= bitmask; 91 value |= bitmask;
92 cpg_mstp_write(group, value, group->smstpcr); 92 cpg_mstp_write(group, value, group->smstpcr);
93 93
94 if (!group->mstpsr) {
95 /* dummy read to ensure write has completed */
96 cpg_mstp_read(group, group->smstpcr);
97 barrier_data(group->smstpcr);
98 }
99
94 spin_unlock_irqrestore(&group->lock, flags); 100 spin_unlock_irqrestore(&group->lock, flags);
95 101
96 if (!enable || !group->mstpsr) 102 if (!enable || !group->mstpsr)
@@ -141,9 +147,9 @@ static const struct clk_ops cpg_mstp_clock_ops = {
141 .is_enabled = cpg_mstp_clock_is_enabled, 147 .is_enabled = cpg_mstp_clock_is_enabled,
142}; 148};
143 149
144static struct clk * __init 150static struct clk * __init cpg_mstp_clock_register(const char *name,
145cpg_mstp_clock_register(const char *name, const char *parent_name, 151 const char *parent_name, unsigned int index,
146 unsigned int index, struct mstp_clock_group *group) 152 struct mstp_clock_group *group)
147{ 153{
148 struct clk_init_data init; 154 struct clk_init_data init;
149 struct mstp_clock *clock; 155 struct mstp_clock *clock;
@@ -158,6 +164,11 @@ cpg_mstp_clock_register(const char *name, const char *parent_name,
158 init.name = name; 164 init.name = name;
159 init.ops = &cpg_mstp_clock_ops; 165 init.ops = &cpg_mstp_clock_ops;
160 init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; 166 init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
167 /* INTC-SYS is the module clock of the GIC, and must not be disabled */
168 if (!strcmp(name, "intc-sys")) {
169 pr_debug("MSTP %s setting CLK_IS_CRITICAL\n", name);
170 init.flags |= CLK_IS_CRITICAL;
171 }
161 init.parent_names = &parent_name; 172 init.parent_names = &parent_name;
162 init.num_parents = 1; 173 init.num_parents = 1;
163 174
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
index 50698a7d9074..bfffdb00df97 100644
--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
@@ -221,6 +221,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
221 DEF_MOD("can-if0", 916, R8A7795_CLK_S3D4), 221 DEF_MOD("can-if0", 916, R8A7795_CLK_S3D4),
222 DEF_MOD("i2c6", 918, R8A7795_CLK_S3D2), 222 DEF_MOD("i2c6", 918, R8A7795_CLK_S3D2),
223 DEF_MOD("i2c5", 919, R8A7795_CLK_S3D2), 223 DEF_MOD("i2c5", 919, R8A7795_CLK_S3D2),
224 DEF_MOD("i2c-dvfs", 926, R8A7795_CLK_CP),
224 DEF_MOD("i2c4", 927, R8A7795_CLK_S3D2), 225 DEF_MOD("i2c4", 927, R8A7795_CLK_S3D2),
225 DEF_MOD("i2c3", 928, R8A7795_CLK_S3D2), 226 DEF_MOD("i2c3", 928, R8A7795_CLK_S3D2),
226 DEF_MOD("i2c2", 929, R8A7795_CLK_S3D2), 227 DEF_MOD("i2c2", 929, R8A7795_CLK_S3D2),
diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c
index 7d298c57a3e0..11e084a56b0d 100644
--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
@@ -103,7 +103,9 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
103 DEF_FIXED("cl", R8A7796_CLK_CL, CLK_PLL1_DIV2, 48, 1), 103 DEF_FIXED("cl", R8A7796_CLK_CL, CLK_PLL1_DIV2, 48, 1),
104 DEF_FIXED("cp", R8A7796_CLK_CP, CLK_EXTAL, 2, 1), 104 DEF_FIXED("cp", R8A7796_CLK_CP, CLK_EXTAL, 2, 1),
105 105
106 DEF_DIV6P1("canfd", R8A7796_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
106 DEF_DIV6P1("csi0", R8A7796_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), 107 DEF_DIV6P1("csi0", R8A7796_CLK_CSI0, CLK_PLL1_DIV4, 0x00c),
108 DEF_DIV6P1("mso", R8A7796_CLK_MSO, CLK_PLL1_DIV4, 0x014),
107 109
108 DEF_DIV6_RO("osc", R8A7796_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), 110 DEF_DIV6_RO("osc", R8A7796_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8),
109 DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), 111 DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32),
@@ -117,6 +119,10 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
117 DEF_MOD("scif3", 204, R8A7796_CLK_S3D4), 119 DEF_MOD("scif3", 204, R8A7796_CLK_S3D4),
118 DEF_MOD("scif1", 206, R8A7796_CLK_S3D4), 120 DEF_MOD("scif1", 206, R8A7796_CLK_S3D4),
119 DEF_MOD("scif0", 207, R8A7796_CLK_S3D4), 121 DEF_MOD("scif0", 207, R8A7796_CLK_S3D4),
122 DEF_MOD("msiof3", 208, R8A7796_CLK_MSO),
123 DEF_MOD("msiof2", 209, R8A7796_CLK_MSO),
124 DEF_MOD("msiof1", 210, R8A7796_CLK_MSO),
125 DEF_MOD("msiof0", 211, R8A7796_CLK_MSO),
120 DEF_MOD("sys-dmac2", 217, R8A7796_CLK_S0D3), 126 DEF_MOD("sys-dmac2", 217, R8A7796_CLK_S0D3),
121 DEF_MOD("sys-dmac1", 218, R8A7796_CLK_S0D3), 127 DEF_MOD("sys-dmac1", 218, R8A7796_CLK_S0D3),
122 DEF_MOD("sys-dmac0", 219, R8A7796_CLK_S0D3), 128 DEF_MOD("sys-dmac0", 219, R8A7796_CLK_S0D3),
@@ -181,8 +187,12 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
181 DEF_MOD("gpio2", 910, R8A7796_CLK_S3D4), 187 DEF_MOD("gpio2", 910, R8A7796_CLK_S3D4),
182 DEF_MOD("gpio1", 911, R8A7796_CLK_S3D4), 188 DEF_MOD("gpio1", 911, R8A7796_CLK_S3D4),
183 DEF_MOD("gpio0", 912, R8A7796_CLK_S3D4), 189 DEF_MOD("gpio0", 912, R8A7796_CLK_S3D4),
190 DEF_MOD("can-fd", 914, R8A7796_CLK_S3D2),
191 DEF_MOD("can-if1", 915, R8A7796_CLK_S3D4),
192 DEF_MOD("can-if0", 916, R8A7796_CLK_S3D4),
184 DEF_MOD("i2c6", 918, R8A7796_CLK_S0D6), 193 DEF_MOD("i2c6", 918, R8A7796_CLK_S0D6),
185 DEF_MOD("i2c5", 919, R8A7796_CLK_S0D6), 194 DEF_MOD("i2c5", 919, R8A7796_CLK_S0D6),
195 DEF_MOD("i2c-dvfs", 926, R8A7796_CLK_CP),
186 DEF_MOD("i2c4", 927, R8A7796_CLK_S0D6), 196 DEF_MOD("i2c4", 927, R8A7796_CLK_S0D6),
187 DEF_MOD("i2c3", 928, R8A7796_CLK_S0D6), 197 DEF_MOD("i2c3", 928, R8A7796_CLK_S0D6),
188 DEF_MOD("i2c2", 929, R8A7796_CLK_S3D2), 198 DEF_MOD("i2c2", 929, R8A7796_CLK_S3D2),
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
index 8359ce75db7a..eadcbd43ff88 100644
--- a/drivers/clk/renesas/renesas-cpg-mssr.c
+++ b/drivers/clk/renesas/renesas-cpg-mssr.c
@@ -16,6 +16,7 @@
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/clk-provider.h> 17#include <linux/clk-provider.h>
18#include <linux/clk/renesas.h> 18#include <linux/clk/renesas.h>
19#include <linux/delay.h>
19#include <linux/device.h> 20#include <linux/device.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/mod_devicetable.h> 22#include <linux/mod_devicetable.h>
@@ -25,6 +26,7 @@
25#include <linux/platform_device.h> 26#include <linux/platform_device.h>
26#include <linux/pm_clock.h> 27#include <linux/pm_clock.h>
27#include <linux/pm_domain.h> 28#include <linux/pm_domain.h>
29#include <linux/reset-controller.h>
28#include <linux/slab.h> 30#include <linux/slab.h>
29 31
30#include <dt-bindings/clock/renesas-cpg-mssr.h> 32#include <dt-bindings/clock/renesas-cpg-mssr.h>
@@ -43,7 +45,7 @@
43 * Module Standby and Software Reset register offets. 45 * Module Standby and Software Reset register offets.
44 * 46 *
45 * If the registers exist, these are valid for SH-Mobile, R-Mobile, 47 * If the registers exist, these are valid for SH-Mobile, R-Mobile,
46 * R-Car Gen 2, and R-Car Gen 3. 48 * R-Car Gen2, R-Car Gen3, and RZ/G1.
47 * These are NOT valid for R-Car Gen1 and RZ/A1! 49 * These are NOT valid for R-Car Gen1 and RZ/A1!
48 */ 50 */
49 51
@@ -96,18 +98,22 @@ static const u16 srcr[] = {
96/** 98/**
97 * Clock Pulse Generator / Module Standby and Software Reset Private Data 99 * Clock Pulse Generator / Module Standby and Software Reset Private Data
98 * 100 *
101 * @rcdev: Optional reset controller entity
99 * @dev: CPG/MSSR device 102 * @dev: CPG/MSSR device
100 * @base: CPG/MSSR register block base address 103 * @base: CPG/MSSR register block base address
101 * @mstp_lock: protects writes to SMSTPCR 104 * @rmw_lock: protects RMW register accesses
102 * @clks: Array containing all Core and Module Clocks 105 * @clks: Array containing all Core and Module Clocks
103 * @num_core_clks: Number of Core Clocks in clks[] 106 * @num_core_clks: Number of Core Clocks in clks[]
104 * @num_mod_clks: Number of Module Clocks in clks[] 107 * @num_mod_clks: Number of Module Clocks in clks[]
105 * @last_dt_core_clk: ID of the last Core Clock exported to DT 108 * @last_dt_core_clk: ID of the last Core Clock exported to DT
106 */ 109 */
107struct cpg_mssr_priv { 110struct cpg_mssr_priv {
111#ifdef CONFIG_RESET_CONTROLLER
112 struct reset_controller_dev rcdev;
113#endif
108 struct device *dev; 114 struct device *dev;
109 void __iomem *base; 115 void __iomem *base;
110 spinlock_t mstp_lock; 116 spinlock_t rmw_lock;
111 117
112 struct clk **clks; 118 struct clk **clks;
113 unsigned int num_core_clks; 119 unsigned int num_core_clks;
@@ -144,7 +150,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
144 150
145 dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk, 151 dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk,
146 enable ? "ON" : "OFF"); 152 enable ? "ON" : "OFF");
147 spin_lock_irqsave(&priv->mstp_lock, flags); 153 spin_lock_irqsave(&priv->rmw_lock, flags);
148 154
149 value = readl(priv->base + SMSTPCR(reg)); 155 value = readl(priv->base + SMSTPCR(reg));
150 if (enable) 156 if (enable)
@@ -153,7 +159,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
153 value |= bitmask; 159 value |= bitmask;
154 writel(value, priv->base + SMSTPCR(reg)); 160 writel(value, priv->base + SMSTPCR(reg));
155 161
156 spin_unlock_irqrestore(&priv->mstp_lock, flags); 162 spin_unlock_irqrestore(&priv->rmw_lock, flags);
157 163
158 if (!enable) 164 if (!enable)
159 return 0; 165 return 0;
@@ -346,17 +352,10 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
346 init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; 352 init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
347 for (i = 0; i < info->num_crit_mod_clks; i++) 353 for (i = 0; i < info->num_crit_mod_clks; i++)
348 if (id == info->crit_mod_clks[i]) { 354 if (id == info->crit_mod_clks[i]) {
349#ifdef CLK_ENABLE_HAND_OFF 355 dev_dbg(dev, "MSTP %s setting CLK_IS_CRITICAL\n",
350 dev_dbg(dev, "MSTP %s setting CLK_ENABLE_HAND_OFF\n",
351 mod->name); 356 mod->name);
352 init.flags |= CLK_ENABLE_HAND_OFF; 357 init.flags |= CLK_IS_CRITICAL;
353 break; 358 break;
354#else
355 dev_dbg(dev, "Ignoring MSTP %s to prevent disabling\n",
356 mod->name);
357 kfree(clock);
358 return;
359#endif
360 } 359 }
361 360
362 parent_name = __clk_get_name(parent); 361 parent_name = __clk_get_name(parent);
@@ -501,6 +500,122 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
501 return 0; 500 return 0;
502} 501}
503 502
503#ifdef CONFIG_RESET_CONTROLLER
504
505#define rcdev_to_priv(x) container_of(x, struct cpg_mssr_priv, rcdev)
506
507static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
508 unsigned long id)
509{
510 struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
511 unsigned int reg = id / 32;
512 unsigned int bit = id % 32;
513 u32 bitmask = BIT(bit);
514 unsigned long flags;
515 u32 value;
516
517 dev_dbg(priv->dev, "reset %u%02u\n", reg, bit);
518
519 /* Reset module */
520 spin_lock_irqsave(&priv->rmw_lock, flags);
521 value = readl(priv->base + SRCR(reg));
522 value |= bitmask;
523 writel(value, priv->base + SRCR(reg));
524 spin_unlock_irqrestore(&priv->rmw_lock, flags);
525
526 /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
527 udelay(35);
528
529 /* Release module from reset state */
530 writel(bitmask, priv->base + SRSTCLR(reg));
531
532 return 0;
533}
534
535static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id)
536{
537 struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
538 unsigned int reg = id / 32;
539 unsigned int bit = id % 32;
540 u32 bitmask = BIT(bit);
541 unsigned long flags;
542 u32 value;
543
544 dev_dbg(priv->dev, "assert %u%02u\n", reg, bit);
545
546 spin_lock_irqsave(&priv->rmw_lock, flags);
547 value = readl(priv->base + SRCR(reg));
548 value |= bitmask;
549 writel(value, priv->base + SRCR(reg));
550 spin_unlock_irqrestore(&priv->rmw_lock, flags);
551 return 0;
552}
553
554static int cpg_mssr_deassert(struct reset_controller_dev *rcdev,
555 unsigned long id)
556{
557 struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
558 unsigned int reg = id / 32;
559 unsigned int bit = id % 32;
560 u32 bitmask = BIT(bit);
561
562 dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit);
563
564 writel(bitmask, priv->base + SRSTCLR(reg));
565 return 0;
566}
567
568static int cpg_mssr_status(struct reset_controller_dev *rcdev,
569 unsigned long id)
570{
571 struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
572 unsigned int reg = id / 32;
573 unsigned int bit = id % 32;
574 u32 bitmask = BIT(bit);
575
576 return !!(readl(priv->base + SRCR(reg)) & bitmask);
577}
578
579static const struct reset_control_ops cpg_mssr_reset_ops = {
580 .reset = cpg_mssr_reset,
581 .assert = cpg_mssr_assert,
582 .deassert = cpg_mssr_deassert,
583 .status = cpg_mssr_status,
584};
585
586static int cpg_mssr_reset_xlate(struct reset_controller_dev *rcdev,
587 const struct of_phandle_args *reset_spec)
588{
589 struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
590 unsigned int unpacked = reset_spec->args[0];
591 unsigned int idx = MOD_CLK_PACK(unpacked);
592
593 if (unpacked % 100 > 31 || idx >= rcdev->nr_resets) {
594 dev_err(priv->dev, "Invalid reset index %u\n", unpacked);
595 return -EINVAL;
596 }
597
598 return idx;
599}
600
601static int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv)
602{
603 priv->rcdev.ops = &cpg_mssr_reset_ops;
604 priv->rcdev.of_node = priv->dev->of_node;
605 priv->rcdev.of_reset_n_cells = 1;
606 priv->rcdev.of_xlate = cpg_mssr_reset_xlate;
607 priv->rcdev.nr_resets = priv->num_mod_clks;
608 return devm_reset_controller_register(priv->dev, &priv->rcdev);
609}
610
611#else /* !CONFIG_RESET_CONTROLLER */
612static inline int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv)
613{
614 return 0;
615}
616#endif /* !CONFIG_RESET_CONTROLLER */
617
618
504static const struct of_device_id cpg_mssr_match[] = { 619static const struct of_device_id cpg_mssr_match[] = {
505#ifdef CONFIG_ARCH_R8A7743 620#ifdef CONFIG_ARCH_R8A7743
506 { 621 {
@@ -557,7 +672,7 @@ static int __init cpg_mssr_probe(struct platform_device *pdev)
557 return -ENOMEM; 672 return -ENOMEM;
558 673
559 priv->dev = dev; 674 priv->dev = dev;
560 spin_lock_init(&priv->mstp_lock); 675 spin_lock_init(&priv->rmw_lock);
561 676
562 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 677 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
563 priv->base = devm_ioremap_resource(dev, res); 678 priv->base = devm_ioremap_resource(dev, res);
@@ -598,6 +713,10 @@ static int __init cpg_mssr_probe(struct platform_device *pdev)
598 if (error) 713 if (error)
599 return error; 714 return error;
600 715
716 error = cpg_mssr_reset_controller_register(priv);
717 if (error)
718 return error;
719
601 return 0; 720 return 0;
602} 721}
603 722
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 16e098c36f90..141971488f40 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -8,6 +8,7 @@ obj-y += clk-pll.o
8obj-y += clk-cpu.o 8obj-y += clk-cpu.o
9obj-y += clk-inverter.o 9obj-y += clk-inverter.o
10obj-y += clk-mmc-phase.o 10obj-y += clk-mmc-phase.o
11obj-y += clk-muxgrf.o
11obj-y += clk-ddr.o 12obj-y += clk-ddr.o
12obj-$(CONFIG_RESET_CONTROLLER) += softrst.o 13obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
13 14
@@ -16,5 +17,6 @@ obj-y += clk-rk3036.o
16obj-y += clk-rk3188.o 17obj-y += clk-rk3188.o
17obj-y += clk-rk3228.o 18obj-y += clk-rk3228.o
18obj-y += clk-rk3288.o 19obj-y += clk-rk3288.o
20obj-y += clk-rk3328.o
19obj-y += clk-rk3368.o 21obj-y += clk-rk3368.o
20obj-y += clk-rk3399.o 22obj-y += clk-rk3399.o
diff --git a/drivers/clk/rockchip/clk-muxgrf.c b/drivers/clk/rockchip/clk-muxgrf.c
new file mode 100644
index 000000000000..4f291180a26b
--- /dev/null
+++ b/drivers/clk/rockchip/clk-muxgrf.c
@@ -0,0 +1,102 @@
1/*
2 *
3 * This software is licensed under the terms of the GNU General Public
4 * License version 2, as published by the Free Software Foundation, and
5 * may be copied, distributed, and modified under those terms.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/slab.h>
14#include <linux/bitops.h>
15#include <linux/regmap.h>
16#include <linux/clk.h>
17#include <linux/clk-provider.h>
18#include "clk.h"
19
20struct rockchip_muxgrf_clock {
21 struct clk_hw hw;
22 struct regmap *regmap;
23 u32 reg;
24 u32 shift;
25 u32 width;
26 int flags;
27};
28
29#define to_muxgrf_clock(_hw) container_of(_hw, struct rockchip_muxgrf_clock, hw)
30
31static u8 rockchip_muxgrf_get_parent(struct clk_hw *hw)
32{
33 struct rockchip_muxgrf_clock *mux = to_muxgrf_clock(hw);
34 unsigned int mask = GENMASK(mux->width - 1, 0);
35 unsigned int val;
36
37 regmap_read(mux->regmap, mux->reg, &val);
38
39 val >>= mux->shift;
40 val &= mask;
41
42 return val;
43}
44
45static int rockchip_muxgrf_set_parent(struct clk_hw *hw, u8 index)
46{
47 struct rockchip_muxgrf_clock *mux = to_muxgrf_clock(hw);
48 unsigned int mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
49 unsigned int val;
50
51 val = index;
52 val <<= mux->shift;
53
54 if (mux->flags & CLK_MUX_HIWORD_MASK)
55 return regmap_write(mux->regmap, mux->reg, val | (mask << 16));
56 else
57 return regmap_update_bits(mux->regmap, mux->reg, mask, val);
58}
59
60static const struct clk_ops rockchip_muxgrf_clk_ops = {
61 .get_parent = rockchip_muxgrf_get_parent,
62 .set_parent = rockchip_muxgrf_set_parent,
63 .determine_rate = __clk_mux_determine_rate,
64};
65
66struct clk *rockchip_clk_register_muxgrf(const char *name,
67 const char *const *parent_names, u8 num_parents,
68 int flags, struct regmap *regmap, int reg,
69 int shift, int width, int mux_flags)
70{
71 struct rockchip_muxgrf_clock *muxgrf_clock;
72 struct clk_init_data init;
73 struct clk *clk;
74
75 if (IS_ERR(regmap)) {
76 pr_err("%s: regmap not available\n", __func__);
77 return ERR_PTR(-ENOTSUPP);
78 }
79
80 muxgrf_clock = kmalloc(sizeof(*muxgrf_clock), GFP_KERNEL);
81 if (!muxgrf_clock)
82 return ERR_PTR(-ENOMEM);
83
84 init.name = name;
85 init.flags = flags;
86 init.num_parents = num_parents;
87 init.parent_names = parent_names;
88 init.ops = &rockchip_muxgrf_clk_ops;
89
90 muxgrf_clock->hw.init = &init;
91 muxgrf_clock->regmap = regmap;
92 muxgrf_clock->reg = reg;
93 muxgrf_clock->shift = shift;
94 muxgrf_clock->width = width;
95 muxgrf_clock->flags = mux_flags;
96
97 clk = clk_register(NULL, &muxgrf_clock->hw);
98 if (IS_ERR(clk))
99 kfree(muxgrf_clock);
100
101 return clk;
102}
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 6ed605776abd..eec51893a7e6 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -29,6 +29,7 @@
29#define PLL_MODE_SLOW 0x0 29#define PLL_MODE_SLOW 0x0
30#define PLL_MODE_NORM 0x1 30#define PLL_MODE_NORM 0x1
31#define PLL_MODE_DEEP 0x2 31#define PLL_MODE_DEEP 0x2
32#define PLL_RK3328_MODE_MASK 0x1
32 33
33struct rockchip_clk_pll { 34struct rockchip_clk_pll {
34 struct clk_hw hw; 35 struct clk_hw hw;
@@ -848,7 +849,8 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
848 struct clk *pll_clk, *mux_clk; 849 struct clk *pll_clk, *mux_clk;
849 char pll_name[20]; 850 char pll_name[20];
850 851
851 if (num_parents != 2) { 852 if ((pll_type != pll_rk3328 && num_parents != 2) ||
853 (pll_type == pll_rk3328 && num_parents != 1)) {
852 pr_err("%s: needs two parent clocks\n", __func__); 854 pr_err("%s: needs two parent clocks\n", __func__);
853 return ERR_PTR(-EINVAL); 855 return ERR_PTR(-EINVAL);
854 } 856 }
@@ -865,13 +867,17 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
865 pll_mux = &pll->pll_mux; 867 pll_mux = &pll->pll_mux;
866 pll_mux->reg = ctx->reg_base + mode_offset; 868 pll_mux->reg = ctx->reg_base + mode_offset;
867 pll_mux->shift = mode_shift; 869 pll_mux->shift = mode_shift;
868 pll_mux->mask = PLL_MODE_MASK; 870 if (pll_type == pll_rk3328)
871 pll_mux->mask = PLL_RK3328_MODE_MASK;
872 else
873 pll_mux->mask = PLL_MODE_MASK;
869 pll_mux->flags = 0; 874 pll_mux->flags = 0;
870 pll_mux->lock = &ctx->lock; 875 pll_mux->lock = &ctx->lock;
871 pll_mux->hw.init = &init; 876 pll_mux->hw.init = &init;
872 877
873 if (pll_type == pll_rk3036 || 878 if (pll_type == pll_rk3036 ||
874 pll_type == pll_rk3066 || 879 pll_type == pll_rk3066 ||
880 pll_type == pll_rk3328 ||
875 pll_type == pll_rk3399) 881 pll_type == pll_rk3399)
876 pll_mux->flags |= CLK_MUX_HIWORD_MASK; 882 pll_mux->flags |= CLK_MUX_HIWORD_MASK;
877 883
@@ -884,7 +890,10 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
884 init.flags = CLK_SET_RATE_PARENT; 890 init.flags = CLK_SET_RATE_PARENT;
885 init.ops = pll->pll_mux_ops; 891 init.ops = pll->pll_mux_ops;
886 init.parent_names = pll_parents; 892 init.parent_names = pll_parents;
887 init.num_parents = ARRAY_SIZE(pll_parents); 893 if (pll_type == pll_rk3328)
894 init.num_parents = 2;
895 else
896 init.num_parents = ARRAY_SIZE(pll_parents);
888 897
889 mux_clk = clk_register(NULL, &pll_mux->hw); 898 mux_clk = clk_register(NULL, &pll_mux->hw);
890 if (IS_ERR(mux_clk)) 899 if (IS_ERR(mux_clk))
@@ -918,6 +927,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
918 927
919 switch (pll_type) { 928 switch (pll_type) {
920 case pll_rk3036: 929 case pll_rk3036:
930 case pll_rk3328:
921 if (!pll->rate_table || IS_ERR(ctx->grf)) 931 if (!pll->rate_table || IS_ERR(ctx->grf))
922 init.ops = &rockchip_rk3036_pll_clk_norate_ops; 932 init.ops = &rockchip_rk3036_pll_clk_norate_ops;
923 else 933 else
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index 062ef4960244..00ad0e5f8d66 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -507,8 +507,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
507 GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), 507 GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
508 GATE(PCLK_EFUSE, "pclk_efuse", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 2, GFLAGS), 508 GATE(PCLK_EFUSE, "pclk_efuse", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 2, GFLAGS),
509 GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 3, GFLAGS), 509 GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 3, GFLAGS),
510 GATE(0, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS), 510 GATE(PCLK_DDRUPCTL, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS),
511 GATE(0, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), 511 GATE(PCLK_PUBL, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS),
512 GATE(0, "pclk_dbg", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS), 512 GATE(0, "pclk_dbg", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS),
513 GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), 513 GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS),
514 GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 5, GFLAGS), 514 GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 5, GFLAGS),
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 39af05a589b3..68ba7d4105e7 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -198,6 +198,7 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" };
198PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; 198PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" };
199PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; 199PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" };
200 200
201PNAME(mux_aclk_vcodec_pre_p) = { "aclk_vepu", "aclk_vdpu" };
201PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m", 202PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m",
202 "sclk_otgphy0_480m" }; 203 "sclk_otgphy0_480m" };
203PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; 204PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" };
@@ -398,14 +399,12 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
398 COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0, 399 COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0,
399 RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, 400 RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
400 RK3288_CLKGATE_CON(3), 11, GFLAGS), 401 RK3288_CLKGATE_CON(3), 11, GFLAGS),
401 /* 402 MUXGRF(0, "aclk_vcodec_pre", mux_aclk_vcodec_pre_p, 0,
402 * We use aclk_vdpu by default GRF_SOC_CON0[7] setting in system, 403 RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS),
403 * so we ignore the mux and make clocks nodes as following, 404 GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0,
404 */
405 GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vdpu", 0,
406 RK3288_CLKGATE_CON(9), 0, GFLAGS), 405 RK3288_CLKGATE_CON(9), 0, GFLAGS),
407 406
408 FACTOR_GATE(0, "hclk_vcodec_pre", "aclk_vdpu", 0, 1, 4, 407 FACTOR_GATE(0, "hclk_vcodec_pre", "aclk_vcodec_pre", 0, 1, 4,
409 RK3288_CLKGATE_CON(3), 10, GFLAGS), 408 RK3288_CLKGATE_CON(3), 10, GFLAGS),
410 409
411 GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, 410 GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0,
@@ -469,7 +468,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
469 COMPOSITE_NODIV(0, "vip_src", mux_pll_src_cpll_gpll_p, 0, 468 COMPOSITE_NODIV(0, "vip_src", mux_pll_src_cpll_gpll_p, 0,
470 RK3288_CLKSEL_CON(26), 8, 1, MFLAGS, 469 RK3288_CLKSEL_CON(26), 8, 1, MFLAGS,
471 RK3288_CLKGATE_CON(3), 7, GFLAGS), 470 RK3288_CLKGATE_CON(3), 7, GFLAGS),
472 COMPOSITE_NOGATE(0, "sclk_vip_out", mux_vip_out_p, 0, 471 COMPOSITE_NOGATE(SCLK_VIP_OUT, "sclk_vip_out", mux_vip_out_p, 0,
473 RK3288_CLKSEL_CON(26), 15, 1, MFLAGS, 9, 5, DFLAGS), 472 RK3288_CLKSEL_CON(26), 15, 1, MFLAGS, 9, 5, DFLAGS),
474 473
475 DIV(0, "pclk_pd_alive", "gpll", 0, 474 DIV(0, "pclk_pd_alive", "gpll", 0,
@@ -690,7 +689,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
690 /* aclk_peri gates */ 689 /* aclk_peri gates */
691 GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 2, GFLAGS), 690 GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 2, GFLAGS),
692 GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS), 691 GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS),
693 GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 11, GFLAGS), 692 GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK3288_CLKGATE_CON(7), 11, GFLAGS),
694 GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(8), 12, GFLAGS), 693 GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(8), 12, GFLAGS),
695 GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS), 694 GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS),
696 GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS), 695 GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS),
@@ -753,12 +752,12 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
753 GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS), 752 GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS),
754 GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS), 753 GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS),
755 GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS), 754 GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS),
756 GATE(0, "pclk_alive_niu", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 12, GFLAGS), 755 GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS),
757 756
758 /* pclk_pd_pmu gates */ 757 /* pclk_pd_pmu gates */
759 GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS), 758 GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS),
760 GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS), 759 GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS),
761 GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 2, GFLAGS), 760 GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 2, GFLAGS),
762 GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 3, GFLAGS), 761 GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 3, GFLAGS),
763 GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS), 762 GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS),
764 763
@@ -767,7 +766,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
767 GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS), 766 GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS),
768 GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS), 767 GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS),
769 GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 9, GFLAGS), 768 GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 9, GFLAGS),
770 GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 10, GFLAGS), 769 GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS),
771 GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS), 770 GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS),
772 GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS), 771 GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS),
773 GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS), 772 GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS),
@@ -783,17 +782,17 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
783 /* aclk_vio0 gates */ 782 /* aclk_vio0 gates */
784 GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS), 783 GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS),
785 GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS), 784 GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS),
786 GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 11, GFLAGS), 785 GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS),
787 GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS), 786 GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS),
788 787
789 /* aclk_vio1 gates */ 788 /* aclk_vio1 gates */
790 GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS), 789 GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS),
791 GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS), 790 GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS),
792 GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 12, GFLAGS), 791 GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS),
793 792
794 /* aclk_rga_pre gates */ 793 /* aclk_rga_pre gates */
795 GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS), 794 GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS),
796 GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 13, GFLAGS), 795 GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS),
797 796
798 /* 797 /*
799 * Other ungrouped clocks. 798 * Other ungrouped clocks.
@@ -801,15 +800,22 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
801 800
802 GATE(0, "pclk_vip_in", "ext_vip", 0, RK3288_CLKGATE_CON(16), 0, GFLAGS), 801 GATE(0, "pclk_vip_in", "ext_vip", 0, RK3288_CLKGATE_CON(16), 0, GFLAGS),
803 INVERTER(0, "pclk_vip", "pclk_vip_in", RK3288_CLKSEL_CON(29), 4, IFLAGS), 802 INVERTER(0, "pclk_vip", "pclk_vip_in", RK3288_CLKSEL_CON(29), 4, IFLAGS),
804 GATE(0, "pclk_isp_in", "ext_isp", 0, RK3288_CLKGATE_CON(16), 3, GFLAGS), 803 GATE(PCLK_ISP_IN, "pclk_isp_in", "ext_isp", 0, RK3288_CLKGATE_CON(16), 3, GFLAGS),
805 INVERTER(0, "pclk_isp", "pclk_isp_in", RK3288_CLKSEL_CON(29), 3, IFLAGS), 804 INVERTER(0, "pclk_isp", "pclk_isp_in", RK3288_CLKSEL_CON(29), 3, IFLAGS),
806}; 805};
807 806
808static const char *const rk3288_critical_clocks[] __initconst = { 807static const char *const rk3288_critical_clocks[] __initconst = {
809 "aclk_cpu", 808 "aclk_cpu",
810 "aclk_peri", 809 "aclk_peri",
810 "aclk_peri_niu",
811 "aclk_vio0_niu",
812 "aclk_vio1_niu",
813 "aclk_rga_niu",
811 "hclk_peri", 814 "hclk_peri",
815 "hclk_vio_niu",
816 "pclk_alive_niu",
812 "pclk_pd_pmu", 817 "pclk_pd_pmu",
818 "pclk_pmu_niu",
813}; 819};
814 820
815static void __iomem *rk3288_cru_base; 821static void __iomem *rk3288_cru_base;
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
new file mode 100644
index 000000000000..1e384e143504
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3328.c
@@ -0,0 +1,895 @@
1/*
2 * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
3 * Author: Elaine <zhangqing@rock-chips.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/clk-provider.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <linux/syscore_ops.h>
20#include <dt-bindings/clock/rk3328-cru.h>
21#include "clk.h"
22
23#define RK3328_GRF_SOC_STATUS0 0x480
24#define RK3328_GRF_MAC_CON1 0x904
25#define RK3328_GRF_MAC_CON2 0x908
26
27enum rk3328_plls {
28 apll, dpll, cpll, gpll, npll,
29};
30
31static struct rockchip_pll_rate_table rk3328_pll_rates[] = {
32 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
33 RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
34 RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
35 RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
36 RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
37 RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
38 RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
39 RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
40 RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
41 RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
42 RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
43 RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
44 RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
45 RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
46 RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
47 RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
48 RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
49 RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
50 RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
51 RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
52 RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
53 RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
54 RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
55 RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0),
56 RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
57 RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0),
58 RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
59 RK3036_PLL_RATE(900000000, 4, 300, 2, 1, 1, 0),
60 RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0),
61 RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0),
62 RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0),
63 RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
64 RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0),
65 RK3036_PLL_RATE(700000000, 6, 350, 2, 1, 1, 0),
66 RK3036_PLL_RATE(696000000, 1, 58, 2, 1, 1, 0),
67 RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
68 RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
69 RK3036_PLL_RATE(504000000, 1, 63, 3, 1, 1, 0),
70 RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0),
71 RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
72 RK3036_PLL_RATE(312000000, 1, 52, 2, 2, 1, 0),
73 RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
74 RK3036_PLL_RATE(96000000, 1, 64, 4, 4, 1, 0),
75 { /* sentinel */ },
76};
77
78static struct rockchip_pll_rate_table rk3328_pll_frac_rates[] = {
79 /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
80 RK3036_PLL_RATE(1016064000, 3, 127, 1, 1, 0, 134217),
81 /* vco = 1016064000 */
82 RK3036_PLL_RATE(983040000, 24, 983, 1, 1, 0, 671088),
83 /* vco = 983040000 */
84 RK3036_PLL_RATE(491520000, 24, 983, 2, 1, 0, 671088),
85 /* vco = 983040000 */
86 RK3036_PLL_RATE(61440000, 6, 215, 7, 2, 0, 671088),
87 /* vco = 860156000 */
88 RK3036_PLL_RATE(56448000, 12, 451, 4, 4, 0, 9797894),
89 /* vco = 903168000 */
90 RK3036_PLL_RATE(40960000, 12, 409, 4, 5, 0, 10066329),
91 /* vco = 819200000 */
92 { /* sentinel */ },
93};
94
95#define RK3328_DIV_ACLKM_MASK 0x7
96#define RK3328_DIV_ACLKM_SHIFT 4
97#define RK3328_DIV_PCLK_DBG_MASK 0xf
98#define RK3328_DIV_PCLK_DBG_SHIFT 0
99
100#define RK3328_CLKSEL1(_aclk_core, _pclk_dbg) \
101{ \
102 .reg = RK3328_CLKSEL_CON(1), \
103 .val = HIWORD_UPDATE(_aclk_core, RK3328_DIV_ACLKM_MASK, \
104 RK3328_DIV_ACLKM_SHIFT) | \
105 HIWORD_UPDATE(_pclk_dbg, RK3328_DIV_PCLK_DBG_MASK, \
106 RK3328_DIV_PCLK_DBG_SHIFT), \
107}
108
109#define RK3328_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg) \
110{ \
111 .prate = _prate, \
112 .divs = { \
113 RK3328_CLKSEL1(_aclk_core, _pclk_dbg), \
114 }, \
115}
116
117static struct rockchip_cpuclk_rate_table rk3328_cpuclk_rates[] __initdata = {
118 RK3328_CPUCLK_RATE(1800000000, 1, 7),
119 RK3328_CPUCLK_RATE(1704000000, 1, 7),
120 RK3328_CPUCLK_RATE(1608000000, 1, 7),
121 RK3328_CPUCLK_RATE(1512000000, 1, 7),
122 RK3328_CPUCLK_RATE(1488000000, 1, 5),
123 RK3328_CPUCLK_RATE(1416000000, 1, 5),
124 RK3328_CPUCLK_RATE(1392000000, 1, 5),
125 RK3328_CPUCLK_RATE(1296000000, 1, 5),
126 RK3328_CPUCLK_RATE(1200000000, 1, 5),
127 RK3328_CPUCLK_RATE(1104000000, 1, 5),
128 RK3328_CPUCLK_RATE(1008000000, 1, 5),
129 RK3328_CPUCLK_RATE(912000000, 1, 5),
130 RK3328_CPUCLK_RATE(816000000, 1, 3),
131 RK3328_CPUCLK_RATE(696000000, 1, 3),
132 RK3328_CPUCLK_RATE(600000000, 1, 3),
133 RK3328_CPUCLK_RATE(408000000, 1, 1),
134 RK3328_CPUCLK_RATE(312000000, 1, 1),
135 RK3328_CPUCLK_RATE(216000000, 1, 1),
136 RK3328_CPUCLK_RATE(96000000, 1, 1),
137};
138
139static const struct rockchip_cpuclk_reg_data rk3328_cpuclk_data = {
140 .core_reg = RK3328_CLKSEL_CON(0),
141 .div_core_shift = 0,
142 .div_core_mask = 0x1f,
143 .mux_core_alt = 1,
144 .mux_core_main = 3,
145 .mux_core_shift = 6,
146 .mux_core_mask = 0x3,
147};
148
149PNAME(mux_pll_p) = { "xin24m" };
150
151PNAME(mux_2plls_p) = { "cpll", "gpll" };
152PNAME(mux_gpll_cpll_p) = { "gpll", "cpll" };
153PNAME(mux_cpll_gpll_apll_p) = { "cpll", "gpll", "apll" };
154PNAME(mux_2plls_xin24m_p) = { "cpll", "gpll", "xin24m" };
155PNAME(mux_2plls_hdmiphy_p) = { "cpll", "gpll",
156 "dummy_hdmiphy" };
157PNAME(mux_4plls_p) = { "cpll", "gpll",
158 "dummy_hdmiphy",
159 "usb480m" };
160PNAME(mux_2plls_u480m_p) = { "cpll", "gpll",
161 "usb480m" };
162PNAME(mux_2plls_24m_u480m_p) = { "cpll", "gpll",
163 "xin24m", "usb480m" };
164
165PNAME(mux_ddrphy_p) = { "dpll", "apll", "cpll" };
166PNAME(mux_armclk_p) = { "apll_core",
167 "gpll_core",
168 "dpll_core",
169 "npll_core"};
170PNAME(mux_hdmiphy_p) = { "hdmi_phy", "xin24m" };
171PNAME(mux_usb480m_p) = { "usb480m_phy",
172 "xin24m" };
173
174PNAME(mux_i2s0_p) = { "clk_i2s0_div",
175 "clk_i2s0_frac",
176 "xin12m",
177 "xin12m" };
178PNAME(mux_i2s1_p) = { "clk_i2s1_div",
179 "clk_i2s1_frac",
180 "clkin_i2s1",
181 "xin12m" };
182PNAME(mux_i2s2_p) = { "clk_i2s2_div",
183 "clk_i2s2_frac",
184 "clkin_i2s2",
185 "xin12m" };
186PNAME(mux_i2s1out_p) = { "clk_i2s1", "xin12m"};
187PNAME(mux_i2s2out_p) = { "clk_i2s2", "xin12m" };
188PNAME(mux_spdif_p) = { "clk_spdif_div",
189 "clk_spdif_frac",
190 "xin12m",
191 "xin12m" };
192PNAME(mux_uart0_p) = { "clk_uart0_div",
193 "clk_uart0_frac",
194 "xin24m" };
195PNAME(mux_uart1_p) = { "clk_uart1_div",
196 "clk_uart1_frac",
197 "xin24m" };
198PNAME(mux_uart2_p) = { "clk_uart2_div",
199 "clk_uart2_frac",
200 "xin24m" };
201
202PNAME(mux_sclk_cif_p) = { "clk_cif_src",
203 "xin24m" };
204PNAME(mux_dclk_lcdc_p) = { "hdmiphy",
205 "dclk_lcdc_src" };
206PNAME(mux_aclk_peri_pre_p) = { "cpll_peri",
207 "gpll_peri",
208 "hdmiphy_peri" };
209PNAME(mux_ref_usb3otg_src_p) = { "xin24m",
210 "clk_usb3otg_ref" };
211PNAME(mux_xin24m_32k_p) = { "xin24m",
212 "clk_rtc32k" };
213PNAME(mux_mac2io_src_p) = { "clk_mac2io_src",
214 "gmac_clkin" };
215PNAME(mux_mac2phy_src_p) = { "clk_mac2phy_src",
216 "phy_50m_out" };
217
218static struct rockchip_pll_clock rk3328_pll_clks[] __initdata = {
219 [apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p,
220 0, RK3328_PLL_CON(0),
221 RK3328_MODE_CON, 0, 4, 0, rk3328_pll_frac_rates),
222 [dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p,
223 0, RK3328_PLL_CON(8),
224 RK3328_MODE_CON, 4, 3, 0, NULL),
225 [cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p,
226 0, RK3328_PLL_CON(16),
227 RK3328_MODE_CON, 8, 2, 0, rk3328_pll_rates),
228 [gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
229 0, RK3328_PLL_CON(24),
230 RK3328_MODE_CON, 12, 1, 0, rk3328_pll_frac_rates),
231 [npll] = PLL(pll_rk3328, PLL_NPLL, "npll", mux_pll_p,
232 0, RK3328_PLL_CON(40),
233 RK3328_MODE_CON, 1, 0, 0, rk3328_pll_rates),
234};
235
236#define MFLAGS CLK_MUX_HIWORD_MASK
237#define DFLAGS CLK_DIVIDER_HIWORD_MASK
238#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
239
240static struct rockchip_clk_branch rk3328_i2s0_fracmux __initdata =
241 MUX(0, "i2s0_pre", mux_i2s0_p, CLK_SET_RATE_PARENT,
242 RK3328_CLKSEL_CON(6), 8, 2, MFLAGS);
243
244static struct rockchip_clk_branch rk3328_i2s1_fracmux __initdata =
245 MUX(0, "i2s1_pre", mux_i2s1_p, CLK_SET_RATE_PARENT,
246 RK3328_CLKSEL_CON(8), 8, 2, MFLAGS);
247
248static struct rockchip_clk_branch rk3328_i2s2_fracmux __initdata =
249 MUX(0, "i2s2_pre", mux_i2s2_p, CLK_SET_RATE_PARENT,
250 RK3328_CLKSEL_CON(10), 8, 2, MFLAGS);
251
252static struct rockchip_clk_branch rk3328_spdif_fracmux __initdata =
253 MUX(SCLK_SPDIF, "sclk_spdif", mux_spdif_p, CLK_SET_RATE_PARENT,
254 RK3328_CLKSEL_CON(12), 8, 2, MFLAGS);
255
256static struct rockchip_clk_branch rk3328_uart0_fracmux __initdata =
257 MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
258 RK3328_CLKSEL_CON(14), 8, 2, MFLAGS);
259
260static struct rockchip_clk_branch rk3328_uart1_fracmux __initdata =
261 MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
262 RK3328_CLKSEL_CON(16), 8, 2, MFLAGS);
263
264static struct rockchip_clk_branch rk3328_uart2_fracmux __initdata =
265 MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
266 RK3328_CLKSEL_CON(18), 8, 2, MFLAGS);
267
268static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
269 /*
270 * Clock-Architecture Diagram 1
271 */
272
273 DIV(0, "clk_24m", "xin24m", CLK_IGNORE_UNUSED,
274 RK3328_CLKSEL_CON(2), 8, 5, DFLAGS),
275 COMPOSITE(SCLK_RTC32K, "clk_rtc32k", mux_2plls_xin24m_p, 0,
276 RK3328_CLKSEL_CON(38), 14, 2, MFLAGS, 0, 14, DFLAGS,
277 RK3328_CLKGATE_CON(0), 11, GFLAGS),
278
279 /* PD_MISC */
280 MUX(HDMIPHY, "hdmiphy", mux_hdmiphy_p, CLK_SET_RATE_PARENT,
281 RK3328_MISC_CON, 13, 1, MFLAGS),
282 MUX(USB480M, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT,
283 RK3328_MISC_CON, 15, 1, MFLAGS),
284
285 /*
286 * Clock-Architecture Diagram 2
287 */
288
289 /* PD_CORE */
290 GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED,
291 RK3328_CLKGATE_CON(0), 0, GFLAGS),
292 GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED,
293 RK3328_CLKGATE_CON(0), 2, GFLAGS),
294 GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED,
295 RK3328_CLKGATE_CON(0), 1, GFLAGS),
296 GATE(0, "npll_core", "npll", CLK_IGNORE_UNUSED,
297 RK3328_CLKGATE_CON(0), 12, GFLAGS),
298 COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED,
299 RK3328_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
300 RK3328_CLKGATE_CON(7), 0, GFLAGS),
301 COMPOSITE_NOMUX(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED,
302 RK3328_CLKSEL_CON(1), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
303 RK3328_CLKGATE_CON(7), 1, GFLAGS),
304 GATE(0, "aclk_core_niu", "aclk_core", CLK_IGNORE_UNUSED,
305 RK3328_CLKGATE_CON(13), 0, GFLAGS),
306 GATE(0, "aclk_gic400", "aclk_core", CLK_IGNORE_UNUSED,
307 RK3328_CLKGATE_CON(13), 1, GFLAGS),
308
309 GATE(0, "clk_jtag", "jtag_clkin", CLK_IGNORE_UNUSED,
310 RK3328_CLKGATE_CON(7), 2, GFLAGS),
311
312 /* PD_GPU */
313 COMPOSITE(0, "aclk_gpu_pre", mux_4plls_p, 0,
314 RK3328_CLKSEL_CON(44), 6, 2, MFLAGS, 0, 5, DFLAGS,
315 RK3328_CLKGATE_CON(6), 6, GFLAGS),
316 GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", CLK_SET_RATE_PARENT,
317 RK3328_CLKGATE_CON(14), 0, GFLAGS),
318 GATE(0, "aclk_gpu_niu", "aclk_gpu_pre", CLK_IGNORE_UNUSED,
319 RK3328_CLKGATE_CON(14), 1, GFLAGS),
320
321 /* PD_DDR */
322 COMPOSITE(0, "clk_ddr", mux_ddrphy_p, CLK_IGNORE_UNUSED,
323 RK3328_CLKSEL_CON(3), 8, 2, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
324 RK3328_CLKGATE_CON(0), 4, GFLAGS),
325 GATE(0, "clk_ddrmsch", "clk_ddr", CLK_IGNORE_UNUSED,
326 RK3328_CLKGATE_CON(18), 6, GFLAGS),
327 GATE(0, "clk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED,
328 RK3328_CLKGATE_CON(18), 5, GFLAGS),
329 GATE(0, "aclk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED,
330 RK3328_CLKGATE_CON(18), 4, GFLAGS),
331 GATE(0, "clk_ddrmon", "xin24m", CLK_IGNORE_UNUSED,
332 RK3328_CLKGATE_CON(0), 6, GFLAGS),
333
334 COMPOSITE(PCLK_DDR, "pclk_ddr", mux_2plls_hdmiphy_p, 0,
335 RK3328_CLKSEL_CON(4), 13, 2, MFLAGS, 8, 3, DFLAGS,
336 RK3328_CLKGATE_CON(7), 4, GFLAGS),
337 GATE(0, "pclk_ddrupctl", "pclk_ddr", CLK_IGNORE_UNUSED,
338 RK3328_CLKGATE_CON(18), 1, GFLAGS),
339 GATE(0, "pclk_ddr_msch", "pclk_ddr", CLK_IGNORE_UNUSED,
340 RK3328_CLKGATE_CON(18), 2, GFLAGS),
341 GATE(0, "pclk_ddr_mon", "pclk_ddr", CLK_IGNORE_UNUSED,
342 RK3328_CLKGATE_CON(18), 3, GFLAGS),
343 GATE(0, "pclk_ddrstdby", "pclk_ddr", CLK_IGNORE_UNUSED,
344 RK3328_CLKGATE_CON(18), 7, GFLAGS),
345 GATE(0, "pclk_ddr_grf", "pclk_ddr", CLK_IGNORE_UNUSED,
346 RK3328_CLKGATE_CON(18), 9, GFLAGS),
347
348 /*
349 * Clock-Architecture Diagram 3
350 */
351
352 /* PD_BUS */
353 COMPOSITE(ACLK_BUS_PRE, "aclk_bus_pre", mux_2plls_hdmiphy_p, 0,
354 RK3328_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS,
355 RK3328_CLKGATE_CON(8), 0, GFLAGS),
356 COMPOSITE_NOMUX(HCLK_BUS_PRE, "hclk_bus_pre", "aclk_bus_pre", 0,
357 RK3328_CLKSEL_CON(1), 8, 2, DFLAGS,
358 RK3328_CLKGATE_CON(8), 1, GFLAGS),
359 COMPOSITE_NOMUX(PCLK_BUS_PRE, "pclk_bus_pre", "aclk_bus_pre", 0,
360 RK3328_CLKSEL_CON(1), 12, 3, DFLAGS,
361 RK3328_CLKGATE_CON(8), 2, GFLAGS),
362 GATE(0, "pclk_bus", "pclk_bus_pre", 0,
363 RK3328_CLKGATE_CON(8), 3, GFLAGS),
364 GATE(0, "pclk_phy_pre", "pclk_bus_pre", 0,
365 RK3328_CLKGATE_CON(8), 4, GFLAGS),
366
367 COMPOSITE(SCLK_TSP, "clk_tsp", mux_2plls_p, 0,
368 RK3328_CLKSEL_CON(21), 15, 1, MFLAGS, 8, 5, DFLAGS,
369 RK3328_CLKGATE_CON(2), 5, GFLAGS),
370 GATE(0, "clk_hsadc_tsp", "ext_gpio3a2", 0,
371 RK3328_CLKGATE_CON(17), 13, GFLAGS),
372
373 /* PD_I2S */
374 COMPOSITE(0, "clk_i2s0_div", mux_2plls_p, 0,
375 RK3328_CLKSEL_CON(6), 15, 1, MFLAGS, 0, 7, DFLAGS,
376 RK3328_CLKGATE_CON(1), 1, GFLAGS),
377 COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", CLK_SET_RATE_PARENT,
378 RK3328_CLKSEL_CON(7), 0,
379 RK3328_CLKGATE_CON(1), 2, GFLAGS,
380 &rk3328_i2s0_fracmux),
381 GATE(SCLK_I2S0, "clk_i2s0", "i2s0_pre", CLK_SET_RATE_PARENT,
382 RK3328_CLKGATE_CON(1), 3, GFLAGS),
383
384 COMPOSITE(0, "clk_i2s1_div", mux_2plls_p, 0,
385 RK3328_CLKSEL_CON(8), 15, 1, MFLAGS, 0, 7, DFLAGS,
386 RK3328_CLKGATE_CON(1), 4, GFLAGS),
387 COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", CLK_SET_RATE_PARENT,
388 RK3328_CLKSEL_CON(9), 0,
389 RK3328_CLKGATE_CON(1), 5, GFLAGS,
390 &rk3328_i2s1_fracmux),
391 GATE(SCLK_I2S1, "clk_i2s1", "i2s1_pre", CLK_SET_RATE_PARENT,
392 RK3328_CLKGATE_CON(0), 6, GFLAGS),
393 COMPOSITE_NODIV(SCLK_I2S1_OUT, "i2s1_out", mux_i2s1out_p, 0,
394 RK3328_CLKSEL_CON(8), 12, 1, MFLAGS,
395 RK3328_CLKGATE_CON(1), 7, GFLAGS),
396
397 COMPOSITE(0, "clk_i2s2_div", mux_2plls_p, 0,
398 RK3328_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 7, DFLAGS,
399 RK3328_CLKGATE_CON(1), 8, GFLAGS),
400 COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", CLK_SET_RATE_PARENT,
401 RK3328_CLKSEL_CON(11), 0,
402 RK3328_CLKGATE_CON(1), 9, GFLAGS,
403 &rk3328_i2s2_fracmux),
404 GATE(SCLK_I2S2, "clk_i2s2", "i2s2_pre", CLK_SET_RATE_PARENT,
405 RK3328_CLKGATE_CON(1), 10, GFLAGS),
406 COMPOSITE_NODIV(SCLK_I2S2_OUT, "i2s2_out", mux_i2s2out_p, 0,
407 RK3328_CLKSEL_CON(10), 12, 1, MFLAGS,
408 RK3328_CLKGATE_CON(1), 11, GFLAGS),
409
410 COMPOSITE(0, "clk_spdif_div", mux_2plls_p, 0,
411 RK3328_CLKSEL_CON(12), 15, 1, MFLAGS, 0, 7, DFLAGS,
412 RK3328_CLKGATE_CON(1), 12, GFLAGS),
413 COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", CLK_SET_RATE_PARENT,
414 RK3328_CLKSEL_CON(13), 0,
415 RK3328_CLKGATE_CON(1), 13, GFLAGS,
416 &rk3328_spdif_fracmux),
417
418 /* PD_UART */
419 COMPOSITE(0, "clk_uart0_div", mux_2plls_u480m_p, 0,
420 RK3328_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS,
421 RK3328_CLKGATE_CON(1), 14, GFLAGS),
422 COMPOSITE(0, "clk_uart1_div", mux_2plls_u480m_p, 0,
423 RK3328_CLKSEL_CON(16), 12, 2, MFLAGS, 0, 7, DFLAGS,
424 RK3328_CLKGATE_CON(2), 0, GFLAGS),
425 COMPOSITE(0, "clk_uart2_div", mux_2plls_u480m_p, 0,
426 RK3328_CLKSEL_CON(18), 12, 2, MFLAGS, 0, 7, DFLAGS,
427 RK3328_CLKGATE_CON(2), 2, GFLAGS),
428 COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", CLK_SET_RATE_PARENT,
429 RK3328_CLKSEL_CON(15), 0,
430 RK3328_CLKGATE_CON(1), 15, GFLAGS,
431 &rk3328_uart0_fracmux),
432 COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", CLK_SET_RATE_PARENT,
433 RK3328_CLKSEL_CON(17), 0,
434 RK3328_CLKGATE_CON(2), 1, GFLAGS,
435 &rk3328_uart1_fracmux),
436 COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", CLK_SET_RATE_PARENT,
437 RK3328_CLKSEL_CON(19), 0,
438 RK3328_CLKGATE_CON(2), 3, GFLAGS,
439 &rk3328_uart2_fracmux),
440
441 /*
442 * Clock-Architecture Diagram 4
443 */
444
445 COMPOSITE(SCLK_I2C0, "clk_i2c0", mux_2plls_p, 0,
446 RK3328_CLKSEL_CON(34), 7, 1, MFLAGS, 0, 7, DFLAGS,
447 RK3328_CLKGATE_CON(2), 9, GFLAGS),
448 COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_2plls_p, 0,
449 RK3328_CLKSEL_CON(34), 15, 1, MFLAGS, 8, 7, DFLAGS,
450 RK3328_CLKGATE_CON(2), 10, GFLAGS),
451 COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_2plls_p, 0,
452 RK3328_CLKSEL_CON(35), 7, 1, MFLAGS, 0, 7, DFLAGS,
453 RK3328_CLKGATE_CON(2), 11, GFLAGS),
454 COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_2plls_p, 0,
455 RK3328_CLKSEL_CON(35), 15, 1, MFLAGS, 8, 7, DFLAGS,
456 RK3328_CLKGATE_CON(2), 12, GFLAGS),
457 COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_2plls_p, 0,
458 RK3328_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 7, DFLAGS,
459 RK3328_CLKGATE_CON(2), 4, GFLAGS),
460 COMPOSITE_NOMUX(SCLK_TSADC, "clk_tsadc", "clk_24m", 0,
461 RK3328_CLKSEL_CON(22), 0, 10, DFLAGS,
462 RK3328_CLKGATE_CON(2), 6, GFLAGS),
463 COMPOSITE_NOMUX(SCLK_SARADC, "clk_saradc", "clk_24m", 0,
464 RK3328_CLKSEL_CON(23), 0, 10, DFLAGS,
465 RK3328_CLKGATE_CON(2), 14, GFLAGS),
466 COMPOSITE(SCLK_SPI, "clk_spi", mux_2plls_p, 0,
467 RK3328_CLKSEL_CON(24), 7, 1, MFLAGS, 0, 7, DFLAGS,
468 RK3328_CLKGATE_CON(2), 7, GFLAGS),
469 COMPOSITE(SCLK_PWM, "clk_pwm", mux_2plls_p, 0,
470 RK3328_CLKSEL_CON(24), 15, 1, MFLAGS, 8, 7, DFLAGS,
471 RK3328_CLKGATE_CON(2), 8, GFLAGS),
472 COMPOSITE(SCLK_OTP, "clk_otp", mux_2plls_xin24m_p, 0,
473 RK3328_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 6, DFLAGS,
474 RK3328_CLKGATE_CON(3), 8, GFLAGS),
475 COMPOSITE(SCLK_EFUSE, "clk_efuse", mux_2plls_xin24m_p, 0,
476 RK3328_CLKSEL_CON(5), 14, 2, MFLAGS, 8, 5, DFLAGS,
477 RK3328_CLKGATE_CON(2), 13, GFLAGS),
478 COMPOSITE(SCLK_PDM, "clk_pdm", mux_cpll_gpll_apll_p, CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
479 RK3328_CLKSEL_CON(20), 14, 2, MFLAGS, 8, 5, DFLAGS,
480 RK3328_CLKGATE_CON(2), 15, GFLAGS),
481
482 GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0,
483 RK3328_CLKGATE_CON(8), 5, GFLAGS),
484 GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0,
485 RK3328_CLKGATE_CON(8), 6, GFLAGS),
486 GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0,
487 RK3328_CLKGATE_CON(8), 7, GFLAGS),
488 GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0,
489 RK3328_CLKGATE_CON(8), 8, GFLAGS),
490 GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0,
491 RK3328_CLKGATE_CON(8), 9, GFLAGS),
492 GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0,
493 RK3328_CLKGATE_CON(8), 10, GFLAGS),
494
495 COMPOSITE(SCLK_WIFI, "clk_wifi", mux_2plls_u480m_p, 0,
496 RK3328_CLKSEL_CON(52), 6, 2, MFLAGS, 0, 6, DFLAGS,
497 RK3328_CLKGATE_CON(0), 10, GFLAGS),
498
499 /*
500 * Clock-Architecture Diagram 5
501 */
502
503 /* PD_VIDEO */
504 COMPOSITE(ACLK_RKVDEC_PRE, "aclk_rkvdec_pre", mux_4plls_p, 0,
505 RK3328_CLKSEL_CON(48), 6, 2, MFLAGS, 0, 5, DFLAGS,
506 RK3328_CLKGATE_CON(6), 0, GFLAGS),
507 FACTOR_GATE(HCLK_RKVDEC_PRE, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, 1, 4,
508 RK3328_CLKGATE_CON(11), 0, GFLAGS),
509 GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", CLK_SET_RATE_PARENT,
510 RK3328_CLKGATE_CON(24), 0, GFLAGS),
511 GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", CLK_SET_RATE_PARENT,
512 RK3328_CLKGATE_CON(24), 1, GFLAGS),
513 GATE(0, "aclk_rkvdec_niu", "aclk_rkvdec_pre", CLK_IGNORE_UNUSED,
514 RK3328_CLKGATE_CON(24), 2, GFLAGS),
515 GATE(0, "hclk_rkvdec_niu", "hclk_rkvdec_pre", CLK_IGNORE_UNUSED,
516 RK3328_CLKGATE_CON(24), 3, GFLAGS),
517
518 COMPOSITE(SCLK_VDEC_CABAC, "sclk_vdec_cabac", mux_4plls_p, 0,
519 RK3328_CLKSEL_CON(48), 14, 2, MFLAGS, 8, 5, DFLAGS,
520 RK3328_CLKGATE_CON(6), 1, GFLAGS),
521
522 COMPOSITE(SCLK_VDEC_CORE, "sclk_vdec_core", mux_4plls_p, 0,
523 RK3328_CLKSEL_CON(49), 6, 2, MFLAGS, 0, 5, DFLAGS,
524 RK3328_CLKGATE_CON(6), 2, GFLAGS),
525
526 COMPOSITE(ACLK_VPU_PRE, "aclk_vpu_pre", mux_4plls_p, 0,
527 RK3328_CLKSEL_CON(50), 6, 2, MFLAGS, 0, 5, DFLAGS,
528 RK3328_CLKGATE_CON(6), 5, GFLAGS),
529 FACTOR_GATE(HCLK_VPU_PRE, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4,
530 RK3328_CLKGATE_CON(11), 8, GFLAGS),
531 GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", CLK_SET_RATE_PARENT,
532 RK3328_CLKGATE_CON(23), 0, GFLAGS),
533 GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", CLK_SET_RATE_PARENT,
534 RK3328_CLKGATE_CON(23), 1, GFLAGS),
535 GATE(0, "aclk_vpu_niu", "aclk_vpu_pre", CLK_IGNORE_UNUSED,
536 RK3328_CLKGATE_CON(23), 2, GFLAGS),
537 GATE(0, "hclk_vpu_niu", "hclk_vpu_pre", CLK_IGNORE_UNUSED,
538 RK3328_CLKGATE_CON(23), 3, GFLAGS),
539
540 COMPOSITE(ACLK_RKVENC, "aclk_rkvenc", mux_4plls_p, 0,
541 RK3328_CLKSEL_CON(51), 6, 2, MFLAGS, 0, 5, DFLAGS,
542 RK3328_CLKGATE_CON(6), 3, GFLAGS),
543 FACTOR_GATE(HCLK_RKVENC, "hclk_rkvenc", "aclk_rkvenc", 0, 1, 4,
544 RK3328_CLKGATE_CON(11), 4, GFLAGS),
545 GATE(0, "aclk_rkvenc_niu", "aclk_rkvenc", CLK_IGNORE_UNUSED,
546 RK3328_CLKGATE_CON(25), 0, GFLAGS),
547 GATE(0, "hclk_rkvenc_niu", "hclk_rkvenc", CLK_IGNORE_UNUSED,
548 RK3328_CLKGATE_CON(25), 1, GFLAGS),
549 GATE(ACLK_H265, "aclk_h265", "aclk_rkvenc", 0,
550 RK3328_CLKGATE_CON(25), 0, GFLAGS),
551 GATE(PCLK_H265, "pclk_h265", "hclk_rkvenc", 0,
552 RK3328_CLKGATE_CON(25), 1, GFLAGS),
553 GATE(ACLK_H264, "aclk_h264", "aclk_rkvenc", 0,
554 RK3328_CLKGATE_CON(25), 0, GFLAGS),
555 GATE(HCLK_H264, "hclk_h264", "hclk_rkvenc", 0,
556 RK3328_CLKGATE_CON(25), 1, GFLAGS),
557 GATE(ACLK_AXISRAM, "aclk_axisram", "aclk_rkvenc", CLK_IGNORE_UNUSED,
558 RK3328_CLKGATE_CON(25), 0, GFLAGS),
559
560 COMPOSITE(SCLK_VENC_CORE, "sclk_venc_core", mux_4plls_p, 0,
561 RK3328_CLKSEL_CON(51), 14, 2, MFLAGS, 8, 5, DFLAGS,
562 RK3328_CLKGATE_CON(6), 4, GFLAGS),
563
564 COMPOSITE(SCLK_VENC_DSP, "sclk_venc_dsp", mux_4plls_p, 0,
565 RK3328_CLKSEL_CON(52), 14, 2, MFLAGS, 8, 5, DFLAGS,
566 RK3328_CLKGATE_CON(6), 7, GFLAGS),
567
568 /*
569 * Clock-Architecture Diagram 6
570 */
571
572 /* PD_VIO */
573 COMPOSITE(ACLK_VIO_PRE, "aclk_vio_pre", mux_4plls_p, 0,
574 RK3328_CLKSEL_CON(37), 6, 2, MFLAGS, 0, 5, DFLAGS,
575 RK3328_CLKGATE_CON(5), 2, GFLAGS),
576 DIV(HCLK_VIO_PRE, "hclk_vio_pre", "aclk_vio_pre", 0,
577 RK3328_CLKSEL_CON(37), 8, 5, DFLAGS),
578
579 COMPOSITE(ACLK_RGA_PRE, "aclk_rga_pre", mux_4plls_p, 0,
580 RK3328_CLKSEL_CON(36), 14, 2, MFLAGS, 8, 5, DFLAGS,
581 RK3328_CLKGATE_CON(5), 0, GFLAGS),
582 COMPOSITE(SCLK_RGA, "clk_rga", mux_4plls_p, 0,
583 RK3328_CLKSEL_CON(36), 6, 2, MFLAGS, 0, 5, DFLAGS,
584 RK3328_CLKGATE_CON(5), 1, GFLAGS),
585 COMPOSITE(ACLK_VOP_PRE, "aclk_vop_pre", mux_4plls_p, 0,
586 RK3328_CLKSEL_CON(39), 6, 2, MFLAGS, 0, 5, DFLAGS,
587 RK3328_CLKGATE_CON(5), 5, GFLAGS),
588 GATE(0, "clk_hdmi_sfc", "xin24m", 0,
589 RK3328_CLKGATE_CON(5), 4, GFLAGS),
590
591 COMPOSITE_NODIV(0, "clk_cif_src", mux_2plls_p, 0,
592 RK3328_CLKSEL_CON(42), 7, 1, MFLAGS,
593 RK3328_CLKGATE_CON(5), 3, GFLAGS),
594 COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cif_out", mux_sclk_cif_p, CLK_SET_RATE_PARENT,
595 RK3328_CLKSEL_CON(42), 5, 1, MFLAGS, 0, 5, DFLAGS),
596
597 COMPOSITE(DCLK_LCDC_SRC, "dclk_lcdc_src", mux_gpll_cpll_p, 0,
598 RK3328_CLKSEL_CON(40), 0, 1, MFLAGS, 8, 8, DFLAGS,
599 RK3328_CLKGATE_CON(5), 6, GFLAGS),
600 DIV(DCLK_HDMIPHY, "dclk_hdmiphy", "dclk_lcdc_src", 0,
601 RK3328_CLKSEL_CON(40), 3, 3, DFLAGS),
602 MUX(DCLK_LCDC, "dclk_lcdc", mux_dclk_lcdc_p, 0,
603 RK3328_CLKSEL_CON(40), 1, 1, MFLAGS),
604
605 /*
606 * Clock-Architecture Diagram 7
607 */
608
609 /* PD_PERI */
610 GATE(0, "gpll_peri", "gpll", CLK_IGNORE_UNUSED,
611 RK3328_CLKGATE_CON(4), 0, GFLAGS),
612 GATE(0, "cpll_peri", "cpll", CLK_IGNORE_UNUSED,
613 RK3328_CLKGATE_CON(4), 1, GFLAGS),
614 GATE(0, "hdmiphy_peri", "hdmiphy", CLK_IGNORE_UNUSED,
615 RK3328_CLKGATE_CON(4), 2, GFLAGS),
616 COMPOSITE_NOGATE(ACLK_PERI_PRE, "aclk_peri_pre", mux_aclk_peri_pre_p, 0,
617 RK3328_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS),
618 COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_pre", CLK_IGNORE_UNUSED,
619 RK3328_CLKSEL_CON(29), 0, 2, DFLAGS,
620 RK3328_CLKGATE_CON(10), 2, GFLAGS),
621 COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_pre", CLK_IGNORE_UNUSED,
622 RK3328_CLKSEL_CON(29), 4, 3, DFLAGS,
623 RK3328_CLKGATE_CON(10), 1, GFLAGS),
624 GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre", CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT,
625 RK3328_CLKGATE_CON(10), 0, GFLAGS),
626
627 COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_2plls_24m_u480m_p, 0,
628 RK3328_CLKSEL_CON(30), 8, 2, MFLAGS, 0, 8, DFLAGS,
629 RK3328_CLKGATE_CON(4), 3, GFLAGS),
630
631 COMPOSITE(SCLK_SDIO, "clk_sdio", mux_2plls_24m_u480m_p, 0,
632 RK3328_CLKSEL_CON(31), 8, 2, MFLAGS, 0, 8, DFLAGS,
633 RK3328_CLKGATE_CON(4), 4, GFLAGS),
634
635 COMPOSITE(SCLK_EMMC, "clk_emmc", mux_2plls_24m_u480m_p, 0,
636 RK3328_CLKSEL_CON(32), 8, 2, MFLAGS, 0, 8, DFLAGS,
637 RK3328_CLKGATE_CON(4), 5, GFLAGS),
638
639 COMPOSITE(SCLK_SDMMC_EXT, "clk_sdmmc_ext", mux_2plls_24m_u480m_p, 0,
640 RK3328_CLKSEL_CON(43), 8, 2, MFLAGS, 0, 8, DFLAGS,
641 RK3328_CLKGATE_CON(4), 10, GFLAGS),
642
643 COMPOSITE(SCLK_REF_USB3OTG_SRC, "clk_ref_usb3otg_src", mux_2plls_p, 0,
644 RK3328_CLKSEL_CON(45), 7, 1, MFLAGS, 0, 7, DFLAGS,
645 RK3328_CLKGATE_CON(4), 9, GFLAGS),
646
647 MUX(SCLK_REF_USB3OTG, "clk_ref_usb3otg", mux_ref_usb3otg_src_p, CLK_SET_RATE_PARENT,
648 RK3328_CLKSEL_CON(45), 8, 1, MFLAGS),
649
650 GATE(SCLK_USB3OTG_REF, "clk_usb3otg_ref", "xin24m", 0,
651 RK3328_CLKGATE_CON(4), 7, GFLAGS),
652
653 COMPOSITE(SCLK_USB3OTG_SUSPEND, "clk_usb3otg_suspend", mux_xin24m_32k_p, 0,
654 RK3328_CLKSEL_CON(33), 15, 1, MFLAGS, 0, 10, DFLAGS,
655 RK3328_CLKGATE_CON(4), 8, GFLAGS),
656
657 /*
658 * Clock-Architecture Diagram 8
659 */
660
661 /* PD_GMAC */
662 COMPOSITE(ACLK_GMAC, "aclk_gmac", mux_2plls_hdmiphy_p, 0,
663 RK3328_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS,
664 RK3328_CLKGATE_CON(3), 2, GFLAGS),
665 COMPOSITE_NOMUX(PCLK_GMAC, "pclk_gmac", "aclk_gmac", 0,
666 RK3328_CLKSEL_CON(25), 8, 3, DFLAGS,
667 RK3328_CLKGATE_CON(9), 0, GFLAGS),
668
669 COMPOSITE(SCLK_MAC2IO_SRC, "clk_mac2io_src", mux_2plls_p, 0,
670 RK3328_CLKSEL_CON(27), 7, 1, MFLAGS, 0, 5, DFLAGS,
671 RK3328_CLKGATE_CON(3), 1, GFLAGS),
672 GATE(SCLK_MAC2IO_REF, "clk_mac2io_ref", "clk_mac2io", 0,
673 RK3328_CLKGATE_CON(9), 7, GFLAGS),
674 GATE(SCLK_MAC2IO_RX, "clk_mac2io_rx", "clk_mac2io", 0,
675 RK3328_CLKGATE_CON(9), 4, GFLAGS),
676 GATE(SCLK_MAC2IO_TX, "clk_mac2io_tx", "clk_mac2io", 0,
677 RK3328_CLKGATE_CON(9), 5, GFLAGS),
678 GATE(SCLK_MAC2IO_REFOUT, "clk_mac2io_refout", "clk_mac2io", 0,
679 RK3328_CLKGATE_CON(9), 6, GFLAGS),
680 COMPOSITE(SCLK_MAC2IO_OUT, "clk_mac2io_out", mux_2plls_p, 0,
681 RK3328_CLKSEL_CON(27), 15, 1, MFLAGS, 8, 5, DFLAGS,
682 RK3328_CLKGATE_CON(3), 5, GFLAGS),
683
684 COMPOSITE(SCLK_MAC2PHY_SRC, "clk_mac2phy_src", mux_2plls_p, 0,
685 RK3328_CLKSEL_CON(26), 7, 1, MFLAGS, 0, 5, DFLAGS,
686 RK3328_CLKGATE_CON(3), 0, GFLAGS),
687 GATE(SCLK_MAC2PHY_REF, "clk_mac2phy_ref", "clk_mac2phy", 0,
688 RK3328_CLKGATE_CON(9), 3, GFLAGS),
689 GATE(SCLK_MAC2PHY_RXTX, "clk_mac2phy_rxtx", "clk_mac2phy", 0,
690 RK3328_CLKGATE_CON(9), 1, GFLAGS),
691 COMPOSITE_NOMUX(SCLK_MAC2PHY_OUT, "clk_mac2phy_out", "clk_mac2phy", 0,
692 RK3328_CLKSEL_CON(26), 8, 2, DFLAGS,
693 RK3328_CLKGATE_CON(9), 2, GFLAGS),
694
695 FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
696
697 /*
698 * Clock-Architecture Diagram 9
699 */
700
701 /* PD_VOP */
702 GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3328_CLKGATE_CON(21), 10, GFLAGS),
703 GATE(0, "aclk_rga_niu", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(22), 3, GFLAGS),
704 GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK3328_CLKGATE_CON(21), 2, GFLAGS),
705 GATE(0, "aclk_vop_niu", "aclk_vop_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(21), 4, GFLAGS),
706
707 GATE(ACLK_IEP, "aclk_iep", "aclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 6, GFLAGS),
708 GATE(ACLK_CIF, "aclk_cif", "aclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 8, GFLAGS),
709 GATE(ACLK_HDCP, "aclk_hdcp", "aclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 15, GFLAGS),
710 GATE(0, "aclk_vio_niu", "aclk_vio_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(22), 2, GFLAGS),
711
712 GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 3, GFLAGS),
713 GATE(0, "hclk_vop_niu", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 5, GFLAGS),
714 GATE(HCLK_IEP, "hclk_iep", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 7, GFLAGS),
715 GATE(HCLK_CIF, "hclk_cif", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 9, GFLAGS),
716 GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 11, GFLAGS),
717 GATE(0, "hclk_ahb1tom", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(21), 12, GFLAGS),
718 GATE(0, "pclk_vio_h2p", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(21), 13, GFLAGS),
719 GATE(0, "hclk_vio_h2p", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(21), 14, GFLAGS),
720 GATE(HCLK_HDCP, "hclk_hdcp", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 0, GFLAGS),
721 GATE(HCLK_VIO, "hclk_vio", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 1, GFLAGS),
722 GATE(PCLK_HDMI, "pclk_hdmi", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 4, GFLAGS),
723 GATE(PCLK_HDCP, "pclk_hdcp", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 5, GFLAGS),
724
725 /* PD_PERI */
726 GATE(0, "aclk_peri_noc", "aclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 11, GFLAGS),
727 GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri", 0, RK3328_CLKGATE_CON(19), 4, GFLAGS),
728
729 GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 0, GFLAGS),
730 GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 1, GFLAGS),
731 GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 2, GFLAGS),
732 GATE(HCLK_SDMMC_EXT, "hclk_sdmmc_ext", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 15, GFLAGS),
733 GATE(HCLK_HOST0, "hclk_host0", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 6, GFLAGS),
734 GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 7, GFLAGS),
735 GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 8, GFLAGS),
736 GATE(HCLK_OTG_PMU, "hclk_otg_pmu", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 9, GFLAGS),
737 GATE(0, "hclk_peri_niu", "hclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 12, GFLAGS),
738 GATE(0, "pclk_peri_niu", "hclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 13, GFLAGS),
739
740 /* PD_GMAC */
741 GATE(ACLK_MAC2PHY, "aclk_mac2phy", "aclk_gmac", 0, RK3328_CLKGATE_CON(26), 0, GFLAGS),
742 GATE(ACLK_MAC2IO, "aclk_mac2io", "aclk_gmac", 0, RK3328_CLKGATE_CON(26), 2, GFLAGS),
743 GATE(0, "aclk_gmac_niu", "aclk_gmac", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(26), 4, GFLAGS),
744 GATE(PCLK_MAC2PHY, "pclk_mac2phy", "pclk_gmac", 0, RK3328_CLKGATE_CON(26), 1, GFLAGS),
745 GATE(PCLK_MAC2IO, "pclk_mac2io", "pclk_gmac", 0, RK3328_CLKGATE_CON(26), 3, GFLAGS),
746 GATE(0, "pclk_gmac_niu", "pclk_gmac", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(26), 5, GFLAGS),
747
748 /* PD_BUS */
749 GATE(0, "aclk_bus_niu", "aclk_bus_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 12, GFLAGS),
750 GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 11, GFLAGS),
751 GATE(ACLK_TSP, "aclk_tsp", "aclk_bus_pre", 0, RK3328_CLKGATE_CON(17), 12, GFLAGS),
752 GATE(0, "aclk_intmem", "aclk_bus_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 0, GFLAGS),
753 GATE(ACLK_DMAC, "aclk_dmac_bus", "aclk_bus_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 1, GFLAGS),
754
755 GATE(0, "hclk_rom", "hclk_bus_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 2, GFLAGS),
756 GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 3, GFLAGS),
757 GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 4, GFLAGS),
758 GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 5, GFLAGS),
759 GATE(HCLK_SPDIF_8CH, "hclk_spdif_8ch", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 6, GFLAGS),
760 GATE(HCLK_TSP, "hclk_tsp", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(17), 11, GFLAGS),
761 GATE(HCLK_CRYPTO_MST, "hclk_crypto_mst", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 7, GFLAGS),
762 GATE(HCLK_CRYPTO_SLV, "hclk_crypto_slv", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 8, GFLAGS),
763 GATE(0, "hclk_bus_niu", "hclk_bus_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 13, GFLAGS),
764 GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(28), 0, GFLAGS),
765
766 GATE(0, "pclk_bus_niu", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 14, GFLAGS),
767 GATE(0, "pclk_efuse", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 9, GFLAGS),
768 GATE(0, "pclk_otp", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(28), 4, GFLAGS),
769 GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0, RK3328_CLKGATE_CON(15), 10, GFLAGS),
770 GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 0, GFLAGS),
771 GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 1, GFLAGS),
772 GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 2, GFLAGS),
773 GATE(PCLK_TIMER, "pclk_timer0", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 3, GFLAGS),
774 GATE(0, "pclk_stimer", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 4, GFLAGS),
775 GATE(PCLK_SPI, "pclk_spi", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 5, GFLAGS),
776 GATE(PCLK_PWM, "pclk_rk_pwm", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 6, GFLAGS),
777 GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 7, GFLAGS),
778 GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 8, GFLAGS),
779 GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 9, GFLAGS),
780 GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 10, GFLAGS),
781 GATE(PCLK_UART0, "pclk_uart0", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 11, GFLAGS),
782 GATE(PCLK_UART1, "pclk_uart1", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 12, GFLAGS),
783 GATE(PCLK_UART2, "pclk_uart2", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 13, GFLAGS),
784 GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 14, GFLAGS),
785 GATE(PCLK_DCF, "pclk_dcf", "pclk_bus", 0, RK3328_CLKGATE_CON(16), 15, GFLAGS),
786 GATE(PCLK_GRF, "pclk_grf", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 0, GFLAGS),
787 GATE(0, "pclk_cru", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 4, GFLAGS),
788 GATE(0, "pclk_sgrf", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 6, GFLAGS),
789 GATE(0, "pclk_sim", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 10, GFLAGS),
790 GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 0, RK3328_CLKGATE_CON(17), 15, GFLAGS),
791 GATE(0, "pclk_pmu", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(28), 3, GFLAGS),
792
793 GATE(PCLK_USB3PHY_OTG, "pclk_usb3phy_otg", "pclk_phy_pre", 0, RK3328_CLKGATE_CON(28), 1, GFLAGS),
794 GATE(PCLK_USB3PHY_PIPE, "pclk_usb3phy_pipe", "pclk_phy_pre", 0, RK3328_CLKGATE_CON(28), 2, GFLAGS),
795 GATE(PCLK_USB3_GRF, "pclk_usb3_grf", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 2, GFLAGS),
796 GATE(PCLK_USB2_GRF, "pclk_usb2_grf", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 14, GFLAGS),
797 GATE(0, "pclk_ddrphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 13, GFLAGS),
798 GATE(0, "pclk_acodecphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 5, GFLAGS),
799 GATE(PCLK_HDMIPHY, "pclk_hdmiphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 7, GFLAGS),
800 GATE(0, "pclk_vdacphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 8, GFLAGS),
801 GATE(0, "pclk_phy_niu", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 15, GFLAGS),
802
803 /* PD_MMC */
804 MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc",
805 RK3328_SDMMC_CON0, 1),
806 MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc",
807 RK3328_SDMMC_CON1, 1),
808
809 MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio",
810 RK3328_SDIO_CON0, 1),
811 MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio",
812 RK3328_SDIO_CON1, 1),
813
814 MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc",
815 RK3328_EMMC_CON0, 1),
816 MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc",
817 RK3328_EMMC_CON1, 1),
818
819 MMC(SCLK_SDMMC_EXT_DRV, "sdmmc_ext_drv", "sclk_sdmmc_ext",
820 RK3328_SDMMC_EXT_CON0, 1),
821 MMC(SCLK_SDMMC_EXT_SAMPLE, "sdmmc_ext_sample", "sclk_sdmmc_ext",
822 RK3328_SDMMC_EXT_CON1, 1),
823};
824
825static const char *const rk3328_critical_clocks[] __initconst = {
826 "aclk_bus",
827 "pclk_bus",
828 "hclk_bus",
829 "aclk_peri",
830 "hclk_peri",
831 "pclk_peri",
832 "pclk_dbg",
833 "aclk_core_niu",
834 "aclk_gic400",
835 "aclk_intmem",
836 "hclk_rom",
837 "pclk_grf",
838 "pclk_cru",
839 "pclk_sgrf",
840 "pclk_timer0",
841 "clk_timer0",
842 "pclk_ddr_msch",
843 "pclk_ddr_mon",
844 "pclk_ddr_grf",
845 "clk_ddrupctl",
846 "clk_ddrmsch",
847 "hclk_ahb1tom",
848 "clk_jtag",
849 "pclk_ddrphy",
850 "pclk_pmu",
851 "hclk_otg_pmu",
852 "aclk_rga_niu",
853 "pclk_vio_h2p",
854 "hclk_vio_h2p",
855};
856
857static void __init rk3328_clk_init(struct device_node *np)
858{
859 struct rockchip_clk_provider *ctx;
860 void __iomem *reg_base;
861
862 reg_base = of_iomap(np, 0);
863 if (!reg_base) {
864 pr_err("%s: could not map cru region\n", __func__);
865 return;
866 }
867
868 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
869 if (IS_ERR(ctx)) {
870 pr_err("%s: rockchip clk init failed\n", __func__);
871 iounmap(reg_base);
872 return;
873 }
874
875 rockchip_clk_register_plls(ctx, rk3328_pll_clks,
876 ARRAY_SIZE(rk3328_pll_clks),
877 RK3328_GRF_SOC_STATUS0);
878 rockchip_clk_register_branches(ctx, rk3328_clk_branches,
879 ARRAY_SIZE(rk3328_clk_branches));
880 rockchip_clk_protect_critical(rk3328_critical_clocks,
881 ARRAY_SIZE(rk3328_critical_clocks));
882
883 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
884 mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
885 &rk3328_cpuclk_data, rk3328_cpuclk_rates,
886 ARRAY_SIZE(rk3328_cpuclk_rates));
887
888 rockchip_register_softrst(np, 11, reg_base + RK3328_SOFTRST_CON(0),
889 ROCKCHIP_SOFTRST_HIWORD_MASK);
890
891 rockchip_register_restart_notifier(ctx, RK3328_GLB_SRST_FST, NULL);
892
893 rockchip_clk_of_add_provider(np, ctx);
894}
895CLK_OF_DECLARE(rk3328_cru, "rockchip,rk3328-cru", rk3328_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
index 3490887b0579..73121b144634 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c
@@ -1132,7 +1132,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
1132 RK3399_CLKGATE_CON(11), 8, GFLAGS), 1132 RK3399_CLKGATE_CON(11), 8, GFLAGS),
1133 1133
1134 COMPOSITE(PCLK_EDP, "pclk_edp", mux_pll_src_cpll_gpll_p, 0, 1134 COMPOSITE(PCLK_EDP, "pclk_edp", mux_pll_src_cpll_gpll_p, 0,
1135 RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 5, DFLAGS, 1135 RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 6, DFLAGS,
1136 RK3399_CLKGATE_CON(11), 11, GFLAGS), 1136 RK3399_CLKGATE_CON(11), 11, GFLAGS),
1137 GATE(PCLK_EDP_NOC, "pclk_edp_noc", "pclk_edp", CLK_IGNORE_UNUSED, 1137 GATE(PCLK_EDP_NOC, "pclk_edp_noc", "pclk_edp", CLK_IGNORE_UNUSED,
1138 RK3399_CLKGATE_CON(32), 12, GFLAGS), 1138 RK3399_CLKGATE_CON(32), 12, GFLAGS),
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index b886be30f34f..fe1d393cf678 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -344,7 +344,6 @@ struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np,
344 ctx->clk_data.clks = clk_table; 344 ctx->clk_data.clks = clk_table;
345 ctx->clk_data.clk_num = nr_clks; 345 ctx->clk_data.clk_num = nr_clks;
346 ctx->cru_node = np; 346 ctx->cru_node = np;
347 ctx->grf = ERR_PTR(-EPROBE_DEFER);
348 spin_lock_init(&ctx->lock); 347 spin_lock_init(&ctx->lock);
349 348
350 ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node, 349 ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
@@ -417,6 +416,13 @@ void __init rockchip_clk_register_branches(
417 list->mux_shift, list->mux_width, 416 list->mux_shift, list->mux_width,
418 list->mux_flags, &ctx->lock); 417 list->mux_flags, &ctx->lock);
419 break; 418 break;
419 case branch_muxgrf:
420 clk = rockchip_clk_register_muxgrf(list->name,
421 list->parent_names, list->num_parents,
422 flags, ctx->grf, list->muxdiv_offset,
423 list->mux_shift, list->mux_width,
424 list->mux_flags);
425 break;
420 case branch_divider: 426 case branch_divider:
421 if (list->div_table) 427 if (list->div_table)
422 clk = clk_register_divider_table(NULL, 428 clk = clk_register_divider_table(NULL,
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index d67eecc4ade9..7c15473ea72b 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -91,6 +91,24 @@ struct clk;
91#define RK3288_EMMC_CON0 0x218 91#define RK3288_EMMC_CON0 0x218
92#define RK3288_EMMC_CON1 0x21c 92#define RK3288_EMMC_CON1 0x21c
93 93
94#define RK3328_PLL_CON(x) RK2928_PLL_CON(x)
95#define RK3328_CLKSEL_CON(x) ((x) * 0x4 + 0x100)
96#define RK3328_CLKGATE_CON(x) ((x) * 0x4 + 0x200)
97#define RK3328_GRFCLKSEL_CON(x) ((x) * 0x4 + 0x100)
98#define RK3328_GLB_SRST_FST 0x9c
99#define RK3328_GLB_SRST_SND 0x98
100#define RK3328_SOFTRST_CON(x) ((x) * 0x4 + 0x300)
101#define RK3328_MODE_CON 0x80
102#define RK3328_MISC_CON 0x84
103#define RK3328_SDMMC_CON0 0x380
104#define RK3328_SDMMC_CON1 0x384
105#define RK3328_SDIO_CON0 0x388
106#define RK3328_SDIO_CON1 0x38c
107#define RK3328_EMMC_CON0 0x390
108#define RK3328_EMMC_CON1 0x394
109#define RK3328_SDMMC_EXT_CON0 0x398
110#define RK3328_SDMMC_EXT_CON1 0x39C
111
94#define RK3368_PLL_CON(x) RK2928_PLL_CON(x) 112#define RK3368_PLL_CON(x) RK2928_PLL_CON(x)
95#define RK3368_CLKSEL_CON(x) ((x) * 0x4 + 0x100) 113#define RK3368_CLKSEL_CON(x) ((x) * 0x4 + 0x100)
96#define RK3368_CLKGATE_CON(x) ((x) * 0x4 + 0x200) 114#define RK3368_CLKGATE_CON(x) ((x) * 0x4 + 0x200)
@@ -130,6 +148,7 @@ struct clk;
130enum rockchip_pll_type { 148enum rockchip_pll_type {
131 pll_rk3036, 149 pll_rk3036,
132 pll_rk3066, 150 pll_rk3066,
151 pll_rk3328,
133 pll_rk3399, 152 pll_rk3399,
134}; 153};
135 154
@@ -317,11 +336,17 @@ struct clk *rockchip_clk_register_inverter(const char *name,
317 void __iomem *reg, int shift, int flags, 336 void __iomem *reg, int shift, int flags,
318 spinlock_t *lock); 337 spinlock_t *lock);
319 338
339struct clk *rockchip_clk_register_muxgrf(const char *name,
340 const char *const *parent_names, u8 num_parents,
341 int flags, struct regmap *grf, int reg,
342 int shift, int width, int mux_flags);
343
320#define PNAME(x) static const char *const x[] __initconst 344#define PNAME(x) static const char *const x[] __initconst
321 345
322enum rockchip_clk_branch_type { 346enum rockchip_clk_branch_type {
323 branch_composite, 347 branch_composite,
324 branch_mux, 348 branch_mux,
349 branch_muxgrf,
325 branch_divider, 350 branch_divider,
326 branch_fraction_divider, 351 branch_fraction_divider,
327 branch_gate, 352 branch_gate,
@@ -551,6 +576,21 @@ struct rockchip_clk_branch {
551 .gate_offset = -1, \ 576 .gate_offset = -1, \
552 } 577 }
553 578
579#define MUXGRF(_id, cname, pnames, f, o, s, w, mf) \
580 { \
581 .id = _id, \
582 .branch_type = branch_muxgrf, \
583 .name = cname, \
584 .parent_names = pnames, \
585 .num_parents = ARRAY_SIZE(pnames), \
586 .flags = f, \
587 .muxdiv_offset = o, \
588 .mux_shift = s, \
589 .mux_width = w, \
590 .mux_flags = mf, \
591 .gate_offset = -1, \
592 }
593
554#define DIV(_id, cname, pname, f, o, s, w, df) \ 594#define DIV(_id, cname, pname, f, o, s, w, df) \
555 { \ 595 { \
556 .id = _id, \ 596 .id = _id, \
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 57f4dc6dc447..7afc21dc374e 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -5,7 +5,6 @@
5obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o clk-cpu.o 5obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o clk-cpu.o
6obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o 6obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o
7obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o 7obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
8obj-$(CONFIG_SOC_EXYNOS4415) += clk-exynos4415.o
9obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o 8obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
10obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o 9obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o
11obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o 10obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o
diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c
index 17e68a724945..cb7df358a27d 100644
--- a/drivers/clk/samsung/clk-exynos-audss.c
+++ b/drivers/clk/samsung/clk-exynos-audss.c
@@ -44,7 +44,7 @@ static unsigned long reg_save[][2] = {
44 { ASS_CLK_GATE, 0 }, 44 { ASS_CLK_GATE, 0 },
45}; 45};
46 46
47static int exynos_audss_clk_suspend(void) 47static int exynos_audss_clk_suspend(struct device *dev)
48{ 48{
49 int i; 49 int i;
50 50
@@ -54,18 +54,15 @@ static int exynos_audss_clk_suspend(void)
54 return 0; 54 return 0;
55} 55}
56 56
57static void exynos_audss_clk_resume(void) 57static int exynos_audss_clk_resume(struct device *dev)
58{ 58{
59 int i; 59 int i;
60 60
61 for (i = 0; i < ARRAY_SIZE(reg_save); i++) 61 for (i = 0; i < ARRAY_SIZE(reg_save); i++)
62 writel(reg_save[i][1], reg_base + reg_save[i][0]); 62 writel(reg_save[i][1], reg_base + reg_save[i][0]);
63}
64 63
65static struct syscore_ops exynos_audss_clk_syscore_ops = { 64 return 0;
66 .suspend = exynos_audss_clk_suspend, 65}
67 .resume = exynos_audss_clk_resume,
68};
69#endif /* CONFIG_PM_SLEEP */ 66#endif /* CONFIG_PM_SLEEP */
70 67
71struct exynos_audss_clk_drvdata { 68struct exynos_audss_clk_drvdata {
@@ -251,9 +248,6 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
251 goto unregister; 248 goto unregister;
252 } 249 }
253 250
254#ifdef CONFIG_PM_SLEEP
255 register_syscore_ops(&exynos_audss_clk_syscore_ops);
256#endif
257 return 0; 251 return 0;
258 252
259unregister: 253unregister:
@@ -267,10 +261,6 @@ unregister:
267 261
268static int exynos_audss_clk_remove(struct platform_device *pdev) 262static int exynos_audss_clk_remove(struct platform_device *pdev)
269{ 263{
270#ifdef CONFIG_PM_SLEEP
271 unregister_syscore_ops(&exynos_audss_clk_syscore_ops);
272#endif
273
274 of_clk_del_provider(pdev->dev.of_node); 264 of_clk_del_provider(pdev->dev.of_node);
275 265
276 exynos_audss_clk_teardown(); 266 exynos_audss_clk_teardown();
@@ -281,10 +271,16 @@ static int exynos_audss_clk_remove(struct platform_device *pdev)
281 return 0; 271 return 0;
282} 272}
283 273
274static const struct dev_pm_ops exynos_audss_clk_pm_ops = {
275 SET_LATE_SYSTEM_SLEEP_PM_OPS(exynos_audss_clk_suspend,
276 exynos_audss_clk_resume)
277};
278
284static struct platform_driver exynos_audss_clk_driver = { 279static struct platform_driver exynos_audss_clk_driver = {
285 .driver = { 280 .driver = {
286 .name = "exynos-audss-clk", 281 .name = "exynos-audss-clk",
287 .of_match_table = exynos_audss_clk_of_match, 282 .of_match_table = exynos_audss_clk_of_match,
283 .pm = &exynos_audss_clk_pm_ops,
288 }, 284 },
289 .probe = exynos_audss_clk_probe, 285 .probe = exynos_audss_clk_probe,
290 .remove = exynos_audss_clk_remove, 286 .remove = exynos_audss_clk_remove,
diff --git a/drivers/clk/samsung/clk-exynos4415.c b/drivers/clk/samsung/clk-exynos4415.c
deleted file mode 100644
index 6c9063159717..000000000000
--- a/drivers/clk/samsung/clk-exynos4415.c
+++ /dev/null
@@ -1,1022 +0,0 @@
1/*
2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 * Author: Chanwoo Choi <cw00.choi@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Common Clock Framework support for Exynos4415 SoC.
10 */
11
12#include <linux/clk-provider.h>
13#include <linux/of.h>
14#include <linux/of_address.h>
15#include <linux/platform_device.h>
16#include <linux/syscore_ops.h>
17
18#include <dt-bindings/clock/exynos4415.h>
19
20#include "clk.h"
21#include "clk-pll.h"
22
23#define SRC_LEFTBUS 0x4200
24#define DIV_LEFTBUS 0x4500
25#define GATE_IP_LEFTBUS 0x4800
26#define GATE_IP_IMAGE 0x4930
27#define SRC_RIGHTBUS 0x8200
28#define DIV_RIGHTBUS 0x8500
29#define GATE_IP_RIGHTBUS 0x8800
30#define GATE_IP_PERIR 0x8960
31#define EPLL_LOCK 0xc010
32#define G3D_PLL_LOCK 0xc020
33#define DISP_PLL_LOCK 0xc030
34#define ISP_PLL_LOCK 0xc040
35#define EPLL_CON0 0xc110
36#define EPLL_CON1 0xc114
37#define EPLL_CON2 0xc118
38#define G3D_PLL_CON0 0xc120
39#define G3D_PLL_CON1 0xc124
40#define G3D_PLL_CON2 0xc128
41#define ISP_PLL_CON0 0xc130
42#define ISP_PLL_CON1 0xc134
43#define ISP_PLL_CON2 0xc138
44#define DISP_PLL_CON0 0xc140
45#define DISP_PLL_CON1 0xc144
46#define DISP_PLL_CON2 0xc148
47#define SRC_TOP0 0xc210
48#define SRC_TOP1 0xc214
49#define SRC_CAM 0xc220
50#define SRC_TV 0xc224
51#define SRC_MFC 0xc228
52#define SRC_G3D 0xc22c
53#define SRC_LCD 0xc234
54#define SRC_ISP 0xc238
55#define SRC_MAUDIO 0xc23c
56#define SRC_FSYS 0xc240
57#define SRC_PERIL0 0xc250
58#define SRC_PERIL1 0xc254
59#define SRC_CAM1 0xc258
60#define SRC_TOP_ISP0 0xc25c
61#define SRC_TOP_ISP1 0xc260
62#define SRC_MASK_TOP 0xc310
63#define SRC_MASK_CAM 0xc320
64#define SRC_MASK_TV 0xc324
65#define SRC_MASK_LCD 0xc334
66#define SRC_MASK_ISP 0xc338
67#define SRC_MASK_MAUDIO 0xc33c
68#define SRC_MASK_FSYS 0xc340
69#define SRC_MASK_PERIL0 0xc350
70#define SRC_MASK_PERIL1 0xc354
71#define DIV_TOP 0xc510
72#define DIV_CAM 0xc520
73#define DIV_TV 0xc524
74#define DIV_MFC 0xc528
75#define DIV_G3D 0xc52c
76#define DIV_LCD 0xc534
77#define DIV_ISP 0xc538
78#define DIV_MAUDIO 0xc53c
79#define DIV_FSYS0 0xc540
80#define DIV_FSYS1 0xc544
81#define DIV_FSYS2 0xc548
82#define DIV_PERIL0 0xc550
83#define DIV_PERIL1 0xc554
84#define DIV_PERIL2 0xc558
85#define DIV_PERIL3 0xc55c
86#define DIV_PERIL4 0xc560
87#define DIV_PERIL5 0xc564
88#define DIV_CAM1 0xc568
89#define DIV_TOP_ISP1 0xc56c
90#define DIV_TOP_ISP0 0xc570
91#define CLKDIV2_RATIO 0xc580
92#define GATE_SCLK_CAM 0xc820
93#define GATE_SCLK_TV 0xc824
94#define GATE_SCLK_MFC 0xc828
95#define GATE_SCLK_G3D 0xc82c
96#define GATE_SCLK_LCD 0xc834
97#define GATE_SCLK_MAUDIO 0xc83c
98#define GATE_SCLK_FSYS 0xc840
99#define GATE_SCLK_PERIL 0xc850
100#define GATE_IP_CAM 0xc920
101#define GATE_IP_TV 0xc924
102#define GATE_IP_MFC 0xc928
103#define GATE_IP_G3D 0xc92c
104#define GATE_IP_LCD 0xc934
105#define GATE_IP_FSYS 0xc940
106#define GATE_IP_PERIL 0xc950
107#define GATE_BLOCK 0xc970
108#define APLL_LOCK 0x14000
109#define APLL_CON0 0x14100
110#define SRC_CPU 0x14200
111#define DIV_CPU0 0x14500
112#define DIV_CPU1 0x14504
113
114static const unsigned long exynos4415_cmu_clk_regs[] __initconst = {
115 SRC_LEFTBUS,
116 DIV_LEFTBUS,
117 GATE_IP_LEFTBUS,
118 GATE_IP_IMAGE,
119 SRC_RIGHTBUS,
120 DIV_RIGHTBUS,
121 GATE_IP_RIGHTBUS,
122 GATE_IP_PERIR,
123 EPLL_LOCK,
124 G3D_PLL_LOCK,
125 DISP_PLL_LOCK,
126 ISP_PLL_LOCK,
127 EPLL_CON0,
128 EPLL_CON1,
129 EPLL_CON2,
130 G3D_PLL_CON0,
131 G3D_PLL_CON1,
132 G3D_PLL_CON2,
133 ISP_PLL_CON0,
134 ISP_PLL_CON1,
135 ISP_PLL_CON2,
136 DISP_PLL_CON0,
137 DISP_PLL_CON1,
138 DISP_PLL_CON2,
139 SRC_TOP0,
140 SRC_TOP1,
141 SRC_CAM,
142 SRC_TV,
143 SRC_MFC,
144 SRC_G3D,
145 SRC_LCD,
146 SRC_ISP,
147 SRC_MAUDIO,
148 SRC_FSYS,
149 SRC_PERIL0,
150 SRC_PERIL1,
151 SRC_CAM1,
152 SRC_TOP_ISP0,
153 SRC_TOP_ISP1,
154 SRC_MASK_TOP,
155 SRC_MASK_CAM,
156 SRC_MASK_TV,
157 SRC_MASK_LCD,
158 SRC_MASK_ISP,
159 SRC_MASK_MAUDIO,
160 SRC_MASK_FSYS,
161 SRC_MASK_PERIL0,
162 SRC_MASK_PERIL1,
163 DIV_TOP,
164 DIV_CAM,
165 DIV_TV,
166 DIV_MFC,
167 DIV_G3D,
168 DIV_LCD,
169 DIV_ISP,
170 DIV_MAUDIO,
171 DIV_FSYS0,
172 DIV_FSYS1,
173 DIV_FSYS2,
174 DIV_PERIL0,
175 DIV_PERIL1,
176 DIV_PERIL2,
177 DIV_PERIL3,
178 DIV_PERIL4,
179 DIV_PERIL5,
180 DIV_CAM1,
181 DIV_TOP_ISP1,
182 DIV_TOP_ISP0,
183 CLKDIV2_RATIO,
184 GATE_SCLK_CAM,
185 GATE_SCLK_TV,
186 GATE_SCLK_MFC,
187 GATE_SCLK_G3D,
188 GATE_SCLK_LCD,
189 GATE_SCLK_MAUDIO,
190 GATE_SCLK_FSYS,
191 GATE_SCLK_PERIL,
192 GATE_IP_CAM,
193 GATE_IP_TV,
194 GATE_IP_MFC,
195 GATE_IP_G3D,
196 GATE_IP_LCD,
197 GATE_IP_FSYS,
198 GATE_IP_PERIL,
199 GATE_BLOCK,
200 APLL_LOCK,
201 APLL_CON0,
202 SRC_CPU,
203 DIV_CPU0,
204 DIV_CPU1,
205};
206
207/* list of all parent clock list */
208PNAME(mout_g3d_pllsrc_p) = { "fin_pll", };
209
210PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
211PNAME(mout_g3d_pll_p) = { "fin_pll", "fout_g3d_pll", };
212PNAME(mout_isp_pll_p) = { "fin_pll", "fout_isp_pll", };
213PNAME(mout_disp_pll_p) = { "fin_pll", "fout_disp_pll", };
214
215PNAME(mout_mpll_user_p) = { "fin_pll", "div_mpll_pre", };
216PNAME(mout_epll_p) = { "fin_pll", "fout_epll", };
217PNAME(mout_core_p) = { "mout_apll", "mout_mpll_user_c", };
218PNAME(mout_hpm_p) = { "mout_apll", "mout_mpll_user_c", };
219
220PNAME(mout_ebi_p) = { "div_aclk_200", "div_aclk_160", };
221PNAME(mout_ebi_1_p) = { "mout_ebi", "mout_g3d_pll", };
222
223PNAME(mout_gdl_p) = { "mout_mpll_user_l", };
224PNAME(mout_gdr_p) = { "mout_mpll_user_r", };
225
226PNAME(mout_aclk_266_p) = { "mout_mpll_user_t", "mout_g3d_pll", };
227
228PNAME(group_epll_g3dpll_p) = { "mout_epll", "mout_g3d_pll" };
229PNAME(group_sclk_p) = { "xxti", "xusbxti",
230 "none", "mout_isp_pll",
231 "none", "none", "div_mpll_pre",
232 "mout_epll", "mout_g3d_pll", };
233PNAME(group_spdif_p) = { "mout_audio0", "mout_audio1",
234 "mout_audio2", "spdif_extclk", };
235PNAME(group_sclk_audio2_p) = { "audiocdclk2", "none",
236 "none", "mout_isp_pll",
237 "mout_disp_pll", "xusbxti",
238 "div_mpll_pre", "mout_epll",
239 "mout_g3d_pll", };
240PNAME(group_sclk_audio1_p) = { "audiocdclk1", "none",
241 "none", "mout_isp_pll",
242 "mout_disp_pll", "xusbxti",
243 "div_mpll_pre", "mout_epll",
244 "mout_g3d_pll", };
245PNAME(group_sclk_audio0_p) = { "audiocdclk0", "none",
246 "none", "mout_isp_pll",
247 "mout_disp_pll", "xusbxti",
248 "div_mpll_pre", "mout_epll",
249 "mout_g3d_pll", };
250PNAME(group_fimc_lclk_p) = { "xxti", "xusbxti",
251 "none", "mout_isp_pll",
252 "none", "mout_disp_pll",
253 "mout_mpll_user_t", "mout_epll",
254 "mout_g3d_pll", };
255PNAME(group_sclk_fimd0_p) = { "xxti", "xusbxti",
256 "m_bitclkhsdiv4_4l", "mout_isp_pll",
257 "mout_disp_pll", "sclk_hdmiphy",
258 "div_mpll_pre", "mout_epll",
259 "mout_g3d_pll", };
260PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy" };
261PNAME(mout_mfc_p) = { "mout_mfc_0", "mout_mfc_1" };
262PNAME(mout_g3d_p) = { "mout_g3d_0", "mout_g3d_1" };
263PNAME(mout_jpeg_p) = { "mout_jpeg_0", "mout_jpeg_1" };
264PNAME(mout_jpeg1_p) = { "mout_epll", "mout_g3d_pll" };
265PNAME(group_aclk_isp0_300_p) = { "mout_isp_pll", "div_mpll_pre" };
266PNAME(group_aclk_isp0_400_user_p) = { "fin_pll", "div_aclk_400_mcuisp" };
267PNAME(group_aclk_isp0_300_user_p) = { "fin_pll", "mout_aclk_isp0_300" };
268PNAME(group_aclk_isp1_300_user_p) = { "fin_pll", "mout_aclk_isp1_300" };
269PNAME(group_mout_mpll_user_t_p) = { "mout_mpll_user_t" };
270
271static const struct samsung_fixed_factor_clock exynos4415_fixed_factor_clks[] __initconst = {
272 /* HACK: fin_pll hardcoded to xusbxti until detection is implemented. */
273 FFACTOR(CLK_FIN_PLL, "fin_pll", "xusbxti", 1, 1, 0),
274};
275
276static const struct samsung_fixed_rate_clock exynos4415_fixed_rate_clks[] __initconst = {
277 FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 27000000),
278};
279
280static const struct samsung_mux_clock exynos4415_mux_clks[] __initconst = {
281 /*
282 * NOTE: Following table is sorted by register address in ascending
283 * order and then bitfield shift in descending order, as it is done
284 * in the User's Manual. When adding new entries, please make sure
285 * that the order is preserved, to avoid merge conflicts and make
286 * further work with defined data easier.
287 */
288
289 /* SRC_LEFTBUS */
290 MUX(CLK_MOUT_MPLL_USER_L, "mout_mpll_user_l", mout_mpll_user_p,
291 SRC_LEFTBUS, 4, 1),
292 MUX(CLK_MOUT_GDL, "mout_gdl", mout_gdl_p, SRC_LEFTBUS, 0, 1),
293
294 /* SRC_RIGHTBUS */
295 MUX(CLK_MOUT_MPLL_USER_R, "mout_mpll_user_r", mout_mpll_user_p,
296 SRC_RIGHTBUS, 4, 1),
297 MUX(CLK_MOUT_GDR, "mout_gdr", mout_gdr_p, SRC_RIGHTBUS, 0, 1),
298
299 /* SRC_TOP0 */
300 MUX(CLK_MOUT_EBI, "mout_ebi", mout_ebi_p, SRC_TOP0, 28, 1),
301 MUX(CLK_MOUT_ACLK_200, "mout_aclk_200", group_mout_mpll_user_t_p,
302 SRC_TOP0, 24, 1),
303 MUX(CLK_MOUT_ACLK_160, "mout_aclk_160", group_mout_mpll_user_t_p,
304 SRC_TOP0, 20, 1),
305 MUX(CLK_MOUT_ACLK_100, "mout_aclk_100", group_mout_mpll_user_t_p,
306 SRC_TOP0, 16, 1),
307 MUX(CLK_MOUT_ACLK_266, "mout_aclk_266", mout_aclk_266_p,
308 SRC_TOP0, 12, 1),
309 MUX(CLK_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p,
310 SRC_TOP0, 8, 1),
311 MUX(CLK_MOUT_EPLL, "mout_epll", mout_epll_p, SRC_TOP0, 4, 1),
312 MUX(CLK_MOUT_EBI_1, "mout_ebi_1", mout_ebi_1_p, SRC_TOP0, 0, 1),
313
314 /* SRC_TOP1 */
315 MUX(CLK_MOUT_ISP_PLL, "mout_isp_pll", mout_isp_pll_p,
316 SRC_TOP1, 28, 1),
317 MUX(CLK_MOUT_DISP_PLL, "mout_disp_pll", mout_disp_pll_p,
318 SRC_TOP1, 16, 1),
319 MUX(CLK_MOUT_MPLL_USER_T, "mout_mpll_user_t", mout_mpll_user_p,
320 SRC_TOP1, 12, 1),
321 MUX(CLK_MOUT_ACLK_400_MCUISP, "mout_aclk_400_mcuisp",
322 group_mout_mpll_user_t_p, SRC_TOP1, 8, 1),
323 MUX(CLK_MOUT_G3D_PLLSRC, "mout_g3d_pllsrc", mout_g3d_pllsrc_p,
324 SRC_TOP1, 0, 1),
325
326 /* SRC_CAM */
327 MUX(CLK_MOUT_CSIS1, "mout_csis1", group_fimc_lclk_p, SRC_CAM, 28, 4),
328 MUX(CLK_MOUT_CSIS0, "mout_csis0", group_fimc_lclk_p, SRC_CAM, 24, 4),
329 MUX(CLK_MOUT_CAM1, "mout_cam1", group_fimc_lclk_p, SRC_CAM, 20, 4),
330 MUX(CLK_MOUT_FIMC3_LCLK, "mout_fimc3_lclk", group_fimc_lclk_p, SRC_CAM,
331 12, 4),
332 MUX(CLK_MOUT_FIMC2_LCLK, "mout_fimc2_lclk", group_fimc_lclk_p, SRC_CAM,
333 8, 4),
334 MUX(CLK_MOUT_FIMC1_LCLK, "mout_fimc1_lclk", group_fimc_lclk_p, SRC_CAM,
335 4, 4),
336 MUX(CLK_MOUT_FIMC0_LCLK, "mout_fimc0_lclk", group_fimc_lclk_p, SRC_CAM,
337 0, 4),
338
339 /* SRC_TV */
340 MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1),
341
342 /* SRC_MFC */
343 MUX(CLK_MOUT_MFC, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1),
344 MUX(CLK_MOUT_MFC_1, "mout_mfc_1", group_epll_g3dpll_p, SRC_MFC, 4, 1),
345 MUX(CLK_MOUT_MFC_0, "mout_mfc_0", group_mout_mpll_user_t_p, SRC_MFC, 0,
346 1),
347
348 /* SRC_G3D */
349 MUX(CLK_MOUT_G3D, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1),
350 MUX(CLK_MOUT_G3D_1, "mout_g3d_1", group_epll_g3dpll_p, SRC_G3D, 4, 1),
351 MUX(CLK_MOUT_G3D_0, "mout_g3d_0", group_mout_mpll_user_t_p, SRC_G3D, 0,
352 1),
353
354 /* SRC_LCD */
355 MUX(CLK_MOUT_MIPI0, "mout_mipi0", group_fimc_lclk_p, SRC_LCD, 12, 4),
356 MUX(CLK_MOUT_FIMD0, "mout_fimd0", group_sclk_fimd0_p, SRC_LCD, 0, 4),
357
358 /* SRC_ISP */
359 MUX(CLK_MOUT_TSADC_ISP, "mout_tsadc_isp", group_fimc_lclk_p, SRC_ISP,
360 16, 4),
361 MUX(CLK_MOUT_UART_ISP, "mout_uart_isp", group_fimc_lclk_p, SRC_ISP,
362 12, 4),
363 MUX(CLK_MOUT_SPI1_ISP, "mout_spi1_isp", group_fimc_lclk_p, SRC_ISP,
364 8, 4),
365 MUX(CLK_MOUT_SPI0_ISP, "mout_spi0_isp", group_fimc_lclk_p, SRC_ISP,
366 4, 4),
367 MUX(CLK_MOUT_PWM_ISP, "mout_pwm_isp", group_fimc_lclk_p, SRC_ISP,
368 0, 4),
369
370 /* SRC_MAUDIO */
371 MUX(CLK_MOUT_AUDIO0, "mout_audio0", group_sclk_audio0_p, SRC_MAUDIO,
372 0, 4),
373
374 /* SRC_FSYS */
375 MUX(CLK_MOUT_TSADC, "mout_tsadc", group_sclk_p, SRC_FSYS, 28, 4),
376 MUX(CLK_MOUT_MMC2, "mout_mmc2", group_sclk_p, SRC_FSYS, 8, 4),
377 MUX(CLK_MOUT_MMC1, "mout_mmc1", group_sclk_p, SRC_FSYS, 4, 4),
378 MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 4),
379
380 /* SRC_PERIL0 */
381 MUX(CLK_MOUT_UART3, "mout_uart3", group_sclk_p, SRC_PERIL0, 12, 4),
382 MUX(CLK_MOUT_UART2, "mout_uart2", group_sclk_p, SRC_PERIL0, 8, 4),
383 MUX(CLK_MOUT_UART1, "mout_uart1", group_sclk_p, SRC_PERIL0, 4, 4),
384 MUX(CLK_MOUT_UART0, "mout_uart0", group_sclk_p, SRC_PERIL0, 0, 4),
385
386 /* SRC_PERIL1 */
387 MUX(CLK_MOUT_SPI2, "mout_spi2", group_sclk_p, SRC_PERIL1, 24, 4),
388 MUX(CLK_MOUT_SPI1, "mout_spi1", group_sclk_p, SRC_PERIL1, 20, 4),
389 MUX(CLK_MOUT_SPI0, "mout_spi0", group_sclk_p, SRC_PERIL1, 16, 4),
390 MUX(CLK_MOUT_SPDIF, "mout_spdif", group_spdif_p, SRC_PERIL1, 8, 4),
391 MUX(CLK_MOUT_AUDIO2, "mout_audio2", group_sclk_audio2_p, SRC_PERIL1,
392 4, 4),
393 MUX(CLK_MOUT_AUDIO1, "mout_audio1", group_sclk_audio1_p, SRC_PERIL1,
394 0, 4),
395
396 /* SRC_CPU */
397 MUX(CLK_MOUT_MPLL_USER_C, "mout_mpll_user_c", mout_mpll_user_p,
398 SRC_CPU, 24, 1),
399 MUX(CLK_MOUT_HPM, "mout_hpm", mout_hpm_p, SRC_CPU, 20, 1),
400 MUX_F(CLK_MOUT_CORE, "mout_core", mout_core_p, SRC_CPU, 16, 1, 0,
401 CLK_MUX_READ_ONLY),
402 MUX_F(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
403 CLK_SET_RATE_PARENT, 0),
404
405 /* SRC_CAM1 */
406 MUX(CLK_MOUT_PXLASYNC_CSIS1_FIMC, "mout_pxlasync_csis1",
407 group_fimc_lclk_p, SRC_CAM1, 20, 1),
408 MUX(CLK_MOUT_PXLASYNC_CSIS0_FIMC, "mout_pxlasync_csis0",
409 group_fimc_lclk_p, SRC_CAM1, 16, 1),
410 MUX(CLK_MOUT_JPEG, "mout_jpeg", mout_jpeg_p, SRC_CAM1, 8, 1),
411 MUX(CLK_MOUT_JPEG1, "mout_jpeg_1", mout_jpeg1_p, SRC_CAM1, 4, 1),
412 MUX(CLK_MOUT_JPEG0, "mout_jpeg_0", group_mout_mpll_user_t_p, SRC_CAM1,
413 0, 1),
414
415 /* SRC_TOP_ISP0 */
416 MUX(CLK_MOUT_ACLK_ISP0_300, "mout_aclk_isp0_300",
417 group_aclk_isp0_300_p, SRC_TOP_ISP0, 8, 1),
418 MUX(CLK_MOUT_ACLK_ISP0_400, "mout_aclk_isp0_400_user",
419 group_aclk_isp0_400_user_p, SRC_TOP_ISP0, 4, 1),
420 MUX(CLK_MOUT_ACLK_ISP0_300_USER, "mout_aclk_isp0_300_user",
421 group_aclk_isp0_300_user_p, SRC_TOP_ISP0, 0, 1),
422
423 /* SRC_TOP_ISP1 */
424 MUX(CLK_MOUT_ACLK_ISP1_300, "mout_aclk_isp1_300",
425 group_aclk_isp0_300_p, SRC_TOP_ISP1, 4, 1),
426 MUX(CLK_MOUT_ACLK_ISP1_300_USER, "mout_aclk_isp1_300_user",
427 group_aclk_isp1_300_user_p, SRC_TOP_ISP1, 0, 1),
428};
429
430static const struct samsung_div_clock exynos4415_div_clks[] __initconst = {
431 /*
432 * NOTE: Following table is sorted by register address in ascending
433 * order and then bitfield shift in descending order, as it is done
434 * in the User's Manual. When adding new entries, please make sure
435 * that the order is preserved, to avoid merge conflicts and make
436 * further work with defined data easier.
437 */
438
439 /* DIV_LEFTBUS */
440 DIV(CLK_DIV_GPL, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3),
441 DIV(CLK_DIV_GDL, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 4),
442
443 /* DIV_RIGHTBUS */
444 DIV(CLK_DIV_GPR, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3),
445 DIV(CLK_DIV_GDR, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 4),
446
447 /* DIV_TOP */
448 DIV(CLK_DIV_ACLK_400_MCUISP, "div_aclk_400_mcuisp",
449 "mout_aclk_400_mcuisp", DIV_TOP, 24, 3),
450 DIV(CLK_DIV_EBI, "div_ebi", "mout_ebi_1", DIV_TOP, 16, 3),
451 DIV(CLK_DIV_ACLK_200, "div_aclk_200", "mout_aclk_200", DIV_TOP, 12, 3),
452 DIV(CLK_DIV_ACLK_160, "div_aclk_160", "mout_aclk_160", DIV_TOP, 8, 3),
453 DIV(CLK_DIV_ACLK_100, "div_aclk_100", "mout_aclk_100", DIV_TOP, 4, 4),
454 DIV(CLK_DIV_ACLK_266, "div_aclk_266", "mout_aclk_266", DIV_TOP, 0, 3),
455
456 /* DIV_CAM */
457 DIV(CLK_DIV_CSIS1, "div_csis1", "mout_csis1", DIV_CAM, 28, 4),
458 DIV(CLK_DIV_CSIS0, "div_csis0", "mout_csis0", DIV_CAM, 24, 4),
459 DIV(CLK_DIV_CAM1, "div_cam1", "mout_cam1", DIV_CAM, 20, 4),
460 DIV(CLK_DIV_FIMC3_LCLK, "div_fimc3_lclk", "mout_fimc3_lclk", DIV_CAM,
461 12, 4),
462 DIV(CLK_DIV_FIMC2_LCLK, "div_fimc2_lclk", "mout_fimc2_lclk", DIV_CAM,
463 8, 4),
464 DIV(CLK_DIV_FIMC1_LCLK, "div_fimc1_lclk", "mout_fimc1_lclk", DIV_CAM,
465 4, 4),
466 DIV(CLK_DIV_FIMC0_LCLK, "div_fimc0_lclk", "mout_fimc0_lclk", DIV_CAM,
467 0, 4),
468
469 /* DIV_TV */
470 DIV(CLK_DIV_TV_BLK, "div_tv_blk", "mout_g3d_pll", DIV_TV, 0, 4),
471
472 /* DIV_MFC */
473 DIV(CLK_DIV_MFC, "div_mfc", "mout_mfc", DIV_MFC, 0, 4),
474
475 /* DIV_G3D */
476 DIV(CLK_DIV_G3D, "div_g3d", "mout_g3d", DIV_G3D, 0, 4),
477
478 /* DIV_LCD */
479 DIV_F(CLK_DIV_MIPI0_PRE, "div_mipi0_pre", "div_mipi0", DIV_LCD, 20, 4,
480 CLK_SET_RATE_PARENT, 0),
481 DIV(CLK_DIV_MIPI0, "div_mipi0", "mout_mipi0", DIV_LCD, 16, 4),
482 DIV(CLK_DIV_FIMD0, "div_fimd0", "mout_fimd0", DIV_LCD, 0, 4),
483
484 /* DIV_ISP */
485 DIV(CLK_DIV_UART_ISP, "div_uart_isp", "mout_uart_isp", DIV_ISP, 28, 4),
486 DIV_F(CLK_DIV_SPI1_ISP_PRE, "div_spi1_isp_pre", "div_spi1_isp",
487 DIV_ISP, 20, 8, CLK_SET_RATE_PARENT, 0),
488 DIV(CLK_DIV_SPI1_ISP, "div_spi1_isp", "mout_spi1_isp", DIV_ISP, 16, 4),
489 DIV_F(CLK_DIV_SPI0_ISP_PRE, "div_spi0_isp_pre", "div_spi0_isp",
490 DIV_ISP, 8, 8, CLK_SET_RATE_PARENT, 0),
491 DIV(CLK_DIV_SPI0_ISP, "div_spi0_isp", "mout_spi0_isp", DIV_ISP, 4, 4),
492 DIV(CLK_DIV_PWM_ISP, "div_pwm_isp", "mout_pwm_isp", DIV_ISP, 0, 4),
493
494 /* DIV_MAUDIO */
495 DIV(CLK_DIV_PCM0, "div_pcm0", "div_audio0", DIV_MAUDIO, 4, 8),
496 DIV(CLK_DIV_AUDIO0, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4),
497
498 /* DIV_FSYS0 */
499 DIV_F(CLK_DIV_TSADC_PRE, "div_tsadc_pre", "div_tsadc", DIV_FSYS0, 8, 8,
500 CLK_SET_RATE_PARENT, 0),
501 DIV(CLK_DIV_TSADC, "div_tsadc", "mout_tsadc", DIV_FSYS0, 0, 4),
502
503 /* DIV_FSYS1 */
504 DIV_F(CLK_DIV_MMC1_PRE, "div_mmc1_pre", "div_mmc1", DIV_FSYS1, 24, 8,
505 CLK_SET_RATE_PARENT, 0),
506 DIV(CLK_DIV_MMC1, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4),
507 DIV_F(CLK_DIV_MMC0_PRE, "div_mmc0_pre", "div_mmc0", DIV_FSYS1, 8, 8,
508 CLK_SET_RATE_PARENT, 0),
509 DIV(CLK_DIV_MMC0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
510
511 /* DIV_FSYS2 */
512 DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2_pre", "div_mmc2", DIV_FSYS2, 8, 8,
513 CLK_SET_RATE_PARENT, 0),
514 DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4,
515 CLK_SET_RATE_PARENT, 0),
516
517 /* DIV_PERIL0 */
518 DIV(CLK_DIV_UART3, "div_uart3", "mout_uart3", DIV_PERIL0, 12, 4),
519 DIV(CLK_DIV_UART2, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4),
520 DIV(CLK_DIV_UART1, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4),
521 DIV(CLK_DIV_UART0, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4),
522
523 /* DIV_PERIL1 */
524 DIV_F(CLK_DIV_SPI1_PRE, "div_spi1_pre", "div_spi1", DIV_PERIL1, 24, 8,
525 CLK_SET_RATE_PARENT, 0),
526 DIV(CLK_DIV_SPI1, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4),
527 DIV_F(CLK_DIV_SPI0_PRE, "div_spi0_pre", "div_spi0", DIV_PERIL1, 8, 8,
528 CLK_SET_RATE_PARENT, 0),
529 DIV(CLK_DIV_SPI0, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4),
530
531 /* DIV_PERIL2 */
532 DIV_F(CLK_DIV_SPI2_PRE, "div_spi2_pre", "div_spi2", DIV_PERIL2, 8, 8,
533 CLK_SET_RATE_PARENT, 0),
534 DIV(CLK_DIV_SPI2, "div_spi2", "mout_spi2", DIV_PERIL2, 0, 4),
535
536 /* DIV_PERIL4 */
537 DIV(CLK_DIV_PCM2, "div_pcm2", "div_audio2", DIV_PERIL4, 20, 8),
538 DIV(CLK_DIV_AUDIO2, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4),
539 DIV(CLK_DIV_PCM1, "div_pcm1", "div_audio1", DIV_PERIL4, 20, 8),
540 DIV(CLK_DIV_AUDIO1, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4),
541
542 /* DIV_PERIL5 */
543 DIV(CLK_DIV_I2S1, "div_i2s1", "div_audio1", DIV_PERIL5, 0, 6),
544
545 /* DIV_CAM1 */
546 DIV(CLK_DIV_PXLASYNC_CSIS1_FIMC, "div_pxlasync_csis1_fimc",
547 "mout_pxlasync_csis1", DIV_CAM1, 24, 4),
548 DIV(CLK_DIV_PXLASYNC_CSIS0_FIMC, "div_pxlasync_csis0_fimc",
549 "mout_pxlasync_csis0", DIV_CAM1, 20, 4),
550 DIV(CLK_DIV_JPEG, "div_jpeg", "mout_jpeg", DIV_CAM1, 0, 4),
551
552 /* DIV_CPU0 */
553 DIV(CLK_DIV_CORE2, "div_core2", "div_core", DIV_CPU0, 28, 3),
554 DIV_F(CLK_DIV_APLL, "div_apll", "mout_apll", DIV_CPU0, 24, 3,
555 CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
556 DIV(CLK_DIV_PCLK_DBG, "div_pclk_dbg", "div_core2", DIV_CPU0, 20, 3),
557 DIV(CLK_DIV_ATB, "div_atb", "div_core2", DIV_CPU0, 16, 3),
558 DIV(CLK_DIV_PERIPH, "div_periph", "div_core2", DIV_CPU0, 12, 3),
559 DIV(CLK_DIV_COREM1, "div_corem1", "div_core2", DIV_CPU0, 8, 3),
560 DIV(CLK_DIV_COREM0, "div_corem0", "div_core2", DIV_CPU0, 4, 3),
561 DIV_F(CLK_DIV_CORE, "div_core", "mout_core", DIV_CPU0, 0, 3,
562 CLK_GET_RATE_NOCACHE, CLK_DIVIDER_READ_ONLY),
563
564 /* DIV_CPU1 */
565 DIV(CLK_DIV_HPM, "div_hpm", "div_copy", DIV_CPU1, 4, 3),
566 DIV(CLK_DIV_COPY, "div_copy", "mout_hpm", DIV_CPU1, 0, 3),
567};
568
569static const struct samsung_gate_clock exynos4415_gate_clks[] __initconst = {
570 /*
571 * NOTE: Following table is sorted by register address in ascending
572 * order and then bitfield shift in descending order, as it is done
573 * in the User's Manual. When adding new entries, please make sure
574 * that the order is preserved, to avoid merge conflicts and make
575 * further work with defined data easier.
576 */
577
578 /* GATE_IP_LEFTBUS */
579 GATE(CLK_ASYNC_G3D, "async_g3d", "div_aclk_100", GATE_IP_LEFTBUS, 6,
580 CLK_IGNORE_UNUSED, 0),
581 GATE(CLK_ASYNC_MFCL, "async_mfcl", "div_aclk_100", GATE_IP_LEFTBUS, 4,
582 CLK_IGNORE_UNUSED, 0),
583 GATE(CLK_ASYNC_TVX, "async_tvx", "div_aclk_100", GATE_IP_LEFTBUS, 3,
584 CLK_IGNORE_UNUSED, 0),
585 GATE(CLK_PPMULEFT, "ppmuleft", "div_aclk_100", GATE_IP_LEFTBUS, 1,
586 CLK_IGNORE_UNUSED, 0),
587 GATE(CLK_GPIO_LEFT, "gpio_left", "div_aclk_100", GATE_IP_LEFTBUS, 0,
588 CLK_IGNORE_UNUSED, 0),
589
590 /* GATE_IP_IMAGE */
591 GATE(CLK_PPMUIMAGE, "ppmuimage", "div_aclk_100", GATE_IP_IMAGE,
592 9, 0, 0),
593 GATE(CLK_QEMDMA2, "qe_mdma2", "div_aclk_100", GATE_IP_IMAGE,
594 8, 0, 0),
595 GATE(CLK_QEROTATOR, "qe_rotator", "div_aclk_100", GATE_IP_IMAGE,
596 7, 0, 0),
597 GATE(CLK_SMMUMDMA2, "smmu_mdam2", "div_aclk_100", GATE_IP_IMAGE,
598 5, 0, 0),
599 GATE(CLK_SMMUROTATOR, "smmu_rotator", "div_aclk_100", GATE_IP_IMAGE,
600 4, 0, 0),
601 GATE(CLK_MDMA2, "mdma2", "div_aclk_100", GATE_IP_IMAGE, 2, 0, 0),
602 GATE(CLK_ROTATOR, "rotator", "div_aclk_100", GATE_IP_IMAGE, 1, 0, 0),
603
604 /* GATE_IP_RIGHTBUS */
605 GATE(CLK_ASYNC_ISPMX, "async_ispmx", "div_aclk_100",
606 GATE_IP_RIGHTBUS, 9, CLK_IGNORE_UNUSED, 0),
607 GATE(CLK_ASYNC_MAUDIOX, "async_maudiox", "div_aclk_100",
608 GATE_IP_RIGHTBUS, 7, CLK_IGNORE_UNUSED, 0),
609 GATE(CLK_ASYNC_MFCR, "async_mfcr", "div_aclk_100",
610 GATE_IP_RIGHTBUS, 6, CLK_IGNORE_UNUSED, 0),
611 GATE(CLK_ASYNC_FSYSD, "async_fsysd", "div_aclk_100",
612 GATE_IP_RIGHTBUS, 5, CLK_IGNORE_UNUSED, 0),
613 GATE(CLK_ASYNC_LCD0X, "async_lcd0x", "div_aclk_100",
614 GATE_IP_RIGHTBUS, 3, CLK_IGNORE_UNUSED, 0),
615 GATE(CLK_ASYNC_CAMX, "async_camx", "div_aclk_100",
616 GATE_IP_RIGHTBUS, 2, CLK_IGNORE_UNUSED, 0),
617 GATE(CLK_PPMURIGHT, "ppmuright", "div_aclk_100",
618 GATE_IP_RIGHTBUS, 1, CLK_IGNORE_UNUSED, 0),
619 GATE(CLK_GPIO_RIGHT, "gpio_right", "div_aclk_100",
620 GATE_IP_RIGHTBUS, 0, CLK_IGNORE_UNUSED, 0),
621
622 /* GATE_IP_PERIR */
623 GATE(CLK_ANTIRBK_APBIF, "antirbk_apbif", "div_aclk_100",
624 GATE_IP_PERIR, 24, CLK_IGNORE_UNUSED, 0),
625 GATE(CLK_EFUSE_WRITER_APBIF, "efuse_writer_apbif", "div_aclk_100",
626 GATE_IP_PERIR, 23, CLK_IGNORE_UNUSED, 0),
627 GATE(CLK_MONOCNT, "monocnt", "div_aclk_100", GATE_IP_PERIR, 22,
628 CLK_IGNORE_UNUSED, 0),
629 GATE(CLK_TZPC6, "tzpc6", "div_aclk_100", GATE_IP_PERIR, 21,
630 CLK_IGNORE_UNUSED, 0),
631 GATE(CLK_PROVISIONKEY1, "provisionkey1", "div_aclk_100",
632 GATE_IP_PERIR, 20, CLK_IGNORE_UNUSED, 0),
633 GATE(CLK_PROVISIONKEY0, "provisionkey0", "div_aclk_100",
634 GATE_IP_PERIR, 19, CLK_IGNORE_UNUSED, 0),
635 GATE(CLK_CMU_ISPPART, "cmu_isppart", "div_aclk_100", GATE_IP_PERIR, 18,
636 CLK_IGNORE_UNUSED, 0),
637 GATE(CLK_TMU_APBIF, "tmu_apbif", "div_aclk_100",
638 GATE_IP_PERIR, 17, 0, 0),
639 GATE(CLK_KEYIF, "keyif", "div_aclk_100", GATE_IP_PERIR, 16, 0, 0),
640 GATE(CLK_RTC, "rtc", "div_aclk_100", GATE_IP_PERIR, 15, 0, 0),
641 GATE(CLK_WDT, "wdt", "div_aclk_100", GATE_IP_PERIR, 14, 0, 0),
642 GATE(CLK_MCT, "mct", "div_aclk_100", GATE_IP_PERIR, 13, 0, 0),
643 GATE(CLK_SECKEY, "seckey", "div_aclk_100", GATE_IP_PERIR, 12,
644 CLK_IGNORE_UNUSED, 0),
645 GATE(CLK_HDMI_CEC, "hdmi_cec", "div_aclk_100", GATE_IP_PERIR, 11,
646 CLK_IGNORE_UNUSED, 0),
647 GATE(CLK_TZPC5, "tzpc5", "div_aclk_100", GATE_IP_PERIR, 10,
648 CLK_IGNORE_UNUSED, 0),
649 GATE(CLK_TZPC4, "tzpc4", "div_aclk_100", GATE_IP_PERIR, 9,
650 CLK_IGNORE_UNUSED, 0),
651 GATE(CLK_TZPC3, "tzpc3", "div_aclk_100", GATE_IP_PERIR, 8,
652 CLK_IGNORE_UNUSED, 0),
653 GATE(CLK_TZPC2, "tzpc2", "div_aclk_100", GATE_IP_PERIR, 7,
654 CLK_IGNORE_UNUSED, 0),
655 GATE(CLK_TZPC1, "tzpc1", "div_aclk_100", GATE_IP_PERIR, 6,
656 CLK_IGNORE_UNUSED, 0),
657 GATE(CLK_TZPC0, "tzpc0", "div_aclk_100", GATE_IP_PERIR, 5,
658 CLK_IGNORE_UNUSED, 0),
659 GATE(CLK_CMU_COREPART, "cmu_corepart", "div_aclk_100", GATE_IP_PERIR, 4,
660 CLK_IGNORE_UNUSED, 0),
661 GATE(CLK_CMU_TOPPART, "cmu_toppart", "div_aclk_100", GATE_IP_PERIR, 3,
662 CLK_IGNORE_UNUSED, 0),
663 GATE(CLK_PMU_APBIF, "pmu_apbif", "div_aclk_100", GATE_IP_PERIR, 2,
664 CLK_IGNORE_UNUSED, 0),
665 GATE(CLK_SYSREG, "sysreg", "div_aclk_100", GATE_IP_PERIR, 1,
666 CLK_IGNORE_UNUSED, 0),
667 GATE(CLK_CHIP_ID, "chip_id", "div_aclk_100", GATE_IP_PERIR, 0,
668 CLK_IGNORE_UNUSED, 0),
669
670 /* GATE_SCLK_CAM - non-completed */
671 GATE(CLK_SCLK_PXLAYSNC_CSIS1_FIMC, "sclk_pxlasync_csis1_fimc",
672 "div_pxlasync_csis1_fimc", GATE_SCLK_CAM, 11,
673 CLK_SET_RATE_PARENT, 0),
674 GATE(CLK_SCLK_PXLAYSNC_CSIS0_FIMC, "sclk_pxlasync_csis0_fimc",
675 "div_pxlasync_csis0_fimc", GATE_SCLK_CAM,
676 10, CLK_SET_RATE_PARENT, 0),
677 GATE(CLK_SCLK_JPEG, "sclk_jpeg", "div_jpeg",
678 GATE_SCLK_CAM, 8, CLK_SET_RATE_PARENT, 0),
679 GATE(CLK_SCLK_CSIS1, "sclk_csis1", "div_csis1",
680 GATE_SCLK_CAM, 7, CLK_SET_RATE_PARENT, 0),
681 GATE(CLK_SCLK_CSIS0, "sclk_csis0", "div_csis0",
682 GATE_SCLK_CAM, 6, CLK_SET_RATE_PARENT, 0),
683 GATE(CLK_SCLK_CAM1, "sclk_cam1", "div_cam1",
684 GATE_SCLK_CAM, 5, CLK_SET_RATE_PARENT, 0),
685 GATE(CLK_SCLK_FIMC3_LCLK, "sclk_fimc3_lclk", "div_fimc3_lclk",
686 GATE_SCLK_CAM, 3, CLK_SET_RATE_PARENT, 0),
687 GATE(CLK_SCLK_FIMC2_LCLK, "sclk_fimc2_lclk", "div_fimc2_lclk",
688 GATE_SCLK_CAM, 2, CLK_SET_RATE_PARENT, 0),
689 GATE(CLK_SCLK_FIMC1_LCLK, "sclk_fimc1_lclk", "div_fimc1_lclk",
690 GATE_SCLK_CAM, 1, CLK_SET_RATE_PARENT, 0),
691 GATE(CLK_SCLK_FIMC0_LCLK, "sclk_fimc0_lclk", "div_fimc0_lclk",
692 GATE_SCLK_CAM, 0, CLK_SET_RATE_PARENT, 0),
693
694 /* GATE_SCLK_TV */
695 GATE(CLK_SCLK_PIXEL, "sclk_pixel", "div_tv_blk",
696 GATE_SCLK_TV, 3, CLK_SET_RATE_PARENT, 0),
697 GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi",
698 GATE_SCLK_TV, 2, CLK_SET_RATE_PARENT, 0),
699 GATE(CLK_SCLK_MIXER, "sclk_mixer", "div_tv_blk",
700 GATE_SCLK_TV, 0, CLK_SET_RATE_PARENT, 0),
701
702 /* GATE_SCLK_MFC */
703 GATE(CLK_SCLK_MFC, "sclk_mfc", "div_mfc",
704 GATE_SCLK_MFC, 0, CLK_SET_RATE_PARENT, 0),
705
706 /* GATE_SCLK_G3D */
707 GATE(CLK_SCLK_G3D, "sclk_g3d", "div_g3d",
708 GATE_SCLK_G3D, 0, CLK_SET_RATE_PARENT, 0),
709
710 /* GATE_SCLK_LCD */
711 GATE(CLK_SCLK_MIPIDPHY4L, "sclk_mipidphy4l", "div_mipi0",
712 GATE_SCLK_LCD, 4, CLK_SET_RATE_PARENT, 0),
713 GATE(CLK_SCLK_MIPI0, "sclk_mipi0", "div_mipi0_pre",
714 GATE_SCLK_LCD, 3, CLK_SET_RATE_PARENT, 0),
715 GATE(CLK_SCLK_MDNIE0, "sclk_mdnie0", "div_fimd0",
716 GATE_SCLK_LCD, 1, CLK_SET_RATE_PARENT, 0),
717 GATE(CLK_SCLK_FIMD0, "sclk_fimd0", "div_fimd0",
718 GATE_SCLK_LCD, 0, CLK_SET_RATE_PARENT, 0),
719
720 /* GATE_SCLK_MAUDIO */
721 GATE(CLK_SCLK_PCM0, "sclk_pcm0", "div_pcm0",
722 GATE_SCLK_MAUDIO, 1, CLK_SET_RATE_PARENT, 0),
723 GATE(CLK_SCLK_AUDIO0, "sclk_audio0", "div_audio0",
724 GATE_SCLK_MAUDIO, 0, CLK_SET_RATE_PARENT, 0),
725
726 /* GATE_SCLK_FSYS */
727 GATE(CLK_SCLK_TSADC, "sclk_tsadc", "div_tsadc_pre",
728 GATE_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0),
729 GATE(CLK_SCLK_EBI, "sclk_ebi", "div_ebi",
730 GATE_SCLK_FSYS, 6, CLK_SET_RATE_PARENT, 0),
731 GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc2_pre",
732 GATE_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0),
733 GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc1_pre",
734 GATE_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0),
735 GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc0_pre",
736 GATE_SCLK_FSYS, 0, CLK_SET_RATE_PARENT, 0),
737
738 /* GATE_SCLK_PERIL */
739 GATE(CLK_SCLK_I2S, "sclk_i2s1", "div_i2s1",
740 GATE_SCLK_PERIL, 18, CLK_SET_RATE_PARENT, 0),
741 GATE(CLK_SCLK_PCM2, "sclk_pcm2", "div_pcm2",
742 GATE_SCLK_PERIL, 16, CLK_SET_RATE_PARENT, 0),
743 GATE(CLK_SCLK_PCM1, "sclk_pcm1", "div_pcm1",
744 GATE_SCLK_PERIL, 15, CLK_SET_RATE_PARENT, 0),
745 GATE(CLK_SCLK_AUDIO2, "sclk_audio2", "div_audio2",
746 GATE_SCLK_PERIL, 14, CLK_SET_RATE_PARENT, 0),
747 GATE(CLK_SCLK_AUDIO1, "sclk_audio1", "div_audio1",
748 GATE_SCLK_PERIL, 13, CLK_SET_RATE_PARENT, 0),
749 GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif",
750 GATE_SCLK_PERIL, 10, CLK_SET_RATE_PARENT, 0),
751 GATE(CLK_SCLK_SPI2, "sclk_spi2", "div_spi2_pre",
752 GATE_SCLK_PERIL, 8, CLK_SET_RATE_PARENT, 0),
753 GATE(CLK_SCLK_SPI1, "sclk_spi1", "div_spi1_pre",
754 GATE_SCLK_PERIL, 7, CLK_SET_RATE_PARENT, 0),
755 GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi0_pre",
756 GATE_SCLK_PERIL, 6, CLK_SET_RATE_PARENT, 0),
757 GATE(CLK_SCLK_UART3, "sclk_uart3", "div_uart3",
758 GATE_SCLK_PERIL, 3, CLK_SET_RATE_PARENT, 0),
759 GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2",
760 GATE_SCLK_PERIL, 2, CLK_SET_RATE_PARENT, 0),
761 GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1",
762 GATE_SCLK_PERIL, 1, CLK_SET_RATE_PARENT, 0),
763 GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0",
764 GATE_SCLK_PERIL, 0, CLK_SET_RATE_PARENT, 0),
765
766 /* GATE_IP_CAM */
767 GATE(CLK_SMMUFIMC_LITE2, "smmufimc_lite2", "div_aclk_160", GATE_IP_CAM,
768 22, CLK_IGNORE_UNUSED, 0),
769 GATE(CLK_FIMC_LITE2, "fimc_lite2", "div_aclk_160", GATE_IP_CAM,
770 20, CLK_IGNORE_UNUSED, 0),
771 GATE(CLK_PIXELASYNCM1, "pixelasyncm1", "div_aclk_160", GATE_IP_CAM,
772 18, CLK_IGNORE_UNUSED, 0),
773 GATE(CLK_PIXELASYNCM0, "pixelasyncm0", "div_aclk_160", GATE_IP_CAM,
774 17, CLK_IGNORE_UNUSED, 0),
775 GATE(CLK_PPMUCAMIF, "ppmucamif", "div_aclk_160", GATE_IP_CAM,
776 16, CLK_IGNORE_UNUSED, 0),
777 GATE(CLK_SMMUJPEG, "smmujpeg", "div_aclk_160", GATE_IP_CAM, 11, 0, 0),
778 GATE(CLK_SMMUFIMC3, "smmufimc3", "div_aclk_160", GATE_IP_CAM, 10, 0, 0),
779 GATE(CLK_SMMUFIMC2, "smmufimc2", "div_aclk_160", GATE_IP_CAM, 9, 0, 0),
780 GATE(CLK_SMMUFIMC1, "smmufimc1", "div_aclk_160", GATE_IP_CAM, 8, 0, 0),
781 GATE(CLK_SMMUFIMC0, "smmufimc0", "div_aclk_160", GATE_IP_CAM, 7, 0, 0),
782 GATE(CLK_JPEG, "jpeg", "div_aclk_160", GATE_IP_CAM, 6, 0, 0),
783 GATE(CLK_CSIS1, "csis1", "div_aclk_160", GATE_IP_CAM, 5, 0, 0),
784 GATE(CLK_CSIS0, "csis0", "div_aclk_160", GATE_IP_CAM, 4, 0, 0),
785 GATE(CLK_FIMC3, "fimc3", "div_aclk_160", GATE_IP_CAM, 3, 0, 0),
786 GATE(CLK_FIMC2, "fimc2", "div_aclk_160", GATE_IP_CAM, 2, 0, 0),
787 GATE(CLK_FIMC1, "fimc1", "div_aclk_160", GATE_IP_CAM, 1, 0, 0),
788 GATE(CLK_FIMC0, "fimc0", "div_aclk_160", GATE_IP_CAM, 0, 0, 0),
789
790 /* GATE_IP_TV */
791 GATE(CLK_PPMUTV, "ppmutv", "div_aclk_100", GATE_IP_TV, 5, 0, 0),
792 GATE(CLK_SMMUTV, "smmutv", "div_aclk_100", GATE_IP_TV, 4, 0, 0),
793 GATE(CLK_HDMI, "hdmi", "div_aclk_100", GATE_IP_TV, 3, 0, 0),
794 GATE(CLK_MIXER, "mixer", "div_aclk_100", GATE_IP_TV, 1, 0, 0),
795 GATE(CLK_VP, "vp", "div_aclk_100", GATE_IP_TV, 0, 0, 0),
796
797 /* GATE_IP_MFC */
798 GATE(CLK_PPMUMFC_R, "ppmumfc_r", "div_aclk_200", GATE_IP_MFC, 4,
799 CLK_IGNORE_UNUSED, 0),
800 GATE(CLK_PPMUMFC_L, "ppmumfc_l", "div_aclk_200", GATE_IP_MFC, 3,
801 CLK_IGNORE_UNUSED, 0),
802 GATE(CLK_SMMUMFC_R, "smmumfc_r", "div_aclk_200", GATE_IP_MFC, 2, 0, 0),
803 GATE(CLK_SMMUMFC_L, "smmumfc_l", "div_aclk_200", GATE_IP_MFC, 1, 0, 0),
804 GATE(CLK_MFC, "mfc", "div_aclk_200", GATE_IP_MFC, 0, 0, 0),
805
806 /* GATE_IP_G3D */
807 GATE(CLK_PPMUG3D, "ppmug3d", "div_aclk_200", GATE_IP_G3D, 1,
808 CLK_IGNORE_UNUSED, 0),
809 GATE(CLK_G3D, "g3d", "div_aclk_200", GATE_IP_G3D, 0, 0, 0),
810
811 /* GATE_IP_LCD */
812 GATE(CLK_PPMULCD0, "ppmulcd0", "div_aclk_160", GATE_IP_LCD, 5,
813 CLK_IGNORE_UNUSED, 0),
814 GATE(CLK_SMMUFIMD0, "smmufimd0", "div_aclk_160", GATE_IP_LCD, 4, 0, 0),
815 GATE(CLK_DSIM0, "dsim0", "div_aclk_160", GATE_IP_LCD, 3, 0, 0),
816 GATE(CLK_SMIES, "smies", "div_aclk_160", GATE_IP_LCD, 2, 0, 0),
817 GATE(CLK_MIE0, "mie0", "div_aclk_160", GATE_IP_LCD, 1, 0, 0),
818 GATE(CLK_FIMD0, "fimd0", "div_aclk_160", GATE_IP_LCD, 0, 0, 0),
819
820 /* GATE_IP_FSYS */
821 GATE(CLK_TSADC, "tsadc", "div_aclk_200", GATE_IP_FSYS, 20, 0, 0),
822 GATE(CLK_PPMUFILE, "ppmufile", "div_aclk_200", GATE_IP_FSYS, 17,
823 CLK_IGNORE_UNUSED, 0),
824 GATE(CLK_NFCON, "nfcon", "div_aclk_200", GATE_IP_FSYS, 16, 0, 0),
825 GATE(CLK_USBDEVICE, "usbdevice", "div_aclk_200", GATE_IP_FSYS, 13,
826 0, 0),
827 GATE(CLK_USBHOST, "usbhost", "div_aclk_200", GATE_IP_FSYS, 12, 0, 0),
828 GATE(CLK_SROMC, "sromc", "div_aclk_200", GATE_IP_FSYS, 11, 0, 0),
829 GATE(CLK_SDMMC2, "sdmmc2", "div_aclk_200", GATE_IP_FSYS, 7, 0, 0),
830 GATE(CLK_SDMMC1, "sdmmc1", "div_aclk_200", GATE_IP_FSYS, 6, 0, 0),
831 GATE(CLK_SDMMC0, "sdmmc0", "div_aclk_200", GATE_IP_FSYS, 5, 0, 0),
832 GATE(CLK_PDMA1, "pdma1", "div_aclk_200", GATE_IP_FSYS, 1, 0, 0),
833 GATE(CLK_PDMA0, "pdma0", "div_aclk_200", GATE_IP_FSYS, 0, 0, 0),
834
835 /* GATE_IP_PERIL */
836 GATE(CLK_SPDIF, "spdif", "div_aclk_100", GATE_IP_PERIL, 26, 0, 0),
837 GATE(CLK_PWM, "pwm", "div_aclk_100", GATE_IP_PERIL, 24, 0, 0),
838 GATE(CLK_PCM2, "pcm2", "div_aclk_100", GATE_IP_PERIL, 23, 0, 0),
839 GATE(CLK_PCM1, "pcm1", "div_aclk_100", GATE_IP_PERIL, 22, 0, 0),
840 GATE(CLK_I2S1, "i2s1", "div_aclk_100", GATE_IP_PERIL, 20, 0, 0),
841 GATE(CLK_SPI2, "spi2", "div_aclk_100", GATE_IP_PERIL, 18, 0, 0),
842 GATE(CLK_SPI1, "spi1", "div_aclk_100", GATE_IP_PERIL, 17, 0, 0),
843 GATE(CLK_SPI0, "spi0", "div_aclk_100", GATE_IP_PERIL, 16, 0, 0),
844 GATE(CLK_I2CHDMI, "i2chdmi", "div_aclk_100", GATE_IP_PERIL, 14, 0, 0),
845 GATE(CLK_I2C7, "i2c7", "div_aclk_100", GATE_IP_PERIL, 13, 0, 0),
846 GATE(CLK_I2C6, "i2c6", "div_aclk_100", GATE_IP_PERIL, 12, 0, 0),
847 GATE(CLK_I2C5, "i2c5", "div_aclk_100", GATE_IP_PERIL, 11, 0, 0),
848 GATE(CLK_I2C4, "i2c4", "div_aclk_100", GATE_IP_PERIL, 10, 0, 0),
849 GATE(CLK_I2C3, "i2c3", "div_aclk_100", GATE_IP_PERIL, 9, 0, 0),
850 GATE(CLK_I2C2, "i2c2", "div_aclk_100", GATE_IP_PERIL, 8, 0, 0),
851 GATE(CLK_I2C1, "i2c1", "div_aclk_100", GATE_IP_PERIL, 7, 0, 0),
852 GATE(CLK_I2C0, "i2c0", "div_aclk_100", GATE_IP_PERIL, 6, 0, 0),
853 GATE(CLK_UART3, "uart3", "div_aclk_100", GATE_IP_PERIL, 3, 0, 0),
854 GATE(CLK_UART2, "uart2", "div_aclk_100", GATE_IP_PERIL, 2, 0, 0),
855 GATE(CLK_UART1, "uart1", "div_aclk_100", GATE_IP_PERIL, 1, 0, 0),
856 GATE(CLK_UART0, "uart0", "div_aclk_100", GATE_IP_PERIL, 0, 0, 0),
857};
858
859/*
860 * APLL & MPLL & BPLL & ISP_PLL & DISP_PLL & G3D_PLL
861 */
862static const struct samsung_pll_rate_table exynos4415_pll_rates[] __initconst = {
863 PLL_35XX_RATE(1600000000, 400, 3, 1),
864 PLL_35XX_RATE(1500000000, 250, 2, 1),
865 PLL_35XX_RATE(1400000000, 175, 3, 0),
866 PLL_35XX_RATE(1300000000, 325, 3, 1),
867 PLL_35XX_RATE(1200000000, 400, 4, 1),
868 PLL_35XX_RATE(1100000000, 275, 3, 1),
869 PLL_35XX_RATE(1066000000, 533, 6, 1),
870 PLL_35XX_RATE(1000000000, 250, 3, 1),
871 PLL_35XX_RATE(960000000, 320, 4, 1),
872 PLL_35XX_RATE(900000000, 300, 4, 1),
873 PLL_35XX_RATE(850000000, 425, 6, 1),
874 PLL_35XX_RATE(800000000, 200, 3, 1),
875 PLL_35XX_RATE(700000000, 175, 3, 1),
876 PLL_35XX_RATE(667000000, 667, 12, 1),
877 PLL_35XX_RATE(600000000, 400, 4, 2),
878 PLL_35XX_RATE(550000000, 275, 3, 2),
879 PLL_35XX_RATE(533000000, 533, 6, 2),
880 PLL_35XX_RATE(520000000, 260, 3, 2),
881 PLL_35XX_RATE(500000000, 250, 3, 2),
882 PLL_35XX_RATE(440000000, 220, 3, 2),
883 PLL_35XX_RATE(400000000, 200, 3, 2),
884 PLL_35XX_RATE(350000000, 175, 3, 2),
885 PLL_35XX_RATE(300000000, 300, 3, 3),
886 PLL_35XX_RATE(266000000, 266, 3, 3),
887 PLL_35XX_RATE(200000000, 200, 3, 3),
888 PLL_35XX_RATE(160000000, 160, 3, 3),
889 PLL_35XX_RATE(100000000, 200, 3, 4),
890 { /* sentinel */ }
891};
892
893/* EPLL */
894static const struct samsung_pll_rate_table exynos4415_epll_rates[] __initconst = {
895 PLL_36XX_RATE(800000000, 200, 3, 1, 0),
896 PLL_36XX_RATE(288000000, 96, 2, 2, 0),
897 PLL_36XX_RATE(192000000, 128, 2, 3, 0),
898 PLL_36XX_RATE(144000000, 96, 2, 3, 0),
899 PLL_36XX_RATE(96000000, 128, 2, 4, 0),
900 PLL_36XX_RATE(84000000, 112, 2, 4, 0),
901 PLL_36XX_RATE(80750011, 107, 2, 4, 43691),
902 PLL_36XX_RATE(73728004, 98, 2, 4, 19923),
903 PLL_36XX_RATE(67987602, 271, 3, 5, 62285),
904 PLL_36XX_RATE(65911004, 175, 2, 5, 49982),
905 PLL_36XX_RATE(50000000, 200, 3, 5, 0),
906 PLL_36XX_RATE(49152003, 131, 2, 5, 4719),
907 PLL_36XX_RATE(48000000, 128, 2, 5, 0),
908 PLL_36XX_RATE(45250000, 181, 3, 5, 0),
909 { /* sentinel */ }
910};
911
912static const struct samsung_pll_clock exynos4415_plls[] __initconst = {
913 PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
914 APLL_LOCK, APLL_CON0, exynos4415_pll_rates),
915 PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
916 EPLL_LOCK, EPLL_CON0, exynos4415_epll_rates),
917 PLL(pll_35xx, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "mout_g3d_pllsrc",
918 G3D_PLL_LOCK, G3D_PLL_CON0, exynos4415_pll_rates),
919 PLL(pll_35xx, CLK_FOUT_ISP_PLL, "fout_isp_pll", "fin_pll",
920 ISP_PLL_LOCK, ISP_PLL_CON0, exynos4415_pll_rates),
921 PLL(pll_35xx, CLK_FOUT_DISP_PLL, "fout_disp_pll",
922 "fin_pll", DISP_PLL_LOCK, DISP_PLL_CON0, exynos4415_pll_rates),
923};
924
925static const struct samsung_cmu_info cmu_info __initconst = {
926 .pll_clks = exynos4415_plls,
927 .nr_pll_clks = ARRAY_SIZE(exynos4415_plls),
928 .mux_clks = exynos4415_mux_clks,
929 .nr_mux_clks = ARRAY_SIZE(exynos4415_mux_clks),
930 .div_clks = exynos4415_div_clks,
931 .nr_div_clks = ARRAY_SIZE(exynos4415_div_clks),
932 .gate_clks = exynos4415_gate_clks,
933 .nr_gate_clks = ARRAY_SIZE(exynos4415_gate_clks),
934 .fixed_clks = exynos4415_fixed_rate_clks,
935 .nr_fixed_clks = ARRAY_SIZE(exynos4415_fixed_rate_clks),
936 .fixed_factor_clks = exynos4415_fixed_factor_clks,
937 .nr_fixed_factor_clks = ARRAY_SIZE(exynos4415_fixed_factor_clks),
938 .nr_clk_ids = CLK_NR_CLKS,
939 .clk_regs = exynos4415_cmu_clk_regs,
940 .nr_clk_regs = ARRAY_SIZE(exynos4415_cmu_clk_regs),
941};
942
943static void __init exynos4415_cmu_init(struct device_node *np)
944{
945 samsung_cmu_register_one(np, &cmu_info);
946}
947CLK_OF_DECLARE(exynos4415_cmu, "samsung,exynos4415-cmu", exynos4415_cmu_init);
948
949/*
950 * CMU DMC
951 */
952
953#define MPLL_LOCK 0x008
954#define MPLL_CON0 0x108
955#define MPLL_CON1 0x10c
956#define MPLL_CON2 0x110
957#define BPLL_LOCK 0x118
958#define BPLL_CON0 0x218
959#define BPLL_CON1 0x21c
960#define BPLL_CON2 0x220
961#define SRC_DMC 0x300
962#define DIV_DMC1 0x504
963
964static const unsigned long exynos4415_cmu_dmc_clk_regs[] __initconst = {
965 MPLL_LOCK,
966 MPLL_CON0,
967 MPLL_CON1,
968 MPLL_CON2,
969 BPLL_LOCK,
970 BPLL_CON0,
971 BPLL_CON1,
972 BPLL_CON2,
973 SRC_DMC,
974 DIV_DMC1,
975};
976
977PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
978PNAME(mout_bpll_p) = { "fin_pll", "fout_bpll", };
979PNAME(mbpll_p) = { "mout_mpll", "mout_bpll", };
980
981static const struct samsung_mux_clock exynos4415_dmc_mux_clks[] __initconst = {
982 MUX(CLK_DMC_MOUT_MPLL, "mout_mpll", mout_mpll_p, SRC_DMC, 12, 1),
983 MUX(CLK_DMC_MOUT_BPLL, "mout_bpll", mout_bpll_p, SRC_DMC, 10, 1),
984 MUX(CLK_DMC_MOUT_DPHY, "mout_dphy", mbpll_p, SRC_DMC, 8, 1),
985 MUX(CLK_DMC_MOUT_DMC_BUS, "mout_dmc_bus", mbpll_p, SRC_DMC, 4, 1),
986};
987
988static const struct samsung_div_clock exynos4415_dmc_div_clks[] __initconst = {
989 DIV(CLK_DMC_DIV_DMC, "div_dmc", "div_dmc_pre", DIV_DMC1, 27, 3),
990 DIV(CLK_DMC_DIV_DPHY, "div_dphy", "mout_dphy", DIV_DMC1, 23, 3),
991 DIV(CLK_DMC_DIV_DMC_PRE, "div_dmc_pre", "mout_dmc_bus",
992 DIV_DMC1, 19, 2),
993 DIV(CLK_DMC_DIV_DMCP, "div_dmcp", "div_dmcd", DIV_DMC1, 15, 3),
994 DIV(CLK_DMC_DIV_DMCD, "div_dmcd", "div_dmc", DIV_DMC1, 11, 3),
995 DIV(CLK_DMC_DIV_MPLL_PRE, "div_mpll_pre", "mout_mpll", DIV_DMC1, 8, 2),
996};
997
998static const struct samsung_pll_clock exynos4415_dmc_plls[] __initconst = {
999 PLL(pll_35xx, CLK_DMC_FOUT_MPLL, "fout_mpll", "fin_pll",
1000 MPLL_LOCK, MPLL_CON0, exynos4415_pll_rates),
1001 PLL(pll_35xx, CLK_DMC_FOUT_BPLL, "fout_bpll", "fin_pll",
1002 BPLL_LOCK, BPLL_CON0, exynos4415_pll_rates),
1003};
1004
1005static const struct samsung_cmu_info cmu_dmc_info __initconst = {
1006 .pll_clks = exynos4415_dmc_plls,
1007 .nr_pll_clks = ARRAY_SIZE(exynos4415_dmc_plls),
1008 .mux_clks = exynos4415_dmc_mux_clks,
1009 .nr_mux_clks = ARRAY_SIZE(exynos4415_dmc_mux_clks),
1010 .div_clks = exynos4415_dmc_div_clks,
1011 .nr_div_clks = ARRAY_SIZE(exynos4415_dmc_div_clks),
1012 .nr_clk_ids = NR_CLKS_DMC,
1013 .clk_regs = exynos4415_cmu_dmc_clk_regs,
1014 .nr_clk_regs = ARRAY_SIZE(exynos4415_cmu_dmc_clk_regs),
1015};
1016
1017static void __init exynos4415_cmu_dmc_init(struct device_node *np)
1018{
1019 samsung_cmu_register_one(np, &cmu_dmc_info);
1020}
1021CLK_OF_DECLARE(exynos4415_cmu_dmc, "samsung,exynos4415-cmu-dmc",
1022 exynos4415_cmu_dmc_init);
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index f096bd7df40c..11343a597093 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -6,7 +6,7 @@
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Common Clock Framework support for Exynos5443 SoC. 9 * Common Clock Framework support for Exynos5433 SoC.
10 */ 10 */
11 11
12#include <linux/clk-provider.h> 12#include <linux/clk-provider.h>
@@ -549,10 +549,10 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
549 29, CLK_IGNORE_UNUSED, 0), 549 29, CLK_IGNORE_UNUSED, 0),
550 GATE(CLK_ACLK_BUS0_400, "aclk_bus0_400", "div_aclk_bus0_400", 550 GATE(CLK_ACLK_BUS0_400, "aclk_bus0_400", "div_aclk_bus0_400",
551 ENABLE_ACLK_TOP, 26, 551 ENABLE_ACLK_TOP, 26,
552 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), 552 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
553 GATE(CLK_ACLK_BUS1_400, "aclk_bus1_400", "div_aclk_bus1_400", 553 GATE(CLK_ACLK_BUS1_400, "aclk_bus1_400", "div_aclk_bus1_400",
554 ENABLE_ACLK_TOP, 25, 554 ENABLE_ACLK_TOP, 25,
555 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), 555 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
556 GATE(CLK_ACLK_IMEM_200, "aclk_imem_200", "div_aclk_imem_266", 556 GATE(CLK_ACLK_IMEM_200, "aclk_imem_200", "div_aclk_imem_266",
557 ENABLE_ACLK_TOP, 24, 557 ENABLE_ACLK_TOP, 24,
558 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), 558 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
@@ -616,7 +616,7 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
616 616
617 /* ENABLE_SCLK_TOP_MSCL */ 617 /* ENABLE_SCLK_TOP_MSCL */
618 GATE(CLK_SCLK_JPEG_MSCL, "sclk_jpeg_mscl", "div_sclk_jpeg", 618 GATE(CLK_SCLK_JPEG_MSCL, "sclk_jpeg_mscl", "div_sclk_jpeg",
619 ENABLE_SCLK_TOP_MSCL, 0, 0, 0), 619 ENABLE_SCLK_TOP_MSCL, 0, CLK_SET_RATE_PARENT, 0),
620 620
621 /* ENABLE_SCLK_TOP_CAM1 */ 621 /* ENABLE_SCLK_TOP_CAM1 */
622 GATE(CLK_SCLK_ISP_SENSOR2, "sclk_isp_sensor2", "div_sclk_isp_sensor2_b", 622 GATE(CLK_SCLK_ISP_SENSOR2, "sclk_isp_sensor2", "div_sclk_isp_sensor2_b",
@@ -698,7 +698,7 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
698 * ATLAS_PLL & APOLLO_PLL & MEM0_PLL & MEM1_PLL & BUS_PLL & MFC_PLL 698 * ATLAS_PLL & APOLLO_PLL & MEM0_PLL & MEM1_PLL & BUS_PLL & MFC_PLL
699 * & MPHY_PLL & G3D_PLL & DISP_PLL & ISP_PLL 699 * & MPHY_PLL & G3D_PLL & DISP_PLL & ISP_PLL
700 */ 700 */
701static const struct samsung_pll_rate_table exynos5443_pll_rates[] __initconst = { 701static const struct samsung_pll_rate_table exynos5433_pll_rates[] __initconst = {
702 PLL_35XX_RATE(2500000000U, 625, 6, 0), 702 PLL_35XX_RATE(2500000000U, 625, 6, 0),
703 PLL_35XX_RATE(2400000000U, 500, 5, 0), 703 PLL_35XX_RATE(2400000000U, 500, 5, 0),
704 PLL_35XX_RATE(2300000000U, 575, 6, 0), 704 PLL_35XX_RATE(2300000000U, 575, 6, 0),
@@ -739,7 +739,9 @@ static const struct samsung_pll_rate_table exynos5443_pll_rates[] __initconst =
739 PLL_35XX_RATE(350000000U, 350, 6, 2), 739 PLL_35XX_RATE(350000000U, 350, 6, 2),
740 PLL_35XX_RATE(333000000U, 222, 4, 2), 740 PLL_35XX_RATE(333000000U, 222, 4, 2),
741 PLL_35XX_RATE(300000000U, 500, 5, 3), 741 PLL_35XX_RATE(300000000U, 500, 5, 3),
742 PLL_35XX_RATE(278000000U, 556, 6, 3),
742 PLL_35XX_RATE(266000000U, 532, 6, 3), 743 PLL_35XX_RATE(266000000U, 532, 6, 3),
744 PLL_35XX_RATE(250000000U, 500, 6, 3),
743 PLL_35XX_RATE(200000000U, 400, 6, 3), 745 PLL_35XX_RATE(200000000U, 400, 6, 3),
744 PLL_35XX_RATE(166000000U, 332, 6, 3), 746 PLL_35XX_RATE(166000000U, 332, 6, 3),
745 PLL_35XX_RATE(160000000U, 320, 6, 3), 747 PLL_35XX_RATE(160000000U, 320, 6, 3),
@@ -749,7 +751,7 @@ static const struct samsung_pll_rate_table exynos5443_pll_rates[] __initconst =
749}; 751};
750 752
751/* AUD_PLL */ 753/* AUD_PLL */
752static const struct samsung_pll_rate_table exynos5443_aud_pll_rates[] __initconst = { 754static const struct samsung_pll_rate_table exynos5433_aud_pll_rates[] __initconst = {
753 PLL_36XX_RATE(400000000U, 200, 3, 2, 0), 755 PLL_36XX_RATE(400000000U, 200, 3, 2, 0),
754 PLL_36XX_RATE(393216000U, 197, 3, 2, -25690), 756 PLL_36XX_RATE(393216000U, 197, 3, 2, -25690),
755 PLL_36XX_RATE(384000000U, 128, 2, 2, 0), 757 PLL_36XX_RATE(384000000U, 128, 2, 2, 0),
@@ -764,9 +766,9 @@ static const struct samsung_pll_rate_table exynos5443_aud_pll_rates[] __initcons
764 766
765static const struct samsung_pll_clock top_pll_clks[] __initconst = { 767static const struct samsung_pll_clock top_pll_clks[] __initconst = {
766 PLL(pll_35xx, CLK_FOUT_ISP_PLL, "fout_isp_pll", "oscclk", 768 PLL(pll_35xx, CLK_FOUT_ISP_PLL, "fout_isp_pll", "oscclk",
767 ISP_PLL_LOCK, ISP_PLL_CON0, exynos5443_pll_rates), 769 ISP_PLL_LOCK, ISP_PLL_CON0, exynos5433_pll_rates),
768 PLL(pll_36xx, CLK_FOUT_AUD_PLL, "fout_aud_pll", "oscclk", 770 PLL(pll_36xx, CLK_FOUT_AUD_PLL, "fout_aud_pll", "oscclk",
769 AUD_PLL_LOCK, AUD_PLL_CON0, exynos5443_aud_pll_rates), 771 AUD_PLL_LOCK, AUD_PLL_CON0, exynos5433_aud_pll_rates),
770}; 772};
771 773
772static const struct samsung_cmu_info top_cmu_info __initconst = { 774static const struct samsung_cmu_info top_cmu_info __initconst = {
@@ -820,7 +822,7 @@ PNAME(mout_mphy_pll_p) = { "oscclk", "fout_mphy_pll", };
820 822
821static const struct samsung_pll_clock cpif_pll_clks[] __initconst = { 823static const struct samsung_pll_clock cpif_pll_clks[] __initconst = {
822 PLL(pll_35xx, CLK_FOUT_MPHY_PLL, "fout_mphy_pll", "oscclk", 824 PLL(pll_35xx, CLK_FOUT_MPHY_PLL, "fout_mphy_pll", "oscclk",
823 MPHY_PLL_LOCK, MPHY_PLL_CON0, exynos5443_pll_rates), 825 MPHY_PLL_LOCK, MPHY_PLL_CON0, exynos5433_pll_rates),
824}; 826};
825 827
826static const struct samsung_mux_clock cpif_mux_clks[] __initconst = { 828static const struct samsung_mux_clock cpif_mux_clks[] __initconst = {
@@ -1011,13 +1013,13 @@ static const unsigned long mif_clk_regs[] __initconst = {
1011 1013
1012static const struct samsung_pll_clock mif_pll_clks[] __initconst = { 1014static const struct samsung_pll_clock mif_pll_clks[] __initconst = {
1013 PLL(pll_35xx, CLK_FOUT_MEM0_PLL, "fout_mem0_pll", "oscclk", 1015 PLL(pll_35xx, CLK_FOUT_MEM0_PLL, "fout_mem0_pll", "oscclk",
1014 MEM0_PLL_LOCK, MEM0_PLL_CON0, exynos5443_pll_rates), 1016 MEM0_PLL_LOCK, MEM0_PLL_CON0, exynos5433_pll_rates),
1015 PLL(pll_35xx, CLK_FOUT_MEM1_PLL, "fout_mem1_pll", "oscclk", 1017 PLL(pll_35xx, CLK_FOUT_MEM1_PLL, "fout_mem1_pll", "oscclk",
1016 MEM1_PLL_LOCK, MEM1_PLL_CON0, exynos5443_pll_rates), 1018 MEM1_PLL_LOCK, MEM1_PLL_CON0, exynos5433_pll_rates),
1017 PLL(pll_35xx, CLK_FOUT_BUS_PLL, "fout_bus_pll", "oscclk", 1019 PLL(pll_35xx, CLK_FOUT_BUS_PLL, "fout_bus_pll", "oscclk",
1018 BUS_PLL_LOCK, BUS_PLL_CON0, exynos5443_pll_rates), 1020 BUS_PLL_LOCK, BUS_PLL_CON0, exynos5433_pll_rates),
1019 PLL(pll_35xx, CLK_FOUT_MFC_PLL, "fout_mfc_pll", "oscclk", 1021 PLL(pll_35xx, CLK_FOUT_MFC_PLL, "fout_mfc_pll", "oscclk",
1020 MFC_PLL_LOCK, MFC_PLL_CON0, exynos5443_pll_rates), 1022 MFC_PLL_LOCK, MFC_PLL_CON0, exynos5433_pll_rates),
1021}; 1023};
1022 1024
1023/* list of all parent clock list */ 1025/* list of all parent clock list */
@@ -1382,7 +1384,7 @@ static const struct samsung_gate_clock mif_gate_clks[] __initconst = {
1382 /* ENABLE_ACLK_MIF3 */ 1384 /* ENABLE_ACLK_MIF3 */
1383 GATE(CLK_ACLK_BUS2_400, "aclk_bus2_400", "div_aclk_bus2_400", 1385 GATE(CLK_ACLK_BUS2_400, "aclk_bus2_400", "div_aclk_bus2_400",
1384 ENABLE_ACLK_MIF3, 4, 1386 ENABLE_ACLK_MIF3, 4,
1385 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), 1387 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
1386 GATE(CLK_ACLK_DISP_333, "aclk_disp_333", "div_aclk_disp_333", 1388 GATE(CLK_ACLK_DISP_333, "aclk_disp_333", "div_aclk_disp_333",
1387 ENABLE_ACLK_MIF3, 1, 1389 ENABLE_ACLK_MIF3, 1,
1388 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0), 1390 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 0),
@@ -2539,7 +2541,7 @@ PNAME(mout_sclk_decon_tv_vclk_b_disp_p) = { "mout_sclk_decon_tv_vclk_a_disp",
2539 2541
2540static const struct samsung_pll_clock disp_pll_clks[] __initconst = { 2542static const struct samsung_pll_clock disp_pll_clks[] __initconst = {
2541 PLL(pll_35xx, CLK_FOUT_DISP_PLL, "fout_disp_pll", "oscclk", 2543 PLL(pll_35xx, CLK_FOUT_DISP_PLL, "fout_disp_pll", "oscclk",
2542 DISP_PLL_LOCK, DISP_PLL_CON0, exynos5443_pll_rates), 2544 DISP_PLL_LOCK, DISP_PLL_CON0, exynos5433_pll_rates),
2543}; 2545};
2544 2546
2545static const struct samsung_fixed_factor_clock disp_fixed_factor_clks[] __initconst = { 2547static const struct samsung_fixed_factor_clock disp_fixed_factor_clks[] __initconst = {
@@ -2559,8 +2561,10 @@ static const struct samsung_fixed_rate_clock disp_fixed_clks[] __initconst = {
2559 FRATE(0, "phyclk_mipidphy1_bitclkdiv8_phy", NULL, 0, 188000000), 2561 FRATE(0, "phyclk_mipidphy1_bitclkdiv8_phy", NULL, 0, 188000000),
2560 FRATE(0, "phyclk_mipidphy1_rxclkesc0_phy", NULL, 0, 100000000), 2562 FRATE(0, "phyclk_mipidphy1_rxclkesc0_phy", NULL, 0, 100000000),
2561 /* PHY clocks from MIPI_DPHY0 */ 2563 /* PHY clocks from MIPI_DPHY0 */
2562 FRATE(0, "phyclk_mipidphy0_bitclkdiv8_phy", NULL, 0, 188000000), 2564 FRATE(CLK_PHYCLK_MIPIDPHY0_BITCLKDIV8_PHY, "phyclk_mipidphy0_bitclkdiv8_phy",
2563 FRATE(0, "phyclk_mipidphy0_rxclkesc0_phy", NULL, 0, 100000000), 2565 NULL, 0, 188000000),
2566 FRATE(CLK_PHYCLK_MIPIDPHY0_RXCLKESC0_PHY, "phyclk_mipidphy0_rxclkesc0_phy",
2567 NULL, 0, 100000000),
2564 /* PHY clocks from HDMI_PHY */ 2568 /* PHY clocks from HDMI_PHY */
2565 FRATE(CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY, "phyclk_hdmiphy_tmds_clko_phy", 2569 FRATE(CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY, "phyclk_hdmiphy_tmds_clko_phy",
2566 NULL, 0, 300000000), 2570 NULL, 0, 300000000),
@@ -3224,7 +3228,7 @@ PNAME(mout_g3d_pll_p) = { "oscclk", "fout_g3d_pll", };
3224 3228
3225static const struct samsung_pll_clock g3d_pll_clks[] __initconst = { 3229static const struct samsung_pll_clock g3d_pll_clks[] __initconst = {
3226 PLL(pll_35xx, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "oscclk", 3230 PLL(pll_35xx, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "oscclk",
3227 G3D_PLL_LOCK, G3D_PLL_CON0, exynos5443_pll_rates), 3231 G3D_PLL_LOCK, G3D_PLL_CON0, exynos5433_pll_rates),
3228}; 3232};
3229 3233
3230static const struct samsung_mux_clock g3d_mux_clks[] __initconst = { 3234static const struct samsung_mux_clock g3d_mux_clks[] __initconst = {
@@ -3514,7 +3518,7 @@ PNAME(mout_apollo_p) = { "mout_apollo_pll",
3514 3518
3515static const struct samsung_pll_clock apollo_pll_clks[] __initconst = { 3519static const struct samsung_pll_clock apollo_pll_clks[] __initconst = {
3516 PLL(pll_35xx, CLK_FOUT_APOLLO_PLL, "fout_apollo_pll", "oscclk", 3520 PLL(pll_35xx, CLK_FOUT_APOLLO_PLL, "fout_apollo_pll", "oscclk",
3517 APOLLO_PLL_LOCK, APOLLO_PLL_CON0, exynos5443_pll_rates), 3521 APOLLO_PLL_LOCK, APOLLO_PLL_CON0, exynos5433_pll_rates),
3518}; 3522};
3519 3523
3520static const struct samsung_mux_clock apollo_mux_clks[] __initconst = { 3524static const struct samsung_mux_clock apollo_mux_clks[] __initconst = {
@@ -3737,7 +3741,7 @@ PNAME(mout_atlas_p) = { "mout_atlas_pll",
3737 3741
3738static const struct samsung_pll_clock atlas_pll_clks[] __initconst = { 3742static const struct samsung_pll_clock atlas_pll_clks[] __initconst = {
3739 PLL(pll_35xx, CLK_FOUT_ATLAS_PLL, "fout_atlas_pll", "oscclk", 3743 PLL(pll_35xx, CLK_FOUT_ATLAS_PLL, "fout_atlas_pll", "oscclk",
3740 ATLAS_PLL_LOCK, ATLAS_PLL_CON0, exynos5443_pll_rates), 3744 ATLAS_PLL_LOCK, ATLAS_PLL_CON0, exynos5433_pll_rates),
3741}; 3745};
3742 3746
3743static const struct samsung_mux_clock atlas_mux_clks[] __initconst = { 3747static const struct samsung_mux_clock atlas_mux_clks[] __initconst = {
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 9617825daabb..52290894857a 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -136,11 +136,39 @@ static const struct clk_ops samsung_pll3000_clk_ops = {
136#define PLL35XX_MDIV_MASK (0x3FF) 136#define PLL35XX_MDIV_MASK (0x3FF)
137#define PLL35XX_PDIV_MASK (0x3F) 137#define PLL35XX_PDIV_MASK (0x3F)
138#define PLL35XX_SDIV_MASK (0x7) 138#define PLL35XX_SDIV_MASK (0x7)
139#define PLL35XX_LOCK_STAT_MASK (0x1)
140#define PLL35XX_MDIV_SHIFT (16) 139#define PLL35XX_MDIV_SHIFT (16)
141#define PLL35XX_PDIV_SHIFT (8) 140#define PLL35XX_PDIV_SHIFT (8)
142#define PLL35XX_SDIV_SHIFT (0) 141#define PLL35XX_SDIV_SHIFT (0)
143#define PLL35XX_LOCK_STAT_SHIFT (29) 142#define PLL35XX_LOCK_STAT_SHIFT (29)
143#define PLL35XX_ENABLE_SHIFT (31)
144
145static int samsung_pll35xx_enable(struct clk_hw *hw)
146{
147 struct samsung_clk_pll *pll = to_clk_pll(hw);
148 u32 tmp;
149
150 tmp = readl_relaxed(pll->con_reg);
151 tmp |= BIT(PLL35XX_ENABLE_SHIFT);
152 writel_relaxed(tmp, pll->con_reg);
153
154 /* wait_lock_time */
155 do {
156 cpu_relax();
157 tmp = readl_relaxed(pll->con_reg);
158 } while (!(tmp & BIT(PLL35XX_LOCK_STAT_SHIFT)));
159
160 return 0;
161}
162
163static void samsung_pll35xx_disable(struct clk_hw *hw)
164{
165 struct samsung_clk_pll *pll = to_clk_pll(hw);
166 u32 tmp;
167
168 tmp = readl_relaxed(pll->con_reg);
169 tmp &= ~BIT(PLL35XX_ENABLE_SHIFT);
170 writel_relaxed(tmp, pll->con_reg);
171}
144 172
145static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw, 173static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
146 unsigned long parent_rate) 174 unsigned long parent_rate)
@@ -210,12 +238,13 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
210 (rate->sdiv << PLL35XX_SDIV_SHIFT); 238 (rate->sdiv << PLL35XX_SDIV_SHIFT);
211 writel_relaxed(tmp, pll->con_reg); 239 writel_relaxed(tmp, pll->con_reg);
212 240
213 /* wait_lock_time */ 241 /* wait_lock_time if enabled */
214 do { 242 if (tmp & BIT(PLL35XX_ENABLE_SHIFT)) {
215 cpu_relax(); 243 do {
216 tmp = readl_relaxed(pll->con_reg); 244 cpu_relax();
217 } while (!(tmp & (PLL35XX_LOCK_STAT_MASK 245 tmp = readl_relaxed(pll->con_reg);
218 << PLL35XX_LOCK_STAT_SHIFT))); 246 } while (!(tmp & BIT(PLL35XX_LOCK_STAT_SHIFT)));
247 }
219 return 0; 248 return 0;
220} 249}
221 250
@@ -223,6 +252,8 @@ static const struct clk_ops samsung_pll35xx_clk_ops = {
223 .recalc_rate = samsung_pll35xx_recalc_rate, 252 .recalc_rate = samsung_pll35xx_recalc_rate,
224 .round_rate = samsung_pll_round_rate, 253 .round_rate = samsung_pll_round_rate,
225 .set_rate = samsung_pll35xx_set_rate, 254 .set_rate = samsung_pll35xx_set_rate,
255 .enable = samsung_pll35xx_enable,
256 .disable = samsung_pll35xx_disable,
226}; 257};
227 258
228static const struct clk_ops samsung_pll35xx_clk_min_ops = { 259static const struct clk_ops samsung_pll35xx_clk_min_ops = {
diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
index d7a1e772d95a..e0650c33863b 100644
--- a/drivers/clk/samsung/clk-s3c2410.c
+++ b/drivers/clk/samsung/clk-s3c2410.c
@@ -76,7 +76,7 @@ static struct syscore_ops s3c2410_clk_syscore_ops = {
76 .resume = s3c2410_clk_resume, 76 .resume = s3c2410_clk_resume,
77}; 77};
78 78
79static void s3c2410_clk_sleep_init(void) 79static void __init s3c2410_clk_sleep_init(void)
80{ 80{
81 s3c2410_save = samsung_clk_alloc_reg_dump(s3c2410_clk_regs, 81 s3c2410_save = samsung_clk_alloc_reg_dump(s3c2410_clk_regs,
82 ARRAY_SIZE(s3c2410_clk_regs)); 82 ARRAY_SIZE(s3c2410_clk_regs));
@@ -90,7 +90,7 @@ static void s3c2410_clk_sleep_init(void)
90 return; 90 return;
91} 91}
92#else 92#else
93static void s3c2410_clk_sleep_init(void) {} 93static void __init s3c2410_clk_sleep_init(void) {}
94#endif 94#endif
95 95
96PNAME(fclk_p) = { "mpll", "div_slow" }; 96PNAME(fclk_p) = { "mpll", "div_slow" };
diff --git a/drivers/clk/samsung/clk-s3c2412.c b/drivers/clk/samsung/clk-s3c2412.c
index ec873ee15d37..b8340a49921b 100644
--- a/drivers/clk/samsung/clk-s3c2412.c
+++ b/drivers/clk/samsung/clk-s3c2412.c
@@ -69,7 +69,7 @@ static struct syscore_ops s3c2412_clk_syscore_ops = {
69 .resume = s3c2412_clk_resume, 69 .resume = s3c2412_clk_resume,
70}; 70};
71 71
72static void s3c2412_clk_sleep_init(void) 72static void __init s3c2412_clk_sleep_init(void)
73{ 73{
74 s3c2412_save = samsung_clk_alloc_reg_dump(s3c2412_clk_regs, 74 s3c2412_save = samsung_clk_alloc_reg_dump(s3c2412_clk_regs,
75 ARRAY_SIZE(s3c2412_clk_regs)); 75 ARRAY_SIZE(s3c2412_clk_regs));
@@ -83,7 +83,7 @@ static void s3c2412_clk_sleep_init(void)
83 return; 83 return;
84} 84}
85#else 85#else
86static void s3c2412_clk_sleep_init(void) {} 86static void __init s3c2412_clk_sleep_init(void) {}
87#endif 87#endif
88 88
89static struct clk_div_table divxti_d[] = { 89static struct clk_div_table divxti_d[] = {
diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c
index 5e24a17e10e6..abb935c42916 100644
--- a/drivers/clk/samsung/clk-s3c2443.c
+++ b/drivers/clk/samsung/clk-s3c2443.c
@@ -89,7 +89,7 @@ static struct syscore_ops s3c2443_clk_syscore_ops = {
89 .resume = s3c2443_clk_resume, 89 .resume = s3c2443_clk_resume,
90}; 90};
91 91
92static void s3c2443_clk_sleep_init(void) 92static void __init s3c2443_clk_sleep_init(void)
93{ 93{
94 s3c2443_save = samsung_clk_alloc_reg_dump(s3c2443_clk_regs, 94 s3c2443_save = samsung_clk_alloc_reg_dump(s3c2443_clk_regs,
95 ARRAY_SIZE(s3c2443_clk_regs)); 95 ARRAY_SIZE(s3c2443_clk_regs));
@@ -103,7 +103,7 @@ static void s3c2443_clk_sleep_init(void)
103 return; 103 return;
104} 104}
105#else 105#else
106static void s3c2443_clk_sleep_init(void) {} 106static void __init s3c2443_clk_sleep_init(void) {}
107#endif 107#endif
108 108
109PNAME(epllref_p) = { "mpllref", "mpllref", "xti", "ext" }; 109PNAME(epllref_p) = { "mpllref", "mpllref", "xti", "ext" };
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c
index a48bd5f17330..7306867a0ab8 100644
--- a/drivers/clk/samsung/clk-s3c64xx.c
+++ b/drivers/clk/samsung/clk-s3c64xx.c
@@ -121,7 +121,7 @@ static struct syscore_ops s3c64xx_clk_syscore_ops = {
121 .resume = s3c64xx_clk_resume, 121 .resume = s3c64xx_clk_resume,
122}; 122};
123 123
124static void s3c64xx_clk_sleep_init(void) 124static void __init s3c64xx_clk_sleep_init(void)
125{ 125{
126 s3c64xx_save_common = samsung_clk_alloc_reg_dump(s3c64xx_clk_regs, 126 s3c64xx_save_common = samsung_clk_alloc_reg_dump(s3c64xx_clk_regs,
127 ARRAY_SIZE(s3c64xx_clk_regs)); 127 ARRAY_SIZE(s3c64xx_clk_regs));
@@ -145,7 +145,7 @@ err_warn:
145 __func__); 145 __func__);
146} 146}
147#else 147#else
148static void s3c64xx_clk_sleep_init(void) {} 148static void __init s3c64xx_clk_sleep_init(void) {}
149#endif 149#endif
150 150
151/* List of parent clocks common for all S3C64xx SoCs. */ 151/* List of parent clocks common for all S3C64xx SoCs. */
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 8454c6e3dd65..695bbf9ef428 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -64,6 +64,17 @@ config SUN50I_A64_CCU
64 select SUNXI_CCU_PHASE 64 select SUNXI_CCU_PHASE
65 default ARM64 && ARCH_SUNXI 65 default ARM64 && ARCH_SUNXI
66 66
67config SUN5I_CCU
68 bool "Support for the Allwinner sun5i family CCM"
69 select SUNXI_CCU_DIV
70 select SUNXI_CCU_MULT
71 select SUNXI_CCU_NK
72 select SUNXI_CCU_NKM
73 select SUNXI_CCU_NM
74 select SUNXI_CCU_MP
75 select SUNXI_CCU_PHASE
76 default MACH_SUN5I
77
67config SUN6I_A31_CCU 78config SUN6I_A31_CCU
68 bool "Support for the Allwinner A31/A31s CCU" 79 bool "Support for the Allwinner A31/A31s CCU"
69 select SUNXI_CCU_DIV 80 select SUNXI_CCU_DIV
@@ -109,4 +120,25 @@ config SUN8I_H3_CCU
109 select SUNXI_CCU_PHASE 120 select SUNXI_CCU_PHASE
110 default MACH_SUN8I 121 default MACH_SUN8I
111 122
123config SUN8I_V3S_CCU
124 bool "Support for the Allwinner V3s CCU"
125 select SUNXI_CCU_DIV
126 select SUNXI_CCU_NK
127 select SUNXI_CCU_NKM
128 select SUNXI_CCU_NKMP
129 select SUNXI_CCU_NM
130 select SUNXI_CCU_MP
131 select SUNXI_CCU_PHASE
132 default MACH_SUN8I
133
134config SUN9I_A80_CCU
135 bool "Support for the Allwinner A80 CCU"
136 select SUNXI_CCU_DIV
137 select SUNXI_CCU_GATE
138 select SUNXI_CCU_NKMP
139 select SUNXI_CCU_NM
140 select SUNXI_CCU_MP
141 select SUNXI_CCU_PHASE
142 default MACH_SUN9I
143
112endif 144endif
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 24fbc6e5deb8..6feaac0c5600 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -19,7 +19,12 @@ obj-$(CONFIG_SUNXI_CCU_MP) += ccu_mp.o
19 19
20# SoC support 20# SoC support
21obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o 21obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o
22obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o
22obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o 23obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o
23obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o 24obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o
24obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o 25obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o
25obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o 26obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o
27obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o
28obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o
29obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o
30obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c
new file mode 100644
index 000000000000..06edaa523479
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun5i.c
@@ -0,0 +1,1022 @@
1/*
2 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/clk-provider.h>
15#include <linux/of_address.h>
16
17#include "ccu_common.h"
18#include "ccu_reset.h"
19
20#include "ccu_div.h"
21#include "ccu_gate.h"
22#include "ccu_mp.h"
23#include "ccu_mult.h"
24#include "ccu_nk.h"
25#include "ccu_nkm.h"
26#include "ccu_nkmp.h"
27#include "ccu_nm.h"
28#include "ccu_phase.h"
29
30#include "ccu-sun5i.h"
31
32static struct ccu_nkmp pll_core_clk = {
33 .enable = BIT(31),
34 .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
35 .k = _SUNXI_CCU_MULT(4, 2),
36 .m = _SUNXI_CCU_DIV(0, 2),
37 .p = _SUNXI_CCU_DIV(16, 2),
38 .common = {
39 .reg = 0x000,
40 .hw.init = CLK_HW_INIT("pll-core",
41 "hosc",
42 &ccu_nkmp_ops,
43 0),
44 },
45};
46
47/*
48 * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
49 * the base (2x, 4x and 8x), and one variable divider (the one true
50 * pll audio).
51 *
52 * We don't have any need for the variable divider for now, so we just
53 * hardcode it to match with the clock names
54 */
55#define SUN5I_PLL_AUDIO_REG 0x008
56
57static struct ccu_nm pll_audio_base_clk = {
58 .enable = BIT(31),
59 .n = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
60
61 /*
62 * The datasheet is wrong here, this doesn't have any
63 * offset
64 */
65 .m = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
66 .common = {
67 .reg = 0x008,
68 .hw.init = CLK_HW_INIT("pll-audio-base",
69 "hosc",
70 &ccu_nm_ops,
71 0),
72 },
73};
74
75static struct ccu_mult pll_video0_clk = {
76 .enable = BIT(31),
77 .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
78 .frac = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
79 270000000, 297000000),
80 .common = {
81 .reg = 0x010,
82 .features = (CCU_FEATURE_FRACTIONAL |
83 CCU_FEATURE_ALL_PREDIV),
84 .prediv = 8,
85 .hw.init = CLK_HW_INIT("pll-video0",
86 "hosc",
87 &ccu_mult_ops,
88 0),
89 },
90};
91
92static struct ccu_nkmp pll_ve_clk = {
93 .enable = BIT(31),
94 .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
95 .k = _SUNXI_CCU_MULT(4, 2),
96 .m = _SUNXI_CCU_DIV(0, 2),
97 .p = _SUNXI_CCU_DIV(16, 2),
98 .common = {
99 .reg = 0x018,
100 .hw.init = CLK_HW_INIT("pll-ve",
101 "hosc",
102 &ccu_nkmp_ops,
103 0),
104 },
105};
106
107static struct ccu_nk pll_ddr_base_clk = {
108 .enable = BIT(31),
109 .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
110 .k = _SUNXI_CCU_MULT(4, 2),
111 .common = {
112 .reg = 0x020,
113 .hw.init = CLK_HW_INIT("pll-ddr-base",
114 "hosc",
115 &ccu_nk_ops,
116 0),
117 },
118};
119
120static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2,
121 CLK_IS_CRITICAL);
122
123static struct ccu_div pll_ddr_other_clk = {
124 .div = _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO),
125
126 .common = {
127 .reg = 0x020,
128 .hw.init = CLK_HW_INIT("pll-ddr-other", "pll-ddr-base",
129 &ccu_div_ops,
130 0),
131 },
132};
133
134static struct ccu_nk pll_periph_clk = {
135 .enable = BIT(31),
136 .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
137 .k = _SUNXI_CCU_MULT(4, 2),
138 .fixed_post_div = 2,
139 .common = {
140 .reg = 0x028,
141 .features = CCU_FEATURE_FIXED_POSTDIV,
142 .hw.init = CLK_HW_INIT("pll-periph",
143 "hosc",
144 &ccu_nk_ops,
145 0),
146 },
147};
148
149static struct ccu_mult pll_video1_clk = {
150 .enable = BIT(31),
151 .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
152 .frac = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
153 270000000, 297000000),
154 .common = {
155 .reg = 0x030,
156 .features = (CCU_FEATURE_FRACTIONAL |
157 CCU_FEATURE_ALL_PREDIV),
158 .prediv = 8,
159 .hw.init = CLK_HW_INIT("pll-video1",
160 "hosc",
161 &ccu_mult_ops,
162 0),
163 },
164};
165
166static SUNXI_CCU_GATE(hosc_clk, "hosc", "osc24M", 0x050, BIT(0), 0);
167
168#define SUN5I_AHB_REG 0x054
169static const char * const cpu_parents[] = { "osc32k", "hosc",
170 "pll-core" , "pll-periph" };
171static const struct ccu_mux_fixed_prediv cpu_predivs[] = {
172 { .index = 3, .div = 3, },
173};
174static struct ccu_mux cpu_clk = {
175 .mux = {
176 .shift = 16,
177 .width = 2,
178 .fixed_predivs = cpu_predivs,
179 .n_predivs = ARRAY_SIZE(cpu_predivs),
180 },
181 .common = {
182 .reg = 0x054,
183 .features = CCU_FEATURE_FIXED_PREDIV,
184 .hw.init = CLK_HW_INIT_PARENTS("cpu",
185 cpu_parents,
186 &ccu_mux_ops,
187 CLK_IS_CRITICAL),
188 }
189};
190
191static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0);
192
193static const char * const ahb_parents[] = { "axi" , "cpu", "pll-periph" };
194static const struct ccu_mux_fixed_prediv ahb_predivs[] = {
195 { .index = 2, .div = 2, },
196};
197static struct ccu_div ahb_clk = {
198 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
199 .mux = {
200 .shift = 6,
201 .width = 2,
202 .fixed_predivs = ahb_predivs,
203 .n_predivs = ARRAY_SIZE(ahb_predivs),
204 },
205
206 .common = {
207 .reg = 0x054,
208 .hw.init = CLK_HW_INIT_PARENTS("ahb",
209 ahb_parents,
210 &ccu_div_ops,
211 0),
212 },
213};
214
215static struct clk_div_table apb0_div_table[] = {
216 { .val = 0, .div = 2 },
217 { .val = 1, .div = 2 },
218 { .val = 2, .div = 4 },
219 { .val = 3, .div = 8 },
220 { /* Sentinel */ },
221};
222static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb",
223 0x054, 8, 2, apb0_div_table, 0);
224
225static const char * const apb1_parents[] = { "hosc", "pll-periph", "osc32k" };
226static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058,
227 0, 5, /* M */
228 16, 2, /* P */
229 24, 2, /* mux */
230 0);
231
232static SUNXI_CCU_GATE(axi_dram_clk, "axi-dram", "axi",
233 0x05c, BIT(0), 0);
234
235static SUNXI_CCU_GATE(ahb_otg_clk, "ahb-otg", "ahb",
236 0x060, BIT(0), 0);
237static SUNXI_CCU_GATE(ahb_ehci_clk, "ahb-ehci", "ahb",
238 0x060, BIT(1), 0);
239static SUNXI_CCU_GATE(ahb_ohci_clk, "ahb-ohci", "ahb",
240 0x060, BIT(2), 0);
241static SUNXI_CCU_GATE(ahb_ss_clk, "ahb-ss", "ahb",
242 0x060, BIT(5), 0);
243static SUNXI_CCU_GATE(ahb_dma_clk, "ahb-dma", "ahb",
244 0x060, BIT(6), 0);
245static SUNXI_CCU_GATE(ahb_bist_clk, "ahb-bist", "ahb",
246 0x060, BIT(6), 0);
247static SUNXI_CCU_GATE(ahb_mmc0_clk, "ahb-mmc0", "ahb",
248 0x060, BIT(8), 0);
249static SUNXI_CCU_GATE(ahb_mmc1_clk, "ahb-mmc1", "ahb",
250 0x060, BIT(9), 0);
251static SUNXI_CCU_GATE(ahb_mmc2_clk, "ahb-mmc2", "ahb",
252 0x060, BIT(10), 0);
253static SUNXI_CCU_GATE(ahb_nand_clk, "ahb-nand", "ahb",
254 0x060, BIT(13), 0);
255static SUNXI_CCU_GATE(ahb_sdram_clk, "ahb-sdram", "ahb",
256 0x060, BIT(14), CLK_IS_CRITICAL);
257static SUNXI_CCU_GATE(ahb_emac_clk, "ahb-emac", "ahb",
258 0x060, BIT(17), 0);
259static SUNXI_CCU_GATE(ahb_ts_clk, "ahb-ts", "ahb",
260 0x060, BIT(18), 0);
261static SUNXI_CCU_GATE(ahb_spi0_clk, "ahb-spi0", "ahb",
262 0x060, BIT(20), 0);
263static SUNXI_CCU_GATE(ahb_spi1_clk, "ahb-spi1", "ahb",
264 0x060, BIT(21), 0);
265static SUNXI_CCU_GATE(ahb_spi2_clk, "ahb-spi2", "ahb",
266 0x060, BIT(22), 0);
267static SUNXI_CCU_GATE(ahb_gps_clk, "ahb-gps", "ahb",
268 0x060, BIT(26), 0);
269static SUNXI_CCU_GATE(ahb_hstimer_clk, "ahb-hstimer", "ahb",
270 0x060, BIT(28), 0);
271
272static SUNXI_CCU_GATE(ahb_ve_clk, "ahb-ve", "ahb",
273 0x064, BIT(0), 0);
274static SUNXI_CCU_GATE(ahb_tve_clk, "ahb-tve", "ahb",
275 0x064, BIT(2), 0);
276static SUNXI_CCU_GATE(ahb_lcd_clk, "ahb-lcd", "ahb",
277 0x064, BIT(4), 0);
278static SUNXI_CCU_GATE(ahb_csi_clk, "ahb-csi", "ahb",
279 0x064, BIT(8), 0);
280static SUNXI_CCU_GATE(ahb_hdmi_clk, "ahb-hdmi", "ahb",
281 0x064, BIT(11), 0);
282static SUNXI_CCU_GATE(ahb_de_be_clk, "ahb-de-be", "ahb",
283 0x064, BIT(12), 0);
284static SUNXI_CCU_GATE(ahb_de_fe_clk, "ahb-de-fe", "ahb",
285 0x064, BIT(14), 0);
286static SUNXI_CCU_GATE(ahb_iep_clk, "ahb-iep", "ahb",
287 0x064, BIT(19), 0);
288static SUNXI_CCU_GATE(ahb_gpu_clk, "ahb-gpu", "ahb",
289 0x064, BIT(20), 0);
290
291static SUNXI_CCU_GATE(apb0_codec_clk, "apb0-codec", "apb0",
292 0x068, BIT(0), 0);
293static SUNXI_CCU_GATE(apb0_spdif_clk, "apb0-spdif", "apb0",
294 0x068, BIT(1), 0);
295static SUNXI_CCU_GATE(apb0_i2s_clk, "apb0-i2s", "apb0",
296 0x068, BIT(3), 0);
297static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0",
298 0x068, BIT(5), 0);
299static SUNXI_CCU_GATE(apb0_ir_clk, "apb0-ir", "apb0",
300 0x068, BIT(6), 0);
301static SUNXI_CCU_GATE(apb0_keypad_clk, "apb0-keypad", "apb0",
302 0x068, BIT(10), 0);
303
304static SUNXI_CCU_GATE(apb1_i2c0_clk, "apb1-i2c0", "apb1",
305 0x06c, BIT(0), 0);
306static SUNXI_CCU_GATE(apb1_i2c1_clk, "apb1-i2c1", "apb1",
307 0x06c, BIT(1), 0);
308static SUNXI_CCU_GATE(apb1_i2c2_clk, "apb1-i2c2", "apb1",
309 0x06c, BIT(2), 0);
310static SUNXI_CCU_GATE(apb1_uart0_clk, "apb1-uart0", "apb1",
311 0x06c, BIT(16), 0);
312static SUNXI_CCU_GATE(apb1_uart1_clk, "apb1-uart1", "apb1",
313 0x06c, BIT(17), 0);
314static SUNXI_CCU_GATE(apb1_uart2_clk, "apb1-uart2", "apb1",
315 0x06c, BIT(18), 0);
316static SUNXI_CCU_GATE(apb1_uart3_clk, "apb1-uart3", "apb1",
317 0x06c, BIT(19), 0);
318
319static const char * const mod0_default_parents[] = { "hosc", "pll-periph",
320 "pll-ddr-other" };
321static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
322 0, 4, /* M */
323 16, 2, /* P */
324 24, 2, /* mux */
325 BIT(31), /* gate */
326 0);
327
328static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
329 0, 4, /* M */
330 16, 2, /* P */
331 24, 2, /* mux */
332 BIT(31), /* gate */
333 0);
334
335static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
336 0, 4, /* M */
337 16, 2, /* P */
338 24, 2, /* mux */
339 BIT(31), /* gate */
340 0);
341
342static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
343 0, 4, /* M */
344 16, 2, /* P */
345 24, 2, /* mux */
346 BIT(31), /* gate */
347 0);
348
349static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098,
350 0, 4, /* M */
351 16, 2, /* P */
352 24, 2, /* mux */
353 BIT(31), /* gate */
354 0);
355
356static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
357 0, 4, /* M */
358 16, 2, /* P */
359 24, 2, /* mux */
360 BIT(31), /* gate */
361 0);
362
363static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
364 0, 4, /* M */
365 16, 2, /* P */
366 24, 2, /* mux */
367 BIT(31), /* gate */
368 0);
369
370static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
371 0, 4, /* M */
372 16, 2, /* P */
373 24, 2, /* mux */
374 BIT(31), /* gate */
375 0);
376
377static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
378 0, 4, /* M */
379 16, 2, /* P */
380 24, 2, /* mux */
381 BIT(31), /* gate */
382 0);
383
384static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", mod0_default_parents, 0x0b0,
385 0, 4, /* M */
386 16, 2, /* P */
387 24, 2, /* mux */
388 BIT(31), /* gate */
389 0);
390
391static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
392 "pll-audio-2x", "pll-audio" };
393static SUNXI_CCU_MUX_WITH_GATE(i2s_clk, "i2s", i2s_parents,
394 0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
395
396static const char * const spdif_parents[] = { "pll-audio-8x", "pll-audio-4x",
397 "pll-audio-2x", "pll-audio" };
398static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", spdif_parents,
399 0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
400
401static const char * const keypad_parents[] = { "hosc", "losc"};
402static const u8 keypad_table[] = { 0, 2 };
403static struct ccu_mp keypad_clk = {
404 .enable = BIT(31),
405 .m = _SUNXI_CCU_DIV(8, 5),
406 .p = _SUNXI_CCU_DIV(20, 2),
407 .mux = _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table),
408
409 .common = {
410 .reg = 0x0c4,
411 .hw.init = CLK_HW_INIT_PARENTS("keypad",
412 keypad_parents,
413 &ccu_mp_ops,
414 0),
415 },
416};
417
418static SUNXI_CCU_GATE(usb_ohci_clk, "usb-ohci", "pll-periph",
419 0x0cc, BIT(6), 0);
420static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "pll-periph",
421 0x0cc, BIT(8), 0);
422static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "pll-periph",
423 0x0cc, BIT(9), 0);
424
425static const char * const gps_parents[] = { "hosc", "pll-periph",
426 "pll-video1", "pll-ve" };
427static SUNXI_CCU_M_WITH_MUX_GATE(gps_clk, "gps", gps_parents,
428 0x0d0, 0, 3, 24, 2, BIT(31), 0);
429
430static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr",
431 0x100, BIT(0), 0);
432static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "pll-ddr",
433 0x100, BIT(1), 0);
434static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "pll-ddr",
435 0x100, BIT(3), 0);
436static SUNXI_CCU_GATE(dram_tve_clk, "dram-tve", "pll-ddr",
437 0x100, BIT(5), 0);
438static SUNXI_CCU_GATE(dram_de_fe_clk, "dram-de-fe", "pll-ddr",
439 0x100, BIT(25), 0);
440static SUNXI_CCU_GATE(dram_de_be_clk, "dram-de-be", "pll-ddr",
441 0x100, BIT(26), 0);
442static SUNXI_CCU_GATE(dram_ace_clk, "dram-ace", "pll-ddr",
443 0x100, BIT(29), 0);
444static SUNXI_CCU_GATE(dram_iep_clk, "dram-iep", "pll-ddr",
445 0x100, BIT(31), 0);
446
447static const char * const de_parents[] = { "pll-video0", "pll-video1",
448 "pll-ddr-other" };
449static SUNXI_CCU_M_WITH_MUX_GATE(de_be_clk, "de-be", de_parents,
450 0x104, 0, 4, 24, 2, BIT(31), 0);
451
452static SUNXI_CCU_M_WITH_MUX_GATE(de_fe_clk, "de-fe", de_parents,
453 0x10c, 0, 4, 24, 2, BIT(31), 0);
454
455static const char * const tcon_parents[] = { "pll-video0", "pll-video1",
456 "pll-video0-2x", "pll-video1-2x" };
457static SUNXI_CCU_MUX_WITH_GATE(tcon_ch0_clk, "tcon-ch0-sclk", tcon_parents,
458 0x118, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
459
460static SUNXI_CCU_M_WITH_MUX_GATE(tcon_ch1_sclk2_clk, "tcon-ch1-sclk2",
461 tcon_parents,
462 0x12c, 0, 4, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
463
464static SUNXI_CCU_M_WITH_GATE(tcon_ch1_sclk1_clk, "tcon-ch1-sclk1", "tcon-ch1-sclk2",
465 0x12c, 11, 1, BIT(15), CLK_SET_RATE_PARENT);
466
467static const char * const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
468 "pll-video0-2x", "pll-video1-2x" };
469static const u8 csi_table[] = { 0, 1, 2, 5, 6 };
470static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi",
471 csi_parents, csi_table,
472 0x134, 0, 5, 24, 2, BIT(31), 0);
473
474static SUNXI_CCU_GATE(ve_clk, "ve", "pll-ve",
475 0x13c, BIT(31), CLK_SET_RATE_PARENT);
476
477static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio",
478 0x140, BIT(31), CLK_SET_RATE_PARENT);
479
480static SUNXI_CCU_GATE(avs_clk, "avs", "hosc",
481 0x144, BIT(31), 0);
482
483static const char * const hdmi_parents[] = { "pll-video0", "pll-video0-2x" };
484static const u8 hdmi_table[] = { 0, 2 };
485static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi_clk, "hdmi",
486 hdmi_parents, hdmi_table,
487 0x150, 0, 4, 24, 2, BIT(31),
488 CLK_SET_RATE_PARENT);
489
490static const char * const gpu_parents[] = { "pll-video0", "pll-ve",
491 "pll-ddr-other", "pll-video1",
492 "pll-video1-2x" };
493static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents,
494 0x154, 0, 4, 24, 3, BIT(31), 0);
495
496static const char * const mbus_parents[] = { "hosc", "pll-periph", "pll-ddr" };
497static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
498 0x15c, 0, 4, 16, 2, 24, 2, BIT(31), CLK_IS_CRITICAL);
499
500static SUNXI_CCU_GATE(iep_clk, "iep", "de-be",
501 0x160, BIT(31), 0);
502
503static struct ccu_common *sun5i_a10s_ccu_clks[] = {
504 &hosc_clk.common,
505 &pll_core_clk.common,
506 &pll_audio_base_clk.common,
507 &pll_video0_clk.common,
508 &pll_ve_clk.common,
509 &pll_ddr_base_clk.common,
510 &pll_ddr_clk.common,
511 &pll_ddr_other_clk.common,
512 &pll_periph_clk.common,
513 &pll_video1_clk.common,
514 &cpu_clk.common,
515 &axi_clk.common,
516 &ahb_clk.common,
517 &apb0_clk.common,
518 &apb1_clk.common,
519 &axi_dram_clk.common,
520 &ahb_otg_clk.common,
521 &ahb_ehci_clk.common,
522 &ahb_ohci_clk.common,
523 &ahb_ss_clk.common,
524 &ahb_dma_clk.common,
525 &ahb_bist_clk.common,
526 &ahb_mmc0_clk.common,
527 &ahb_mmc1_clk.common,
528 &ahb_mmc2_clk.common,
529 &ahb_nand_clk.common,
530 &ahb_sdram_clk.common,
531 &ahb_emac_clk.common,
532 &ahb_ts_clk.common,
533 &ahb_spi0_clk.common,
534 &ahb_spi1_clk.common,
535 &ahb_spi2_clk.common,
536 &ahb_gps_clk.common,
537 &ahb_hstimer_clk.common,
538 &ahb_ve_clk.common,
539 &ahb_tve_clk.common,
540 &ahb_lcd_clk.common,
541 &ahb_csi_clk.common,
542 &ahb_hdmi_clk.common,
543 &ahb_de_be_clk.common,
544 &ahb_de_fe_clk.common,
545 &ahb_iep_clk.common,
546 &ahb_gpu_clk.common,
547 &apb0_codec_clk.common,
548 &apb0_spdif_clk.common,
549 &apb0_i2s_clk.common,
550 &apb0_pio_clk.common,
551 &apb0_ir_clk.common,
552 &apb0_keypad_clk.common,
553 &apb1_i2c0_clk.common,
554 &apb1_i2c1_clk.common,
555 &apb1_i2c2_clk.common,
556 &apb1_uart0_clk.common,
557 &apb1_uart1_clk.common,
558 &apb1_uart2_clk.common,
559 &apb1_uart3_clk.common,
560 &nand_clk.common,
561 &mmc0_clk.common,
562 &mmc1_clk.common,
563 &mmc2_clk.common,
564 &ts_clk.common,
565 &ss_clk.common,
566 &spi0_clk.common,
567 &spi1_clk.common,
568 &spi2_clk.common,
569 &ir_clk.common,
570 &i2s_clk.common,
571 &spdif_clk.common,
572 &keypad_clk.common,
573 &usb_ohci_clk.common,
574 &usb_phy0_clk.common,
575 &usb_phy1_clk.common,
576 &gps_clk.common,
577 &dram_ve_clk.common,
578 &dram_csi_clk.common,
579 &dram_ts_clk.common,
580 &dram_tve_clk.common,
581 &dram_de_fe_clk.common,
582 &dram_de_be_clk.common,
583 &dram_ace_clk.common,
584 &dram_iep_clk.common,
585 &de_be_clk.common,
586 &de_fe_clk.common,
587 &tcon_ch0_clk.common,
588 &tcon_ch1_sclk2_clk.common,
589 &tcon_ch1_sclk1_clk.common,
590 &csi_clk.common,
591 &ve_clk.common,
592 &codec_clk.common,
593 &avs_clk.common,
594 &hdmi_clk.common,
595 &gpu_clk.common,
596 &mbus_clk.common,
597 &iep_clk.common,
598};
599
600/* We hardcode the divider to 4 for now */
601static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
602 "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
603static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
604 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
605static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
606 "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
607static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
608 "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
609static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
610 "pll-video0", 1, 2, CLK_SET_RATE_PARENT);
611static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
612 "pll-video1", 1, 2, CLK_SET_RATE_PARENT);
613
614static struct clk_hw_onecell_data sun5i_a10s_hw_clks = {
615 .hws = {
616 [CLK_HOSC] = &hosc_clk.common.hw,
617 [CLK_PLL_CORE] = &pll_core_clk.common.hw,
618 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
619 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
620 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
621 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
622 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
623 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
624 [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
625 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
626 [CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw,
627 [CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
628 [CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw,
629 [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
630 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
631 [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
632 [CLK_CPU] = &cpu_clk.common.hw,
633 [CLK_AXI] = &axi_clk.common.hw,
634 [CLK_AHB] = &ahb_clk.common.hw,
635 [CLK_APB0] = &apb0_clk.common.hw,
636 [CLK_APB1] = &apb1_clk.common.hw,
637 [CLK_DRAM_AXI] = &axi_dram_clk.common.hw,
638 [CLK_AHB_OTG] = &ahb_otg_clk.common.hw,
639 [CLK_AHB_EHCI] = &ahb_ehci_clk.common.hw,
640 [CLK_AHB_OHCI] = &ahb_ohci_clk.common.hw,
641 [CLK_AHB_SS] = &ahb_ss_clk.common.hw,
642 [CLK_AHB_DMA] = &ahb_dma_clk.common.hw,
643 [CLK_AHB_BIST] = &ahb_bist_clk.common.hw,
644 [CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw,
645 [CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw,
646 [CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw,
647 [CLK_AHB_NAND] = &ahb_nand_clk.common.hw,
648 [CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw,
649 [CLK_AHB_EMAC] = &ahb_emac_clk.common.hw,
650 [CLK_AHB_TS] = &ahb_ts_clk.common.hw,
651 [CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw,
652 [CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw,
653 [CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw,
654 [CLK_AHB_GPS] = &ahb_gps_clk.common.hw,
655 [CLK_AHB_HSTIMER] = &ahb_hstimer_clk.common.hw,
656 [CLK_AHB_VE] = &ahb_ve_clk.common.hw,
657 [CLK_AHB_TVE] = &ahb_tve_clk.common.hw,
658 [CLK_AHB_LCD] = &ahb_lcd_clk.common.hw,
659 [CLK_AHB_CSI] = &ahb_csi_clk.common.hw,
660 [CLK_AHB_HDMI] = &ahb_hdmi_clk.common.hw,
661 [CLK_AHB_DE_BE] = &ahb_de_be_clk.common.hw,
662 [CLK_AHB_DE_FE] = &ahb_de_fe_clk.common.hw,
663 [CLK_AHB_IEP] = &ahb_iep_clk.common.hw,
664 [CLK_AHB_GPU] = &ahb_gpu_clk.common.hw,
665 [CLK_APB0_CODEC] = &apb0_codec_clk.common.hw,
666 [CLK_APB0_I2S] = &apb0_i2s_clk.common.hw,
667 [CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
668 [CLK_APB0_IR] = &apb0_ir_clk.common.hw,
669 [CLK_APB0_KEYPAD] = &apb0_keypad_clk.common.hw,
670 [CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw,
671 [CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw,
672 [CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw,
673 [CLK_APB1_UART0] = &apb1_uart0_clk.common.hw,
674 [CLK_APB1_UART1] = &apb1_uart1_clk.common.hw,
675 [CLK_APB1_UART2] = &apb1_uart2_clk.common.hw,
676 [CLK_APB1_UART3] = &apb1_uart3_clk.common.hw,
677 [CLK_NAND] = &nand_clk.common.hw,
678 [CLK_MMC0] = &mmc0_clk.common.hw,
679 [CLK_MMC1] = &mmc1_clk.common.hw,
680 [CLK_MMC2] = &mmc2_clk.common.hw,
681 [CLK_TS] = &ts_clk.common.hw,
682 [CLK_SS] = &ss_clk.common.hw,
683 [CLK_SPI0] = &spi0_clk.common.hw,
684 [CLK_SPI1] = &spi1_clk.common.hw,
685 [CLK_SPI2] = &spi2_clk.common.hw,
686 [CLK_IR] = &ir_clk.common.hw,
687 [CLK_I2S] = &i2s_clk.common.hw,
688 [CLK_KEYPAD] = &keypad_clk.common.hw,
689 [CLK_USB_OHCI] = &usb_ohci_clk.common.hw,
690 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
691 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
692 [CLK_GPS] = &gps_clk.common.hw,
693 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
694 [CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
695 [CLK_DRAM_TS] = &dram_ts_clk.common.hw,
696 [CLK_DRAM_TVE] = &dram_tve_clk.common.hw,
697 [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw,
698 [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw,
699 [CLK_DRAM_ACE] = &dram_ace_clk.common.hw,
700 [CLK_DRAM_IEP] = &dram_iep_clk.common.hw,
701 [CLK_DE_BE] = &de_be_clk.common.hw,
702 [CLK_DE_FE] = &de_fe_clk.common.hw,
703 [CLK_TCON_CH0] = &tcon_ch0_clk.common.hw,
704 [CLK_TCON_CH1_SCLK] = &tcon_ch1_sclk2_clk.common.hw,
705 [CLK_TCON_CH1] = &tcon_ch1_sclk1_clk.common.hw,
706 [CLK_CSI] = &csi_clk.common.hw,
707 [CLK_VE] = &ve_clk.common.hw,
708 [CLK_CODEC] = &codec_clk.common.hw,
709 [CLK_AVS] = &avs_clk.common.hw,
710 [CLK_HDMI] = &hdmi_clk.common.hw,
711 [CLK_GPU] = &gpu_clk.common.hw,
712 [CLK_MBUS] = &mbus_clk.common.hw,
713 [CLK_IEP] = &iep_clk.common.hw,
714 },
715 .num = CLK_NUMBER,
716};
717
718static struct ccu_reset_map sun5i_a10s_ccu_resets[] = {
719 [RST_USB_PHY0] = { 0x0cc, BIT(0) },
720 [RST_USB_PHY1] = { 0x0cc, BIT(1) },
721
722 [RST_GPS] = { 0x0d0, BIT(30) },
723
724 [RST_DE_BE] = { 0x104, BIT(30) },
725
726 [RST_DE_FE] = { 0x10c, BIT(30) },
727
728 [RST_TVE] = { 0x118, BIT(29) },
729 [RST_LCD] = { 0x118, BIT(30) },
730
731 [RST_CSI] = { 0x134, BIT(30) },
732
733 [RST_VE] = { 0x13c, BIT(0) },
734
735 [RST_GPU] = { 0x154, BIT(30) },
736
737 [RST_IEP] = { 0x160, BIT(30) },
738};
739
740static const struct sunxi_ccu_desc sun5i_a10s_ccu_desc = {
741 .ccu_clks = sun5i_a10s_ccu_clks,
742 .num_ccu_clks = ARRAY_SIZE(sun5i_a10s_ccu_clks),
743
744 .hw_clks = &sun5i_a10s_hw_clks,
745
746 .resets = sun5i_a10s_ccu_resets,
747 .num_resets = ARRAY_SIZE(sun5i_a10s_ccu_resets),
748};
749
750/*
751 * The A13 is the A10s minus the TS, GPS, HDMI, I2S and the keypad
752 */
753static struct clk_hw_onecell_data sun5i_a13_hw_clks = {
754 .hws = {
755 [CLK_HOSC] = &hosc_clk.common.hw,
756 [CLK_PLL_CORE] = &pll_core_clk.common.hw,
757 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
758 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
759 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
760 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
761 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
762 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
763 [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
764 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
765 [CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw,
766 [CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
767 [CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw,
768 [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
769 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
770 [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
771 [CLK_CPU] = &cpu_clk.common.hw,
772 [CLK_AXI] = &axi_clk.common.hw,
773 [CLK_AHB] = &ahb_clk.common.hw,
774 [CLK_APB0] = &apb0_clk.common.hw,
775 [CLK_APB1] = &apb1_clk.common.hw,
776 [CLK_DRAM_AXI] = &axi_dram_clk.common.hw,
777 [CLK_AHB_OTG] = &ahb_otg_clk.common.hw,
778 [CLK_AHB_EHCI] = &ahb_ehci_clk.common.hw,
779 [CLK_AHB_OHCI] = &ahb_ohci_clk.common.hw,
780 [CLK_AHB_SS] = &ahb_ss_clk.common.hw,
781 [CLK_AHB_DMA] = &ahb_dma_clk.common.hw,
782 [CLK_AHB_BIST] = &ahb_bist_clk.common.hw,
783 [CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw,
784 [CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw,
785 [CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw,
786 [CLK_AHB_NAND] = &ahb_nand_clk.common.hw,
787 [CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw,
788 [CLK_AHB_EMAC] = &ahb_emac_clk.common.hw,
789 [CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw,
790 [CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw,
791 [CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw,
792 [CLK_AHB_HSTIMER] = &ahb_hstimer_clk.common.hw,
793 [CLK_AHB_VE] = &ahb_ve_clk.common.hw,
794 [CLK_AHB_TVE] = &ahb_tve_clk.common.hw,
795 [CLK_AHB_LCD] = &ahb_lcd_clk.common.hw,
796 [CLK_AHB_CSI] = &ahb_csi_clk.common.hw,
797 [CLK_AHB_DE_BE] = &ahb_de_be_clk.common.hw,
798 [CLK_AHB_DE_FE] = &ahb_de_fe_clk.common.hw,
799 [CLK_AHB_IEP] = &ahb_iep_clk.common.hw,
800 [CLK_AHB_GPU] = &ahb_gpu_clk.common.hw,
801 [CLK_APB0_CODEC] = &apb0_codec_clk.common.hw,
802 [CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
803 [CLK_APB0_IR] = &apb0_ir_clk.common.hw,
804 [CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw,
805 [CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw,
806 [CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw,
807 [CLK_APB1_UART0] = &apb1_uart0_clk.common.hw,
808 [CLK_APB1_UART1] = &apb1_uart1_clk.common.hw,
809 [CLK_APB1_UART2] = &apb1_uart2_clk.common.hw,
810 [CLK_APB1_UART3] = &apb1_uart3_clk.common.hw,
811 [CLK_NAND] = &nand_clk.common.hw,
812 [CLK_MMC0] = &mmc0_clk.common.hw,
813 [CLK_MMC1] = &mmc1_clk.common.hw,
814 [CLK_MMC2] = &mmc2_clk.common.hw,
815 [CLK_SS] = &ss_clk.common.hw,
816 [CLK_SPI0] = &spi0_clk.common.hw,
817 [CLK_SPI1] = &spi1_clk.common.hw,
818 [CLK_SPI2] = &spi2_clk.common.hw,
819 [CLK_IR] = &ir_clk.common.hw,
820 [CLK_USB_OHCI] = &usb_ohci_clk.common.hw,
821 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
822 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
823 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
824 [CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
825 [CLK_DRAM_TVE] = &dram_tve_clk.common.hw,
826 [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw,
827 [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw,
828 [CLK_DRAM_ACE] = &dram_ace_clk.common.hw,
829 [CLK_DRAM_IEP] = &dram_iep_clk.common.hw,
830 [CLK_DE_BE] = &de_be_clk.common.hw,
831 [CLK_DE_FE] = &de_fe_clk.common.hw,
832 [CLK_TCON_CH0] = &tcon_ch0_clk.common.hw,
833 [CLK_TCON_CH1_SCLK] = &tcon_ch1_sclk2_clk.common.hw,
834 [CLK_TCON_CH1] = &tcon_ch1_sclk1_clk.common.hw,
835 [CLK_CSI] = &csi_clk.common.hw,
836 [CLK_VE] = &ve_clk.common.hw,
837 [CLK_CODEC] = &codec_clk.common.hw,
838 [CLK_AVS] = &avs_clk.common.hw,
839 [CLK_GPU] = &gpu_clk.common.hw,
840 [CLK_MBUS] = &mbus_clk.common.hw,
841 [CLK_IEP] = &iep_clk.common.hw,
842 },
843 .num = CLK_NUMBER,
844};
845
846static const struct sunxi_ccu_desc sun5i_a13_ccu_desc = {
847 .ccu_clks = sun5i_a10s_ccu_clks,
848 .num_ccu_clks = ARRAY_SIZE(sun5i_a10s_ccu_clks),
849
850 .hw_clks = &sun5i_a13_hw_clks,
851
852 .resets = sun5i_a10s_ccu_resets,
853 .num_resets = ARRAY_SIZE(sun5i_a10s_ccu_resets),
854};
855
856/*
857 * The GR8 is the A10s CCU minus the HDMI and keypad, plus SPDIF
858 */
859static struct clk_hw_onecell_data sun5i_gr8_hw_clks = {
860 .hws = {
861 [CLK_HOSC] = &hosc_clk.common.hw,
862 [CLK_PLL_CORE] = &pll_core_clk.common.hw,
863 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
864 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
865 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
866 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
867 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
868 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
869 [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
870 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
871 [CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw,
872 [CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
873 [CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw,
874 [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
875 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
876 [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
877 [CLK_CPU] = &cpu_clk.common.hw,
878 [CLK_AXI] = &axi_clk.common.hw,
879 [CLK_AHB] = &ahb_clk.common.hw,
880 [CLK_APB0] = &apb0_clk.common.hw,
881 [CLK_APB1] = &apb1_clk.common.hw,
882 [CLK_DRAM_AXI] = &axi_dram_clk.common.hw,
883 [CLK_AHB_OTG] = &ahb_otg_clk.common.hw,
884 [CLK_AHB_EHCI] = &ahb_ehci_clk.common.hw,
885 [CLK_AHB_OHCI] = &ahb_ohci_clk.common.hw,
886 [CLK_AHB_SS] = &ahb_ss_clk.common.hw,
887 [CLK_AHB_DMA] = &ahb_dma_clk.common.hw,
888 [CLK_AHB_BIST] = &ahb_bist_clk.common.hw,
889 [CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw,
890 [CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw,
891 [CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw,
892 [CLK_AHB_NAND] = &ahb_nand_clk.common.hw,
893 [CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw,
894 [CLK_AHB_EMAC] = &ahb_emac_clk.common.hw,
895 [CLK_AHB_TS] = &ahb_ts_clk.common.hw,
896 [CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw,
897 [CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw,
898 [CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw,
899 [CLK_AHB_GPS] = &ahb_gps_clk.common.hw,
900 [CLK_AHB_HSTIMER] = &ahb_hstimer_clk.common.hw,
901 [CLK_AHB_VE] = &ahb_ve_clk.common.hw,
902 [CLK_AHB_TVE] = &ahb_tve_clk.common.hw,
903 [CLK_AHB_LCD] = &ahb_lcd_clk.common.hw,
904 [CLK_AHB_CSI] = &ahb_csi_clk.common.hw,
905 [CLK_AHB_DE_BE] = &ahb_de_be_clk.common.hw,
906 [CLK_AHB_DE_FE] = &ahb_de_fe_clk.common.hw,
907 [CLK_AHB_IEP] = &ahb_iep_clk.common.hw,
908 [CLK_AHB_GPU] = &ahb_gpu_clk.common.hw,
909 [CLK_APB0_CODEC] = &apb0_codec_clk.common.hw,
910 [CLK_APB0_SPDIF] = &apb0_spdif_clk.common.hw,
911 [CLK_APB0_I2S] = &apb0_i2s_clk.common.hw,
912 [CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
913 [CLK_APB0_IR] = &apb0_ir_clk.common.hw,
914 [CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw,
915 [CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw,
916 [CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw,
917 [CLK_APB1_UART0] = &apb1_uart0_clk.common.hw,
918 [CLK_APB1_UART1] = &apb1_uart1_clk.common.hw,
919 [CLK_APB1_UART2] = &apb1_uart2_clk.common.hw,
920 [CLK_APB1_UART3] = &apb1_uart3_clk.common.hw,
921 [CLK_NAND] = &nand_clk.common.hw,
922 [CLK_MMC0] = &mmc0_clk.common.hw,
923 [CLK_MMC1] = &mmc1_clk.common.hw,
924 [CLK_MMC2] = &mmc2_clk.common.hw,
925 [CLK_TS] = &ts_clk.common.hw,
926 [CLK_SS] = &ss_clk.common.hw,
927 [CLK_SPI0] = &spi0_clk.common.hw,
928 [CLK_SPI1] = &spi1_clk.common.hw,
929 [CLK_SPI2] = &spi2_clk.common.hw,
930 [CLK_IR] = &ir_clk.common.hw,
931 [CLK_I2S] = &i2s_clk.common.hw,
932 [CLK_SPDIF] = &spdif_clk.common.hw,
933 [CLK_USB_OHCI] = &usb_ohci_clk.common.hw,
934 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
935 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
936 [CLK_GPS] = &gps_clk.common.hw,
937 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
938 [CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
939 [CLK_DRAM_TS] = &dram_ts_clk.common.hw,
940 [CLK_DRAM_TVE] = &dram_tve_clk.common.hw,
941 [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw,
942 [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw,
943 [CLK_DRAM_ACE] = &dram_ace_clk.common.hw,
944 [CLK_DRAM_IEP] = &dram_iep_clk.common.hw,
945 [CLK_DE_BE] = &de_be_clk.common.hw,
946 [CLK_DE_FE] = &de_fe_clk.common.hw,
947 [CLK_TCON_CH0] = &tcon_ch0_clk.common.hw,
948 [CLK_TCON_CH1_SCLK] = &tcon_ch1_sclk2_clk.common.hw,
949 [CLK_TCON_CH1] = &tcon_ch1_sclk1_clk.common.hw,
950 [CLK_CSI] = &csi_clk.common.hw,
951 [CLK_VE] = &ve_clk.common.hw,
952 [CLK_CODEC] = &codec_clk.common.hw,
953 [CLK_AVS] = &avs_clk.common.hw,
954 [CLK_GPU] = &gpu_clk.common.hw,
955 [CLK_MBUS] = &mbus_clk.common.hw,
956 [CLK_IEP] = &iep_clk.common.hw,
957 },
958 .num = CLK_NUMBER,
959};
960
961static const struct sunxi_ccu_desc sun5i_gr8_ccu_desc = {
962 .ccu_clks = sun5i_a10s_ccu_clks,
963 .num_ccu_clks = ARRAY_SIZE(sun5i_a10s_ccu_clks),
964
965 .hw_clks = &sun5i_gr8_hw_clks,
966
967 .resets = sun5i_a10s_ccu_resets,
968 .num_resets = ARRAY_SIZE(sun5i_a10s_ccu_resets),
969};
970
971static void __init sun5i_ccu_init(struct device_node *node,
972 const struct sunxi_ccu_desc *desc)
973{
974 void __iomem *reg;
975 u32 val;
976
977 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
978 if (IS_ERR(reg)) {
979 pr_err("%s: Could not map the clock registers\n",
980 of_node_full_name(node));
981 return;
982 }
983
984 /* Force the PLL-Audio-1x divider to 4 */
985 val = readl(reg + SUN5I_PLL_AUDIO_REG);
986 val &= ~GENMASK(19, 16);
987 writel(val | (3 << 16), reg + SUN5I_PLL_AUDIO_REG);
988
989 /*
990 * Use the peripheral PLL as the AHB parent, instead of CPU /
991 * AXI which have rate changes due to cpufreq.
992 *
993 * This is especially a big deal for the HS timer whose parent
994 * clock is AHB.
995 */
996 val = readl(reg + SUN5I_AHB_REG);
997 val &= ~GENMASK(7, 6);
998 writel(val | (2 << 6), reg + SUN5I_AHB_REG);
999
1000 sunxi_ccu_probe(node, reg, desc);
1001}
1002
1003static void __init sun5i_a10s_ccu_setup(struct device_node *node)
1004{
1005 sun5i_ccu_init(node, &sun5i_a10s_ccu_desc);
1006}
1007CLK_OF_DECLARE(sun5i_a10s_ccu, "allwinner,sun5i-a10s-ccu",
1008 sun5i_a10s_ccu_setup);
1009
1010static void __init sun5i_a13_ccu_setup(struct device_node *node)
1011{
1012 sun5i_ccu_init(node, &sun5i_a13_ccu_desc);
1013}
1014CLK_OF_DECLARE(sun5i_a13_ccu, "allwinner,sun5i-a13-ccu",
1015 sun5i_a13_ccu_setup);
1016
1017static void __init sun5i_gr8_ccu_setup(struct device_node *node)
1018{
1019 sun5i_ccu_init(node, &sun5i_gr8_ccu_desc);
1020}
1021CLK_OF_DECLARE(sun5i_gr8_ccu, "nextthing,gr8-ccu",
1022 sun5i_gr8_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.h b/drivers/clk/sunxi-ng/ccu-sun5i.h
new file mode 100644
index 000000000000..8144487eb7ca
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun5i.h
@@ -0,0 +1,67 @@
1/*
2 * Copyright 2016 Maxime Ripard
3 *
4 * Maxime Ripard <maxime.ripard@free-electrons.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _CCU_SUN5I_H_
18#define _CCU_SUN5I_H_
19
20#include <dt-bindings/clock/sun5i-ccu.h>
21#include <dt-bindings/reset/sun5i-ccu.h>
22
23/* The HOSC is exported */
24#define CLK_PLL_CORE 2
25#define CLK_PLL_AUDIO_BASE 3
26#define CLK_PLL_AUDIO 4
27#define CLK_PLL_AUDIO_2X 5
28#define CLK_PLL_AUDIO_4X 6
29#define CLK_PLL_AUDIO_8X 7
30#define CLK_PLL_VIDEO0 8
31#define CLK_PLL_VIDEO0_2X 9
32#define CLK_PLL_VE 10
33#define CLK_PLL_DDR_BASE 11
34#define CLK_PLL_DDR 12
35#define CLK_PLL_DDR_OTHER 13
36#define CLK_PLL_PERIPH 14
37#define CLK_PLL_VIDEO1 15
38#define CLK_PLL_VIDEO1_2X 16
39
40/* The CPU clock is exported */
41
42#define CLK_AXI 18
43#define CLK_AHB 19
44#define CLK_APB0 20
45#define CLK_APB1 21
46#define CLK_DRAM_AXI 22
47
48/* AHB gates are exported */
49/* APB0 gates are exported */
50/* APB1 gates are exported */
51/* Modules clocks are exported */
52/* USB clocks are exported */
53/* GPS clock is exported */
54/* DRAM gates are exported */
55/* More display modules clocks are exported */
56
57#define CLK_TCON_CH1_SCLK 91
58
59/* The rest of the module clocks are exported */
60
61#define CLK_MBUS 99
62
63/* And finally the IEP clock */
64
65#define CLK_NUMBER (CLK_IEP + 1)
66
67#endif /* _CCU_SUN5I_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
index fc75a335a7ce..4c9a920ff4ab 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
@@ -468,8 +468,8 @@ static SUNXI_CCU_MUX_WITH_GATE(daudio0_clk, "daudio0", daudio_parents,
468static SUNXI_CCU_MUX_WITH_GATE(daudio1_clk, "daudio1", daudio_parents, 468static SUNXI_CCU_MUX_WITH_GATE(daudio1_clk, "daudio1", daudio_parents,
469 0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 469 0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
470 470
471static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio", 471static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", daudio_parents,
472 0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT); 472 0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
473 473
474static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 474static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
475 0x0cc, BIT(8), 0); 475 0x0cc, BIT(8), 0);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
index 9bd1f78a0547..a7b3c08ed0e2 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
@@ -170,7 +170,7 @@ static SUNXI_CCU_N_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1",
170static const char * const cpux_parents[] = { "osc32k", "osc24M", 170static const char * const cpux_parents[] = { "osc32k", "osc24M",
171 "pll-cpux" , "pll-cpux" }; 171 "pll-cpux" , "pll-cpux" };
172static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents, 172static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
173 0x050, 16, 2, CLK_IS_CRITICAL); 173 0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT);
174 174
175static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); 175static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
176 176
@@ -440,7 +440,7 @@ static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
440 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT); 440 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
441 441
442static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio", 442static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio",
443 0x140, BIT(31), 0); 443 0x140, BIT(31), CLK_SET_RATE_PARENT);
444static SUNXI_CCU_GATE(ac_dig_4x_clk, "ac-dig-4x", "pll-audio-4x", 444static SUNXI_CCU_GATE(ac_dig_4x_clk, "ac-dig-4x", "pll-audio-4x",
445 0x140, BIT(30), 0); 445 0x140, BIT(30), 0);
446static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 446static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
@@ -468,7 +468,7 @@ static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(drc_clk, "drc",
468 0x180, 0, 4, 24, 3, BIT(31), 0); 468 0x180, 0, 4, 24, 3, BIT(31), 0);
469 469
470static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu", 470static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
471 0x1a0, 0, 3, BIT(31), 0); 471 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
472 472
473static const char * const ats_parents[] = { "osc24M", "pll-periph" }; 473static const char * const ats_parents[] = { "osc24M", "pll-periph" };
474static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", ats_parents, 474static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", ats_parents,
@@ -752,6 +752,13 @@ static const struct sunxi_ccu_desc sun8i_a33_ccu_desc = {
752 .num_resets = ARRAY_SIZE(sun8i_a33_ccu_resets), 752 .num_resets = ARRAY_SIZE(sun8i_a33_ccu_resets),
753}; 753};
754 754
755static struct ccu_mux_nb sun8i_a33_cpu_nb = {
756 .common = &cpux_clk.common,
757 .cm = &cpux_clk.mux,
758 .delay_us = 1, /* > 8 clock cycles at 24 MHz */
759 .bypass_index = 1, /* index of 24 MHz oscillator */
760};
761
755static void __init sun8i_a33_ccu_setup(struct device_node *node) 762static void __init sun8i_a33_ccu_setup(struct device_node *node)
756{ 763{
757 void __iomem *reg; 764 void __iomem *reg;
@@ -775,6 +782,9 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
775 writel(val, reg + SUN8I_A33_PLL_MIPI_REG); 782 writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
776 783
777 sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc); 784 sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
785
786 ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
787 &sun8i_a33_cpu_nb);
778} 788}
779CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu", 789CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu",
780 sun8i_a33_ccu_setup); 790 sun8i_a33_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
index 21c427d86f28..a26c8a19fe93 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
@@ -803,6 +803,13 @@ static const struct sunxi_ccu_desc sun8i_h3_ccu_desc = {
803 .num_resets = ARRAY_SIZE(sun8i_h3_ccu_resets), 803 .num_resets = ARRAY_SIZE(sun8i_h3_ccu_resets),
804}; 804};
805 805
806static struct ccu_mux_nb sun8i_h3_cpu_nb = {
807 .common = &cpux_clk.common,
808 .cm = &cpux_clk.mux,
809 .delay_us = 1, /* > 8 clock cycles at 24 MHz */
810 .bypass_index = 1, /* index of 24 MHz oscillator */
811};
812
806static void __init sun8i_h3_ccu_setup(struct device_node *node) 813static void __init sun8i_h3_ccu_setup(struct device_node *node)
807{ 814{
808 void __iomem *reg; 815 void __iomem *reg;
@@ -821,6 +828,9 @@ static void __init sun8i_h3_ccu_setup(struct device_node *node)
821 writel(val | (3 << 16), reg + SUN8I_H3_PLL_AUDIO_REG); 828 writel(val | (3 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
822 829
823 sunxi_ccu_probe(node, reg, &sun8i_h3_ccu_desc); 830 sunxi_ccu_probe(node, reg, &sun8i_h3_ccu_desc);
831
832 ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
833 &sun8i_h3_cpu_nb);
824} 834}
825CLK_OF_DECLARE(sun8i_h3_ccu, "allwinner,sun8i-h3-ccu", 835CLK_OF_DECLARE(sun8i_h3_ccu, "allwinner,sun8i-h3-ccu",
826 sun8i_h3_ccu_setup); 836 sun8i_h3_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
new file mode 100644
index 000000000000..e58706b40ae9
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
@@ -0,0 +1,591 @@
1/*
2 * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
3 *
4 * Based on ccu-sun8i-h3.c, which is:
5 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/clk-provider.h>
18#include <linux/of_address.h>
19
20#include "ccu_common.h"
21#include "ccu_reset.h"
22
23#include "ccu_div.h"
24#include "ccu_gate.h"
25#include "ccu_mp.h"
26#include "ccu_mult.h"
27#include "ccu_nk.h"
28#include "ccu_nkm.h"
29#include "ccu_nkmp.h"
30#include "ccu_nm.h"
31#include "ccu_phase.h"
32
33#include "ccu-sun8i-v3s.h"
34
35static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
36 "osc24M", 0x000,
37 8, 5, /* N */
38 4, 2, /* K */
39 0, 2, /* M */
40 16, 2, /* P */
41 BIT(31), /* gate */
42 BIT(28), /* lock */
43 0);
44
45/*
46 * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
47 * the base (2x, 4x and 8x), and one variable divider (the one true
48 * pll audio).
49 *
50 * We don't have any need for the variable divider for now, so we just
51 * hardcode it to match with the clock names
52 */
53#define SUN8I_V3S_PLL_AUDIO_REG 0x008
54
55static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
56 "osc24M", 0x008,
57 8, 7, /* N */
58 0, 5, /* M */
59 BIT(31), /* gate */
60 BIT(28), /* lock */
61 0);
62
63static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
64 "osc24M", 0x0010,
65 8, 7, /* N */
66 0, 4, /* M */
67 BIT(24), /* frac enable */
68 BIT(25), /* frac select */
69 270000000, /* frac rate 0 */
70 297000000, /* frac rate 1 */
71 BIT(31), /* gate */
72 BIT(28), /* lock */
73 0);
74
75static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
76 "osc24M", 0x0018,
77 8, 7, /* N */
78 0, 4, /* M */
79 BIT(24), /* frac enable */
80 BIT(25), /* frac select */
81 270000000, /* frac rate 0 */
82 297000000, /* frac rate 1 */
83 BIT(31), /* gate */
84 BIT(28), /* lock */
85 0);
86
87static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
88 "osc24M", 0x020,
89 8, 5, /* N */
90 4, 2, /* K */
91 0, 2, /* M */
92 BIT(31), /* gate */
93 BIT(28), /* lock */
94 0);
95
96static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph0_clk, "pll-periph0",
97 "osc24M", 0x028,
98 8, 5, /* N */
99 4, 2, /* K */
100 BIT(31), /* gate */
101 BIT(28), /* lock */
102 2, /* post-div */
103 0);
104
105static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_isp_clk, "pll-isp",
106 "osc24M", 0x002c,
107 8, 7, /* N */
108 0, 4, /* M */
109 BIT(24), /* frac enable */
110 BIT(25), /* frac select */
111 270000000, /* frac rate 0 */
112 297000000, /* frac rate 1 */
113 BIT(31), /* gate */
114 BIT(28), /* lock */
115 0);
116
117static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph1_clk, "pll-periph1",
118 "osc24M", 0x044,
119 8, 5, /* N */
120 4, 2, /* K */
121 BIT(31), /* gate */
122 BIT(28), /* lock */
123 2, /* post-div */
124 0);
125
126static const char * const cpu_parents[] = { "osc32k", "osc24M",
127 "pll-cpu", "pll-cpu" };
128static SUNXI_CCU_MUX(cpu_clk, "cpu", cpu_parents,
129 0x050, 16, 2, CLK_IS_CRITICAL);
130
131static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x050, 0, 2, 0);
132
133static const char * const ahb1_parents[] = { "osc32k", "osc24M",
134 "axi", "pll-periph0" };
135static struct ccu_div ahb1_clk = {
136 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
137
138 .mux = {
139 .shift = 12,
140 .width = 2,
141
142 .variable_prediv = {
143 .index = 3,
144 .shift = 6,
145 .width = 2,
146 },
147 },
148
149 .common = {
150 .reg = 0x054,
151 .features = CCU_FEATURE_VARIABLE_PREDIV,
152 .hw.init = CLK_HW_INIT_PARENTS("ahb1",
153 ahb1_parents,
154 &ccu_div_ops,
155 0),
156 },
157};
158
159static struct clk_div_table apb1_div_table[] = {
160 { .val = 0, .div = 2 },
161 { .val = 1, .div = 2 },
162 { .val = 2, .div = 4 },
163 { .val = 3, .div = 8 },
164 { /* Sentinel */ },
165};
166static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
167 0x054, 8, 2, apb1_div_table, 0);
168
169static const char * const apb2_parents[] = { "osc32k", "osc24M",
170 "pll-periph0", "pll-periph0" };
171static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
172 0, 5, /* M */
173 16, 2, /* P */
174 24, 2, /* mux */
175 0);
176
177static const char * const ahb2_parents[] = { "ahb1", "pll-periph0" };
178static const struct ccu_mux_fixed_prediv ahb2_fixed_predivs[] = {
179 { .index = 1, .div = 2 },
180};
181static struct ccu_mux ahb2_clk = {
182 .mux = {
183 .shift = 0,
184 .width = 1,
185 .fixed_predivs = ahb2_fixed_predivs,
186 .n_predivs = ARRAY_SIZE(ahb2_fixed_predivs),
187 },
188
189 .common = {
190 .reg = 0x05c,
191 .features = CCU_FEATURE_FIXED_PREDIV,
192 .hw.init = CLK_HW_INIT_PARENTS("ahb2",
193 ahb2_parents,
194 &ccu_mux_ops,
195 0),
196 },
197};
198
199static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb1",
200 0x060, BIT(5), 0);
201static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1",
202 0x060, BIT(6), 0);
203static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1",
204 0x060, BIT(8), 0);
205static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1",
206 0x060, BIT(9), 0);
207static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1",
208 0x060, BIT(10), 0);
209static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1",
210 0x060, BIT(14), 0);
211static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb2",
212 0x060, BIT(17), 0);
213static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1",
214 0x060, BIT(19), 0);
215static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1",
216 0x060, BIT(20), 0);
217static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1",
218 0x060, BIT(24), 0);
219static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb1",
220 0x060, BIT(26), 0);
221static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb1",
222 0x060, BIT(29), 0);
223
224static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1",
225 0x064, BIT(0), 0);
226static SUNXI_CCU_GATE(bus_tcon0_clk, "bus-tcon0", "ahb1",
227 0x064, BIT(4), 0);
228static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1",
229 0x064, BIT(8), 0);
230static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "ahb1",
231 0x064, BIT(12), 0);
232
233static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1",
234 0x068, BIT(0), 0);
235static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1",
236 0x068, BIT(5), 0);
237
238static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2",
239 0x06c, BIT(0), 0);
240static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2",
241 0x06c, BIT(1), 0);
242static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2",
243 0x06c, BIT(16), 0);
244static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2",
245 0x06c, BIT(17), 0);
246static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2",
247 0x06c, BIT(18), 0);
248
249static SUNXI_CCU_GATE(bus_ephy_clk, "bus-ephy", "ahb1",
250 0x070, BIT(0), 0);
251static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb1",
252 0x070, BIT(7), 0);
253
254static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0",
255 "pll-periph1" };
256static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
257 0, 4, /* M */
258 16, 2, /* P */
259 24, 2, /* mux */
260 BIT(31), /* gate */
261 0);
262
263static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
264 0x088, 20, 3, 0);
265static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
266 0x088, 8, 3, 0);
267
268static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
269 0, 4, /* M */
270 16, 2, /* P */
271 24, 2, /* mux */
272 BIT(31), /* gate */
273 0);
274
275static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
276 0x08c, 20, 3, 0);
277static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
278 0x08c, 8, 3, 0);
279
280static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
281 0, 4, /* M */
282 16, 2, /* P */
283 24, 2, /* mux */
284 BIT(31), /* gate */
285 0);
286
287static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
288 0x090, 20, 3, 0);
289static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
290 0x090, 8, 3, 0);
291
292static const char * const ce_parents[] = { "osc24M", "pll-periph0", };
293
294static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x09c,
295 0, 4, /* M */
296 16, 2, /* P */
297 24, 2, /* mux */
298 BIT(31), /* gate */
299 0);
300
301static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
302 0, 4, /* M */
303 16, 2, /* P */
304 24, 2, /* mux */
305 BIT(31), /* gate */
306 0);
307
308static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
309 0x0cc, BIT(8), 0);
310static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M",
311 0x0cc, BIT(16), 0);
312
313static const char * const dram_parents[] = { "pll-ddr", "pll-periph0-2x" };
314static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents,
315 0x0f4, 0, 4, 20, 2, CLK_IS_CRITICAL);
316
317static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram",
318 0x100, BIT(0), 0);
319static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "dram",
320 0x100, BIT(1), 0);
321static SUNXI_CCU_GATE(dram_ehci_clk, "dram-ehci", "dram",
322 0x100, BIT(17), 0);
323static SUNXI_CCU_GATE(dram_ohci_clk, "dram-ohci", "dram",
324 0x100, BIT(18), 0);
325
326static const char * const de_parents[] = { "pll-video", "pll-periph0" };
327static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
328 0x104, 0, 4, 24, 2, BIT(31), 0);
329
330static const char * const tcon_parents[] = { "pll-video" };
331static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents,
332 0x118, 0, 4, 24, 3, BIT(31), 0);
333
334static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M",
335 0x130, BIT(31), 0);
336
337static const char * const csi_mclk_parents[] = { "osc24M", "pll-video",
338 "pll-periph0", "pll-periph1" };
339static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk", csi_mclk_parents,
340 0x130, 0, 5, 8, 3, BIT(15), 0);
341
342static const char * const csi1_sclk_parents[] = { "pll-video", "pll-isp" };
343static SUNXI_CCU_M_WITH_MUX_GATE(csi1_sclk_clk, "csi-sclk", csi1_sclk_parents,
344 0x134, 16, 4, 24, 3, BIT(31), 0);
345
346static SUNXI_CCU_M_WITH_MUX_GATE(csi1_mclk_clk, "csi-mclk", csi_mclk_parents,
347 0x134, 0, 5, 8, 3, BIT(15), 0);
348
349static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
350 0x13c, 16, 3, BIT(31), 0);
351
352static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio",
353 0x140, BIT(31), CLK_SET_RATE_PARENT);
354static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
355 0x144, BIT(31), 0);
356
357static const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x",
358 "pll-ddr" };
359static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
360 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
361
362static const char * const mipi_csi_parents[] = { "pll-video", "pll-periph0",
363 "pll-isp" };
364static SUNXI_CCU_M_WITH_MUX_GATE(mipi_csi_clk, "mipi-csi", mipi_csi_parents,
365 0x16c, 0, 3, 24, 2, BIT(31), 0);
366
367static struct ccu_common *sun8i_v3s_ccu_clks[] = {
368 &pll_cpu_clk.common,
369 &pll_audio_base_clk.common,
370 &pll_video_clk.common,
371 &pll_ve_clk.common,
372 &pll_ddr_clk.common,
373 &pll_periph0_clk.common,
374 &pll_isp_clk.common,
375 &pll_periph1_clk.common,
376 &cpu_clk.common,
377 &axi_clk.common,
378 &ahb1_clk.common,
379 &apb1_clk.common,
380 &apb2_clk.common,
381 &ahb2_clk.common,
382 &bus_ce_clk.common,
383 &bus_dma_clk.common,
384 &bus_mmc0_clk.common,
385 &bus_mmc1_clk.common,
386 &bus_mmc2_clk.common,
387 &bus_dram_clk.common,
388 &bus_emac_clk.common,
389 &bus_hstimer_clk.common,
390 &bus_spi0_clk.common,
391 &bus_otg_clk.common,
392 &bus_ehci0_clk.common,
393 &bus_ohci0_clk.common,
394 &bus_ve_clk.common,
395 &bus_tcon0_clk.common,
396 &bus_csi_clk.common,
397 &bus_de_clk.common,
398 &bus_codec_clk.common,
399 &bus_pio_clk.common,
400 &bus_i2c0_clk.common,
401 &bus_i2c1_clk.common,
402 &bus_uart0_clk.common,
403 &bus_uart1_clk.common,
404 &bus_uart2_clk.common,
405 &bus_ephy_clk.common,
406 &bus_dbg_clk.common,
407 &mmc0_clk.common,
408 &mmc0_sample_clk.common,
409 &mmc0_output_clk.common,
410 &mmc1_clk.common,
411 &mmc1_sample_clk.common,
412 &mmc1_output_clk.common,
413 &mmc2_clk.common,
414 &mmc2_sample_clk.common,
415 &mmc2_output_clk.common,
416 &ce_clk.common,
417 &spi0_clk.common,
418 &usb_phy0_clk.common,
419 &usb_ohci0_clk.common,
420 &dram_clk.common,
421 &dram_ve_clk.common,
422 &dram_csi_clk.common,
423 &dram_ohci_clk.common,
424 &dram_ehci_clk.common,
425 &de_clk.common,
426 &tcon_clk.common,
427 &csi_misc_clk.common,
428 &csi0_mclk_clk.common,
429 &csi1_sclk_clk.common,
430 &csi1_mclk_clk.common,
431 &ve_clk.common,
432 &ac_dig_clk.common,
433 &avs_clk.common,
434 &mbus_clk.common,
435 &mipi_csi_clk.common,
436};
437
438/* We hardcode the divider to 4 for now */
439static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
440 "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
441static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
442 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
443static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
444 "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
445static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
446 "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
447static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x",
448 "pll-periph0", 1, 2, 0);
449
450static struct clk_hw_onecell_data sun8i_v3s_hw_clks = {
451 .hws = {
452 [CLK_PLL_CPU] = &pll_cpu_clk.common.hw,
453 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
454 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
455 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
456 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
457 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
458 [CLK_PLL_VIDEO] = &pll_video_clk.common.hw,
459 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
460 [CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
461 [CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw,
462 [CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.hw,
463 [CLK_PLL_ISP] = &pll_isp_clk.common.hw,
464 [CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw,
465 [CLK_CPU] = &cpu_clk.common.hw,
466 [CLK_AXI] = &axi_clk.common.hw,
467 [CLK_AHB1] = &ahb1_clk.common.hw,
468 [CLK_APB1] = &apb1_clk.common.hw,
469 [CLK_APB2] = &apb2_clk.common.hw,
470 [CLK_AHB2] = &ahb2_clk.common.hw,
471 [CLK_BUS_CE] = &bus_ce_clk.common.hw,
472 [CLK_BUS_DMA] = &bus_dma_clk.common.hw,
473 [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw,
474 [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw,
475 [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw,
476 [CLK_BUS_DRAM] = &bus_dram_clk.common.hw,
477 [CLK_BUS_EMAC] = &bus_emac_clk.common.hw,
478 [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw,
479 [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
480 [CLK_BUS_OTG] = &bus_otg_clk.common.hw,
481 [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw,
482 [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw,
483 [CLK_BUS_VE] = &bus_ve_clk.common.hw,
484 [CLK_BUS_TCON0] = &bus_tcon0_clk.common.hw,
485 [CLK_BUS_CSI] = &bus_csi_clk.common.hw,
486 [CLK_BUS_DE] = &bus_de_clk.common.hw,
487 [CLK_BUS_CODEC] = &bus_codec_clk.common.hw,
488 [CLK_BUS_PIO] = &bus_pio_clk.common.hw,
489 [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
490 [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw,
491 [CLK_BUS_UART0] = &bus_uart0_clk.common.hw,
492 [CLK_BUS_UART1] = &bus_uart1_clk.common.hw,
493 [CLK_BUS_UART2] = &bus_uart2_clk.common.hw,
494 [CLK_BUS_EPHY] = &bus_ephy_clk.common.hw,
495 [CLK_BUS_DBG] = &bus_dbg_clk.common.hw,
496 [CLK_MMC0] = &mmc0_clk.common.hw,
497 [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw,
498 [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw,
499 [CLK_MMC1] = &mmc1_clk.common.hw,
500 [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw,
501 [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw,
502 [CLK_CE] = &ce_clk.common.hw,
503 [CLK_SPI0] = &spi0_clk.common.hw,
504 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
505 [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
506 [CLK_DRAM] = &dram_clk.common.hw,
507 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
508 [CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
509 [CLK_DRAM_EHCI] = &dram_ehci_clk.common.hw,
510 [CLK_DRAM_OHCI] = &dram_ohci_clk.common.hw,
511 [CLK_DE] = &de_clk.common.hw,
512 [CLK_TCON0] = &tcon_clk.common.hw,
513 [CLK_CSI_MISC] = &csi_misc_clk.common.hw,
514 [CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw,
515 [CLK_CSI1_SCLK] = &csi1_sclk_clk.common.hw,
516 [CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw,
517 [CLK_VE] = &ve_clk.common.hw,
518 [CLK_AC_DIG] = &ac_dig_clk.common.hw,
519 [CLK_AVS] = &avs_clk.common.hw,
520 [CLK_MBUS] = &mbus_clk.common.hw,
521 [CLK_MIPI_CSI] = &mipi_csi_clk.common.hw,
522 },
523 .num = CLK_NUMBER,
524};
525
526static struct ccu_reset_map sun8i_v3s_ccu_resets[] = {
527 [RST_USB_PHY0] = { 0x0cc, BIT(0) },
528
529 [RST_MBUS] = { 0x0fc, BIT(31) },
530
531 [RST_BUS_CE] = { 0x2c0, BIT(5) },
532 [RST_BUS_DMA] = { 0x2c0, BIT(6) },
533 [RST_BUS_MMC0] = { 0x2c0, BIT(8) },
534 [RST_BUS_MMC1] = { 0x2c0, BIT(9) },
535 [RST_BUS_MMC2] = { 0x2c0, BIT(10) },
536 [RST_BUS_DRAM] = { 0x2c0, BIT(14) },
537 [RST_BUS_EMAC] = { 0x2c0, BIT(17) },
538 [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) },
539 [RST_BUS_SPI0] = { 0x2c0, BIT(20) },
540 [RST_BUS_OTG] = { 0x2c0, BIT(23) },
541 [RST_BUS_EHCI0] = { 0x2c0, BIT(26) },
542 [RST_BUS_OHCI0] = { 0x2c0, BIT(29) },
543
544 [RST_BUS_VE] = { 0x2c4, BIT(0) },
545 [RST_BUS_TCON0] = { 0x2c4, BIT(3) },
546 [RST_BUS_CSI] = { 0x2c4, BIT(8) },
547 [RST_BUS_DE] = { 0x2c4, BIT(12) },
548 [RST_BUS_DBG] = { 0x2c4, BIT(31) },
549
550 [RST_BUS_EPHY] = { 0x2c8, BIT(2) },
551
552 [RST_BUS_CODEC] = { 0x2d0, BIT(0) },
553
554 [RST_BUS_I2C0] = { 0x2d8, BIT(0) },
555 [RST_BUS_I2C1] = { 0x2d8, BIT(1) },
556 [RST_BUS_UART0] = { 0x2d8, BIT(16) },
557 [RST_BUS_UART1] = { 0x2d8, BIT(17) },
558 [RST_BUS_UART2] = { 0x2d8, BIT(18) },
559};
560
561static const struct sunxi_ccu_desc sun8i_v3s_ccu_desc = {
562 .ccu_clks = sun8i_v3s_ccu_clks,
563 .num_ccu_clks = ARRAY_SIZE(sun8i_v3s_ccu_clks),
564
565 .hw_clks = &sun8i_v3s_hw_clks,
566
567 .resets = sun8i_v3s_ccu_resets,
568 .num_resets = ARRAY_SIZE(sun8i_v3s_ccu_resets),
569};
570
571static void __init sun8i_v3s_ccu_setup(struct device_node *node)
572{
573 void __iomem *reg;
574 u32 val;
575
576 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
577 if (IS_ERR(reg)) {
578 pr_err("%s: Could not map the clock registers\n",
579 of_node_full_name(node));
580 return;
581 }
582
583 /* Force the PLL-Audio-1x divider to 4 */
584 val = readl(reg + SUN8I_V3S_PLL_AUDIO_REG);
585 val &= ~GENMASK(19, 16);
586 writel(val | (3 << 16), reg + SUN8I_V3S_PLL_AUDIO_REG);
587
588 sunxi_ccu_probe(node, reg, &sun8i_v3s_ccu_desc);
589}
590CLK_OF_DECLARE(sun8i_v3s_ccu, "allwinner,sun8i-v3s-ccu",
591 sun8i_v3s_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h
new file mode 100644
index 000000000000..4a4d36fdad96
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
3 *
4 * Based on ccu-sun8i-h3.h, which is:
5 * Copyright (c) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
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 as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#ifndef _CCU_SUN8I_H3_H_
19#define _CCU_SUN8I_H3_H_
20
21#include <dt-bindings/clock/sun8i-v3s-ccu.h>
22#include <dt-bindings/reset/sun8i-v3s-ccu.h>
23
24#define CLK_PLL_CPU 0
25#define CLK_PLL_AUDIO_BASE 1
26#define CLK_PLL_AUDIO 2
27#define CLK_PLL_AUDIO_2X 3
28#define CLK_PLL_AUDIO_4X 4
29#define CLK_PLL_AUDIO_8X 5
30#define CLK_PLL_VIDEO 6
31#define CLK_PLL_VE 7
32#define CLK_PLL_DDR 8
33#define CLK_PLL_PERIPH0 9
34#define CLK_PLL_PERIPH0_2X 10
35#define CLK_PLL_ISP 11
36#define CLK_PLL_PERIPH1 12
37/* Reserve one number for not implemented and not used PLL_DDR1 */
38
39/* The CPU clock is exported */
40
41#define CLK_AXI 15
42#define CLK_AHB1 16
43#define CLK_APB1 17
44#define CLK_APB2 18
45#define CLK_AHB2 19
46
47/* All the bus gates are exported */
48
49/* The first bunch of module clocks are exported */
50
51#define CLK_DRAM 58
52
53/* All the DRAM gates are exported */
54
55/* Some more module clocks are exported */
56
57#define CLK_MBUS 72
58
59/* And the GPU module clock is exported */
60
61#define CLK_NUMBER (CLK_MIPI_CSI + 1)
62
63#endif /* _CCU_SUN8I_H3_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
new file mode 100644
index 000000000000..6d116581c86d
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
@@ -0,0 +1,283 @@
1/*
2 * Copyright (c) 2016 Chen-Yu Tsai. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/clk.h>
15#include <linux/clk-provider.h>
16#include <linux/of_address.h>
17#include <linux/platform_device.h>
18#include <linux/reset.h>
19
20#include "ccu_common.h"
21#include "ccu_div.h"
22#include "ccu_gate.h"
23#include "ccu_reset.h"
24
25#include "ccu-sun9i-a80-de.h"
26
27static SUNXI_CCU_GATE(fe0_clk, "fe0", "fe0-div",
28 0x00, BIT(0), 0);
29static SUNXI_CCU_GATE(fe1_clk, "fe1", "fe1-div",
30 0x00, BIT(1), 0);
31static SUNXI_CCU_GATE(fe2_clk, "fe2", "fe2-div",
32 0x00, BIT(2), 0);
33static SUNXI_CCU_GATE(iep_deu0_clk, "iep-deu0", "de",
34 0x00, BIT(4), 0);
35static SUNXI_CCU_GATE(iep_deu1_clk, "iep-deu1", "de",
36 0x00, BIT(5), 0);
37static SUNXI_CCU_GATE(be0_clk, "be0", "be0-div",
38 0x00, BIT(8), 0);
39static SUNXI_CCU_GATE(be1_clk, "be1", "be1-div",
40 0x00, BIT(9), 0);
41static SUNXI_CCU_GATE(be2_clk, "be2", "be2-div",
42 0x00, BIT(10), 0);
43static SUNXI_CCU_GATE(iep_drc0_clk, "iep-drc0", "de",
44 0x00, BIT(12), 0);
45static SUNXI_CCU_GATE(iep_drc1_clk, "iep-drc1", "de",
46 0x00, BIT(13), 0);
47static SUNXI_CCU_GATE(merge_clk, "merge", "de",
48 0x00, BIT(20), 0);
49
50static SUNXI_CCU_GATE(dram_fe0_clk, "dram-fe0", "sdram",
51 0x04, BIT(0), 0);
52static SUNXI_CCU_GATE(dram_fe1_clk, "dram-fe1", "sdram",
53 0x04, BIT(1), 0);
54static SUNXI_CCU_GATE(dram_fe2_clk, "dram-fe2", "sdram",
55 0x04, BIT(2), 0);
56static SUNXI_CCU_GATE(dram_deu0_clk, "dram-deu0", "sdram",
57 0x04, BIT(4), 0);
58static SUNXI_CCU_GATE(dram_deu1_clk, "dram-deu1", "sdram",
59 0x04, BIT(5), 0);
60static SUNXI_CCU_GATE(dram_be0_clk, "dram-be0", "sdram",
61 0x04, BIT(8), 0);
62static SUNXI_CCU_GATE(dram_be1_clk, "dram-be1", "sdram",
63 0x04, BIT(9), 0);
64static SUNXI_CCU_GATE(dram_be2_clk, "dram-be2", "sdram",
65 0x04, BIT(10), 0);
66static SUNXI_CCU_GATE(dram_drc0_clk, "dram-drc0", "sdram",
67 0x04, BIT(12), 0);
68static SUNXI_CCU_GATE(dram_drc1_clk, "dram-drc1", "sdram",
69 0x04, BIT(13), 0);
70
71static SUNXI_CCU_GATE(bus_fe0_clk, "bus-fe0", "bus-de",
72 0x08, BIT(0), 0);
73static SUNXI_CCU_GATE(bus_fe1_clk, "bus-fe1", "bus-de",
74 0x08, BIT(1), 0);
75static SUNXI_CCU_GATE(bus_fe2_clk, "bus-fe2", "bus-de",
76 0x08, BIT(2), 0);
77static SUNXI_CCU_GATE(bus_deu0_clk, "bus-deu0", "bus-de",
78 0x08, BIT(4), 0);
79static SUNXI_CCU_GATE(bus_deu1_clk, "bus-deu1", "bus-de",
80 0x08, BIT(5), 0);
81static SUNXI_CCU_GATE(bus_be0_clk, "bus-be0", "bus-de",
82 0x08, BIT(8), 0);
83static SUNXI_CCU_GATE(bus_be1_clk, "bus-be1", "bus-de",
84 0x08, BIT(9), 0);
85static SUNXI_CCU_GATE(bus_be2_clk, "bus-be2", "bus-de",
86 0x08, BIT(10), 0);
87static SUNXI_CCU_GATE(bus_drc0_clk, "bus-drc0", "bus-de",
88 0x08, BIT(12), 0);
89static SUNXI_CCU_GATE(bus_drc1_clk, "bus-drc1", "bus-de",
90 0x08, BIT(13), 0);
91
92static SUNXI_CCU_M(fe0_div_clk, "fe0-div", "de", 0x20, 0, 4, 0);
93static SUNXI_CCU_M(fe1_div_clk, "fe1-div", "de", 0x20, 4, 4, 0);
94static SUNXI_CCU_M(fe2_div_clk, "fe2-div", "de", 0x20, 8, 4, 0);
95static SUNXI_CCU_M(be0_div_clk, "be0-div", "de", 0x20, 16, 4, 0);
96static SUNXI_CCU_M(be1_div_clk, "be1-div", "de", 0x20, 20, 4, 0);
97static SUNXI_CCU_M(be2_div_clk, "be2-div", "de", 0x20, 24, 4, 0);
98
99static struct ccu_common *sun9i_a80_de_clks[] = {
100 &fe0_clk.common,
101 &fe1_clk.common,
102 &fe2_clk.common,
103 &iep_deu0_clk.common,
104 &iep_deu1_clk.common,
105 &be0_clk.common,
106 &be1_clk.common,
107 &be2_clk.common,
108 &iep_drc0_clk.common,
109 &iep_drc1_clk.common,
110 &merge_clk.common,
111
112 &dram_fe0_clk.common,
113 &dram_fe1_clk.common,
114 &dram_fe2_clk.common,
115 &dram_deu0_clk.common,
116 &dram_deu1_clk.common,
117 &dram_be0_clk.common,
118 &dram_be1_clk.common,
119 &dram_be2_clk.common,
120 &dram_drc0_clk.common,
121 &dram_drc1_clk.common,
122
123 &bus_fe0_clk.common,
124 &bus_fe1_clk.common,
125 &bus_fe2_clk.common,
126 &bus_deu0_clk.common,
127 &bus_deu1_clk.common,
128 &bus_be0_clk.common,
129 &bus_be1_clk.common,
130 &bus_be2_clk.common,
131 &bus_drc0_clk.common,
132 &bus_drc1_clk.common,
133
134 &fe0_div_clk.common,
135 &fe1_div_clk.common,
136 &fe2_div_clk.common,
137 &be0_div_clk.common,
138 &be1_div_clk.common,
139 &be2_div_clk.common,
140};
141
142static struct clk_hw_onecell_data sun9i_a80_de_hw_clks = {
143 .hws = {
144 [CLK_FE0] = &fe0_clk.common.hw,
145 [CLK_FE1] = &fe1_clk.common.hw,
146 [CLK_FE2] = &fe2_clk.common.hw,
147 [CLK_IEP_DEU0] = &iep_deu0_clk.common.hw,
148 [CLK_IEP_DEU1] = &iep_deu1_clk.common.hw,
149 [CLK_BE0] = &be0_clk.common.hw,
150 [CLK_BE1] = &be1_clk.common.hw,
151 [CLK_BE2] = &be2_clk.common.hw,
152 [CLK_IEP_DRC0] = &iep_drc0_clk.common.hw,
153 [CLK_IEP_DRC1] = &iep_drc1_clk.common.hw,
154 [CLK_MERGE] = &merge_clk.common.hw,
155
156 [CLK_DRAM_FE0] = &dram_fe0_clk.common.hw,
157 [CLK_DRAM_FE1] = &dram_fe1_clk.common.hw,
158 [CLK_DRAM_FE2] = &dram_fe2_clk.common.hw,
159 [CLK_DRAM_DEU0] = &dram_deu0_clk.common.hw,
160 [CLK_DRAM_DEU1] = &dram_deu1_clk.common.hw,
161 [CLK_DRAM_BE0] = &dram_be0_clk.common.hw,
162 [CLK_DRAM_BE1] = &dram_be1_clk.common.hw,
163 [CLK_DRAM_BE2] = &dram_be2_clk.common.hw,
164 [CLK_DRAM_DRC0] = &dram_drc0_clk.common.hw,
165 [CLK_DRAM_DRC1] = &dram_drc1_clk.common.hw,
166
167 [CLK_BUS_FE0] = &bus_fe0_clk.common.hw,
168 [CLK_BUS_FE1] = &bus_fe1_clk.common.hw,
169 [CLK_BUS_FE2] = &bus_fe2_clk.common.hw,
170 [CLK_BUS_DEU0] = &bus_deu0_clk.common.hw,
171 [CLK_BUS_DEU1] = &bus_deu1_clk.common.hw,
172 [CLK_BUS_BE0] = &bus_be0_clk.common.hw,
173 [CLK_BUS_BE1] = &bus_be1_clk.common.hw,
174 [CLK_BUS_BE2] = &bus_be2_clk.common.hw,
175 [CLK_BUS_DRC0] = &bus_drc0_clk.common.hw,
176 [CLK_BUS_DRC1] = &bus_drc1_clk.common.hw,
177
178 [CLK_FE0_DIV] = &fe0_div_clk.common.hw,
179 [CLK_FE1_DIV] = &fe1_div_clk.common.hw,
180 [CLK_FE2_DIV] = &fe2_div_clk.common.hw,
181 [CLK_BE0_DIV] = &be0_div_clk.common.hw,
182 [CLK_BE1_DIV] = &be1_div_clk.common.hw,
183 [CLK_BE2_DIV] = &be2_div_clk.common.hw,
184 },
185 .num = CLK_NUMBER,
186};
187
188static struct ccu_reset_map sun9i_a80_de_resets[] = {
189 [RST_FE0] = { 0x0c, BIT(0) },
190 [RST_FE1] = { 0x0c, BIT(1) },
191 [RST_FE2] = { 0x0c, BIT(2) },
192 [RST_DEU0] = { 0x0c, BIT(4) },
193 [RST_DEU1] = { 0x0c, BIT(5) },
194 [RST_BE0] = { 0x0c, BIT(8) },
195 [RST_BE1] = { 0x0c, BIT(9) },
196 [RST_BE2] = { 0x0c, BIT(10) },
197 [RST_DRC0] = { 0x0c, BIT(12) },
198 [RST_DRC1] = { 0x0c, BIT(13) },
199 [RST_MERGE] = { 0x0c, BIT(20) },
200};
201
202static const struct sunxi_ccu_desc sun9i_a80_de_clk_desc = {
203 .ccu_clks = sun9i_a80_de_clks,
204 .num_ccu_clks = ARRAY_SIZE(sun9i_a80_de_clks),
205
206 .hw_clks = &sun9i_a80_de_hw_clks,
207
208 .resets = sun9i_a80_de_resets,
209 .num_resets = ARRAY_SIZE(sun9i_a80_de_resets),
210};
211
212static int sun9i_a80_de_clk_probe(struct platform_device *pdev)
213{
214 struct resource *res;
215 struct clk *bus_clk;
216 struct reset_control *rstc;
217 void __iomem *reg;
218 int ret;
219
220 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
221 reg = devm_ioremap_resource(&pdev->dev, res);
222 if (IS_ERR(reg))
223 return PTR_ERR(reg);
224
225 bus_clk = devm_clk_get(&pdev->dev, "bus");
226 if (IS_ERR(bus_clk)) {
227 ret = PTR_ERR(bus_clk);
228 if (ret != -EPROBE_DEFER)
229 dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
230 return ret;
231 }
232
233 rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
234 if (IS_ERR(rstc)) {
235 ret = PTR_ERR(rstc);
236 if (ret != -EPROBE_DEFER)
237 dev_err(&pdev->dev,
238 "Couldn't get reset control: %d\n", ret);
239 return ret;
240 }
241
242 /* The bus clock needs to be enabled for us to access the registers */
243 ret = clk_prepare_enable(bus_clk);
244 if (ret) {
245 dev_err(&pdev->dev, "Couldn't enable bus clk: %d\n", ret);
246 return ret;
247 }
248
249 /* The reset control needs to be asserted for the controls to work */
250 ret = reset_control_deassert(rstc);
251 if (ret) {
252 dev_err(&pdev->dev,
253 "Couldn't deassert reset control: %d\n", ret);
254 goto err_disable_clk;
255 }
256
257 ret = sunxi_ccu_probe(pdev->dev.of_node, reg,
258 &sun9i_a80_de_clk_desc);
259 if (ret)
260 goto err_assert_reset;
261
262 return 0;
263
264err_assert_reset:
265 reset_control_assert(rstc);
266err_disable_clk:
267 clk_disable_unprepare(bus_clk);
268 return ret;
269}
270
271static const struct of_device_id sun9i_a80_de_clk_ids[] = {
272 { .compatible = "allwinner,sun9i-a80-de-clks" },
273 { }
274};
275
276static struct platform_driver sun9i_a80_de_clk_driver = {
277 .probe = sun9i_a80_de_clk_probe,
278 .driver = {
279 .name = "sun9i-a80-de-clks",
280 .of_match_table = sun9i_a80_de_clk_ids,
281 },
282};
283builtin_platform_driver(sun9i_a80_de_clk_driver);
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.h b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.h
new file mode 100644
index 000000000000..a4769041e40f
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright 2016 Chen-Yu Tsai
3 *
4 * Chen-Yu Tsai <wens@csie.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _CCU_SUN9I_A80_DE_H_
18#define _CCU_SUN9I_A80_DE_H_
19
20#include <dt-bindings/clock/sun9i-a80-de.h>
21#include <dt-bindings/reset/sun9i-a80-de.h>
22
23/* Intermediary clock dividers are not exported */
24#define CLK_FE0_DIV 31
25#define CLK_FE1_DIV 32
26#define CLK_FE2_DIV 33
27#define CLK_BE0_DIV 34
28#define CLK_BE1_DIV 35
29#define CLK_BE2_DIV 36
30
31#define CLK_NUMBER (CLK_BE2_DIV + 1)
32
33#endif /* _CCU_SUN9I_A80_DE_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c
new file mode 100644
index 000000000000..1d76f24f7df3
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c
@@ -0,0 +1,144 @@
1/*
2 * Copyright (c) 2016 Chen-Yu Tsai. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/clk.h>
15#include <linux/clk-provider.h>
16#include <linux/of_address.h>
17#include <linux/platform_device.h>
18
19#include "ccu_common.h"
20#include "ccu_gate.h"
21#include "ccu_reset.h"
22
23#include "ccu-sun9i-a80-usb.h"
24
25static SUNXI_CCU_GATE(bus_hci0_clk, "bus-hci0", "bus-usb", 0x0, BIT(1), 0);
26static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M", 0x0, BIT(2), 0);
27static SUNXI_CCU_GATE(bus_hci1_clk, "bus-hci1", "bus-usb", 0x0, BIT(3), 0);
28static SUNXI_CCU_GATE(bus_hci2_clk, "bus-hci2", "bus-usb", 0x0, BIT(5), 0);
29static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc24M", 0x0, BIT(6), 0);
30
31static SUNXI_CCU_GATE(usb0_phy_clk, "usb0-phy", "osc24M", 0x4, BIT(1), 0);
32static SUNXI_CCU_GATE(usb1_hsic_clk, "usb1-hsic", "osc24M", 0x4, BIT(2), 0);
33static SUNXI_CCU_GATE(usb1_phy_clk, "usb1-phy", "osc24M", 0x4, BIT(3), 0);
34static SUNXI_CCU_GATE(usb2_hsic_clk, "usb2-hsic", "osc24M", 0x4, BIT(4), 0);
35static SUNXI_CCU_GATE(usb2_phy_clk, "usb2-phy", "osc24M", 0x4, BIT(5), 0);
36static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "osc24M", 0x4, BIT(10), 0);
37
38static struct ccu_common *sun9i_a80_usb_clks[] = {
39 &bus_hci0_clk.common,
40 &usb_ohci0_clk.common,
41 &bus_hci1_clk.common,
42 &bus_hci2_clk.common,
43 &usb_ohci2_clk.common,
44
45 &usb0_phy_clk.common,
46 &usb1_hsic_clk.common,
47 &usb1_phy_clk.common,
48 &usb2_hsic_clk.common,
49 &usb2_phy_clk.common,
50 &usb_hsic_clk.common,
51};
52
53static struct clk_hw_onecell_data sun9i_a80_usb_hw_clks = {
54 .hws = {
55 [CLK_BUS_HCI0] = &bus_hci0_clk.common.hw,
56 [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
57 [CLK_BUS_HCI1] = &bus_hci1_clk.common.hw,
58 [CLK_BUS_HCI2] = &bus_hci2_clk.common.hw,
59 [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw,
60
61 [CLK_USB0_PHY] = &usb0_phy_clk.common.hw,
62 [CLK_USB1_HSIC] = &usb1_hsic_clk.common.hw,
63 [CLK_USB1_PHY] = &usb1_phy_clk.common.hw,
64 [CLK_USB2_HSIC] = &usb2_hsic_clk.common.hw,
65 [CLK_USB2_PHY] = &usb2_phy_clk.common.hw,
66 [CLK_USB_HSIC] = &usb_hsic_clk.common.hw,
67 },
68 .num = CLK_NUMBER,
69};
70
71static struct ccu_reset_map sun9i_a80_usb_resets[] = {
72 [RST_USB0_HCI] = { 0x0, BIT(17) },
73 [RST_USB1_HCI] = { 0x0, BIT(18) },
74 [RST_USB2_HCI] = { 0x0, BIT(19) },
75
76 [RST_USB0_PHY] = { 0x4, BIT(17) },
77 [RST_USB1_HSIC] = { 0x4, BIT(18) },
78 [RST_USB1_PHY] = { 0x4, BIT(19) },
79 [RST_USB2_HSIC] = { 0x4, BIT(20) },
80 [RST_USB2_PHY] = { 0x4, BIT(21) },
81};
82
83static const struct sunxi_ccu_desc sun9i_a80_usb_clk_desc = {
84 .ccu_clks = sun9i_a80_usb_clks,
85 .num_ccu_clks = ARRAY_SIZE(sun9i_a80_usb_clks),
86
87 .hw_clks = &sun9i_a80_usb_hw_clks,
88
89 .resets = sun9i_a80_usb_resets,
90 .num_resets = ARRAY_SIZE(sun9i_a80_usb_resets),
91};
92
93static int sun9i_a80_usb_clk_probe(struct platform_device *pdev)
94{
95 struct resource *res;
96 struct clk *bus_clk;
97 void __iomem *reg;
98 int ret;
99
100 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
101 reg = devm_ioremap_resource(&pdev->dev, res);
102 if (IS_ERR(reg))
103 return PTR_ERR(reg);
104
105 bus_clk = devm_clk_get(&pdev->dev, "bus");
106 if (IS_ERR(bus_clk)) {
107 ret = PTR_ERR(bus_clk);
108 if (ret != -EPROBE_DEFER)
109 dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
110 return ret;
111 }
112
113 /* The bus clock needs to be enabled for us to access the registers */
114 ret = clk_prepare_enable(bus_clk);
115 if (ret) {
116 dev_err(&pdev->dev, "Couldn't enable bus clk: %d\n", ret);
117 return ret;
118 }
119
120 ret = sunxi_ccu_probe(pdev->dev.of_node, reg,
121 &sun9i_a80_usb_clk_desc);
122 if (ret)
123 goto err_disable_clk;
124
125 return 0;
126
127err_disable_clk:
128 clk_disable_unprepare(bus_clk);
129 return ret;
130}
131
132static const struct of_device_id sun9i_a80_usb_clk_ids[] = {
133 { .compatible = "allwinner,sun9i-a80-usb-clks" },
134 { }
135};
136
137static struct platform_driver sun9i_a80_usb_clk_driver = {
138 .probe = sun9i_a80_usb_clk_probe,
139 .driver = {
140 .name = "sun9i-a80-usb-clks",
141 .of_match_table = sun9i_a80_usb_clk_ids,
142 },
143};
144builtin_platform_driver(sun9i_a80_usb_clk_driver);
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.h b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.h
new file mode 100644
index 000000000000..a184280ba854
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.h
@@ -0,0 +1,25 @@
1/*
2 * Copyright 2016 Chen-Yu Tsai
3 *
4 * Chen-Yu Tsai <wens@csie.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _CCU_SUN9I_A80_USB_H_
18#define _CCU_SUN9I_A80_USB_H_
19
20#include <dt-bindings/clock/sun9i-a80-usb.h>
21#include <dt-bindings/reset/sun9i-a80-usb.h>
22
23#define CLK_NUMBER (CLK_USB_HSIC + 1)
24
25#endif /* _CCU_SUN9I_A80_USB_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
new file mode 100644
index 000000000000..e13e313ce4f5
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
@@ -0,0 +1,1223 @@
1/*
2 * Copyright (c) 2016 Chen-Yu Tsai. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/clk-provider.h>
15#include <linux/of_address.h>
16#include <linux/platform_device.h>
17
18#include "ccu_common.h"
19#include "ccu_reset.h"
20
21#include "ccu_div.h"
22#include "ccu_gate.h"
23#include "ccu_mp.h"
24#include "ccu_nkmp.h"
25#include "ccu_nm.h"
26#include "ccu_phase.h"
27
28#include "ccu-sun9i-a80.h"
29
30#define CCU_SUN9I_LOCK_REG 0x09c
31
32static struct clk_div_table pll_cpux_p_div_table[] = {
33 { .val = 0, .div = 1 },
34 { .val = 1, .div = 4 },
35 { /* Sentinel */ },
36};
37
38/*
39 * The CPU PLLs are actually NP clocks, but P is /1 or /4, so here we
40 * use the NM clocks with a divider table for M.
41 */
42static struct ccu_nm pll_c0cpux_clk = {
43 .enable = BIT(31),
44 .lock = BIT(0),
45 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
46 .m = _SUNXI_CCU_DIV_TABLE(16, 1, pll_cpux_p_div_table),
47 .common = {
48 .reg = 0x000,
49 .lock_reg = CCU_SUN9I_LOCK_REG,
50 .features = CCU_FEATURE_LOCK_REG,
51 .hw.init = CLK_HW_INIT("pll-c0cpux", "osc24M",
52 &ccu_nm_ops, CLK_SET_RATE_UNGATE),
53 },
54};
55
56static struct ccu_nm pll_c1cpux_clk = {
57 .enable = BIT(31),
58 .lock = BIT(1),
59 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
60 .m = _SUNXI_CCU_DIV_TABLE(16, 1, pll_cpux_p_div_table),
61 .common = {
62 .reg = 0x004,
63 .lock_reg = CCU_SUN9I_LOCK_REG,
64 .features = CCU_FEATURE_LOCK_REG,
65 .hw.init = CLK_HW_INIT("pll-c1cpux", "osc24M",
66 &ccu_nm_ops, CLK_SET_RATE_UNGATE),
67 },
68};
69
70/*
71 * The Audio PLL has d1, d2 dividers in addition to the usual N, M
72 * factors. Since we only need 2 frequencies from this PLL: 22.5792 MHz
73 * and 24.576 MHz, ignore them for now. Enforce the default for them,
74 * which is d1 = 0, d2 = 1.
75 */
76#define SUN9I_A80_PLL_AUDIO_REG 0x008
77
78static struct ccu_nm pll_audio_clk = {
79 .enable = BIT(31),
80 .lock = BIT(2),
81 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
82 .m = _SUNXI_CCU_DIV_OFFSET(0, 6, 0),
83 .common = {
84 .reg = 0x008,
85 .lock_reg = CCU_SUN9I_LOCK_REG,
86 .features = CCU_FEATURE_LOCK_REG,
87 .hw.init = CLK_HW_INIT("pll-audio", "osc24M",
88 &ccu_nm_ops, CLK_SET_RATE_UNGATE),
89 },
90};
91
92/* Some PLLs are input * N / div1 / div2. Model them as NKMP with no K */
93static struct ccu_nkmp pll_periph0_clk = {
94 .enable = BIT(31),
95 .lock = BIT(3),
96 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
97 .m = _SUNXI_CCU_DIV(16, 1), /* input divider */
98 .p = _SUNXI_CCU_DIV(18, 1), /* output divider */
99 .common = {
100 .reg = 0x00c,
101 .lock_reg = CCU_SUN9I_LOCK_REG,
102 .features = CCU_FEATURE_LOCK_REG,
103 .hw.init = CLK_HW_INIT("pll-periph0", "osc24M",
104 &ccu_nkmp_ops,
105 CLK_SET_RATE_UNGATE),
106 },
107};
108
109static struct ccu_nkmp pll_ve_clk = {
110 .enable = BIT(31),
111 .lock = BIT(4),
112 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
113 .m = _SUNXI_CCU_DIV(16, 1), /* input divider */
114 .p = _SUNXI_CCU_DIV(18, 1), /* output divider */
115 .common = {
116 .reg = 0x010,
117 .lock_reg = CCU_SUN9I_LOCK_REG,
118 .features = CCU_FEATURE_LOCK_REG,
119 .hw.init = CLK_HW_INIT("pll-ve", "osc24M",
120 &ccu_nkmp_ops,
121 CLK_SET_RATE_UNGATE),
122 },
123};
124
125static struct ccu_nkmp pll_ddr_clk = {
126 .enable = BIT(31),
127 .lock = BIT(5),
128 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
129 .m = _SUNXI_CCU_DIV(16, 1), /* input divider */
130 .p = _SUNXI_CCU_DIV(18, 1), /* output divider */
131 .common = {
132 .reg = 0x014,
133 .lock_reg = CCU_SUN9I_LOCK_REG,
134 .features = CCU_FEATURE_LOCK_REG,
135 .hw.init = CLK_HW_INIT("pll-ddr", "osc24M",
136 &ccu_nkmp_ops,
137 CLK_SET_RATE_UNGATE),
138 },
139};
140
141static struct ccu_nm pll_video0_clk = {
142 .enable = BIT(31),
143 .lock = BIT(6),
144 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
145 .m = _SUNXI_CCU_DIV(16, 1), /* input divider */
146 .common = {
147 .reg = 0x018,
148 .lock_reg = CCU_SUN9I_LOCK_REG,
149 .features = CCU_FEATURE_LOCK_REG,
150 .hw.init = CLK_HW_INIT("pll-video0", "osc24M",
151 &ccu_nm_ops,
152 CLK_SET_RATE_UNGATE),
153 },
154};
155
156static struct ccu_nkmp pll_video1_clk = {
157 .enable = BIT(31),
158 .lock = BIT(7),
159 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
160 .m = _SUNXI_CCU_DIV(16, 1), /* input divider */
161 .p = _SUNXI_CCU_DIV(0, 2), /* external divider p */
162 .common = {
163 .reg = 0x01c,
164 .lock_reg = CCU_SUN9I_LOCK_REG,
165 .features = CCU_FEATURE_LOCK_REG,
166 .hw.init = CLK_HW_INIT("pll-video1", "osc24M",
167 &ccu_nkmp_ops,
168 CLK_SET_RATE_UNGATE),
169 },
170};
171
172static struct ccu_nkmp pll_gpu_clk = {
173 .enable = BIT(31),
174 .lock = BIT(8),
175 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
176 .m = _SUNXI_CCU_DIV(16, 1), /* input divider */
177 .p = _SUNXI_CCU_DIV(18, 1), /* output divider */
178 .common = {
179 .reg = 0x020,
180 .lock_reg = CCU_SUN9I_LOCK_REG,
181 .features = CCU_FEATURE_LOCK_REG,
182 .hw.init = CLK_HW_INIT("pll-gpu", "osc24M",
183 &ccu_nkmp_ops,
184 CLK_SET_RATE_UNGATE),
185 },
186};
187
188static struct ccu_nkmp pll_de_clk = {
189 .enable = BIT(31),
190 .lock = BIT(9),
191 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
192 .m = _SUNXI_CCU_DIV(16, 1), /* input divider */
193 .p = _SUNXI_CCU_DIV(18, 1), /* output divider */
194 .common = {
195 .reg = 0x024,
196 .lock_reg = CCU_SUN9I_LOCK_REG,
197 .features = CCU_FEATURE_LOCK_REG,
198 .hw.init = CLK_HW_INIT("pll-de", "osc24M",
199 &ccu_nkmp_ops,
200 CLK_SET_RATE_UNGATE),
201 },
202};
203
204static struct ccu_nkmp pll_isp_clk = {
205 .enable = BIT(31),
206 .lock = BIT(10),
207 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
208 .m = _SUNXI_CCU_DIV(16, 1), /* input divider */
209 .p = _SUNXI_CCU_DIV(18, 1), /* output divider */
210 .common = {
211 .reg = 0x028,
212 .lock_reg = CCU_SUN9I_LOCK_REG,
213 .features = CCU_FEATURE_LOCK_REG,
214 .hw.init = CLK_HW_INIT("pll-isp", "osc24M",
215 &ccu_nkmp_ops,
216 CLK_SET_RATE_UNGATE),
217 },
218};
219
220static struct ccu_nkmp pll_periph1_clk = {
221 .enable = BIT(31),
222 .lock = BIT(11),
223 .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
224 .m = _SUNXI_CCU_DIV(16, 1), /* input divider */
225 .p = _SUNXI_CCU_DIV(18, 1), /* output divider */
226 .common = {
227 .reg = 0x028,
228 .lock_reg = CCU_SUN9I_LOCK_REG,
229 .features = CCU_FEATURE_LOCK_REG,
230 .hw.init = CLK_HW_INIT("pll-periph1", "osc24M",
231 &ccu_nkmp_ops,
232 CLK_SET_RATE_UNGATE),
233 },
234};
235
236static const char * const c0cpux_parents[] = { "osc24M", "pll-c0cpux" };
237static SUNXI_CCU_MUX(c0cpux_clk, "c0cpux", c0cpux_parents,
238 0x50, 0, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
239
240static const char * const c1cpux_parents[] = { "osc24M", "pll-c1cpux" };
241static SUNXI_CCU_MUX(c1cpux_clk, "c1cpux", c1cpux_parents,
242 0x50, 8, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
243
244static struct clk_div_table axi_div_table[] = {
245 { .val = 0, .div = 1 },
246 { .val = 1, .div = 2 },
247 { .val = 2, .div = 3 },
248 { .val = 3, .div = 4 },
249 { .val = 4, .div = 4 },
250 { .val = 5, .div = 4 },
251 { .val = 6, .div = 4 },
252 { .val = 7, .div = 4 },
253 { /* Sentinel */ },
254};
255
256static SUNXI_CCU_M(atb0_clk, "atb0", "c0cpux", 0x054, 8, 2, 0);
257
258static SUNXI_CCU_DIV_TABLE(axi0_clk, "axi0", "c0cpux",
259 0x054, 0, 3, axi_div_table, 0);
260
261static SUNXI_CCU_M(atb1_clk, "atb1", "c1cpux", 0x058, 8, 2, 0);
262
263static SUNXI_CCU_DIV_TABLE(axi1_clk, "axi1", "c1cpux",
264 0x058, 0, 3, axi_div_table, 0);
265
266static const char * const gtbus_parents[] = { "osc24M", "pll-periph0",
267 "pll-periph1", "pll-periph1" };
268static SUNXI_CCU_M_WITH_MUX(gtbus_clk, "gtbus", gtbus_parents,
269 0x05c, 0, 2, 24, 2, CLK_IS_CRITICAL);
270
271static const char * const ahb_parents[] = { "gtbus", "pll-periph0",
272 "pll-periph1", "pll-periph1" };
273static struct ccu_div ahb0_clk = {
274 .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
275 .mux = _SUNXI_CCU_MUX(24, 2),
276 .common = {
277 .reg = 0x060,
278 .hw.init = CLK_HW_INIT_PARENTS("ahb0",
279 ahb_parents,
280 &ccu_div_ops,
281 0),
282 },
283};
284
285static struct ccu_div ahb1_clk = {
286 .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
287 .mux = _SUNXI_CCU_MUX(24, 2),
288 .common = {
289 .reg = 0x064,
290 .hw.init = CLK_HW_INIT_PARENTS("ahb1",
291 ahb_parents,
292 &ccu_div_ops,
293 0),
294 },
295};
296
297static struct ccu_div ahb2_clk = {
298 .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
299 .mux = _SUNXI_CCU_MUX(24, 2),
300 .common = {
301 .reg = 0x068,
302 .hw.init = CLK_HW_INIT_PARENTS("ahb2",
303 ahb_parents,
304 &ccu_div_ops,
305 0),
306 },
307};
308
309static const char * const apb_parents[] = { "osc24M", "pll-periph0" };
310
311static struct ccu_div apb0_clk = {
312 .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
313 .mux = _SUNXI_CCU_MUX(24, 1),
314 .common = {
315 .reg = 0x070,
316 .hw.init = CLK_HW_INIT_PARENTS("apb0",
317 apb_parents,
318 &ccu_div_ops,
319 0),
320 },
321};
322
323static struct ccu_div apb1_clk = {
324 .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
325 .mux = _SUNXI_CCU_MUX(24, 1),
326 .common = {
327 .reg = 0x074,
328 .hw.init = CLK_HW_INIT_PARENTS("apb1",
329 apb_parents,
330 &ccu_div_ops,
331 0),
332 },
333};
334
335static struct ccu_div cci400_clk = {
336 .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
337 .mux = _SUNXI_CCU_MUX(24, 2),
338 .common = {
339 .reg = 0x078,
340 .hw.init = CLK_HW_INIT_PARENTS("cci400",
341 ahb_parents,
342 &ccu_div_ops,
343 CLK_IS_CRITICAL),
344 },
345};
346
347static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", apb_parents,
348 0x080, 0, 3, 24, 2, BIT(31), 0);
349
350static SUNXI_CCU_M_WITH_MUX_GATE(trace_clk, "trace", apb_parents,
351 0x084, 0, 3, 24, 2, BIT(31), 0);
352
353static const char * const out_parents[] = { "osc24M", "osc32k", "osc24M" };
354static const struct ccu_mux_fixed_prediv out_prediv = {
355 .index = 0, .div = 750
356};
357
358static struct ccu_mp out_a_clk = {
359 .enable = BIT(31),
360 .m = _SUNXI_CCU_DIV(8, 5),
361 .p = _SUNXI_CCU_DIV(20, 2),
362 .mux = {
363 .shift = 24,
364 .width = 4,
365 .fixed_predivs = &out_prediv,
366 .n_predivs = 1,
367 },
368 .common = {
369 .reg = 0x180,
370 .features = CCU_FEATURE_FIXED_PREDIV,
371 .hw.init = CLK_HW_INIT_PARENTS("out-a",
372 out_parents,
373 &ccu_mp_ops,
374 0),
375 },
376};
377
378static struct ccu_mp out_b_clk = {
379 .enable = BIT(31),
380 .m = _SUNXI_CCU_DIV(8, 5),
381 .p = _SUNXI_CCU_DIV(20, 2),
382 .mux = {
383 .shift = 24,
384 .width = 4,
385 .fixed_predivs = &out_prediv,
386 .n_predivs = 1,
387 },
388 .common = {
389 .reg = 0x184,
390 .features = CCU_FEATURE_FIXED_PREDIV,
391 .hw.init = CLK_HW_INIT_PARENTS("out-b",
392 out_parents,
393 &ccu_mp_ops,
394 0),
395 },
396};
397
398static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0" };
399
400static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_0_clk, "nand0-0", mod0_default_parents,
401 0x400,
402 0, 4, /* M */
403 16, 2, /* P */
404 24, 4, /* mux */
405 BIT(31), /* gate */
406 0);
407
408static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_1_clk, "nand0-1", mod0_default_parents,
409 0x404,
410 0, 4, /* M */
411 16, 2, /* P */
412 24, 4, /* mux */
413 BIT(31), /* gate */
414 0);
415
416static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_0_clk, "nand1-0", mod0_default_parents,
417 0x408,
418 0, 4, /* M */
419 16, 2, /* P */
420 24, 4, /* mux */
421 BIT(31), /* gate */
422 0);
423
424static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_1_clk, "nand1-1", mod0_default_parents,
425 0x40c,
426 0, 4, /* M */
427 16, 2, /* P */
428 24, 4, /* mux */
429 BIT(31), /* gate */
430 0);
431
432static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents,
433 0x410,
434 0, 4, /* M */
435 16, 2, /* P */
436 24, 4, /* mux */
437 BIT(31), /* gate */
438 0);
439
440static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0-sample", "mmc0",
441 0x410, 20, 3, 0);
442static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0-output", "mmc0",
443 0x410, 8, 3, 0);
444
445static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents,
446 0x414,
447 0, 4, /* M */
448 16, 2, /* P */
449 24, 4, /* mux */
450 BIT(31), /* gate */
451 0);
452
453static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1-sample", "mmc1",
454 0x414, 20, 3, 0);
455static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1-output", "mmc1",
456 0x414, 8, 3, 0);
457
458static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents,
459 0x418,
460 0, 4, /* M */
461 16, 2, /* P */
462 24, 4, /* mux */
463 BIT(31), /* gate */
464 0);
465
466static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2-sample", "mmc2",
467 0x418, 20, 3, 0);
468static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2-output", "mmc2",
469 0x418, 8, 3, 0);
470
471static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents,
472 0x41c,
473 0, 4, /* M */
474 16, 2, /* P */
475 24, 4, /* mux */
476 BIT(31), /* gate */
477 0);
478
479static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3-sample", "mmc3",
480 0x41c, 20, 3, 0);
481static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3-output", "mmc3",
482 0x41c, 8, 3, 0);
483
484static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents,
485 0x428,
486 0, 4, /* M */
487 16, 2, /* P */
488 24, 4, /* mux */
489 BIT(31), /* gate */
490 0);
491
492static const char * const ss_parents[] = { "osc24M", "pll-periph",
493 "pll-periph1" };
494static const u8 ss_table[] = { 0, 1, 13 };
495static struct ccu_mp ss_clk = {
496 .enable = BIT(31),
497 .m = _SUNXI_CCU_DIV(0, 4),
498 .p = _SUNXI_CCU_DIV(16, 2),
499 .mux = _SUNXI_CCU_MUX_TABLE(24, 4, ss_table),
500 .common = {
501 .reg = 0x42c,
502 .hw.init = CLK_HW_INIT_PARENTS("ss",
503 ss_parents,
504 &ccu_mp_ops,
505 0),
506 },
507};
508
509static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents,
510 0x430,
511 0, 4, /* M */
512 16, 2, /* P */
513 24, 4, /* mux */
514 BIT(31), /* gate */
515 0);
516
517static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents,
518 0x434,
519 0, 4, /* M */
520 16, 2, /* P */
521 24, 4, /* mux */
522 BIT(31), /* gate */
523 0);
524
525static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents,
526 0x438,
527 0, 4, /* M */
528 16, 2, /* P */
529 24, 4, /* mux */
530 BIT(31), /* gate */
531 0);
532
533static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents,
534 0x43c,
535 0, 4, /* M */
536 16, 2, /* P */
537 24, 4, /* mux */
538 BIT(31), /* gate */
539 0);
540
541static SUNXI_CCU_M_WITH_GATE(i2s0_clk, "i2s0", "pll-audio",
542 0x440, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
543static SUNXI_CCU_M_WITH_GATE(i2s1_clk, "i2s1", "pll-audio",
544 0x444, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
545static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
546 0x44c, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
547
548static const char * const sdram_parents[] = { "pll-periph0", "pll-ddr" };
549static const u8 sdram_table[] = { 0, 3 };
550
551static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(sdram_clk, "sdram",
552 sdram_parents, sdram_table,
553 0x484,
554 8, 4, /* M */
555 12, 4, /* mux */
556 0, /* no gate */
557 CLK_IS_CRITICAL);
558
559static SUNXI_CCU_M_WITH_GATE(de_clk, "de", "pll-de", 0x490,
560 0, 4, BIT(31), CLK_SET_RATE_PARENT);
561
562static SUNXI_CCU_GATE(edp_clk, "edp", "osc24M", 0x494, BIT(31), 0);
563
564static const char * const mp_parents[] = { "pll-video1", "pll-gpu", "pll-de" };
565static const u8 mp_table[] = { 9, 10, 11 };
566static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mp_clk, "mp", mp_parents, mp_table,
567 0x498,
568 0, 4, /* M */
569 24, 4, /* mux */
570 BIT(31), /* gate */
571 0);
572
573static const char * const display_parents[] = { "pll-video0", "pll-video1" };
574static const u8 display_table[] = { 8, 9 };
575
576static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd0_clk, "lcd0",
577 display_parents, display_table,
578 0x49c,
579 0, 4, /* M */
580 24, 4, /* mux */
581 BIT(31), /* gate */
582 CLK_SET_RATE_NO_REPARENT |
583 CLK_SET_RATE_PARENT);
584
585static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd1_clk, "lcd1",
586 display_parents, display_table,
587 0x4a0,
588 0, 4, /* M */
589 24, 4, /* mux */
590 BIT(31), /* gate */
591 CLK_SET_RATE_NO_REPARENT |
592 CLK_SET_RATE_PARENT);
593
594static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi0_clk, "mipi-dsi0",
595 display_parents, display_table,
596 0x4a8,
597 0, 4, /* M */
598 24, 4, /* mux */
599 BIT(31), /* gate */
600 CLK_SET_RATE_PARENT);
601
602static const char * const mipi_dsi1_parents[] = { "osc24M", "pll-video1" };
603static const u8 mipi_dsi1_table[] = { 0, 9 };
604static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi1_clk, "mipi-dsi1",
605 mipi_dsi1_parents, mipi_dsi1_table,
606 0x4ac,
607 0, 4, /* M */
608 24, 4, /* mux */
609 BIT(31), /* gate */
610 CLK_SET_RATE_PARENT);
611
612static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi_clk, "hdmi",
613 display_parents, display_table,
614 0x4b0,
615 0, 4, /* M */
616 24, 4, /* mux */
617 BIT(31), /* gate */
618 CLK_SET_RATE_NO_REPARENT |
619 CLK_SET_RATE_PARENT);
620
621static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", 0x4b4, BIT(31), 0);
622
623static SUNXI_CCU_M_WITH_GATE(mipi_csi_clk, "mipi-csi", "osc24M", 0x4bc,
624 0, 4, BIT(31), 0);
625
626static SUNXI_CCU_M_WITH_GATE(csi_isp_clk, "csi-isp", "pll-isp", 0x4c0,
627 0, 4, BIT(31), CLK_SET_RATE_PARENT);
628
629static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M", 0x4c0, BIT(16), 0);
630
631static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi0_mclk_clk, "csi0-mclk",
632 mipi_dsi1_parents, mipi_dsi1_table,
633 0x4c4,
634 0, 4, /* M */
635 24, 4, /* mux */
636 BIT(31), /* gate */
637 CLK_SET_RATE_PARENT);
638
639static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi1_mclk_clk, "csi1-mclk",
640 mipi_dsi1_parents, mipi_dsi1_table,
641 0x4c8,
642 0, 4, /* M */
643 24, 4, /* mux */
644 BIT(31), /* gate */
645 CLK_SET_RATE_PARENT);
646
647static const char * const fd_parents[] = { "pll-periph0", "pll-isp" };
648static const u8 fd_table[] = { 1, 12 };
649static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(fd_clk, "fd", fd_parents, fd_table,
650 0x4cc,
651 0, 4, /* M */
652 24, 4, /* mux */
653 BIT(31), /* gate */
654 0);
655static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x4d0,
656 16, 3, BIT(31), CLK_SET_RATE_PARENT);
657
658static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x4d4, BIT(31), 0);
659
660static SUNXI_CCU_M_WITH_GATE(gpu_core_clk, "gpu-core", "pll-gpu", 0x4f0,
661 0, 3, BIT(31), CLK_SET_RATE_PARENT);
662static SUNXI_CCU_M_WITH_GATE(gpu_memory_clk, "gpu-memory", "pll-gpu", 0x4f4,
663 0, 3, BIT(31), CLK_SET_RATE_PARENT);
664
665static const char * const gpu_axi_parents[] = { "pll-periph0", "pll-gpu" };
666static const u8 gpu_axi_table[] = { 1, 10 };
667static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(gpu_axi_clk, "gpu-axi",
668 gpu_axi_parents, gpu_axi_table,
669 0x4f8,
670 0, 4, /* M */
671 24, 4, /* mux */
672 BIT(31), /* gate */
673 CLK_SET_RATE_PARENT);
674
675static SUNXI_CCU_M_WITH_GATE(sata_clk, "sata", "pll-periph0", 0x500,
676 0, 4, BIT(31), 0);
677
678static SUNXI_CCU_M_WITH_GATE(ac97_clk, "ac97", "pll-audio",
679 0x504, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
680
681static SUNXI_CCU_M_WITH_MUX_GATE(mipi_hsi_clk, "mipi-hsi",
682 mod0_default_parents, 0x508,
683 0, 4, /* M */
684 24, 4, /* mux */
685 BIT(31), /* gate */
686 0);
687
688static const char * const gpadc_parents[] = { "osc24M", "pll-audio", "osc32k" };
689static const u8 gpadc_table[] = { 0, 4, 7 };
690static struct ccu_mp gpadc_clk = {
691 .enable = BIT(31),
692 .m = _SUNXI_CCU_DIV(0, 4),
693 .p = _SUNXI_CCU_DIV(16, 2),
694 .mux = _SUNXI_CCU_MUX_TABLE(24, 4, gpadc_table),
695 .common = {
696 .reg = 0x50c,
697 .hw.init = CLK_HW_INIT_PARENTS("gpadc",
698 gpadc_parents,
699 &ccu_mp_ops,
700 0),
701 },
702};
703
704static const char * const cir_tx_parents[] = { "osc24M", "osc32k" };
705static const u8 cir_tx_table[] = { 0, 7 };
706static struct ccu_mp cir_tx_clk = {
707 .enable = BIT(31),
708 .m = _SUNXI_CCU_DIV(0, 4),
709 .p = _SUNXI_CCU_DIV(16, 2),
710 .mux = _SUNXI_CCU_MUX_TABLE(24, 4, cir_tx_table),
711 .common = {
712 .reg = 0x510,
713 .hw.init = CLK_HW_INIT_PARENTS("cir-tx",
714 cir_tx_parents,
715 &ccu_mp_ops,
716 0),
717 },
718};
719
720/* AHB0 bus gates */
721static SUNXI_CCU_GATE(bus_fd_clk, "bus-fd", "ahb0",
722 0x580, BIT(0), 0);
723static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb0",
724 0x580, BIT(1), 0);
725static SUNXI_CCU_GATE(bus_gpu_ctrl_clk, "bus-gpu-ctrl", "ahb0",
726 0x580, BIT(3), 0);
727static SUNXI_CCU_GATE(bus_ss_clk, "bus-ss", "ahb0",
728 0x580, BIT(5), 0);
729static SUNXI_CCU_GATE(bus_mmc_clk, "bus-mmc", "ahb0",
730 0x580, BIT(8), 0);
731static SUNXI_CCU_GATE(bus_nand0_clk, "bus-nand0", "ahb0",
732 0x580, BIT(12), 0);
733static SUNXI_CCU_GATE(bus_nand1_clk, "bus-nand1", "ahb0",
734 0x580, BIT(13), 0);
735static SUNXI_CCU_GATE(bus_sdram_clk, "bus-sdram", "ahb0",
736 0x580, BIT(14), 0);
737static SUNXI_CCU_GATE(bus_mipi_hsi_clk, "bus-mipi-hsi", "ahb0",
738 0x580, BIT(15), 0);
739static SUNXI_CCU_GATE(bus_sata_clk, "bus-sata", "ahb0",
740 0x580, BIT(16), 0);
741static SUNXI_CCU_GATE(bus_ts_clk, "bus-ts", "ahb0",
742 0x580, BIT(18), 0);
743static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb0",
744 0x580, BIT(20), 0);
745static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb0",
746 0x580, BIT(21), 0);
747static SUNXI_CCU_GATE(bus_spi2_clk, "bus-spi2", "ahb0",
748 0x580, BIT(22), 0);
749static SUNXI_CCU_GATE(bus_spi3_clk, "bus-spi3", "ahb0",
750 0x580, BIT(23), 0);
751
752/* AHB1 bus gates */
753static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1",
754 0x584, BIT(0), 0);
755static SUNXI_CCU_GATE(bus_usb_clk, "bus-usb", "ahb1",
756 0x584, BIT(1), 0);
757static SUNXI_CCU_GATE(bus_gmac_clk, "bus-gmac", "ahb1",
758 0x584, BIT(17), 0);
759static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1",
760 0x584, BIT(21), 0);
761static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1",
762 0x584, BIT(22), 0);
763static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1",
764 0x584, BIT(23), 0);
765static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1",
766 0x584, BIT(24), 0);
767
768/* AHB2 bus gates */
769static SUNXI_CCU_GATE(bus_lcd0_clk, "bus-lcd0", "ahb2",
770 0x588, BIT(0), 0);
771static SUNXI_CCU_GATE(bus_lcd1_clk, "bus-lcd1", "ahb2",
772 0x588, BIT(1), 0);
773static SUNXI_CCU_GATE(bus_edp_clk, "bus-edp", "ahb2",
774 0x588, BIT(2), 0);
775static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb2",
776 0x588, BIT(4), 0);
777static SUNXI_CCU_GATE(bus_hdmi_clk, "bus-hdmi", "ahb2",
778 0x588, BIT(5), 0);
779static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "ahb2",
780 0x588, BIT(7), 0);
781static SUNXI_CCU_GATE(bus_mp_clk, "bus-mp", "ahb2",
782 0x588, BIT(8), 0);
783static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb2",
784 0x588, BIT(11), 0);
785
786/* APB0 bus gates */
787static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb0",
788 0x590, BIT(1), 0);
789static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb0",
790 0x590, BIT(5), 0);
791static SUNXI_CCU_GATE(bus_ac97_clk, "bus-ac97", "apb0",
792 0x590, BIT(11), 0);
793static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb0",
794 0x590, BIT(12), 0);
795static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb0",
796 0x590, BIT(13), 0);
797static SUNXI_CCU_GATE(bus_lradc_clk, "bus-lradc", "apb0",
798 0x590, BIT(15), 0);
799static SUNXI_CCU_GATE(bus_gpadc_clk, "bus-gpadc", "apb0",
800 0x590, BIT(17), 0);
801static SUNXI_CCU_GATE(bus_twd_clk, "bus-twd", "apb0",
802 0x590, BIT(18), 0);
803static SUNXI_CCU_GATE(bus_cir_tx_clk, "bus-cir-tx", "apb0",
804 0x590, BIT(19), 0);
805
806/* APB1 bus gates */
807static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb1",
808 0x594, BIT(0), 0);
809static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb1",
810 0x594, BIT(1), 0);
811static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb1",
812 0x594, BIT(2), 0);
813static SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3", "apb1",
814 0x594, BIT(3), 0);
815static SUNXI_CCU_GATE(bus_i2c4_clk, "bus-i2c4", "apb1",
816 0x594, BIT(4), 0);
817static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb1",
818 0x594, BIT(16), 0);
819static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb1",
820 0x594, BIT(17), 0);
821static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb1",
822 0x594, BIT(18), 0);
823static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb1",
824 0x594, BIT(19), 0);
825static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb1",
826 0x594, BIT(20), 0);
827static SUNXI_CCU_GATE(bus_uart5_clk, "bus-uart5", "apb1",
828 0x594, BIT(21), 0);
829
830static struct ccu_common *sun9i_a80_ccu_clks[] = {
831 &pll_c0cpux_clk.common,
832 &pll_c1cpux_clk.common,
833 &pll_audio_clk.common,
834 &pll_periph0_clk.common,
835 &pll_ve_clk.common,
836 &pll_ddr_clk.common,
837 &pll_video0_clk.common,
838 &pll_video1_clk.common,
839 &pll_gpu_clk.common,
840 &pll_de_clk.common,
841 &pll_isp_clk.common,
842 &pll_periph1_clk.common,
843 &c0cpux_clk.common,
844 &c1cpux_clk.common,
845 &atb0_clk.common,
846 &axi0_clk.common,
847 &atb1_clk.common,
848 &axi1_clk.common,
849 &gtbus_clk.common,
850 &ahb0_clk.common,
851 &ahb1_clk.common,
852 &ahb2_clk.common,
853 &apb0_clk.common,
854 &apb1_clk.common,
855 &cci400_clk.common,
856 &ats_clk.common,
857 &trace_clk.common,
858
859 &out_a_clk.common,
860 &out_b_clk.common,
861
862 /* module clocks */
863 &nand0_0_clk.common,
864 &nand0_1_clk.common,
865 &nand1_0_clk.common,
866 &nand1_1_clk.common,
867 &mmc0_clk.common,
868 &mmc0_sample_clk.common,
869 &mmc0_output_clk.common,
870 &mmc1_clk.common,
871 &mmc1_sample_clk.common,
872 &mmc1_output_clk.common,
873 &mmc2_clk.common,
874 &mmc2_sample_clk.common,
875 &mmc2_output_clk.common,
876 &mmc3_clk.common,
877 &mmc3_sample_clk.common,
878 &mmc3_output_clk.common,
879 &ts_clk.common,
880 &ss_clk.common,
881 &spi0_clk.common,
882 &spi1_clk.common,
883 &spi2_clk.common,
884 &spi3_clk.common,
885 &i2s0_clk.common,
886 &i2s1_clk.common,
887 &spdif_clk.common,
888 &sdram_clk.common,
889 &de_clk.common,
890 &edp_clk.common,
891 &mp_clk.common,
892 &lcd0_clk.common,
893 &lcd1_clk.common,
894 &mipi_dsi0_clk.common,
895 &mipi_dsi1_clk.common,
896 &hdmi_clk.common,
897 &hdmi_slow_clk.common,
898 &mipi_csi_clk.common,
899 &csi_isp_clk.common,
900 &csi_misc_clk.common,
901 &csi0_mclk_clk.common,
902 &csi1_mclk_clk.common,
903 &fd_clk.common,
904 &ve_clk.common,
905 &avs_clk.common,
906 &gpu_core_clk.common,
907 &gpu_memory_clk.common,
908 &gpu_axi_clk.common,
909 &sata_clk.common,
910 &ac97_clk.common,
911 &mipi_hsi_clk.common,
912 &gpadc_clk.common,
913 &cir_tx_clk.common,
914
915 /* AHB0 bus gates */
916 &bus_fd_clk.common,
917 &bus_ve_clk.common,
918 &bus_gpu_ctrl_clk.common,
919 &bus_ss_clk.common,
920 &bus_mmc_clk.common,
921 &bus_nand0_clk.common,
922 &bus_nand1_clk.common,
923 &bus_sdram_clk.common,
924 &bus_mipi_hsi_clk.common,
925 &bus_sata_clk.common,
926 &bus_ts_clk.common,
927 &bus_spi0_clk.common,
928 &bus_spi1_clk.common,
929 &bus_spi2_clk.common,
930 &bus_spi3_clk.common,
931
932 /* AHB1 bus gates */
933 &bus_otg_clk.common,
934 &bus_usb_clk.common,
935 &bus_gmac_clk.common,
936 &bus_msgbox_clk.common,
937 &bus_spinlock_clk.common,
938 &bus_hstimer_clk.common,
939 &bus_dma_clk.common,
940
941 /* AHB2 bus gates */
942 &bus_lcd0_clk.common,
943 &bus_lcd1_clk.common,
944 &bus_edp_clk.common,
945 &bus_csi_clk.common,
946 &bus_hdmi_clk.common,
947 &bus_de_clk.common,
948 &bus_mp_clk.common,
949 &bus_mipi_dsi_clk.common,
950
951 /* APB0 bus gates */
952 &bus_spdif_clk.common,
953 &bus_pio_clk.common,
954 &bus_ac97_clk.common,
955 &bus_i2s0_clk.common,
956 &bus_i2s1_clk.common,
957 &bus_lradc_clk.common,
958 &bus_gpadc_clk.common,
959 &bus_twd_clk.common,
960 &bus_cir_tx_clk.common,
961
962 /* APB1 bus gates */
963 &bus_i2c0_clk.common,
964 &bus_i2c1_clk.common,
965 &bus_i2c2_clk.common,
966 &bus_i2c3_clk.common,
967 &bus_i2c4_clk.common,
968 &bus_uart0_clk.common,
969 &bus_uart1_clk.common,
970 &bus_uart2_clk.common,
971 &bus_uart3_clk.common,
972 &bus_uart4_clk.common,
973 &bus_uart5_clk.common,
974};
975
976static struct clk_hw_onecell_data sun9i_a80_hw_clks = {
977 .hws = {
978 [CLK_PLL_C0CPUX] = &pll_c0cpux_clk.common.hw,
979 [CLK_PLL_C1CPUX] = &pll_c1cpux_clk.common.hw,
980 [CLK_PLL_AUDIO] = &pll_audio_clk.common.hw,
981 [CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw,
982 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
983 [CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
984 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
985 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
986 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
987 [CLK_PLL_DE] = &pll_de_clk.common.hw,
988 [CLK_PLL_ISP] = &pll_isp_clk.common.hw,
989 [CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw,
990 [CLK_C0CPUX] = &c0cpux_clk.common.hw,
991 [CLK_C1CPUX] = &c1cpux_clk.common.hw,
992 [CLK_ATB0] = &atb0_clk.common.hw,
993 [CLK_AXI0] = &axi0_clk.common.hw,
994 [CLK_ATB1] = &atb1_clk.common.hw,
995 [CLK_AXI1] = &axi1_clk.common.hw,
996 [CLK_GTBUS] = &gtbus_clk.common.hw,
997 [CLK_AHB0] = &ahb0_clk.common.hw,
998 [CLK_AHB1] = &ahb1_clk.common.hw,
999 [CLK_AHB2] = &ahb2_clk.common.hw,
1000 [CLK_APB0] = &apb0_clk.common.hw,
1001 [CLK_APB1] = &apb1_clk.common.hw,
1002 [CLK_CCI400] = &cci400_clk.common.hw,
1003 [CLK_ATS] = &ats_clk.common.hw,
1004 [CLK_TRACE] = &trace_clk.common.hw,
1005
1006 [CLK_OUT_A] = &out_a_clk.common.hw,
1007 [CLK_OUT_B] = &out_b_clk.common.hw,
1008
1009 [CLK_NAND0_0] = &nand0_0_clk.common.hw,
1010 [CLK_NAND0_1] = &nand0_1_clk.common.hw,
1011 [CLK_NAND1_0] = &nand1_0_clk.common.hw,
1012 [CLK_NAND1_1] = &nand1_1_clk.common.hw,
1013 [CLK_MMC0] = &mmc0_clk.common.hw,
1014 [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw,
1015 [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw,
1016 [CLK_MMC1] = &mmc1_clk.common.hw,
1017 [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw,
1018 [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw,
1019 [CLK_MMC2] = &mmc2_clk.common.hw,
1020 [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw,
1021 [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw,
1022 [CLK_MMC3] = &mmc3_clk.common.hw,
1023 [CLK_MMC3_SAMPLE] = &mmc3_sample_clk.common.hw,
1024 [CLK_MMC3_OUTPUT] = &mmc3_output_clk.common.hw,
1025 [CLK_TS] = &ts_clk.common.hw,
1026 [CLK_SS] = &ss_clk.common.hw,
1027 [CLK_SPI0] = &spi0_clk.common.hw,
1028 [CLK_SPI1] = &spi1_clk.common.hw,
1029 [CLK_SPI2] = &spi2_clk.common.hw,
1030 [CLK_SPI3] = &spi3_clk.common.hw,
1031 [CLK_I2S0] = &i2s0_clk.common.hw,
1032 [CLK_I2S1] = &i2s1_clk.common.hw,
1033 [CLK_SPDIF] = &spdif_clk.common.hw,
1034 [CLK_SDRAM] = &sdram_clk.common.hw,
1035 [CLK_DE] = &de_clk.common.hw,
1036 [CLK_EDP] = &edp_clk.common.hw,
1037 [CLK_MP] = &mp_clk.common.hw,
1038 [CLK_LCD0] = &lcd0_clk.common.hw,
1039 [CLK_LCD1] = &lcd1_clk.common.hw,
1040 [CLK_MIPI_DSI0] = &mipi_dsi0_clk.common.hw,
1041 [CLK_MIPI_DSI1] = &mipi_dsi1_clk.common.hw,
1042 [CLK_HDMI] = &hdmi_clk.common.hw,
1043 [CLK_HDMI_SLOW] = &hdmi_slow_clk.common.hw,
1044 [CLK_MIPI_CSI] = &mipi_csi_clk.common.hw,
1045 [CLK_CSI_ISP] = &csi_isp_clk.common.hw,
1046 [CLK_CSI_MISC] = &csi_misc_clk.common.hw,
1047 [CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw,
1048 [CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw,
1049 [CLK_FD] = &fd_clk.common.hw,
1050 [CLK_VE] = &ve_clk.common.hw,
1051 [CLK_AVS] = &avs_clk.common.hw,
1052 [CLK_GPU_CORE] = &gpu_core_clk.common.hw,
1053 [CLK_GPU_MEMORY] = &gpu_memory_clk.common.hw,
1054 [CLK_GPU_AXI] = &gpu_axi_clk.common.hw,
1055 [CLK_SATA] = &sata_clk.common.hw,
1056 [CLK_AC97] = &ac97_clk.common.hw,
1057 [CLK_MIPI_HSI] = &mipi_hsi_clk.common.hw,
1058 [CLK_GPADC] = &gpadc_clk.common.hw,
1059 [CLK_CIR_TX] = &cir_tx_clk.common.hw,
1060
1061 [CLK_BUS_FD] = &bus_fd_clk.common.hw,
1062 [CLK_BUS_VE] = &bus_ve_clk.common.hw,
1063 [CLK_BUS_GPU_CTRL] = &bus_gpu_ctrl_clk.common.hw,
1064 [CLK_BUS_SS] = &bus_ss_clk.common.hw,
1065 [CLK_BUS_MMC] = &bus_mmc_clk.common.hw,
1066 [CLK_BUS_NAND0] = &bus_nand0_clk.common.hw,
1067 [CLK_BUS_NAND1] = &bus_nand1_clk.common.hw,
1068 [CLK_BUS_SDRAM] = &bus_sdram_clk.common.hw,
1069 [CLK_BUS_MIPI_HSI] = &bus_mipi_hsi_clk.common.hw,
1070 [CLK_BUS_SATA] = &bus_sata_clk.common.hw,
1071 [CLK_BUS_TS] = &bus_ts_clk.common.hw,
1072 [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
1073 [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
1074 [CLK_BUS_SPI2] = &bus_spi2_clk.common.hw,
1075 [CLK_BUS_SPI3] = &bus_spi3_clk.common.hw,
1076
1077 [CLK_BUS_OTG] = &bus_otg_clk.common.hw,
1078 [CLK_BUS_USB] = &bus_usb_clk.common.hw,
1079 [CLK_BUS_GMAC] = &bus_gmac_clk.common.hw,
1080 [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw,
1081 [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw,
1082 [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw,
1083 [CLK_BUS_DMA] = &bus_dma_clk.common.hw,
1084
1085 [CLK_BUS_LCD0] = &bus_lcd0_clk.common.hw,
1086 [CLK_BUS_LCD1] = &bus_lcd1_clk.common.hw,
1087 [CLK_BUS_EDP] = &bus_edp_clk.common.hw,
1088 [CLK_BUS_CSI] = &bus_csi_clk.common.hw,
1089 [CLK_BUS_HDMI] = &bus_hdmi_clk.common.hw,
1090 [CLK_BUS_DE] = &bus_de_clk.common.hw,
1091 [CLK_BUS_MP] = &bus_mp_clk.common.hw,
1092 [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw,
1093
1094 [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw,
1095 [CLK_BUS_PIO] = &bus_pio_clk.common.hw,
1096 [CLK_BUS_AC97] = &bus_ac97_clk.common.hw,
1097 [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
1098 [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw,
1099 [CLK_BUS_LRADC] = &bus_lradc_clk.common.hw,
1100 [CLK_BUS_GPADC] = &bus_gpadc_clk.common.hw,
1101 [CLK_BUS_TWD] = &bus_twd_clk.common.hw,
1102 [CLK_BUS_CIR_TX] = &bus_cir_tx_clk.common.hw,
1103
1104 [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
1105 [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw,
1106 [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw,
1107 [CLK_BUS_I2C3] = &bus_i2c3_clk.common.hw,
1108 [CLK_BUS_I2C4] = &bus_i2c4_clk.common.hw,
1109 [CLK_BUS_UART0] = &bus_uart0_clk.common.hw,
1110 [CLK_BUS_UART1] = &bus_uart1_clk.common.hw,
1111 [CLK_BUS_UART2] = &bus_uart2_clk.common.hw,
1112 [CLK_BUS_UART3] = &bus_uart3_clk.common.hw,
1113 [CLK_BUS_UART4] = &bus_uart4_clk.common.hw,
1114 [CLK_BUS_UART5] = &bus_uart5_clk.common.hw,
1115 },
1116 .num = CLK_NUMBER,
1117};
1118
1119static struct ccu_reset_map sun9i_a80_ccu_resets[] = {
1120 /* AHB0 reset controls */
1121 [RST_BUS_FD] = { 0x5a0, BIT(0) },
1122 [RST_BUS_VE] = { 0x5a0, BIT(1) },
1123 [RST_BUS_GPU_CTRL] = { 0x5a0, BIT(3) },
1124 [RST_BUS_SS] = { 0x5a0, BIT(5) },
1125 [RST_BUS_MMC] = { 0x5a0, BIT(8) },
1126 [RST_BUS_NAND0] = { 0x5a0, BIT(12) },
1127 [RST_BUS_NAND1] = { 0x5a0, BIT(13) },
1128 [RST_BUS_SDRAM] = { 0x5a0, BIT(14) },
1129 [RST_BUS_SATA] = { 0x5a0, BIT(16) },
1130 [RST_BUS_TS] = { 0x5a0, BIT(18) },
1131 [RST_BUS_SPI0] = { 0x5a0, BIT(20) },
1132 [RST_BUS_SPI1] = { 0x5a0, BIT(21) },
1133 [RST_BUS_SPI2] = { 0x5a0, BIT(22) },
1134 [RST_BUS_SPI3] = { 0x5a0, BIT(23) },
1135
1136 /* AHB1 reset controls */
1137 [RST_BUS_OTG] = { 0x5a4, BIT(0) },
1138 [RST_BUS_OTG_PHY] = { 0x5a4, BIT(1) },
1139 [RST_BUS_MIPI_HSI] = { 0x5a4, BIT(9) },
1140 [RST_BUS_GMAC] = { 0x5a4, BIT(17) },
1141 [RST_BUS_MSGBOX] = { 0x5a4, BIT(21) },
1142 [RST_BUS_SPINLOCK] = { 0x5a4, BIT(22) },
1143 [RST_BUS_HSTIMER] = { 0x5a4, BIT(23) },
1144 [RST_BUS_DMA] = { 0x5a4, BIT(24) },
1145
1146 /* AHB2 reset controls */
1147 [RST_BUS_LCD0] = { 0x5a8, BIT(0) },
1148 [RST_BUS_LCD1] = { 0x5a8, BIT(1) },
1149 [RST_BUS_EDP] = { 0x5a8, BIT(2) },
1150 [RST_BUS_LVDS] = { 0x5a8, BIT(3) },
1151 [RST_BUS_CSI] = { 0x5a8, BIT(4) },
1152 [RST_BUS_HDMI0] = { 0x5a8, BIT(5) },
1153 [RST_BUS_HDMI1] = { 0x5a8, BIT(6) },
1154 [RST_BUS_DE] = { 0x5a8, BIT(7) },
1155 [RST_BUS_MP] = { 0x5a8, BIT(8) },
1156 [RST_BUS_GPU] = { 0x5a8, BIT(9) },
1157 [RST_BUS_MIPI_DSI] = { 0x5a8, BIT(11) },
1158
1159 /* APB0 reset controls */
1160 [RST_BUS_SPDIF] = { 0x5b0, BIT(1) },
1161 [RST_BUS_AC97] = { 0x5b0, BIT(11) },
1162 [RST_BUS_I2S0] = { 0x5b0, BIT(12) },
1163 [RST_BUS_I2S1] = { 0x5b0, BIT(13) },
1164 [RST_BUS_LRADC] = { 0x5b0, BIT(15) },
1165 [RST_BUS_GPADC] = { 0x5b0, BIT(17) },
1166 [RST_BUS_CIR_TX] = { 0x5b0, BIT(19) },
1167
1168 /* APB1 reset controls */
1169 [RST_BUS_I2C0] = { 0x5b4, BIT(0) },
1170 [RST_BUS_I2C1] = { 0x5b4, BIT(1) },
1171 [RST_BUS_I2C2] = { 0x5b4, BIT(2) },
1172 [RST_BUS_I2C3] = { 0x5b4, BIT(3) },
1173 [RST_BUS_I2C4] = { 0x5b4, BIT(4) },
1174 [RST_BUS_UART0] = { 0x5b4, BIT(16) },
1175 [RST_BUS_UART1] = { 0x5b4, BIT(17) },
1176 [RST_BUS_UART2] = { 0x5b4, BIT(18) },
1177 [RST_BUS_UART3] = { 0x5b4, BIT(19) },
1178 [RST_BUS_UART4] = { 0x5b4, BIT(20) },
1179 [RST_BUS_UART5] = { 0x5b4, BIT(21) },
1180};
1181
1182static const struct sunxi_ccu_desc sun9i_a80_ccu_desc = {
1183 .ccu_clks = sun9i_a80_ccu_clks,
1184 .num_ccu_clks = ARRAY_SIZE(sun9i_a80_ccu_clks),
1185
1186 .hw_clks = &sun9i_a80_hw_clks,
1187
1188 .resets = sun9i_a80_ccu_resets,
1189 .num_resets = ARRAY_SIZE(sun9i_a80_ccu_resets),
1190};
1191
1192static int sun9i_a80_ccu_probe(struct platform_device *pdev)
1193{
1194 struct resource *res;
1195 void __iomem *reg;
1196 u32 val;
1197
1198 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1199 reg = devm_ioremap_resource(&pdev->dev, res);
1200 if (IS_ERR(reg))
1201 return PTR_ERR(reg);
1202
1203 /* Enforce d1 = 0, d2 = 0 for Audio PLL */
1204 val = readl(reg + SUN9I_A80_PLL_AUDIO_REG);
1205 val &= (BIT(16) & BIT(18));
1206 writel(val, reg + SUN9I_A80_PLL_AUDIO_REG);
1207
1208 return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun9i_a80_ccu_desc);
1209}
1210
1211static const struct of_device_id sun9i_a80_ccu_ids[] = {
1212 { .compatible = "allwinner,sun9i-a80-ccu" },
1213 { }
1214};
1215
1216static struct platform_driver sun9i_a80_ccu_driver = {
1217 .probe = sun9i_a80_ccu_probe,
1218 .driver = {
1219 .name = "sun9i-a80-ccu",
1220 .of_match_table = sun9i_a80_ccu_ids,
1221 },
1222};
1223builtin_platform_driver(sun9i_a80_ccu_driver);
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.h b/drivers/clk/sunxi-ng/ccu-sun9i-a80.h
new file mode 100644
index 000000000000..315662341c70
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright 2016 Chen-Yu Tsai
3 *
4 * Chen-Yu Tsai <wens@csie.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _CCU_SUN9I_A80_H_
18#define _CCU_SUN9I_A80_H_
19
20#include <dt-bindings/clock/sun9i-a80-ccu.h>
21#include <dt-bindings/reset/sun9i-a80-ccu.h>
22
23#define CLK_PLL_C0CPUX 0
24#define CLK_PLL_C1CPUX 1
25
26/* pll-audio and pll-periph0 are exported to the PRCM block */
27
28#define CLK_PLL_VE 4
29#define CLK_PLL_DDR 5
30#define CLK_PLL_VIDEO0 6
31#define CLK_PLL_VIDEO1 7
32#define CLK_PLL_GPU 8
33#define CLK_PLL_DE 9
34#define CLK_PLL_ISP 10
35#define CLK_PLL_PERIPH1 11
36
37/* The CPUX clocks are exported */
38
39#define CLK_ATB0 14
40#define CLK_AXI0 15
41#define CLK_ATB1 16
42#define CLK_AXI1 17
43#define CLK_GTBUS 18
44#define CLK_AHB0 19
45#define CLK_AHB1 20
46#define CLK_AHB2 21
47#define CLK_APB0 22
48#define CLK_APB1 23
49#define CLK_CCI400 24
50#define CLK_ATS 25
51#define CLK_TRACE 26
52
53/* module clocks and bus gates exported */
54
55#define CLK_NUMBER (CLK_BUS_UART5 + 1)
56
57#endif /* _CCU_SUN9I_A80_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c
index 51d4bac97ab3..8a47bafd7890 100644
--- a/drivers/clk/sunxi-ng/ccu_common.c
+++ b/drivers/clk/sunxi-ng/ccu_common.c
@@ -25,13 +25,18 @@ static DEFINE_SPINLOCK(ccu_lock);
25 25
26void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock) 26void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock)
27{ 27{
28 void __iomem *addr;
28 u32 reg; 29 u32 reg;
29 30
30 if (!lock) 31 if (!lock)
31 return; 32 return;
32 33
33 WARN_ON(readl_relaxed_poll_timeout(common->base + common->reg, reg, 34 if (common->features & CCU_FEATURE_LOCK_REG)
34 reg & lock, 100, 70000)); 35 addr = common->base + common->lock_reg;
36 else
37 addr = common->base + common->reg;
38
39 WARN_ON(readl_relaxed_poll_timeout(addr, reg, reg & lock, 100, 70000));
35} 40}
36 41
37int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, 42int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
@@ -70,6 +75,11 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
70 goto err_clk_unreg; 75 goto err_clk_unreg;
71 76
72 reset = kzalloc(sizeof(*reset), GFP_KERNEL); 77 reset = kzalloc(sizeof(*reset), GFP_KERNEL);
78 if (!reset) {
79 ret = -ENOMEM;
80 goto err_alloc_reset;
81 }
82
73 reset->rcdev.of_node = node; 83 reset->rcdev.of_node = node;
74 reset->rcdev.ops = &ccu_reset_ops; 84 reset->rcdev.ops = &ccu_reset_ops;
75 reset->rcdev.owner = THIS_MODULE; 85 reset->rcdev.owner = THIS_MODULE;
@@ -85,6 +95,16 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
85 return 0; 95 return 0;
86 96
87err_of_clk_unreg: 97err_of_clk_unreg:
98 kfree(reset);
99err_alloc_reset:
100 of_clk_del_provider(node);
88err_clk_unreg: 101err_clk_unreg:
102 while (--i >= 0) {
103 struct clk_hw *hw = desc->hw_clks->hws[i];
104
105 if (!hw)
106 continue;
107 clk_hw_unregister(hw);
108 }
89 return ret; 109 return ret;
90} 110}
diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h
index b3d9abfbd721..73d81dc58fc5 100644
--- a/drivers/clk/sunxi-ng/ccu_common.h
+++ b/drivers/clk/sunxi-ng/ccu_common.h
@@ -21,6 +21,8 @@
21#define CCU_FEATURE_VARIABLE_PREDIV BIT(1) 21#define CCU_FEATURE_VARIABLE_PREDIV BIT(1)
22#define CCU_FEATURE_FIXED_PREDIV BIT(2) 22#define CCU_FEATURE_FIXED_PREDIV BIT(2)
23#define CCU_FEATURE_FIXED_POSTDIV BIT(3) 23#define CCU_FEATURE_FIXED_POSTDIV BIT(3)
24#define CCU_FEATURE_ALL_PREDIV BIT(4)
25#define CCU_FEATURE_LOCK_REG BIT(5)
24 26
25struct device_node; 27struct device_node;
26 28
@@ -56,6 +58,8 @@ struct device_node;
56struct ccu_common { 58struct ccu_common {
57 void __iomem *base; 59 void __iomem *base;
58 u16 reg; 60 u16 reg;
61 u16 lock_reg;
62 u32 prediv;
59 63
60 unsigned long features; 64 unsigned long features;
61 spinlock_t *lock; 65 spinlock_t *lock;
diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c
index 8659b4cb6c20..4057e6021aa9 100644
--- a/drivers/clk/sunxi-ng/ccu_div.c
+++ b/drivers/clk/sunxi-ng/ccu_div.c
@@ -77,6 +77,18 @@ static int ccu_div_determine_rate(struct clk_hw *hw,
77{ 77{
78 struct ccu_div *cd = hw_to_ccu_div(hw); 78 struct ccu_div *cd = hw_to_ccu_div(hw);
79 79
80 if (clk_hw_get_num_parents(hw) == 1) {
81 req->rate = divider_round_rate(hw, req->rate,
82 &req->best_parent_rate,
83 cd->div.table,
84 cd->div.width,
85 cd->div.flags);
86
87 req->best_parent_hw = clk_hw_get_parent(hw);
88
89 return 0;
90 }
91
80 return ccu_mux_helper_determine_rate(&cd->common, &cd->mux, 92 return ccu_mux_helper_determine_rate(&cd->common, &cd->mux,
81 req, ccu_div_round_rate, cd); 93 req, ccu_div_round_rate, cd);
82} 94}
diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h
index 06540f7cf41c..08d074451204 100644
--- a/drivers/clk/sunxi-ng/ccu_div.h
+++ b/drivers/clk/sunxi-ng/ccu_div.h
@@ -41,6 +41,7 @@ struct ccu_div_internal {
41 u8 width; 41 u8 width;
42 42
43 u32 max; 43 u32 max;
44 u32 offset;
44 45
45 u32 flags; 46 u32 flags;
46 47
@@ -58,20 +59,27 @@ struct ccu_div_internal {
58#define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \ 59#define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \
59 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0) 60 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
60 61
61#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \ 62#define _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _off, _max, _flags) \
62 { \ 63 { \
63 .shift = _shift, \ 64 .shift = _shift, \
64 .width = _width, \ 65 .width = _width, \
65 .flags = _flags, \ 66 .flags = _flags, \
66 .max = _max, \ 67 .max = _max, \
68 .offset = _off, \
67 } 69 }
68 70
71#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
72 _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, 1, _max, _flags)
73
69#define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \ 74#define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \
70 _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags) 75 _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
71 76
72#define _SUNXI_CCU_DIV_MAX(_shift, _width, _max) \ 77#define _SUNXI_CCU_DIV_MAX(_shift, _width, _max) \
73 _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0) 78 _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
74 79
80#define _SUNXI_CCU_DIV_OFFSET(_shift, _width, _offset) \
81 _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _offset, 0, 0)
82
75#define _SUNXI_CCU_DIV(_shift, _width) \ 83#define _SUNXI_CCU_DIV(_shift, _width) \
76 _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0) 84 _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
77 85
diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
index ebb1b31568a5..22c2ca7a2a22 100644
--- a/drivers/clk/sunxi-ng/ccu_mp.c
+++ b/drivers/clk/sunxi-ng/ccu_mp.c
@@ -89,11 +89,14 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
89 89
90 m = reg >> cmp->m.shift; 90 m = reg >> cmp->m.shift;
91 m &= (1 << cmp->m.width) - 1; 91 m &= (1 << cmp->m.width) - 1;
92 m += cmp->m.offset;
93 if (!m)
94 m++;
92 95
93 p = reg >> cmp->p.shift; 96 p = reg >> cmp->p.shift;
94 p &= (1 << cmp->p.width) - 1; 97 p &= (1 << cmp->p.width) - 1;
95 98
96 return (parent_rate >> p) / (m + 1); 99 return (parent_rate >> p) / m;
97} 100}
98 101
99static int ccu_mp_determine_rate(struct clk_hw *hw, 102static int ccu_mp_determine_rate(struct clk_hw *hw,
@@ -124,9 +127,10 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
124 reg = readl(cmp->common.base + cmp->common.reg); 127 reg = readl(cmp->common.base + cmp->common.reg);
125 reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift); 128 reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift);
126 reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift); 129 reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift);
130 reg |= (m - cmp->m.offset) << cmp->m.shift;
131 reg |= ilog2(p) << cmp->p.shift;
127 132
128 writel(reg | (ilog2(p) << cmp->p.shift) | ((m - 1) << cmp->m.shift), 133 writel(reg, cmp->common.base + cmp->common.reg);
129 cmp->common.base + cmp->common.reg);
130 134
131 spin_unlock_irqrestore(cmp->common.lock, flags); 135 spin_unlock_irqrestore(cmp->common.lock, flags);
132 136
diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c
index 678b6cb49f01..8724c01171b1 100644
--- a/drivers/clk/sunxi-ng/ccu_mult.c
+++ b/drivers/clk/sunxi-ng/ccu_mult.c
@@ -40,8 +40,13 @@ static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux,
40 struct ccu_mult *cm = data; 40 struct ccu_mult *cm = data;
41 struct _ccu_mult _cm; 41 struct _ccu_mult _cm;
42 42
43 _cm.min = 1; 43 _cm.min = cm->mult.min;
44 _cm.max = 1 << cm->mult.width; 44
45 if (cm->mult.max)
46 _cm.max = cm->mult.max;
47 else
48 _cm.max = (1 << cm->mult.width) + cm->mult.offset - 1;
49
45 ccu_mult_find_best(parent_rate, rate, &_cm); 50 ccu_mult_find_best(parent_rate, rate, &_cm);
46 51
47 return parent_rate * _cm.mult; 52 return parent_rate * _cm.mult;
@@ -75,6 +80,9 @@ static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
75 unsigned long val; 80 unsigned long val;
76 u32 reg; 81 u32 reg;
77 82
83 if (ccu_frac_helper_is_enabled(&cm->common, &cm->frac))
84 return ccu_frac_helper_read_rate(&cm->common, &cm->frac);
85
78 reg = readl(cm->common.base + cm->common.reg); 86 reg = readl(cm->common.base + cm->common.reg);
79 val = reg >> cm->mult.shift; 87 val = reg >> cm->mult.shift;
80 val &= (1 << cm->mult.width) - 1; 88 val &= (1 << cm->mult.width) - 1;
@@ -82,7 +90,7 @@ static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
82 ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1, 90 ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
83 &parent_rate); 91 &parent_rate);
84 92
85 return parent_rate * (val + 1); 93 return parent_rate * (val + cm->mult.offset);
86} 94}
87 95
88static int ccu_mult_determine_rate(struct clk_hw *hw, 96static int ccu_mult_determine_rate(struct clk_hw *hw,
@@ -102,20 +110,30 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
102 unsigned long flags; 110 unsigned long flags;
103 u32 reg; 111 u32 reg;
104 112
113 if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate))
114 return ccu_frac_helper_set_rate(&cm->common, &cm->frac, rate);
115 else
116 ccu_frac_helper_disable(&cm->common, &cm->frac);
117
105 ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1, 118 ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
106 &parent_rate); 119 &parent_rate);
107 120
108 _cm.min = cm->mult.min; 121 _cm.min = cm->mult.min;
109 _cm.max = 1 << cm->mult.width; 122
123 if (cm->mult.max)
124 _cm.max = cm->mult.max;
125 else
126 _cm.max = (1 << cm->mult.width) + cm->mult.offset - 1;
127
110 ccu_mult_find_best(parent_rate, rate, &_cm); 128 ccu_mult_find_best(parent_rate, rate, &_cm);
111 129
112 spin_lock_irqsave(cm->common.lock, flags); 130 spin_lock_irqsave(cm->common.lock, flags);
113 131
114 reg = readl(cm->common.base + cm->common.reg); 132 reg = readl(cm->common.base + cm->common.reg);
115 reg &= ~GENMASK(cm->mult.width + cm->mult.shift - 1, cm->mult.shift); 133 reg &= ~GENMASK(cm->mult.width + cm->mult.shift - 1, cm->mult.shift);
134 reg |= ((_cm.mult - cm->mult.offset) << cm->mult.shift);
116 135
117 writel(reg | ((_cm.mult - 1) << cm->mult.shift), 136 writel(reg, cm->common.base + cm->common.reg);
118 cm->common.base + cm->common.reg);
119 137
120 spin_unlock_irqrestore(cm->common.lock, flags); 138 spin_unlock_irqrestore(cm->common.lock, flags);
121 139
diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h
index c1a2134bdc71..524acddfcb2e 100644
--- a/drivers/clk/sunxi-ng/ccu_mult.h
+++ b/drivers/clk/sunxi-ng/ccu_mult.h
@@ -2,27 +2,39 @@
2#define _CCU_MULT_H_ 2#define _CCU_MULT_H_
3 3
4#include "ccu_common.h" 4#include "ccu_common.h"
5#include "ccu_frac.h"
5#include "ccu_mux.h" 6#include "ccu_mux.h"
6 7
7struct ccu_mult_internal { 8struct ccu_mult_internal {
9 u8 offset;
8 u8 shift; 10 u8 shift;
9 u8 width; 11 u8 width;
10 u8 min; 12 u8 min;
13 u8 max;
11}; 14};
12 15
13#define _SUNXI_CCU_MULT_MIN(_shift, _width, _min) \ 16#define _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, _offset, _min, _max) \
14 { \ 17 { \
15 .shift = _shift, \ 18 .min = _min, \
16 .width = _width, \ 19 .max = _max, \
17 .min = _min, \ 20 .offset = _offset, \
21 .shift = _shift, \
22 .width = _width, \
18 } 23 }
19 24
25#define _SUNXI_CCU_MULT_MIN(_shift, _width, _min) \
26 _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, 1, _min, 0)
27
28#define _SUNXI_CCU_MULT_OFFSET(_shift, _width, _offset) \
29 _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, _offset, 1, 0)
30
20#define _SUNXI_CCU_MULT(_shift, _width) \ 31#define _SUNXI_CCU_MULT(_shift, _width) \
21 _SUNXI_CCU_MULT_MIN(_shift, _width, 1) 32 _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, 1, 1, 0)
22 33
23struct ccu_mult { 34struct ccu_mult {
24 u32 enable; 35 u32 enable;
25 36
37 struct ccu_frac_internal frac;
26 struct ccu_mult_internal mult; 38 struct ccu_mult_internal mult;
27 struct ccu_mux_internal mux; 39 struct ccu_mux_internal mux;
28 struct ccu_common common; 40 struct ccu_common common;
diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c
index a43ad52a957d..c6bb1f523232 100644
--- a/drivers/clk/sunxi-ng/ccu_mux.c
+++ b/drivers/clk/sunxi-ng/ccu_mux.c
@@ -25,9 +25,15 @@ void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common,
25 int i; 25 int i;
26 26
27 if (!((common->features & CCU_FEATURE_FIXED_PREDIV) || 27 if (!((common->features & CCU_FEATURE_FIXED_PREDIV) ||
28 (common->features & CCU_FEATURE_VARIABLE_PREDIV))) 28 (common->features & CCU_FEATURE_VARIABLE_PREDIV) ||
29 (common->features & CCU_FEATURE_ALL_PREDIV)))
29 return; 30 return;
30 31
32 if (common->features & CCU_FEATURE_ALL_PREDIV) {
33 *parent_rate = *parent_rate / common->prediv;
34 return;
35 }
36
31 reg = readl(common->base + common->reg); 37 reg = readl(common->base + common->reg);
32 if (parent_index < 0) { 38 if (parent_index < 0) {
33 parent_index = reg >> cm->shift; 39 parent_index = reg >> cm->shift;
@@ -64,19 +70,46 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common,
64 struct clk_hw *best_parent, *hw = &common->hw; 70 struct clk_hw *best_parent, *hw = &common->hw;
65 unsigned int i; 71 unsigned int i;
66 72
73 if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) {
74 unsigned long adj_parent_rate;
75
76 best_parent = clk_hw_get_parent(hw);
77 best_parent_rate = clk_hw_get_rate(best_parent);
78
79 adj_parent_rate = best_parent_rate;
80 ccu_mux_helper_adjust_parent_for_prediv(common, cm, -1,
81 &adj_parent_rate);
82
83 best_rate = round(cm, adj_parent_rate, req->rate, data);
84
85 goto out;
86 }
87
67 for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 88 for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
68 unsigned long tmp_rate, parent_rate; 89 unsigned long tmp_rate, parent_rate, adj_parent_rate;
69 struct clk_hw *parent; 90 struct clk_hw *parent;
70 91
71 parent = clk_hw_get_parent_by_index(hw, i); 92 parent = clk_hw_get_parent_by_index(hw, i);
72 if (!parent) 93 if (!parent)
73 continue; 94 continue;
74 95
75 parent_rate = clk_hw_get_rate(parent); 96 if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
97 struct clk_rate_request parent_req = *req;
98 int ret = __clk_determine_rate(parent, &parent_req);
99
100 if (ret)
101 continue;
102
103 parent_rate = parent_req.rate;
104 } else {
105 parent_rate = clk_hw_get_rate(parent);
106 }
107
108 adj_parent_rate = parent_rate;
76 ccu_mux_helper_adjust_parent_for_prediv(common, cm, i, 109 ccu_mux_helper_adjust_parent_for_prediv(common, cm, i,
77 &parent_rate); 110 &adj_parent_rate);
78 111
79 tmp_rate = round(cm, clk_hw_get_rate(parent), req->rate, data); 112 tmp_rate = round(cm, adj_parent_rate, req->rate, data);
80 if (tmp_rate == req->rate) { 113 if (tmp_rate == req->rate) {
81 best_parent = parent; 114 best_parent = parent;
82 best_parent_rate = parent_rate; 115 best_parent_rate = parent_rate;
diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c
index eaf0fdf78d2b..b9e9b8a9d1b4 100644
--- a/drivers/clk/sunxi-ng/ccu_nk.c
+++ b/drivers/clk/sunxi-ng/ccu_nk.c
@@ -76,12 +76,17 @@ static unsigned long ccu_nk_recalc_rate(struct clk_hw *hw,
76 76
77 n = reg >> nk->n.shift; 77 n = reg >> nk->n.shift;
78 n &= (1 << nk->n.width) - 1; 78 n &= (1 << nk->n.width) - 1;
79 n += nk->n.offset;
80 if (!n)
81 n++;
79 82
80 k = reg >> nk->k.shift; 83 k = reg >> nk->k.shift;
81 k &= (1 << nk->k.width) - 1; 84 k &= (1 << nk->k.width) - 1;
85 k += nk->k.offset;
86 if (!k)
87 k++;
82 88
83 rate = parent_rate * (n + 1) * (k + 1); 89 rate = parent_rate * n * k;
84
85 if (nk->common.features & CCU_FEATURE_FIXED_POSTDIV) 90 if (nk->common.features & CCU_FEATURE_FIXED_POSTDIV)
86 rate /= nk->fixed_post_div; 91 rate /= nk->fixed_post_div;
87 92
@@ -98,9 +103,9 @@ static long ccu_nk_round_rate(struct clk_hw *hw, unsigned long rate,
98 rate *= nk->fixed_post_div; 103 rate *= nk->fixed_post_div;
99 104
100 _nk.min_n = nk->n.min; 105 _nk.min_n = nk->n.min;
101 _nk.max_n = 1 << nk->n.width; 106 _nk.max_n = nk->n.max ?: 1 << nk->n.width;
102 _nk.min_k = nk->k.min; 107 _nk.min_k = nk->k.min;
103 _nk.max_k = 1 << nk->k.width; 108 _nk.max_k = nk->k.max ?: 1 << nk->k.width;
104 109
105 ccu_nk_find_best(*parent_rate, rate, &_nk); 110 ccu_nk_find_best(*parent_rate, rate, &_nk);
106 rate = *parent_rate * _nk.n * _nk.k; 111 rate = *parent_rate * _nk.n * _nk.k;
@@ -123,9 +128,9 @@ static int ccu_nk_set_rate(struct clk_hw *hw, unsigned long rate,
123 rate = rate * nk->fixed_post_div; 128 rate = rate * nk->fixed_post_div;
124 129
125 _nk.min_n = nk->n.min; 130 _nk.min_n = nk->n.min;
126 _nk.max_n = 1 << nk->n.width; 131 _nk.max_n = nk->n.max ?: 1 << nk->n.width;
127 _nk.min_k = nk->k.min; 132 _nk.min_k = nk->k.min;
128 _nk.max_k = 1 << nk->k.width; 133 _nk.max_k = nk->k.max ?: 1 << nk->k.width;
129 134
130 ccu_nk_find_best(parent_rate, rate, &_nk); 135 ccu_nk_find_best(parent_rate, rate, &_nk);
131 136
@@ -135,8 +140,9 @@ static int ccu_nk_set_rate(struct clk_hw *hw, unsigned long rate,
135 reg &= ~GENMASK(nk->n.width + nk->n.shift - 1, nk->n.shift); 140 reg &= ~GENMASK(nk->n.width + nk->n.shift - 1, nk->n.shift);
136 reg &= ~GENMASK(nk->k.width + nk->k.shift - 1, nk->k.shift); 141 reg &= ~GENMASK(nk->k.width + nk->k.shift - 1, nk->k.shift);
137 142
138 writel(reg | ((_nk.k - 1) << nk->k.shift) | ((_nk.n - 1) << nk->n.shift), 143 reg |= (_nk.k - nk->k.offset) << nk->k.shift;
139 nk->common.base + nk->common.reg); 144 reg |= (_nk.n - nk->n.offset) << nk->n.shift;
145 writel(reg, nk->common.base + nk->common.reg);
140 146
141 spin_unlock_irqrestore(nk->common.lock, flags); 147 spin_unlock_irqrestore(nk->common.lock, flags);
142 148
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
index 9b840a47a94d..71f81e95a061 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
@@ -82,14 +82,23 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
82 82
83 n = reg >> nkm->n.shift; 83 n = reg >> nkm->n.shift;
84 n &= (1 << nkm->n.width) - 1; 84 n &= (1 << nkm->n.width) - 1;
85 n += nkm->n.offset;
86 if (!n)
87 n++;
85 88
86 k = reg >> nkm->k.shift; 89 k = reg >> nkm->k.shift;
87 k &= (1 << nkm->k.width) - 1; 90 k &= (1 << nkm->k.width) - 1;
91 k += nkm->k.offset;
92 if (!k)
93 k++;
88 94
89 m = reg >> nkm->m.shift; 95 m = reg >> nkm->m.shift;
90 m &= (1 << nkm->m.width) - 1; 96 m &= (1 << nkm->m.width) - 1;
97 m += nkm->m.offset;
98 if (!m)
99 m++;
91 100
92 return parent_rate * (n + 1) * (k + 1) / (m + 1); 101 return parent_rate * n * k / m;
93} 102}
94 103
95static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, 104static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
@@ -101,9 +110,9 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
101 struct _ccu_nkm _nkm; 110 struct _ccu_nkm _nkm;
102 111
103 _nkm.min_n = nkm->n.min; 112 _nkm.min_n = nkm->n.min;
104 _nkm.max_n = 1 << nkm->n.width; 113 _nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
105 _nkm.min_k = nkm->k.min; 114 _nkm.min_k = nkm->k.min;
106 _nkm.max_k = 1 << nkm->k.width; 115 _nkm.max_k = nkm->k.max ?: 1 << nkm->k.width;
107 _nkm.min_m = 1; 116 _nkm.min_m = 1;
108 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; 117 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
109 118
@@ -130,9 +139,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
130 u32 reg; 139 u32 reg;
131 140
132 _nkm.min_n = nkm->n.min; 141 _nkm.min_n = nkm->n.min;
133 _nkm.max_n = 1 << nkm->n.width; 142 _nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
134 _nkm.min_k = nkm->k.min; 143 _nkm.min_k = nkm->k.min;
135 _nkm.max_k = 1 << nkm->k.width; 144 _nkm.max_k = nkm->k.max ?: 1 << nkm->k.width;
136 _nkm.min_m = 1; 145 _nkm.min_m = 1;
137 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; 146 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
138 147
@@ -145,10 +154,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
145 reg &= ~GENMASK(nkm->k.width + nkm->k.shift - 1, nkm->k.shift); 154 reg &= ~GENMASK(nkm->k.width + nkm->k.shift - 1, nkm->k.shift);
146 reg &= ~GENMASK(nkm->m.width + nkm->m.shift - 1, nkm->m.shift); 155 reg &= ~GENMASK(nkm->m.width + nkm->m.shift - 1, nkm->m.shift);
147 156
148 reg |= (_nkm.n - 1) << nkm->n.shift; 157 reg |= (_nkm.n - nkm->n.offset) << nkm->n.shift;
149 reg |= (_nkm.k - 1) << nkm->k.shift; 158 reg |= (_nkm.k - nkm->k.offset) << nkm->k.shift;
150 reg |= (_nkm.m - 1) << nkm->m.shift; 159 reg |= (_nkm.m - nkm->m.offset) << nkm->m.shift;
151
152 writel(reg, nkm->common.base + nkm->common.reg); 160 writel(reg, nkm->common.base + nkm->common.reg);
153 161
154 spin_unlock_irqrestore(nkm->common.lock, flags); 162 spin_unlock_irqrestore(nkm->common.lock, flags);
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
index 684c42da3ebb..a2b40a000157 100644
--- a/drivers/clk/sunxi-ng/ccu_nkmp.c
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
@@ -88,17 +88,26 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
88 88
89 n = reg >> nkmp->n.shift; 89 n = reg >> nkmp->n.shift;
90 n &= (1 << nkmp->n.width) - 1; 90 n &= (1 << nkmp->n.width) - 1;
91 n += nkmp->n.offset;
92 if (!n)
93 n++;
91 94
92 k = reg >> nkmp->k.shift; 95 k = reg >> nkmp->k.shift;
93 k &= (1 << nkmp->k.width) - 1; 96 k &= (1 << nkmp->k.width) - 1;
97 k += nkmp->k.offset;
98 if (!k)
99 k++;
94 100
95 m = reg >> nkmp->m.shift; 101 m = reg >> nkmp->m.shift;
96 m &= (1 << nkmp->m.width) - 1; 102 m &= (1 << nkmp->m.width) - 1;
103 m += nkmp->m.offset;
104 if (!m)
105 m++;
97 106
98 p = reg >> nkmp->p.shift; 107 p = reg >> nkmp->p.shift;
99 p &= (1 << nkmp->p.width) - 1; 108 p &= (1 << nkmp->p.width) - 1;
100 109
101 return (parent_rate * (n + 1) * (k + 1) >> p) / (m + 1); 110 return parent_rate * n * k >> p / m;
102} 111}
103 112
104static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, 113static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -108,9 +117,9 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
108 struct _ccu_nkmp _nkmp; 117 struct _ccu_nkmp _nkmp;
109 118
110 _nkmp.min_n = nkmp->n.min; 119 _nkmp.min_n = nkmp->n.min;
111 _nkmp.max_n = 1 << nkmp->n.width; 120 _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
112 _nkmp.min_k = nkmp->k.min; 121 _nkmp.min_k = nkmp->k.min;
113 _nkmp.max_k = 1 << nkmp->k.width; 122 _nkmp.max_k = nkmp->k.max ?: 1 << nkmp->k.width;
114 _nkmp.min_m = 1; 123 _nkmp.min_m = 1;
115 _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width; 124 _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
116 _nkmp.min_p = 1; 125 _nkmp.min_p = 1;
@@ -130,9 +139,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
130 u32 reg; 139 u32 reg;
131 140
132 _nkmp.min_n = 1; 141 _nkmp.min_n = 1;
133 _nkmp.max_n = 1 << nkmp->n.width; 142 _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
134 _nkmp.min_k = 1; 143 _nkmp.min_k = 1;
135 _nkmp.max_k = 1 << nkmp->k.width; 144 _nkmp.max_k = nkmp->k.max ?: 1 << nkmp->k.width;
136 _nkmp.min_m = 1; 145 _nkmp.min_m = 1;
137 _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width; 146 _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
138 _nkmp.min_p = 1; 147 _nkmp.min_p = 1;
@@ -148,9 +157,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
148 reg &= ~GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift); 157 reg &= ~GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift);
149 reg &= ~GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift); 158 reg &= ~GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift);
150 159
151 reg |= (_nkmp.n - 1) << nkmp->n.shift; 160 reg |= (_nkmp.n - nkmp->n.offset) << nkmp->n.shift;
152 reg |= (_nkmp.k - 1) << nkmp->k.shift; 161 reg |= (_nkmp.k - nkmp->k.offset) << nkmp->k.shift;
153 reg |= (_nkmp.m - 1) << nkmp->m.shift; 162 reg |= (_nkmp.m - nkmp->m.offset) << nkmp->m.shift;
154 reg |= ilog2(_nkmp.p) << nkmp->p.shift; 163 reg |= ilog2(_nkmp.p) << nkmp->p.shift;
155 164
156 writel(reg, nkmp->common.base + nkmp->common.reg); 165 writel(reg, nkmp->common.base + nkmp->common.reg);
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
index c9f3b6c982f0..af71b1909cd9 100644
--- a/drivers/clk/sunxi-ng/ccu_nm.c
+++ b/drivers/clk/sunxi-ng/ccu_nm.c
@@ -80,11 +80,17 @@ static unsigned long ccu_nm_recalc_rate(struct clk_hw *hw,
80 80
81 n = reg >> nm->n.shift; 81 n = reg >> nm->n.shift;
82 n &= (1 << nm->n.width) - 1; 82 n &= (1 << nm->n.width) - 1;
83 n += nm->n.offset;
84 if (!n)
85 n++;
83 86
84 m = reg >> nm->m.shift; 87 m = reg >> nm->m.shift;
85 m &= (1 << nm->m.width) - 1; 88 m &= (1 << nm->m.width) - 1;
89 m += nm->m.offset;
90 if (!m)
91 m++;
86 92
87 return parent_rate * (n + 1) / (m + 1); 93 return parent_rate * n / m;
88} 94}
89 95
90static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, 96static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -94,7 +100,7 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
94 struct _ccu_nm _nm; 100 struct _ccu_nm _nm;
95 101
96 _nm.min_n = nm->n.min; 102 _nm.min_n = nm->n.min;
97 _nm.max_n = 1 << nm->n.width; 103 _nm.max_n = nm->n.max ?: 1 << nm->n.width;
98 _nm.min_m = 1; 104 _nm.min_m = 1;
99 _nm.max_m = nm->m.max ?: 1 << nm->m.width; 105 _nm.max_m = nm->m.max ?: 1 << nm->m.width;
100 106
@@ -117,7 +123,7 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
117 ccu_frac_helper_disable(&nm->common, &nm->frac); 123 ccu_frac_helper_disable(&nm->common, &nm->frac);
118 124
119 _nm.min_n = 1; 125 _nm.min_n = 1;
120 _nm.max_n = 1 << nm->n.width; 126 _nm.max_n = nm->n.max ?: 1 << nm->n.width;
121 _nm.min_m = 1; 127 _nm.min_m = 1;
122 _nm.max_m = nm->m.max ?: 1 << nm->m.width; 128 _nm.max_m = nm->m.max ?: 1 << nm->m.width;
123 129
@@ -129,8 +135,9 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
129 reg &= ~GENMASK(nm->n.width + nm->n.shift - 1, nm->n.shift); 135 reg &= ~GENMASK(nm->n.width + nm->n.shift - 1, nm->n.shift);
130 reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift); 136 reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift);
131 137
132 writel(reg | ((_nm.m - 1) << nm->m.shift) | ((_nm.n - 1) << nm->n.shift), 138 reg |= (_nm.n - nm->n.offset) << nm->n.shift;
133 nm->common.base + nm->common.reg); 139 reg |= (_nm.m - nm->m.offset) << nm->m.shift;
140 writel(reg, nm->common.base + nm->common.reg);
134 141
135 spin_unlock_irqrestore(nm->common.lock, flags); 142 spin_unlock_irqrestore(nm->common.lock, flags);
136 143
diff --git a/drivers/clk/tegra/Kconfig b/drivers/clk/tegra/Kconfig
index 1ba30d1e14f2..7ddacae5d0b1 100644
--- a/drivers/clk/tegra/Kconfig
+++ b/drivers/clk/tegra/Kconfig
@@ -1,3 +1,7 @@
1config TEGRA_CLK_EMC 1config TEGRA_CLK_EMC
2 def_bool y 2 def_bool y
3 depends on TEGRA124_EMC 3 depends on TEGRA124_EMC
4
5config CLK_TEGRA_BPMP
6 def_bool y
7 depends on TEGRA_BPMP
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index 33fd0938d79e..4be8af28ee61 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124-dfll-fcpu.o
22obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o 22obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o
23obj-y += cvb.o 23obj-y += cvb.o
24obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o 24obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o
25obj-$(CONFIG_CLK_TEGRA_BPMP) += clk-bpmp.o
diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c
new file mode 100644
index 000000000000..638ace64033b
--- /dev/null
+++ b/drivers/clk/tegra/clk-bpmp.c
@@ -0,0 +1,620 @@
1/*
2 * Copyright (C) 2016 NVIDIA Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/clk-provider.h>
10#include <linux/device.h>
11#include <linux/seq_buf.h>
12#include <linux/slab.h>
13
14#include <soc/tegra/bpmp.h>
15#include <soc/tegra/bpmp-abi.h>
16
17#define TEGRA_BPMP_DUMP_CLOCK_INFO 0
18
19#define TEGRA_BPMP_CLK_HAS_MUX BIT(0)
20#define TEGRA_BPMP_CLK_HAS_SET_RATE BIT(1)
21#define TEGRA_BPMP_CLK_IS_ROOT BIT(2)
22
23struct tegra_bpmp_clk_info {
24 unsigned int id;
25 char name[MRQ_CLK_NAME_MAXLEN];
26 unsigned int parents[MRQ_CLK_MAX_PARENTS];
27 unsigned int num_parents;
28 unsigned long flags;
29};
30
31struct tegra_bpmp_clk {
32 struct clk_hw hw;
33
34 struct tegra_bpmp *bpmp;
35 unsigned int id;
36
37 unsigned int num_parents;
38 unsigned int *parents;
39};
40
41static inline struct tegra_bpmp_clk *to_tegra_bpmp_clk(struct clk_hw *hw)
42{
43 return container_of(hw, struct tegra_bpmp_clk, hw);
44}
45
46struct tegra_bpmp_clk_message {
47 unsigned int cmd;
48 unsigned int id;
49
50 struct {
51 const void *data;
52 size_t size;
53 } tx;
54
55 struct {
56 void *data;
57 size_t size;
58 } rx;
59};
60
61static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
62 const struct tegra_bpmp_clk_message *clk)
63{
64 struct mrq_clk_request request;
65 struct tegra_bpmp_message msg;
66 void *req = &request;
67
68 memset(&request, 0, sizeof(request));
69 request.cmd_and_id = (clk->cmd << 24) | clk->id;
70
71 /*
72 * The mrq_clk_request structure has an anonymous union at offset 4
73 * that contains all possible sub-command structures. Copy the data
74 * to that union. Ideally we'd be able to refer to it by name, but
75 * doing so would require changing the ABI header and increase the
76 * maintenance burden.
77 */
78 memcpy(req + 4, clk->tx.data, clk->tx.size);
79
80 memset(&msg, 0, sizeof(msg));
81 msg.mrq = MRQ_CLK;
82 msg.tx.data = &request;
83 msg.tx.size = sizeof(request);
84 msg.rx.data = clk->rx.data;
85 msg.rx.size = clk->rx.size;
86
87 return tegra_bpmp_transfer(bpmp, &msg);
88}
89
90static int tegra_bpmp_clk_prepare(struct clk_hw *hw)
91{
92 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
93 struct tegra_bpmp_clk_message msg;
94
95 memset(&msg, 0, sizeof(msg));
96 msg.cmd = CMD_CLK_ENABLE;
97 msg.id = clk->id;
98
99 return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
100}
101
102static void tegra_bpmp_clk_unprepare(struct clk_hw *hw)
103{
104 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
105 struct tegra_bpmp_clk_message msg;
106 int err;
107
108 memset(&msg, 0, sizeof(msg));
109 msg.cmd = CMD_CLK_DISABLE;
110 msg.id = clk->id;
111
112 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
113 if (err < 0)
114 dev_err(clk->bpmp->dev, "failed to disable clock %s: %d\n",
115 clk_hw_get_name(hw), err);
116}
117
118static int tegra_bpmp_clk_is_prepared(struct clk_hw *hw)
119{
120 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
121 struct cmd_clk_is_enabled_response response;
122 struct tegra_bpmp_clk_message msg;
123 int err;
124
125 memset(&msg, 0, sizeof(msg));
126 msg.cmd = CMD_CLK_IS_ENABLED;
127 msg.id = clk->id;
128 msg.rx.data = &response;
129 msg.rx.size = sizeof(response);
130
131 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
132 if (err < 0)
133 return err;
134
135 return response.state;
136}
137
138static unsigned long tegra_bpmp_clk_recalc_rate(struct clk_hw *hw,
139 unsigned long parent_rate)
140{
141 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
142 struct cmd_clk_get_rate_response response;
143 struct cmd_clk_get_rate_request request;
144 struct tegra_bpmp_clk_message msg;
145 int err;
146
147 memset(&msg, 0, sizeof(msg));
148 msg.cmd = CMD_CLK_GET_RATE;
149 msg.id = clk->id;
150 msg.tx.data = &request;
151 msg.tx.size = sizeof(request);
152 msg.rx.data = &response;
153 msg.rx.size = sizeof(response);
154
155 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
156 if (err < 0)
157 return err;
158
159 return response.rate;
160}
161
162static long tegra_bpmp_clk_round_rate(struct clk_hw *hw, unsigned long rate,
163 unsigned long *parent_rate)
164{
165 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
166 struct cmd_clk_round_rate_response response;
167 struct cmd_clk_round_rate_request request;
168 struct tegra_bpmp_clk_message msg;
169 int err;
170
171 memset(&request, 0, sizeof(request));
172 request.rate = rate;
173
174 memset(&msg, 0, sizeof(msg));
175 msg.cmd = CMD_CLK_ROUND_RATE;
176 msg.id = clk->id;
177 msg.tx.data = &request;
178 msg.tx.size = sizeof(request);
179 msg.rx.data = &response;
180 msg.rx.size = sizeof(response);
181
182 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
183 if (err < 0)
184 return err;
185
186 return response.rate;
187}
188
189static int tegra_bpmp_clk_set_parent(struct clk_hw *hw, u8 index)
190{
191 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
192 struct cmd_clk_set_parent_response response;
193 struct cmd_clk_set_parent_request request;
194 struct tegra_bpmp_clk_message msg;
195 int err;
196
197 memset(&request, 0, sizeof(request));
198 request.parent_id = clk->parents[index];
199
200 memset(&msg, 0, sizeof(msg));
201 msg.cmd = CMD_CLK_SET_PARENT;
202 msg.id = clk->id;
203 msg.tx.data = &request;
204 msg.tx.size = sizeof(request);
205 msg.rx.data = &response;
206 msg.rx.size = sizeof(response);
207
208 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
209 if (err < 0)
210 return err;
211
212 /* XXX check parent ID in response */
213
214 return 0;
215}
216
217static u8 tegra_bpmp_clk_get_parent(struct clk_hw *hw)
218{
219 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
220 struct cmd_clk_get_parent_response response;
221 struct tegra_bpmp_clk_message msg;
222 unsigned int i;
223 int err;
224
225 memset(&msg, 0, sizeof(msg));
226 msg.cmd = CMD_CLK_GET_PARENT;
227 msg.id = clk->id;
228 msg.rx.data = &response;
229 msg.rx.size = sizeof(response);
230
231 err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
232 if (err < 0) {
233 dev_err(clk->bpmp->dev, "failed to get parent for %s: %d\n",
234 clk_hw_get_name(hw), err);
235 return U8_MAX;
236 }
237
238 for (i = 0; i < clk->num_parents; i++)
239 if (clk->parents[i] == response.parent_id)
240 return i;
241
242 return U8_MAX;
243}
244
245static int tegra_bpmp_clk_set_rate(struct clk_hw *hw, unsigned long rate,
246 unsigned long parent_rate)
247{
248 struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
249 struct cmd_clk_set_rate_response response;
250 struct cmd_clk_set_rate_request request;
251 struct tegra_bpmp_clk_message msg;
252
253 memset(&request, 0, sizeof(request));
254 request.rate = rate;
255
256 memset(&msg, 0, sizeof(msg));
257 msg.cmd = CMD_CLK_SET_RATE;
258 msg.id = clk->id;
259 msg.tx.data = &request;
260 msg.tx.size = sizeof(request);
261 msg.rx.data = &response;
262 msg.rx.size = sizeof(response);
263
264 return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
265}
266
267static const struct clk_ops tegra_bpmp_clk_gate_ops = {
268 .prepare = tegra_bpmp_clk_prepare,
269 .unprepare = tegra_bpmp_clk_unprepare,
270 .is_prepared = tegra_bpmp_clk_is_prepared,
271 .recalc_rate = tegra_bpmp_clk_recalc_rate,
272};
273
274static const struct clk_ops tegra_bpmp_clk_mux_ops = {
275 .prepare = tegra_bpmp_clk_prepare,
276 .unprepare = tegra_bpmp_clk_unprepare,
277 .is_prepared = tegra_bpmp_clk_is_prepared,
278 .recalc_rate = tegra_bpmp_clk_recalc_rate,
279 .set_parent = tegra_bpmp_clk_set_parent,
280 .get_parent = tegra_bpmp_clk_get_parent,
281};
282
283static const struct clk_ops tegra_bpmp_clk_rate_ops = {
284 .prepare = tegra_bpmp_clk_prepare,
285 .unprepare = tegra_bpmp_clk_unprepare,
286 .is_prepared = tegra_bpmp_clk_is_prepared,
287 .recalc_rate = tegra_bpmp_clk_recalc_rate,
288 .round_rate = tegra_bpmp_clk_round_rate,
289 .set_rate = tegra_bpmp_clk_set_rate,
290};
291
292static const struct clk_ops tegra_bpmp_clk_mux_rate_ops = {
293 .prepare = tegra_bpmp_clk_prepare,
294 .unprepare = tegra_bpmp_clk_unprepare,
295 .is_prepared = tegra_bpmp_clk_is_prepared,
296 .recalc_rate = tegra_bpmp_clk_recalc_rate,
297 .round_rate = tegra_bpmp_clk_round_rate,
298 .set_parent = tegra_bpmp_clk_set_parent,
299 .get_parent = tegra_bpmp_clk_get_parent,
300 .set_rate = tegra_bpmp_clk_set_rate,
301};
302
303static int tegra_bpmp_clk_get_max_id(struct tegra_bpmp *bpmp)
304{
305 struct cmd_clk_get_max_clk_id_response response;
306 struct tegra_bpmp_clk_message msg;
307 int err;
308
309 memset(&msg, 0, sizeof(msg));
310 msg.cmd = CMD_CLK_GET_MAX_CLK_ID;
311 msg.rx.data = &response;
312 msg.rx.size = sizeof(response);
313
314 err = tegra_bpmp_clk_transfer(bpmp, &msg);
315 if (err < 0)
316 return err;
317
318 if (response.max_id > INT_MAX)
319 return -E2BIG;
320
321 return response.max_id;
322}
323
324static int tegra_bpmp_clk_get_info(struct tegra_bpmp *bpmp, unsigned int id,
325 struct tegra_bpmp_clk_info *info)
326{
327 struct cmd_clk_get_all_info_response response;
328 struct tegra_bpmp_clk_message msg;
329 unsigned int i;
330 int err;
331
332 memset(&msg, 0, sizeof(msg));
333 msg.cmd = CMD_CLK_GET_ALL_INFO;
334 msg.id = id;
335 msg.rx.data = &response;
336 msg.rx.size = sizeof(response);
337
338 err = tegra_bpmp_clk_transfer(bpmp, &msg);
339 if (err < 0)
340 return err;
341
342 strlcpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN);
343 info->num_parents = response.num_parents;
344
345 for (i = 0; i < info->num_parents; i++)
346 info->parents[i] = response.parents[i];
347
348 info->flags = response.flags;
349
350 return 0;
351}
352
353static void tegra_bpmp_clk_info_dump(struct tegra_bpmp *bpmp,
354 const char *level,
355 const struct tegra_bpmp_clk_info *info)
356{
357 const char *prefix = "";
358 struct seq_buf buf;
359 unsigned int i;
360 char flags[64];
361
362 seq_buf_init(&buf, flags, sizeof(flags));
363
364 if (info->flags)
365 seq_buf_printf(&buf, "(");
366
367 if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) {
368 seq_buf_printf(&buf, "%smux", prefix);
369 prefix = ", ";
370 }
371
372 if ((info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) == 0) {
373 seq_buf_printf(&buf, "%sfixed", prefix);
374 prefix = ", ";
375 }
376
377 if (info->flags & TEGRA_BPMP_CLK_IS_ROOT) {
378 seq_buf_printf(&buf, "%sroot", prefix);
379 prefix = ", ";
380 }
381
382 if (info->flags)
383 seq_buf_printf(&buf, ")");
384
385 dev_printk(level, bpmp->dev, "%03u: %s\n", info->id, info->name);
386 dev_printk(level, bpmp->dev, " flags: %lx %s\n", info->flags, flags);
387 dev_printk(level, bpmp->dev, " parents: %u\n", info->num_parents);
388
389 for (i = 0; i < info->num_parents; i++)
390 dev_printk(level, bpmp->dev, " %03u\n", info->parents[i]);
391}
392
393static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp,
394 struct tegra_bpmp_clk_info **clocksp)
395{
396 struct tegra_bpmp_clk_info *clocks;
397 unsigned int max_id, id, count = 0;
398 unsigned int holes = 0;
399 int err;
400
401 err = tegra_bpmp_clk_get_max_id(bpmp);
402 if (err < 0)
403 return err;
404
405 max_id = err;
406
407 dev_dbg(bpmp->dev, "maximum clock ID: %u\n", max_id);
408
409 clocks = kcalloc(max_id + 1, sizeof(*clocks), GFP_KERNEL);
410 if (!clocks)
411 return -ENOMEM;
412
413 for (id = 0; id <= max_id; id++) {
414 struct tegra_bpmp_clk_info *info = &clocks[count];
415
416 err = tegra_bpmp_clk_get_info(bpmp, id, info);
417 if (err < 0) {
418 dev_err(bpmp->dev, "failed to query clock %u: %d\n",
419 id, err);
420 continue;
421 }
422
423 if (info->num_parents >= U8_MAX) {
424 dev_err(bpmp->dev,
425 "clock %u has too many parents (%u, max: %u)\n",
426 id, info->num_parents, U8_MAX);
427 continue;
428 }
429
430 /* clock not exposed by BPMP */
431 if (info->name[0] == '\0') {
432 holes++;
433 continue;
434 }
435
436 info->id = id;
437 count++;
438
439 if (TEGRA_BPMP_DUMP_CLOCK_INFO)
440 tegra_bpmp_clk_info_dump(bpmp, KERN_DEBUG, info);
441 }
442
443 dev_dbg(bpmp->dev, "holes: %u\n", holes);
444 *clocksp = clocks;
445
446 return count;
447}
448
449static const struct tegra_bpmp_clk_info *
450tegra_bpmp_clk_find(const struct tegra_bpmp_clk_info *clocks,
451 unsigned int num_clocks, unsigned int id)
452{
453 unsigned int i;
454
455 for (i = 0; i < num_clocks; i++)
456 if (clocks[i].id == id)
457 return &clocks[i];
458
459 return NULL;
460}
461
462static struct tegra_bpmp_clk *
463tegra_bpmp_clk_register(struct tegra_bpmp *bpmp,
464 const struct tegra_bpmp_clk_info *info,
465 const struct tegra_bpmp_clk_info *clocks,
466 unsigned int num_clocks)
467{
468 struct tegra_bpmp_clk *clk;
469 struct clk_init_data init;
470 const char **parents;
471 unsigned int i;
472 int err;
473
474 clk = devm_kzalloc(bpmp->dev, sizeof(*clk), GFP_KERNEL);
475 if (!clk)
476 return ERR_PTR(-ENOMEM);
477
478 clk->id = info->id;
479 clk->bpmp = bpmp;
480
481 clk->parents = devm_kcalloc(bpmp->dev, info->num_parents,
482 sizeof(*clk->parents), GFP_KERNEL);
483 if (!clk->parents)
484 return ERR_PTR(-ENOMEM);
485
486 clk->num_parents = info->num_parents;
487
488 /* hardware clock initialization */
489 memset(&init, 0, sizeof(init));
490 init.name = info->name;
491 clk->hw.init = &init;
492
493 if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) {
494 if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE)
495 init.ops = &tegra_bpmp_clk_mux_rate_ops;
496 else
497 init.ops = &tegra_bpmp_clk_mux_ops;
498 } else {
499 if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE)
500 init.ops = &tegra_bpmp_clk_rate_ops;
501 else
502 init.ops = &tegra_bpmp_clk_gate_ops;
503 }
504
505 init.num_parents = info->num_parents;
506
507 parents = kcalloc(info->num_parents, sizeof(*parents), GFP_KERNEL);
508 if (!parents)
509 return ERR_PTR(-ENOMEM);
510
511 for (i = 0; i < info->num_parents; i++) {
512 const struct tegra_bpmp_clk_info *parent;
513
514 /* keep a private copy of the ID to parent index map */
515 clk->parents[i] = info->parents[i];
516
517 parent = tegra_bpmp_clk_find(clocks, num_clocks,
518 info->parents[i]);
519 if (!parent) {
520 dev_err(bpmp->dev, "no parent %u found for %u\n",
521 info->parents[i], info->id);
522 continue;
523 }
524
525 parents[i] = parent->name;
526 }
527
528 init.parent_names = parents;
529
530 err = devm_clk_hw_register(bpmp->dev, &clk->hw);
531
532 kfree(parents);
533
534 if (err < 0)
535 return ERR_PTR(err);
536
537 return clk;
538}
539
540static int tegra_bpmp_register_clocks(struct tegra_bpmp *bpmp,
541 struct tegra_bpmp_clk_info *infos,
542 unsigned int count)
543{
544 struct tegra_bpmp_clk *clk;
545 unsigned int i;
546
547 bpmp->num_clocks = count;
548
549 bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(clk), GFP_KERNEL);
550 if (!bpmp->clocks)
551 return -ENOMEM;
552
553 for (i = 0; i < count; i++) {
554 struct tegra_bpmp_clk_info *info = &infos[i];
555
556 clk = tegra_bpmp_clk_register(bpmp, info, infos, count);
557 if (IS_ERR(clk)) {
558 dev_err(bpmp->dev,
559 "failed to register clock %u (%s): %ld\n",
560 info->id, info->name, PTR_ERR(clk));
561 continue;
562 }
563
564 bpmp->clocks[i] = clk;
565 }
566
567 return 0;
568}
569
570static void tegra_bpmp_unregister_clocks(struct tegra_bpmp *bpmp)
571{
572 unsigned int i;
573
574 for (i = 0; i < bpmp->num_clocks; i++)
575 clk_hw_unregister(&bpmp->clocks[i]->hw);
576}
577
578static struct clk_hw *tegra_bpmp_clk_of_xlate(struct of_phandle_args *clkspec,
579 void *data)
580{
581 unsigned int id = clkspec->args[0], i;
582 struct tegra_bpmp *bpmp = data;
583
584 for (i = 0; i < bpmp->num_clocks; i++)
585 if (bpmp->clocks[i]->id == id)
586 return &bpmp->clocks[i]->hw;
587
588 return NULL;
589}
590
591int tegra_bpmp_init_clocks(struct tegra_bpmp *bpmp)
592{
593 struct tegra_bpmp_clk_info *clocks;
594 unsigned int count;
595 int err;
596
597 err = tegra_bpmp_probe_clocks(bpmp, &clocks);
598 if (err < 0)
599 return err;
600
601 count = err;
602
603 dev_dbg(bpmp->dev, "%u clocks probed\n", count);
604
605 err = tegra_bpmp_register_clocks(bpmp, clocks, count);
606 if (err < 0)
607 goto free;
608
609 err = of_clk_add_hw_provider(bpmp->dev->of_node,
610 tegra_bpmp_clk_of_xlate,
611 bpmp);
612 if (err < 0) {
613 tegra_bpmp_unregister_clocks(bpmp);
614 goto free;
615 }
616
617free:
618 kfree(clocks);
619 return err;
620}
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index b4e5de16e561..6bb87784a0d6 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -140,6 +140,35 @@ static bool _is_valid_div(struct clk_divider *divider, unsigned int div)
140 return true; 140 return true;
141} 141}
142 142
143static int _div_round_up(const struct clk_div_table *table,
144 unsigned long parent_rate, unsigned long rate)
145{
146 const struct clk_div_table *clkt;
147 int up = INT_MAX;
148 int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
149
150 for (clkt = table; clkt->div; clkt++) {
151 if (clkt->div == div)
152 return clkt->div;
153 else if (clkt->div < div)
154 continue;
155
156 if ((clkt->div - div) < (up - div))
157 up = clkt->div;
158 }
159
160 return up;
161}
162
163static int _div_round(const struct clk_div_table *table,
164 unsigned long parent_rate, unsigned long rate)
165{
166 if (!table)
167 return DIV_ROUND_UP(parent_rate, rate);
168
169 return _div_round_up(table, parent_rate, rate);
170}
171
143static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, 172static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
144 unsigned long *best_parent_rate) 173 unsigned long *best_parent_rate)
145{ 174{
@@ -155,7 +184,7 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
155 184
156 if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { 185 if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
157 parent_rate = *best_parent_rate; 186 parent_rate = *best_parent_rate;
158 bestdiv = DIV_ROUND_UP(parent_rate, rate); 187 bestdiv = _div_round(divider->table, parent_rate, rate);
159 bestdiv = bestdiv == 0 ? 1 : bestdiv; 188 bestdiv = bestdiv == 0 ? 1 : bestdiv;
160 bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; 189 bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
161 return bestdiv; 190 return bestdiv;
diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c
index 0007218ce6a0..2cf386347f0c 100644
--- a/drivers/clk/uniphier/clk-uniphier-core.c
+++ b/drivers/clk/uniphier/clk-uniphier-core.c
@@ -90,11 +90,8 @@ static int uniphier_clk_probe(struct platform_device *pdev)
90 90
91 dev_dbg(dev, "register %s (index=%d)\n", p->name, p->idx); 91 dev_dbg(dev, "register %s (index=%d)\n", p->name, p->idx);
92 hw = uniphier_clk_register(dev, regmap, p); 92 hw = uniphier_clk_register(dev, regmap, p);
93 if (IS_ERR(hw)) { 93 if (WARN(IS_ERR(hw), "failed to register %s", p->name))
94 dev_err(dev, "failed to register %s (error %ld)\n", 94 continue;
95 p->name, PTR_ERR(hw));
96 return PTR_ERR(hw);
97 }
98 95
99 if (p->idx >= 0) 96 if (p->idx >= 0)
100 hw_data->hws[p->idx] = hw; 97 hw_data->hws[p->idx] = hw;
diff --git a/drivers/clk/uniphier/clk-uniphier-cpugear.c b/drivers/clk/uniphier/clk-uniphier-cpugear.c
index 9bff26e0cbb0..ec11f55594ad 100644
--- a/drivers/clk/uniphier/clk-uniphier-cpugear.c
+++ b/drivers/clk/uniphier/clk-uniphier-cpugear.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/clk-provider.h> 16#include <linux/clk-provider.h>
17#include <linux/delay.h>
18#include <linux/device.h> 17#include <linux/device.h>
19#include <linux/regmap.h> 18#include <linux/regmap.h>
20 19
diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c b/drivers/clk/uniphier/clk-uniphier-sys.c
index d049316c1c0f..c8027d909429 100644
--- a/drivers/clk/uniphier/clk-uniphier-sys.c
+++ b/drivers/clk/uniphier/clk-uniphier-sys.c
@@ -29,6 +29,15 @@
29 UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 10), \ 29 UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 10), \
30 UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15) 30 UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15)
31 31
32#define UNIPHIER_SLD3_SYS_CLK_NAND(idx) \
33 UNIPHIER_CLK_GATE("nand", (idx), NULL, 0x2104, 2)
34
35#define UNIPHIER_LD11_SYS_CLK_NAND(idx) \
36 UNIPHIER_CLK_GATE("nand", (idx), NULL, 0x210c, 0)
37
38#define UNIPHIER_LD11_SYS_CLK_EMMC(idx) \
39 UNIPHIER_CLK_GATE("emmc", (idx), NULL, 0x210c, 2)
40
32#define UNIPHIER_SLD3_SYS_CLK_STDMAC(idx) \ 41#define UNIPHIER_SLD3_SYS_CLK_STDMAC(idx) \
33 UNIPHIER_CLK_GATE("stdmac", (idx), NULL, 0x2104, 10) 42 UNIPHIER_CLK_GATE("stdmac", (idx), NULL, 0x2104, 10)
34 43
@@ -48,6 +57,7 @@ const struct uniphier_clk_data uniphier_sld3_sys_clk_data[] = {
48 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ 57 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */
49 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), 58 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16),
50 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), 59 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16),
60 UNIPHIER_SLD3_SYS_CLK_NAND(2),
51 UNIPHIER_SLD3_SYS_CLK_SD, 61 UNIPHIER_SLD3_SYS_CLK_SD,
52 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 62 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
53 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), 63 UNIPHIER_SLD3_SYS_CLK_STDMAC(8),
@@ -61,6 +71,7 @@ const struct uniphier_clk_data uniphier_ld4_sys_clk_data[] = {
61 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ 71 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */
62 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), 72 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16),
63 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), 73 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16),
74 UNIPHIER_SLD3_SYS_CLK_NAND(2),
64 UNIPHIER_SLD3_SYS_CLK_SD, 75 UNIPHIER_SLD3_SYS_CLK_SD,
65 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 76 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
66 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ 77 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */
@@ -74,6 +85,7 @@ const struct uniphier_clk_data uniphier_pro4_sys_clk_data[] = {
74 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ 85 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */
75 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8), 86 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8),
76 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32), 87 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32),
88 UNIPHIER_SLD3_SYS_CLK_NAND(2),
77 UNIPHIER_SLD3_SYS_CLK_SD, 89 UNIPHIER_SLD3_SYS_CLK_SD,
78 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 90 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
79 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, MIO, RLE */ 91 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, MIO, RLE */
@@ -89,6 +101,7 @@ const struct uniphier_clk_data uniphier_sld8_sys_clk_data[] = {
89 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ 101 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */
90 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20), 102 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20),
91 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), 103 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16),
104 UNIPHIER_SLD3_SYS_CLK_NAND(2),
92 UNIPHIER_SLD3_SYS_CLK_SD, 105 UNIPHIER_SLD3_SYS_CLK_SD,
93 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 106 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12),
94 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ 107 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */
@@ -101,6 +114,7 @@ const struct uniphier_clk_data uniphier_pro5_sys_clk_data[] = {
101 UNIPHIER_CLK_FACTOR("dapll2", -1, "ref", 144, 125), /* 2949.12 MHz */ 114 UNIPHIER_CLK_FACTOR("dapll2", -1, "ref", 144, 125), /* 2949.12 MHz */
102 UNIPHIER_CLK_FACTOR("uart", 0, "dapll2", 1, 40), 115 UNIPHIER_CLK_FACTOR("uart", 0, "dapll2", 1, 40),
103 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), 116 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
117 UNIPHIER_SLD3_SYS_CLK_NAND(2),
104 UNIPHIER_PRO5_SYS_CLK_SD, 118 UNIPHIER_PRO5_SYS_CLK_SD,
105 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC */ 119 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC */
106 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */ 120 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */
@@ -113,6 +127,7 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = {
113 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 96, 1), /* 2400 MHz */ 127 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 96, 1), /* 2400 MHz */
114 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 27), 128 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 27),
115 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), 129 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
130 UNIPHIER_SLD3_SYS_CLK_NAND(2),
116 UNIPHIER_PRO5_SYS_CLK_SD, 131 UNIPHIER_PRO5_SYS_CLK_SD,
117 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, RLE */ 132 UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, RLE */
118 /* GIO is always clock-enabled: no function for 0x2104 bit6 */ 133 /* GIO is always clock-enabled: no function for 0x2104 bit6 */
@@ -131,6 +146,9 @@ const struct uniphier_clk_data uniphier_ld11_sys_clk_data[] = {
131 UNIPHIER_CLK_FACTOR("vspll", -1, "ref", 80, 1), /* 2000 MHz */ 146 UNIPHIER_CLK_FACTOR("vspll", -1, "ref", 80, 1), /* 2000 MHz */
132 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), 147 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34),
133 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), 148 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40),
149 UNIPHIER_LD11_SYS_CLK_NAND(2),
150 UNIPHIER_LD11_SYS_CLK_EMMC(4),
151 /* Index 5 reserved for eMMC PHY */
134 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC, MIO */ 152 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC, MIO */
135 UNIPHIER_CLK_FACTOR("usb2", -1, "ref", 24, 25), 153 UNIPHIER_CLK_FACTOR("usb2", -1, "ref", 24, 25),
136 /* CPU gears */ 154 /* CPU gears */
@@ -156,6 +174,9 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = {
156 UNIPHIER_CLK_FACTOR("vppll", -1, "ref", 504, 5), /* 2520 MHz */ 174 UNIPHIER_CLK_FACTOR("vppll", -1, "ref", 504, 5), /* 2520 MHz */
157 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), 175 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34),
158 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), 176 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40),
177 UNIPHIER_LD11_SYS_CLK_NAND(2),
178 UNIPHIER_LD11_SYS_CLK_EMMC(4),
179 /* Index 5 reserved for eMMC PHY */
159 UNIPHIER_LD20_SYS_CLK_SD, 180 UNIPHIER_LD20_SYS_CLK_SD,
160 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC */ 181 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC */
161 /* GIO is always clock-enabled: no function for 0x210c bit5 */ 182 /* GIO is always clock-enabled: no function for 0x210c bit5 */
diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c
index a07c31e6f26d..2257d12ba988 100644
--- a/drivers/clk/ux500/abx500-clk.c
+++ b/drivers/clk/ux500/abx500-clk.c
@@ -10,20 +10,26 @@
10#include <linux/err.h> 10#include <linux/err.h>
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/device.h> 12#include <linux/device.h>
13#include <linux/of.h>
13#include <linux/platform_device.h> 14#include <linux/platform_device.h>
14#include <linux/mfd/abx500/ab8500.h> 15#include <linux/mfd/abx500/ab8500.h>
15#include <linux/mfd/abx500/ab8500-sysctrl.h> 16#include <linux/mfd/abx500/ab8500-sysctrl.h>
16#include <linux/clkdev.h> 17#include <linux/clkdev.h>
17#include <linux/clk-provider.h> 18#include <linux/clk-provider.h>
18#include <linux/mfd/dbx500-prcmu.h> 19#include <dt-bindings/clock/ste-ab8500.h>
19#include "clk.h" 20#include "clk.h"
20 21
22#define AB8500_NUM_CLKS 6
23
24static struct clk *ab8500_clks[AB8500_NUM_CLKS];
25static struct clk_onecell_data ab8500_clk_data;
26
21/* Clock definitions for ab8500 */ 27/* Clock definitions for ab8500 */
22static int ab8500_reg_clks(struct device *dev) 28static int ab8500_reg_clks(struct device *dev)
23{ 29{
24 int ret; 30 int ret;
25 struct clk *clk; 31 struct clk *clk;
26 32 struct device_node *np = dev->of_node;
27 const char *intclk_parents[] = {"ab8500_sysclk", "ulpclk"}; 33 const char *intclk_parents[] = {"ab8500_sysclk", "ulpclk"};
28 u16 intclk_reg_sel[] = {0 , AB8500_SYSULPCLKCTRL1}; 34 u16 intclk_reg_sel[] = {0 , AB8500_SYSULPCLKCTRL1};
29 u8 intclk_reg_mask[] = {0 , AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK}; 35 u8 intclk_reg_mask[] = {0 , AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK};
@@ -32,55 +38,52 @@ static int ab8500_reg_clks(struct device *dev)
32 (1 << AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT) 38 (1 << AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT)
33 }; 39 };
34 40
35 dev_info(dev, "register clocks for ab850x\n");
36
37 /* Enable SWAT */ 41 /* Enable SWAT */
38 ret = ab8500_sysctrl_set(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE); 42 ret = ab8500_sysctrl_set(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE);
39 if (ret) 43 if (ret)
40 return ret; 44 return ret;
41 45
42 /* ab8500_sysclk */
43 clk = clk_reg_prcmu_gate("ab8500_sysclk", NULL, PRCMU_SYSCLK, 0);
44 clk_register_clkdev(clk, "sysclk", "ab8500-usb.0");
45 clk_register_clkdev(clk, "sysclk", "ab-iddet.0");
46 clk_register_clkdev(clk, "sysclk", "snd-soc-mop500.0");
47 clk_register_clkdev(clk, "sysclk", "shrm_bus");
48
49 /* ab8500_sysclk2 */ 46 /* ab8500_sysclk2 */
50 clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk2", "ab8500_sysclk", 47 clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk2", "ab8500_sysclk",
51 AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, 48 AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ,
52 AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, 0, 0); 49 AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, 0, 0);
53 clk_register_clkdev(clk, "sysclk", "0-0070"); 50 ab8500_clks[AB8500_SYSCLK_BUF2] = clk;
54 51
55 /* ab8500_sysclk3 */ 52 /* ab8500_sysclk3 */
56 clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk3", "ab8500_sysclk", 53 clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk3", "ab8500_sysclk",
57 AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, 54 AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ,
58 AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, 0, 0); 55 AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, 0, 0);
59 clk_register_clkdev(clk, "sysclk", "cg1960_core.0"); 56 ab8500_clks[AB8500_SYSCLK_BUF3] = clk;
60 57
61 /* ab8500_sysclk4 */ 58 /* ab8500_sysclk4 */
62 clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk4", "ab8500_sysclk", 59 clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk4", "ab8500_sysclk",
63 AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, 60 AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ,
64 AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, 0, 0); 61 AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, 0, 0);
62 ab8500_clks[AB8500_SYSCLK_BUF4] = clk;
65 63
66 /* ab_ulpclk */ 64 /* ab_ulpclk */
67 clk = clk_reg_sysctrl_gate_fixed_rate(dev, "ulpclk", NULL, 65 clk = clk_reg_sysctrl_gate_fixed_rate(dev, "ulpclk", NULL,
68 AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, 66 AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ,
69 AB8500_SYSULPCLKCTRL1_ULPCLKREQ, 67 AB8500_SYSULPCLKCTRL1_ULPCLKREQ,
70 38400000, 9000, 0); 68 38400000, 9000, 0);
71 clk_register_clkdev(clk, "ulpclk", "snd-soc-mop500.0"); 69 ab8500_clks[AB8500_SYSCLK_ULP] = clk;
72 70
73 /* ab8500_intclk */ 71 /* ab8500_intclk */
74 clk = clk_reg_sysctrl_set_parent(dev , "intclk", intclk_parents, 2, 72 clk = clk_reg_sysctrl_set_parent(dev , "intclk", intclk_parents, 2,
75 intclk_reg_sel, intclk_reg_mask, intclk_reg_bits, 0); 73 intclk_reg_sel, intclk_reg_mask, intclk_reg_bits, 0);
76 clk_register_clkdev(clk, "intclk", "snd-soc-mop500.0"); 74 ab8500_clks[AB8500_SYSCLK_INT] = clk;
77 clk_register_clkdev(clk, NULL, "ab8500-pwm.1");
78 75
79 /* ab8500_audioclk */ 76 /* ab8500_audioclk */
80 clk = clk_reg_sysctrl_gate(dev , "audioclk", "intclk", 77 clk = clk_reg_sysctrl_gate(dev , "audioclk", "intclk",
81 AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 78 AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA,
82 AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 0, 0); 79 AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 0, 0);
83 clk_register_clkdev(clk, "audioclk", "ab8500-codec.0"); 80 ab8500_clks[AB8500_SYSCLK_AUDIO] = clk;
81
82 ab8500_clk_data.clks = ab8500_clks;
83 ab8500_clk_data.clk_num = ARRAY_SIZE(ab8500_clks);
84 of_clk_add_provider(np, of_clk_src_onecell_get, &ab8500_clk_data);
85
86 dev_info(dev, "registered clocks for ab850x\n");
84 87
85 return 0; 88 return 0;
86} 89}
@@ -116,9 +119,15 @@ static int abx500_clk_probe(struct platform_device *pdev)
116 return ret; 119 return ret;
117} 120}
118 121
122static const struct of_device_id abx500_clk_match[] = {
123 { .compatible = "stericsson,ab8500-clk", },
124 {}
125};
126
119static struct platform_driver abx500_clk_driver = { 127static struct platform_driver abx500_clk_driver = {
120 .driver = { 128 .driver = {
121 .name = "abx500-clk", 129 .name = "abx500-clk",
130 .of_match_table = abx500_clk_match,
122 }, 131 },
123 .probe = abx500_clk_probe, 132 .probe = abx500_clk_probe,
124}; 133};
@@ -127,7 +136,6 @@ static int __init abx500_clk_init(void)
127{ 136{
128 return platform_driver_register(&abx500_clk_driver); 137 return platform_driver_register(&abx500_clk_driver);
129} 138}
130
131arch_initcall(abx500_clk_init); 139arch_initcall(abx500_clk_init);
132 140
133MODULE_AUTHOR("Ulf Hansson <ulf.hansson@linaro.org"); 141MODULE_AUTHOR("Ulf Hansson <ulf.hansson@linaro.org");
diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c
index e960d686d9db..d5888591e1a9 100644
--- a/drivers/clk/ux500/u8500_of_clk.c
+++ b/drivers/clk/ux500/u8500_of_clk.c
@@ -206,6 +206,9 @@ static void u8500_clk_init(struct device_node *np)
206 clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, 0); 206 clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, 0);
207 prcmu_clk[PRCMU_TIMCLK] = clk; 207 prcmu_clk[PRCMU_TIMCLK] = clk;
208 208
209 clk = clk_reg_prcmu_gate("ab8500_sysclk", NULL, PRCMU_SYSCLK, 0);
210 prcmu_clk[PRCMU_SYSCLK] = clk;
211
209 clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, PRCMU_SDMMCCLK, 212 clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, PRCMU_SDMMCCLK,
210 100000000, CLK_SET_RATE_GATE); 213 100000000, CLK_SET_RATE_GATE);
211 prcmu_clk[PRCMU_SDMMCCLK] = clk; 214 prcmu_clk[PRCMU_SDMMCCLK] = clk;
diff --git a/drivers/clk/x86/Makefile b/drivers/clk/x86/Makefile
index 04781389d0fb..1367afb03858 100644
--- a/drivers/clk/x86/Makefile
+++ b/drivers/clk/x86/Makefile
@@ -1,2 +1,3 @@
1clk-x86-lpss-objs := clk-lpt.o 1clk-x86-lpss-objs := clk-lpt.o
2obj-$(CONFIG_X86_INTEL_LPSS) += clk-x86-lpss.o 2obj-$(CONFIG_X86_INTEL_LPSS) += clk-x86-lpss.o
3obj-$(CONFIG_PMC_ATOM) += clk-pmc-atom.o
diff --git a/drivers/clk/x86/clk-pmc-atom.c b/drivers/clk/x86/clk-pmc-atom.c
new file mode 100644
index 000000000000..2b60577703ef
--- /dev/null
+++ b/drivers/clk/x86/clk-pmc-atom.c
@@ -0,0 +1,371 @@
1/*
2 * Intel Atom platform clocks driver for BayTrail and CherryTrail SoCs
3 *
4 * Copyright (C) 2016, Intel Corporation
5 * Author: Irina Tirdea <irina.tirdea@intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 */
16
17#include <linux/clk-provider.h>
18#include <linux/clkdev.h>
19#include <linux/err.h>
20#include <linux/platform_data/x86/clk-pmc-atom.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23
24#define PLT_CLK_NAME_BASE "pmc_plt_clk"
25
26#define PMC_CLK_CTL_OFFSET 0x60
27#define PMC_CLK_CTL_SIZE 4
28#define PMC_CLK_NUM 6
29#define PMC_CLK_CTL_GATED_ON_D3 0x0
30#define PMC_CLK_CTL_FORCE_ON 0x1
31#define PMC_CLK_CTL_FORCE_OFF 0x2
32#define PMC_CLK_CTL_RESERVED 0x3
33#define PMC_MASK_CLK_CTL GENMASK(1, 0)
34#define PMC_MASK_CLK_FREQ BIT(2)
35#define PMC_CLK_FREQ_XTAL (0 << 2) /* 25 MHz */
36#define PMC_CLK_FREQ_PLL (1 << 2) /* 19.2 MHz */
37
38struct clk_plt_fixed {
39 struct clk_hw *clk;
40 struct clk_lookup *lookup;
41};
42
43struct clk_plt {
44 struct clk_hw hw;
45 void __iomem *reg;
46 struct clk_lookup *lookup;
47 /* protect access to PMC registers */
48 spinlock_t lock;
49};
50
51#define to_clk_plt(_hw) container_of(_hw, struct clk_plt, hw)
52
53struct clk_plt_data {
54 struct clk_plt_fixed **parents;
55 u8 nparents;
56 struct clk_plt *clks[PMC_CLK_NUM];
57};
58
59/* Return an index in parent table */
60static inline int plt_reg_to_parent(int reg)
61{
62 switch (reg & PMC_MASK_CLK_FREQ) {
63 default:
64 case PMC_CLK_FREQ_XTAL:
65 return 0;
66 case PMC_CLK_FREQ_PLL:
67 return 1;
68 }
69}
70
71/* Return clk index of parent */
72static inline int plt_parent_to_reg(int index)
73{
74 switch (index) {
75 default:
76 case 0:
77 return PMC_CLK_FREQ_XTAL;
78 case 1:
79 return PMC_CLK_FREQ_PLL;
80 }
81}
82
83/* Abstract status in simpler enabled/disabled value */
84static inline int plt_reg_to_enabled(int reg)
85{
86 switch (reg & PMC_MASK_CLK_CTL) {
87 case PMC_CLK_CTL_GATED_ON_D3:
88 case PMC_CLK_CTL_FORCE_ON:
89 return 1; /* enabled */
90 case PMC_CLK_CTL_FORCE_OFF:
91 case PMC_CLK_CTL_RESERVED:
92 default:
93 return 0; /* disabled */
94 }
95}
96
97static void plt_clk_reg_update(struct clk_plt *clk, u32 mask, u32 val)
98{
99 u32 tmp;
100 unsigned long flags;
101
102 spin_lock_irqsave(&clk->lock, flags);
103
104 tmp = readl(clk->reg);
105 tmp = (tmp & ~mask) | (val & mask);
106 writel(tmp, clk->reg);
107
108 spin_unlock_irqrestore(&clk->lock, flags);
109}
110
111static int plt_clk_set_parent(struct clk_hw *hw, u8 index)
112{
113 struct clk_plt *clk = to_clk_plt(hw);
114
115 plt_clk_reg_update(clk, PMC_MASK_CLK_FREQ, plt_parent_to_reg(index));
116
117 return 0;
118}
119
120static u8 plt_clk_get_parent(struct clk_hw *hw)
121{
122 struct clk_plt *clk = to_clk_plt(hw);
123 u32 value;
124
125 value = readl(clk->reg);
126
127 return plt_reg_to_parent(value);
128}
129
130static int plt_clk_enable(struct clk_hw *hw)
131{
132 struct clk_plt *clk = to_clk_plt(hw);
133
134 plt_clk_reg_update(clk, PMC_MASK_CLK_CTL, PMC_CLK_CTL_FORCE_ON);
135
136 return 0;
137}
138
139static void plt_clk_disable(struct clk_hw *hw)
140{
141 struct clk_plt *clk = to_clk_plt(hw);
142
143 plt_clk_reg_update(clk, PMC_MASK_CLK_CTL, PMC_CLK_CTL_FORCE_OFF);
144}
145
146static int plt_clk_is_enabled(struct clk_hw *hw)
147{
148 struct clk_plt *clk = to_clk_plt(hw);
149 u32 value;
150
151 value = readl(clk->reg);
152
153 return plt_reg_to_enabled(value);
154}
155
156static const struct clk_ops plt_clk_ops = {
157 .enable = plt_clk_enable,
158 .disable = plt_clk_disable,
159 .is_enabled = plt_clk_is_enabled,
160 .get_parent = plt_clk_get_parent,
161 .set_parent = plt_clk_set_parent,
162 .determine_rate = __clk_mux_determine_rate,
163};
164
165static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id,
166 void __iomem *base,
167 const char **parent_names,
168 int num_parents)
169{
170 struct clk_plt *pclk;
171 struct clk_init_data init;
172 int ret;
173
174 pclk = devm_kzalloc(&pdev->dev, sizeof(*pclk), GFP_KERNEL);
175 if (!pclk)
176 return ERR_PTR(-ENOMEM);
177
178 init.name = kasprintf(GFP_KERNEL, "%s_%d", PLT_CLK_NAME_BASE, id);
179 init.ops = &plt_clk_ops;
180 init.flags = 0;
181 init.parent_names = parent_names;
182 init.num_parents = num_parents;
183
184 pclk->hw.init = &init;
185 pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
186 spin_lock_init(&pclk->lock);
187
188 ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
189 if (ret) {
190 pclk = ERR_PTR(ret);
191 goto err_free_init;
192 }
193
194 pclk->lookup = clkdev_hw_create(&pclk->hw, init.name, NULL);
195 if (!pclk->lookup) {
196 pclk = ERR_PTR(-ENOMEM);
197 goto err_free_init;
198 }
199
200err_free_init:
201 kfree(init.name);
202 return pclk;
203}
204
205static void plt_clk_unregister(struct clk_plt *pclk)
206{
207 clkdev_drop(pclk->lookup);
208}
209
210static struct clk_plt_fixed *plt_clk_register_fixed_rate(struct platform_device *pdev,
211 const char *name,
212 const char *parent_name,
213 unsigned long fixed_rate)
214{
215 struct clk_plt_fixed *pclk;
216
217 pclk = devm_kzalloc(&pdev->dev, sizeof(*pclk), GFP_KERNEL);
218 if (!pclk)
219 return ERR_PTR(-ENOMEM);
220
221 pclk->clk = clk_hw_register_fixed_rate(&pdev->dev, name, parent_name,
222 0, fixed_rate);
223 if (IS_ERR(pclk->clk))
224 return ERR_CAST(pclk->clk);
225
226 pclk->lookup = clkdev_hw_create(pclk->clk, name, NULL);
227 if (!pclk->lookup) {
228 clk_hw_unregister_fixed_rate(pclk->clk);
229 return ERR_PTR(-ENOMEM);
230 }
231
232 return pclk;
233}
234
235static void plt_clk_unregister_fixed_rate(struct clk_plt_fixed *pclk)
236{
237 clkdev_drop(pclk->lookup);
238 clk_hw_unregister_fixed_rate(pclk->clk);
239}
240
241static void plt_clk_unregister_fixed_rate_loop(struct clk_plt_data *data,
242 unsigned int i)
243{
244 while (i--)
245 plt_clk_unregister_fixed_rate(data->parents[i]);
246}
247
248static void plt_clk_free_parent_names_loop(const char **parent_names,
249 unsigned int i)
250{
251 while (i--)
252 kfree_const(parent_names[i]);
253 kfree(parent_names);
254}
255
256static void plt_clk_unregister_loop(struct clk_plt_data *data,
257 unsigned int i)
258{
259 while (i--)
260 plt_clk_unregister(data->clks[i]);
261}
262
263static const char **plt_clk_register_parents(struct platform_device *pdev,
264 struct clk_plt_data *data,
265 const struct pmc_clk *clks)
266{
267 const char **parent_names;
268 unsigned int i;
269 int err;
270 int nparents = 0;
271
272 data->nparents = 0;
273 while (clks[nparents].name)
274 nparents++;
275
276 data->parents = devm_kcalloc(&pdev->dev, nparents,
277 sizeof(*data->parents), GFP_KERNEL);
278 if (!data->parents)
279 return ERR_PTR(-ENOMEM);
280
281 parent_names = kcalloc(nparents, sizeof(*parent_names),
282 GFP_KERNEL);
283 if (!parent_names)
284 return ERR_PTR(-ENOMEM);
285
286 for (i = 0; i < nparents; i++) {
287 data->parents[i] =
288 plt_clk_register_fixed_rate(pdev, clks[i].name,
289 clks[i].parent_name,
290 clks[i].freq);
291 if (IS_ERR(data->parents[i])) {
292 err = PTR_ERR(data->parents[i]);
293 goto err_unreg;
294 }
295 parent_names[i] = kstrdup_const(clks[i].name, GFP_KERNEL);
296 }
297
298 data->nparents = nparents;
299 return parent_names;
300
301err_unreg:
302 plt_clk_unregister_fixed_rate_loop(data, i);
303 plt_clk_free_parent_names_loop(parent_names, i);
304 return ERR_PTR(err);
305}
306
307static void plt_clk_unregister_parents(struct clk_plt_data *data)
308{
309 plt_clk_unregister_fixed_rate_loop(data, data->nparents);
310}
311
312static int plt_clk_probe(struct platform_device *pdev)
313{
314 const struct pmc_clk_data *pmc_data;
315 const char **parent_names;
316 struct clk_plt_data *data;
317 unsigned int i;
318 int err;
319
320 pmc_data = dev_get_platdata(&pdev->dev);
321 if (!pmc_data || !pmc_data->clks)
322 return -EINVAL;
323
324 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
325 if (!data)
326 return -ENOMEM;
327
328 parent_names = plt_clk_register_parents(pdev, data, pmc_data->clks);
329 if (IS_ERR(parent_names))
330 return PTR_ERR(parent_names);
331
332 for (i = 0; i < PMC_CLK_NUM; i++) {
333 data->clks[i] = plt_clk_register(pdev, i, pmc_data->base,
334 parent_names, data->nparents);
335 if (IS_ERR(data->clks[i])) {
336 err = PTR_ERR(data->clks[i]);
337 goto err_unreg_clk_plt;
338 }
339 }
340
341 plt_clk_free_parent_names_loop(parent_names, data->nparents);
342
343 platform_set_drvdata(pdev, data);
344 return 0;
345
346err_unreg_clk_plt:
347 plt_clk_unregister_loop(data, i);
348 plt_clk_unregister_parents(data);
349 plt_clk_free_parent_names_loop(parent_names, data->nparents);
350 return err;
351}
352
353static int plt_clk_remove(struct platform_device *pdev)
354{
355 struct clk_plt_data *data;
356
357 data = platform_get_drvdata(pdev);
358
359 plt_clk_unregister_loop(data, PMC_CLK_NUM);
360 plt_clk_unregister_parents(data);
361 return 0;
362}
363
364static struct platform_driver plt_clk_driver = {
365 .driver = {
366 .name = "clk-pmc-atom",
367 },
368 .probe = plt_clk_probe,
369 .remove = plt_clk_remove,
370};
371builtin_platform_driver(plt_clk_driver);
diff --git a/drivers/clk/zte/clk-zx296718.c b/drivers/clk/zte/clk-zx296718.c
index 707d62956e9b..2f7c668643fe 100644
--- a/drivers/clk/zte/clk-zx296718.c
+++ b/drivers/clk/zte/clk-zx296718.c
@@ -610,9 +610,12 @@ static int __init top_clocks_init(struct device_node *np)
610 } 610 }
611 } 611 }
612 612
613 if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &top_hw_onecell_data)) 613 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
614 panic("could not register clk provider\n"); 614 &top_hw_onecell_data);
615 pr_info("top clk init over, nr:%d\n", TOP_NR_CLKS); 615 if (ret) {
616 pr_err("failed to register top clk provider: %d\n", ret);
617 return ret;
618 }
616 619
617 return 0; 620 return 0;
618} 621}
@@ -776,9 +779,12 @@ static int __init lsp0_clocks_init(struct device_node *np)
776 } 779 }
777 } 780 }
778 781
779 if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &lsp0_hw_onecell_data)) 782 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
780 panic("could not register clk provider\n"); 783 &lsp0_hw_onecell_data);
781 pr_info("lsp0-clk init over:%d\n", LSP0_NR_CLKS); 784 if (ret) {
785 pr_err("failed to register lsp0 clk provider: %d\n", ret);
786 return ret;
787 }
782 788
783 return 0; 789 return 0;
784} 790}
@@ -881,9 +887,142 @@ static int __init lsp1_clocks_init(struct device_node *np)
881 } 887 }
882 } 888 }
883 889
884 if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &lsp1_hw_onecell_data)) 890 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
885 panic("could not register clk provider\n"); 891 &lsp1_hw_onecell_data);
886 pr_info("lsp1-clk init over, nr:%d\n", LSP1_NR_CLKS); 892 if (ret) {
893 pr_err("failed to register lsp1 clk provider: %d\n", ret);
894 return ret;
895 }
896
897 return 0;
898}
899
900PNAME(audio_wclk_common_p) = {
901 "audio_99m",
902 "audio_24m",
903};
904
905PNAME(audio_timer_p) = {
906 "audio_24m",
907 "audio_32k",
908};
909
910static struct zx_clk_mux audio_mux_clk[] = {
911 MUX(0, "i2s0_wclk_mux", audio_wclk_common_p, AUDIO_I2S0_CLK, 0, 1),
912 MUX(0, "i2s1_wclk_mux", audio_wclk_common_p, AUDIO_I2S1_CLK, 0, 1),
913 MUX(0, "i2s2_wclk_mux", audio_wclk_common_p, AUDIO_I2S2_CLK, 0, 1),
914 MUX(0, "i2s3_wclk_mux", audio_wclk_common_p, AUDIO_I2S3_CLK, 0, 1),
915 MUX(0, "i2c0_wclk_mux", audio_wclk_common_p, AUDIO_I2C0_CLK, 0, 1),
916 MUX(0, "spdif0_wclk_mux", audio_wclk_common_p, AUDIO_SPDIF0_CLK, 0, 1),
917 MUX(0, "spdif1_wclk_mux", audio_wclk_common_p, AUDIO_SPDIF1_CLK, 0, 1),
918 MUX(0, "timer_wclk_mux", audio_timer_p, AUDIO_TIMER_CLK, 0, 1),
919};
920
921static struct clk_zx_audio_divider audio_adiv_clk[] = {
922 AUDIO_DIV(0, "i2s0_wclk_div", "i2s0_wclk_mux", AUDIO_I2S0_DIV_CFG1),
923 AUDIO_DIV(0, "i2s1_wclk_div", "i2s1_wclk_mux", AUDIO_I2S1_DIV_CFG1),
924 AUDIO_DIV(0, "i2s2_wclk_div", "i2s2_wclk_mux", AUDIO_I2S2_DIV_CFG1),
925 AUDIO_DIV(0, "i2s3_wclk_div", "i2s3_wclk_mux", AUDIO_I2S3_DIV_CFG1),
926 AUDIO_DIV(0, "spdif0_wclk_div", "spdif0_wclk_mux", AUDIO_SPDIF0_DIV_CFG1),
927 AUDIO_DIV(0, "spdif1_wclk_div", "spdif1_wclk_mux", AUDIO_SPDIF1_DIV_CFG1),
928};
929
930static struct zx_clk_div audio_div_clk[] = {
931 DIV_T(0, "tdm_wclk_div", "audio_16m384", AUDIO_TDM_CLK, 8, 4, 0, common_div_table),
932};
933
934static struct zx_clk_gate audio_gate_clk[] = {
935 GATE(AUDIO_I2S0_WCLK, "i2s0_wclk", "i2s0_wclk_div", AUDIO_I2S0_CLK, 9, CLK_SET_RATE_PARENT, 0),
936 GATE(AUDIO_I2S1_WCLK, "i2s1_wclk", "i2s1_wclk_div", AUDIO_I2S1_CLK, 9, CLK_SET_RATE_PARENT, 0),
937 GATE(AUDIO_I2S2_WCLK, "i2s2_wclk", "i2s2_wclk_div", AUDIO_I2S2_CLK, 9, CLK_SET_RATE_PARENT, 0),
938 GATE(AUDIO_I2S3_WCLK, "i2s3_wclk", "i2s3_wclk_div", AUDIO_I2S3_CLK, 9, CLK_SET_RATE_PARENT, 0),
939 GATE(AUDIO_I2S0_PCLK, "i2s0_pclk", "clk49m5", AUDIO_I2S0_CLK, 8, 0, 0),
940 GATE(AUDIO_I2S1_PCLK, "i2s1_pclk", "clk49m5", AUDIO_I2S1_CLK, 8, 0, 0),
941 GATE(AUDIO_I2S2_PCLK, "i2s2_pclk", "clk49m5", AUDIO_I2S2_CLK, 8, 0, 0),
942 GATE(AUDIO_I2S3_PCLK, "i2s3_pclk", "clk49m5", AUDIO_I2S3_CLK, 8, 0, 0),
943 GATE(AUDIO_I2C0_WCLK, "i2c0_wclk", "i2c0_wclk_mux", AUDIO_I2C0_CLK, 9, CLK_SET_RATE_PARENT, 0),
944 GATE(AUDIO_SPDIF0_WCLK, "spdif0_wclk", "spdif0_wclk_div", AUDIO_SPDIF0_CLK, 9, CLK_SET_RATE_PARENT, 0),
945 GATE(AUDIO_SPDIF1_WCLK, "spdif1_wclk", "spdif1_wclk_div", AUDIO_SPDIF1_CLK, 9, CLK_SET_RATE_PARENT, 0),
946 GATE(AUDIO_TDM_WCLK, "tdm_wclk", "tdm_wclk_div", AUDIO_TDM_CLK, 17, CLK_SET_RATE_PARENT, 0),
947 GATE(AUDIO_TS_PCLK, "tempsensor_pclk", "clk49m5", AUDIO_TS_CLK, 1, 0, 0),
948};
949
950static struct clk_hw_onecell_data audio_hw_onecell_data = {
951 .num = AUDIO_NR_CLKS,
952 .hws = {
953 [AUDIO_NR_CLKS - 1] = NULL,
954 },
955};
956
957static int __init audio_clocks_init(struct device_node *np)
958{
959 void __iomem *reg_base;
960 int i, ret;
961
962 reg_base = of_iomap(np, 0);
963 if (!reg_base) {
964 pr_err("%s: Unable to map audio clk base\n", __func__);
965 return -ENXIO;
966 }
967
968 for (i = 0; i < ARRAY_SIZE(audio_mux_clk); i++) {
969 if (audio_mux_clk[i].id)
970 audio_hw_onecell_data.hws[audio_mux_clk[i].id] =
971 &audio_mux_clk[i].mux.hw;
972
973 audio_mux_clk[i].mux.reg += (uintptr_t)reg_base;
974 ret = clk_hw_register(NULL, &audio_mux_clk[i].mux.hw);
975 if (ret) {
976 pr_warn("audio clk %s init error!\n",
977 audio_mux_clk[i].mux.hw.init->name);
978 }
979 }
980
981 for (i = 0; i < ARRAY_SIZE(audio_adiv_clk); i++) {
982 if (audio_adiv_clk[i].id)
983 audio_hw_onecell_data.hws[audio_adiv_clk[i].id] =
984 &audio_adiv_clk[i].hw;
985
986 audio_adiv_clk[i].reg_base += (uintptr_t)reg_base;
987 ret = clk_hw_register(NULL, &audio_adiv_clk[i].hw);
988 if (ret) {
989 pr_warn("audio clk %s init error!\n",
990 audio_adiv_clk[i].hw.init->name);
991 }
992 }
993
994 for (i = 0; i < ARRAY_SIZE(audio_div_clk); i++) {
995 if (audio_div_clk[i].id)
996 audio_hw_onecell_data.hws[audio_div_clk[i].id] =
997 &audio_div_clk[i].div.hw;
998
999 audio_div_clk[i].div.reg += (uintptr_t)reg_base;
1000 ret = clk_hw_register(NULL, &audio_div_clk[i].div.hw);
1001 if (ret) {
1002 pr_warn("audio clk %s init error!\n",
1003 audio_div_clk[i].div.hw.init->name);
1004 }
1005 }
1006
1007 for (i = 0; i < ARRAY_SIZE(audio_gate_clk); i++) {
1008 if (audio_gate_clk[i].id)
1009 audio_hw_onecell_data.hws[audio_gate_clk[i].id] =
1010 &audio_gate_clk[i].gate.hw;
1011
1012 audio_gate_clk[i].gate.reg += (uintptr_t)reg_base;
1013 ret = clk_hw_register(NULL, &audio_gate_clk[i].gate.hw);
1014 if (ret) {
1015 pr_warn("audio clk %s init error!\n",
1016 audio_gate_clk[i].gate.hw.init->name);
1017 }
1018 }
1019
1020 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
1021 &audio_hw_onecell_data);
1022 if (ret) {
1023 pr_err("failed to register audio clk provider: %d\n", ret);
1024 return ret;
1025 }
887 1026
888 return 0; 1027 return 0;
889} 1028}
@@ -892,6 +1031,7 @@ static const struct of_device_id zx_clkc_match_table[] = {
892 { .compatible = "zte,zx296718-topcrm", .data = &top_clocks_init }, 1031 { .compatible = "zte,zx296718-topcrm", .data = &top_clocks_init },
893 { .compatible = "zte,zx296718-lsp0crm", .data = &lsp0_clocks_init }, 1032 { .compatible = "zte,zx296718-lsp0crm", .data = &lsp0_clocks_init },
894 { .compatible = "zte,zx296718-lsp1crm", .data = &lsp1_clocks_init }, 1033 { .compatible = "zte,zx296718-lsp1crm", .data = &lsp1_clocks_init },
1034 { .compatible = "zte,zx296718-audiocrm", .data = &audio_clocks_init },
895 { } 1035 { }
896}; 1036};
897 1037
diff --git a/drivers/clk/zte/clk.c b/drivers/clk/zte/clk.c
index c4c1251bc1e7..878d879b23ff 100644
--- a/drivers/clk/zte/clk.c
+++ b/drivers/clk/zte/clk.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/clk-provider.h> 10#include <linux/clk-provider.h>
11#include <linux/err.h> 11#include <linux/err.h>
12#include <linux/gcd.h>
12#include <linux/io.h> 13#include <linux/io.h>
13#include <linux/iopoll.h> 14#include <linux/iopoll.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
@@ -310,3 +311,129 @@ struct clk *clk_register_zx_audio(const char *name,
310 311
311 return clk; 312 return clk;
312} 313}
314
315#define CLK_AUDIO_DIV_FRAC BIT(0)
316#define CLK_AUDIO_DIV_INT BIT(1)
317#define CLK_AUDIO_DIV_UNCOMMON BIT(1)
318
319#define CLK_AUDIO_DIV_FRAC_NSHIFT 16
320#define CLK_AUDIO_DIV_INT_FRAC_RE BIT(16)
321#define CLK_AUDIO_DIV_INT_FRAC_MAX (0xffff)
322#define CLK_AUDIO_DIV_INT_FRAC_MIN (0x2)
323#define CLK_AUDIO_DIV_INT_INT_SHIFT 24
324#define CLK_AUDIO_DIV_INT_INT_WIDTH 4
325
326struct zx_clk_audio_div_table {
327 unsigned long rate;
328 unsigned int int_reg;
329 unsigned int frac_reg;
330};
331
332#define to_clk_zx_audio_div(_hw) container_of(_hw, struct clk_zx_audio_divider, hw)
333
334static unsigned long audio_calc_rate(struct clk_zx_audio_divider *audio_div,
335 u32 reg_frac, u32 reg_int,
336 unsigned long parent_rate)
337{
338 unsigned long rate, m, n;
339
340 m = reg_frac & 0xffff;
341 n = (reg_frac >> 16) & 0xffff;
342
343 m = (reg_int & 0xffff) * n + m;
344 rate = (parent_rate * n) / m;
345
346 return rate;
347}
348
349static void audio_calc_reg(struct clk_zx_audio_divider *audio_div,
350 struct zx_clk_audio_div_table *div_table,
351 unsigned long rate, unsigned long parent_rate)
352{
353 unsigned int reg_int, reg_frac;
354 unsigned long m, n, div;
355
356 reg_int = parent_rate / rate;
357
358 if (reg_int > CLK_AUDIO_DIV_INT_FRAC_MAX)
359 reg_int = CLK_AUDIO_DIV_INT_FRAC_MAX;
360 else if (reg_int < CLK_AUDIO_DIV_INT_FRAC_MIN)
361 reg_int = 0;
362 m = parent_rate - rate * reg_int;
363 n = rate;
364
365 div = gcd(m, n);
366 m = m / div;
367 n = n / div;
368
369 if ((m >> 16) || (n >> 16)) {
370 if (m > n) {
371 n = n * 0xffff / m;
372 m = 0xffff;
373 } else {
374 m = m * 0xffff / n;
375 n = 0xffff;
376 }
377 }
378 reg_frac = m | (n << 16);
379
380 div_table->rate = parent_rate * n / (reg_int * n + m);
381 div_table->int_reg = reg_int;
382 div_table->frac_reg = reg_frac;
383}
384
385static unsigned long zx_audio_div_recalc_rate(struct clk_hw *hw,
386 unsigned long parent_rate)
387{
388 struct clk_zx_audio_divider *zx_audio_div = to_clk_zx_audio_div(hw);
389 u32 reg_frac, reg_int;
390
391 reg_frac = readl_relaxed(zx_audio_div->reg_base);
392 reg_int = readl_relaxed(zx_audio_div->reg_base + 0x4);
393
394 return audio_calc_rate(zx_audio_div, reg_frac, reg_int, parent_rate);
395}
396
397static long zx_audio_div_round_rate(struct clk_hw *hw, unsigned long rate,
398 unsigned long *prate)
399{
400 struct clk_zx_audio_divider *zx_audio_div = to_clk_zx_audio_div(hw);
401 struct zx_clk_audio_div_table divt;
402
403 audio_calc_reg(zx_audio_div, &divt, rate, *prate);
404
405 return audio_calc_rate(zx_audio_div, divt.frac_reg, divt.int_reg, *prate);
406}
407
408static int zx_audio_div_set_rate(struct clk_hw *hw, unsigned long rate,
409 unsigned long parent_rate)
410{
411 struct clk_zx_audio_divider *zx_audio_div = to_clk_zx_audio_div(hw);
412 struct zx_clk_audio_div_table divt;
413 unsigned int val;
414
415 audio_calc_reg(zx_audio_div, &divt, rate, parent_rate);
416 if (divt.rate != rate)
417 pr_debug("the real rate is:%ld", divt.rate);
418
419 writel_relaxed(divt.frac_reg, zx_audio_div->reg_base);
420
421 val = readl_relaxed(zx_audio_div->reg_base + 0x4);
422 val &= ~0xffff;
423 val |= divt.int_reg | CLK_AUDIO_DIV_INT_FRAC_RE;
424 writel_relaxed(val, zx_audio_div->reg_base + 0x4);
425
426 mdelay(1);
427
428 val = readl_relaxed(zx_audio_div->reg_base + 0x4);
429 val &= ~CLK_AUDIO_DIV_INT_FRAC_RE;
430 writel_relaxed(val, zx_audio_div->reg_base + 0x4);
431
432 return 0;
433}
434
435const struct clk_ops zx_audio_div_ops = {
436 .recalc_rate = zx_audio_div_recalc_rate,
437 .round_rate = zx_audio_div_round_rate,
438 .set_rate = zx_audio_div_set_rate,
439};
diff --git a/drivers/clk/zte/clk.h b/drivers/clk/zte/clk.h
index 0df3474b2cf3..84a55a3e2bd4 100644
--- a/drivers/clk/zte/clk.h
+++ b/drivers/clk/zte/clk.h
@@ -153,6 +153,25 @@ struct zx_clk_div {
153 .id = _id, \ 153 .id = _id, \
154} 154}
155 155
156struct clk_zx_audio_divider {
157 struct clk_hw hw;
158 void __iomem *reg_base;
159 unsigned int rate_count;
160 spinlock_t *lock;
161 u16 id;
162};
163
164#define AUDIO_DIV(_id, _name, _parent, _reg) \
165{ \
166 .reg_base = (void __iomem *) _reg, \
167 .lock = &clk_lock, \
168 .hw.init = CLK_HW_INIT(_name, \
169 _parent, \
170 &zx_audio_div_ops, \
171 0), \
172 .id = _id, \
173}
174
156struct clk *clk_register_zx_pll(const char *name, const char *parent_name, 175struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
157 unsigned long flags, void __iomem *reg_base, 176 unsigned long flags, void __iomem *reg_base,
158 const struct zx_pll_config *lookup_table, int count, spinlock_t *lock); 177 const struct zx_pll_config *lookup_table, int count, spinlock_t *lock);
@@ -167,4 +186,6 @@ struct clk *clk_register_zx_audio(const char *name,
167 unsigned long flags, void __iomem *reg_base); 186 unsigned long flags, void __iomem *reg_base);
168 187
169extern const struct clk_ops zx_pll_ops; 188extern const struct clk_ops zx_pll_ops;
189extern const struct clk_ops zx_audio_div_ops;
190
170#endif 191#endif
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 49a594855f98..a9e9c91cf4d4 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1070,3 +1070,8 @@ config MLX_CPLD_PLATFORM
1070 cables and fans on the wide range Mellanox IB and Ethernet systems. 1070 cables and fans on the wide range Mellanox IB and Ethernet systems.
1071 1071
1072endif # X86_PLATFORM_DEVICES 1072endif # X86_PLATFORM_DEVICES
1073
1074config PMC_ATOM
1075 def_bool y
1076 depends on PCI
1077 select COMMON_CLK
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index b2f52a7690af..cf9fc3e930c7 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -73,5 +73,6 @@ obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \
73 intel_telemetry_pltdrv.o \ 73 intel_telemetry_pltdrv.o \
74 intel_telemetry_debugfs.o 74 intel_telemetry_debugfs.o
75obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o 75obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o
76obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
76obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o 77obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
77obj-$(CONFIG_MLX_CPLD_PLATFORM) += mlxcpld-hotplug.o 78obj-$(CONFIG_MLX_CPLD_PLATFORM) += mlxcpld-hotplug.o
diff --git a/arch/x86/platform/atom/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
index 964ff4fc61f9..77bac859342d 100644
--- a/arch/x86/platform/atom/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -15,14 +15,15 @@
15 15
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 17
18#include <linux/debugfs.h>
19#include <linux/device.h>
18#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/io.h>
22#include <linux/platform_data/x86/clk-pmc-atom.h>
23#include <linux/platform_data/x86/pmc_atom.h>
24#include <linux/platform_device.h>
19#include <linux/pci.h> 25#include <linux/pci.h>
20#include <linux/device.h>
21#include <linux/debugfs.h>
22#include <linux/seq_file.h> 26#include <linux/seq_file.h>
23#include <linux/io.h>
24
25#include <asm/pmc_atom.h>
26 27
27struct pmc_bit_map { 28struct pmc_bit_map {
28 const char *name; 29 const char *name;
@@ -37,6 +38,11 @@ struct pmc_reg_map {
37 const struct pmc_bit_map *pss; 38 const struct pmc_bit_map *pss;
38}; 39};
39 40
41struct pmc_data {
42 const struct pmc_reg_map *map;
43 const struct pmc_clk *clks;
44};
45
40struct pmc_dev { 46struct pmc_dev {
41 u32 base_addr; 47 u32 base_addr;
42 void __iomem *regmap; 48 void __iomem *regmap;
@@ -50,6 +56,29 @@ struct pmc_dev {
50static struct pmc_dev pmc_device; 56static struct pmc_dev pmc_device;
51static u32 acpi_base_addr; 57static u32 acpi_base_addr;
52 58
59static const struct pmc_clk byt_clks[] = {
60 {
61 .name = "xtal",
62 .freq = 25000000,
63 .parent_name = NULL,
64 },
65 {
66 .name = "pll",
67 .freq = 19200000,
68 .parent_name = "xtal",
69 },
70 {},
71};
72
73static const struct pmc_clk cht_clks[] = {
74 {
75 .name = "xtal",
76 .freq = 19200000,
77 .parent_name = NULL,
78 },
79 {},
80};
81
53static const struct pmc_bit_map d3_sts_0_map[] = { 82static const struct pmc_bit_map d3_sts_0_map[] = {
54 {"LPSS1_F0_DMA", BIT_LPSS1_F0_DMA}, 83 {"LPSS1_F0_DMA", BIT_LPSS1_F0_DMA},
55 {"LPSS1_F1_PWM1", BIT_LPSS1_F1_PWM1}, 84 {"LPSS1_F1_PWM1", BIT_LPSS1_F1_PWM1},
@@ -169,6 +198,16 @@ static const struct pmc_reg_map cht_reg_map = {
169 .pss = cht_pss_map, 198 .pss = cht_pss_map,
170}; 199};
171 200
201static const struct pmc_data byt_data = {
202 .map = &byt_reg_map,
203 .clks = byt_clks,
204};
205
206static const struct pmc_data cht_data = {
207 .map = &cht_reg_map,
208 .clks = cht_clks,
209};
210
172static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset) 211static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset)
173{ 212{
174 return readl(pmc->regmap + reg_offset); 213 return readl(pmc->regmap + reg_offset);
@@ -382,10 +421,37 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc)
382} 421}
383#endif /* CONFIG_DEBUG_FS */ 422#endif /* CONFIG_DEBUG_FS */
384 423
424static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap,
425 const struct pmc_data *pmc_data)
426{
427 struct platform_device *clkdev;
428 struct pmc_clk_data *clk_data;
429
430 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
431 if (!clk_data)
432 return -ENOMEM;
433
434 clk_data->base = pmc_regmap; /* offset is added by client */
435 clk_data->clks = pmc_data->clks;
436
437 clkdev = platform_device_register_data(&pdev->dev, "clk-pmc-atom",
438 PLATFORM_DEVID_NONE,
439 clk_data, sizeof(*clk_data));
440 if (IS_ERR(clkdev)) {
441 kfree(clk_data);
442 return PTR_ERR(clkdev);
443 }
444
445 kfree(clk_data);
446
447 return 0;
448}
449
385static int pmc_setup_dev(struct pci_dev *pdev, const struct pci_device_id *ent) 450static int pmc_setup_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
386{ 451{
387 struct pmc_dev *pmc = &pmc_device; 452 struct pmc_dev *pmc = &pmc_device;
388 const struct pmc_reg_map *map = (struct pmc_reg_map *)ent->driver_data; 453 const struct pmc_data *data = (struct pmc_data *)ent->driver_data;
454 const struct pmc_reg_map *map = data->map;
389 int ret; 455 int ret;
390 456
391 /* Obtain ACPI base address */ 457 /* Obtain ACPI base address */
@@ -414,6 +480,12 @@ static int pmc_setup_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
414 if (ret) 480 if (ret)
415 dev_warn(&pdev->dev, "debugfs register failed\n"); 481 dev_warn(&pdev->dev, "debugfs register failed\n");
416 482
483 /* Register platform clocks - PMC_PLT_CLK [0..5] */
484 ret = pmc_setup_clks(pdev, pmc->regmap, data);
485 if (ret)
486 dev_warn(&pdev->dev, "platform clocks register failed: %d\n",
487 ret);
488
417 pmc->init = true; 489 pmc->init = true;
418 return ret; 490 return ret;
419} 491}
@@ -424,8 +496,8 @@ static int pmc_setup_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
424 * used by pci_match_id() call below. 496 * used by pci_match_id() call below.
425 */ 497 */
426static const struct pci_device_id pmc_pci_ids[] = { 498static const struct pci_device_id pmc_pci_ids[] = {
427 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_VLV_PMC), (kernel_ulong_t)&byt_reg_map }, 499 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_VLV_PMC), (kernel_ulong_t)&byt_data },
428 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_CHT_PMC), (kernel_ulong_t)&cht_reg_map }, 500 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_CHT_PMC), (kernel_ulong_t)&cht_data },
429 { 0, }, 501 { 0, },
430}; 502};
431 503
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
index 360e00cefd35..a0c812b0fa39 100644
--- a/include/dt-bindings/clock/bcm2835.h
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -64,3 +64,5 @@
64#define BCM2835_CLOCK_CAM1 46 64#define BCM2835_CLOCK_CAM1 46
65#define BCM2835_CLOCK_DSI0E 47 65#define BCM2835_CLOCK_DSI0E 47
66#define BCM2835_CLOCK_DSI1E 48 66#define BCM2835_CLOCK_DSI1E 48
67#define BCM2835_CLOCK_DSI0P 49
68#define BCM2835_CLOCK_DSI1P 50
diff --git a/include/dt-bindings/clock/exynos4415.h b/include/dt-bindings/clock/exynos4415.h
deleted file mode 100644
index 7eed55100721..000000000000
--- a/include/dt-bindings/clock/exynos4415.h
+++ /dev/null
@@ -1,360 +0,0 @@
1/*
2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 * Author: Chanwoo Choi <cw00.choi@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Device Tree binding constants for Samsung Exynos4415 clock controllers.
10 */
11
12#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H
13#define _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H
14
15/*
16 * Let each exported clock get a unique index, which is used on DT-enabled
17 * platforms to lookup the clock from a clock specifier. These indices are
18 * therefore considered an ABI and so must not be changed. This implies
19 * that new clocks should be added either in free spaces between clock groups
20 * or at the end.
21 */
22
23/*
24 * Main CMU
25 */
26
27#define CLK_OSCSEL 1
28#define CLK_FIN_PLL 2
29#define CLK_FOUT_APLL 3
30#define CLK_FOUT_MPLL 4
31#define CLK_FOUT_EPLL 5
32#define CLK_FOUT_G3D_PLL 6
33#define CLK_FOUT_ISP_PLL 7
34#define CLK_FOUT_DISP_PLL 8
35
36/* Muxes */
37#define CLK_MOUT_MPLL_USER_L 16
38#define CLK_MOUT_GDL 17
39#define CLK_MOUT_MPLL_USER_R 18
40#define CLK_MOUT_GDR 19
41#define CLK_MOUT_EBI 20
42#define CLK_MOUT_ACLK_200 21
43#define CLK_MOUT_ACLK_160 22
44#define CLK_MOUT_ACLK_100 23
45#define CLK_MOUT_ACLK_266 24
46#define CLK_MOUT_G3D_PLL 25
47#define CLK_MOUT_EPLL 26
48#define CLK_MOUT_EBI_1 27
49#define CLK_MOUT_ISP_PLL 28
50#define CLK_MOUT_DISP_PLL 29
51#define CLK_MOUT_MPLL_USER_T 30
52#define CLK_MOUT_ACLK_400_MCUISP 31
53#define CLK_MOUT_G3D_PLLSRC 32
54#define CLK_MOUT_CSIS1 33
55#define CLK_MOUT_CSIS0 34
56#define CLK_MOUT_CAM1 35
57#define CLK_MOUT_FIMC3_LCLK 36
58#define CLK_MOUT_FIMC2_LCLK 37
59#define CLK_MOUT_FIMC1_LCLK 38
60#define CLK_MOUT_FIMC0_LCLK 39
61#define CLK_MOUT_MFC 40
62#define CLK_MOUT_MFC_1 41
63#define CLK_MOUT_MFC_0 42
64#define CLK_MOUT_G3D 43
65#define CLK_MOUT_G3D_1 44
66#define CLK_MOUT_G3D_0 45
67#define CLK_MOUT_MIPI0 46
68#define CLK_MOUT_FIMD0 47
69#define CLK_MOUT_TSADC_ISP 48
70#define CLK_MOUT_UART_ISP 49
71#define CLK_MOUT_SPI1_ISP 50
72#define CLK_MOUT_SPI0_ISP 51
73#define CLK_MOUT_PWM_ISP 52
74#define CLK_MOUT_AUDIO0 53
75#define CLK_MOUT_TSADC 54
76#define CLK_MOUT_MMC2 55
77#define CLK_MOUT_MMC1 56
78#define CLK_MOUT_MMC0 57
79#define CLK_MOUT_UART3 58
80#define CLK_MOUT_UART2 59
81#define CLK_MOUT_UART1 60
82#define CLK_MOUT_UART0 61
83#define CLK_MOUT_SPI2 62
84#define CLK_MOUT_SPI1 63
85#define CLK_MOUT_SPI0 64
86#define CLK_MOUT_SPDIF 65
87#define CLK_MOUT_AUDIO2 66
88#define CLK_MOUT_AUDIO1 67
89#define CLK_MOUT_MPLL_USER_C 68
90#define CLK_MOUT_HPM 69
91#define CLK_MOUT_CORE 70
92#define CLK_MOUT_APLL 71
93#define CLK_MOUT_PXLASYNC_CSIS1_FIMC 72
94#define CLK_MOUT_PXLASYNC_CSIS0_FIMC 73
95#define CLK_MOUT_JPEG 74
96#define CLK_MOUT_JPEG1 75
97#define CLK_MOUT_JPEG0 76
98#define CLK_MOUT_ACLK_ISP0_300 77
99#define CLK_MOUT_ACLK_ISP0_400 78
100#define CLK_MOUT_ACLK_ISP0_300_USER 79
101#define CLK_MOUT_ACLK_ISP1_300 80
102#define CLK_MOUT_ACLK_ISP1_300_USER 81
103#define CLK_MOUT_HDMI 82
104
105/* Dividers */
106#define CLK_DIV_GPL 90
107#define CLK_DIV_GDL 91
108#define CLK_DIV_GPR 92
109#define CLK_DIV_GDR 93
110#define CLK_DIV_ACLK_400_MCUISP 94
111#define CLK_DIV_EBI 95
112#define CLK_DIV_ACLK_200 96
113#define CLK_DIV_ACLK_160 97
114#define CLK_DIV_ACLK_100 98
115#define CLK_DIV_ACLK_266 99
116#define CLK_DIV_CSIS1 100
117#define CLK_DIV_CSIS0 101
118#define CLK_DIV_CAM1 102
119#define CLK_DIV_FIMC3_LCLK 103
120#define CLK_DIV_FIMC2_LCLK 104
121#define CLK_DIV_FIMC1_LCLK 105
122#define CLK_DIV_FIMC0_LCLK 106
123#define CLK_DIV_TV_BLK 107
124#define CLK_DIV_MFC 108
125#define CLK_DIV_G3D 109
126#define CLK_DIV_MIPI0_PRE 110
127#define CLK_DIV_MIPI0 111
128#define CLK_DIV_FIMD0 112
129#define CLK_DIV_UART_ISP 113
130#define CLK_DIV_SPI1_ISP_PRE 114
131#define CLK_DIV_SPI1_ISP 115
132#define CLK_DIV_SPI0_ISP_PRE 116
133#define CLK_DIV_SPI0_ISP 117
134#define CLK_DIV_PWM_ISP 118
135#define CLK_DIV_PCM0 119
136#define CLK_DIV_AUDIO0 120
137#define CLK_DIV_TSADC_PRE 121
138#define CLK_DIV_TSADC 122
139#define CLK_DIV_MMC1_PRE 123
140#define CLK_DIV_MMC1 124
141#define CLK_DIV_MMC0_PRE 125
142#define CLK_DIV_MMC0 126
143#define CLK_DIV_MMC2_PRE 127
144#define CLK_DIV_MMC2 128
145#define CLK_DIV_UART3 129
146#define CLK_DIV_UART2 130
147#define CLK_DIV_UART1 131
148#define CLK_DIV_UART0 132
149#define CLK_DIV_SPI1_PRE 133
150#define CLK_DIV_SPI1 134
151#define CLK_DIV_SPI0_PRE 135
152#define CLK_DIV_SPI0 136
153#define CLK_DIV_SPI2_PRE 137
154#define CLK_DIV_SPI2 138
155#define CLK_DIV_PCM2 139
156#define CLK_DIV_AUDIO2 140
157#define CLK_DIV_PCM1 141
158#define CLK_DIV_AUDIO1 142
159#define CLK_DIV_I2S1 143
160#define CLK_DIV_PXLASYNC_CSIS1_FIMC 144
161#define CLK_DIV_PXLASYNC_CSIS0_FIMC 145
162#define CLK_DIV_JPEG 146
163#define CLK_DIV_CORE2 147
164#define CLK_DIV_APLL 148
165#define CLK_DIV_PCLK_DBG 149
166#define CLK_DIV_ATB 150
167#define CLK_DIV_PERIPH 151
168#define CLK_DIV_COREM1 152
169#define CLK_DIV_COREM0 153
170#define CLK_DIV_CORE 154
171#define CLK_DIV_HPM 155
172#define CLK_DIV_COPY 156
173
174/* Gates */
175#define CLK_ASYNC_G3D 180
176#define CLK_ASYNC_MFCL 181
177#define CLK_ASYNC_TVX 182
178#define CLK_PPMULEFT 183
179#define CLK_GPIO_LEFT 184
180#define CLK_PPMUIMAGE 185
181#define CLK_QEMDMA2 186
182#define CLK_QEROTATOR 187
183#define CLK_SMMUMDMA2 188
184#define CLK_SMMUROTATOR 189
185#define CLK_MDMA2 190
186#define CLK_ROTATOR 191
187#define CLK_ASYNC_ISPMX 192
188#define CLK_ASYNC_MAUDIOX 193
189#define CLK_ASYNC_MFCR 194
190#define CLK_ASYNC_FSYSD 195
191#define CLK_ASYNC_LCD0X 196
192#define CLK_ASYNC_CAMX 197
193#define CLK_PPMURIGHT 198
194#define CLK_GPIO_RIGHT 199
195#define CLK_ANTIRBK_APBIF 200
196#define CLK_EFUSE_WRITER_APBIF 201
197#define CLK_MONOCNT 202
198#define CLK_TZPC6 203
199#define CLK_PROVISIONKEY1 204
200#define CLK_PROVISIONKEY0 205
201#define CLK_CMU_ISPPART 206
202#define CLK_TMU_APBIF 207
203#define CLK_KEYIF 208
204#define CLK_RTC 209
205#define CLK_WDT 210
206#define CLK_MCT 211
207#define CLK_SECKEY 212
208#define CLK_HDMI_CEC 213
209#define CLK_TZPC5 214
210#define CLK_TZPC4 215
211#define CLK_TZPC3 216
212#define CLK_TZPC2 217
213#define CLK_TZPC1 218
214#define CLK_TZPC0 219
215#define CLK_CMU_COREPART 220
216#define CLK_CMU_TOPPART 221
217#define CLK_PMU_APBIF 222
218#define CLK_SYSREG 223
219#define CLK_CHIP_ID 224
220#define CLK_SMMUFIMC_LITE2 225
221#define CLK_FIMC_LITE2 226
222#define CLK_PIXELASYNCM1 227
223#define CLK_PIXELASYNCM0 228
224#define CLK_PPMUCAMIF 229
225#define CLK_SMMUJPEG 230
226#define CLK_SMMUFIMC3 231
227#define CLK_SMMUFIMC2 232
228#define CLK_SMMUFIMC1 233
229#define CLK_SMMUFIMC0 234
230#define CLK_JPEG 235
231#define CLK_CSIS1 236
232#define CLK_CSIS0 237
233#define CLK_FIMC3 238
234#define CLK_FIMC2 239
235#define CLK_FIMC1 240
236#define CLK_FIMC0 241
237#define CLK_PPMUTV 242
238#define CLK_SMMUTV 243
239#define CLK_HDMI 244
240#define CLK_MIXER 245
241#define CLK_VP 246
242#define CLK_PPMUMFC_R 247
243#define CLK_PPMUMFC_L 248
244#define CLK_SMMUMFC_R 249
245#define CLK_SMMUMFC_L 250
246#define CLK_MFC 251
247#define CLK_PPMUG3D 252
248#define CLK_G3D 253
249#define CLK_PPMULCD0 254
250#define CLK_SMMUFIMD0 255
251#define CLK_DSIM0 256
252#define CLK_SMIES 257
253#define CLK_MIE0 258
254#define CLK_FIMD0 259
255#define CLK_TSADC 260
256#define CLK_PPMUFILE 261
257#define CLK_NFCON 262
258#define CLK_USBDEVICE 263
259#define CLK_USBHOST 264
260#define CLK_SROMC 265
261#define CLK_SDMMC2 266
262#define CLK_SDMMC1 267
263#define CLK_SDMMC0 268
264#define CLK_PDMA1 269
265#define CLK_PDMA0 270
266#define CLK_SPDIF 271
267#define CLK_PWM 272
268#define CLK_PCM2 273
269#define CLK_PCM1 274
270#define CLK_I2S1 275
271#define CLK_SPI2 276
272#define CLK_SPI1 277
273#define CLK_SPI0 278
274#define CLK_I2CHDMI 279
275#define CLK_I2C7 280
276#define CLK_I2C6 281
277#define CLK_I2C5 282
278#define CLK_I2C4 283
279#define CLK_I2C3 284
280#define CLK_I2C2 285
281#define CLK_I2C1 286
282#define CLK_I2C0 287
283#define CLK_UART3 288
284#define CLK_UART2 289
285#define CLK_UART1 290
286#define CLK_UART0 291
287
288/* Special clocks */
289#define CLK_SCLK_PXLAYSNC_CSIS1_FIMC 330
290#define CLK_SCLK_PXLAYSNC_CSIS0_FIMC 331
291#define CLK_SCLK_JPEG 332
292#define CLK_SCLK_CSIS1 333
293#define CLK_SCLK_CSIS0 334
294#define CLK_SCLK_CAM1 335
295#define CLK_SCLK_FIMC3_LCLK 336
296#define CLK_SCLK_FIMC2_LCLK 337
297#define CLK_SCLK_FIMC1_LCLK 338
298#define CLK_SCLK_FIMC0_LCLK 339
299#define CLK_SCLK_PIXEL 340
300#define CLK_SCLK_HDMI 341
301#define CLK_SCLK_MIXER 342
302#define CLK_SCLK_MFC 343
303#define CLK_SCLK_G3D 344
304#define CLK_SCLK_MIPIDPHY4L 345
305#define CLK_SCLK_MIPI0 346
306#define CLK_SCLK_MDNIE0 347
307#define CLK_SCLK_FIMD0 348
308#define CLK_SCLK_PCM0 349
309#define CLK_SCLK_AUDIO0 350
310#define CLK_SCLK_TSADC 351
311#define CLK_SCLK_EBI 352
312#define CLK_SCLK_MMC2 353
313#define CLK_SCLK_MMC1 354
314#define CLK_SCLK_MMC0 355
315#define CLK_SCLK_I2S 356
316#define CLK_SCLK_PCM2 357
317#define CLK_SCLK_PCM1 358
318#define CLK_SCLK_AUDIO2 359
319#define CLK_SCLK_AUDIO1 360
320#define CLK_SCLK_SPDIF 361
321#define CLK_SCLK_SPI2 362
322#define CLK_SCLK_SPI1 363
323#define CLK_SCLK_SPI0 364
324#define CLK_SCLK_UART3 365
325#define CLK_SCLK_UART2 366
326#define CLK_SCLK_UART1 367
327#define CLK_SCLK_UART0 368
328#define CLK_SCLK_HDMIPHY 369
329
330/*
331 * Total number of clocks of main CMU.
332 * NOTE: Must be equal to last clock ID increased by one.
333 */
334#define CLK_NR_CLKS 370
335
336/*
337 * CMU DMC
338 */
339#define CLK_DMC_FOUT_MPLL 1
340#define CLK_DMC_FOUT_BPLL 2
341
342#define CLK_DMC_MOUT_MPLL 3
343#define CLK_DMC_MOUT_BPLL 4
344#define CLK_DMC_MOUT_DPHY 5
345#define CLK_DMC_MOUT_DMC_BUS 6
346
347#define CLK_DMC_DIV_DMC 7
348#define CLK_DMC_DIV_DPHY 8
349#define CLK_DMC_DIV_DMC_PRE 9
350#define CLK_DMC_DIV_DMCP 10
351#define CLK_DMC_DIV_DMCD 11
352#define CLK_DMC_DIV_MPLL_PRE 12
353
354/*
355 * Total number of clocks of CMU_DMC.
356 * NOTE: Must be equal to highest clock ID increased by one.
357 */
358#define NR_CLKS_DMC 13
359
360#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS4415_CLOCK_H */
diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h
index 4fa6bb2136e3..be39d23e6a32 100644
--- a/include/dt-bindings/clock/exynos5433.h
+++ b/include/dt-bindings/clock/exynos5433.h
@@ -771,7 +771,10 @@
771 771
772#define CLK_PCLK_DECON 113 772#define CLK_PCLK_DECON 113
773 773
774#define DISP_NR_CLK 114 774#define CLK_PHYCLK_MIPIDPHY0_BITCLKDIV8_PHY 114
775#define CLK_PHYCLK_MIPIDPHY0_RXCLKESC0_PHY 115
776
777#define DISP_NR_CLK 116
775 778
776/* CMU_AUD */ 779/* CMU_AUD */
777#define CLK_MOUT_AUD_PLL_USER 1 780#define CLK_MOUT_AUD_PLL_USER 1
diff --git a/include/dt-bindings/clock/hi3660-clock.h b/include/dt-bindings/clock/hi3660-clock.h
new file mode 100644
index 000000000000..1c00b7fe296f
--- /dev/null
+++ b/include/dt-bindings/clock/hi3660-clock.h
@@ -0,0 +1,194 @@
1/*
2 * Copyright (c) 2016-2017 Linaro Ltd.
3 * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#ifndef __DTS_HI3660_CLOCK_H
12#define __DTS_HI3660_CLOCK_H
13
14/* fixed rate clocks */
15#define HI3660_CLKIN_SYS 0
16#define HI3660_CLKIN_REF 1
17#define HI3660_CLK_FLL_SRC 2
18#define HI3660_CLK_PPLL0 3
19#define HI3660_CLK_PPLL1 4
20#define HI3660_CLK_PPLL2 5
21#define HI3660_CLK_PPLL3 6
22#define HI3660_CLK_SCPLL 7
23#define HI3660_PCLK 8
24#define HI3660_CLK_UART0_DBG 9
25#define HI3660_CLK_UART6 10
26#define HI3660_OSC32K 11
27#define HI3660_OSC19M 12
28#define HI3660_CLK_480M 13
29#define HI3660_CLK_INV 14
30
31/* clk in crgctrl */
32#define HI3660_FACTOR_UART3 15
33#define HI3660_CLK_FACTOR_MMC 16
34#define HI3660_CLK_GATE_I2C0 17
35#define HI3660_CLK_GATE_I2C1 18
36#define HI3660_CLK_GATE_I2C2 19
37#define HI3660_CLK_GATE_I2C6 20
38#define HI3660_CLK_DIV_SYSBUS 21
39#define HI3660_CLK_DIV_320M 22
40#define HI3660_CLK_DIV_A53 23
41#define HI3660_CLK_GATE_SPI0 24
42#define HI3660_CLK_GATE_SPI2 25
43#define HI3660_PCIEPHY_REF 26
44#define HI3660_CLK_ABB_USB 27
45#define HI3660_HCLK_GATE_SDIO0 28
46#define HI3660_HCLK_GATE_SD 29
47#define HI3660_CLK_GATE_AOMM 30
48#define HI3660_PCLK_GPIO0 31
49#define HI3660_PCLK_GPIO1 32
50#define HI3660_PCLK_GPIO2 33
51#define HI3660_PCLK_GPIO3 34
52#define HI3660_PCLK_GPIO4 35
53#define HI3660_PCLK_GPIO5 36
54#define HI3660_PCLK_GPIO6 37
55#define HI3660_PCLK_GPIO7 38
56#define HI3660_PCLK_GPIO8 39
57#define HI3660_PCLK_GPIO9 40
58#define HI3660_PCLK_GPIO10 41
59#define HI3660_PCLK_GPIO11 42
60#define HI3660_PCLK_GPIO12 43
61#define HI3660_PCLK_GPIO13 44
62#define HI3660_PCLK_GPIO14 45
63#define HI3660_PCLK_GPIO15 46
64#define HI3660_PCLK_GPIO16 47
65#define HI3660_PCLK_GPIO17 48
66#define HI3660_PCLK_GPIO18 49
67#define HI3660_PCLK_GPIO19 50
68#define HI3660_PCLK_GPIO20 51
69#define HI3660_PCLK_GPIO21 52
70#define HI3660_CLK_GATE_SPI3 53
71#define HI3660_CLK_GATE_I2C7 54
72#define HI3660_CLK_GATE_I2C3 55
73#define HI3660_CLK_GATE_SPI1 56
74#define HI3660_CLK_GATE_UART1 57
75#define HI3660_CLK_GATE_UART2 58
76#define HI3660_CLK_GATE_UART4 59
77#define HI3660_CLK_GATE_UART5 60
78#define HI3660_CLK_GATE_I2C4 61
79#define HI3660_CLK_GATE_DMAC 62
80#define HI3660_PCLK_GATE_DSS 63
81#define HI3660_ACLK_GATE_DSS 64
82#define HI3660_CLK_GATE_LDI1 65
83#define HI3660_CLK_GATE_LDI0 66
84#define HI3660_CLK_GATE_VIVOBUS 67
85#define HI3660_CLK_GATE_EDC0 68
86#define HI3660_CLK_GATE_TXDPHY0_CFG 69
87#define HI3660_CLK_GATE_TXDPHY0_REF 70
88#define HI3660_CLK_GATE_TXDPHY1_CFG 71
89#define HI3660_CLK_GATE_TXDPHY1_REF 72
90#define HI3660_ACLK_GATE_USB3OTG 73
91#define HI3660_CLK_GATE_SPI4 74
92#define HI3660_CLK_GATE_SD 75
93#define HI3660_CLK_GATE_SDIO0 76
94#define HI3660_CLK_GATE_UFS_SUBSYS 77
95#define HI3660_PCLK_GATE_DSI0 78
96#define HI3660_PCLK_GATE_DSI1 79
97#define HI3660_ACLK_GATE_PCIE 80
98#define HI3660_PCLK_GATE_PCIE_SYS 81
99#define HI3660_CLK_GATE_PCIEAUX 82
100#define HI3660_PCLK_GATE_PCIE_PHY 83
101#define HI3660_CLK_ANDGT_LDI0 84
102#define HI3660_CLK_ANDGT_LDI1 85
103#define HI3660_CLK_ANDGT_EDC0 86
104#define HI3660_CLK_GATE_UFSPHY_GT 87
105#define HI3660_CLK_ANDGT_MMC 88
106#define HI3660_CLK_ANDGT_SD 89
107#define HI3660_CLK_A53HPM_ANDGT 90
108#define HI3660_CLK_ANDGT_SDIO 91
109#define HI3660_CLK_ANDGT_UART0 92
110#define HI3660_CLK_ANDGT_UART1 93
111#define HI3660_CLK_ANDGT_UARTH 94
112#define HI3660_CLK_ANDGT_SPI 95
113#define HI3660_CLK_VIVOBUS_ANDGT 96
114#define HI3660_CLK_AOMM_ANDGT 97
115#define HI3660_CLK_320M_PLL_GT 98
116#define HI3660_AUTODIV_EMMC0BUS 99
117#define HI3660_AUTODIV_SYSBUS 100
118#define HI3660_CLK_GATE_UFSPHY_CFG 101
119#define HI3660_CLK_GATE_UFSIO_REF 102
120#define HI3660_CLK_MUX_SYSBUS 103
121#define HI3660_CLK_MUX_UART0 104
122#define HI3660_CLK_MUX_UART1 105
123#define HI3660_CLK_MUX_UARTH 106
124#define HI3660_CLK_MUX_SPI 107
125#define HI3660_CLK_MUX_I2C 108
126#define HI3660_CLK_MUX_MMC_PLL 109
127#define HI3660_CLK_MUX_LDI1 110
128#define HI3660_CLK_MUX_LDI0 111
129#define HI3660_CLK_MUX_SD_PLL 112
130#define HI3660_CLK_MUX_SD_SYS 113
131#define HI3660_CLK_MUX_EDC0 114
132#define HI3660_CLK_MUX_SDIO_SYS 115
133#define HI3660_CLK_MUX_SDIO_PLL 116
134#define HI3660_CLK_MUX_VIVOBUS 117
135#define HI3660_CLK_MUX_A53HPM 118
136#define HI3660_CLK_MUX_320M 119
137#define HI3660_CLK_MUX_IOPERI 120
138#define HI3660_CLK_DIV_UART0 121
139#define HI3660_CLK_DIV_UART1 122
140#define HI3660_CLK_DIV_UARTH 123
141#define HI3660_CLK_DIV_MMC 124
142#define HI3660_CLK_DIV_SD 125
143#define HI3660_CLK_DIV_EDC0 126
144#define HI3660_CLK_DIV_LDI0 127
145#define HI3660_CLK_DIV_SDIO 128
146#define HI3660_CLK_DIV_LDI1 129
147#define HI3660_CLK_DIV_SPI 130
148#define HI3660_CLK_DIV_VIVOBUS 131
149#define HI3660_CLK_DIV_I2C 132
150#define HI3660_CLK_DIV_UFSPHY 133
151#define HI3660_CLK_DIV_CFGBUS 134
152#define HI3660_CLK_DIV_MMC0BUS 135
153#define HI3660_CLK_DIV_MMC1BUS 136
154#define HI3660_CLK_DIV_UFSPERI 137
155#define HI3660_CLK_DIV_AOMM 138
156#define HI3660_CLK_DIV_IOPERI 139
157
158/* clk in pmuctrl */
159#define HI3660_GATE_ABB_192 0
160
161/* clk in pctrl */
162#define HI3660_GATE_UFS_TCXO_EN 0
163#define HI3660_GATE_USB_TCXO_EN 1
164
165/* clk in sctrl */
166#define HI3660_PCLK_AO_GPIO0 0
167#define HI3660_PCLK_AO_GPIO1 1
168#define HI3660_PCLK_AO_GPIO2 2
169#define HI3660_PCLK_AO_GPIO3 3
170#define HI3660_PCLK_AO_GPIO4 4
171#define HI3660_PCLK_AO_GPIO5 5
172#define HI3660_PCLK_AO_GPIO6 6
173#define HI3660_PCLK_GATE_MMBUF 7
174#define HI3660_CLK_GATE_DSS_AXI_MM 8
175#define HI3660_PCLK_MMBUF_ANDGT 9
176#define HI3660_CLK_MMBUF_PLL_ANDGT 10
177#define HI3660_CLK_FLL_MMBUF_ANDGT 11
178#define HI3660_CLK_SYS_MMBUF_ANDGT 12
179#define HI3660_CLK_GATE_PCIEPHY_GT 13
180#define HI3660_ACLK_MUX_MMBUF 14
181#define HI3660_CLK_SW_MMBUF 15
182#define HI3660_CLK_DIV_AOBUS 16
183#define HI3660_PCLK_DIV_MMBUF 17
184#define HI3660_ACLK_DIV_MMBUF 18
185#define HI3660_CLK_DIV_PCIEPHY 19
186
187/* clk in iomcu */
188#define HI3660_CLK_I2C0_IOMCU 0
189#define HI3660_CLK_I2C1_IOMCU 1
190#define HI3660_CLK_I2C2_IOMCU 2
191#define HI3660_CLK_I2C6_IOMCU 3
192#define HI3660_CLK_IOMCU_PERI0 4
193
194#endif /* __DTS_HI3660_CLOCK_H */
diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h
index 1183347c383f..a7a1a50f33ef 100644
--- a/include/dt-bindings/clock/imx7d-clock.h
+++ b/include/dt-bindings/clock/imx7d-clock.h
@@ -449,5 +449,6 @@
449#define IMX7D_ADC_ROOT_CLK 436 449#define IMX7D_ADC_ROOT_CLK 436
450#define IMX7D_CLK_ARM 437 450#define IMX7D_CLK_ARM 437
451#define IMX7D_CKIL 438 451#define IMX7D_CKIL 438
452#define IMX7D_CLK_END 439 452#define IMX7D_OCOTP_CLK 439
453#define IMX7D_CLK_END 440
453#endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ 454#endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
diff --git a/include/dt-bindings/clock/qcom,gcc-ipq4019.h b/include/dt-bindings/clock/qcom,gcc-ipq4019.h
index 6240e5b0e900..7e8a7be6dcda 100644
--- a/include/dt-bindings/clock/qcom,gcc-ipq4019.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq4019.h
@@ -81,6 +81,17 @@
81#define GCC_WCSS5G_CLK 62 81#define GCC_WCSS5G_CLK 62
82#define GCC_WCSS5G_REF_CLK 63 82#define GCC_WCSS5G_REF_CLK 63
83#define GCC_WCSS5G_RTC_CLK 64 83#define GCC_WCSS5G_RTC_CLK 64
84#define GCC_APSS_DDRPLL_VCO 65
85#define GCC_SDCC_PLLDIV_CLK 66
86#define GCC_FEPLL_VCO 67
87#define GCC_FEPLL125_CLK 68
88#define GCC_FEPLL125DLY_CLK 69
89#define GCC_FEPLL200_CLK 70
90#define GCC_FEPLL500_CLK 71
91#define GCC_FEPLL_WCSS2G_CLK 72
92#define GCC_FEPLL_WCSS5G_CLK 73
93#define GCC_APSS_CPU_PLLDIV_CLK 74
94#define GCC_PCNOC_AHB_CLK_SRC 75
84 95
85#define WIFI0_CPU_INIT_RESET 0 96#define WIFI0_CPU_INIT_RESET 0
86#define WIFI0_RADIO_SRIF_RESET 1 97#define WIFI0_RADIO_SRIF_RESET 1
diff --git a/include/dt-bindings/clock/qcom,gcc-mdm9615.h b/include/dt-bindings/clock/qcom,gcc-mdm9615.h
index 9ab2c4087120..787e448958bd 100644
--- a/include/dt-bindings/clock/qcom,gcc-mdm9615.h
+++ b/include/dt-bindings/clock/qcom,gcc-mdm9615.h
@@ -323,5 +323,7 @@
323#define CE3_H_CLK 305 323#define CE3_H_CLK 305
324#define USB_HS1_SYSTEM_CLK_SRC 306 324#define USB_HS1_SYSTEM_CLK_SRC 306
325#define USB_HS1_SYSTEM_CLK 307 325#define USB_HS1_SYSTEM_CLK 307
326#define EBI2_CLK 308
327#define EBI2_AON_CLK 309
326 328
327#endif 329#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8994.h b/include/dt-bindings/clock/qcom,gcc-msm8994.h
index 8fa535be2ebc..df47da0860f7 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8994.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8994.h
@@ -133,5 +133,6 @@
133#define GCC_USB30_MOCK_UTMI_CLK 115 133#define GCC_USB30_MOCK_UTMI_CLK 115
134#define GCC_USB3_PHY_AUX_CLK 116 134#define GCC_USB3_PHY_AUX_CLK 116
135#define GCC_USB_HS_SYSTEM_CLK 117 135#define GCC_USB_HS_SYSTEM_CLK 117
136#define GCC_SDCC1_AHB_CLK 118
136 137
137#endif 138#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h
index 1828723eb621..1f5c42254798 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8996.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h
@@ -339,6 +339,7 @@
339#define GCC_PCIE_PHY_COM_NOCSR_BCR 102 339#define GCC_PCIE_PHY_COM_NOCSR_BCR 102
340#define GCC_USB3_PHY_BCR 103 340#define GCC_USB3_PHY_BCR 103
341#define GCC_USB3PHY_PHY_BCR 104 341#define GCC_USB3PHY_PHY_BCR 104
342#define GCC_MSS_RESTART 105
342 343
343 344
344/* Indexes for GDSCs */ 345/* Indexes for GDSCs */
diff --git a/include/dt-bindings/clock/qcom,rpmcc.h b/include/dt-bindings/clock/qcom,rpmcc.h
index 5924cdb71336..96b63c00249e 100644
--- a/include/dt-bindings/clock/qcom,rpmcc.h
+++ b/include/dt-bindings/clock/qcom,rpmcc.h
@@ -14,7 +14,7 @@
14#ifndef _DT_BINDINGS_CLK_MSM_RPMCC_H 14#ifndef _DT_BINDINGS_CLK_MSM_RPMCC_H
15#define _DT_BINDINGS_CLK_MSM_RPMCC_H 15#define _DT_BINDINGS_CLK_MSM_RPMCC_H
16 16
17/* apq8064 */ 17/* RPM clocks */
18#define RPM_PXO_CLK 0 18#define RPM_PXO_CLK 0
19#define RPM_PXO_A_CLK 1 19#define RPM_PXO_A_CLK 1
20#define RPM_CXO_CLK 2 20#define RPM_CXO_CLK 2
@@ -38,7 +38,7 @@
38#define RPM_SFPB_CLK 20 38#define RPM_SFPB_CLK 20
39#define RPM_SFPB_A_CLK 21 39#define RPM_SFPB_A_CLK 21
40 40
41/* msm8916 */ 41/* SMD RPM clocks */
42#define RPM_SMD_XO_CLK_SRC 0 42#define RPM_SMD_XO_CLK_SRC 0
43#define RPM_SMD_XO_A_CLK_SRC 1 43#define RPM_SMD_XO_A_CLK_SRC 1
44#define RPM_SMD_PCNOC_CLK 2 44#define RPM_SMD_PCNOC_CLK 2
@@ -65,5 +65,41 @@
65#define RPM_SMD_RF_CLK1_A_PIN 23 65#define RPM_SMD_RF_CLK1_A_PIN 23
66#define RPM_SMD_RF_CLK2_PIN 24 66#define RPM_SMD_RF_CLK2_PIN 24
67#define RPM_SMD_RF_CLK2_A_PIN 25 67#define RPM_SMD_RF_CLK2_A_PIN 25
68#define RPM_SMD_PNOC_CLK 26
69#define RPM_SMD_PNOC_A_CLK 27
70#define RPM_SMD_CNOC_CLK 28
71#define RPM_SMD_CNOC_A_CLK 29
72#define RPM_SMD_MMSSNOC_AHB_CLK 30
73#define RPM_SMD_MMSSNOC_AHB_A_CLK 31
74#define RPM_SMD_GFX3D_CLK_SRC 32
75#define RPM_SMD_GFX3D_A_CLK_SRC 33
76#define RPM_SMD_OCMEMGX_CLK 34
77#define RPM_SMD_OCMEMGX_A_CLK 35
78#define RPM_SMD_CXO_D0 36
79#define RPM_SMD_CXO_D0_A 37
80#define RPM_SMD_CXO_D1 38
81#define RPM_SMD_CXO_D1_A 39
82#define RPM_SMD_CXO_A0 40
83#define RPM_SMD_CXO_A0_A 41
84#define RPM_SMD_CXO_A1 42
85#define RPM_SMD_CXO_A1_A 43
86#define RPM_SMD_CXO_A2 44
87#define RPM_SMD_CXO_A2_A 45
88#define RPM_SMD_DIV_CLK1 46
89#define RPM_SMD_DIV_A_CLK1 47
90#define RPM_SMD_DIV_CLK2 48
91#define RPM_SMD_DIV_A_CLK2 49
92#define RPM_SMD_DIFF_CLK 50
93#define RPM_SMD_DIFF_A_CLK 51
94#define RPM_SMD_CXO_D0_PIN 52
95#define RPM_SMD_CXO_D0_A_PIN 53
96#define RPM_SMD_CXO_D1_PIN 54
97#define RPM_SMD_CXO_D1_A_PIN 55
98#define RPM_SMD_CXO_A0_PIN 56
99#define RPM_SMD_CXO_A0_A_PIN 57
100#define RPM_SMD_CXO_A1_PIN 58
101#define RPM_SMD_CXO_A1_A_PIN 59
102#define RPM_SMD_CXO_A2_PIN 60
103#define RPM_SMD_CXO_A2_A_PIN 61
68 104
69#endif 105#endif
diff --git a/include/dt-bindings/clock/rk3188-cru-common.h b/include/dt-bindings/clock/rk3188-cru-common.h
index d141c1f0c778..eff4319d008b 100644
--- a/include/dt-bindings/clock/rk3188-cru-common.h
+++ b/include/dt-bindings/clock/rk3188-cru-common.h
@@ -108,6 +108,8 @@
108#define PCLK_TSADC 349 108#define PCLK_TSADC 349
109#define PCLK_CPU 350 109#define PCLK_CPU 350
110#define PCLK_PERI 351 110#define PCLK_PERI 351
111#define PCLK_DDRUPCTL 352
112#define PCLK_PUBL 353
111 113
112/* hclk gates */ 114/* hclk gates */
113#define HCLK_SDMMC 448 115#define HCLK_SDMMC 448
diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h
index 9a586e2d9c91..d7b6c83ea63f 100644
--- a/include/dt-bindings/clock/rk3288-cru.h
+++ b/include/dt-bindings/clock/rk3288-cru.h
@@ -88,6 +88,7 @@
88#define SCLK_PVTM_GPU 124 88#define SCLK_PVTM_GPU 124
89#define SCLK_CRYPTO 125 89#define SCLK_CRYPTO 125
90#define SCLK_MIPIDSI_24M 126 90#define SCLK_MIPIDSI_24M 126
91#define SCLK_VIP_OUT 127
91 92
92#define SCLK_MAC 151 93#define SCLK_MAC 151
93#define SCLK_MACREF_OUT 152 94#define SCLK_MACREF_OUT 152
@@ -168,6 +169,7 @@
168#define PCLK_WDT 368 169#define PCLK_WDT 368
169#define PCLK_EFUSE256 369 170#define PCLK_EFUSE256 369
170#define PCLK_EFUSE1024 370 171#define PCLK_EFUSE1024 370
172#define PCLK_ISP_IN 371
171 173
172/* hclk gates */ 174/* hclk gates */
173#define HCLK_GPS 448 175#define HCLK_GPS 448
diff --git a/include/dt-bindings/clock/rk3328-cru.h b/include/dt-bindings/clock/rk3328-cru.h
new file mode 100644
index 000000000000..ee702c8e4c09
--- /dev/null
+++ b/include/dt-bindings/clock/rk3328-cru.h
@@ -0,0 +1,400 @@
1/*
2 * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
3 * Author: Elaine <zhangqing@rock-chips.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3328_H
17#define _DT_BINDINGS_CLK_ROCKCHIP_RK3328_H
18
19/* core clocks */
20#define PLL_APLL 1
21#define PLL_DPLL 2
22#define PLL_CPLL 3
23#define PLL_GPLL 4
24#define PLL_NPLL 5
25#define ARMCLK 6
26
27/* sclk gates (special clocks) */
28#define SCLK_RTC32K 30
29#define SCLK_SDMMC_EXT 31
30#define SCLK_SPI 32
31#define SCLK_SDMMC 33
32#define SCLK_SDIO 34
33#define SCLK_EMMC 35
34#define SCLK_TSADC 36
35#define SCLK_SARADC 37
36#define SCLK_UART0 38
37#define SCLK_UART1 39
38#define SCLK_UART2 40
39#define SCLK_I2S0 41
40#define SCLK_I2S1 42
41#define SCLK_I2S2 43
42#define SCLK_I2S1_OUT 44
43#define SCLK_I2S2_OUT 45
44#define SCLK_SPDIF 46
45#define SCLK_TIMER0 47
46#define SCLK_TIMER1 48
47#define SCLK_TIMER2 49
48#define SCLK_TIMER3 50
49#define SCLK_TIMER4 51
50#define SCLK_TIMER5 52
51#define SCLK_WIFI 53
52#define SCLK_CIF_OUT 54
53#define SCLK_I2C0 55
54#define SCLK_I2C1 56
55#define SCLK_I2C2 57
56#define SCLK_I2C3 58
57#define SCLK_CRYPTO 59
58#define SCLK_PWM 60
59#define SCLK_PDM 61
60#define SCLK_EFUSE 62
61#define SCLK_OTP 63
62#define SCLK_DDRCLK 64
63#define SCLK_VDEC_CABAC 65
64#define SCLK_VDEC_CORE 66
65#define SCLK_VENC_DSP 67
66#define SCLK_VENC_CORE 68
67#define SCLK_RGA 69
68#define SCLK_HDMI_SFC 70
69#define SCLK_HDMI_CEC 71
70#define SCLK_USB3_REF 72
71#define SCLK_USB3_SUSPEND 73
72#define SCLK_SDMMC_DRV 74
73#define SCLK_SDIO_DRV 75
74#define SCLK_EMMC_DRV 76
75#define SCLK_SDMMC_EXT_DRV 77
76#define SCLK_SDMMC_SAMPLE 78
77#define SCLK_SDIO_SAMPLE 79
78#define SCLK_EMMC_SAMPLE 80
79#define SCLK_SDMMC_EXT_SAMPLE 81
80#define SCLK_VOP 82
81#define SCLK_MAC2PHY_RXTX 83
82#define SCLK_MAC2PHY_SRC 84
83#define SCLK_MAC2PHY_REF 85
84#define SCLK_MAC2PHY_OUT 86
85#define SCLK_MAC2IO_RX 87
86#define SCLK_MAC2IO_TX 88
87#define SCLK_MAC2IO_REFOUT 89
88#define SCLK_MAC2IO_REF 90
89#define SCLK_MAC2IO_OUT 91
90#define SCLK_TSP 92
91#define SCLK_HSADC_TSP 93
92#define SCLK_USB3PHY_REF 94
93#define SCLK_REF_USB3OTG 95
94#define SCLK_USB3OTG_REF 96
95#define SCLK_USB3OTG_SUSPEND 97
96#define SCLK_REF_USB3OTG_SRC 98
97#define SCLK_MAC2IO_SRC 99
98#define SCLK_MAC2IO 100
99#define SCLK_MAC2PHY 101
100
101/* dclk gates */
102#define DCLK_LCDC 120
103#define DCLK_HDMIPHY 121
104#define HDMIPHY 122
105#define USB480M 123
106#define DCLK_LCDC_SRC 124
107
108/* aclk gates */
109#define ACLK_AXISRAM 130
110#define ACLK_VOP_PRE 131
111#define ACLK_USB3OTG 132
112#define ACLK_RGA_PRE 133
113#define ACLK_DMAC 134
114#define ACLK_GPU 135
115#define ACLK_BUS_PRE 136
116#define ACLK_PERI_PRE 137
117#define ACLK_RKVDEC_PRE 138
118#define ACLK_RKVDEC 139
119#define ACLK_RKVENC 140
120#define ACLK_VPU_PRE 141
121#define ACLK_VIO_PRE 142
122#define ACLK_VPU 143
123#define ACLK_VIO 144
124#define ACLK_VOP 145
125#define ACLK_GMAC 146
126#define ACLK_H265 147
127#define ACLK_H264 148
128#define ACLK_MAC2PHY 149
129#define ACLK_MAC2IO 150
130#define ACLK_DCF 151
131#define ACLK_TSP 152
132#define ACLK_PERI 153
133#define ACLK_RGA 154
134#define ACLK_IEP 155
135#define ACLK_CIF 156
136#define ACLK_HDCP 157
137
138/* pclk gates */
139#define PCLK_GPIO0 200
140#define PCLK_GPIO1 201
141#define PCLK_GPIO2 202
142#define PCLK_GPIO3 203
143#define PCLK_GRF 204
144#define PCLK_I2C0 205
145#define PCLK_I2C1 206
146#define PCLK_I2C2 207
147#define PCLK_I2C3 208
148#define PCLK_SPI 209
149#define PCLK_UART0 210
150#define PCLK_UART1 211
151#define PCLK_UART2 212
152#define PCLK_TSADC 213
153#define PCLK_PWM 214
154#define PCLK_TIMER 215
155#define PCLK_BUS_PRE 216
156#define PCLK_PERI_PRE 217
157#define PCLK_HDMI_CTRL 218
158#define PCLK_HDMI_PHY 219
159#define PCLK_GMAC 220
160#define PCLK_H265 221
161#define PCLK_MAC2PHY 222
162#define PCLK_MAC2IO 223
163#define PCLK_USB3PHY_OTG 224
164#define PCLK_USB3PHY_PIPE 225
165#define PCLK_USB3_GRF 226
166#define PCLK_USB2_GRF 227
167#define PCLK_HDMIPHY 228
168#define PCLK_DDR 229
169#define PCLK_PERI 230
170#define PCLK_HDMI 231
171#define PCLK_HDCP 232
172#define PCLK_DCF 233
173#define PCLK_SARADC 234
174
175/* hclk gates */
176#define HCLK_PERI 308
177#define HCLK_TSP 309
178#define HCLK_GMAC 310
179#define HCLK_I2S0_8CH 311
180#define HCLK_I2S1_8CH 313
181#define HCLK_I2S2_2CH 313
182#define HCLK_SPDIF_8CH 314
183#define HCLK_VOP 315
184#define HCLK_NANDC 316
185#define HCLK_SDMMC 317
186#define HCLK_SDIO 318
187#define HCLK_EMMC 319
188#define HCLK_SDMMC_EXT 320
189#define HCLK_RKVDEC_PRE 321
190#define HCLK_RKVDEC 322
191#define HCLK_RKVENC 323
192#define HCLK_VPU_PRE 324
193#define HCLK_VIO_PRE 325
194#define HCLK_VPU 326
195#define HCLK_VIO 327
196#define HCLK_BUS_PRE 328
197#define HCLK_PERI_PRE 329
198#define HCLK_H264 330
199#define HCLK_CIF 331
200#define HCLK_OTG_PMU 332
201#define HCLK_OTG 333
202#define HCLK_HOST0 334
203#define HCLK_HOST0_ARB 335
204#define HCLK_CRYPTO_MST 336
205#define HCLK_CRYPTO_SLV 337
206#define HCLK_PDM 338
207#define HCLK_IEP 339
208#define HCLK_RGA 340
209#define HCLK_HDCP 341
210
211#define CLK_NR_CLKS (HCLK_HDCP + 1)
212
213/* soft-reset indices */
214#define SRST_CORE0_PO 0
215#define SRST_CORE1_PO 1
216#define SRST_CORE2_PO 2
217#define SRST_CORE3_PO 3
218#define SRST_CORE0 4
219#define SRST_CORE1 5
220#define SRST_CORE2 6
221#define SRST_CORE3 7
222#define SRST_CORE0_DBG 8
223#define SRST_CORE1_DBG 9
224#define SRST_CORE2_DBG 10
225#define SRST_CORE3_DBG 11
226#define SRST_TOPDBG 12
227#define SRST_CORE_NIU 13
228#define SRST_STRC_A 14
229#define SRST_L2C 15
230
231#define SRST_A53_GIC 18
232#define SRST_DAP 19
233#define SRST_PMU_P 21
234#define SRST_EFUSE 22
235#define SRST_BUSSYS_H 23
236#define SRST_BUSSYS_P 24
237#define SRST_SPDIF 25
238#define SRST_INTMEM 26
239#define SRST_ROM 27
240#define SRST_GPIO0 28
241#define SRST_GPIO1 29
242#define SRST_GPIO2 30
243#define SRST_GPIO3 31
244
245#define SRST_I2S0 32
246#define SRST_I2S1 33
247#define SRST_I2S2 34
248#define SRST_I2S0_H 35
249#define SRST_I2S1_H 36
250#define SRST_I2S2_H 37
251#define SRST_UART0 38
252#define SRST_UART1 39
253#define SRST_UART2 40
254#define SRST_UART0_P 41
255#define SRST_UART1_P 42
256#define SRST_UART2_P 43
257#define SRST_I2C0 44
258#define SRST_I2C1 45
259#define SRST_I2C2 46
260#define SRST_I2C3 47
261
262#define SRST_I2C0_P 48
263#define SRST_I2C1_P 49
264#define SRST_I2C2_P 50
265#define SRST_I2C3_P 51
266#define SRST_EFUSE_SE_P 52
267#define SRST_EFUSE_NS_P 53
268#define SRST_PWM0 54
269#define SRST_PWM0_P 55
270#define SRST_DMA 56
271#define SRST_TSP_A 57
272#define SRST_TSP_H 58
273#define SRST_TSP 59
274#define SRST_TSP_HSADC 60
275#define SRST_DCF_A 61
276#define SRST_DCF_P 62
277
278#define SRST_SCR 64
279#define SRST_SPI 65
280#define SRST_TSADC 66
281#define SRST_TSADC_P 67
282#define SRST_CRYPTO 68
283#define SRST_SGRF 69
284#define SRST_GRF 70
285#define SRST_USB_GRF 71
286#define SRST_TIMER_6CH_P 72
287#define SRST_TIMER0 73
288#define SRST_TIMER1 74
289#define SRST_TIMER2 75
290#define SRST_TIMER3 76
291#define SRST_TIMER4 77
292#define SRST_TIMER5 78
293#define SRST_USB3GRF 79
294
295#define SRST_PHYNIU 80
296#define SRST_HDMIPHY 81
297#define SRST_VDAC 82
298#define SRST_ACODEC_p 83
299#define SRST_SARADC 85
300#define SRST_SARADC_P 86
301#define SRST_GRF_DDR 87
302#define SRST_DFIMON 88
303#define SRST_MSCH 89
304#define SRST_DDRMSCH 91
305#define SRST_DDRCTRL 92
306#define SRST_DDRCTRL_P 93
307#define SRST_DDRPHY 94
308#define SRST_DDRPHY_P 95
309
310#define SRST_GMAC_NIU_A 96
311#define SRST_GMAC_NIU_P 97
312#define SRST_GMAC2PHY_A 98
313#define SRST_GMAC2IO_A 99
314#define SRST_MACPHY 100
315#define SRST_OTP_PHY 101
316#define SRST_GPU_A 102
317#define SRST_GPU_NIU_A 103
318#define SRST_SDMMCEXT 104
319#define SRST_PERIPH_NIU_A 105
320#define SRST_PERIHP_NIU_H 106
321#define SRST_PERIHP_P 107
322#define SRST_PERIPHSYS_H 108
323#define SRST_MMC0 109
324#define SRST_SDIO 110
325#define SRST_EMMC 111
326
327#define SRST_USB2OTG_H 112
328#define SRST_USB2OTG 113
329#define SRST_USB2OTG_ADP 114
330#define SRST_USB2HOST_H 115
331#define SRST_USB2HOST_ARB 116
332#define SRST_USB2HOST_AUX 117
333#define SRST_USB2HOST_EHCIPHY 118
334#define SRST_USB2HOST_UTMI 119
335#define SRST_USB3OTG 120
336#define SRST_USBPOR 121
337#define SRST_USB2OTG_UTMI 122
338#define SRST_USB2HOST_PHY_UTMI 123
339#define SRST_USB3OTG_UTMI 124
340#define SRST_USB3PHY_U2 125
341#define SRST_USB3PHY_U3 126
342#define SRST_USB3PHY_PIPE 127
343
344#define SRST_VIO_A 128
345#define SRST_VIO_BUS_H 129
346#define SRST_VIO_H2P_H 130
347#define SRST_VIO_ARBI_H 131
348#define SRST_VOP_NIU_A 132
349#define SRST_VOP_A 133
350#define SRST_VOP_H 134
351#define SRST_VOP_D 135
352#define SRST_RGA 136
353#define SRST_RGA_NIU_A 137
354#define SRST_RGA_A 138
355#define SRST_RGA_H 139
356#define SRST_IEP_A 140
357#define SRST_IEP_H 141
358#define SRST_HDMI 142
359#define SRST_HDMI_P 143
360
361#define SRST_HDCP_A 144
362#define SRST_HDCP 145
363#define SRST_HDCP_H 146
364#define SRST_CIF_A 147
365#define SRST_CIF_H 148
366#define SRST_CIF_P 149
367#define SRST_OTP_P 150
368#define SRST_OTP_SBPI 151
369#define SRST_OTP_USER 152
370#define SRST_DDRCTRL_A 153
371#define SRST_DDRSTDY_P 154
372#define SRST_DDRSTDY 155
373#define SRST_PDM_H 156
374#define SRST_PDM 157
375#define SRST_USB3PHY_OTG_P 158
376#define SRST_USB3PHY_PIPE_P 159
377
378#define SRST_VCODEC_A 160
379#define SRST_VCODEC_NIU_A 161
380#define SRST_VCODEC_H 162
381#define SRST_VCODEC_NIU_H 163
382#define SRST_VDEC_A 164
383#define SRST_VDEC_NIU_A 165
384#define SRST_VDEC_H 166
385#define SRST_VDEC_NIU_H 167
386#define SRST_VDEC_CORE 168
387#define SRST_VDEC_CABAC 169
388#define SRST_DDRPHYDIV 175
389
390#define SRST_RKVENC_NIU_A 176
391#define SRST_RKVENC_NIU_H 177
392#define SRST_RKVENC_H265_A 178
393#define SRST_RKVENC_H265_P 179
394#define SRST_RKVENC_H265_CORE 180
395#define SRST_RKVENC_H265_DSP 181
396#define SRST_RKVENC_H264_A 182
397#define SRST_RKVENC_H264_H 183
398#define SRST_RKVENC_INTMEM 184
399
400#endif
diff --git a/include/dt-bindings/clock/ste-ab8500.h b/include/dt-bindings/clock/ste-ab8500.h
new file mode 100644
index 000000000000..6731f1f00a84
--- /dev/null
+++ b/include/dt-bindings/clock/ste-ab8500.h
@@ -0,0 +1,11 @@
1#ifndef __STE_CLK_AB8500_H__
2#define __STE_CLK_AB8500_H__
3
4#define AB8500_SYSCLK_BUF2 0
5#define AB8500_SYSCLK_BUF3 1
6#define AB8500_SYSCLK_BUF4 2
7#define AB8500_SYSCLK_ULP 3
8#define AB8500_SYSCLK_INT 4
9#define AB8500_SYSCLK_AUDIO 5
10
11#endif
diff --git a/include/dt-bindings/clock/stm32fx-clock.h b/include/dt-bindings/clock/stm32fx-clock.h
index 08bcab61b714..49bb3c203e5c 100644
--- a/include/dt-bindings/clock/stm32fx-clock.h
+++ b/include/dt-bindings/clock/stm32fx-clock.h
@@ -36,4 +36,24 @@
36 36
37#define END_PRIMARY_CLK 14 37#define END_PRIMARY_CLK 14
38 38
39#define CLK_HSI 14
40#define CLK_SYSCLK 15
41#define CLK_HDMI_CEC 16
42#define CLK_SPDIF 17
43#define CLK_USART1 18
44#define CLK_USART2 19
45#define CLK_USART3 20
46#define CLK_UART4 21
47#define CLK_UART5 22
48#define CLK_USART6 23
49#define CLK_UART7 24
50#define CLK_UART8 25
51#define CLK_I2C1 26
52#define CLK_I2C2 27
53#define CLK_I2C3 28
54#define CLK_I2C4 29
55#define CLK_LPTIMER 30
56
57#define END_PRIMARY_CLK_F7 31
58
39#endif 59#endif
diff --git a/include/dt-bindings/clock/sun5i-ccu.h b/include/dt-bindings/clock/sun5i-ccu.h
new file mode 100644
index 000000000000..aeb2e2f781fb
--- /dev/null
+++ b/include/dt-bindings/clock/sun5i-ccu.h
@@ -0,0 +1,103 @@
1/*
2 * Copyright 2016 Maxime Ripard
3 *
4 * Maxime Ripard <maxime.ripard@free-electrons.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _DT_BINDINGS_CLK_SUN5I_H_
18#define _DT_BINDINGS_CLK_SUN5I_H_
19
20#define CLK_HOSC 1
21
22#define CLK_CPU 17
23
24#define CLK_AHB_OTG 23
25#define CLK_AHB_EHCI 24
26#define CLK_AHB_OHCI 25
27#define CLK_AHB_SS 26
28#define CLK_AHB_DMA 27
29#define CLK_AHB_BIST 28
30#define CLK_AHB_MMC0 29
31#define CLK_AHB_MMC1 30
32#define CLK_AHB_MMC2 31
33#define CLK_AHB_NAND 32
34#define CLK_AHB_SDRAM 33
35#define CLK_AHB_EMAC 34
36#define CLK_AHB_TS 35
37#define CLK_AHB_SPI0 36
38#define CLK_AHB_SPI1 37
39#define CLK_AHB_SPI2 38
40#define CLK_AHB_GPS 39
41#define CLK_AHB_HSTIMER 40
42#define CLK_AHB_VE 41
43#define CLK_AHB_TVE 42
44#define CLK_AHB_LCD 43
45#define CLK_AHB_CSI 44
46#define CLK_AHB_HDMI 45
47#define CLK_AHB_DE_BE 46
48#define CLK_AHB_DE_FE 47
49#define CLK_AHB_IEP 48
50#define CLK_AHB_GPU 49
51#define CLK_APB0_CODEC 50
52#define CLK_APB0_SPDIF 51
53#define CLK_APB0_I2S 52
54#define CLK_APB0_PIO 53
55#define CLK_APB0_IR 54
56#define CLK_APB0_KEYPAD 55
57#define CLK_APB1_I2C0 56
58#define CLK_APB1_I2C1 57
59#define CLK_APB1_I2C2 58
60#define CLK_APB1_UART0 59
61#define CLK_APB1_UART1 60
62#define CLK_APB1_UART2 61
63#define CLK_APB1_UART3 62
64#define CLK_NAND 63
65#define CLK_MMC0 64
66#define CLK_MMC1 65
67#define CLK_MMC2 66
68#define CLK_TS 67
69#define CLK_SS 68
70#define CLK_SPI0 69
71#define CLK_SPI1 70
72#define CLK_SPI2 71
73#define CLK_IR 72
74#define CLK_I2S 73
75#define CLK_SPDIF 74
76#define CLK_KEYPAD 75
77#define CLK_USB_OHCI 76
78#define CLK_USB_PHY0 77
79#define CLK_USB_PHY1 78
80#define CLK_GPS 79
81#define CLK_DRAM_VE 80
82#define CLK_DRAM_CSI 81
83#define CLK_DRAM_TS 82
84#define CLK_DRAM_TVE 83
85#define CLK_DRAM_DE_FE 84
86#define CLK_DRAM_DE_BE 85
87#define CLK_DRAM_ACE 86
88#define CLK_DRAM_IEP 87
89#define CLK_DE_BE 88
90#define CLK_DE_FE 89
91#define CLK_TCON_CH0 90
92
93#define CLK_TCON_CH1 92
94#define CLK_CSI 93
95#define CLK_VE 94
96#define CLK_CODEC 95
97#define CLK_AVS 96
98#define CLK_HDMI 97
99#define CLK_GPU 98
100
101#define CLK_IEP 100
102
103#endif /* _DT_BINDINGS_CLK_SUN5I_H_ */
diff --git a/include/dt-bindings/clock/sun8i-v3s-ccu.h b/include/dt-bindings/clock/sun8i-v3s-ccu.h
new file mode 100644
index 000000000000..c0d5d5599c87
--- /dev/null
+++ b/include/dt-bindings/clock/sun8i-v3s-ccu.h
@@ -0,0 +1,107 @@
1/*
2 * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
3 *
4 * Based on sun8i-h3-ccu.h, which is:
5 * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
6 *
7 * This file is dual-licensed: you can use it either under the terms
8 * of the GPL or the X11 license, at your option. Note that this dual
9 * licensing only applies to this file, and not this project as a
10 * whole.
11 *
12 * a) This file is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * This file is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * Or, alternatively,
23 *
24 * b) Permission is hereby granted, free of charge, to any person
25 * obtaining a copy of this software and associated documentation
26 * files (the "Software"), to deal in the Software without
27 * restriction, including without limitation the rights to use,
28 * copy, modify, merge, publish, distribute, sublicense, and/or
29 * sell copies of the Software, and to permit persons to whom the
30 * Software is furnished to do so, subject to the following
31 * conditions:
32 *
33 * The above copyright notice and this permission notice shall be
34 * included in all copies or substantial portions of the Software.
35 *
36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
37 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
38 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
39 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
40 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
41 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
42 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
43 * OTHER DEALINGS IN THE SOFTWARE.
44 */
45
46#ifndef _DT_BINDINGS_CLK_SUN8I_V3S_H_
47#define _DT_BINDINGS_CLK_SUN8I_V3S_H_
48
49#define CLK_CPU 14
50
51#define CLK_BUS_CE 20
52#define CLK_BUS_DMA 21
53#define CLK_BUS_MMC0 22
54#define CLK_BUS_MMC1 23
55#define CLK_BUS_MMC2 24
56#define CLK_BUS_DRAM 25
57#define CLK_BUS_EMAC 26
58#define CLK_BUS_HSTIMER 27
59#define CLK_BUS_SPI0 28
60#define CLK_BUS_OTG 29
61#define CLK_BUS_EHCI0 30
62#define CLK_BUS_OHCI0 31
63#define CLK_BUS_VE 32
64#define CLK_BUS_TCON0 33
65#define CLK_BUS_CSI 34
66#define CLK_BUS_DE 35
67#define CLK_BUS_CODEC 36
68#define CLK_BUS_PIO 37
69#define CLK_BUS_I2C0 38
70#define CLK_BUS_I2C1 39
71#define CLK_BUS_UART0 40
72#define CLK_BUS_UART1 41
73#define CLK_BUS_UART2 42
74#define CLK_BUS_EPHY 43
75#define CLK_BUS_DBG 44
76
77#define CLK_MMC0 45
78#define CLK_MMC0_SAMPLE 46
79#define CLK_MMC0_OUTPUT 47
80#define CLK_MMC1 48
81#define CLK_MMC1_SAMPLE 49
82#define CLK_MMC1_OUTPUT 50
83#define CLK_MMC2 51
84#define CLK_MMC2_SAMPLE 52
85#define CLK_MMC2_OUTPUT 53
86#define CLK_CE 54
87#define CLK_SPI0 55
88#define CLK_USB_PHY0 56
89#define CLK_USB_OHCI0 57
90
91#define CLK_DRAM_VE 59
92#define CLK_DRAM_CSI 60
93#define CLK_DRAM_EHCI 61
94#define CLK_DRAM_OHCI 62
95#define CLK_DE 63
96#define CLK_TCON0 64
97#define CLK_CSI_MISC 65
98#define CLK_CSI0_MCLK 66
99#define CLK_CSI1_SCLK 67
100#define CLK_CSI1_MCLK 68
101#define CLK_VE 69
102#define CLK_AC_DIG 70
103#define CLK_AVS 71
104
105#define CLK_MIPI_CSI 73
106
107#endif /* _DT_BINDINGS_CLK_SUN8I_V3S_H_ */
diff --git a/include/dt-bindings/clock/sun9i-a80-ccu.h b/include/dt-bindings/clock/sun9i-a80-ccu.h
new file mode 100644
index 000000000000..6ea1492a73a6
--- /dev/null
+++ b/include/dt-bindings/clock/sun9i-a80-ccu.h
@@ -0,0 +1,162 @@
1/*
2 * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_CLOCK_SUN9I_A80_CCU_H_
44#define _DT_BINDINGS_CLOCK_SUN9I_A80_CCU_H_
45
46#define CLK_PLL_AUDIO 2
47#define CLK_PLL_PERIPH0 3
48
49#define CLK_C0CPUX 12
50#define CLK_C1CPUX 13
51
52#define CLK_OUT_A 27
53#define CLK_OUT_B 28
54
55#define CLK_NAND0_0 29
56#define CLK_NAND0_1 30
57#define CLK_NAND1_0 31
58#define CLK_NAND1_1 32
59#define CLK_MMC0 33
60#define CLK_MMC0_SAMPLE 34
61#define CLK_MMC0_OUTPUT 35
62#define CLK_MMC1 36
63#define CLK_MMC1_SAMPLE 37
64#define CLK_MMC1_OUTPUT 38
65#define CLK_MMC2 39
66#define CLK_MMC2_SAMPLE 40
67#define CLK_MMC2_OUTPUT 41
68#define CLK_MMC3 42
69#define CLK_MMC3_SAMPLE 43
70#define CLK_MMC3_OUTPUT 44
71#define CLK_TS 45
72#define CLK_SS 46
73#define CLK_SPI0 47
74#define CLK_SPI1 48
75#define CLK_SPI2 49
76#define CLK_SPI3 50
77#define CLK_I2S0 51
78#define CLK_I2S1 52
79#define CLK_SPDIF 53
80#define CLK_SDRAM 54
81#define CLK_DE 55
82#define CLK_EDP 56
83#define CLK_MP 57
84#define CLK_LCD0 58
85#define CLK_LCD1 59
86#define CLK_MIPI_DSI0 60
87#define CLK_MIPI_DSI1 61
88#define CLK_HDMI 62
89#define CLK_HDMI_SLOW 63
90#define CLK_MIPI_CSI 64
91#define CLK_CSI_ISP 65
92#define CLK_CSI_MISC 66
93#define CLK_CSI0_MCLK 67
94#define CLK_CSI1_MCLK 68
95#define CLK_FD 69
96#define CLK_VE 70
97#define CLK_AVS 71
98#define CLK_GPU_CORE 72
99#define CLK_GPU_MEMORY 73
100#define CLK_GPU_AXI 74
101#define CLK_SATA 75
102#define CLK_AC97 76
103#define CLK_MIPI_HSI 77
104#define CLK_GPADC 78
105#define CLK_CIR_TX 79
106
107#define CLK_BUS_FD 80
108#define CLK_BUS_VE 81
109#define CLK_BUS_GPU_CTRL 82
110#define CLK_BUS_SS 83
111#define CLK_BUS_MMC 84
112#define CLK_BUS_NAND0 85
113#define CLK_BUS_NAND1 86
114#define CLK_BUS_SDRAM 87
115#define CLK_BUS_MIPI_HSI 88
116#define CLK_BUS_SATA 89
117#define CLK_BUS_TS 90
118#define CLK_BUS_SPI0 91
119#define CLK_BUS_SPI1 92
120#define CLK_BUS_SPI2 93
121#define CLK_BUS_SPI3 94
122
123#define CLK_BUS_OTG 95
124#define CLK_BUS_USB 96
125#define CLK_BUS_GMAC 97
126#define CLK_BUS_MSGBOX 98
127#define CLK_BUS_SPINLOCK 99
128#define CLK_BUS_HSTIMER 100
129#define CLK_BUS_DMA 101
130
131#define CLK_BUS_LCD0 102
132#define CLK_BUS_LCD1 103
133#define CLK_BUS_EDP 104
134#define CLK_BUS_CSI 105
135#define CLK_BUS_HDMI 106
136#define CLK_BUS_DE 107
137#define CLK_BUS_MP 108
138#define CLK_BUS_MIPI_DSI 109
139
140#define CLK_BUS_SPDIF 110
141#define CLK_BUS_PIO 111
142#define CLK_BUS_AC97 112
143#define CLK_BUS_I2S0 113
144#define CLK_BUS_I2S1 114
145#define CLK_BUS_LRADC 115
146#define CLK_BUS_GPADC 116
147#define CLK_BUS_TWD 117
148#define CLK_BUS_CIR_TX 118
149
150#define CLK_BUS_I2C0 119
151#define CLK_BUS_I2C1 120
152#define CLK_BUS_I2C2 121
153#define CLK_BUS_I2C3 122
154#define CLK_BUS_I2C4 123
155#define CLK_BUS_UART0 124
156#define CLK_BUS_UART1 125
157#define CLK_BUS_UART2 126
158#define CLK_BUS_UART3 127
159#define CLK_BUS_UART4 128
160#define CLK_BUS_UART5 129
161
162#endif /* _DT_BINDINGS_CLOCK_SUN9I_A80_CCU_H_ */
diff --git a/include/dt-bindings/clock/sun9i-a80-de.h b/include/dt-bindings/clock/sun9i-a80-de.h
new file mode 100644
index 000000000000..3dad6c3cd131
--- /dev/null
+++ b/include/dt-bindings/clock/sun9i-a80-de.h
@@ -0,0 +1,80 @@
1/*
2 * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_CLOCK_SUN9I_A80_DE_H_
44#define _DT_BINDINGS_CLOCK_SUN9I_A80_DE_H_
45
46#define CLK_FE0 0
47#define CLK_FE1 1
48#define CLK_FE2 2
49#define CLK_IEP_DEU0 3
50#define CLK_IEP_DEU1 4
51#define CLK_BE0 5
52#define CLK_BE1 6
53#define CLK_BE2 7
54#define CLK_IEP_DRC0 8
55#define CLK_IEP_DRC1 9
56#define CLK_MERGE 10
57
58#define CLK_DRAM_FE0 11
59#define CLK_DRAM_FE1 12
60#define CLK_DRAM_FE2 13
61#define CLK_DRAM_DEU0 14
62#define CLK_DRAM_DEU1 15
63#define CLK_DRAM_BE0 16
64#define CLK_DRAM_BE1 17
65#define CLK_DRAM_BE2 18
66#define CLK_DRAM_DRC0 19
67#define CLK_DRAM_DRC1 20
68
69#define CLK_BUS_FE0 21
70#define CLK_BUS_FE1 22
71#define CLK_BUS_FE2 23
72#define CLK_BUS_DEU0 24
73#define CLK_BUS_DEU1 25
74#define CLK_BUS_BE0 26
75#define CLK_BUS_BE1 27
76#define CLK_BUS_BE2 28
77#define CLK_BUS_DRC0 29
78#define CLK_BUS_DRC1 30
79
80#endif /* _DT_BINDINGS_CLOCK_SUN9I_A80_DE_H_ */
diff --git a/include/dt-bindings/clock/sun9i-a80-usb.h b/include/dt-bindings/clock/sun9i-a80-usb.h
new file mode 100644
index 000000000000..783a60d2ccea
--- /dev/null
+++ b/include/dt-bindings/clock/sun9i-a80-usb.h
@@ -0,0 +1,59 @@
1/*
2 * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_
44#define _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_
45
46#define CLK_BUS_HCI0 0
47#define CLK_USB_OHCI0 1
48#define CLK_BUS_HCI1 2
49#define CLK_BUS_HCI2 3
50#define CLK_USB_OHCI2 4
51
52#define CLK_USB0_PHY 5
53#define CLK_USB1_HSIC 6
54#define CLK_USB1_PHY 7
55#define CLK_USB2_HSIC 8
56#define CLK_USB2_PHY 9
57#define CLK_USB_HSIC 10
58
59#endif /* _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_ */
diff --git a/include/dt-bindings/reset/sun5i-ccu.h b/include/dt-bindings/reset/sun5i-ccu.h
new file mode 100644
index 000000000000..c2b9726b5026
--- /dev/null
+++ b/include/dt-bindings/reset/sun5i-ccu.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright 2016 Maxime Ripard
3 *
4 * Maxime Ripard <maxime.ripard@free-electrons.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _RST_SUN5I_H_
18#define _RST_SUN5I_H_
19
20#define RST_USB_PHY0 0
21#define RST_USB_PHY1 1
22#define RST_GPS 2
23#define RST_DE_BE 3
24#define RST_DE_FE 4
25#define RST_TVE 5
26#define RST_LCD 6
27#define RST_CSI 7
28#define RST_VE 8
29#define RST_GPU 9
30#define RST_IEP 10
31
32#endif /* _RST_SUN5I_H_ */
diff --git a/include/dt-bindings/reset/sun8i-v3s-ccu.h b/include/dt-bindings/reset/sun8i-v3s-ccu.h
new file mode 100644
index 000000000000..b58ef21a2e18
--- /dev/null
+++ b/include/dt-bindings/reset/sun8i-v3s-ccu.h
@@ -0,0 +1,78 @@
1/*
2 * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz>
3 *
4 * Based on sun8i-v3s-ccu.h, which is
5 * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
6 *
7 * This file is dual-licensed: you can use it either under the terms
8 * of the GPL or the X11 license, at your option. Note that this dual
9 * licensing only applies to this file, and not this project as a
10 * whole.
11 *
12 * a) This file is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * This file is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * Or, alternatively,
23 *
24 * b) Permission is hereby granted, free of charge, to any person
25 * obtaining a copy of this software and associated documentation
26 * files (the "Software"), to deal in the Software without
27 * restriction, including without limitation the rights to use,
28 * copy, modify, merge, publish, distribute, sublicense, and/or
29 * sell copies of the Software, and to permit persons to whom the
30 * Software is furnished to do so, subject to the following
31 * conditions:
32 *
33 * The above copyright notice and this permission notice shall be
34 * included in all copies or substantial portions of the Software.
35 *
36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
37 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
38 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
39 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
40 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
41 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
42 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
43 * OTHER DEALINGS IN THE SOFTWARE.
44 */
45
46#ifndef _DT_BINDINGS_RST_SUN8I_V3S_H_
47#define _DT_BINDINGS_RST_SUN8I_V3S_H_
48
49#define RST_USB_PHY0 0
50
51#define RST_MBUS 1
52
53#define RST_BUS_CE 5
54#define RST_BUS_DMA 6
55#define RST_BUS_MMC0 7
56#define RST_BUS_MMC1 8
57#define RST_BUS_MMC2 9
58#define RST_BUS_DRAM 11
59#define RST_BUS_EMAC 12
60#define RST_BUS_HSTIMER 14
61#define RST_BUS_SPI0 15
62#define RST_BUS_OTG 17
63#define RST_BUS_EHCI0 18
64#define RST_BUS_OHCI0 22
65#define RST_BUS_VE 26
66#define RST_BUS_TCON0 27
67#define RST_BUS_CSI 30
68#define RST_BUS_DE 34
69#define RST_BUS_DBG 38
70#define RST_BUS_EPHY 39
71#define RST_BUS_CODEC 40
72#define RST_BUS_I2C0 46
73#define RST_BUS_I2C1 47
74#define RST_BUS_UART0 49
75#define RST_BUS_UART1 50
76#define RST_BUS_UART2 51
77
78#endif /* _DT_BINDINGS_RST_SUN8I_H3_H_ */
diff --git a/include/dt-bindings/reset/sun9i-a80-ccu.h b/include/dt-bindings/reset/sun9i-a80-ccu.h
new file mode 100644
index 000000000000..4b8df4b36788
--- /dev/null
+++ b/include/dt-bindings/reset/sun9i-a80-ccu.h
@@ -0,0 +1,102 @@
1/*
2 * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_RESET_SUN9I_A80_CCU_H_
44#define _DT_BINDINGS_RESET_SUN9I_A80_CCU_H_
45
46#define RST_BUS_FD 0
47#define RST_BUS_VE 1
48#define RST_BUS_GPU_CTRL 2
49#define RST_BUS_SS 3
50#define RST_BUS_MMC 4
51#define RST_BUS_NAND0 5
52#define RST_BUS_NAND1 6
53#define RST_BUS_SDRAM 7
54#define RST_BUS_SATA 8
55#define RST_BUS_TS 9
56#define RST_BUS_SPI0 10
57#define RST_BUS_SPI1 11
58#define RST_BUS_SPI2 12
59#define RST_BUS_SPI3 13
60
61#define RST_BUS_OTG 14
62#define RST_BUS_OTG_PHY 15
63#define RST_BUS_MIPI_HSI 16
64#define RST_BUS_GMAC 17
65#define RST_BUS_MSGBOX 18
66#define RST_BUS_SPINLOCK 19
67#define RST_BUS_HSTIMER 20
68#define RST_BUS_DMA 21
69
70#define RST_BUS_LCD0 22
71#define RST_BUS_LCD1 23
72#define RST_BUS_EDP 24
73#define RST_BUS_LVDS 25
74#define RST_BUS_CSI 26
75#define RST_BUS_HDMI0 27
76#define RST_BUS_HDMI1 28
77#define RST_BUS_DE 29
78#define RST_BUS_MP 30
79#define RST_BUS_GPU 31
80#define RST_BUS_MIPI_DSI 32
81
82#define RST_BUS_SPDIF 33
83#define RST_BUS_AC97 34
84#define RST_BUS_I2S0 35
85#define RST_BUS_I2S1 36
86#define RST_BUS_LRADC 37
87#define RST_BUS_GPADC 38
88#define RST_BUS_CIR_TX 39
89
90#define RST_BUS_I2C0 40
91#define RST_BUS_I2C1 41
92#define RST_BUS_I2C2 42
93#define RST_BUS_I2C3 43
94#define RST_BUS_I2C4 44
95#define RST_BUS_UART0 45
96#define RST_BUS_UART1 46
97#define RST_BUS_UART2 47
98#define RST_BUS_UART3 48
99#define RST_BUS_UART4 49
100#define RST_BUS_UART5 50
101
102#endif /* _DT_BINDINGS_RESET_SUN9I_A80_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun9i-a80-de.h b/include/dt-bindings/reset/sun9i-a80-de.h
new file mode 100644
index 000000000000..205072770171
--- /dev/null
+++ b/include/dt-bindings/reset/sun9i-a80-de.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_RESET_SUN9I_A80_DE_H_
44#define _DT_BINDINGS_RESET_SUN9I_A80_DE_H_
45
46#define RST_FE0 0
47#define RST_FE1 1
48#define RST_FE2 2
49#define RST_DEU0 3
50#define RST_DEU1 4
51#define RST_BE0 5
52#define RST_BE1 6
53#define RST_BE2 7
54#define RST_DRC0 8
55#define RST_DRC1 9
56#define RST_MERGE 10
57
58#endif /* _DT_BINDINGS_RESET_SUN9I_A80_DE_H_ */
diff --git a/include/dt-bindings/reset/sun9i-a80-usb.h b/include/dt-bindings/reset/sun9i-a80-usb.h
new file mode 100644
index 000000000000..ee492864c2aa
--- /dev/null
+++ b/include/dt-bindings/reset/sun9i-a80-usb.h
@@ -0,0 +1,56 @@
1/*
2 * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_RESET_SUN9I_A80_USB_H_
44#define _DT_BINDINGS_RESET_SUN9I_A80_USB_H_
45
46#define RST_USB0_HCI 0
47#define RST_USB1_HCI 1
48#define RST_USB2_HCI 2
49
50#define RST_USB0_PHY 3
51#define RST_USB1_HSIC 4
52#define RST_USB1_PHY 5
53#define RST_USB2_HSIC 6
54#define RST_USB2_PHY 7
55
56#endif /* _DT_BINDINGS_RESET_SUN9I_A80_USB_H_ */
diff --git a/include/linux/platform_data/x86/clk-pmc-atom.h b/include/linux/platform_data/x86/clk-pmc-atom.h
new file mode 100644
index 000000000000..3ab892208343
--- /dev/null
+++ b/include/linux/platform_data/x86/clk-pmc-atom.h
@@ -0,0 +1,44 @@
1/*
2 * Intel Atom platform clocks for BayTrail and CherryTrail SoC.
3 *
4 * Copyright (C) 2016, Intel Corporation
5 * Author: Irina Tirdea <irina.tirdea@intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 */
16
17#ifndef __PLATFORM_DATA_X86_CLK_PMC_ATOM_H
18#define __PLATFORM_DATA_X86_CLK_PMC_ATOM_H
19
20/**
21 * struct pmc_clk - PMC platform clock configuration
22 *
23 * @name: identified, typically pmc_plt_clk_<x>, x=[0..5]
24 * @freq: in Hz, 19.2MHz and 25MHz (Baytrail only) supported
25 * @parent_name: one of 'xtal' or 'osc'
26 */
27struct pmc_clk {
28 const char *name;
29 unsigned long freq;
30 const char *parent_name;
31};
32
33/**
34 * struct pmc_clk_data - common PMC clock configuration
35 *
36 * @base: PMC clock register base offset
37 * @clks: pointer to set of registered clocks, typically 0..5
38 */
39struct pmc_clk_data {
40 void __iomem *base;
41 const struct pmc_clk *clks;
42};
43
44#endif /* __PLATFORM_DATA_X86_CLK_PMC_ATOM_H */
diff --git a/arch/x86/include/asm/pmc_atom.h b/include/linux/platform_data/x86/pmc_atom.h
index aa8744c77c6d..e4905fe69c38 100644
--- a/arch/x86/include/asm/pmc_atom.h
+++ b/include/linux/platform_data/x86/pmc_atom.h
@@ -50,7 +50,7 @@
50 BIT_ORED_DEDICATED_IRQ_GPSC | \ 50 BIT_ORED_DEDICATED_IRQ_GPSC | \
51 BIT_SHARED_IRQ_GPSS) 51 BIT_SHARED_IRQ_GPSS)
52 52
53/* The timers acumulate time spent in sleep state */ 53/* The timers accumulate time spent in sleep state */
54#define PMC_S0IR_TMR 0x80 54#define PMC_S0IR_TMR 0x80
55#define PMC_S0I1_TMR 0x84 55#define PMC_S0I1_TMR 0x84
56#define PMC_S0I2_TMR 0x88 56#define PMC_S0I2_TMR 0x88