aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-05 15:59:36 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-05 15:59:36 -0500
commitf66477a0aeb77f97a7de5f791700dadc42f3f792 (patch)
tree0a49febcf211c33948be618860eb3d545b7c6608
parent400c5bd5a5b1faf3089322ace58b974446a8ddc3 (diff)
parente5bf1991ea62b4f4fc906d0828f7eed988fc3835 (diff)
Merge tag 'clk-for-linus-20151104' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd: "The majority of the changes are driver updates and new device support. The core framework is mostly unchanged this time around, with only a couple patches to expose a clk provider API and make getting clk parent names from DT more robust. Driver updates: - Support for clock controllers found on Broadcom Northstar SoCs and bcm2835 SoC - Support for Allwinner audio clocks - A few cleanup patches for Tegra drivers and support for the highest DFLL frequencies on Tegra124 - Samsung exynos7 fixes and improvements - i.Mx SoC updates to add a few missing clocks and keep debug uart clocks on during kernel intialization - Some mediatek cleanups and support for more subsystem clocks - Support for msm8916 gpu/audio clocks and qcom's GDSC power domain controllers - A new driver for the Silabs si514 clock chip" * tag 'clk-for-linus-20151104' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (143 commits) clk: qcom: msm8960: Fix dsi1/2 halt bits clk: lpc18xx-cgu: fix potential system hang when disabling unused clocks clk: lpc18xx-ccu: fix potential system hang when disabling unused clocks clk: Add clk_hw_is_enabled() for use by clk providers clk: Add stubs for of_clk_*() APIs when CONFIG_OF=n clk: versatile-icst: fix memory leak clk: Remove clk_{register,unregister}_multiplier() clk: iproc: define Broadcom NS2 iProc clock binding clk: iproc: define Broadcom NSP iProc clock binding clk: ns2: add clock support for Broadcom Northstar 2 SoC clk: iproc: Separate status and control variables clk: iproc: Split off dig_filter clk: iproc: Add PLL base write function clk: nsp: add clock support for Broadcom Northstar Plus SoC clk: iproc: Add PWRCTRL support clk: cygnus: Convert all macros to all caps ARM: cygnus: fix link failures when CONFIG_COMMON_CLK_IPROC is disabled clk: imx31: add missing of_node_put clk: imx27: add missing of_node_put clk: si5351: add missing of_node_put ...
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt22
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt22
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt22
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt22
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt22
-rw-r--r--Documentation/devicetree/bindings/clock/at91-clock.txt35
-rw-r--r--Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt45
-rw-r--r--Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt78
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt69
-rw-r--r--Documentation/devicetree/bindings/clock/silabs,si514.txt24
-rw-r--r--Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt1
-rw-r--r--arch/arm/mach-at91/Kconfig3
-rw-r--r--arch/arm/mach-bcm/Kconfig2
-rw-r--r--drivers/base/power/domain.c2
-rw-r--r--drivers/clk/Kconfig19
-rw-r--r--drivers/clk/Makefile5
-rw-r--r--drivers/clk/at91/Makefile1
-rw-r--r--drivers/clk/at91/clk-generated.c306
-rw-r--r--drivers/clk/at91/clk-peripheral.c24
-rw-r--r--drivers/clk/at91/clk-system.c3
-rw-r--r--drivers/clk/at91/clk-utmi.c4
-rw-r--r--drivers/clk/at91/pmc.c21
-rw-r--r--drivers/clk/at91/pmc.h3
-rw-r--r--drivers/clk/bcm/Kconfig6
-rw-r--r--drivers/clk/bcm/Makefile4
-rw-r--r--drivers/clk/bcm/clk-bcm2835.c1575
-rw-r--r--drivers/clk/bcm/clk-cygnus.c155
-rw-r--r--drivers/clk/bcm/clk-iproc-pll.c196
-rw-r--r--drivers/clk/bcm/clk-iproc.h22
-rw-r--r--drivers/clk/bcm/clk-ns2.c288
-rw-r--r--drivers/clk/bcm/clk-nsp.c139
-rw-r--r--drivers/clk/berlin/bg2.c4
-rw-r--r--drivers/clk/berlin/bg2q.c2
-rw-r--r--drivers/clk/clk-bcm2835.c55
-rw-r--r--drivers/clk/clk-divider.c20
-rw-r--r--drivers/clk/clk-fractional-divider.c53
-rw-r--r--drivers/clk/clk-max77802.c2
-rw-r--r--drivers/clk/clk-multiplier.c130
-rw-r--r--drivers/clk/clk-si514.c379
-rw-r--r--drivers/clk/clk-si5351.c17
-rw-r--r--drivers/clk/clk-xgene.c1
-rw-r--r--drivers/clk/clk.c38
-rw-r--r--drivers/clk/hisilicon/clk-hi6220-stub.c2
-rw-r--r--drivers/clk/imx/clk-imx25.c12
-rw-r--r--drivers/clk/imx/clk-imx27.c17
-rw-r--r--drivers/clk/imx/clk-imx31.c39
-rw-r--r--drivers/clk/imx/clk-imx35.c59
-rw-r--r--drivers/clk/imx/clk-imx51-imx53.c16
-rw-r--r--drivers/clk/imx/clk-imx6q.c12
-rw-r--r--drivers/clk/imx/clk-imx6sl.c12
-rw-r--r--drivers/clk/imx/clk-imx6sx.c9
-rw-r--r--drivers/clk/imx/clk-imx6ul.c18
-rw-r--r--drivers/clk/imx/clk-imx7d.c14
-rw-r--r--drivers/clk/imx/clk-pllv2.c12
-rw-r--r--drivers/clk/imx/clk-vf610.c1
-rw-r--r--drivers/clk/imx/clk.c38
-rw-r--r--drivers/clk/imx/clk.h1
-rw-r--r--drivers/clk/keystone/pll.c2
-rw-r--r--drivers/clk/mediatek/Makefile2
-rw-r--r--drivers/clk/mediatek/clk-apmixed.c107
-rw-r--r--drivers/clk/mediatek/clk-gate.c2
-rw-r--r--drivers/clk/mediatek/clk-mt8173.c347
-rw-r--r--drivers/clk/mediatek/clk-mtk.c36
-rw-r--r--drivers/clk/mediatek/clk-mtk.h24
-rw-r--r--drivers/clk/mediatek/clk-pll.c7
-rw-r--r--drivers/clk/mvebu/clk-cpu.c4
-rw-r--r--drivers/clk/mvebu/common.c2
-rw-r--r--drivers/clk/mxs/clk-frac.c12
-rw-r--r--drivers/clk/nxp/clk-lpc18xx-ccu.c17
-rw-r--r--drivers/clk/nxp/clk-lpc18xx-cgu.c42
-rw-r--r--drivers/clk/qcom/Kconfig9
-rw-r--r--drivers/clk/qcom/Makefile1
-rw-r--r--drivers/clk/qcom/clk-rcg.c230
-rw-r--r--drivers/clk/qcom/clk-rcg.h8
-rw-r--r--drivers/clk/qcom/clk-rcg2.c170
-rw-r--r--drivers/clk/qcom/common.c42
-rw-r--r--drivers/clk/qcom/common.h4
-rw-r--r--drivers/clk/qcom/gcc-apq8084.c49
-rw-r--r--drivers/clk/qcom/gcc-ipq806x.c7
-rw-r--r--drivers/clk/qcom/gcc-msm8660.c7
-rw-r--r--drivers/clk/qcom/gcc-msm8916.c569
-rw-r--r--drivers/clk/qcom/gcc-msm8960.c20
-rw-r--r--drivers/clk/qcom/gcc-msm8974.c22
-rw-r--r--drivers/clk/qcom/gdsc.c237
-rw-r--r--drivers/clk/qcom/gdsc.h68
-rw-r--r--drivers/clk/qcom/lcc-ipq806x.c7
-rw-r--r--drivers/clk/qcom/lcc-msm8960.c7
-rw-r--r--drivers/clk/qcom/mmcc-apq8084.c111
-rw-r--r--drivers/clk/qcom/mmcc-msm8960.c411
-rw-r--r--drivers/clk/qcom/mmcc-msm8974.c92
-rw-r--r--drivers/clk/rockchip/clk-mmc-phase.c11
-rw-r--r--drivers/clk/rockchip/clk-pll.c135
-rw-r--r--drivers/clk/rockchip/clk.c6
-rw-r--r--drivers/clk/samsung/clk-exynos7.c467
-rw-r--r--drivers/clk/shmobile/clk-mstp.c2
-rw-r--r--drivers/clk/shmobile/clk-r8a7778.c8
-rw-r--r--drivers/clk/sirf/clk-atlas7.c358
-rw-r--r--drivers/clk/st/clk-flexgen.c7
-rw-r--r--drivers/clk/st/clkgen-mux.c3
-rw-r--r--drivers/clk/st/clkgen-pll.c469
-rw-r--r--drivers/clk/st/clkgen.h2
-rw-r--r--drivers/clk/sunxi/Makefile3
-rw-r--r--drivers/clk/sunxi/clk-a10-codec.c44
-rw-r--r--drivers/clk/sunxi/clk-a10-mod1.c81
-rw-r--r--drivers/clk/sunxi/clk-a10-pll2.c216
-rw-r--r--drivers/clk/sunxi/clk-simple-gates.c2
-rw-r--r--drivers/clk/sunxi/clk-sun6i-apb0-gates.c1
-rw-r--r--drivers/clk/sunxi/clk-sun6i-apb0.c1
-rw-r--r--drivers/clk/sunxi/clk-sun6i-ar100.c1
-rw-r--r--drivers/clk/sunxi/clk-sun8i-apb0.c1
-rw-r--r--drivers/clk/sunxi/clk-sun9i-mmc.c1
-rw-r--r--drivers/clk/tegra/clk-dfll.c114
-rw-r--r--drivers/clk/tegra/clk-emc.c4
-rw-r--r--drivers/clk/tegra/clk-tegra-audio.c25
-rw-r--r--drivers/clk/tegra/clk-tegra114.c8
-rw-r--r--drivers/clk/tegra/clk-tegra124.c8
-rw-r--r--drivers/clk/tegra/clk-tegra30.c8
-rw-r--r--drivers/clk/tegra/clk.h106
-rw-r--r--drivers/clk/tegra/cvb.c7
-rw-r--r--drivers/clk/versatile/Kconfig2
-rw-r--r--drivers/clk/versatile/clk-icst.c4
-rw-r--r--drivers/tty/serial/8250/8250_dw.c4
-rw-r--r--include/dt-bindings/clock/at91.h1
-rw-r--r--include/dt-bindings/clock/bcm-ns2.h72
-rw-r--r--include/dt-bindings/clock/bcm-nsp.h51
-rw-r--r--include/dt-bindings/clock/bcm2835.h47
-rw-r--r--include/dt-bindings/clock/exynos7-clk.h43
-rw-r--r--include/dt-bindings/clock/imx6qdl-clock.h3
-rw-r--r--include/dt-bindings/clock/imx6sl-clock.h3
-rw-r--r--include/dt-bindings/clock/imx6sx-clock.h3
-rw-r--r--include/dt-bindings/clock/imx7d-clock.h3
-rw-r--r--include/dt-bindings/clock/mt8173-clk.h104
-rw-r--r--include/dt-bindings/clock/qcom,gcc-apq8084.h6
-rw-r--r--include/dt-bindings/clock/qcom,gcc-msm8916.h30
-rw-r--r--include/dt-bindings/clock/qcom,gcc-msm8974.h3
-rw-r--r--include/dt-bindings/clock/qcom,mmcc-apq8084.h10
-rw-r--r--include/dt-bindings/clock/qcom,mmcc-msm8974.h8
-rw-r--r--include/dt-bindings/clock/r8a7795-cpg-mssr.h63
-rw-r--r--include/dt-bindings/clock/renesas-cpg-mssr.h15
-rw-r--r--include/dt-bindings/clock/sun4i-a10-pll2.h53
-rw-r--r--include/dt-bindings/clock/vf610-clock.h3
-rw-r--r--include/linux/clk-provider.h50
-rw-r--r--include/linux/clk/at91_pmc.h22
144 files changed, 8452 insertions, 1030 deletions
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
new file mode 100644
index 000000000000..b1f2ce17dff8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
@@ -0,0 +1,22 @@
1Mediatek imgsys controller
2============================
3
4The Mediatek imgsys controller provides various clocks to the system.
5
6Required Properties:
7
8- compatible: Should be:
9 - "mediatek,mt8173-imgsys", "syscon"
10- #clock-cells: Must be 1
11
12The imgsys controller uses the common clk binding from
13Documentation/devicetree/bindings/clock/clock-bindings.txt
14The available clocks are defined in dt-bindings/clock/mt*-clk.h.
15
16Example:
17
18imgsys: clock-controller@15000000 {
19 compatible = "mediatek,mt8173-imgsys", "syscon";
20 reg = <0 0x15000000 0 0x1000>;
21 #clock-cells = <1>;
22};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
new file mode 100644
index 000000000000..4385946eadef
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
@@ -0,0 +1,22 @@
1Mediatek mmsys controller
2============================
3
4The Mediatek mmsys controller provides various clocks to the system.
5
6Required Properties:
7
8- compatible: Should be:
9 - "mediatek,mt8173-mmsys", "syscon"
10- #clock-cells: Must be 1
11
12The mmsys controller uses the common clk binding from
13Documentation/devicetree/bindings/clock/clock-bindings.txt
14The available clocks are defined in dt-bindings/clock/mt*-clk.h.
15
16Example:
17
18mmsys: clock-controller@14000000 {
19 compatible = "mediatek,mt8173-mmsys", "syscon";
20 reg = <0 0x14000000 0 0x1000>;
21 #clock-cells = <1>;
22};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
new file mode 100644
index 000000000000..1faacf1c1b25
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
@@ -0,0 +1,22 @@
1Mediatek vdecsys controller
2============================
3
4The Mediatek vdecsys controller provides various clocks to the system.
5
6Required Properties:
7
8- compatible: Should be:
9 - "mediatek,mt8173-vdecsys", "syscon"
10- #clock-cells: Must be 1
11
12The vdecsys controller uses the common clk binding from
13Documentation/devicetree/bindings/clock/clock-bindings.txt
14The available clocks are defined in dt-bindings/clock/mt*-clk.h.
15
16Example:
17
18vdecsys: clock-controller@16000000 {
19 compatible = "mediatek,mt8173-vdecsys", "syscon";
20 reg = <0 0x16000000 0 0x1000>;
21 #clock-cells = <1>;
22};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
new file mode 100644
index 000000000000..3cc299fd7857
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
@@ -0,0 +1,22 @@
1Mediatek vencltsys controller
2============================
3
4The Mediatek vencltsys controller provides various clocks to the system.
5
6Required Properties:
7
8- compatible: Should be:
9 - "mediatek,mt8173-vencltsys", "syscon"
10- #clock-cells: Must be 1
11
12The vencltsys controller uses the common clk binding from
13Documentation/devicetree/bindings/clock/clock-bindings.txt
14The available clocks are defined in dt-bindings/clock/mt*-clk.h.
15
16Example:
17
18vencltsys: clock-controller@19000000 {
19 compatible = "mediatek,mt8173-vencltsys", "syscon";
20 reg = <0 0x19000000 0 0x1000>;
21 #clock-cells = <1>;
22};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
new file mode 100644
index 000000000000..5bb2866a2b50
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
@@ -0,0 +1,22 @@
1Mediatek vencsys controller
2============================
3
4The Mediatek vencsys controller provides various clocks to the system.
5
6Required Properties:
7
8- compatible: Should be:
9 - "mediatek,mt8173-vencsys", "syscon"
10- #clock-cells: Must be 1
11
12The vencsys controller uses the common clk binding from
13Documentation/devicetree/bindings/clock/clock-bindings.txt
14The available clocks are defined in dt-bindings/clock/mt*-clk.h.
15
16Example:
17
18vencsys: clock-controller@18000000 {
19 compatible = "mediatek,mt8173-vencsys", "syscon";
20 reg = <0 0x18000000 0 0x1000>;
21 #clock-cells = <1>;
22};
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt
index 5ba6450693b9..181bc8ac4e3a 100644
--- a/Documentation/devicetree/bindings/clock/at91-clock.txt
+++ b/Documentation/devicetree/bindings/clock/at91-clock.txt
@@ -77,6 +77,9 @@ Required properties:
77 "atmel,sama5d4-clk-h32mx": 77 "atmel,sama5d4-clk-h32mx":
78 at91 h32mx clock 78 at91 h32mx clock
79 79
80 "atmel,sama5d2-clk-generated":
81 at91 generated clock
82
80Required properties for SCKC node: 83Required properties for SCKC node:
81- reg : defines the IO memory reserved for the SCKC. 84- reg : defines the IO memory reserved for the SCKC.
82- #size-cells : shall be 0 (reg is used to encode clk id). 85- #size-cells : shall be 0 (reg is used to encode clk id).
@@ -461,3 +464,35 @@ For example:
461 compatible = "atmel,sama5d4-clk-h32mx"; 464 compatible = "atmel,sama5d4-clk-h32mx";
462 clocks = <&mck>; 465 clocks = <&mck>;
463 }; 466 };
467
468Required properties for generated clocks:
469- #size-cells : shall be 0 (reg is used to encode clk id).
470- #address-cells : shall be 1 (reg is used to encode clk id).
471- clocks : shall be the generated clock source phandles.
472 e.g. clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>;
473- name: device tree node describing a specific generated clock.
474 * #clock-cells : from common clock binding; shall be set to 0.
475 * reg: peripheral id. See Atmel's datasheets to get a full
476 list of peripheral ids.
477 * atmel,clk-output-range : minimum and maximum clock frequency
478 (two u32 fields).
479
480For example:
481 gck {
482 compatible = "atmel,sama5d2-clk-generated";
483 #address-cells = <1>;
484 #size-cells = <0>;
485 clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>;
486
487 tcb0_gclk: tcb0_gclk {
488 #clock-cells = <0>;
489 reg = <35>;
490 atmel,clk-output-range = <0 83000000>;
491 };
492
493 pwm_gclk: pwm_gclk {
494 #clock-cells = <0>;
495 reg = <38>;
496 atmel,clk-output-range = <0 83000000>;
497 };
498 };
diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
new file mode 100644
index 000000000000..e56a1df3a9d3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
@@ -0,0 +1,45 @@
1Broadcom BCM2835 CPRMAN clocks
2
3This binding uses the common clock binding:
4 Documentation/devicetree/bindings/clock/clock-bindings.txt
5
6The CPRMAN clock controller generates clocks in the audio power domain
7of the BCM2835. There is a level of PLLs deriving from an external
8oscillator, a level of PLL dividers that produce channels off of the
9few PLLs, and a level of mostly-generic clock generators sourcing from
10the PLL channels. Most other hardware components source from the
11clock generators, but a few (like the ARM or HDMI) will source from
12the PLL dividers directly.
13
14Required properties:
15- compatible: Should be "brcm,bcm2835-cprman"
16- #clock-cells: Should be <1>. The permitted clock-specifier values can be
17 found in include/dt-bindings/clock/bcm2835.h
18- reg: Specifies base physical address and size of the registers
19- clocks: The external oscillator clock phandle
20
21Example:
22
23 clk_osc: clock@3 {
24 compatible = "fixed-clock";
25 reg = <3>;
26 #clock-cells = <0>;
27 clock-output-names = "osc";
28 clock-frequency = <19200000>;
29 };
30
31 clocks: cprman@7e101000 {
32 compatible = "brcm,bcm2835-cprman";
33 #clock-cells = <1>;
34 reg = <0x7e101000 0x2000>;
35 clocks = <&clk_osc>;
36 };
37
38 i2c0: i2c@7e205000 {
39 compatible = "brcm,bcm2835-i2c";
40 reg = <0x7e205000 0x1000>;
41 interrupts = <2 21>;
42 clocks = <&clocks BCM2835_CLOCK_VPU>;
43 #address-cells = <1>;
44 #size-cells = <0>;
45 };
diff --git a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt
index da8d9bb5751c..ede65a55e21b 100644
--- a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt
@@ -130,3 +130,81 @@ These clock IDs are defined in:
130 ch3_unused mipipll 4 BCM_CYGNUS_MIPIPLL_CH3_UNUSED 130 ch3_unused mipipll 4 BCM_CYGNUS_MIPIPLL_CH3_UNUSED
131 ch4_unused mipipll 5 BCM_CYGNUS_MIPIPLL_CH4_UNUSED 131 ch4_unused mipipll 5 BCM_CYGNUS_MIPIPLL_CH4_UNUSED
132 ch5_unused mipipll 6 BCM_CYGNUS_MIPIPLL_CH5_UNUSED 132 ch5_unused mipipll 6 BCM_CYGNUS_MIPIPLL_CH5_UNUSED
133
134Northstar and Northstar Plus
135------
136PLL and leaf clock compatible strings for Northstar and Northstar Plus are:
137 "brcm,nsp-armpll"
138 "brcm,nsp-genpll"
139 "brcm,nsp-lcpll0"
140
141The following table defines the set of PLL/clock index and ID for Northstar and
142Northstar Plus. These clock IDs are defined in:
143 "include/dt-bindings/clock/bcm-nsp.h"
144
145 Clock Source Index ID
146 --- ----- ----- ---------
147 crystal N/A N/A N/A
148
149 armpll crystal N/A N/A
150
151 genpll crystal 0 BCM_NSP_GENPLL
152 phy genpll 1 BCM_NSP_GENPLL_PHY_CLK
153 ethernetclk genpll 2 BCM_NSP_GENPLL_ENET_SW_CLK
154 usbclk genpll 3 BCM_NSP_GENPLL_USB_PHY_REF_CLK
155 iprocfast genpll 4 BCM_NSP_GENPLL_IPROCFAST_CLK
156 sata1 genpll 5 BCM_NSP_GENPLL_SATA1_CLK
157 sata2 genpll 6 BCM_NSP_GENPLL_SATA2_CLK
158
159 lcpll0 crystal 0 BCM_NSP_LCPLL0
160 pcie_phy lcpll0 1 BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK
161 sdio lcpll0 2 BCM_NSP_LCPLL0_SDIO_CLK
162 ddr_phy lcpll0 3 BCM_NSP_LCPLL0_DDR_PHY_CLK
163
164Northstar 2
165-----------
166PLL and leaf clock compatible strings for Northstar 2 are:
167 "brcm,ns2-genpll-scr"
168 "brcm,ns2-genpll-sw"
169 "brcm,ns2-lcpll-ddr"
170 "brcm,ns2-lcpll-ports"
171
172The following table defines the set of PLL/clock index and ID for Northstar 2.
173These clock IDs are defined in:
174 "include/dt-bindings/clock/bcm-ns2.h"
175
176 Clock Source Index ID
177 --- ----- ----- ---------
178 crystal N/A N/A N/A
179
180 genpll_scr crystal 0 BCM_NS2_GENPLL_SCR
181 scr genpll_scr 1 BCM_NS2_GENPLL_SCR_SCR_CLK
182 fs genpll_scr 2 BCM_NS2_GENPLL_SCR_FS_CLK
183 audio_ref genpll_scr 3 BCM_NS2_GENPLL_SCR_AUDIO_CLK
184 ch3_unused genpll_scr 4 BCM_NS2_GENPLL_SCR_CH3_UNUSED
185 ch4_unused genpll_scr 5 BCM_NS2_GENPLL_SCR_CH4_UNUSED
186 ch5_unused genpll_scr 6 BCM_NS2_GENPLL_SCR_CH5_UNUSED
187
188 genpll_sw crystal 0 BCM_NS2_GENPLL_SW
189 rpe genpll_sw 1 BCM_NS2_GENPLL_SW_RPE_CLK
190 250 genpll_sw 2 BCM_NS2_GENPLL_SW_250_CLK
191 nic genpll_sw 3 BCM_NS2_GENPLL_SW_NIC_CLK
192 chimp genpll_sw 4 BCM_NS2_GENPLL_SW_CHIMP_CLK
193 port genpll_sw 5 BCM_NS2_GENPLL_SW_PORT_CLK
194 sdio genpll_sw 6 BCM_NS2_GENPLL_SW_SDIO_CLK
195
196 lcpll_ddr crystal 0 BCM_NS2_LCPLL_DDR
197 pcie_sata_usb lcpll_ddr 1 BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK
198 ddr lcpll_ddr 2 BCM_NS2_LCPLL_DDR_DDR_CLK
199 ch2_unused lcpll_ddr 3 BCM_NS2_LCPLL_DDR_CH2_UNUSED
200 ch3_unused lcpll_ddr 4 BCM_NS2_LCPLL_DDR_CH3_UNUSED
201 ch4_unused lcpll_ddr 5 BCM_NS2_LCPLL_DDR_CH4_UNUSED
202 ch5_unused lcpll_ddr 6 BCM_NS2_LCPLL_DDR_CH5_UNUSED
203
204 lcpll_ports crystal 0 BCM_NS2_LCPLL_PORTS
205 wan lcpll_ports 1 BCM_NS2_LCPLL_PORTS_WAN_CLK
206 rgmii lcpll_ports 2 BCM_NS2_LCPLL_PORTS_RGMII_CLK
207 ch2_unused lcpll_ports 3 BCM_NS2_LCPLL_PORTS_CH2_UNUSED
208 ch3_unused lcpll_ports 4 BCM_NS2_LCPLL_PORTS_CH3_UNUSED
209 ch4_unused lcpll_ports 5 BCM_NS2_LCPLL_PORTS_CH4_UNUSED
210 ch5_unused lcpll_ports 6 BCM_NS2_LCPLL_PORTS_CH5_UNUSED
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
index 5ddb68418655..38dcf0370143 100644
--- a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
@@ -1,7 +1,7 @@
1* Renesas CPG DIV6 Clock 1* Renesas CPG DIV6 Clock
2 2
3The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse 3The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse
4Generator (CPG). They clock input is divided by a configurable factor from 1 4Generator (CPG). Their clock input is divided by a configurable factor from 1
5to 64. 5to 64.
6 6
7Required Properties: 7Required Properties:
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
new file mode 100644
index 000000000000..59297d34b208
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
@@ -0,0 +1,69 @@
1* Renesas Clock Pulse Generator / Module Standby and Software Reset
2
3On Renesas ARM SoCs (SH/R-Mobile, R-Car, RZ), the CPG (Clock Pulse Generator)
4and MSSR (Module Standby and Software Reset) blocks are intimately connected,
5and share the same register block.
6
7They provide the following functionalities:
8 - The CPG block generates various core clocks,
9 - The MSSR block provides two functions:
10 1. Module Standby, providing a Clock Domain to control the clock supply
11 to individual SoC devices,
12 2. Reset Control, to perform a software reset of individual SoC devices.
13
14Required Properties:
15 - compatible: Must be one of:
16 - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC
17
18 - reg: Base address and length of the memory resource used by the CPG/MSSR
19 block
20
21 - clocks: References to external parent clocks, one entry for each entry in
22 clock-names
23 - clock-names: List of external parent clock names. Valid names are:
24 - "extal" (r8a7795)
25 - "extalr" (r8a7795)
26
27 - #clock-cells: Must be 2
28 - For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
29 and a core clock reference, as defined in
30 <dt-bindings/clock/*-cpg-mssr.h>.
31 - For module clocks, the two clock specifier cells must be "CPG_MOD" and
32 a module number, as defined in the datasheet.
33
34 - #power-domain-cells: Must be 0
35 - SoC devices that are part of the CPG/MSSR Clock Domain and can be
36 power-managed through Module Standby should refer to the CPG device
37 node in their "power-domains" property, as documented by the generic PM
38 Domain bindings in
39 Documentation/devicetree/bindings/power/power_domain.txt.
40
41
42Examples
43--------
44
45 - CPG device node:
46
47 cpg: clock-controller@e6150000 {
48 compatible = "renesas,r8a7795-cpg-mssr";
49 reg = <0 0xe6150000 0 0x1000>;
50 clocks = <&extal_clk>, <&extalr_clk>;
51 clock-names = "extal", "extalr";
52 #clock-cells = <2>;
53 #power-domain-cells = <0>;
54 };
55
56
57 - CPG/MSSR Clock Domain member device node:
58
59 scif2: serial@e6e88000 {
60 compatible = "renesas,scif-r8a7795", "renesas,scif";
61 reg = <0 0xe6e88000 0 64>;
62 interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
63 clocks = <&cpg CPG_MOD 310>;
64 clock-names = "sci_ick";
65 dmas = <&dmac1 0x13>, <&dmac1 0x12>;
66 dma-names = "tx", "rx";
67 power-domains = <&cpg>;
68 status = "disabled";
69 };
diff --git a/Documentation/devicetree/bindings/clock/silabs,si514.txt b/Documentation/devicetree/bindings/clock/silabs,si514.txt
new file mode 100644
index 000000000000..ea1a9dbc63b6
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/silabs,si514.txt
@@ -0,0 +1,24 @@
1Binding for Silicon Labs 514 programmable I2C clock generator.
2
3Reference
4This binding uses the common clock binding[1]. Details about the device can be
5found in the datasheet[2].
6
7[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
8[2] Si514 datasheet
9 http://www.silabs.com/Support%20Documents/TechnicalDocs/si514.pdf
10
11Required properties:
12 - compatible: Shall be "silabs,si514"
13 - reg: I2C device address.
14 - #clock-cells: From common clock bindings: Shall be 0.
15
16Optional properties:
17 - clock-output-names: From common clock bindings. Recommended to be "si514".
18
19Example:
20 si514: clock-generator@55 {
21 reg = <0x55>;
22 #clock-cells = <0>;
23 compatible = "silabs,si514";
24 };
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
index d8b168ebd5f1..844b3a0976bf 100644
--- a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
+++ b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
@@ -23,6 +23,7 @@ Required properties:
23 "st,stih407-plls-c32-a9", "st,clkgen-plls-c32" 23 "st,stih407-plls-c32-a9", "st,clkgen-plls-c32"
24 "sst,plls-c32-cx_0", "st,clkgen-plls-c32" 24 "sst,plls-c32-cx_0", "st,clkgen-plls-c32"
25 "sst,plls-c32-cx_1", "st,clkgen-plls-c32" 25 "sst,plls-c32-cx_1", "st,clkgen-plls-c32"
26 "st,stih418-plls-c28-a9", "st,clkgen-plls-c32"
26 27
27 "st,stih415-gpu-pll-c32", "st,clkgengpu-pll-c32" 28 "st,stih415-gpu-pll-c32", "st,clkgengpu-pll-c32"
28 "st,stih416-gpu-pll-c32", "st,clkgengpu-pll-c32" 29 "st,stih416-gpu-pll-c32", "st,clkgengpu-pll-c32"
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 89a755b90db2..92673006e55c 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -102,6 +102,9 @@ config HAVE_AT91_SMD
102config HAVE_AT91_H32MX 102config HAVE_AT91_H32MX
103 bool 103 bool
104 104
105config HAVE_AT91_GENERATED_CLK
106 bool
107
105config SOC_SAM_V4_V5 108config SOC_SAM_V4_V5
106 bool 109 bool
107 110
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 1319c3c14327..84bd26535ae9 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -14,7 +14,7 @@ config ARCH_BCM_IPROC
14 select HAVE_ARM_SCU if SMP 14 select HAVE_ARM_SCU if SMP
15 select HAVE_ARM_TWD if SMP 15 select HAVE_ARM_TWD if SMP
16 select ARM_GLOBAL_TIMER 16 select ARM_GLOBAL_TIMER
17 17 select COMMON_CLK_IPROC
18 select CLKSRC_MMIO 18 select CLKSRC_MMIO
19 select ARCH_REQUIRE_GPIOLIB 19 select ARCH_REQUIRE_GPIOLIB
20 select ARM_AMBA 20 select ARM_AMBA
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index a7dfdf9f15ba..80e298870388 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1353,6 +1353,7 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
1353 1353
1354 return ret; 1354 return ret;
1355} 1355}
1356EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain);
1356 1357
1357/** 1358/**
1358 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain. 1359 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
@@ -1400,6 +1401,7 @@ out:
1400 1401
1401 return ret; 1402 return ret;
1402} 1403}
1404EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
1403 1405
1404/* Default device callbacks for generic PM domains. */ 1406/* Default device callbacks for generic PM domains. */
1405 1407
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 42f7120ca9ce..57316528e924 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -14,6 +14,7 @@ config COMMON_CLK
14 select HAVE_CLK_PREPARE 14 select HAVE_CLK_PREPARE
15 select CLKDEV_LOOKUP 15 select CLKDEV_LOOKUP
16 select SRCU 16 select SRCU
17 select RATIONAL
17 ---help--- 18 ---help---
18 The common clock framework is a single definition of struct 19 The common clock framework is a single definition of struct
19 clk, useful across many platforms, as well as an 20 clk, useful across many platforms, as well as an
@@ -68,6 +69,16 @@ config COMMON_CLK_SI5351
68 This driver supports Silicon Labs 5351A/B/C programmable clock 69 This driver supports Silicon Labs 5351A/B/C programmable clock
69 generators. 70 generators.
70 71
72config COMMON_CLK_SI514
73 tristate "Clock driver for SiLabs 514 devices"
74 depends on I2C
75 depends on OF
76 select REGMAP_I2C
77 help
78 ---help---
79 This driver supports the Silicon Labs 514 programmable clock
80 generator.
81
71config COMMON_CLK_SI570 82config COMMON_CLK_SI570
72 tristate "Clock driver for SiLabs 570 and compatible devices" 83 tristate "Clock driver for SiLabs 570 and compatible devices"
73 depends on I2C 84 depends on I2C
@@ -113,7 +124,7 @@ config CLK_TWL6040
113 124
114config COMMON_CLK_AXI_CLKGEN 125config COMMON_CLK_AXI_CLKGEN
115 tristate "AXI clkgen driver" 126 tristate "AXI clkgen driver"
116 depends on ARCH_ZYNQ || MICROBLAZE 127 depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
117 help 128 help
118 ---help--- 129 ---help---
119 Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx 130 Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
@@ -121,7 +132,7 @@ config COMMON_CLK_AXI_CLKGEN
121 132
122config CLK_QORIQ 133config CLK_QORIQ
123 bool "Clock driver for Freescale QorIQ platforms" 134 bool "Clock driver for Freescale QorIQ platforms"
124 depends on (PPC_E500MC || ARM) && OF 135 depends on (PPC_E500MC || ARM || COMPILE_TEST) && OF
125 ---help--- 136 ---help---
126 This adds the clock driver support for Freescale QorIQ platforms 137 This adds the clock driver support for Freescale QorIQ platforms
127 using common clock framework. 138 using common clock framework.
@@ -129,13 +140,13 @@ config CLK_QORIQ
129config COMMON_CLK_XGENE 140config COMMON_CLK_XGENE
130 bool "Clock driver for APM XGene SoC" 141 bool "Clock driver for APM XGene SoC"
131 default y 142 default y
132 depends on ARM64 143 depends on ARM64 || COMPILE_TEST
133 ---help--- 144 ---help---
134 Sypport for the APM X-Gene SoC reference, PLL, and device clocks. 145 Sypport for the APM X-Gene SoC reference, PLL, and device clocks.
135 146
136config COMMON_CLK_KEYSTONE 147config COMMON_CLK_KEYSTONE
137 tristate "Clock drivers for Keystone based SOCs" 148 tristate "Clock drivers for Keystone based SOCs"
138 depends on ARCH_KEYSTONE && OF 149 depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF
139 ---help--- 150 ---help---
140 Supports clock drivers for Keystone based SOCs. These SOCs have local 151 Supports clock drivers for Keystone based SOCs. These SOCs have local
141 a power sleep control module that gate the clock to the IPs and PLLs. 152 a power sleep control module that gate the clock to the IPs and PLLs.
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d08b3e5985be..d3e1910eebab 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-divider.o
6obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o 6obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o
7obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o 7obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o
8obj-$(CONFIG_COMMON_CLK) += clk-gate.o 8obj-$(CONFIG_COMMON_CLK) += clk-gate.o
9obj-$(CONFIG_COMMON_CLK) += clk-multiplier.o
9obj-$(CONFIG_COMMON_CLK) += clk-mux.o 10obj-$(CONFIG_COMMON_CLK) += clk-mux.o
10obj-$(CONFIG_COMMON_CLK) += clk-composite.o 11obj-$(CONFIG_COMMON_CLK) += clk-composite.o
11obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o 12obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o
@@ -19,7 +20,6 @@ endif
19obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o 20obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o
20obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o 21obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
21obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o 22obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o
22obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
23obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o 23obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o
24obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o 24obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
25obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o 25obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
@@ -37,6 +37,7 @@ obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o
37obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o 37obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
38obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o 38obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
39obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o 39obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
40obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o
40obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o 41obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
41obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o 42obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o
42obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o 43obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o
@@ -47,7 +48,7 @@ obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
47obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o 48obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
48obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o 49obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
49obj-$(CONFIG_COMMON_CLK_AT91) += at91/ 50obj-$(CONFIG_COMMON_CLK_AT91) += at91/
50obj-$(CONFIG_ARCH_BCM) += bcm/ 51obj-y += bcm/
51obj-$(CONFIG_ARCH_BERLIN) += berlin/ 52obj-$(CONFIG_ARCH_BERLIN) += berlin/
52obj-$(CONFIG_ARCH_HISI) += hisilicon/ 53obj-$(CONFIG_ARCH_HISI) += hisilicon/
53obj-$(CONFIG_ARCH_MXC) += imx/ 54obj-$(CONFIG_ARCH_MXC) += imx/
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 89a48a7bd5df..13e67bd35cff 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o
10obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o 10obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o
11obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o 11obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o
12obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o 12obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o
13obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
new file mode 100644
index 000000000000..abc80949e1dd
--- /dev/null
+++ b/drivers/clk/at91/clk-generated.c
@@ -0,0 +1,306 @@
1/*
2 * Copyright (C) 2015 Atmel Corporation,
3 * Nicolas Ferre <nicolas.ferre@atmel.com>
4 *
5 * Based on clk-programmable & clk-peripheral drivers by Boris BREZILLON.
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 */
13
14#include <linux/clk-provider.h>
15#include <linux/clkdev.h>
16#include <linux/clk/at91_pmc.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <linux/io.h>
20
21#include "pmc.h"
22
23#define PERIPHERAL_MAX 64
24#define PERIPHERAL_ID_MIN 2
25
26#define GENERATED_SOURCE_MAX 6
27#define GENERATED_MAX_DIV 255
28
29struct clk_generated {
30 struct clk_hw hw;
31 struct at91_pmc *pmc;
32 struct clk_range range;
33 u32 id;
34 u32 gckdiv;
35 u8 parent_id;
36};
37
38#define to_clk_generated(hw) \
39 container_of(hw, struct clk_generated, hw)
40
41static int clk_generated_enable(struct clk_hw *hw)
42{
43 struct clk_generated *gck = to_clk_generated(hw);
44 struct at91_pmc *pmc = gck->pmc;
45 u32 tmp;
46
47 pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n",
48 __func__, gck->gckdiv, gck->parent_id);
49
50 pmc_lock(pmc);
51 pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
52 tmp = pmc_read(pmc, AT91_PMC_PCR) &
53 ~(AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK);
54 pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_GCKCSS(gck->parent_id)
55 | AT91_PMC_PCR_CMD
56 | AT91_PMC_PCR_GCKDIV(gck->gckdiv)
57 | AT91_PMC_PCR_GCKEN);
58 pmc_unlock(pmc);
59 return 0;
60}
61
62static void clk_generated_disable(struct clk_hw *hw)
63{
64 struct clk_generated *gck = to_clk_generated(hw);
65 struct at91_pmc *pmc = gck->pmc;
66 u32 tmp;
67
68 pmc_lock(pmc);
69 pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
70 tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_GCKEN;
71 pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD);
72 pmc_unlock(pmc);
73}
74
75static int clk_generated_is_enabled(struct clk_hw *hw)
76{
77 struct clk_generated *gck = to_clk_generated(hw);
78 struct at91_pmc *pmc = gck->pmc;
79 int ret;
80
81 pmc_lock(pmc);
82 pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
83 ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_GCKEN);
84 pmc_unlock(pmc);
85
86 return ret;
87}
88
89static unsigned long
90clk_generated_recalc_rate(struct clk_hw *hw,
91 unsigned long parent_rate)
92{
93 struct clk_generated *gck = to_clk_generated(hw);
94
95 return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1);
96}
97
98static int clk_generated_determine_rate(struct clk_hw *hw,
99 struct clk_rate_request *req)
100{
101 struct clk_generated *gck = to_clk_generated(hw);
102 struct clk_hw *parent = NULL;
103 long best_rate = -EINVAL;
104 unsigned long tmp_rate, min_rate;
105 int best_diff = -1;
106 int tmp_diff;
107 int i;
108
109 for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
110 u32 div;
111 unsigned long parent_rate;
112
113 parent = clk_hw_get_parent_by_index(hw, i);
114 if (!parent)
115 continue;
116
117 parent_rate = clk_hw_get_rate(parent);
118 min_rate = DIV_ROUND_CLOSEST(parent_rate, GENERATED_MAX_DIV + 1);
119 if (!parent_rate ||
120 (gck->range.max && min_rate > gck->range.max))
121 continue;
122
123 for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
124 tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div);
125 tmp_diff = abs(req->rate - tmp_rate);
126
127 if (best_diff < 0 || best_diff > tmp_diff) {
128 best_rate = tmp_rate;
129 best_diff = tmp_diff;
130 req->best_parent_rate = parent_rate;
131 req->best_parent_hw = parent;
132 }
133
134 if (!best_diff || tmp_rate < req->rate)
135 break;
136 }
137
138 if (!best_diff)
139 break;
140 }
141
142 pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
143 __func__, best_rate,
144 __clk_get_name((req->best_parent_hw)->clk),
145 req->best_parent_rate);
146
147 if (best_rate < 0)
148 return best_rate;
149
150 req->rate = best_rate;
151 return 0;
152}
153
154/* No modification of hardware as we have the flag CLK_SET_PARENT_GATE set */
155static int clk_generated_set_parent(struct clk_hw *hw, u8 index)
156{
157 struct clk_generated *gck = to_clk_generated(hw);
158
159 if (index >= clk_hw_get_num_parents(hw))
160 return -EINVAL;
161
162 gck->parent_id = index;
163 return 0;
164}
165
166static u8 clk_generated_get_parent(struct clk_hw *hw)
167{
168 struct clk_generated *gck = to_clk_generated(hw);
169
170 return gck->parent_id;
171}
172
173/* No modification of hardware as we have the flag CLK_SET_RATE_GATE set */
174static int clk_generated_set_rate(struct clk_hw *hw,
175 unsigned long rate,
176 unsigned long parent_rate)
177{
178 struct clk_generated *gck = to_clk_generated(hw);
179 u32 div;
180
181 if (!rate)
182 return -EINVAL;
183
184 if (gck->range.max && rate > gck->range.max)
185 return -EINVAL;
186
187 div = DIV_ROUND_CLOSEST(parent_rate, rate);
188 if (div > GENERATED_MAX_DIV + 1 || !div)
189 return -EINVAL;
190
191 gck->gckdiv = div - 1;
192 return 0;
193}
194
195static const struct clk_ops generated_ops = {
196 .enable = clk_generated_enable,
197 .disable = clk_generated_disable,
198 .is_enabled = clk_generated_is_enabled,
199 .recalc_rate = clk_generated_recalc_rate,
200 .determine_rate = clk_generated_determine_rate,
201 .get_parent = clk_generated_get_parent,
202 .set_parent = clk_generated_set_parent,
203 .set_rate = clk_generated_set_rate,
204};
205
206/**
207 * clk_generated_startup - Initialize a given clock to its default parent and
208 * divisor parameter.
209 *
210 * @gck: Generated clock to set the startup parameters for.
211 *
212 * Take parameters from the hardware and update local clock configuration
213 * accordingly.
214 */
215static void clk_generated_startup(struct clk_generated *gck)
216{
217 struct at91_pmc *pmc = gck->pmc;
218 u32 tmp;
219
220 pmc_lock(pmc);
221 pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
222 tmp = pmc_read(pmc, AT91_PMC_PCR);
223 pmc_unlock(pmc);
224
225 gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK)
226 >> AT91_PMC_PCR_GCKCSS_OFFSET;
227 gck->gckdiv = (tmp & AT91_PMC_PCR_GCKDIV_MASK)
228 >> AT91_PMC_PCR_GCKDIV_OFFSET;
229}
230
231static struct clk * __init
232at91_clk_register_generated(struct at91_pmc *pmc, const char *name,
233 const char **parent_names, u8 num_parents,
234 u8 id, const struct clk_range *range)
235{
236 struct clk_generated *gck;
237 struct clk *clk = NULL;
238 struct clk_init_data init;
239
240 gck = kzalloc(sizeof(*gck), GFP_KERNEL);
241 if (!gck)
242 return ERR_PTR(-ENOMEM);
243
244 init.name = name;
245 init.ops = &generated_ops;
246 init.parent_names = parent_names;
247 init.num_parents = num_parents;
248 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
249
250 gck->id = id;
251 gck->hw.init = &init;
252 gck->pmc = pmc;
253 gck->range = *range;
254
255 clk = clk_register(NULL, &gck->hw);
256 if (IS_ERR(clk))
257 kfree(gck);
258 else
259 clk_generated_startup(gck);
260
261 return clk;
262}
263
264void __init of_sama5d2_clk_generated_setup(struct device_node *np,
265 struct at91_pmc *pmc)
266{
267 int num;
268 u32 id;
269 const char *name;
270 struct clk *clk;
271 int num_parents;
272 const char *parent_names[GENERATED_SOURCE_MAX];
273 struct device_node *gcknp;
274 struct clk_range range = CLK_RANGE(0, 0);
275
276 num_parents = of_clk_get_parent_count(np);
277 if (num_parents <= 0 || num_parents > GENERATED_SOURCE_MAX)
278 return;
279
280 of_clk_parent_fill(np, parent_names, num_parents);
281
282 num = of_get_child_count(np);
283 if (!num || num > PERIPHERAL_MAX)
284 return;
285
286 for_each_child_of_node(np, gcknp) {
287 if (of_property_read_u32(gcknp, "reg", &id))
288 continue;
289
290 if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
291 continue;
292
293 if (of_property_read_string(np, "clock-output-names", &name))
294 name = gcknp->name;
295
296 of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
297 &range);
298
299 clk = at91_clk_register_generated(pmc, name, parent_names,
300 num_parents, id, &range);
301 if (IS_ERR(clk))
302 continue;
303
304 of_clk_add_provider(gcknp, of_clk_src_simple_get, clk);
305 }
306}
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index e4d7b574f1ea..58f3b568e9cb 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -161,14 +161,18 @@ static int clk_sam9x5_peripheral_enable(struct clk_hw *hw)
161{ 161{
162 struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); 162 struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
163 struct at91_pmc *pmc = periph->pmc; 163 struct at91_pmc *pmc = periph->pmc;
164 u32 tmp;
164 165
165 if (periph->id < PERIPHERAL_ID_MIN) 166 if (periph->id < PERIPHERAL_ID_MIN)
166 return 0; 167 return 0;
167 168
168 pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) | 169 pmc_lock(pmc);
169 AT91_PMC_PCR_CMD | 170 pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
170 AT91_PMC_PCR_DIV(periph->div) | 171 tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_DIV_MASK;
171 AT91_PMC_PCR_EN); 172 pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_DIV(periph->div)
173 | AT91_PMC_PCR_CMD
174 | AT91_PMC_PCR_EN);
175 pmc_unlock(pmc);
172 return 0; 176 return 0;
173} 177}
174 178
@@ -176,12 +180,16 @@ static void clk_sam9x5_peripheral_disable(struct clk_hw *hw)
176{ 180{
177 struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); 181 struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
178 struct at91_pmc *pmc = periph->pmc; 182 struct at91_pmc *pmc = periph->pmc;
183 u32 tmp;
179 184
180 if (periph->id < PERIPHERAL_ID_MIN) 185 if (periph->id < PERIPHERAL_ID_MIN)
181 return; 186 return;
182 187
183 pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) | 188 pmc_lock(pmc);
184 AT91_PMC_PCR_CMD); 189 pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
190 tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_EN;
191 pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD);
192 pmc_unlock(pmc);
185} 193}
186 194
187static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw) 195static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)
@@ -194,7 +202,7 @@ static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)
194 return 1; 202 return 1;
195 203
196 pmc_lock(pmc); 204 pmc_lock(pmc);
197 pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID)); 205 pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
198 ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_EN); 206 ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_EN);
199 pmc_unlock(pmc); 207 pmc_unlock(pmc);
200 208
@@ -213,7 +221,7 @@ clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw,
213 return parent_rate; 221 return parent_rate;
214 222
215 pmc_lock(pmc); 223 pmc_lock(pmc);
216 pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID)); 224 pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
217 tmp = pmc_read(pmc, AT91_PMC_PCR); 225 tmp = pmc_read(pmc, AT91_PMC_PCR);
218 pmc_unlock(pmc); 226 pmc_unlock(pmc);
219 227
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index 58008b3e8bc1..3f5314344286 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -138,7 +138,8 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name,
138 138
139 clk = clk_register(NULL, &sys->hw); 139 clk = clk_register(NULL, &sys->hw);
140 if (IS_ERR(clk)) { 140 if (IS_ERR(clk)) {
141 free_irq(sys->irq, sys); 141 if (irq)
142 free_irq(sys->irq, sys);
142 kfree(sys); 143 kfree(sys);
143 } 144 }
144 145
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
index 30dd697b1668..ca561e90a60f 100644
--- a/drivers/clk/at91/clk-utmi.c
+++ b/drivers/clk/at91/clk-utmi.c
@@ -47,7 +47,7 @@ static int clk_utmi_prepare(struct clk_hw *hw)
47{ 47{
48 struct clk_utmi *utmi = to_clk_utmi(hw); 48 struct clk_utmi *utmi = to_clk_utmi(hw);
49 struct at91_pmc *pmc = utmi->pmc; 49 struct at91_pmc *pmc = utmi->pmc;
50 u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) | AT91_PMC_UPLLEN | 50 u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) | AT91_PMC_UPLLEN |
51 AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN; 51 AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN;
52 52
53 pmc_write(pmc, AT91_CKGR_UCKR, tmp); 53 pmc_write(pmc, AT91_CKGR_UCKR, tmp);
@@ -73,7 +73,7 @@ static void clk_utmi_unprepare(struct clk_hw *hw)
73{ 73{
74 struct clk_utmi *utmi = to_clk_utmi(hw); 74 struct clk_utmi *utmi = to_clk_utmi(hw);
75 struct at91_pmc *pmc = utmi->pmc; 75 struct at91_pmc *pmc = utmi->pmc;
76 u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN; 76 u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN;
77 77
78 pmc_write(pmc, AT91_CKGR_UCKR, tmp); 78 pmc_write(pmc, AT91_CKGR_UCKR, tmp);
79} 79}
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index d1844f1f3729..8476b570779b 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -206,6 +206,14 @@ static const struct at91_pmc_caps at91sam9x5_caps = {
206 AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, 206 AT91_PMC_MOSCRCS | AT91_PMC_CFDEV,
207}; 207};
208 208
209static const struct at91_pmc_caps sama5d2_caps = {
210 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
211 AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
212 AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY |
213 AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS |
214 AT91_PMC_CFDEV | AT91_PMC_GCKRDY,
215};
216
209static const struct at91_pmc_caps sama5d3_caps = { 217static const struct at91_pmc_caps sama5d3_caps = {
210 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | 218 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
211 AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | 219 AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
@@ -369,6 +377,12 @@ static const struct of_device_id pmc_clk_ids[] __initconst = {
369 .data = of_sama5d4_clk_h32mx_setup, 377 .data = of_sama5d4_clk_h32mx_setup,
370 }, 378 },
371#endif 379#endif
380#if defined(CONFIG_HAVE_AT91_GENERATED_CLK)
381 {
382 .compatible = "atmel,sama5d2-clk-generated",
383 .data = of_sama5d2_clk_generated_setup,
384 },
385#endif
372 { /*sentinel*/ } 386 { /*sentinel*/ }
373}; 387};
374 388
@@ -436,6 +450,13 @@ static void __init of_at91sam9x5_pmc_setup(struct device_node *np)
436CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc", 450CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc",
437 of_at91sam9x5_pmc_setup); 451 of_at91sam9x5_pmc_setup);
438 452
453static void __init of_sama5d2_pmc_setup(struct device_node *np)
454{
455 of_at91_pmc_setup(np, &sama5d2_caps);
456}
457CLK_OF_DECLARE(sama5d2_clk_pmc, "atmel,sama5d2-pmc",
458 of_sama5d2_pmc_setup);
459
439static void __init of_sama5d3_pmc_setup(struct device_node *np) 460static void __init of_sama5d3_pmc_setup(struct device_node *np)
440{ 461{
441 of_at91_pmc_setup(np, &sama5d3_caps); 462 of_at91_pmc_setup(np, &sama5d3_caps);
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 8b87771c69b2..f65739272779 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -118,4 +118,7 @@ void of_at91sam9x5_clk_smd_setup(struct device_node *np,
118void of_sama5d4_clk_h32mx_setup(struct device_node *np, 118void of_sama5d4_clk_h32mx_setup(struct device_node *np,
119 struct at91_pmc *pmc); 119 struct at91_pmc *pmc);
120 120
121void of_sama5d2_clk_generated_setup(struct device_node *np,
122 struct at91_pmc *pmc);
123
121#endif /* __PMC_H_ */ 124#endif /* __PMC_H_ */
diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig
index 88febf53b276..85260fb96b36 100644
--- a/drivers/clk/bcm/Kconfig
+++ b/drivers/clk/bcm/Kconfig
@@ -1,6 +1,6 @@
1config CLK_BCM_KONA 1config CLK_BCM_KONA
2 bool "Broadcom Kona CCU clock support" 2 bool "Broadcom Kona CCU clock support"
3 depends on ARCH_BCM_MOBILE 3 depends on ARCH_BCM_MOBILE || COMPILE_TEST
4 depends on COMMON_CLK 4 depends on COMMON_CLK
5 default y 5 default y
6 help 6 help
@@ -9,10 +9,8 @@ config CLK_BCM_KONA
9 in the BCM281xx and BCM21664 families. 9 in the BCM281xx and BCM21664 families.
10 10
11config COMMON_CLK_IPROC 11config COMMON_CLK_IPROC
12 bool "Broadcom iProc clock support" 12 bool
13 depends on ARCH_BCM_IPROC
14 depends on COMMON_CLK 13 depends on COMMON_CLK
15 default ARCH_BCM_IPROC
16 help 14 help
17 Enable common clock framework support for Broadcom SoCs 15 Enable common clock framework support for Broadcom SoCs
18 based on the iProc architecture 16 based on the iProc architecture
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile
index 8a7a477862c7..3fc95060d875 100644
--- a/drivers/clk/bcm/Makefile
+++ b/drivers/clk/bcm/Makefile
@@ -3,4 +3,8 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o
3obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o 3obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o
4obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o 4obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o
5obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o 5obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o
6obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
7obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o
6obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o 8obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o
9obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o
10obj-$(CONFIG_ARCH_BCM_5301X) += clk-nsp.o
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
new file mode 100644
index 000000000000..39bf5820297e
--- /dev/null
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -0,0 +1,1575 @@
1/*
2 * Copyright (C) 2010,2015 Broadcom
3 * Copyright (C) 2012 Stephen Warren
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/**
21 * DOC: BCM2835 CPRMAN (clock manager for the "audio" domain)
22 *
23 * The clock tree on the 2835 has several levels. There's a root
24 * oscillator running at 19.2Mhz. After the oscillator there are 5
25 * PLLs, roughly divided as "camera", "ARM", "core", "DSI displays",
26 * and "HDMI displays". Those 5 PLLs each can divide their output to
27 * produce up to 4 channels. Finally, there is the level of clocks to
28 * be consumed by other hardware components (like "H264" or "HDMI
29 * state machine"), which divide off of some subset of the PLL
30 * channels.
31 *
32 * All of the clocks in the tree are exposed in the DT, because the DT
33 * may want to make assignments of the final layer of clocks to the
34 * PLL channels, and some components of the hardware will actually
35 * skip layers of the tree (for example, the pixel clock comes
36 * directly from the PLLH PIX channel without using a CM_*CTL clock
37 * generator).
38 */
39
40#include <linux/clk-provider.h>
41#include <linux/clkdev.h>
42#include <linux/clk/bcm2835.h>
43#include <linux/module.h>
44#include <linux/of.h>
45#include <linux/platform_device.h>
46#include <linux/slab.h>
47#include <dt-bindings/clock/bcm2835.h>
48
49#define CM_PASSWORD 0x5a000000
50
51#define CM_GNRICCTL 0x000
52#define CM_GNRICDIV 0x004
53# define CM_DIV_FRAC_BITS 12
54
55#define CM_VPUCTL 0x008
56#define CM_VPUDIV 0x00c
57#define CM_SYSCTL 0x010
58#define CM_SYSDIV 0x014
59#define CM_PERIACTL 0x018
60#define CM_PERIADIV 0x01c
61#define CM_PERIICTL 0x020
62#define CM_PERIIDIV 0x024
63#define CM_H264CTL 0x028
64#define CM_H264DIV 0x02c
65#define CM_ISPCTL 0x030
66#define CM_ISPDIV 0x034
67#define CM_V3DCTL 0x038
68#define CM_V3DDIV 0x03c
69#define CM_CAM0CTL 0x040
70#define CM_CAM0DIV 0x044
71#define CM_CAM1CTL 0x048
72#define CM_CAM1DIV 0x04c
73#define CM_CCP2CTL 0x050
74#define CM_CCP2DIV 0x054
75#define CM_DSI0ECTL 0x058
76#define CM_DSI0EDIV 0x05c
77#define CM_DSI0PCTL 0x060
78#define CM_DSI0PDIV 0x064
79#define CM_DPICTL 0x068
80#define CM_DPIDIV 0x06c
81#define CM_GP0CTL 0x070
82#define CM_GP0DIV 0x074
83#define CM_GP1CTL 0x078
84#define CM_GP1DIV 0x07c
85#define CM_GP2CTL 0x080
86#define CM_GP2DIV 0x084
87#define CM_HSMCTL 0x088
88#define CM_HSMDIV 0x08c
89#define CM_OTPCTL 0x090
90#define CM_OTPDIV 0x094
91#define CM_PWMCTL 0x0a0
92#define CM_PWMDIV 0x0a4
93#define CM_SMICTL 0x0b0
94#define CM_SMIDIV 0x0b4
95#define CM_TSENSCTL 0x0e0
96#define CM_TSENSDIV 0x0e4
97#define CM_TIMERCTL 0x0e8
98#define CM_TIMERDIV 0x0ec
99#define CM_UARTCTL 0x0f0
100#define CM_UARTDIV 0x0f4
101#define CM_VECCTL 0x0f8
102#define CM_VECDIV 0x0fc
103#define CM_PULSECTL 0x190
104#define CM_PULSEDIV 0x194
105#define CM_SDCCTL 0x1a8
106#define CM_SDCDIV 0x1ac
107#define CM_ARMCTL 0x1b0
108#define CM_EMMCCTL 0x1c0
109#define CM_EMMCDIV 0x1c4
110
111/* General bits for the CM_*CTL regs */
112# define CM_ENABLE BIT(4)
113# define CM_KILL BIT(5)
114# define CM_GATE_BIT 6
115# define CM_GATE BIT(CM_GATE_BIT)
116# define CM_BUSY BIT(7)
117# define CM_BUSYD BIT(8)
118# define CM_SRC_SHIFT 0
119# define CM_SRC_BITS 4
120# define CM_SRC_MASK 0xf
121# define CM_SRC_GND 0
122# define CM_SRC_OSC 1
123# define CM_SRC_TESTDEBUG0 2
124# define CM_SRC_TESTDEBUG1 3
125# define CM_SRC_PLLA_CORE 4
126# define CM_SRC_PLLA_PER 4
127# define CM_SRC_PLLC_CORE0 5
128# define CM_SRC_PLLC_PER 5
129# define CM_SRC_PLLC_CORE1 8
130# define CM_SRC_PLLD_CORE 6
131# define CM_SRC_PLLD_PER 6
132# define CM_SRC_PLLH_AUX 7
133# define CM_SRC_PLLC_CORE1 8
134# define CM_SRC_PLLC_CORE2 9
135
136#define CM_OSCCOUNT 0x100
137
138#define CM_PLLA 0x104
139# define CM_PLL_ANARST BIT(8)
140# define CM_PLLA_HOLDPER BIT(7)
141# define CM_PLLA_LOADPER BIT(6)
142# define CM_PLLA_HOLDCORE BIT(5)
143# define CM_PLLA_LOADCORE BIT(4)
144# define CM_PLLA_HOLDCCP2 BIT(3)
145# define CM_PLLA_LOADCCP2 BIT(2)
146# define CM_PLLA_HOLDDSI0 BIT(1)
147# define CM_PLLA_LOADDSI0 BIT(0)
148
149#define CM_PLLC 0x108
150# define CM_PLLC_HOLDPER BIT(7)
151# define CM_PLLC_LOADPER BIT(6)
152# define CM_PLLC_HOLDCORE2 BIT(5)
153# define CM_PLLC_LOADCORE2 BIT(4)
154# define CM_PLLC_HOLDCORE1 BIT(3)
155# define CM_PLLC_LOADCORE1 BIT(2)
156# define CM_PLLC_HOLDCORE0 BIT(1)
157# define CM_PLLC_LOADCORE0 BIT(0)
158
159#define CM_PLLD 0x10c
160# define CM_PLLD_HOLDPER BIT(7)
161# define CM_PLLD_LOADPER BIT(6)
162# define CM_PLLD_HOLDCORE BIT(5)
163# define CM_PLLD_LOADCORE BIT(4)
164# define CM_PLLD_HOLDDSI1 BIT(3)
165# define CM_PLLD_LOADDSI1 BIT(2)
166# define CM_PLLD_HOLDDSI0 BIT(1)
167# define CM_PLLD_LOADDSI0 BIT(0)
168
169#define CM_PLLH 0x110
170# define CM_PLLH_LOADRCAL BIT(2)
171# define CM_PLLH_LOADAUX BIT(1)
172# define CM_PLLH_LOADPIX BIT(0)
173
174#define CM_LOCK 0x114
175# define CM_LOCK_FLOCKH BIT(12)
176# define CM_LOCK_FLOCKD BIT(11)
177# define CM_LOCK_FLOCKC BIT(10)
178# define CM_LOCK_FLOCKB BIT(9)
179# define CM_LOCK_FLOCKA BIT(8)
180
181#define CM_EVENT 0x118
182#define CM_DSI1ECTL 0x158
183#define CM_DSI1EDIV 0x15c
184#define CM_DSI1PCTL 0x160
185#define CM_DSI1PDIV 0x164
186#define CM_DFTCTL 0x168
187#define CM_DFTDIV 0x16c
188
189#define CM_PLLB 0x170
190# define CM_PLLB_HOLDARM BIT(1)
191# define CM_PLLB_LOADARM BIT(0)
192
193#define A2W_PLLA_CTRL 0x1100
194#define A2W_PLLC_CTRL 0x1120
195#define A2W_PLLD_CTRL 0x1140
196#define A2W_PLLH_CTRL 0x1160
197#define A2W_PLLB_CTRL 0x11e0
198# define A2W_PLL_CTRL_PRST_DISABLE BIT(17)
199# define A2W_PLL_CTRL_PWRDN BIT(16)
200# define A2W_PLL_CTRL_PDIV_MASK 0x000007000
201# define A2W_PLL_CTRL_PDIV_SHIFT 12
202# define A2W_PLL_CTRL_NDIV_MASK 0x0000003ff
203# define A2W_PLL_CTRL_NDIV_SHIFT 0
204
205#define A2W_PLLA_ANA0 0x1010
206#define A2W_PLLC_ANA0 0x1030
207#define A2W_PLLD_ANA0 0x1050
208#define A2W_PLLH_ANA0 0x1070
209#define A2W_PLLB_ANA0 0x10f0
210
211#define A2W_PLL_KA_SHIFT 7
212#define A2W_PLL_KA_MASK GENMASK(9, 7)
213#define A2W_PLL_KI_SHIFT 19
214#define A2W_PLL_KI_MASK GENMASK(21, 19)
215#define A2W_PLL_KP_SHIFT 15
216#define A2W_PLL_KP_MASK GENMASK(18, 15)
217
218#define A2W_PLLH_KA_SHIFT 19
219#define A2W_PLLH_KA_MASK GENMASK(21, 19)
220#define A2W_PLLH_KI_LOW_SHIFT 22
221#define A2W_PLLH_KI_LOW_MASK GENMASK(23, 22)
222#define A2W_PLLH_KI_HIGH_SHIFT 0
223#define A2W_PLLH_KI_HIGH_MASK GENMASK(0, 0)
224#define A2W_PLLH_KP_SHIFT 1
225#define A2W_PLLH_KP_MASK GENMASK(4, 1)
226
227#define A2W_XOSC_CTRL 0x1190
228# define A2W_XOSC_CTRL_PLLB_ENABLE BIT(7)
229# define A2W_XOSC_CTRL_PLLA_ENABLE BIT(6)
230# define A2W_XOSC_CTRL_PLLD_ENABLE BIT(5)
231# define A2W_XOSC_CTRL_DDR_ENABLE BIT(4)
232# define A2W_XOSC_CTRL_CPR1_ENABLE BIT(3)
233# define A2W_XOSC_CTRL_USB_ENABLE BIT(2)
234# define A2W_XOSC_CTRL_HDMI_ENABLE BIT(1)
235# define A2W_XOSC_CTRL_PLLC_ENABLE BIT(0)
236
237#define A2W_PLLA_FRAC 0x1200
238#define A2W_PLLC_FRAC 0x1220
239#define A2W_PLLD_FRAC 0x1240
240#define A2W_PLLH_FRAC 0x1260
241#define A2W_PLLB_FRAC 0x12e0
242# define A2W_PLL_FRAC_MASK ((1 << A2W_PLL_FRAC_BITS) - 1)
243# define A2W_PLL_FRAC_BITS 20
244
245#define A2W_PLL_CHANNEL_DISABLE BIT(8)
246#define A2W_PLL_DIV_BITS 8
247#define A2W_PLL_DIV_SHIFT 0
248
249#define A2W_PLLA_DSI0 0x1300
250#define A2W_PLLA_CORE 0x1400
251#define A2W_PLLA_PER 0x1500
252#define A2W_PLLA_CCP2 0x1600
253
254#define A2W_PLLC_CORE2 0x1320
255#define A2W_PLLC_CORE1 0x1420
256#define A2W_PLLC_PER 0x1520
257#define A2W_PLLC_CORE0 0x1620
258
259#define A2W_PLLD_DSI0 0x1340
260#define A2W_PLLD_CORE 0x1440
261#define A2W_PLLD_PER 0x1540
262#define A2W_PLLD_DSI1 0x1640
263
264#define A2W_PLLH_AUX 0x1360
265#define A2W_PLLH_RCAL 0x1460
266#define A2W_PLLH_PIX 0x1560
267#define A2W_PLLH_STS 0x1660
268
269#define A2W_PLLH_CTRLR 0x1960
270#define A2W_PLLH_FRACR 0x1a60
271#define A2W_PLLH_AUXR 0x1b60
272#define A2W_PLLH_RCALR 0x1c60
273#define A2W_PLLH_PIXR 0x1d60
274#define A2W_PLLH_STSR 0x1e60
275
276#define A2W_PLLB_ARM 0x13e0
277#define A2W_PLLB_SP0 0x14e0
278#define A2W_PLLB_SP1 0x15e0
279#define A2W_PLLB_SP2 0x16e0
280
281#define LOCK_TIMEOUT_NS 100000000
282#define BCM2835_MAX_FB_RATE 1750000000u
283
284struct bcm2835_cprman {
285 struct device *dev;
286 void __iomem *regs;
287 spinlock_t regs_lock;
288 const char *osc_name;
289
290 struct clk_onecell_data onecell;
291 struct clk *clks[BCM2835_CLOCK_COUNT];
292};
293
294static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val)
295{
296 writel(CM_PASSWORD | val, cprman->regs + reg);
297}
298
299static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg)
300{
301 return readl(cprman->regs + reg);
302}
303
304/*
305 * These are fixed clocks. They're probably not all root clocks and it may
306 * be possible to turn them on and off but until this is mapped out better
307 * it's the only way they can be used.
308 */
309void __init bcm2835_init_clocks(void)
310{
311 struct clk *clk;
312 int ret;
313
314 clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
315 126000000);
316 if (IS_ERR(clk))
317 pr_err("apb_pclk not registered\n");
318
319 clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT,
320 3000000);
321 if (IS_ERR(clk))
322 pr_err("uart0_pclk not registered\n");
323 ret = clk_register_clkdev(clk, NULL, "20201000.uart");
324 if (ret)
325 pr_err("uart0_pclk alias not registered\n");
326
327 clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT,
328 125000000);
329 if (IS_ERR(clk))
330 pr_err("uart1_pclk not registered\n");
331 ret = clk_register_clkdev(clk, NULL, "20215000.uart");
332 if (ret)
333 pr_err("uart1_pclk alias not registered\n");
334}
335
336struct bcm2835_pll_data {
337 const char *name;
338 u32 cm_ctrl_reg;
339 u32 a2w_ctrl_reg;
340 u32 frac_reg;
341 u32 ana_reg_base;
342 u32 reference_enable_mask;
343 /* Bit in CM_LOCK to indicate when the PLL has locked. */
344 u32 lock_mask;
345
346 const struct bcm2835_pll_ana_bits *ana;
347
348 unsigned long min_rate;
349 unsigned long max_rate;
350 /*
351 * Highest rate for the VCO before we have to use the
352 * pre-divide-by-2.
353 */
354 unsigned long max_fb_rate;
355};
356
357struct bcm2835_pll_ana_bits {
358 u32 mask0;
359 u32 set0;
360 u32 mask1;
361 u32 set1;
362 u32 mask3;
363 u32 set3;
364 u32 fb_prediv_mask;
365};
366
367static const struct bcm2835_pll_ana_bits bcm2835_ana_default = {
368 .mask0 = 0,
369 .set0 = 0,
370 .mask1 = ~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK),
371 .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT),
372 .mask3 = ~A2W_PLL_KA_MASK,
373 .set3 = (2 << A2W_PLL_KA_SHIFT),
374 .fb_prediv_mask = BIT(14),
375};
376
377static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = {
378 .mask0 = ~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK),
379 .set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT),
380 .mask1 = ~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK),
381 .set1 = (6 << A2W_PLLH_KP_SHIFT),
382 .mask3 = 0,
383 .set3 = 0,
384 .fb_prediv_mask = BIT(11),
385};
386
387/*
388 * PLLA is the auxiliary PLL, used to drive the CCP2 (Compact Camera
389 * Port 2) transmitter clock.
390 *
391 * It is in the PX LDO power domain, which is on when the AUDIO domain
392 * is on.
393 */
394static const struct bcm2835_pll_data bcm2835_plla_data = {
395 .name = "plla",
396 .cm_ctrl_reg = CM_PLLA,
397 .a2w_ctrl_reg = A2W_PLLA_CTRL,
398 .frac_reg = A2W_PLLA_FRAC,
399 .ana_reg_base = A2W_PLLA_ANA0,
400 .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
401 .lock_mask = CM_LOCK_FLOCKA,
402
403 .ana = &bcm2835_ana_default,
404
405 .min_rate = 600000000u,
406 .max_rate = 2400000000u,
407 .max_fb_rate = BCM2835_MAX_FB_RATE,
408};
409
410/* PLLB is used for the ARM's clock. */
411static const struct bcm2835_pll_data bcm2835_pllb_data = {
412 .name = "pllb",
413 .cm_ctrl_reg = CM_PLLB,
414 .a2w_ctrl_reg = A2W_PLLB_CTRL,
415 .frac_reg = A2W_PLLB_FRAC,
416 .ana_reg_base = A2W_PLLB_ANA0,
417 .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
418 .lock_mask = CM_LOCK_FLOCKB,
419
420 .ana = &bcm2835_ana_default,
421
422 .min_rate = 600000000u,
423 .max_rate = 3000000000u,
424 .max_fb_rate = BCM2835_MAX_FB_RATE,
425};
426
427/*
428 * PLLC is the core PLL, used to drive the core VPU clock.
429 *
430 * It is in the PX LDO power domain, which is on when the AUDIO domain
431 * is on.
432*/
433static const struct bcm2835_pll_data bcm2835_pllc_data = {
434 .name = "pllc",
435 .cm_ctrl_reg = CM_PLLC,
436 .a2w_ctrl_reg = A2W_PLLC_CTRL,
437 .frac_reg = A2W_PLLC_FRAC,
438 .ana_reg_base = A2W_PLLC_ANA0,
439 .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
440 .lock_mask = CM_LOCK_FLOCKC,
441
442 .ana = &bcm2835_ana_default,
443
444 .min_rate = 600000000u,
445 .max_rate = 3000000000u,
446 .max_fb_rate = BCM2835_MAX_FB_RATE,
447};
448
449/*
450 * PLLD is the display PLL, used to drive DSI display panels.
451 *
452 * It is in the PX LDO power domain, which is on when the AUDIO domain
453 * is on.
454 */
455static const struct bcm2835_pll_data bcm2835_plld_data = {
456 .name = "plld",
457 .cm_ctrl_reg = CM_PLLD,
458 .a2w_ctrl_reg = A2W_PLLD_CTRL,
459 .frac_reg = A2W_PLLD_FRAC,
460 .ana_reg_base = A2W_PLLD_ANA0,
461 .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
462 .lock_mask = CM_LOCK_FLOCKD,
463
464 .ana = &bcm2835_ana_default,
465
466 .min_rate = 600000000u,
467 .max_rate = 2400000000u,
468 .max_fb_rate = BCM2835_MAX_FB_RATE,
469};
470
471/*
472 * PLLH is used to supply the pixel clock or the AUX clock for the TV
473 * encoder.
474 *
475 * It is in the HDMI power domain.
476 */
477static const struct bcm2835_pll_data bcm2835_pllh_data = {
478 "pllh",
479 .cm_ctrl_reg = CM_PLLH,
480 .a2w_ctrl_reg = A2W_PLLH_CTRL,
481 .frac_reg = A2W_PLLH_FRAC,
482 .ana_reg_base = A2W_PLLH_ANA0,
483 .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
484 .lock_mask = CM_LOCK_FLOCKH,
485
486 .ana = &bcm2835_ana_pllh,
487
488 .min_rate = 600000000u,
489 .max_rate = 3000000000u,
490 .max_fb_rate = BCM2835_MAX_FB_RATE,
491};
492
493struct bcm2835_pll_divider_data {
494 const char *name;
495 const struct bcm2835_pll_data *source_pll;
496 u32 cm_reg;
497 u32 a2w_reg;
498
499 u32 load_mask;
500 u32 hold_mask;
501 u32 fixed_divider;
502};
503
504static const struct bcm2835_pll_divider_data bcm2835_plla_core_data = {
505 .name = "plla_core",
506 .source_pll = &bcm2835_plla_data,
507 .cm_reg = CM_PLLA,
508 .a2w_reg = A2W_PLLA_CORE,
509 .load_mask = CM_PLLA_LOADCORE,
510 .hold_mask = CM_PLLA_HOLDCORE,
511 .fixed_divider = 1,
512};
513
514static const struct bcm2835_pll_divider_data bcm2835_plla_per_data = {
515 .name = "plla_per",
516 .source_pll = &bcm2835_plla_data,
517 .cm_reg = CM_PLLA,
518 .a2w_reg = A2W_PLLA_PER,
519 .load_mask = CM_PLLA_LOADPER,
520 .hold_mask = CM_PLLA_HOLDPER,
521 .fixed_divider = 1,
522};
523
524static const struct bcm2835_pll_divider_data bcm2835_pllb_arm_data = {
525 .name = "pllb_arm",
526 .source_pll = &bcm2835_pllb_data,
527 .cm_reg = CM_PLLB,
528 .a2w_reg = A2W_PLLB_ARM,
529 .load_mask = CM_PLLB_LOADARM,
530 .hold_mask = CM_PLLB_HOLDARM,
531 .fixed_divider = 1,
532};
533
534static const struct bcm2835_pll_divider_data bcm2835_pllc_core0_data = {
535 .name = "pllc_core0",
536 .source_pll = &bcm2835_pllc_data,
537 .cm_reg = CM_PLLC,
538 .a2w_reg = A2W_PLLC_CORE0,
539 .load_mask = CM_PLLC_LOADCORE0,
540 .hold_mask = CM_PLLC_HOLDCORE0,
541 .fixed_divider = 1,
542};
543
544static const struct bcm2835_pll_divider_data bcm2835_pllc_core1_data = {
545 .name = "pllc_core1", .source_pll = &bcm2835_pllc_data,
546 .cm_reg = CM_PLLC, A2W_PLLC_CORE1,
547 .load_mask = CM_PLLC_LOADCORE1,
548 .hold_mask = CM_PLLC_HOLDCORE1,
549 .fixed_divider = 1,
550};
551
552static const struct bcm2835_pll_divider_data bcm2835_pllc_core2_data = {
553 .name = "pllc_core2",
554 .source_pll = &bcm2835_pllc_data,
555 .cm_reg = CM_PLLC,
556 .a2w_reg = A2W_PLLC_CORE2,
557 .load_mask = CM_PLLC_LOADCORE2,
558 .hold_mask = CM_PLLC_HOLDCORE2,
559 .fixed_divider = 1,
560};
561
562static const struct bcm2835_pll_divider_data bcm2835_pllc_per_data = {
563 .name = "pllc_per",
564 .source_pll = &bcm2835_pllc_data,
565 .cm_reg = CM_PLLC,
566 .a2w_reg = A2W_PLLC_PER,
567 .load_mask = CM_PLLC_LOADPER,
568 .hold_mask = CM_PLLC_HOLDPER,
569 .fixed_divider = 1,
570};
571
572static const struct bcm2835_pll_divider_data bcm2835_plld_core_data = {
573 .name = "plld_core",
574 .source_pll = &bcm2835_plld_data,
575 .cm_reg = CM_PLLD,
576 .a2w_reg = A2W_PLLD_CORE,
577 .load_mask = CM_PLLD_LOADCORE,
578 .hold_mask = CM_PLLD_HOLDCORE,
579 .fixed_divider = 1,
580};
581
582static const struct bcm2835_pll_divider_data bcm2835_plld_per_data = {
583 .name = "plld_per",
584 .source_pll = &bcm2835_plld_data,
585 .cm_reg = CM_PLLD,
586 .a2w_reg = A2W_PLLD_PER,
587 .load_mask = CM_PLLD_LOADPER,
588 .hold_mask = CM_PLLD_HOLDPER,
589 .fixed_divider = 1,
590};
591
592static const struct bcm2835_pll_divider_data bcm2835_pllh_rcal_data = {
593 .name = "pllh_rcal",
594 .source_pll = &bcm2835_pllh_data,
595 .cm_reg = CM_PLLH,
596 .a2w_reg = A2W_PLLH_RCAL,
597 .load_mask = CM_PLLH_LOADRCAL,
598 .hold_mask = 0,
599 .fixed_divider = 10,
600};
601
602static const struct bcm2835_pll_divider_data bcm2835_pllh_aux_data = {
603 .name = "pllh_aux",
604 .source_pll = &bcm2835_pllh_data,
605 .cm_reg = CM_PLLH,
606 .a2w_reg = A2W_PLLH_AUX,
607 .load_mask = CM_PLLH_LOADAUX,
608 .hold_mask = 0,
609 .fixed_divider = 10,
610};
611
612static const struct bcm2835_pll_divider_data bcm2835_pllh_pix_data = {
613 .name = "pllh_pix",
614 .source_pll = &bcm2835_pllh_data,
615 .cm_reg = CM_PLLH,
616 .a2w_reg = A2W_PLLH_PIX,
617 .load_mask = CM_PLLH_LOADPIX,
618 .hold_mask = 0,
619 .fixed_divider = 10,
620};
621
622struct bcm2835_clock_data {
623 const char *name;
624
625 const char *const *parents;
626 int num_mux_parents;
627
628 u32 ctl_reg;
629 u32 div_reg;
630
631 /* Number of integer bits in the divider */
632 u32 int_bits;
633 /* Number of fractional bits in the divider */
634 u32 frac_bits;
635
636 bool is_vpu_clock;
637};
638
639static const char *const bcm2835_clock_per_parents[] = {
640 "gnd",
641 "xosc",
642 "testdebug0",
643 "testdebug1",
644 "plla_per",
645 "pllc_per",
646 "plld_per",
647 "pllh_aux",
648};
649
650static const char *const bcm2835_clock_vpu_parents[] = {
651 "gnd",
652 "xosc",
653 "testdebug0",
654 "testdebug1",
655 "plla_core",
656 "pllc_core0",
657 "plld_core",
658 "pllh_aux",
659 "pllc_core1",
660 "pllc_core2",
661};
662
663static const char *const bcm2835_clock_osc_parents[] = {
664 "gnd",
665 "xosc",
666 "testdebug0",
667 "testdebug1"
668};
669
670/*
671 * Used for a 1Mhz clock for the system clocksource, and also used by
672 * the watchdog timer and the camera pulse generator.
673 */
674static const struct bcm2835_clock_data bcm2835_clock_timer_data = {
675 .name = "timer",
676 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
677 .parents = bcm2835_clock_osc_parents,
678 .ctl_reg = CM_TIMERCTL,
679 .div_reg = CM_TIMERDIV,
680 .int_bits = 6,
681 .frac_bits = 12,
682};
683
684/* One Time Programmable Memory clock. Maximum 10Mhz. */
685static const struct bcm2835_clock_data bcm2835_clock_otp_data = {
686 .name = "otp",
687 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
688 .parents = bcm2835_clock_osc_parents,
689 .ctl_reg = CM_OTPCTL,
690 .div_reg = CM_OTPDIV,
691 .int_bits = 4,
692 .frac_bits = 0,
693};
694
695/*
696 * VPU clock. This doesn't have an enable bit, since it drives the
697 * bus for everything else, and is special so it doesn't need to be
698 * gated for rate changes. It is also known as "clk_audio" in various
699 * hardware documentation.
700 */
701static const struct bcm2835_clock_data bcm2835_clock_vpu_data = {
702 .name = "vpu",
703 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
704 .parents = bcm2835_clock_vpu_parents,
705 .ctl_reg = CM_VPUCTL,
706 .div_reg = CM_VPUDIV,
707 .int_bits = 12,
708 .frac_bits = 8,
709 .is_vpu_clock = true,
710};
711
712static const struct bcm2835_clock_data bcm2835_clock_v3d_data = {
713 .name = "v3d",
714 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
715 .parents = bcm2835_clock_vpu_parents,
716 .ctl_reg = CM_V3DCTL,
717 .div_reg = CM_V3DDIV,
718 .int_bits = 4,
719 .frac_bits = 8,
720};
721
722static const struct bcm2835_clock_data bcm2835_clock_isp_data = {
723 .name = "isp",
724 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
725 .parents = bcm2835_clock_vpu_parents,
726 .ctl_reg = CM_ISPCTL,
727 .div_reg = CM_ISPDIV,
728 .int_bits = 4,
729 .frac_bits = 8,
730};
731
732static const struct bcm2835_clock_data bcm2835_clock_h264_data = {
733 .name = "h264",
734 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
735 .parents = bcm2835_clock_vpu_parents,
736 .ctl_reg = CM_H264CTL,
737 .div_reg = CM_H264DIV,
738 .int_bits = 4,
739 .frac_bits = 8,
740};
741
742/* TV encoder clock. Only operating frequency is 108Mhz. */
743static const struct bcm2835_clock_data bcm2835_clock_vec_data = {
744 .name = "vec",
745 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
746 .parents = bcm2835_clock_per_parents,
747 .ctl_reg = CM_VECCTL,
748 .div_reg = CM_VECDIV,
749 .int_bits = 4,
750 .frac_bits = 0,
751};
752
753static const struct bcm2835_clock_data bcm2835_clock_uart_data = {
754 .name = "uart",
755 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
756 .parents = bcm2835_clock_per_parents,
757 .ctl_reg = CM_UARTCTL,
758 .div_reg = CM_UARTDIV,
759 .int_bits = 10,
760 .frac_bits = 12,
761};
762
763/* HDMI state machine */
764static const struct bcm2835_clock_data bcm2835_clock_hsm_data = {
765 .name = "hsm",
766 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
767 .parents = bcm2835_clock_per_parents,
768 .ctl_reg = CM_HSMCTL,
769 .div_reg = CM_HSMDIV,
770 .int_bits = 4,
771 .frac_bits = 8,
772};
773
774/*
775 * Secondary SDRAM clock. Used for low-voltage modes when the PLL in
776 * the SDRAM controller can't be used.
777 */
778static const struct bcm2835_clock_data bcm2835_clock_sdram_data = {
779 .name = "sdram",
780 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
781 .parents = bcm2835_clock_vpu_parents,
782 .ctl_reg = CM_SDCCTL,
783 .div_reg = CM_SDCDIV,
784 .int_bits = 6,
785 .frac_bits = 0,
786};
787
788/* Clock for the temperature sensor. Generally run at 2Mhz, max 5Mhz. */
789static const struct bcm2835_clock_data bcm2835_clock_tsens_data = {
790 .name = "tsens",
791 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
792 .parents = bcm2835_clock_osc_parents,
793 .ctl_reg = CM_TSENSCTL,
794 .div_reg = CM_TSENSDIV,
795 .int_bits = 5,
796 .frac_bits = 0,
797};
798
799/* Arasan EMMC clock */
800static const struct bcm2835_clock_data bcm2835_clock_emmc_data = {
801 .name = "emmc",
802 .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
803 .parents = bcm2835_clock_per_parents,
804 .ctl_reg = CM_EMMCCTL,
805 .div_reg = CM_EMMCDIV,
806 .int_bits = 4,
807 .frac_bits = 8,
808};
809
810struct bcm2835_pll {
811 struct clk_hw hw;
812 struct bcm2835_cprman *cprman;
813 const struct bcm2835_pll_data *data;
814};
815
816static int bcm2835_pll_is_on(struct clk_hw *hw)
817{
818 struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
819 struct bcm2835_cprman *cprman = pll->cprman;
820 const struct bcm2835_pll_data *data = pll->data;
821
822 return cprman_read(cprman, data->a2w_ctrl_reg) &
823 A2W_PLL_CTRL_PRST_DISABLE;
824}
825
826static void bcm2835_pll_choose_ndiv_and_fdiv(unsigned long rate,
827 unsigned long parent_rate,
828 u32 *ndiv, u32 *fdiv)
829{
830 u64 div;
831
832 div = (u64)rate << A2W_PLL_FRAC_BITS;
833 do_div(div, parent_rate);
834
835 *ndiv = div >> A2W_PLL_FRAC_BITS;
836 *fdiv = div & ((1 << A2W_PLL_FRAC_BITS) - 1);
837}
838
839static long bcm2835_pll_rate_from_divisors(unsigned long parent_rate,
840 u32 ndiv, u32 fdiv, u32 pdiv)
841{
842 u64 rate;
843
844 if (pdiv == 0)
845 return 0;
846
847 rate = (u64)parent_rate * ((ndiv << A2W_PLL_FRAC_BITS) + fdiv);
848 do_div(rate, pdiv);
849 return rate >> A2W_PLL_FRAC_BITS;
850}
851
852static long bcm2835_pll_round_rate(struct clk_hw *hw, unsigned long rate,
853 unsigned long *parent_rate)
854{
855 u32 ndiv, fdiv;
856
857 bcm2835_pll_choose_ndiv_and_fdiv(rate, *parent_rate, &ndiv, &fdiv);
858
859 return bcm2835_pll_rate_from_divisors(*parent_rate, ndiv, fdiv, 1);
860}
861
862static unsigned long bcm2835_pll_get_rate(struct clk_hw *hw,
863 unsigned long parent_rate)
864{
865 struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
866 struct bcm2835_cprman *cprman = pll->cprman;
867 const struct bcm2835_pll_data *data = pll->data;
868 u32 a2wctrl = cprman_read(cprman, data->a2w_ctrl_reg);
869 u32 ndiv, pdiv, fdiv;
870 bool using_prediv;
871
872 if (parent_rate == 0)
873 return 0;
874
875 fdiv = cprman_read(cprman, data->frac_reg) & A2W_PLL_FRAC_MASK;
876 ndiv = (a2wctrl & A2W_PLL_CTRL_NDIV_MASK) >> A2W_PLL_CTRL_NDIV_SHIFT;
877 pdiv = (a2wctrl & A2W_PLL_CTRL_PDIV_MASK) >> A2W_PLL_CTRL_PDIV_SHIFT;
878 using_prediv = cprman_read(cprman, data->ana_reg_base + 4) &
879 data->ana->fb_prediv_mask;
880
881 if (using_prediv)
882 ndiv *= 2;
883
884 return bcm2835_pll_rate_from_divisors(parent_rate, ndiv, fdiv, pdiv);
885}
886
887static void bcm2835_pll_off(struct clk_hw *hw)
888{
889 struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
890 struct bcm2835_cprman *cprman = pll->cprman;
891 const struct bcm2835_pll_data *data = pll->data;
892
893 cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST);
894 cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN);
895}
896
897static int bcm2835_pll_on(struct clk_hw *hw)
898{
899 struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
900 struct bcm2835_cprman *cprman = pll->cprman;
901 const struct bcm2835_pll_data *data = pll->data;
902 ktime_t timeout;
903
904 /* Take the PLL out of reset. */
905 cprman_write(cprman, data->cm_ctrl_reg,
906 cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST);
907
908 /* Wait for the PLL to lock. */
909 timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
910 while (!(cprman_read(cprman, CM_LOCK) & data->lock_mask)) {
911 if (ktime_after(ktime_get(), timeout)) {
912 dev_err(cprman->dev, "%s: couldn't lock PLL\n",
913 clk_hw_get_name(hw));
914 return -ETIMEDOUT;
915 }
916
917 cpu_relax();
918 }
919
920 return 0;
921}
922
923static void
924bcm2835_pll_write_ana(struct bcm2835_cprman *cprman, u32 ana_reg_base, u32 *ana)
925{
926 int i;
927
928 /*
929 * ANA register setup is done as a series of writes to
930 * ANA3-ANA0, in that order. This lets us write all 4
931 * registers as a single cycle of the serdes interface (taking
932 * 100 xosc clocks), whereas if we were to update ana0, 1, and
933 * 3 individually through their partial-write registers, each
934 * would be their own serdes cycle.
935 */
936 for (i = 3; i >= 0; i--)
937 cprman_write(cprman, ana_reg_base + i * 4, ana[i]);
938}
939
940static int bcm2835_pll_set_rate(struct clk_hw *hw,
941 unsigned long rate, unsigned long parent_rate)
942{
943 struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
944 struct bcm2835_cprman *cprman = pll->cprman;
945 const struct bcm2835_pll_data *data = pll->data;
946 bool was_using_prediv, use_fb_prediv, do_ana_setup_first;
947 u32 ndiv, fdiv, a2w_ctl;
948 u32 ana[4];
949 int i;
950
951 if (rate < data->min_rate || rate > data->max_rate) {
952 dev_err(cprman->dev, "%s: rate out of spec: %lu vs (%lu, %lu)\n",
953 clk_hw_get_name(hw), rate,
954 data->min_rate, data->max_rate);
955 return -EINVAL;
956 }
957
958 if (rate > data->max_fb_rate) {
959 use_fb_prediv = true;
960 rate /= 2;
961 } else {
962 use_fb_prediv = false;
963 }
964
965 bcm2835_pll_choose_ndiv_and_fdiv(rate, parent_rate, &ndiv, &fdiv);
966
967 for (i = 3; i >= 0; i--)
968 ana[i] = cprman_read(cprman, data->ana_reg_base + i * 4);
969
970 was_using_prediv = ana[1] & data->ana->fb_prediv_mask;
971
972 ana[0] &= ~data->ana->mask0;
973 ana[0] |= data->ana->set0;
974 ana[1] &= ~data->ana->mask1;
975 ana[1] |= data->ana->set1;
976 ana[3] &= ~data->ana->mask3;
977 ana[3] |= data->ana->set3;
978
979 if (was_using_prediv && !use_fb_prediv) {
980 ana[1] &= ~data->ana->fb_prediv_mask;
981 do_ana_setup_first = true;
982 } else if (!was_using_prediv && use_fb_prediv) {
983 ana[1] |= data->ana->fb_prediv_mask;
984 do_ana_setup_first = false;
985 } else {
986 do_ana_setup_first = true;
987 }
988
989 /* Unmask the reference clock from the oscillator. */
990 cprman_write(cprman, A2W_XOSC_CTRL,
991 cprman_read(cprman, A2W_XOSC_CTRL) |
992 data->reference_enable_mask);
993
994 if (do_ana_setup_first)
995 bcm2835_pll_write_ana(cprman, data->ana_reg_base, ana);
996
997 /* Set the PLL multiplier from the oscillator. */
998 cprman_write(cprman, data->frac_reg, fdiv);
999
1000 a2w_ctl = cprman_read(cprman, data->a2w_ctrl_reg);
1001 a2w_ctl &= ~A2W_PLL_CTRL_NDIV_MASK;
1002 a2w_ctl |= ndiv << A2W_PLL_CTRL_NDIV_SHIFT;
1003 a2w_ctl &= ~A2W_PLL_CTRL_PDIV_MASK;
1004 a2w_ctl |= 1 << A2W_PLL_CTRL_PDIV_SHIFT;
1005 cprman_write(cprman, data->a2w_ctrl_reg, a2w_ctl);
1006
1007 if (!do_ana_setup_first)
1008 bcm2835_pll_write_ana(cprman, data->ana_reg_base, ana);
1009
1010 return 0;
1011}
1012
1013static const struct clk_ops bcm2835_pll_clk_ops = {
1014 .is_prepared = bcm2835_pll_is_on,
1015 .prepare = bcm2835_pll_on,
1016 .unprepare = bcm2835_pll_off,
1017 .recalc_rate = bcm2835_pll_get_rate,
1018 .set_rate = bcm2835_pll_set_rate,
1019 .round_rate = bcm2835_pll_round_rate,
1020};
1021
1022struct bcm2835_pll_divider {
1023 struct clk_divider div;
1024 struct bcm2835_cprman *cprman;
1025 const struct bcm2835_pll_divider_data *data;
1026};
1027
1028static struct bcm2835_pll_divider *
1029bcm2835_pll_divider_from_hw(struct clk_hw *hw)
1030{
1031 return container_of(hw, struct bcm2835_pll_divider, div.hw);
1032}
1033
1034static int bcm2835_pll_divider_is_on(struct clk_hw *hw)
1035{
1036 struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
1037 struct bcm2835_cprman *cprman = divider->cprman;
1038 const struct bcm2835_pll_divider_data *data = divider->data;
1039
1040 return !(cprman_read(cprman, data->a2w_reg) & A2W_PLL_CHANNEL_DISABLE);
1041}
1042
1043static long bcm2835_pll_divider_round_rate(struct clk_hw *hw,
1044 unsigned long rate,
1045 unsigned long *parent_rate)
1046{
1047 return clk_divider_ops.round_rate(hw, rate, parent_rate);
1048}
1049
1050static unsigned long bcm2835_pll_divider_get_rate(struct clk_hw *hw,
1051 unsigned long parent_rate)
1052{
1053 struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
1054 struct bcm2835_cprman *cprman = divider->cprman;
1055 const struct bcm2835_pll_divider_data *data = divider->data;
1056 u32 div = cprman_read(cprman, data->a2w_reg);
1057
1058 div &= (1 << A2W_PLL_DIV_BITS) - 1;
1059 if (div == 0)
1060 div = 256;
1061
1062 return parent_rate / div;
1063}
1064
1065static void bcm2835_pll_divider_off(struct clk_hw *hw)
1066{
1067 struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
1068 struct bcm2835_cprman *cprman = divider->cprman;
1069 const struct bcm2835_pll_divider_data *data = divider->data;
1070
1071 cprman_write(cprman, data->cm_reg,
1072 (cprman_read(cprman, data->cm_reg) &
1073 ~data->load_mask) | data->hold_mask);
1074 cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE);
1075}
1076
1077static int bcm2835_pll_divider_on(struct clk_hw *hw)
1078{
1079 struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
1080 struct bcm2835_cprman *cprman = divider->cprman;
1081 const struct bcm2835_pll_divider_data *data = divider->data;
1082
1083 cprman_write(cprman, data->a2w_reg,
1084 cprman_read(cprman, data->a2w_reg) &
1085 ~A2W_PLL_CHANNEL_DISABLE);
1086
1087 cprman_write(cprman, data->cm_reg,
1088 cprman_read(cprman, data->cm_reg) & ~data->hold_mask);
1089
1090 return 0;
1091}
1092
1093static int bcm2835_pll_divider_set_rate(struct clk_hw *hw,
1094 unsigned long rate,
1095 unsigned long parent_rate)
1096{
1097 struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
1098 struct bcm2835_cprman *cprman = divider->cprman;
1099 const struct bcm2835_pll_divider_data *data = divider->data;
1100 u32 cm;
1101 int ret;
1102
1103 ret = clk_divider_ops.set_rate(hw, rate, parent_rate);
1104 if (ret)
1105 return ret;
1106
1107 cm = cprman_read(cprman, data->cm_reg);
1108 cprman_write(cprman, data->cm_reg, cm | data->load_mask);
1109 cprman_write(cprman, data->cm_reg, cm & ~data->load_mask);
1110
1111 return 0;
1112}
1113
1114static const struct clk_ops bcm2835_pll_divider_clk_ops = {
1115 .is_prepared = bcm2835_pll_divider_is_on,
1116 .prepare = bcm2835_pll_divider_on,
1117 .unprepare = bcm2835_pll_divider_off,
1118 .recalc_rate = bcm2835_pll_divider_get_rate,
1119 .set_rate = bcm2835_pll_divider_set_rate,
1120 .round_rate = bcm2835_pll_divider_round_rate,
1121};
1122
1123/*
1124 * The CM dividers do fixed-point division, so we can't use the
1125 * generic integer divider code like the PLL dividers do (and we can't
1126 * fake it by having some fixed shifts preceding it in the clock tree,
1127 * because we'd run out of bits in a 32-bit unsigned long).
1128 */
1129struct bcm2835_clock {
1130 struct clk_hw hw;
1131 struct bcm2835_cprman *cprman;
1132 const struct bcm2835_clock_data *data;
1133};
1134
1135static struct bcm2835_clock *bcm2835_clock_from_hw(struct clk_hw *hw)
1136{
1137 return container_of(hw, struct bcm2835_clock, hw);
1138}
1139
1140static int bcm2835_clock_is_on(struct clk_hw *hw)
1141{
1142 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
1143 struct bcm2835_cprman *cprman = clock->cprman;
1144 const struct bcm2835_clock_data *data = clock->data;
1145
1146 return (cprman_read(cprman, data->ctl_reg) & CM_ENABLE) != 0;
1147}
1148
1149static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
1150 unsigned long rate,
1151 unsigned long parent_rate)
1152{
1153 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
1154 const struct bcm2835_clock_data *data = clock->data;
1155 u32 unused_frac_mask = GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0);
1156 u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS;
1157 u32 div;
1158
1159 do_div(temp, rate);
1160 div = temp;
1161
1162 /* Round and mask off the unused bits */
1163 if (unused_frac_mask != 0) {
1164 div += unused_frac_mask >> 1;
1165 div &= ~unused_frac_mask;
1166 }
1167
1168 /* Clamp to the limits. */
1169 div = max(div, unused_frac_mask + 1);
1170 div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
1171 CM_DIV_FRAC_BITS - data->frac_bits));
1172
1173 return div;
1174}
1175
1176static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
1177 unsigned long parent_rate,
1178 u32 div)
1179{
1180 const struct bcm2835_clock_data *data = clock->data;
1181 u64 temp;
1182
1183 /*
1184 * The divisor is a 12.12 fixed point field, but only some of
1185 * the bits are populated in any given clock.
1186 */
1187 div >>= CM_DIV_FRAC_BITS - data->frac_bits;
1188 div &= (1 << (data->int_bits + data->frac_bits)) - 1;
1189
1190 if (div == 0)
1191 return 0;
1192
1193 temp = (u64)parent_rate << data->frac_bits;
1194
1195 do_div(temp, div);
1196
1197 return temp;
1198}
1199
1200static long bcm2835_clock_round_rate(struct clk_hw *hw,
1201 unsigned long rate,
1202 unsigned long *parent_rate)
1203{
1204 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
1205 u32 div = bcm2835_clock_choose_div(hw, rate, *parent_rate);
1206
1207 return bcm2835_clock_rate_from_divisor(clock, *parent_rate, div);
1208}
1209
1210static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw,
1211 unsigned long parent_rate)
1212{
1213 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
1214 struct bcm2835_cprman *cprman = clock->cprman;
1215 const struct bcm2835_clock_data *data = clock->data;
1216 u32 div = cprman_read(cprman, data->div_reg);
1217
1218 return bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
1219}
1220
1221static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock)
1222{
1223 struct bcm2835_cprman *cprman = clock->cprman;
1224 const struct bcm2835_clock_data *data = clock->data;
1225 ktime_t timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
1226
1227 while (cprman_read(cprman, data->ctl_reg) & CM_BUSY) {
1228 if (ktime_after(ktime_get(), timeout)) {
1229 dev_err(cprman->dev, "%s: couldn't lock PLL\n",
1230 clk_hw_get_name(&clock->hw));
1231 return;
1232 }
1233 cpu_relax();
1234 }
1235}
1236
1237static void bcm2835_clock_off(struct clk_hw *hw)
1238{
1239 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
1240 struct bcm2835_cprman *cprman = clock->cprman;
1241 const struct bcm2835_clock_data *data = clock->data;
1242
1243 spin_lock(&cprman->regs_lock);
1244 cprman_write(cprman, data->ctl_reg,
1245 cprman_read(cprman, data->ctl_reg) & ~CM_ENABLE);
1246 spin_unlock(&cprman->regs_lock);
1247
1248 /* BUSY will remain high until the divider completes its cycle. */
1249 bcm2835_clock_wait_busy(clock);
1250}
1251
1252static int bcm2835_clock_on(struct clk_hw *hw)
1253{
1254 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
1255 struct bcm2835_cprman *cprman = clock->cprman;
1256 const struct bcm2835_clock_data *data = clock->data;
1257
1258 spin_lock(&cprman->regs_lock);
1259 cprman_write(cprman, data->ctl_reg,
1260 cprman_read(cprman, data->ctl_reg) |
1261 CM_ENABLE |
1262 CM_GATE);
1263 spin_unlock(&cprman->regs_lock);
1264
1265 return 0;
1266}
1267
1268static int bcm2835_clock_set_rate(struct clk_hw *hw,
1269 unsigned long rate, unsigned long parent_rate)
1270{
1271 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
1272 struct bcm2835_cprman *cprman = clock->cprman;
1273 const struct bcm2835_clock_data *data = clock->data;
1274 u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate);
1275
1276 cprman_write(cprman, data->div_reg, div);
1277
1278 return 0;
1279}
1280
1281static const struct clk_ops bcm2835_clock_clk_ops = {
1282 .is_prepared = bcm2835_clock_is_on,
1283 .prepare = bcm2835_clock_on,
1284 .unprepare = bcm2835_clock_off,
1285 .recalc_rate = bcm2835_clock_get_rate,
1286 .set_rate = bcm2835_clock_set_rate,
1287 .round_rate = bcm2835_clock_round_rate,
1288};
1289
1290static int bcm2835_vpu_clock_is_on(struct clk_hw *hw)
1291{
1292 return true;
1293}
1294
1295/*
1296 * The VPU clock can never be disabled (it doesn't have an ENABLE
1297 * bit), so it gets its own set of clock ops.
1298 */
1299static const struct clk_ops bcm2835_vpu_clock_clk_ops = {
1300 .is_prepared = bcm2835_vpu_clock_is_on,
1301 .recalc_rate = bcm2835_clock_get_rate,
1302 .set_rate = bcm2835_clock_set_rate,
1303 .round_rate = bcm2835_clock_round_rate,
1304};
1305
1306static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
1307 const struct bcm2835_pll_data *data)
1308{
1309 struct bcm2835_pll *pll;
1310 struct clk_init_data init;
1311
1312 memset(&init, 0, sizeof(init));
1313
1314 /* All of the PLLs derive from the external oscillator. */
1315 init.parent_names = &cprman->osc_name;
1316 init.num_parents = 1;
1317 init.name = data->name;
1318 init.ops = &bcm2835_pll_clk_ops;
1319 init.flags = CLK_IGNORE_UNUSED;
1320
1321 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
1322 if (!pll)
1323 return NULL;
1324
1325 pll->cprman = cprman;
1326 pll->data = data;
1327 pll->hw.init = &init;
1328
1329 return devm_clk_register(cprman->dev, &pll->hw);
1330}
1331
1332static struct clk *
1333bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
1334 const struct bcm2835_pll_divider_data *data)
1335{
1336 struct bcm2835_pll_divider *divider;
1337 struct clk_init_data init;
1338 struct clk *clk;
1339 const char *divider_name;
1340
1341 if (data->fixed_divider != 1) {
1342 divider_name = devm_kasprintf(cprman->dev, GFP_KERNEL,
1343 "%s_prediv", data->name);
1344 if (!divider_name)
1345 return NULL;
1346 } else {
1347 divider_name = data->name;
1348 }
1349
1350 memset(&init, 0, sizeof(init));
1351
1352 init.parent_names = &data->source_pll->name;
1353 init.num_parents = 1;
1354 init.name = divider_name;
1355 init.ops = &bcm2835_pll_divider_clk_ops;
1356 init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED;
1357
1358 divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL);
1359 if (!divider)
1360 return NULL;
1361
1362 divider->div.reg = cprman->regs + data->a2w_reg;
1363 divider->div.shift = A2W_PLL_DIV_SHIFT;
1364 divider->div.width = A2W_PLL_DIV_BITS;
1365 divider->div.flags = 0;
1366 divider->div.lock = &cprman->regs_lock;
1367 divider->div.hw.init = &init;
1368 divider->div.table = NULL;
1369
1370 divider->cprman = cprman;
1371 divider->data = data;
1372
1373 clk = devm_clk_register(cprman->dev, &divider->div.hw);
1374 if (IS_ERR(clk))
1375 return clk;
1376
1377 /*
1378 * PLLH's channels have a fixed divide by 10 afterwards, which
1379 * is what our consumers are actually using.
1380 */
1381 if (data->fixed_divider != 1) {
1382 return clk_register_fixed_factor(cprman->dev, data->name,
1383 divider_name,
1384 CLK_SET_RATE_PARENT,
1385 1,
1386 data->fixed_divider);
1387 }
1388
1389 return clk;
1390}
1391
1392static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
1393 const struct bcm2835_clock_data *data)
1394{
1395 struct bcm2835_clock *clock;
1396 struct clk_init_data init;
1397 const char *parent;
1398
1399 /*
1400 * Most of the clock generators have a mux field, so we
1401 * instantiate a generic mux as our parent to handle it.
1402 */
1403 if (data->num_mux_parents) {
1404 const char *parents[1 << CM_SRC_BITS];
1405 int i;
1406
1407 parent = devm_kasprintf(cprman->dev, GFP_KERNEL,
1408 "mux_%s", data->name);
1409 if (!parent)
1410 return NULL;
1411
1412 /*
1413 * Replace our "xosc" references with the oscillator's
1414 * actual name.
1415 */
1416 for (i = 0; i < data->num_mux_parents; i++) {
1417 if (strcmp(data->parents[i], "xosc") == 0)
1418 parents[i] = cprman->osc_name;
1419 else
1420 parents[i] = data->parents[i];
1421 }
1422
1423 clk_register_mux(cprman->dev, parent,
1424 parents, data->num_mux_parents,
1425 CLK_SET_RATE_PARENT,
1426 cprman->regs + data->ctl_reg,
1427 CM_SRC_SHIFT, CM_SRC_BITS,
1428 0, &cprman->regs_lock);
1429 } else {
1430 parent = data->parents[0];
1431 }
1432
1433 memset(&init, 0, sizeof(init));
1434 init.parent_names = &parent;
1435 init.num_parents = 1;
1436 init.name = data->name;
1437 init.flags = CLK_IGNORE_UNUSED;
1438
1439 if (data->is_vpu_clock) {
1440 init.ops = &bcm2835_vpu_clock_clk_ops;
1441 } else {
1442 init.ops = &bcm2835_clock_clk_ops;
1443 init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
1444 }
1445
1446 clock = devm_kzalloc(cprman->dev, sizeof(*clock), GFP_KERNEL);
1447 if (!clock)
1448 return NULL;
1449
1450 clock->cprman = cprman;
1451 clock->data = data;
1452 clock->hw.init = &init;
1453
1454 return devm_clk_register(cprman->dev, &clock->hw);
1455}
1456
1457static int bcm2835_clk_probe(struct platform_device *pdev)
1458{
1459 struct device *dev = &pdev->dev;
1460 struct clk **clks;
1461 struct bcm2835_cprman *cprman;
1462 struct resource *res;
1463
1464 cprman = devm_kzalloc(dev, sizeof(*cprman), GFP_KERNEL);
1465 if (!cprman)
1466 return -ENOMEM;
1467
1468 spin_lock_init(&cprman->regs_lock);
1469 cprman->dev = dev;
1470 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1471 cprman->regs = devm_ioremap_resource(dev, res);
1472 if (IS_ERR(cprman->regs))
1473 return PTR_ERR(cprman->regs);
1474
1475 cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0);
1476 if (!cprman->osc_name)
1477 return -ENODEV;
1478
1479 platform_set_drvdata(pdev, cprman);
1480
1481 cprman->onecell.clk_num = BCM2835_CLOCK_COUNT;
1482 cprman->onecell.clks = cprman->clks;
1483 clks = cprman->clks;
1484
1485 clks[BCM2835_PLLA] = bcm2835_register_pll(cprman, &bcm2835_plla_data);
1486 clks[BCM2835_PLLB] = bcm2835_register_pll(cprman, &bcm2835_pllb_data);
1487 clks[BCM2835_PLLC] = bcm2835_register_pll(cprman, &bcm2835_pllc_data);
1488 clks[BCM2835_PLLD] = bcm2835_register_pll(cprman, &bcm2835_plld_data);
1489 clks[BCM2835_PLLH] = bcm2835_register_pll(cprman, &bcm2835_pllh_data);
1490
1491 clks[BCM2835_PLLA_CORE] =
1492 bcm2835_register_pll_divider(cprman, &bcm2835_plla_core_data);
1493 clks[BCM2835_PLLA_PER] =
1494 bcm2835_register_pll_divider(cprman, &bcm2835_plla_per_data);
1495 clks[BCM2835_PLLC_CORE0] =
1496 bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core0_data);
1497 clks[BCM2835_PLLC_CORE1] =
1498 bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core1_data);
1499 clks[BCM2835_PLLC_CORE2] =
1500 bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core2_data);
1501 clks[BCM2835_PLLC_PER] =
1502 bcm2835_register_pll_divider(cprman, &bcm2835_pllc_per_data);
1503 clks[BCM2835_PLLD_CORE] =
1504 bcm2835_register_pll_divider(cprman, &bcm2835_plld_core_data);
1505 clks[BCM2835_PLLD_PER] =
1506 bcm2835_register_pll_divider(cprman, &bcm2835_plld_per_data);
1507 clks[BCM2835_PLLH_RCAL] =
1508 bcm2835_register_pll_divider(cprman, &bcm2835_pllh_rcal_data);
1509 clks[BCM2835_PLLH_AUX] =
1510 bcm2835_register_pll_divider(cprman, &bcm2835_pllh_aux_data);
1511 clks[BCM2835_PLLH_PIX] =
1512 bcm2835_register_pll_divider(cprman, &bcm2835_pllh_pix_data);
1513
1514 clks[BCM2835_CLOCK_TIMER] =
1515 bcm2835_register_clock(cprman, &bcm2835_clock_timer_data);
1516 clks[BCM2835_CLOCK_OTP] =
1517 bcm2835_register_clock(cprman, &bcm2835_clock_otp_data);
1518 clks[BCM2835_CLOCK_TSENS] =
1519 bcm2835_register_clock(cprman, &bcm2835_clock_tsens_data);
1520 clks[BCM2835_CLOCK_VPU] =
1521 bcm2835_register_clock(cprman, &bcm2835_clock_vpu_data);
1522 clks[BCM2835_CLOCK_V3D] =
1523 bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
1524 clks[BCM2835_CLOCK_ISP] =
1525 bcm2835_register_clock(cprman, &bcm2835_clock_isp_data);
1526 clks[BCM2835_CLOCK_H264] =
1527 bcm2835_register_clock(cprman, &bcm2835_clock_h264_data);
1528 clks[BCM2835_CLOCK_V3D] =
1529 bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
1530 clks[BCM2835_CLOCK_SDRAM] =
1531 bcm2835_register_clock(cprman, &bcm2835_clock_sdram_data);
1532 clks[BCM2835_CLOCK_UART] =
1533 bcm2835_register_clock(cprman, &bcm2835_clock_uart_data);
1534 clks[BCM2835_CLOCK_VEC] =
1535 bcm2835_register_clock(cprman, &bcm2835_clock_vec_data);
1536 clks[BCM2835_CLOCK_HSM] =
1537 bcm2835_register_clock(cprman, &bcm2835_clock_hsm_data);
1538 clks[BCM2835_CLOCK_EMMC] =
1539 bcm2835_register_clock(cprman, &bcm2835_clock_emmc_data);
1540
1541 /*
1542 * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
1543 * you have the debug bit set in the power manager, which we
1544 * don't bother exposing) are individual gates off of the
1545 * non-stop vpu clock.
1546 */
1547 clks[BCM2835_CLOCK_PERI_IMAGE] =
1548 clk_register_gate(dev, "peri_image", "vpu",
1549 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
1550 cprman->regs + CM_PERIICTL, CM_GATE_BIT,
1551 0, &cprman->regs_lock);
1552
1553 return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
1554 &cprman->onecell);
1555}
1556
1557static const struct of_device_id bcm2835_clk_of_match[] = {
1558 { .compatible = "brcm,bcm2835-cprman", },
1559 {}
1560};
1561MODULE_DEVICE_TABLE(of, bcm2835_clk_of_match);
1562
1563static struct platform_driver bcm2835_clk_driver = {
1564 .driver = {
1565 .name = "bcm2835-clk",
1566 .of_match_table = bcm2835_clk_of_match,
1567 },
1568 .probe = bcm2835_clk_probe,
1569};
1570
1571builtin_platform_driver(bcm2835_clk_driver);
1572
1573MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
1574MODULE_DESCRIPTION("BCM2835 clock driver");
1575MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/bcm/clk-cygnus.c b/drivers/clk/bcm/clk-cygnus.c
index 316c60337661..3a228b6d4fee 100644
--- a/drivers/clk/bcm/clk-cygnus.c
+++ b/drivers/clk/bcm/clk-cygnus.c
@@ -23,28 +23,30 @@
23#include <dt-bindings/clock/bcm-cygnus.h> 23#include <dt-bindings/clock/bcm-cygnus.h>
24#include "clk-iproc.h" 24#include "clk-iproc.h"
25 25
26#define reg_val(o, s, w) { .offset = o, .shift = s, .width = w, } 26#define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
27 27
28#define aon_val(o, pw, ps, is) { .offset = o, .pwr_width = pw, \ 28#define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
29 .pwr_shift = ps, .iso_shift = is } 29 .pwr_shift = ps, .iso_shift = is }
30 30
31#define sw_ctrl_val(o, s) { .offset = o, .shift = s, } 31#define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, }
32 32
33#define asiu_div_val(o, es, hs, hw, ls, lw) \ 33#define ASIU_DIV_VAL(o, es, hs, hw, ls, lw) \
34 { .offset = o, .en_shift = es, .high_shift = hs, \ 34 { .offset = o, .en_shift = es, .high_shift = hs, \
35 .high_width = hw, .low_shift = ls, .low_width = lw } 35 .high_width = hw, .low_shift = ls, .low_width = lw }
36 36
37#define reset_val(o, rs, prs, kis, kiw, kps, kpw, kas, kaw) { .offset = o, \ 37#define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
38 .reset_shift = rs, .p_reset_shift = prs, .ki_shift = kis, \ 38 .p_reset_shift = prs }
39 .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \ 39
40#define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\
41 .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \
40 .ka_width = kaw } 42 .ka_width = kaw }
41 43
42#define vco_ctrl_val(uo, lo) { .u_offset = uo, .l_offset = lo } 44#define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
43 45
44#define enable_val(o, es, hs, bs) { .offset = o, .enable_shift = es, \ 46#define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
45 .hold_shift = hs, .bypass_shift = bs } 47 .hold_shift = hs, .bypass_shift = bs }
46 48
47#define asiu_gate_val(o, es) { .offset = o, .en_shift = es } 49#define ASIU_GATE_VAL(o, es) { .offset = o, .en_shift = es }
48 50
49static void __init cygnus_armpll_init(struct device_node *node) 51static void __init cygnus_armpll_init(struct device_node *node)
50{ 52{
@@ -55,52 +57,53 @@ CLK_OF_DECLARE(cygnus_armpll, "brcm,cygnus-armpll", cygnus_armpll_init);
55static const struct iproc_pll_ctrl genpll = { 57static const struct iproc_pll_ctrl genpll = {
56 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC | 58 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
57 IPROC_CLK_PLL_NEEDS_SW_CFG, 59 IPROC_CLK_PLL_NEEDS_SW_CFG,
58 .aon = aon_val(0x0, 2, 1, 0), 60 .aon = AON_VAL(0x0, 2, 1, 0),
59 .reset = reset_val(0x0, 11, 10, 4, 3, 0, 4, 7, 3), 61 .reset = RESET_VAL(0x0, 11, 10),
60 .sw_ctrl = sw_ctrl_val(0x10, 31), 62 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
61 .ndiv_int = reg_val(0x10, 20, 10), 63 .sw_ctrl = SW_CTRL_VAL(0x10, 31),
62 .ndiv_frac = reg_val(0x10, 0, 20), 64 .ndiv_int = REG_VAL(0x10, 20, 10),
63 .pdiv = reg_val(0x14, 0, 4), 65 .ndiv_frac = REG_VAL(0x10, 0, 20),
64 .vco_ctrl = vco_ctrl_val(0x18, 0x1c), 66 .pdiv = REG_VAL(0x14, 0, 4),
65 .status = reg_val(0x28, 12, 1), 67 .vco_ctrl = VCO_CTRL_VAL(0x18, 0x1c),
68 .status = REG_VAL(0x28, 12, 1),
66}; 69};
67 70
68static const struct iproc_clk_ctrl genpll_clk[] = { 71static const struct iproc_clk_ctrl genpll_clk[] = {
69 [BCM_CYGNUS_GENPLL_AXI21_CLK] = { 72 [BCM_CYGNUS_GENPLL_AXI21_CLK] = {
70 .channel = BCM_CYGNUS_GENPLL_AXI21_CLK, 73 .channel = BCM_CYGNUS_GENPLL_AXI21_CLK,
71 .flags = IPROC_CLK_AON, 74 .flags = IPROC_CLK_AON,
72 .enable = enable_val(0x4, 6, 0, 12), 75 .enable = ENABLE_VAL(0x4, 6, 0, 12),
73 .mdiv = reg_val(0x20, 0, 8), 76 .mdiv = REG_VAL(0x20, 0, 8),
74 }, 77 },
75 [BCM_CYGNUS_GENPLL_250MHZ_CLK] = { 78 [BCM_CYGNUS_GENPLL_250MHZ_CLK] = {
76 .channel = BCM_CYGNUS_GENPLL_250MHZ_CLK, 79 .channel = BCM_CYGNUS_GENPLL_250MHZ_CLK,
77 .flags = IPROC_CLK_AON, 80 .flags = IPROC_CLK_AON,
78 .enable = enable_val(0x4, 7, 1, 13), 81 .enable = ENABLE_VAL(0x4, 7, 1, 13),
79 .mdiv = reg_val(0x20, 10, 8), 82 .mdiv = REG_VAL(0x20, 10, 8),
80 }, 83 },
81 [BCM_CYGNUS_GENPLL_IHOST_SYS_CLK] = { 84 [BCM_CYGNUS_GENPLL_IHOST_SYS_CLK] = {
82 .channel = BCM_CYGNUS_GENPLL_IHOST_SYS_CLK, 85 .channel = BCM_CYGNUS_GENPLL_IHOST_SYS_CLK,
83 .flags = IPROC_CLK_AON, 86 .flags = IPROC_CLK_AON,
84 .enable = enable_val(0x4, 8, 2, 14), 87 .enable = ENABLE_VAL(0x4, 8, 2, 14),
85 .mdiv = reg_val(0x20, 20, 8), 88 .mdiv = REG_VAL(0x20, 20, 8),
86 }, 89 },
87 [BCM_CYGNUS_GENPLL_ENET_SW_CLK] = { 90 [BCM_CYGNUS_GENPLL_ENET_SW_CLK] = {
88 .channel = BCM_CYGNUS_GENPLL_ENET_SW_CLK, 91 .channel = BCM_CYGNUS_GENPLL_ENET_SW_CLK,
89 .flags = IPROC_CLK_AON, 92 .flags = IPROC_CLK_AON,
90 .enable = enable_val(0x4, 9, 3, 15), 93 .enable = ENABLE_VAL(0x4, 9, 3, 15),
91 .mdiv = reg_val(0x24, 0, 8), 94 .mdiv = REG_VAL(0x24, 0, 8),
92 }, 95 },
93 [BCM_CYGNUS_GENPLL_AUDIO_125_CLK] = { 96 [BCM_CYGNUS_GENPLL_AUDIO_125_CLK] = {
94 .channel = BCM_CYGNUS_GENPLL_AUDIO_125_CLK, 97 .channel = BCM_CYGNUS_GENPLL_AUDIO_125_CLK,
95 .flags = IPROC_CLK_AON, 98 .flags = IPROC_CLK_AON,
96 .enable = enable_val(0x4, 10, 4, 16), 99 .enable = ENABLE_VAL(0x4, 10, 4, 16),
97 .mdiv = reg_val(0x24, 10, 8), 100 .mdiv = REG_VAL(0x24, 10, 8),
98 }, 101 },
99 [BCM_CYGNUS_GENPLL_CAN_CLK] = { 102 [BCM_CYGNUS_GENPLL_CAN_CLK] = {
100 .channel = BCM_CYGNUS_GENPLL_CAN_CLK, 103 .channel = BCM_CYGNUS_GENPLL_CAN_CLK,
101 .flags = IPROC_CLK_AON, 104 .flags = IPROC_CLK_AON,
102 .enable = enable_val(0x4, 11, 5, 17), 105 .enable = ENABLE_VAL(0x4, 11, 5, 17),
103 .mdiv = reg_val(0x24, 20, 8), 106 .mdiv = REG_VAL(0x24, 20, 8),
104 }, 107 },
105}; 108};
106 109
@@ -113,51 +116,52 @@ CLK_OF_DECLARE(cygnus_genpll, "brcm,cygnus-genpll", cygnus_genpll_clk_init);
113 116
114static const struct iproc_pll_ctrl lcpll0 = { 117static const struct iproc_pll_ctrl lcpll0 = {
115 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG, 118 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
116 .aon = aon_val(0x0, 2, 5, 4), 119 .aon = AON_VAL(0x0, 2, 5, 4),
117 .reset = reset_val(0x0, 31, 30, 27, 3, 23, 4, 19, 4), 120 .reset = RESET_VAL(0x0, 31, 30),
118 .sw_ctrl = sw_ctrl_val(0x4, 31), 121 .dig_filter = DF_VAL(0x0, 27, 3, 23, 4, 19, 4),
119 .ndiv_int = reg_val(0x4, 16, 10), 122 .sw_ctrl = SW_CTRL_VAL(0x4, 31),
120 .pdiv = reg_val(0x4, 26, 4), 123 .ndiv_int = REG_VAL(0x4, 16, 10),
121 .vco_ctrl = vco_ctrl_val(0x10, 0x14), 124 .pdiv = REG_VAL(0x4, 26, 4),
122 .status = reg_val(0x18, 12, 1), 125 .vco_ctrl = VCO_CTRL_VAL(0x10, 0x14),
126 .status = REG_VAL(0x18, 12, 1),
123}; 127};
124 128
125static const struct iproc_clk_ctrl lcpll0_clk[] = { 129static const struct iproc_clk_ctrl lcpll0_clk[] = {
126 [BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK] = { 130 [BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK] = {
127 .channel = BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK, 131 .channel = BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK,
128 .flags = IPROC_CLK_AON, 132 .flags = IPROC_CLK_AON,
129 .enable = enable_val(0x0, 7, 1, 13), 133 .enable = ENABLE_VAL(0x0, 7, 1, 13),
130 .mdiv = reg_val(0x8, 0, 8), 134 .mdiv = REG_VAL(0x8, 0, 8),
131 }, 135 },
132 [BCM_CYGNUS_LCPLL0_DDR_PHY_CLK] = { 136 [BCM_CYGNUS_LCPLL0_DDR_PHY_CLK] = {
133 .channel = BCM_CYGNUS_LCPLL0_DDR_PHY_CLK, 137 .channel = BCM_CYGNUS_LCPLL0_DDR_PHY_CLK,
134 .flags = IPROC_CLK_AON, 138 .flags = IPROC_CLK_AON,
135 .enable = enable_val(0x0, 8, 2, 14), 139 .enable = ENABLE_VAL(0x0, 8, 2, 14),
136 .mdiv = reg_val(0x8, 10, 8), 140 .mdiv = REG_VAL(0x8, 10, 8),
137 }, 141 },
138 [BCM_CYGNUS_LCPLL0_SDIO_CLK] = { 142 [BCM_CYGNUS_LCPLL0_SDIO_CLK] = {
139 .channel = BCM_CYGNUS_LCPLL0_SDIO_CLK, 143 .channel = BCM_CYGNUS_LCPLL0_SDIO_CLK,
140 .flags = IPROC_CLK_AON, 144 .flags = IPROC_CLK_AON,
141 .enable = enable_val(0x0, 9, 3, 15), 145 .enable = ENABLE_VAL(0x0, 9, 3, 15),
142 .mdiv = reg_val(0x8, 20, 8), 146 .mdiv = REG_VAL(0x8, 20, 8),
143 }, 147 },
144 [BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK] = { 148 [BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK] = {
145 .channel = BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK, 149 .channel = BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK,
146 .flags = IPROC_CLK_AON, 150 .flags = IPROC_CLK_AON,
147 .enable = enable_val(0x0, 10, 4, 16), 151 .enable = ENABLE_VAL(0x0, 10, 4, 16),
148 .mdiv = reg_val(0xc, 0, 8), 152 .mdiv = REG_VAL(0xc, 0, 8),
149 }, 153 },
150 [BCM_CYGNUS_LCPLL0_SMART_CARD_CLK] = { 154 [BCM_CYGNUS_LCPLL0_SMART_CARD_CLK] = {
151 .channel = BCM_CYGNUS_LCPLL0_SMART_CARD_CLK, 155 .channel = BCM_CYGNUS_LCPLL0_SMART_CARD_CLK,
152 .flags = IPROC_CLK_AON, 156 .flags = IPROC_CLK_AON,
153 .enable = enable_val(0x0, 11, 5, 17), 157 .enable = ENABLE_VAL(0x0, 11, 5, 17),
154 .mdiv = reg_val(0xc, 10, 8), 158 .mdiv = REG_VAL(0xc, 10, 8),
155 }, 159 },
156 [BCM_CYGNUS_LCPLL0_CH5_UNUSED] = { 160 [BCM_CYGNUS_LCPLL0_CH5_UNUSED] = {
157 .channel = BCM_CYGNUS_LCPLL0_CH5_UNUSED, 161 .channel = BCM_CYGNUS_LCPLL0_CH5_UNUSED,
158 .flags = IPROC_CLK_AON, 162 .flags = IPROC_CLK_AON,
159 .enable = enable_val(0x0, 12, 6, 18), 163 .enable = ENABLE_VAL(0x0, 12, 6, 18),
160 .mdiv = reg_val(0xc, 20, 8), 164 .mdiv = REG_VAL(0xc, 20, 8),
161 }, 165 },
162}; 166};
163 167
@@ -189,52 +193,53 @@ static const struct iproc_pll_vco_param mipipll_vco_params[] = {
189static const struct iproc_pll_ctrl mipipll = { 193static const struct iproc_pll_ctrl mipipll = {
190 .flags = IPROC_CLK_PLL_ASIU | IPROC_CLK_PLL_HAS_NDIV_FRAC | 194 .flags = IPROC_CLK_PLL_ASIU | IPROC_CLK_PLL_HAS_NDIV_FRAC |
191 IPROC_CLK_NEEDS_READ_BACK, 195 IPROC_CLK_NEEDS_READ_BACK,
192 .aon = aon_val(0x0, 4, 17, 16), 196 .aon = AON_VAL(0x0, 4, 17, 16),
193 .asiu = asiu_gate_val(0x0, 3), 197 .asiu = ASIU_GATE_VAL(0x0, 3),
194 .reset = reset_val(0x0, 11, 10, 4, 3, 0, 4, 7, 4), 198 .reset = RESET_VAL(0x0, 11, 10),
195 .ndiv_int = reg_val(0x10, 20, 10), 199 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 4),
196 .ndiv_frac = reg_val(0x10, 0, 20), 200 .ndiv_int = REG_VAL(0x10, 20, 10),
197 .pdiv = reg_val(0x14, 0, 4), 201 .ndiv_frac = REG_VAL(0x10, 0, 20),
198 .vco_ctrl = vco_ctrl_val(0x18, 0x1c), 202 .pdiv = REG_VAL(0x14, 0, 4),
199 .status = reg_val(0x28, 12, 1), 203 .vco_ctrl = VCO_CTRL_VAL(0x18, 0x1c),
204 .status = REG_VAL(0x28, 12, 1),
200}; 205};
201 206
202static const struct iproc_clk_ctrl mipipll_clk[] = { 207static const struct iproc_clk_ctrl mipipll_clk[] = {
203 [BCM_CYGNUS_MIPIPLL_CH0_UNUSED] = { 208 [BCM_CYGNUS_MIPIPLL_CH0_UNUSED] = {
204 .channel = BCM_CYGNUS_MIPIPLL_CH0_UNUSED, 209 .channel = BCM_CYGNUS_MIPIPLL_CH0_UNUSED,
205 .flags = IPROC_CLK_NEEDS_READ_BACK, 210 .flags = IPROC_CLK_NEEDS_READ_BACK,
206 .enable = enable_val(0x4, 12, 6, 18), 211 .enable = ENABLE_VAL(0x4, 12, 6, 18),
207 .mdiv = reg_val(0x20, 0, 8), 212 .mdiv = REG_VAL(0x20, 0, 8),
208 }, 213 },
209 [BCM_CYGNUS_MIPIPLL_CH1_LCD] = { 214 [BCM_CYGNUS_MIPIPLL_CH1_LCD] = {
210 .channel = BCM_CYGNUS_MIPIPLL_CH1_LCD, 215 .channel = BCM_CYGNUS_MIPIPLL_CH1_LCD,
211 .flags = IPROC_CLK_NEEDS_READ_BACK, 216 .flags = IPROC_CLK_NEEDS_READ_BACK,
212 .enable = enable_val(0x4, 13, 7, 19), 217 .enable = ENABLE_VAL(0x4, 13, 7, 19),
213 .mdiv = reg_val(0x20, 10, 8), 218 .mdiv = REG_VAL(0x20, 10, 8),
214 }, 219 },
215 [BCM_CYGNUS_MIPIPLL_CH2_V3D] = { 220 [BCM_CYGNUS_MIPIPLL_CH2_V3D] = {
216 .channel = BCM_CYGNUS_MIPIPLL_CH2_V3D, 221 .channel = BCM_CYGNUS_MIPIPLL_CH2_V3D,
217 .flags = IPROC_CLK_NEEDS_READ_BACK, 222 .flags = IPROC_CLK_NEEDS_READ_BACK,
218 .enable = enable_val(0x4, 14, 8, 20), 223 .enable = ENABLE_VAL(0x4, 14, 8, 20),
219 .mdiv = reg_val(0x20, 20, 8), 224 .mdiv = REG_VAL(0x20, 20, 8),
220 }, 225 },
221 [BCM_CYGNUS_MIPIPLL_CH3_UNUSED] = { 226 [BCM_CYGNUS_MIPIPLL_CH3_UNUSED] = {
222 .channel = BCM_CYGNUS_MIPIPLL_CH3_UNUSED, 227 .channel = BCM_CYGNUS_MIPIPLL_CH3_UNUSED,
223 .flags = IPROC_CLK_NEEDS_READ_BACK, 228 .flags = IPROC_CLK_NEEDS_READ_BACK,
224 .enable = enable_val(0x4, 15, 9, 21), 229 .enable = ENABLE_VAL(0x4, 15, 9, 21),
225 .mdiv = reg_val(0x24, 0, 8), 230 .mdiv = REG_VAL(0x24, 0, 8),
226 }, 231 },
227 [BCM_CYGNUS_MIPIPLL_CH4_UNUSED] = { 232 [BCM_CYGNUS_MIPIPLL_CH4_UNUSED] = {
228 .channel = BCM_CYGNUS_MIPIPLL_CH4_UNUSED, 233 .channel = BCM_CYGNUS_MIPIPLL_CH4_UNUSED,
229 .flags = IPROC_CLK_NEEDS_READ_BACK, 234 .flags = IPROC_CLK_NEEDS_READ_BACK,
230 .enable = enable_val(0x4, 16, 10, 22), 235 .enable = ENABLE_VAL(0x4, 16, 10, 22),
231 .mdiv = reg_val(0x24, 10, 8), 236 .mdiv = REG_VAL(0x24, 10, 8),
232 }, 237 },
233 [BCM_CYGNUS_MIPIPLL_CH5_UNUSED] = { 238 [BCM_CYGNUS_MIPIPLL_CH5_UNUSED] = {
234 .channel = BCM_CYGNUS_MIPIPLL_CH5_UNUSED, 239 .channel = BCM_CYGNUS_MIPIPLL_CH5_UNUSED,
235 .flags = IPROC_CLK_NEEDS_READ_BACK, 240 .flags = IPROC_CLK_NEEDS_READ_BACK,
236 .enable = enable_val(0x4, 17, 11, 23), 241 .enable = ENABLE_VAL(0x4, 17, 11, 23),
237 .mdiv = reg_val(0x24, 20, 8), 242 .mdiv = REG_VAL(0x24, 20, 8),
238 }, 243 },
239}; 244};
240 245
@@ -247,15 +252,15 @@ static void __init cygnus_mipipll_clk_init(struct device_node *node)
247CLK_OF_DECLARE(cygnus_mipipll, "brcm,cygnus-mipipll", cygnus_mipipll_clk_init); 252CLK_OF_DECLARE(cygnus_mipipll, "brcm,cygnus-mipipll", cygnus_mipipll_clk_init);
248 253
249static const struct iproc_asiu_div asiu_div[] = { 254static const struct iproc_asiu_div asiu_div[] = {
250 [BCM_CYGNUS_ASIU_KEYPAD_CLK] = asiu_div_val(0x0, 31, 16, 10, 0, 10), 255 [BCM_CYGNUS_ASIU_KEYPAD_CLK] = ASIU_DIV_VAL(0x0, 31, 16, 10, 0, 10),
251 [BCM_CYGNUS_ASIU_ADC_CLK] = asiu_div_val(0x4, 31, 16, 10, 0, 10), 256 [BCM_CYGNUS_ASIU_ADC_CLK] = ASIU_DIV_VAL(0x4, 31, 16, 10, 0, 10),
252 [BCM_CYGNUS_ASIU_PWM_CLK] = asiu_div_val(0x8, 31, 16, 10, 0, 10), 257 [BCM_CYGNUS_ASIU_PWM_CLK] = ASIU_DIV_VAL(0x8, 31, 16, 10, 0, 10),
253}; 258};
254 259
255static const struct iproc_asiu_gate asiu_gate[] = { 260static const struct iproc_asiu_gate asiu_gate[] = {
256 [BCM_CYGNUS_ASIU_KEYPAD_CLK] = asiu_gate_val(0x0, 7), 261 [BCM_CYGNUS_ASIU_KEYPAD_CLK] = ASIU_GATE_VAL(0x0, 7),
257 [BCM_CYGNUS_ASIU_ADC_CLK] = asiu_gate_val(0x0, 9), 262 [BCM_CYGNUS_ASIU_ADC_CLK] = ASIU_GATE_VAL(0x0, 9),
258 [BCM_CYGNUS_ASIU_PWM_CLK] = asiu_gate_val(IPROC_CLK_INVALID_OFFSET, 0), 263 [BCM_CYGNUS_ASIU_PWM_CLK] = ASIU_GATE_VAL(IPROC_CLK_INVALID_OFFSET, 0),
259}; 264};
260 265
261static void __init cygnus_asiu_init(struct device_node *node) 266static void __init cygnus_asiu_init(struct device_node *node)
diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c
index 2dda4e8295a9..afd5891ac9e6 100644
--- a/drivers/clk/bcm/clk-iproc-pll.c
+++ b/drivers/clk/bcm/clk-iproc-pll.c
@@ -74,7 +74,8 @@ struct iproc_clk {
74}; 74};
75 75
76struct iproc_pll { 76struct iproc_pll {
77 void __iomem *pll_base; 77 void __iomem *status_base;
78 void __iomem *control_base;
78 void __iomem *pwr_base; 79 void __iomem *pwr_base;
79 void __iomem *asiu_base; 80 void __iomem *asiu_base;
80 81
@@ -127,7 +128,7 @@ static int pll_wait_for_lock(struct iproc_pll *pll)
127 const struct iproc_pll_ctrl *ctrl = pll->ctrl; 128 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
128 129
129 for (i = 0; i < LOCK_DELAY; i++) { 130 for (i = 0; i < LOCK_DELAY; i++) {
130 u32 val = readl(pll->pll_base + ctrl->status.offset); 131 u32 val = readl(pll->status_base + ctrl->status.offset);
131 132
132 if (val & (1 << ctrl->status.shift)) 133 if (val & (1 << ctrl->status.shift))
133 return 0; 134 return 0;
@@ -137,6 +138,18 @@ static int pll_wait_for_lock(struct iproc_pll *pll)
137 return -EIO; 138 return -EIO;
138} 139}
139 140
141static void iproc_pll_write(const struct iproc_pll *pll, void __iomem *base,
142 const u32 offset, u32 val)
143{
144 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
145
146 writel(val, base + offset);
147
148 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK &&
149 (base == pll->status_base || base == pll->control_base)))
150 val = readl(base + offset);
151}
152
140static void __pll_disable(struct iproc_pll *pll) 153static void __pll_disable(struct iproc_pll *pll)
141{ 154{
142 const struct iproc_pll_ctrl *ctrl = pll->ctrl; 155 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
@@ -145,17 +158,25 @@ static void __pll_disable(struct iproc_pll *pll)
145 if (ctrl->flags & IPROC_CLK_PLL_ASIU) { 158 if (ctrl->flags & IPROC_CLK_PLL_ASIU) {
146 val = readl(pll->asiu_base + ctrl->asiu.offset); 159 val = readl(pll->asiu_base + ctrl->asiu.offset);
147 val &= ~(1 << ctrl->asiu.en_shift); 160 val &= ~(1 << ctrl->asiu.en_shift);
148 writel(val, pll->asiu_base + ctrl->asiu.offset); 161 iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val);
162 }
163
164 if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
165 val = readl(pll->control_base + ctrl->aon.offset);
166 val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
167 iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val);
149 } 168 }
150 169
151 /* latch input value so core power can be shut down */ 170 if (pll->pwr_base) {
152 val = readl(pll->pwr_base + ctrl->aon.offset); 171 /* latch input value so core power can be shut down */
153 val |= (1 << ctrl->aon.iso_shift); 172 val = readl(pll->pwr_base + ctrl->aon.offset);
154 writel(val, pll->pwr_base + ctrl->aon.offset); 173 val |= 1 << ctrl->aon.iso_shift;
174 iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
155 175
156 /* power down the core */ 176 /* power down the core */
157 val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift); 177 val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
158 writel(val, pll->pwr_base + ctrl->aon.offset); 178 iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
179 }
159} 180}
160 181
161static int __pll_enable(struct iproc_pll *pll) 182static int __pll_enable(struct iproc_pll *pll)
@@ -163,17 +184,25 @@ static int __pll_enable(struct iproc_pll *pll)
163 const struct iproc_pll_ctrl *ctrl = pll->ctrl; 184 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
164 u32 val; 185 u32 val;
165 186
166 /* power up the PLL and make sure it's not latched */ 187 if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
167 val = readl(pll->pwr_base + ctrl->aon.offset); 188 val = readl(pll->control_base + ctrl->aon.offset);
168 val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift; 189 val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
169 val &= ~(1 << ctrl->aon.iso_shift); 190 iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val);
170 writel(val, pll->pwr_base + ctrl->aon.offset); 191 }
192
193 if (pll->pwr_base) {
194 /* power up the PLL and make sure it's not latched */
195 val = readl(pll->pwr_base + ctrl->aon.offset);
196 val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
197 val &= ~(1 << ctrl->aon.iso_shift);
198 iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
199 }
171 200
172 /* certain PLLs also need to be ungated from the ASIU top level */ 201 /* certain PLLs also need to be ungated from the ASIU top level */
173 if (ctrl->flags & IPROC_CLK_PLL_ASIU) { 202 if (ctrl->flags & IPROC_CLK_PLL_ASIU) {
174 val = readl(pll->asiu_base + ctrl->asiu.offset); 203 val = readl(pll->asiu_base + ctrl->asiu.offset);
175 val |= (1 << ctrl->asiu.en_shift); 204 val |= (1 << ctrl->asiu.en_shift);
176 writel(val, pll->asiu_base + ctrl->asiu.offset); 205 iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val);
177 } 206 }
178 207
179 return 0; 208 return 0;
@@ -185,11 +214,9 @@ static void __pll_put_in_reset(struct iproc_pll *pll)
185 const struct iproc_pll_ctrl *ctrl = pll->ctrl; 214 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
186 const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; 215 const struct iproc_pll_reset_ctrl *reset = &ctrl->reset;
187 216
188 val = readl(pll->pll_base + reset->offset); 217 val = readl(pll->control_base + reset->offset);
189 val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift); 218 val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift);
190 writel(val, pll->pll_base + reset->offset); 219 iproc_pll_write(pll, pll->control_base, reset->offset, val);
191 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
192 readl(pll->pll_base + reset->offset);
193} 220}
194 221
195static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp, 222static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp,
@@ -198,17 +225,19 @@ static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp,
198 u32 val; 225 u32 val;
199 const struct iproc_pll_ctrl *ctrl = pll->ctrl; 226 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
200 const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; 227 const struct iproc_pll_reset_ctrl *reset = &ctrl->reset;
228 const struct iproc_pll_dig_filter_ctrl *dig_filter = &ctrl->dig_filter;
229
230 val = readl(pll->control_base + dig_filter->offset);
231 val &= ~(bit_mask(dig_filter->ki_width) << dig_filter->ki_shift |
232 bit_mask(dig_filter->kp_width) << dig_filter->kp_shift |
233 bit_mask(dig_filter->ka_width) << dig_filter->ka_shift);
234 val |= ki << dig_filter->ki_shift | kp << dig_filter->kp_shift |
235 ka << dig_filter->ka_shift;
236 iproc_pll_write(pll, pll->control_base, dig_filter->offset, val);
201 237
202 val = readl(pll->pll_base + reset->offset); 238 val = readl(pll->control_base + reset->offset);
203 val &= ~(bit_mask(reset->ki_width) << reset->ki_shift |
204 bit_mask(reset->kp_width) << reset->kp_shift |
205 bit_mask(reset->ka_width) << reset->ka_shift);
206 val |= ki << reset->ki_shift | kp << reset->kp_shift |
207 ka << reset->ka_shift;
208 val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift; 239 val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift;
209 writel(val, pll->pll_base + reset->offset); 240 iproc_pll_write(pll, pll->control_base, reset->offset, val);
210 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
211 readl(pll->pll_base + reset->offset);
212} 241}
213 242
214static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, 243static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index,
@@ -263,10 +292,9 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index,
263 /* put PLL in reset */ 292 /* put PLL in reset */
264 __pll_put_in_reset(pll); 293 __pll_put_in_reset(pll);
265 294
266 writel(0, pll->pll_base + ctrl->vco_ctrl.u_offset); 295 iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0);
267 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) 296
268 readl(pll->pll_base + ctrl->vco_ctrl.u_offset); 297 val = readl(pll->control_base + ctrl->vco_ctrl.l_offset);
269 val = readl(pll->pll_base + ctrl->vco_ctrl.l_offset);
270 298
271 if (rate >= VCO_LOW && rate < VCO_MID) 299 if (rate >= VCO_LOW && rate < VCO_MID)
272 val |= (1 << PLL_VCO_LOW_SHIFT); 300 val |= (1 << PLL_VCO_LOW_SHIFT);
@@ -276,36 +304,29 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index,
276 else 304 else
277 val |= (1 << PLL_VCO_HIGH_SHIFT); 305 val |= (1 << PLL_VCO_HIGH_SHIFT);
278 306
279 writel(val, pll->pll_base + ctrl->vco_ctrl.l_offset); 307 iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.l_offset, val);
280 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
281 readl(pll->pll_base + ctrl->vco_ctrl.l_offset);
282 308
283 /* program integer part of NDIV */ 309 /* program integer part of NDIV */
284 val = readl(pll->pll_base + ctrl->ndiv_int.offset); 310 val = readl(pll->control_base + ctrl->ndiv_int.offset);
285 val &= ~(bit_mask(ctrl->ndiv_int.width) << ctrl->ndiv_int.shift); 311 val &= ~(bit_mask(ctrl->ndiv_int.width) << ctrl->ndiv_int.shift);
286 val |= vco->ndiv_int << ctrl->ndiv_int.shift; 312 val |= vco->ndiv_int << ctrl->ndiv_int.shift;
287 writel(val, pll->pll_base + ctrl->ndiv_int.offset); 313 iproc_pll_write(pll, pll->control_base, ctrl->ndiv_int.offset, val);
288 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
289 readl(pll->pll_base + ctrl->ndiv_int.offset);
290 314
291 /* program fractional part of NDIV */ 315 /* program fractional part of NDIV */
292 if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) { 316 if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
293 val = readl(pll->pll_base + ctrl->ndiv_frac.offset); 317 val = readl(pll->control_base + ctrl->ndiv_frac.offset);
294 val &= ~(bit_mask(ctrl->ndiv_frac.width) << 318 val &= ~(bit_mask(ctrl->ndiv_frac.width) <<
295 ctrl->ndiv_frac.shift); 319 ctrl->ndiv_frac.shift);
296 val |= vco->ndiv_frac << ctrl->ndiv_frac.shift; 320 val |= vco->ndiv_frac << ctrl->ndiv_frac.shift;
297 writel(val, pll->pll_base + ctrl->ndiv_frac.offset); 321 iproc_pll_write(pll, pll->control_base, ctrl->ndiv_frac.offset,
298 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) 322 val);
299 readl(pll->pll_base + ctrl->ndiv_frac.offset);
300 } 323 }
301 324
302 /* program PDIV */ 325 /* program PDIV */
303 val = readl(pll->pll_base + ctrl->pdiv.offset); 326 val = readl(pll->control_base + ctrl->pdiv.offset);
304 val &= ~(bit_mask(ctrl->pdiv.width) << ctrl->pdiv.shift); 327 val &= ~(bit_mask(ctrl->pdiv.width) << ctrl->pdiv.shift);
305 val |= vco->pdiv << ctrl->pdiv.shift; 328 val |= vco->pdiv << ctrl->pdiv.shift;
306 writel(val, pll->pll_base + ctrl->pdiv.offset); 329 iproc_pll_write(pll, pll->control_base, ctrl->pdiv.offset, val);
307 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
308 readl(pll->pll_base + ctrl->pdiv.offset);
309 330
310 __pll_bring_out_reset(pll, kp, ka, ki); 331 __pll_bring_out_reset(pll, kp, ka, ki);
311 332
@@ -345,14 +366,14 @@ static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw,
345 struct iproc_pll *pll = clk->pll; 366 struct iproc_pll *pll = clk->pll;
346 const struct iproc_pll_ctrl *ctrl = pll->ctrl; 367 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
347 u32 val; 368 u32 val;
348 u64 ndiv; 369 u64 ndiv, ndiv_int, ndiv_frac;
349 unsigned int ndiv_int, ndiv_frac, pdiv; 370 unsigned int pdiv;
350 371
351 if (parent_rate == 0) 372 if (parent_rate == 0)
352 return 0; 373 return 0;
353 374
354 /* PLL needs to be locked */ 375 /* PLL needs to be locked */
355 val = readl(pll->pll_base + ctrl->status.offset); 376 val = readl(pll->status_base + ctrl->status.offset);
356 if ((val & (1 << ctrl->status.shift)) == 0) { 377 if ((val & (1 << ctrl->status.shift)) == 0) {
357 clk->rate = 0; 378 clk->rate = 0;
358 return 0; 379 return 0;
@@ -363,25 +384,22 @@ static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw,
363 * 384 *
364 * ((ndiv_int + ndiv_frac / 2^20) * (parent clock rate / pdiv) 385 * ((ndiv_int + ndiv_frac / 2^20) * (parent clock rate / pdiv)
365 */ 386 */
366 val = readl(pll->pll_base + ctrl->ndiv_int.offset); 387 val = readl(pll->control_base + ctrl->ndiv_int.offset);
367 ndiv_int = (val >> ctrl->ndiv_int.shift) & 388 ndiv_int = (val >> ctrl->ndiv_int.shift) &
368 bit_mask(ctrl->ndiv_int.width); 389 bit_mask(ctrl->ndiv_int.width);
369 ndiv = (u64)ndiv_int << ctrl->ndiv_int.shift; 390 ndiv = ndiv_int << 20;
370 391
371 if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) { 392 if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
372 val = readl(pll->pll_base + ctrl->ndiv_frac.offset); 393 val = readl(pll->control_base + ctrl->ndiv_frac.offset);
373 ndiv_frac = (val >> ctrl->ndiv_frac.shift) & 394 ndiv_frac = (val >> ctrl->ndiv_frac.shift) &
374 bit_mask(ctrl->ndiv_frac.width); 395 bit_mask(ctrl->ndiv_frac.width);
375 396 ndiv += ndiv_frac;
376 if (ndiv_frac != 0)
377 ndiv = ((u64)ndiv_int << ctrl->ndiv_int.shift) |
378 ndiv_frac;
379 } 397 }
380 398
381 val = readl(pll->pll_base + ctrl->pdiv.offset); 399 val = readl(pll->control_base + ctrl->pdiv.offset);
382 pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width); 400 pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width);
383 401
384 clk->rate = (ndiv * parent_rate) >> ctrl->ndiv_int.shift; 402 clk->rate = (ndiv * parent_rate) >> 20;
385 403
386 if (pdiv == 0) 404 if (pdiv == 0)
387 clk->rate *= 2; 405 clk->rate *= 2;
@@ -443,16 +461,14 @@ static int iproc_clk_enable(struct clk_hw *hw)
443 u32 val; 461 u32 val;
444 462
445 /* channel enable is active low */ 463 /* channel enable is active low */
446 val = readl(pll->pll_base + ctrl->enable.offset); 464 val = readl(pll->control_base + ctrl->enable.offset);
447 val &= ~(1 << ctrl->enable.enable_shift); 465 val &= ~(1 << ctrl->enable.enable_shift);
448 writel(val, pll->pll_base + ctrl->enable.offset); 466 iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
449 467
450 /* also make sure channel is not held */ 468 /* also make sure channel is not held */
451 val = readl(pll->pll_base + ctrl->enable.offset); 469 val = readl(pll->control_base + ctrl->enable.offset);
452 val &= ~(1 << ctrl->enable.hold_shift); 470 val &= ~(1 << ctrl->enable.hold_shift);
453 writel(val, pll->pll_base + ctrl->enable.offset); 471 iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
454 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
455 readl(pll->pll_base + ctrl->enable.offset);
456 472
457 return 0; 473 return 0;
458} 474}
@@ -467,11 +483,9 @@ static void iproc_clk_disable(struct clk_hw *hw)
467 if (ctrl->flags & IPROC_CLK_AON) 483 if (ctrl->flags & IPROC_CLK_AON)
468 return; 484 return;
469 485
470 val = readl(pll->pll_base + ctrl->enable.offset); 486 val = readl(pll->control_base + ctrl->enable.offset);
471 val |= 1 << ctrl->enable.enable_shift; 487 val |= 1 << ctrl->enable.enable_shift;
472 writel(val, pll->pll_base + ctrl->enable.offset); 488 iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
473 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
474 readl(pll->pll_base + ctrl->enable.offset);
475} 489}
476 490
477static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw, 491static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw,
@@ -486,7 +500,7 @@ static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw,
486 if (parent_rate == 0) 500 if (parent_rate == 0)
487 return 0; 501 return 0;
488 502
489 val = readl(pll->pll_base + ctrl->mdiv.offset); 503 val = readl(pll->control_base + ctrl->mdiv.offset);
490 mdiv = (val >> ctrl->mdiv.shift) & bit_mask(ctrl->mdiv.width); 504 mdiv = (val >> ctrl->mdiv.shift) & bit_mask(ctrl->mdiv.width);
491 if (mdiv == 0) 505 if (mdiv == 0)
492 mdiv = 256; 506 mdiv = 256;
@@ -533,16 +547,14 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
533 if (div > 256) 547 if (div > 256)
534 return -EINVAL; 548 return -EINVAL;
535 549
536 val = readl(pll->pll_base + ctrl->mdiv.offset); 550 val = readl(pll->control_base + ctrl->mdiv.offset);
537 if (div == 256) { 551 if (div == 256) {
538 val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift); 552 val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift);
539 } else { 553 } else {
540 val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift); 554 val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift);
541 val |= div << ctrl->mdiv.shift; 555 val |= div << ctrl->mdiv.shift;
542 } 556 }
543 writel(val, pll->pll_base + ctrl->mdiv.offset); 557 iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val);
544 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
545 readl(pll->pll_base + ctrl->mdiv.offset);
546 clk->rate = parent_rate / div; 558 clk->rate = parent_rate / div;
547 559
548 return 0; 560 return 0;
@@ -567,11 +579,10 @@ static void iproc_pll_sw_cfg(struct iproc_pll *pll)
567 if (ctrl->flags & IPROC_CLK_PLL_NEEDS_SW_CFG) { 579 if (ctrl->flags & IPROC_CLK_PLL_NEEDS_SW_CFG) {
568 u32 val; 580 u32 val;
569 581
570 val = readl(pll->pll_base + ctrl->sw_ctrl.offset); 582 val = readl(pll->control_base + ctrl->sw_ctrl.offset);
571 val |= BIT(ctrl->sw_ctrl.shift); 583 val |= BIT(ctrl->sw_ctrl.shift);
572 writel(val, pll->pll_base + ctrl->sw_ctrl.offset); 584 iproc_pll_write(pll, pll->control_base, ctrl->sw_ctrl.offset,
573 if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) 585 val);
574 readl(pll->pll_base + ctrl->sw_ctrl.offset);
575 } 586 }
576} 587}
577 588
@@ -606,13 +617,12 @@ void __init iproc_pll_clk_setup(struct device_node *node,
606 if (WARN_ON(!pll->clks)) 617 if (WARN_ON(!pll->clks))
607 goto err_clks; 618 goto err_clks;
608 619
609 pll->pll_base = of_iomap(node, 0); 620 pll->control_base = of_iomap(node, 0);
610 if (WARN_ON(!pll->pll_base)) 621 if (WARN_ON(!pll->control_base))
611 goto err_pll_iomap; 622 goto err_pll_iomap;
612 623
624 /* Some SoCs do not require the pwr_base, thus failing is not fatal */
613 pll->pwr_base = of_iomap(node, 1); 625 pll->pwr_base = of_iomap(node, 1);
614 if (WARN_ON(!pll->pwr_base))
615 goto err_pwr_iomap;
616 626
617 /* some PLLs require gating control at the top ASIU level */ 627 /* some PLLs require gating control at the top ASIU level */
618 if (pll_ctrl->flags & IPROC_CLK_PLL_ASIU) { 628 if (pll_ctrl->flags & IPROC_CLK_PLL_ASIU) {
@@ -621,6 +631,16 @@ void __init iproc_pll_clk_setup(struct device_node *node,
621 goto err_asiu_iomap; 631 goto err_asiu_iomap;
622 } 632 }
623 633
634 if (pll_ctrl->flags & IPROC_CLK_PLL_SPLIT_STAT_CTRL) {
635 /* Some SoCs have a split status/control. If this does not
636 * exist, assume they are unified.
637 */
638 pll->status_base = of_iomap(node, 2);
639 if (!pll->status_base)
640 goto err_status_iomap;
641 } else
642 pll->status_base = pll->control_base;
643
624 /* initialize and register the PLL itself */ 644 /* initialize and register the PLL itself */
625 pll->ctrl = pll_ctrl; 645 pll->ctrl = pll_ctrl;
626 646
@@ -691,14 +711,18 @@ err_clk_register:
691 clk_unregister(pll->clk_data.clks[i]); 711 clk_unregister(pll->clk_data.clks[i]);
692 712
693err_pll_register: 713err_pll_register:
714 if (pll->status_base != pll->control_base)
715 iounmap(pll->status_base);
716
717err_status_iomap:
694 if (pll->asiu_base) 718 if (pll->asiu_base)
695 iounmap(pll->asiu_base); 719 iounmap(pll->asiu_base);
696 720
697err_asiu_iomap: 721err_asiu_iomap:
698 iounmap(pll->pwr_base); 722 if (pll->pwr_base)
723 iounmap(pll->pwr_base);
699 724
700err_pwr_iomap: 725 iounmap(pll->control_base);
701 iounmap(pll->pll_base);
702 726
703err_pll_iomap: 727err_pll_iomap:
704 kfree(pll->clks); 728 kfree(pll->clks);
diff --git a/drivers/clk/bcm/clk-iproc.h b/drivers/clk/bcm/clk-iproc.h
index d834b7abd5c6..8988de70a98c 100644
--- a/drivers/clk/bcm/clk-iproc.h
+++ b/drivers/clk/bcm/clk-iproc.h
@@ -49,6 +49,18 @@
49#define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4) 49#define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4)
50 50
51/* 51/*
52 * Some PLLs use a different way to control clock power, via the PWRDWN bit in
53 * the PLL control register
54 */
55#define IPROC_CLK_EMBED_PWRCTRL BIT(5)
56
57/*
58 * Some PLLs have separate registers for Status and Control. Identify this to
59 * let the driver know if additional registers need to be used
60 */
61#define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6)
62
63/*
52 * Parameters for VCO frequency configuration 64 * Parameters for VCO frequency configuration
53 * 65 *
54 * VCO frequency = 66 * VCO frequency =
@@ -88,12 +100,19 @@ struct iproc_pll_aon_pwr_ctrl {
88}; 100};
89 101
90/* 102/*
91 * Control of the PLL reset, with Ki, Kp, and Ka parameters 103 * Control of the PLL reset
92 */ 104 */
93struct iproc_pll_reset_ctrl { 105struct iproc_pll_reset_ctrl {
94 unsigned int offset; 106 unsigned int offset;
95 unsigned int reset_shift; 107 unsigned int reset_shift;
96 unsigned int p_reset_shift; 108 unsigned int p_reset_shift;
109};
110
111/*
112 * Control of the Ki, Kp, and Ka parameters
113 */
114struct iproc_pll_dig_filter_ctrl {
115 unsigned int offset;
97 unsigned int ki_shift; 116 unsigned int ki_shift;
98 unsigned int ki_width; 117 unsigned int ki_width;
99 unsigned int kp_shift; 118 unsigned int kp_shift;
@@ -123,6 +142,7 @@ struct iproc_pll_ctrl {
123 struct iproc_pll_aon_pwr_ctrl aon; 142 struct iproc_pll_aon_pwr_ctrl aon;
124 struct iproc_asiu_gate asiu; 143 struct iproc_asiu_gate asiu;
125 struct iproc_pll_reset_ctrl reset; 144 struct iproc_pll_reset_ctrl reset;
145 struct iproc_pll_dig_filter_ctrl dig_filter;
126 struct iproc_pll_sw_ctrl sw_ctrl; 146 struct iproc_pll_sw_ctrl sw_ctrl;
127 struct iproc_clk_reg_op ndiv_int; 147 struct iproc_clk_reg_op ndiv_int;
128 struct iproc_clk_reg_op ndiv_frac; 148 struct iproc_clk_reg_op ndiv_frac;
diff --git a/drivers/clk/bcm/clk-ns2.c b/drivers/clk/bcm/clk-ns2.c
new file mode 100644
index 000000000000..a564e9248814
--- /dev/null
+++ b/drivers/clk/bcm/clk-ns2.c
@@ -0,0 +1,288 @@
1/*
2 * Copyright (C) 2015 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <linux/clk-provider.h>
17#include <linux/io.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20
21#include <dt-bindings/clock/bcm-ns2.h>
22#include "clk-iproc.h"
23
24#define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
25
26#define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
27 .pwr_shift = ps, .iso_shift = is }
28
29#define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
30 .p_reset_shift = prs }
31
32#define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\
33 .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \
34 .ka_width = kaw }
35
36#define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
37
38#define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
39 .hold_shift = hs, .bypass_shift = bs }
40
41static const struct iproc_pll_ctrl genpll_scr = {
42 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
43 .aon = AON_VAL(0x0, 1, 15, 12),
44 .reset = RESET_VAL(0x4, 2, 1),
45 .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3),
46 .ndiv_int = REG_VAL(0x8, 4, 10),
47 .pdiv = REG_VAL(0x8, 0, 4),
48 .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
49 .status = REG_VAL(0x0, 27, 1),
50};
51
52
53static const struct iproc_clk_ctrl genpll_scr_clk[] = {
54 /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
55 * in NS2. However, it doesn't appear to be used anywhere, so setting
56 * it to 0.
57 */
58 [BCM_NS2_GENPLL_SCR_SCR_CLK] = {
59 .channel = BCM_NS2_GENPLL_SCR_SCR_CLK,
60 .flags = IPROC_CLK_AON,
61 .enable = ENABLE_VAL(0x0, 18, 12, 0),
62 .mdiv = REG_VAL(0x18, 0, 8),
63 },
64 [BCM_NS2_GENPLL_SCR_FS_CLK] = {
65 .channel = BCM_NS2_GENPLL_SCR_FS_CLK,
66 .flags = IPROC_CLK_AON,
67 .enable = ENABLE_VAL(0x0, 19, 13, 0),
68 .mdiv = REG_VAL(0x18, 8, 8),
69 },
70 [BCM_NS2_GENPLL_SCR_AUDIO_CLK] = {
71 .channel = BCM_NS2_GENPLL_SCR_AUDIO_CLK,
72 .flags = IPROC_CLK_AON,
73 .enable = ENABLE_VAL(0x0, 20, 14, 0),
74 .mdiv = REG_VAL(0x14, 0, 8),
75 },
76 [BCM_NS2_GENPLL_SCR_CH3_UNUSED] = {
77 .channel = BCM_NS2_GENPLL_SCR_CH3_UNUSED,
78 .flags = IPROC_CLK_AON,
79 .enable = ENABLE_VAL(0x0, 21, 15, 0),
80 .mdiv = REG_VAL(0x14, 8, 8),
81 },
82 [BCM_NS2_GENPLL_SCR_CH4_UNUSED] = {
83 .channel = BCM_NS2_GENPLL_SCR_CH4_UNUSED,
84 .flags = IPROC_CLK_AON,
85 .enable = ENABLE_VAL(0x0, 22, 16, 0),
86 .mdiv = REG_VAL(0x14, 16, 8),
87 },
88 [BCM_NS2_GENPLL_SCR_CH5_UNUSED] = {
89 .channel = BCM_NS2_GENPLL_SCR_CH5_UNUSED,
90 .flags = IPROC_CLK_AON,
91 .enable = ENABLE_VAL(0x0, 23, 17, 0),
92 .mdiv = REG_VAL(0x14, 24, 8),
93 },
94};
95
96static void __init ns2_genpll_scr_clk_init(struct device_node *node)
97{
98 iproc_pll_clk_setup(node, &genpll_scr, NULL, 0, genpll_scr_clk,
99 ARRAY_SIZE(genpll_scr_clk));
100}
101CLK_OF_DECLARE(ns2_genpll_src_clk, "brcm,ns2-genpll-scr",
102 ns2_genpll_scr_clk_init);
103
104static const struct iproc_pll_ctrl genpll_sw = {
105 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
106 .aon = AON_VAL(0x0, 2, 9, 8),
107 .reset = RESET_VAL(0x4, 2, 1),
108 .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3),
109 .ndiv_int = REG_VAL(0x8, 4, 10),
110 .pdiv = REG_VAL(0x8, 0, 4),
111 .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
112 .status = REG_VAL(0x0, 13, 1),
113};
114
115static const struct iproc_clk_ctrl genpll_sw_clk[] = {
116 /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
117 * in NS2. However, it doesn't appear to be used anywhere, so setting
118 * it to 0.
119 */
120 [BCM_NS2_GENPLL_SW_RPE_CLK] = {
121 .channel = BCM_NS2_GENPLL_SW_RPE_CLK,
122 .flags = IPROC_CLK_AON,
123 .enable = ENABLE_VAL(0x0, 18, 12, 0),
124 .mdiv = REG_VAL(0x18, 0, 8),
125 },
126 [BCM_NS2_GENPLL_SW_250_CLK] = {
127 .channel = BCM_NS2_GENPLL_SW_250_CLK,
128 .flags = IPROC_CLK_AON,
129 .enable = ENABLE_VAL(0x0, 19, 13, 0),
130 .mdiv = REG_VAL(0x18, 8, 8),
131 },
132 [BCM_NS2_GENPLL_SW_NIC_CLK] = {
133 .channel = BCM_NS2_GENPLL_SW_NIC_CLK,
134 .flags = IPROC_CLK_AON,
135 .enable = ENABLE_VAL(0x0, 20, 14, 0),
136 .mdiv = REG_VAL(0x14, 0, 8),
137 },
138 [BCM_NS2_GENPLL_SW_CHIMP_CLK] = {
139 .channel = BCM_NS2_GENPLL_SW_CHIMP_CLK,
140 .flags = IPROC_CLK_AON,
141 .enable = ENABLE_VAL(0x0, 21, 15, 0),
142 .mdiv = REG_VAL(0x14, 8, 8),
143 },
144 [BCM_NS2_GENPLL_SW_PORT_CLK] = {
145 .channel = BCM_NS2_GENPLL_SW_PORT_CLK,
146 .flags = IPROC_CLK_AON,
147 .enable = ENABLE_VAL(0x0, 22, 16, 0),
148 .mdiv = REG_VAL(0x14, 16, 8),
149 },
150 [BCM_NS2_GENPLL_SW_SDIO_CLK] = {
151 .channel = BCM_NS2_GENPLL_SW_SDIO_CLK,
152 .flags = IPROC_CLK_AON,
153 .enable = ENABLE_VAL(0x0, 23, 17, 0),
154 .mdiv = REG_VAL(0x14, 24, 8),
155 },
156};
157
158static void __init ns2_genpll_sw_clk_init(struct device_node *node)
159{
160 iproc_pll_clk_setup(node, &genpll_sw, NULL, 0, genpll_sw_clk,
161 ARRAY_SIZE(genpll_sw_clk));
162}
163CLK_OF_DECLARE(ns2_genpll_sw_clk, "brcm,ns2-genpll-sw",
164 ns2_genpll_sw_clk_init);
165
166static const struct iproc_pll_ctrl lcpll_ddr = {
167 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
168 .aon = AON_VAL(0x0, 2, 1, 0),
169 .reset = RESET_VAL(0x4, 2, 1),
170 .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 1, 4),
171 .ndiv_int = REG_VAL(0x8, 4, 10),
172 .pdiv = REG_VAL(0x8, 0, 4),
173 .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
174 .status = REG_VAL(0x0, 0, 1),
175};
176
177static const struct iproc_clk_ctrl lcpll_ddr_clk[] = {
178 /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
179 * in NS2. However, it doesn't appear to be used anywhere, so setting
180 * it to 0.
181 */
182 [BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK] = {
183 .channel = BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK,
184 .flags = IPROC_CLK_AON,
185 .enable = ENABLE_VAL(0x0, 18, 12, 0),
186 .mdiv = REG_VAL(0x14, 0, 8),
187 },
188 [BCM_NS2_LCPLL_DDR_DDR_CLK] = {
189 .channel = BCM_NS2_LCPLL_DDR_DDR_CLK,
190 .flags = IPROC_CLK_AON,
191 .enable = ENABLE_VAL(0x0, 19, 13, 0),
192 .mdiv = REG_VAL(0x14, 8, 8),
193 },
194 [BCM_NS2_LCPLL_DDR_CH2_UNUSED] = {
195 .channel = BCM_NS2_LCPLL_DDR_CH2_UNUSED,
196 .flags = IPROC_CLK_AON,
197 .enable = ENABLE_VAL(0x0, 20, 14, 0),
198 .mdiv = REG_VAL(0x10, 0, 8),
199 },
200 [BCM_NS2_LCPLL_DDR_CH3_UNUSED] = {
201 .channel = BCM_NS2_LCPLL_DDR_CH3_UNUSED,
202 .flags = IPROC_CLK_AON,
203 .enable = ENABLE_VAL(0x0, 21, 15, 0),
204 .mdiv = REG_VAL(0x10, 8, 8),
205 },
206 [BCM_NS2_LCPLL_DDR_CH4_UNUSED] = {
207 .channel = BCM_NS2_LCPLL_DDR_CH4_UNUSED,
208 .flags = IPROC_CLK_AON,
209 .enable = ENABLE_VAL(0x0, 22, 16, 0),
210 .mdiv = REG_VAL(0x10, 16, 8),
211 },
212 [BCM_NS2_LCPLL_DDR_CH5_UNUSED] = {
213 .channel = BCM_NS2_LCPLL_DDR_CH5_UNUSED,
214 .flags = IPROC_CLK_AON,
215 .enable = ENABLE_VAL(0x0, 23, 17, 0),
216 .mdiv = REG_VAL(0x10, 24, 8),
217 },
218};
219
220static void __init ns2_lcpll_ddr_clk_init(struct device_node *node)
221{
222 iproc_pll_clk_setup(node, &lcpll_ddr, NULL, 0, lcpll_ddr_clk,
223 ARRAY_SIZE(lcpll_ddr_clk));
224}
225CLK_OF_DECLARE(ns2_lcpll_ddr_clk, "brcm,ns2-lcpll-ddr",
226 ns2_lcpll_ddr_clk_init);
227
228static const struct iproc_pll_ctrl lcpll_ports = {
229 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
230 .aon = AON_VAL(0x0, 2, 5, 4),
231 .reset = RESET_VAL(0x4, 2, 1),
232 .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 1, 4),
233 .ndiv_int = REG_VAL(0x8, 4, 10),
234 .pdiv = REG_VAL(0x8, 0, 4),
235 .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
236 .status = REG_VAL(0x0, 0, 1),
237};
238
239static const struct iproc_clk_ctrl lcpll_ports_clk[] = {
240 /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
241 * in NS2. However, it doesn't appear to be used anywhere, so setting
242 * it to 0.
243 */
244 [BCM_NS2_LCPLL_PORTS_WAN_CLK] = {
245 .channel = BCM_NS2_LCPLL_PORTS_WAN_CLK,
246 .flags = IPROC_CLK_AON,
247 .enable = ENABLE_VAL(0x0, 18, 12, 0),
248 .mdiv = REG_VAL(0x14, 0, 8),
249 },
250 [BCM_NS2_LCPLL_PORTS_RGMII_CLK] = {
251 .channel = BCM_NS2_LCPLL_PORTS_RGMII_CLK,
252 .flags = IPROC_CLK_AON,
253 .enable = ENABLE_VAL(0x0, 19, 13, 0),
254 .mdiv = REG_VAL(0x14, 8, 8),
255 },
256 [BCM_NS2_LCPLL_PORTS_CH2_UNUSED] = {
257 .channel = BCM_NS2_LCPLL_PORTS_CH2_UNUSED,
258 .flags = IPROC_CLK_AON,
259 .enable = ENABLE_VAL(0x0, 20, 14, 0),
260 .mdiv = REG_VAL(0x10, 0, 8),
261 },
262 [BCM_NS2_LCPLL_PORTS_CH3_UNUSED] = {
263 .channel = BCM_NS2_LCPLL_PORTS_CH3_UNUSED,
264 .flags = IPROC_CLK_AON,
265 .enable = ENABLE_VAL(0x0, 21, 15, 0),
266 .mdiv = REG_VAL(0x10, 8, 8),
267 },
268 [BCM_NS2_LCPLL_PORTS_CH4_UNUSED] = {
269 .channel = BCM_NS2_LCPLL_PORTS_CH4_UNUSED,
270 .flags = IPROC_CLK_AON,
271 .enable = ENABLE_VAL(0x0, 22, 16, 0),
272 .mdiv = REG_VAL(0x10, 16, 8),
273 },
274 [BCM_NS2_LCPLL_PORTS_CH5_UNUSED] = {
275 .channel = BCM_NS2_LCPLL_PORTS_CH5_UNUSED,
276 .flags = IPROC_CLK_AON,
277 .enable = ENABLE_VAL(0x0, 23, 17, 0),
278 .mdiv = REG_VAL(0x10, 24, 8),
279 },
280};
281
282static void __init ns2_lcpll_ports_clk_init(struct device_node *node)
283{
284 iproc_pll_clk_setup(node, &lcpll_ports, NULL, 0, lcpll_ports_clk,
285 ARRAY_SIZE(lcpll_ports_clk));
286}
287CLK_OF_DECLARE(ns2_lcpll_ports_clk, "brcm,ns2-lcpll-ports",
288 ns2_lcpll_ports_clk_init);
diff --git a/drivers/clk/bcm/clk-nsp.c b/drivers/clk/bcm/clk-nsp.c
new file mode 100644
index 000000000000..cf66f640a47d
--- /dev/null
+++ b/drivers/clk/bcm/clk-nsp.c
@@ -0,0 +1,139 @@
1/*
2 * Copyright (C) 2015 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <linux/clk-provider.h>
17#include <linux/io.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20
21#include <dt-bindings/clock/bcm-nsp.h>
22#include "clk-iproc.h"
23
24#define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
25
26#define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
27 .pwr_shift = ps, .iso_shift = is }
28
29#define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
30 .p_reset_shift = prs }
31
32#define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\
33 .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \
34 .ka_width = kaw }
35
36#define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
37 .hold_shift = hs, .bypass_shift = bs }
38
39static void __init nsp_armpll_init(struct device_node *node)
40{
41 iproc_armpll_setup(node);
42}
43CLK_OF_DECLARE(nsp_armpll, "brcm,nsp-armpll", nsp_armpll_init);
44
45static const struct iproc_pll_ctrl genpll = {
46 .flags = IPROC_CLK_PLL_HAS_NDIV_FRAC | IPROC_CLK_EMBED_PWRCTRL,
47 .aon = AON_VAL(0x0, 1, 12, 0),
48 .reset = RESET_VAL(0x0, 11, 10),
49 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
50 .ndiv_int = REG_VAL(0x14, 20, 10),
51 .ndiv_frac = REG_VAL(0x14, 0, 20),
52 .pdiv = REG_VAL(0x18, 24, 3),
53 .status = REG_VAL(0x20, 12, 1),
54};
55
56static const struct iproc_clk_ctrl genpll_clk[] = {
57 [BCM_NSP_GENPLL_PHY_CLK] = {
58 .channel = BCM_NSP_GENPLL_PHY_CLK,
59 .flags = IPROC_CLK_AON,
60 .enable = ENABLE_VAL(0x4, 12, 6, 18),
61 .mdiv = REG_VAL(0x18, 16, 8),
62 },
63 [BCM_NSP_GENPLL_ENET_SW_CLK] = {
64 .channel = BCM_NSP_GENPLL_ENET_SW_CLK,
65 .flags = IPROC_CLK_AON,
66 .enable = ENABLE_VAL(0x4, 13, 7, 19),
67 .mdiv = REG_VAL(0x18, 8, 8),
68 },
69 [BCM_NSP_GENPLL_USB_PHY_REF_CLK] = {
70 .channel = BCM_NSP_GENPLL_USB_PHY_REF_CLK,
71 .flags = IPROC_CLK_AON,
72 .enable = ENABLE_VAL(0x4, 14, 8, 20),
73 .mdiv = REG_VAL(0x18, 0, 8),
74 },
75 [BCM_NSP_GENPLL_IPROCFAST_CLK] = {
76 .channel = BCM_NSP_GENPLL_IPROCFAST_CLK,
77 .flags = IPROC_CLK_AON,
78 .enable = ENABLE_VAL(0x4, 15, 9, 21),
79 .mdiv = REG_VAL(0x1c, 16, 8),
80 },
81 [BCM_NSP_GENPLL_SATA1_CLK] = {
82 .channel = BCM_NSP_GENPLL_SATA1_CLK,
83 .flags = IPROC_CLK_AON,
84 .enable = ENABLE_VAL(0x4, 16, 10, 22),
85 .mdiv = REG_VAL(0x1c, 8, 8),
86 },
87 [BCM_NSP_GENPLL_SATA2_CLK] = {
88 .channel = BCM_NSP_GENPLL_SATA2_CLK,
89 .flags = IPROC_CLK_AON,
90 .enable = ENABLE_VAL(0x4, 17, 11, 23),
91 .mdiv = REG_VAL(0x1c, 0, 8),
92 },
93};
94
95static void __init nsp_genpll_clk_init(struct device_node *node)
96{
97 iproc_pll_clk_setup(node, &genpll, NULL, 0, genpll_clk,
98 ARRAY_SIZE(genpll_clk));
99}
100CLK_OF_DECLARE(nsp_genpll_clk, "brcm,nsp-genpll", nsp_genpll_clk_init);
101
102static const struct iproc_pll_ctrl lcpll0 = {
103 .flags = IPROC_CLK_PLL_HAS_NDIV_FRAC | IPROC_CLK_EMBED_PWRCTRL,
104 .aon = AON_VAL(0x0, 1, 24, 0),
105 .reset = RESET_VAL(0x0, 23, 22),
106 .dig_filter = DF_VAL(0x0, 16, 3, 12, 4, 19, 4),
107 .ndiv_int = REG_VAL(0x4, 20, 8),
108 .ndiv_frac = REG_VAL(0x4, 0, 20),
109 .pdiv = REG_VAL(0x4, 28, 3),
110 .status = REG_VAL(0x10, 12, 1),
111};
112
113static const struct iproc_clk_ctrl lcpll0_clk[] = {
114 [BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK] = {
115 .channel = BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK,
116 .flags = IPROC_CLK_AON,
117 .enable = ENABLE_VAL(0x0, 6, 3, 9),
118 .mdiv = REG_VAL(0x8, 24, 8),
119 },
120 [BCM_NSP_LCPLL0_SDIO_CLK] = {
121 .channel = BCM_NSP_LCPLL0_SDIO_CLK,
122 .flags = IPROC_CLK_AON,
123 .enable = ENABLE_VAL(0x0, 7, 4, 10),
124 .mdiv = REG_VAL(0x8, 16, 8),
125 },
126 [BCM_NSP_LCPLL0_DDR_PHY_CLK] = {
127 .channel = BCM_NSP_LCPLL0_DDR_PHY_CLK,
128 .flags = IPROC_CLK_AON,
129 .enable = ENABLE_VAL(0x0, 8, 5, 11),
130 .mdiv = REG_VAL(0x8, 8, 8),
131 },
132};
133
134static void __init nsp_lcpll0_clk_init(struct device_node *node)
135{
136 iproc_pll_clk_setup(node, &lcpll0, NULL, 0, lcpll0_clk,
137 ARRAY_SIZE(lcpll0_clk));
138}
139CLK_OF_DECLARE(nsp_lcpll0_clk, "brcm,nsp-lcpll0", nsp_lcpll0_clk_init);
diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c
index 73153fc45ee9..23e0e3be6c37 100644
--- a/drivers/clk/berlin/bg2.c
+++ b/drivers/clk/berlin/bg2.c
@@ -490,8 +490,8 @@ static const struct berlin2_gate_data bg2_gates[] __initconst = {
490 { "usb0", "perif", 11 }, 490 { "usb0", "perif", 11 },
491 { "usb1", "perif", 12 }, 491 { "usb1", "perif", 12 },
492 { "pbridge", "perif", 13, CLK_IGNORE_UNUSED }, 492 { "pbridge", "perif", 13, CLK_IGNORE_UNUSED },
493 { "sdio0", "perif", 14, CLK_IGNORE_UNUSED }, 493 { "sdio0", "perif", 14 },
494 { "sdio1", "perif", 15, CLK_IGNORE_UNUSED }, 494 { "sdio1", "perif", 15 },
495 { "nfc", "perif", 17 }, 495 { "nfc", "perif", 17 },
496 { "smemc", "perif", 19 }, 496 { "smemc", "perif", 19 },
497 { "audiohd", "audiohd_pll", 26 }, 497 { "audiohd", "audiohd_pll", 26 },
diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
index 221f40c2b850..243f421abcb4 100644
--- a/drivers/clk/berlin/bg2q.c
+++ b/drivers/clk/berlin/bg2q.c
@@ -283,7 +283,7 @@ static const struct berlin2_gate_data bg2q_gates[] __initconst = {
283 { "usb2", "perif", 13 }, 283 { "usb2", "perif", 13 },
284 { "usb3", "perif", 14 }, 284 { "usb3", "perif", 14 },
285 { "pbridge", "perif", 15, CLK_IGNORE_UNUSED }, 285 { "pbridge", "perif", 15, CLK_IGNORE_UNUSED },
286 { "sdio", "perif", 16, CLK_IGNORE_UNUSED }, 286 { "sdio", "perif", 16 },
287 { "nfc", "perif", 18 }, 287 { "nfc", "perif", 18 },
288 { "pcie", "perif", 22 }, 288 { "pcie", "perif", 22 },
289}; 289};
diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c
deleted file mode 100644
index dd295e498309..000000000000
--- a/drivers/clk/clk-bcm2835.c
+++ /dev/null
@@ -1,55 +0,0 @@
1/*
2 * Copyright (C) 2010 Broadcom
3 * Copyright (C) 2012 Stephen Warren
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/clk-provider.h>
21#include <linux/clkdev.h>
22#include <linux/clk/bcm2835.h>
23#include <linux/of.h>
24
25/*
26 * These are fixed clocks. They're probably not all root clocks and it may
27 * be possible to turn them on and off but until this is mapped out better
28 * it's the only way they can be used.
29 */
30void __init bcm2835_init_clocks(void)
31{
32 struct clk *clk;
33 int ret;
34
35 clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
36 126000000);
37 if (IS_ERR(clk))
38 pr_err("apb_pclk not registered\n");
39
40 clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT,
41 3000000);
42 if (IS_ERR(clk))
43 pr_err("uart0_pclk not registered\n");
44 ret = clk_register_clkdev(clk, NULL, "20201000.uart");
45 if (ret)
46 pr_err("uart0_pclk alias not registered\n");
47
48 clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT,
49 125000000);
50 if (IS_ERR(clk))
51 pr_err("uart1_pclk not registered\n");
52 ret = clk_register_clkdev(clk, NULL, "20215000.uart");
53 if (ret)
54 pr_err("uart1_pclk alias not registered\n");
55}
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index f24d0a19ae70..3ace102a2a0a 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -24,7 +24,7 @@
24 * Traits of this clock: 24 * Traits of this clock:
25 * prepare - clk_prepare only ensures that parents are prepared 25 * prepare - clk_prepare only ensures that parents are prepared
26 * enable - clk_enable only ensures that parents are enabled 26 * enable - clk_enable only ensures that parents are enabled
27 * rate - rate is adjustable. clk->rate = DIV_ROUND_UP(parent->rate / divisor) 27 * rate - rate is adjustable. clk->rate = ceiling(parent->rate / divisor)
28 * parent - fixed parent. No clk_set_parent support 28 * parent - fixed parent. No clk_set_parent support
29 */ 29 */
30 30
@@ -132,7 +132,7 @@ unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
132 return parent_rate; 132 return parent_rate;
133 } 133 }
134 134
135 return DIV_ROUND_UP(parent_rate, div); 135 return DIV_ROUND_UP_ULL((u64)parent_rate, div);
136} 136}
137EXPORT_SYMBOL_GPL(divider_recalc_rate); 137EXPORT_SYMBOL_GPL(divider_recalc_rate);
138 138
@@ -210,7 +210,7 @@ static int _div_round_up(const struct clk_div_table *table,
210 unsigned long parent_rate, unsigned long rate, 210 unsigned long parent_rate, unsigned long rate,
211 unsigned long flags) 211 unsigned long flags)
212{ 212{
213 int div = DIV_ROUND_UP(parent_rate, rate); 213 int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
214 214
215 if (flags & CLK_DIVIDER_POWER_OF_TWO) 215 if (flags & CLK_DIVIDER_POWER_OF_TWO)
216 div = __roundup_pow_of_two(div); 216 div = __roundup_pow_of_two(div);
@@ -227,7 +227,7 @@ static int _div_round_closest(const struct clk_div_table *table,
227 int up, down; 227 int up, down;
228 unsigned long up_rate, down_rate; 228 unsigned long up_rate, down_rate;
229 229
230 up = DIV_ROUND_UP(parent_rate, rate); 230 up = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
231 down = parent_rate / rate; 231 down = parent_rate / rate;
232 232
233 if (flags & CLK_DIVIDER_POWER_OF_TWO) { 233 if (flags & CLK_DIVIDER_POWER_OF_TWO) {
@@ -238,8 +238,8 @@ static int _div_round_closest(const struct clk_div_table *table,
238 down = _round_down_table(table, down); 238 down = _round_down_table(table, down);
239 } 239 }
240 240
241 up_rate = DIV_ROUND_UP(parent_rate, up); 241 up_rate = DIV_ROUND_UP_ULL((u64)parent_rate, up);
242 down_rate = DIV_ROUND_UP(parent_rate, down); 242 down_rate = DIV_ROUND_UP_ULL((u64)parent_rate, down);
243 243
244 return (rate - up_rate) <= (down_rate - rate) ? up : down; 244 return (rate - up_rate) <= (down_rate - rate) ? up : down;
245} 245}
@@ -318,7 +318,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
318 } 318 }
319 parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 319 parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
320 rate * i); 320 rate * i);
321 now = DIV_ROUND_UP(parent_rate, i); 321 now = DIV_ROUND_UP_ULL((u64)parent_rate, i);
322 if (_is_best_div(rate, now, best, flags)) { 322 if (_is_best_div(rate, now, best, flags)) {
323 bestdiv = i; 323 bestdiv = i;
324 best = now; 324 best = now;
@@ -342,7 +342,7 @@ long divider_round_rate(struct clk_hw *hw, unsigned long rate,
342 342
343 div = clk_divider_bestdiv(hw, rate, prate, table, width, flags); 343 div = clk_divider_bestdiv(hw, rate, prate, table, width, flags);
344 344
345 return DIV_ROUND_UP(*prate, div); 345 return DIV_ROUND_UP_ULL((u64)*prate, div);
346} 346}
347EXPORT_SYMBOL_GPL(divider_round_rate); 347EXPORT_SYMBOL_GPL(divider_round_rate);
348 348
@@ -358,7 +358,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
358 bestdiv &= div_mask(divider->width); 358 bestdiv &= div_mask(divider->width);
359 bestdiv = _get_div(divider->table, bestdiv, divider->flags, 359 bestdiv = _get_div(divider->table, bestdiv, divider->flags,
360 divider->width); 360 divider->width);
361 return DIV_ROUND_UP(*prate, bestdiv); 361 return DIV_ROUND_UP_ULL((u64)*prate, bestdiv);
362 } 362 }
363 363
364 return divider_round_rate(hw, rate, prate, divider->table, 364 return divider_round_rate(hw, rate, prate, divider->table,
@@ -371,7 +371,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate,
371{ 371{
372 unsigned int div, value; 372 unsigned int div, value;
373 373
374 div = DIV_ROUND_UP(parent_rate, rate); 374 div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
375 375
376 if (!_is_valid_div(table, div, flags)) 376 if (!_is_valid_div(table, div, flags))
377 return -EINVAL; 377 return -EINVAL;
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index e85f856b8592..5c4955e33f7a 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -7,13 +7,14 @@
7 * 7 *
8 * Adjustable fractional divider clock implementation. 8 * Adjustable fractional divider clock implementation.
9 * Output rate = (m / n) * parent_rate. 9 * Output rate = (m / n) * parent_rate.
10 * Uses rational best approximation algorithm.
10 */ 11 */
11 12
12#include <linux/clk-provider.h> 13#include <linux/clk-provider.h>
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/device.h> 15#include <linux/device.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/gcd.h> 17#include <linux/rational.h>
17 18
18#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) 19#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
19 20
@@ -22,7 +23,8 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
22{ 23{
23 struct clk_fractional_divider *fd = to_clk_fd(hw); 24 struct clk_fractional_divider *fd = to_clk_fd(hw);
24 unsigned long flags = 0; 25 unsigned long flags = 0;
25 u32 val, m, n; 26 unsigned long m, n;
27 u32 val;
26 u64 ret; 28 u64 ret;
27 29
28 if (fd->lock) 30 if (fd->lock)
@@ -50,23 +52,33 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
50} 52}
51 53
52static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, 54static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
53 unsigned long *prate) 55 unsigned long *parent_rate)
54{ 56{
55 struct clk_fractional_divider *fd = to_clk_fd(hw); 57 struct clk_fractional_divider *fd = to_clk_fd(hw);
56 unsigned maxn = (fd->nmask >> fd->nshift) + 1; 58 unsigned long scale;
57 unsigned div; 59 unsigned long m, n;
60 u64 ret;
58 61
59 if (!rate || rate >= *prate) 62 if (!rate || rate >= *parent_rate)
60 return *prate; 63 return *parent_rate;
61 64
62 div = gcd(*prate, rate); 65 /*
66 * Get rate closer to *parent_rate to guarantee there is no overflow
67 * for m and n. In the result it will be the nearest rate left shifted
68 * by (scale - fd->nwidth) bits.
69 */
70 scale = fls_long(*parent_rate / rate - 1);
71 if (scale > fd->nwidth)
72 rate <<= scale - fd->nwidth;
63 73
64 while ((*prate / div) > maxn) { 74 rational_best_approximation(rate, *parent_rate,
65 div <<= 1; 75 GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
66 rate <<= 1; 76 &m, &n);
67 }
68 77
69 return rate; 78 ret = (u64)*parent_rate * m;
79 do_div(ret, n);
80
81 return ret;
70} 82}
71 83
72static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate, 84static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -74,13 +86,12 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
74{ 86{
75 struct clk_fractional_divider *fd = to_clk_fd(hw); 87 struct clk_fractional_divider *fd = to_clk_fd(hw);
76 unsigned long flags = 0; 88 unsigned long flags = 0;
77 unsigned long div; 89 unsigned long m, n;
78 unsigned n, m;
79 u32 val; 90 u32 val;
80 91
81 div = gcd(parent_rate, rate); 92 rational_best_approximation(rate, parent_rate,
82 m = rate / div; 93 GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
83 n = parent_rate / div; 94 &m, &n);
84 95
85 if (fd->lock) 96 if (fd->lock)
86 spin_lock_irqsave(fd->lock, flags); 97 spin_lock_irqsave(fd->lock, flags);
@@ -128,9 +139,11 @@ struct clk *clk_register_fractional_divider(struct device *dev,
128 139
129 fd->reg = reg; 140 fd->reg = reg;
130 fd->mshift = mshift; 141 fd->mshift = mshift;
131 fd->mmask = (BIT(mwidth) - 1) << mshift; 142 fd->mwidth = mwidth;
143 fd->mmask = GENMASK(mwidth - 1, 0) << mshift;
132 fd->nshift = nshift; 144 fd->nshift = nshift;
133 fd->nmask = (BIT(nwidth) - 1) << nshift; 145 fd->nwidth = nwidth;
146 fd->nmask = GENMASK(nwidth - 1, 0) << nshift;
134 fd->flags = clk_divider_flags; 147 fd->flags = clk_divider_flags;
135 fd->lock = lock; 148 fd->lock = lock;
136 fd->hw.init = &init; 149 fd->hw.init = &init;
diff --git a/drivers/clk/clk-max77802.c b/drivers/clk/clk-max77802.c
index 74c49b93a6eb..4a89f7979ba0 100644
--- a/drivers/clk/clk-max77802.c
+++ b/drivers/clk/clk-max77802.c
@@ -94,5 +94,5 @@ static struct platform_driver max77802_clk_driver = {
94module_platform_driver(max77802_clk_driver); 94module_platform_driver(max77802_clk_driver);
95 95
96MODULE_DESCRIPTION("MAXIM 77802 Clock Driver"); 96MODULE_DESCRIPTION("MAXIM 77802 Clock Driver");
97MODULE_AUTHOR("Javier Martinez Canillas <javier.martinez@collabora.co.uk>"); 97MODULE_AUTHOR("Javier Martinez Canillas <javier@osg.samsung.com");
98MODULE_LICENSE("GPL"); 98MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-multiplier.c b/drivers/clk/clk-multiplier.c
new file mode 100644
index 000000000000..fe7806506bf3
--- /dev/null
+++ b/drivers/clk/clk-multiplier.c
@@ -0,0 +1,130 @@
1/*
2 * Copyright (C) 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
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/bitops.h>
10#include <linux/clk-provider.h>
11#include <linux/err.h>
12#include <linux/export.h>
13#include <linux/kernel.h>
14#include <linux/of.h>
15#include <linux/slab.h>
16
17#define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw)
18
19static unsigned long __get_mult(struct clk_multiplier *mult,
20 unsigned long rate,
21 unsigned long parent_rate)
22{
23 if (mult->flags & CLK_MULTIPLIER_ROUND_CLOSEST)
24 return DIV_ROUND_CLOSEST(rate, parent_rate);
25
26 return rate / parent_rate;
27}
28
29static unsigned long clk_multiplier_recalc_rate(struct clk_hw *hw,
30 unsigned long parent_rate)
31{
32 struct clk_multiplier *mult = to_clk_multiplier(hw);
33 unsigned long val;
34
35 val = clk_readl(mult->reg) >> mult->shift;
36 val &= GENMASK(mult->width - 1, 0);
37
38 if (!val && mult->flags & CLK_MULTIPLIER_ZERO_BYPASS)
39 val = 1;
40
41 return parent_rate * val;
42}
43
44static bool __is_best_rate(unsigned long rate, unsigned long new,
45 unsigned long best, unsigned long flags)
46{
47 if (flags & CLK_MULTIPLIER_ROUND_CLOSEST)
48 return abs(rate - new) < abs(rate - best);
49
50 return new >= rate && new < best;
51}
52
53static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate,
54 unsigned long *best_parent_rate,
55 u8 width, unsigned long flags)
56{
57 unsigned long orig_parent_rate = *best_parent_rate;
58 unsigned long parent_rate, current_rate, best_rate = ~0;
59 unsigned int i, bestmult = 0;
60
61 if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
62 return rate / *best_parent_rate;
63
64 for (i = 1; i < ((1 << width) - 1); i++) {
65 if (rate == orig_parent_rate * i) {
66 /*
67 * This is the best case for us if we have a
68 * perfect match without changing the parent
69 * rate.
70 */
71 *best_parent_rate = orig_parent_rate;
72 return i;
73 }
74
75 parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
76 rate / i);
77 current_rate = parent_rate * i;
78
79 if (__is_best_rate(rate, current_rate, best_rate, flags)) {
80 bestmult = i;
81 best_rate = current_rate;
82 *best_parent_rate = parent_rate;
83 }
84 }
85
86 return bestmult;
87}
88
89static long clk_multiplier_round_rate(struct clk_hw *hw, unsigned long rate,
90 unsigned long *parent_rate)
91{
92 struct clk_multiplier *mult = to_clk_multiplier(hw);
93 unsigned long factor = __bestmult(hw, rate, parent_rate,
94 mult->width, mult->flags);
95
96 return *parent_rate * factor;
97}
98
99static int clk_multiplier_set_rate(struct clk_hw *hw, unsigned long rate,
100 unsigned long parent_rate)
101{
102 struct clk_multiplier *mult = to_clk_multiplier(hw);
103 unsigned long factor = __get_mult(mult, rate, parent_rate);
104 unsigned long flags = 0;
105 unsigned long val;
106
107 if (mult->lock)
108 spin_lock_irqsave(mult->lock, flags);
109 else
110 __acquire(mult->lock);
111
112 val = clk_readl(mult->reg);
113 val &= ~GENMASK(mult->width + mult->shift - 1, mult->shift);
114 val |= factor << mult->shift;
115 clk_writel(val, mult->reg);
116
117 if (mult->lock)
118 spin_unlock_irqrestore(mult->lock, flags);
119 else
120 __release(mult->lock);
121
122 return 0;
123}
124
125const struct clk_ops clk_multiplier_ops = {
126 .recalc_rate = clk_multiplier_recalc_rate,
127 .round_rate = clk_multiplier_round_rate,
128 .set_rate = clk_multiplier_set_rate,
129};
130EXPORT_SYMBOL_GPL(clk_multiplier_ops);
diff --git a/drivers/clk/clk-si514.c b/drivers/clk/clk-si514.c
new file mode 100644
index 000000000000..6af7dce54241
--- /dev/null
+++ b/drivers/clk/clk-si514.c
@@ -0,0 +1,379 @@
1/*
2 * Driver for Silicon Labs Si514 Programmable Oscillator
3 *
4 * Copyright (C) 2015 Topic Embedded Products
5 *
6 * Author: Mike Looijmans <mike.looijmans@topic.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/clk-provider.h>
20#include <linux/delay.h>
21#include <linux/module.h>
22#include <linux/i2c.h>
23#include <linux/regmap.h>
24#include <linux/slab.h>
25
26/* I2C registers */
27#define SI514_REG_LP 0
28#define SI514_REG_M_FRAC1 5
29#define SI514_REG_M_FRAC2 6
30#define SI514_REG_M_FRAC3 7
31#define SI514_REG_M_INT_FRAC 8
32#define SI514_REG_M_INT 9
33#define SI514_REG_HS_DIV 10
34#define SI514_REG_LS_HS_DIV 11
35#define SI514_REG_OE_STATE 14
36#define SI514_REG_RESET 128
37#define SI514_REG_CONTROL 132
38
39/* Register values */
40#define SI514_RESET_RST BIT(7)
41
42#define SI514_CONTROL_FCAL BIT(0)
43#define SI514_CONTROL_OE BIT(2)
44
45#define SI514_MIN_FREQ 100000U
46#define SI514_MAX_FREQ 250000000U
47
48#define FXO 31980000U
49
50#define FVCO_MIN 2080000000U
51#define FVCO_MAX 2500000000U
52
53#define HS_DIV_MAX 1022
54
55struct clk_si514 {
56 struct clk_hw hw;
57 struct regmap *regmap;
58 struct i2c_client *i2c_client;
59};
60#define to_clk_si514(_hw) container_of(_hw, struct clk_si514, hw)
61
62/* Multiplier/divider settings */
63struct clk_si514_muldiv {
64 u32 m_frac; /* 29-bit Fractional part of multiplier M */
65 u8 m_int; /* Integer part of multiplier M, 65..78 */
66 u8 ls_div_bits; /* 2nd divider, as 2^x */
67 u16 hs_div; /* 1st divider, must be even and 10<=x<=1022 */
68};
69
70/* Enables or disables the output driver */
71static int si514_enable_output(struct clk_si514 *data, bool enable)
72{
73 return regmap_update_bits(data->regmap, SI514_REG_CONTROL,
74 SI514_CONTROL_OE, enable ? SI514_CONTROL_OE : 0);
75}
76
77/* Retrieve clock multiplier and dividers from hardware */
78static int si514_get_muldiv(struct clk_si514 *data,
79 struct clk_si514_muldiv *settings)
80{
81 int err;
82 u8 reg[7];
83
84 err = regmap_bulk_read(data->regmap, SI514_REG_M_FRAC1,
85 reg, ARRAY_SIZE(reg));
86 if (err)
87 return err;
88
89 settings->m_frac = reg[0] | reg[1] << 8 | reg[2] << 16 |
90 (reg[3] & 0x1F) << 24;
91 settings->m_int = (reg[4] & 0x3f) << 3 | reg[3] >> 5;
92 settings->ls_div_bits = (reg[6] >> 4) & 0x07;
93 settings->hs_div = (reg[6] & 0x03) << 8 | reg[5];
94 return 0;
95}
96
97static int si514_set_muldiv(struct clk_si514 *data,
98 struct clk_si514_muldiv *settings)
99{
100 u8 lp;
101 u8 reg[7];
102 int err;
103
104 /* Calculate LP1/LP2 according to table 13 in the datasheet */
105 /* 65.259980246 */
106 if (settings->m_int < 65 ||
107 (settings->m_int == 65 && settings->m_frac <= 139575831))
108 lp = 0x22;
109 /* 67.859763463 */
110 else if (settings->m_int < 67 ||
111 (settings->m_int == 67 && settings->m_frac <= 461581994))
112 lp = 0x23;
113 /* 72.937624981 */
114 else if (settings->m_int < 72 ||
115 (settings->m_int == 72 && settings->m_frac <= 503383578))
116 lp = 0x33;
117 /* 75.843265046 */
118 else if (settings->m_int < 75 ||
119 (settings->m_int == 75 && settings->m_frac <= 452724474))
120 lp = 0x34;
121 else
122 lp = 0x44;
123
124 err = regmap_write(data->regmap, SI514_REG_LP, lp);
125 if (err < 0)
126 return err;
127
128 reg[0] = settings->m_frac;
129 reg[1] = settings->m_frac >> 8;
130 reg[2] = settings->m_frac >> 16;
131 reg[3] = settings->m_frac >> 24 | settings->m_int << 5;
132 reg[4] = settings->m_int >> 3;
133 reg[5] = settings->hs_div;
134 reg[6] = (settings->hs_div >> 8) | (settings->ls_div_bits << 4);
135
136 err = regmap_bulk_write(data->regmap, SI514_REG_HS_DIV, reg + 5, 2);
137 if (err < 0)
138 return err;
139 /*
140 * Writing to SI514_REG_M_INT_FRAC triggers the clock change, so that
141 * must be written last
142 */
143 return regmap_bulk_write(data->regmap, SI514_REG_M_FRAC1, reg, 5);
144}
145
146/* Calculate divider settings for a given frequency */
147static int si514_calc_muldiv(struct clk_si514_muldiv *settings,
148 unsigned long frequency)
149{
150 u64 m;
151 u32 ls_freq;
152 u32 tmp;
153 u8 res;
154
155 if ((frequency < SI514_MIN_FREQ) || (frequency > SI514_MAX_FREQ))
156 return -EINVAL;
157
158 /* Determine the minimum value of LS_DIV and resulting target freq. */
159 ls_freq = frequency;
160 if (frequency >= (FVCO_MIN / HS_DIV_MAX))
161 settings->ls_div_bits = 0;
162 else {
163 res = 1;
164 tmp = 2 * HS_DIV_MAX;
165 while (tmp <= (HS_DIV_MAX * 32)) {
166 if ((frequency * tmp) >= FVCO_MIN)
167 break;
168 ++res;
169 tmp <<= 1;
170 }
171 settings->ls_div_bits = res;
172 ls_freq = frequency << res;
173 }
174
175 /* Determine minimum HS_DIV, round up to even number */
176 settings->hs_div = DIV_ROUND_UP(FVCO_MIN >> 1, ls_freq) << 1;
177
178 /* M = LS_DIV x HS_DIV x frequency / F_XO (in fixed-point) */
179 m = ((u64)(ls_freq * settings->hs_div) << 29) + (FXO / 2);
180 do_div(m, FXO);
181 settings->m_frac = (u32)m & (BIT(29) - 1);
182 settings->m_int = (u32)(m >> 29);
183
184 return 0;
185}
186
187/* Calculate resulting frequency given the register settings */
188static unsigned long si514_calc_rate(struct clk_si514_muldiv *settings)
189{
190 u64 m = settings->m_frac | ((u64)settings->m_int << 29);
191 u32 d = settings->hs_div * BIT(settings->ls_div_bits);
192
193 return ((u32)(((m * FXO) + (FXO / 2)) >> 29)) / d;
194}
195
196static unsigned long si514_recalc_rate(struct clk_hw *hw,
197 unsigned long parent_rate)
198{
199 struct clk_si514 *data = to_clk_si514(hw);
200 struct clk_si514_muldiv settings;
201 int err;
202
203 err = si514_get_muldiv(data, &settings);
204 if (err) {
205 dev_err(&data->i2c_client->dev, "unable to retrieve settings\n");
206 return 0;
207 }
208
209 return si514_calc_rate(&settings);
210}
211
212static long si514_round_rate(struct clk_hw *hw, unsigned long rate,
213 unsigned long *parent_rate)
214{
215 struct clk_si514_muldiv settings;
216 int err;
217
218 if (!rate)
219 return 0;
220
221 err = si514_calc_muldiv(&settings, rate);
222 if (err)
223 return err;
224
225 return si514_calc_rate(&settings);
226}
227
228/*
229 * Update output frequency for big frequency changes (> 1000 ppm).
230 * The chip supports <1000ppm changes "on the fly", we haven't implemented
231 * that here.
232 */
233static int si514_set_rate(struct clk_hw *hw, unsigned long rate,
234 unsigned long parent_rate)
235{
236 struct clk_si514 *data = to_clk_si514(hw);
237 struct clk_si514_muldiv settings;
238 int err;
239
240 err = si514_calc_muldiv(&settings, rate);
241 if (err)
242 return err;
243
244 si514_enable_output(data, false);
245
246 err = si514_set_muldiv(data, &settings);
247 if (err < 0)
248 return err; /* Undefined state now, best to leave disabled */
249
250 /* Trigger calibration */
251 err = regmap_write(data->regmap, SI514_REG_CONTROL, SI514_CONTROL_FCAL);
252 if (err < 0)
253 return err;
254
255 /* Applying a new frequency can take up to 10ms */
256 usleep_range(10000, 12000);
257
258 si514_enable_output(data, true);
259
260 return err;
261}
262
263static const struct clk_ops si514_clk_ops = {
264 .recalc_rate = si514_recalc_rate,
265 .round_rate = si514_round_rate,
266 .set_rate = si514_set_rate,
267};
268
269static bool si514_regmap_is_volatile(struct device *dev, unsigned int reg)
270{
271 switch (reg) {
272 case SI514_REG_CONTROL:
273 case SI514_REG_RESET:
274 return true;
275 default:
276 return false;
277 }
278}
279
280static bool si514_regmap_is_writeable(struct device *dev, unsigned int reg)
281{
282 switch (reg) {
283 case SI514_REG_LP:
284 case SI514_REG_M_FRAC1 ... SI514_REG_LS_HS_DIV:
285 case SI514_REG_OE_STATE:
286 case SI514_REG_RESET:
287 case SI514_REG_CONTROL:
288 return true;
289 default:
290 return false;
291 }
292}
293
294static const struct regmap_config si514_regmap_config = {
295 .reg_bits = 8,
296 .val_bits = 8,
297 .cache_type = REGCACHE_RBTREE,
298 .max_register = SI514_REG_CONTROL,
299 .writeable_reg = si514_regmap_is_writeable,
300 .volatile_reg = si514_regmap_is_volatile,
301};
302
303static int si514_probe(struct i2c_client *client,
304 const struct i2c_device_id *id)
305{
306 struct clk_si514 *data;
307 struct clk_init_data init;
308 struct clk *clk;
309 int err;
310
311 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
312 if (!data)
313 return -ENOMEM;
314
315 init.ops = &si514_clk_ops;
316 init.flags = CLK_IS_ROOT;
317 init.num_parents = 0;
318 data->hw.init = &init;
319 data->i2c_client = client;
320
321 if (of_property_read_string(client->dev.of_node, "clock-output-names",
322 &init.name))
323 init.name = client->dev.of_node->name;
324
325 data->regmap = devm_regmap_init_i2c(client, &si514_regmap_config);
326 if (IS_ERR(data->regmap)) {
327 dev_err(&client->dev, "failed to allocate register map\n");
328 return PTR_ERR(data->regmap);
329 }
330
331 i2c_set_clientdata(client, data);
332
333 clk = devm_clk_register(&client->dev, &data->hw);
334 if (IS_ERR(clk)) {
335 dev_err(&client->dev, "clock registration failed\n");
336 return PTR_ERR(clk);
337 }
338 err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get,
339 clk);
340 if (err) {
341 dev_err(&client->dev, "unable to add clk provider\n");
342 return err;
343 }
344
345 return 0;
346}
347
348static int si514_remove(struct i2c_client *client)
349{
350 of_clk_del_provider(client->dev.of_node);
351 return 0;
352}
353
354static const struct i2c_device_id si514_id[] = {
355 { "si514", 0 },
356 { }
357};
358MODULE_DEVICE_TABLE(i2c, si514_id);
359
360static const struct of_device_id clk_si514_of_match[] = {
361 { .compatible = "silabs,si514" },
362 { },
363};
364MODULE_DEVICE_TABLE(of, clk_si514_of_match);
365
366static struct i2c_driver si514_driver = {
367 .driver = {
368 .name = "si514",
369 .of_match_table = clk_si514_of_match,
370 },
371 .probe = si514_probe,
372 .remove = si514_remove,
373 .id_table = si514_id,
374};
375module_i2c_driver(si514_driver);
376
377MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>");
378MODULE_DESCRIPTION("Si514 driver");
379MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 5596c0aac22f..e346b223199d 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -1183,13 +1183,13 @@ static int si5351_dt_parse(struct i2c_client *client,
1183 if (of_property_read_u32(child, "reg", &num)) { 1183 if (of_property_read_u32(child, "reg", &num)) {
1184 dev_err(&client->dev, "missing reg property of %s\n", 1184 dev_err(&client->dev, "missing reg property of %s\n",
1185 child->name); 1185 child->name);
1186 return -EINVAL; 1186 goto put_child;
1187 } 1187 }
1188 1188
1189 if (num >= 8 || 1189 if (num >= 8 ||
1190 (variant == SI5351_VARIANT_A3 && num >= 3)) { 1190 (variant == SI5351_VARIANT_A3 && num >= 3)) {
1191 dev_err(&client->dev, "invalid clkout %d\n", num); 1191 dev_err(&client->dev, "invalid clkout %d\n", num);
1192 return -EINVAL; 1192 goto put_child;
1193 } 1193 }
1194 1194
1195 if (!of_property_read_u32(child, "silabs,multisynth-source", 1195 if (!of_property_read_u32(child, "silabs,multisynth-source",
@@ -1207,7 +1207,7 @@ static int si5351_dt_parse(struct i2c_client *client,
1207 dev_err(&client->dev, 1207 dev_err(&client->dev,
1208 "invalid parent %d for multisynth %d\n", 1208 "invalid parent %d for multisynth %d\n",
1209 val, num); 1209 val, num);
1210 return -EINVAL; 1210 goto put_child;
1211 } 1211 }
1212 } 1212 }
1213 1213
@@ -1230,7 +1230,7 @@ static int si5351_dt_parse(struct i2c_client *client,
1230 dev_err(&client->dev, 1230 dev_err(&client->dev,
1231 "invalid parent %d for clkout %d\n", 1231 "invalid parent %d for clkout %d\n",
1232 val, num); 1232 val, num);
1233 return -EINVAL; 1233 goto put_child;
1234 } 1234 }
1235 pdata->clkout[num].clkout_src = 1235 pdata->clkout[num].clkout_src =
1236 SI5351_CLKOUT_SRC_CLKIN; 1236 SI5351_CLKOUT_SRC_CLKIN;
@@ -1239,7 +1239,7 @@ static int si5351_dt_parse(struct i2c_client *client,
1239 dev_err(&client->dev, 1239 dev_err(&client->dev,
1240 "invalid parent %d for clkout %d\n", 1240 "invalid parent %d for clkout %d\n",
1241 val, num); 1241 val, num);
1242 return -EINVAL; 1242 goto put_child;
1243 } 1243 }
1244 } 1244 }
1245 1245
@@ -1256,7 +1256,7 @@ static int si5351_dt_parse(struct i2c_client *client,
1256 dev_err(&client->dev, 1256 dev_err(&client->dev,
1257 "invalid drive strength %d for clkout %d\n", 1257 "invalid drive strength %d for clkout %d\n",
1258 val, num); 1258 val, num);
1259 return -EINVAL; 1259 goto put_child;
1260 } 1260 }
1261 } 1261 }
1262 1262
@@ -1283,7 +1283,7 @@ static int si5351_dt_parse(struct i2c_client *client,
1283 dev_err(&client->dev, 1283 dev_err(&client->dev,
1284 "invalid disable state %d for clkout %d\n", 1284 "invalid disable state %d for clkout %d\n",
1285 val, num); 1285 val, num);
1286 return -EINVAL; 1286 goto put_child;
1287 } 1287 }
1288 } 1288 }
1289 1289
@@ -1296,6 +1296,9 @@ static int si5351_dt_parse(struct i2c_client *client,
1296 client->dev.platform_data = pdata; 1296 client->dev.platform_data = pdata;
1297 1297
1298 return 0; 1298 return 0;
1299put_child:
1300 of_node_put(child);
1301 return -EINVAL;
1299} 1302}
1300#else 1303#else
1301static int si5351_dt_parse(struct i2c_client *client, enum si5351_variant variant) 1304static int si5351_dt_parse(struct i2c_client *client, enum si5351_variant variant)
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index 96a6190acac2..27c0da29eca3 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -27,7 +27,6 @@
27#include <linux/clkdev.h> 27#include <linux/clkdev.h>
28#include <linux/clk-provider.h> 28#include <linux/clk-provider.h>
29#include <linux/of_address.h> 29#include <linux/of_address.h>
30#include <asm/setup.h>
31 30
32/* Register SCU_PCPPLL bit fields */ 31/* Register SCU_PCPPLL bit fields */
33#define N_DIV_RD(src) (((src) & 0x000001ff)) 32#define N_DIV_RD(src) (((src) & 0x000001ff))
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 0ebcf449778a..f13c3f4228d4 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -272,7 +272,7 @@ late_initcall_sync(clk_disable_unused);
272 272
273/*** helper functions ***/ 273/*** helper functions ***/
274 274
275const char *__clk_get_name(struct clk *clk) 275const char *__clk_get_name(const struct clk *clk)
276{ 276{
277 return !clk ? NULL : clk->core->name; 277 return !clk ? NULL : clk->core->name;
278} 278}
@@ -427,6 +427,11 @@ bool clk_hw_is_prepared(const struct clk_hw *hw)
427 return clk_core_is_prepared(hw->core); 427 return clk_core_is_prepared(hw->core);
428} 428}
429 429
430bool clk_hw_is_enabled(const struct clk_hw *hw)
431{
432 return clk_core_is_enabled(hw->core);
433}
434
430bool __clk_is_enabled(struct clk *clk) 435bool __clk_is_enabled(struct clk *clk)
431{ 436{
432 if (!clk) 437 if (!clk)
@@ -1685,7 +1690,7 @@ static struct clk_core *__clk_init_parent(struct clk_core *core)
1685 "%s: multi-parent clocks must implement .get_parent\n", 1690 "%s: multi-parent clocks must implement .get_parent\n",
1686 __func__); 1691 __func__);
1687 goto out; 1692 goto out;
1688 }; 1693 }
1689 1694
1690 /* 1695 /*
1691 * Do our best to cache parent clocks in core->parents. This prevents 1696 * Do our best to cache parent clocks in core->parents. This prevents
@@ -2932,7 +2937,7 @@ struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
2932 unsigned int idx = clkspec->args[0]; 2937 unsigned int idx = clkspec->args[0];
2933 2938
2934 if (idx >= clk_data->clk_num) { 2939 if (idx >= clk_data->clk_num) {
2935 pr_err("%s: invalid clock index %d\n", __func__, idx); 2940 pr_err("%s: invalid clock index %u\n", __func__, idx);
2936 return ERR_PTR(-EINVAL); 2941 return ERR_PTR(-EINVAL);
2937 } 2942 }
2938 2943
@@ -3055,6 +3060,7 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
3055 u32 pv; 3060 u32 pv;
3056 int rc; 3061 int rc;
3057 int count; 3062 int count;
3063 struct clk *clk;
3058 3064
3059 if (index < 0) 3065 if (index < 0)
3060 return NULL; 3066 return NULL;
@@ -3080,8 +3086,25 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
3080 3086
3081 if (of_property_read_string_index(clkspec.np, "clock-output-names", 3087 if (of_property_read_string_index(clkspec.np, "clock-output-names",
3082 index, 3088 index,
3083 &clk_name) < 0) 3089 &clk_name) < 0) {
3084 clk_name = clkspec.np->name; 3090 /*
3091 * Best effort to get the name if the clock has been
3092 * registered with the framework. If the clock isn't
3093 * registered, we return the node name as the name of
3094 * the clock as long as #clock-cells = 0.
3095 */
3096 clk = of_clk_get_from_provider(&clkspec);
3097 if (IS_ERR(clk)) {
3098 if (clkspec.args_count == 0)
3099 clk_name = clkspec.np->name;
3100 else
3101 clk_name = NULL;
3102 } else {
3103 clk_name = __clk_get_name(clk);
3104 clk_put(clk);
3105 }
3106 }
3107
3085 3108
3086 of_node_put(clkspec.np); 3109 of_node_put(clkspec.np);
3087 return clk_name; 3110 return clk_name;
@@ -3179,13 +3202,15 @@ void __init of_clk_init(const struct of_device_id *matches)
3179 list_for_each_entry_safe(clk_provider, next, 3202 list_for_each_entry_safe(clk_provider, next,
3180 &clk_provider_list, node) { 3203 &clk_provider_list, node) {
3181 list_del(&clk_provider->node); 3204 list_del(&clk_provider->node);
3205 of_node_put(clk_provider->np);
3182 kfree(clk_provider); 3206 kfree(clk_provider);
3183 } 3207 }
3208 of_node_put(np);
3184 return; 3209 return;
3185 } 3210 }
3186 3211
3187 parent->clk_init_cb = match->data; 3212 parent->clk_init_cb = match->data;
3188 parent->np = np; 3213 parent->np = of_node_get(np);
3189 list_add_tail(&parent->node, &clk_provider_list); 3214 list_add_tail(&parent->node, &clk_provider_list);
3190 } 3215 }
3191 3216
@@ -3199,6 +3224,7 @@ void __init of_clk_init(const struct of_device_id *matches)
3199 of_clk_set_defaults(clk_provider->np, true); 3224 of_clk_set_defaults(clk_provider->np, true);
3200 3225
3201 list_del(&clk_provider->node); 3226 list_del(&clk_provider->node);
3227 of_node_put(clk_provider->np);
3202 kfree(clk_provider); 3228 kfree(clk_provider);
3203 is_init_done = true; 3229 is_init_done = true;
3204 } 3230 }
diff --git a/drivers/clk/hisilicon/clk-hi6220-stub.c b/drivers/clk/hisilicon/clk-hi6220-stub.c
index 2c4add11c1ca..8afb40ef40ce 100644
--- a/drivers/clk/hisilicon/clk-hi6220-stub.c
+++ b/drivers/clk/hisilicon/clk-hi6220-stub.c
@@ -230,7 +230,7 @@ static int hi6220_stub_clk_probe(struct platform_device *pdev)
230 if (IS_ERR(stub_clk->mbox)) { 230 if (IS_ERR(stub_clk->mbox)) {
231 dev_err(dev, "failed get mailbox channel\n"); 231 dev_err(dev, "failed get mailbox channel\n");
232 return PTR_ERR(stub_clk->mbox); 232 return PTR_ERR(stub_clk->mbox);
233 }; 233 }
234 234
235 init.name = "acpu0"; 235 init.name = "acpu0";
236 init.ops = &hi6220_stub_clk_ops; 236 init.ops = &hi6220_stub_clk_ops;
diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c
index ec1a4c1dacf1..c4c141cab444 100644
--- a/drivers/clk/imx/clk-imx25.c
+++ b/drivers/clk/imx/clk-imx25.c
@@ -86,6 +86,16 @@ enum mx25_clks {
86 86
87static struct clk *clk[clk_max]; 87static struct clk *clk[clk_max];
88 88
89static struct clk ** const uart_clks[] __initconst = {
90 &clk[uart_ipg_per],
91 &clk[uart1_ipg],
92 &clk[uart2_ipg],
93 &clk[uart3_ipg],
94 &clk[uart4_ipg],
95 &clk[uart5_ipg],
96 NULL
97};
98
89static int __init __mx25_clocks_init(unsigned long osc_rate, 99static int __init __mx25_clocks_init(unsigned long osc_rate,
90 void __iomem *ccm_base) 100 void __iomem *ccm_base)
91{ 101{
@@ -233,6 +243,8 @@ static int __init __mx25_clocks_init(unsigned long osc_rate,
233 */ 243 */
234 clk_set_parent(clk[cko_sel], clk[ipg]); 244 clk_set_parent(clk[cko_sel], clk[ipg]);
235 245
246 imx_register_uart_clocks(uart_clks);
247
236 return 0; 248 return 0;
237} 249}
238 250
diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c
index d9d50d54ef2a..cf5cf75a4848 100644
--- a/drivers/clk/imx/clk-imx27.c
+++ b/drivers/clk/imx/clk-imx27.c
@@ -47,6 +47,17 @@ static const char *ssi_sel_clks[] = { "spll_gate", "mpll", };
47static struct clk *clk[IMX27_CLK_MAX]; 47static struct clk *clk[IMX27_CLK_MAX];
48static struct clk_onecell_data clk_data; 48static struct clk_onecell_data clk_data;
49 49
50static struct clk ** const uart_clks[] __initconst = {
51 &clk[IMX27_CLK_PER1_GATE],
52 &clk[IMX27_CLK_UART1_IPG_GATE],
53 &clk[IMX27_CLK_UART2_IPG_GATE],
54 &clk[IMX27_CLK_UART3_IPG_GATE],
55 &clk[IMX27_CLK_UART4_IPG_GATE],
56 &clk[IMX27_CLK_UART5_IPG_GATE],
57 &clk[IMX27_CLK_UART6_IPG_GATE],
58 NULL
59};
60
50static void __init _mx27_clocks_init(unsigned long fref) 61static void __init _mx27_clocks_init(unsigned long fref)
51{ 62{
52 BUG_ON(!ccm); 63 BUG_ON(!ccm);
@@ -163,6 +174,8 @@ static void __init _mx27_clocks_init(unsigned long fref)
163 174
164 clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]); 175 clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]);
165 176
177 imx_register_uart_clocks(uart_clks);
178
166 imx_print_silicon_rev("i.MX27", mx27_revision()); 179 imx_print_silicon_rev("i.MX27", mx27_revision());
167} 180}
168 181
@@ -248,8 +261,10 @@ static void __init mx27_clocks_init_dt(struct device_node *np)
248 if (!of_device_is_compatible(refnp, "fsl,imx-osc26m")) 261 if (!of_device_is_compatible(refnp, "fsl,imx-osc26m"))
249 continue; 262 continue;
250 263
251 if (!of_property_read_u32(refnp, "clock-frequency", &fref)) 264 if (!of_property_read_u32(refnp, "clock-frequency", &fref)) {
265 of_node_put(refnp);
252 break; 266 break;
267 }
253 } 268 }
254 269
255 ccm = of_iomap(np, 0); 270 ccm = of_iomap(np, 0);
diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c
index 1f8383475bb3..6a964144a5b5 100644
--- a/drivers/clk/imx/clk-imx31.c
+++ b/drivers/clk/imx/clk-imx31.c
@@ -62,7 +62,17 @@ enum mx31_clks {
62static struct clk *clk[clk_max]; 62static struct clk *clk[clk_max];
63static struct clk_onecell_data clk_data; 63static struct clk_onecell_data clk_data;
64 64
65int __init mx31_clocks_init(unsigned long fref) 65static struct clk ** const uart_clks[] __initconst = {
66 &clk[ipg],
67 &clk[uart1_gate],
68 &clk[uart2_gate],
69 &clk[uart3_gate],
70 &clk[uart4_gate],
71 &clk[uart5_gate],
72 NULL
73};
74
75static void __init _mx31_clocks_init(unsigned long fref)
66{ 76{
67 void __iomem *base; 77 void __iomem *base;
68 struct device_node *np; 78 struct device_node *np;
@@ -132,6 +142,12 @@ int __init mx31_clocks_init(unsigned long fref)
132 142
133 imx_check_clocks(clk, ARRAY_SIZE(clk)); 143 imx_check_clocks(clk, ARRAY_SIZE(clk));
134 144
145 clk_set_parent(clk[csi], clk[upll]);
146 clk_prepare_enable(clk[emi_gate]);
147 clk_prepare_enable(clk[iim_gate]);
148 mx31_revision();
149 clk_disable_unprepare(clk[iim_gate]);
150
135 np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm"); 151 np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm");
136 152
137 if (np) { 153 if (np) {
@@ -139,6 +155,13 @@ int __init mx31_clocks_init(unsigned long fref)
139 clk_data.clk_num = ARRAY_SIZE(clk); 155 clk_data.clk_num = ARRAY_SIZE(clk);
140 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 156 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
141 } 157 }
158}
159
160int __init mx31_clocks_init(void)
161{
162 u32 fref = 26000000; /* default */
163
164 _mx31_clocks_init(fref);
142 165
143 clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); 166 clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
144 clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); 167 clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
@@ -194,12 +217,8 @@ int __init mx31_clocks_init(unsigned long fref)
194 clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma"); 217 clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma");
195 clk_register_clkdev(clk[iim_gate], "iim", NULL); 218 clk_register_clkdev(clk[iim_gate], "iim", NULL);
196 219
197 clk_set_parent(clk[csi], clk[upll]);
198 clk_prepare_enable(clk[emi_gate]);
199 clk_prepare_enable(clk[iim_gate]);
200 mx31_revision();
201 clk_disable_unprepare(clk[iim_gate]);
202 220
221 imx_register_uart_clocks(uart_clks);
203 mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31); 222 mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31);
204 223
205 return 0; 224 return 0;
@@ -214,9 +233,13 @@ int __init mx31_clocks_init_dt(void)
214 if (!of_device_is_compatible(np, "fsl,imx-osc26m")) 233 if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
215 continue; 234 continue;
216 235
217 if (!of_property_read_u32(np, "clock-frequency", &fref)) 236 if (!of_property_read_u32(np, "clock-frequency", &fref)) {
237 of_node_put(np);
218 break; 238 break;
239 }
219 } 240 }
220 241
221 return mx31_clocks_init(fref); 242 _mx31_clocks_init(fref);
243
244 return 0;
222} 245}
diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
index 8623cd4e49fd..a71d24cb4c06 100644
--- a/drivers/clk/imx/clk-imx35.c
+++ b/drivers/clk/imx/clk-imx35.c
@@ -84,7 +84,15 @@ enum mx35_clks {
84 84
85static struct clk *clk[clk_max]; 85static struct clk *clk[clk_max];
86 86
87int __init mx35_clocks_init(void) 87static struct clk ** const uart_clks[] __initconst = {
88 &clk[ipg],
89 &clk[uart1_gate],
90 &clk[uart2_gate],
91 &clk[uart3_gate],
92 NULL
93};
94
95static void __init _mx35_clocks_init(void)
88{ 96{
89 void __iomem *base; 97 void __iomem *base;
90 u32 pdr0, consumer_sel, hsp_sel; 98 u32 pdr0, consumer_sel, hsp_sel;
@@ -220,6 +228,32 @@ int __init mx35_clocks_init(void)
220 228
221 imx_check_clocks(clk, ARRAY_SIZE(clk)); 229 imx_check_clocks(clk, ARRAY_SIZE(clk));
222 230
231 clk_prepare_enable(clk[spba_gate]);
232 clk_prepare_enable(clk[gpio1_gate]);
233 clk_prepare_enable(clk[gpio2_gate]);
234 clk_prepare_enable(clk[gpio3_gate]);
235 clk_prepare_enable(clk[iim_gate]);
236 clk_prepare_enable(clk[emi_gate]);
237 clk_prepare_enable(clk[max_gate]);
238 clk_prepare_enable(clk[iomuxc_gate]);
239
240 /*
241 * SCC is needed to boot via mmc after a watchdog reset. The clock code
242 * before conversion to common clk also enabled UART1 (which isn't
243 * handled here and not needed for mmc) and IIM (which is enabled
244 * unconditionally above).
245 */
246 clk_prepare_enable(clk[scc_gate]);
247
248 imx_register_uart_clocks(uart_clks);
249
250 imx_print_silicon_rev("i.MX35", mx35_revision());
251}
252
253int __init mx35_clocks_init(void)
254{
255 _mx35_clocks_init();
256
223 clk_register_clkdev(clk[pata_gate], NULL, "pata_imx"); 257 clk_register_clkdev(clk[pata_gate], NULL, "pata_imx");
224 clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0"); 258 clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0");
225 clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1"); 259 clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1");
@@ -279,25 +313,6 @@ int __init mx35_clocks_init(void)
279 clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); 313 clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
280 clk_register_clkdev(clk[admux_gate], "audmux", NULL); 314 clk_register_clkdev(clk[admux_gate], "audmux", NULL);
281 315
282 clk_prepare_enable(clk[spba_gate]);
283 clk_prepare_enable(clk[gpio1_gate]);
284 clk_prepare_enable(clk[gpio2_gate]);
285 clk_prepare_enable(clk[gpio3_gate]);
286 clk_prepare_enable(clk[iim_gate]);
287 clk_prepare_enable(clk[emi_gate]);
288 clk_prepare_enable(clk[max_gate]);
289 clk_prepare_enable(clk[iomuxc_gate]);
290
291 /*
292 * SCC is needed to boot via mmc after a watchdog reset. The clock code
293 * before conversion to common clk also enabled UART1 (which isn't
294 * handled here and not needed for mmc) and IIM (which is enabled
295 * unconditionally above).
296 */
297 clk_prepare_enable(clk[scc_gate]);
298
299 imx_print_silicon_rev("i.MX35", mx35_revision());
300
301 mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31); 316 mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31);
302 317
303 return 0; 318 return 0;
@@ -305,10 +320,10 @@ int __init mx35_clocks_init(void)
305 320
306static void __init mx35_clocks_init_dt(struct device_node *ccm_node) 321static void __init mx35_clocks_init_dt(struct device_node *ccm_node)
307{ 322{
323 _mx35_clocks_init();
324
308 clk_data.clks = clk; 325 clk_data.clks = clk;
309 clk_data.clk_num = ARRAY_SIZE(clk); 326 clk_data.clk_num = ARRAY_SIZE(clk);
310 of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data); 327 of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
311
312 mx35_clocks_init();
313} 328}
314CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt); 329CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt);
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c
index a7e4f394be0d..c6770348d2ab 100644
--- a/drivers/clk/imx/clk-imx51-imx53.c
+++ b/drivers/clk/imx/clk-imx51-imx53.c
@@ -130,6 +130,20 @@ static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" };
130static struct clk *clk[IMX5_CLK_END]; 130static struct clk *clk[IMX5_CLK_END];
131static struct clk_onecell_data clk_data; 131static struct clk_onecell_data clk_data;
132 132
133static struct clk ** const uart_clks[] __initconst = {
134 &clk[IMX5_CLK_UART1_IPG_GATE],
135 &clk[IMX5_CLK_UART1_PER_GATE],
136 &clk[IMX5_CLK_UART2_IPG_GATE],
137 &clk[IMX5_CLK_UART2_PER_GATE],
138 &clk[IMX5_CLK_UART3_IPG_GATE],
139 &clk[IMX5_CLK_UART3_PER_GATE],
140 &clk[IMX5_CLK_UART4_IPG_GATE],
141 &clk[IMX5_CLK_UART4_PER_GATE],
142 &clk[IMX5_CLK_UART5_IPG_GATE],
143 &clk[IMX5_CLK_UART5_PER_GATE],
144 NULL
145};
146
133static void __init mx5_clocks_common_init(void __iomem *ccm_base) 147static void __init mx5_clocks_common_init(void __iomem *ccm_base)
134{ 148{
135 clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0); 149 clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
@@ -310,6 +324,8 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
310 clk_prepare_enable(clk[IMX5_CLK_TMAX1]); 324 clk_prepare_enable(clk[IMX5_CLK_TMAX1]);
311 clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */ 325 clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */
312 clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */ 326 clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */
327
328 imx_register_uart_clocks(uart_clks);
313} 329}
314 330
315static void __init mx50_clocks_init(struct device_node *np) 331static void __init mx50_clocks_init(struct device_node *np)
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index b2c1c047dc94..c1935081d34a 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -119,6 +119,7 @@ static unsigned int share_count_ssi1;
119static unsigned int share_count_ssi2; 119static unsigned int share_count_ssi2;
120static unsigned int share_count_ssi3; 120static unsigned int share_count_ssi3;
121static unsigned int share_count_mipi_core_cfg; 121static unsigned int share_count_mipi_core_cfg;
122static unsigned int share_count_spdif;
122 123
123static inline int clk_on_imx6q(void) 124static inline int clk_on_imx6q(void)
124{ 125{
@@ -130,6 +131,12 @@ static inline int clk_on_imx6dl(void)
130 return of_machine_is_compatible("fsl,imx6dl"); 131 return of_machine_is_compatible("fsl,imx6dl");
131} 132}
132 133
134static struct clk ** const uart_clks[] __initconst = {
135 &clk[IMX6QDL_CLK_UART_IPG],
136 &clk[IMX6QDL_CLK_UART_SERIAL],
137 NULL
138};
139
133static void __init imx6q_clocks_init(struct device_node *ccm_node) 140static void __init imx6q_clocks_init(struct device_node *ccm_node)
134{ 141{
135 struct device_node *np; 142 struct device_node *np;
@@ -456,7 +463,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
456 clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); 463 clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4);
457 clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); 464 clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
458 clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); 465 clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
459 clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif_podf", base + 0x7c, 14); 466 clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_spdif);
467 clk[IMX6QDL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_spdif);
460 clk[IMX6QDL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); 468 clk[IMX6QDL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
461 clk[IMX6QDL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); 469 clk[IMX6QDL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
462 clk[IMX6QDL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); 470 clk[IMX6QDL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);
@@ -541,5 +549,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
541 /* All existing boards with PCIe use LVDS1 */ 549 /* All existing boards with PCIe use LVDS1 */
542 if (IS_ENABLED(CONFIG_PCI_IMX6)) 550 if (IS_ENABLED(CONFIG_PCI_IMX6))
543 clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]); 551 clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]);
552
553 imx_register_uart_clocks(uart_clks);
544} 554}
545CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init); 555CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c
index a0d4cf26cfa9..1be6230a07af 100644
--- a/drivers/clk/imx/clk-imx6sl.c
+++ b/drivers/clk/imx/clk-imx6sl.c
@@ -97,6 +97,7 @@ static struct clk_div_table video_div_table[] = {
97static unsigned int share_count_ssi1; 97static unsigned int share_count_ssi1;
98static unsigned int share_count_ssi2; 98static unsigned int share_count_ssi2;
99static unsigned int share_count_ssi3; 99static unsigned int share_count_ssi3;
100static unsigned int share_count_spdif;
100 101
101static struct clk *clks[IMX6SL_CLK_END]; 102static struct clk *clks[IMX6SL_CLK_END];
102static struct clk_onecell_data clk_data; 103static struct clk_onecell_data clk_data;
@@ -184,6 +185,12 @@ void imx6sl_set_wait_clk(bool enter)
184 imx6sl_enable_pll_arm(false); 185 imx6sl_enable_pll_arm(false);
185} 186}
186 187
188static struct clk ** const uart_clks[] __initconst = {
189 &clks[IMX6SL_CLK_UART],
190 &clks[IMX6SL_CLK_UART_SERIAL],
191 NULL
192};
193
187static void __init imx6sl_clocks_init(struct device_node *ccm_node) 194static void __init imx6sl_clocks_init(struct device_node *ccm_node)
188{ 195{
189 struct device_node *np; 196 struct device_node *np;
@@ -391,7 +398,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
391 clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22); 398 clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
392 clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6); 399 clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6);
393 clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); 400 clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
394 clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif0_podf", base + 0x7c, 14); 401 clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif0_podf", base + 0x7c, 14, &share_count_spdif);
402 clks[IMX6SL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_spdif);
395 clks[IMX6SL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); 403 clks[IMX6SL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
396 clks[IMX6SL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); 404 clks[IMX6SL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
397 clks[IMX6SL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); 405 clks[IMX6SL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);
@@ -439,5 +447,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
439 447
440 clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL], 448 clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL],
441 clks[IMX6SL_CLK_PLL2_PFD2]); 449 clks[IMX6SL_CLK_PLL2_PFD2]);
450
451 imx_register_uart_clocks(uart_clks);
442} 452}
443CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init); 453CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
index 5b95c2c2bf52..fea125eb4330 100644
--- a/drivers/clk/imx/clk-imx6sx.c
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -135,6 +135,12 @@ static u32 share_count_ssi1;
135static u32 share_count_ssi2; 135static u32 share_count_ssi2;
136static u32 share_count_ssi3; 136static u32 share_count_ssi3;
137 137
138static struct clk ** const uart_clks[] __initconst = {
139 &clks[IMX6SX_CLK_UART_IPG],
140 &clks[IMX6SX_CLK_UART_SERIAL],
141 NULL
142};
143
138static void __init imx6sx_clocks_init(struct device_node *ccm_node) 144static void __init imx6sx_clocks_init(struct device_node *ccm_node)
139{ 145{
140 struct device_node *np; 146 struct device_node *np;
@@ -454,6 +460,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
454 clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); 460 clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
455 clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); 461 clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio);
456 clks[IMX6SX_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); 462 clks[IMX6SX_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio);
463 clks[IMX6SX_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_audio);
457 clks[IMX6SX_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); 464 clks[IMX6SX_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1);
458 clks[IMX6SX_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); 465 clks[IMX6SX_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2);
459 clks[IMX6SX_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); 466 clks[IMX6SX_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3);
@@ -557,5 +564,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
557 564
558 clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]); 565 clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
559 clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]); 566 clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
567
568 imx_register_uart_clocks(uart_clks);
560} 569}
561CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init); 570CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index aaa36650695f..01718d05e952 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -407,6 +407,24 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
407 clk_data.clk_num = ARRAY_SIZE(clks); 407 clk_data.clk_num = ARRAY_SIZE(clks);
408 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 408 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
409 409
410 /*
411 * Lower the AHB clock rate before changing the parent clock source,
412 * as AHB clock rate can NOT be higher than 133MHz, but its parent
413 * will be switched from 396MHz PFD to 528MHz PLL in order to increase
414 * AXI clock rate, so we need to lower AHB rate first to make sure at
415 * any time, AHB rate is <= 133MHz.
416 */
417 clk_set_rate(clks[IMX6UL_CLK_AHB], 99000000);
418
419 /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */
420 clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_PLL3_USB_OTG]);
421 clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_CLK2]);
422 clk_set_parent(clks[IMX6UL_CLK_PERIPH_PRE], clks[IMX6UL_CLK_PLL2_BUS]);
423 clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_PRE]);
424
425 /* Make sure AHB rate is 132MHz */
426 clk_set_rate(clks[IMX6UL_CLK_AHB], 132000000);
427
410 /* set perclk to from OSC */ 428 /* set perclk to from OSC */
411 clk_set_parent(clks[IMX6UL_CLK_PERCLK_SEL], clks[IMX6UL_CLK_OSC]); 429 clk_set_parent(clks[IMX6UL_CLK_PERCLK_SEL], clks[IMX6UL_CLK_OSC]);
412 430
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index 71f3a94b472c..448ef321948b 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -363,6 +363,17 @@ static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_
363 363
364static struct clk_onecell_data clk_data; 364static struct clk_onecell_data clk_data;
365 365
366static struct clk ** const uart_clks[] __initconst = {
367 &clks[IMX7D_UART1_ROOT_CLK],
368 &clks[IMX7D_UART2_ROOT_CLK],
369 &clks[IMX7D_UART3_ROOT_CLK],
370 &clks[IMX7D_UART4_ROOT_CLK],
371 &clks[IMX7D_UART5_ROOT_CLK],
372 &clks[IMX7D_UART6_ROOT_CLK],
373 &clks[IMX7D_UART7_ROOT_CLK],
374 NULL
375};
376
366static void __init imx7d_clocks_init(struct device_node *ccm_node) 377static void __init imx7d_clocks_init(struct device_node *ccm_node)
367{ 378{
368 struct device_node *np; 379 struct device_node *np;
@@ -818,6 +829,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
818 clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate2("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0); 829 clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate2("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0);
819 clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate2("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0); 830 clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate2("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0);
820 clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate2("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0); 831 clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate2("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0);
832 clks[IMX7D_ADC_ROOT_CLK] = imx_clk_gate2("adc_root_clk", "ipg_root_clk", base + 0x4200, 0);
821 833
822 clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); 834 clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
823 835
@@ -856,5 +868,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
856 /* set uart module clock's parent clock source that must be great then 80MHz */ 868 /* set uart module clock's parent clock source that must be great then 80MHz */
857 clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); 869 clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
858 870
871 imx_register_uart_clocks(uart_clks);
872
859} 873}
860CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init); 874CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init);
diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c
index 20889d59b44d..b18f875eac6a 100644
--- a/drivers/clk/imx/clk-pllv2.c
+++ b/drivers/clk/imx/clk-pllv2.c
@@ -77,7 +77,7 @@ struct clk_pllv2 {
77static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, 77static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
78 u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn) 78 u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn)
79{ 79{
80 long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; 80 long mfi, mfn, mfd, pdf, ref_clk;
81 unsigned long dbl; 81 unsigned long dbl;
82 s64 temp; 82 s64 temp;
83 83
@@ -87,19 +87,15 @@ static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
87 mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; 87 mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
88 mfi = (mfi <= 5) ? 5 : mfi; 88 mfi = (mfi <= 5) ? 5 : mfi;
89 mfd = dp_mfd & MXC_PLL_DP_MFD_MASK; 89 mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
90 mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK; 90 mfn = dp_mfn & MXC_PLL_DP_MFN_MASK;
91 /* Sign extend to 32-bits */ 91 mfn = sign_extend32(mfn, 26);
92 if (mfn >= 0x04000000) {
93 mfn |= 0xFC000000;
94 mfn_abs = -mfn;
95 }
96 92
97 ref_clk = 2 * parent_rate; 93 ref_clk = 2 * parent_rate;
98 if (dbl != 0) 94 if (dbl != 0)
99 ref_clk *= 2; 95 ref_clk *= 2;
100 96
101 ref_clk /= (pdf + 1); 97 ref_clk /= (pdf + 1);
102 temp = (u64) ref_clk * mfn_abs; 98 temp = (u64) ref_clk * abs(mfn);
103 do_div(temp, mfd + 1); 99 do_div(temp, mfd + 1);
104 if (mfn < 0) 100 if (mfn < 0)
105 temp = -temp; 101 temp = -temp;
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index bff45ead7389..d1b1c95177bb 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -387,6 +387,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
387 387
388 clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7)); 388 clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
389 clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24); 389 clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24);
390 clk[VF610_CLK_OCOTP] = imx_clk_gate("ocotp", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(5));
390 391
391 imx_check_clocks(clk, ARRAY_SIZE(clk)); 392 imx_check_clocks(clk, ARRAY_SIZE(clk));
392 393
diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
index df12b5307175..a634b1185be3 100644
--- a/drivers/clk/imx/clk.c
+++ b/drivers/clk/imx/clk.c
@@ -73,3 +73,41 @@ void imx_cscmr1_fixup(u32 *val)
73 *val ^= CSCMR1_FIXUP; 73 *val ^= CSCMR1_FIXUP;
74 return; 74 return;
75} 75}
76
77static int imx_keep_uart_clocks __initdata;
78static struct clk ** const *imx_uart_clocks __initdata;
79
80static int __init imx_keep_uart_clocks_param(char *str)
81{
82 imx_keep_uart_clocks = 1;
83
84 return 0;
85}
86__setup_param("earlycon", imx_keep_uart_earlycon,
87 imx_keep_uart_clocks_param, 0);
88__setup_param("earlyprintk", imx_keep_uart_earlyprintk,
89 imx_keep_uart_clocks_param, 0);
90
91void __init imx_register_uart_clocks(struct clk ** const clks[])
92{
93 if (imx_keep_uart_clocks) {
94 int i;
95
96 imx_uart_clocks = clks;
97 for (i = 0; imx_uart_clocks[i]; i++)
98 clk_prepare_enable(*imx_uart_clocks[i]);
99 }
100}
101
102static int __init imx_clk_disable_uart(void)
103{
104 if (imx_keep_uart_clocks && imx_uart_clocks) {
105 int i;
106
107 for (i = 0; imx_uart_clocks[i]; i++)
108 clk_disable_unprepare(*imx_uart_clocks[i]);
109 }
110
111 return 0;
112}
113late_initcall_sync(imx_clk_disable_uart);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 1049b0c7d818..c94ac5c26226 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -7,6 +7,7 @@
7extern spinlock_t imx_ccm_lock; 7extern spinlock_t imx_ccm_lock;
8 8
9void imx_check_clocks(struct clk *clks[], unsigned int count); 9void imx_check_clocks(struct clk *clks[], unsigned int count);
10void imx_register_uart_clocks(struct clk ** const clks[]);
10 11
11extern void imx_cscmr1_fixup(u32 *val); 12extern void imx_cscmr1_fixup(u32 *val);
12 13
diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c
index 3f553d0ae0b5..a26ba2184454 100644
--- a/drivers/clk/keystone/pll.c
+++ b/drivers/clk/keystone/pll.c
@@ -157,7 +157,7 @@ out:
157 * _of_clk_init - PLL initialisation via DT 157 * _of_clk_init - PLL initialisation via DT
158 * @node: device tree node for this clock 158 * @node: device tree node for this clock
159 * @pllctrl: If true, lower 6 bits of multiplier is in pllm register of 159 * @pllctrl: If true, lower 6 bits of multiplier is in pllm register of
160 * pll controller, else it is in the control regsiter0(bit 11-6) 160 * pll controller, else it is in the control register0(bit 11-6)
161 */ 161 */
162static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl) 162static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl)
163{ 163{
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 8e4b2a4635b9..95fdfacb2ebf 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,4 +1,4 @@
1obj-y += clk-mtk.o clk-pll.o clk-gate.o 1obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
2obj-$(CONFIG_RESET_CONTROLLER) += reset.o 2obj-$(CONFIG_RESET_CONTROLLER) += reset.o
3obj-y += clk-mt8135.o 3obj-y += clk-mt8135.o
4obj-y += clk-mt8173.o 4obj-y += clk-mt8173.o
diff --git a/drivers/clk/mediatek/clk-apmixed.c b/drivers/clk/mediatek/clk-apmixed.c
new file mode 100644
index 000000000000..5303c5980867
--- /dev/null
+++ b/drivers/clk/mediatek/clk-apmixed.c
@@ -0,0 +1,107 @@
1/*
2 * Copyright (c) 2015 MediaTek Inc.
3 * Author: James Liao <jamesjj.liao@mediatek.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 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/delay.h>
16#include <linux/of_address.h>
17#include <linux/slab.h>
18
19#include "clk-mtk.h"
20
21#define REF2USB_TX_EN BIT(0)
22#define REF2USB_TX_LPF_EN BIT(1)
23#define REF2USB_TX_OUT_EN BIT(2)
24#define REF2USB_EN_MASK (REF2USB_TX_EN | REF2USB_TX_LPF_EN | \
25 REF2USB_TX_OUT_EN)
26
27struct mtk_ref2usb_tx {
28 struct clk_hw hw;
29 void __iomem *base_addr;
30};
31
32static inline struct mtk_ref2usb_tx *to_mtk_ref2usb_tx(struct clk_hw *hw)
33{
34 return container_of(hw, struct mtk_ref2usb_tx, hw);
35}
36
37static int mtk_ref2usb_tx_is_prepared(struct clk_hw *hw)
38{
39 struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
40
41 return (readl(tx->base_addr) & REF2USB_EN_MASK) == REF2USB_EN_MASK;
42}
43
44static int mtk_ref2usb_tx_prepare(struct clk_hw *hw)
45{
46 struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
47 u32 val;
48
49 val = readl(tx->base_addr);
50
51 val |= REF2USB_TX_EN;
52 writel(val, tx->base_addr);
53 udelay(100);
54
55 val |= REF2USB_TX_LPF_EN;
56 writel(val, tx->base_addr);
57
58 val |= REF2USB_TX_OUT_EN;
59 writel(val, tx->base_addr);
60
61 return 0;
62}
63
64static void mtk_ref2usb_tx_unprepare(struct clk_hw *hw)
65{
66 struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
67 u32 val;
68
69 val = readl(tx->base_addr);
70 val &= ~REF2USB_EN_MASK;
71 writel(val, tx->base_addr);
72}
73
74static const struct clk_ops mtk_ref2usb_tx_ops = {
75 .is_prepared = mtk_ref2usb_tx_is_prepared,
76 .prepare = mtk_ref2usb_tx_prepare,
77 .unprepare = mtk_ref2usb_tx_unprepare,
78};
79
80struct clk * __init mtk_clk_register_ref2usb_tx(const char *name,
81 const char *parent_name, void __iomem *reg)
82{
83 struct mtk_ref2usb_tx *tx;
84 struct clk_init_data init = {};
85 struct clk *clk;
86
87 tx = kzalloc(sizeof(*tx), GFP_KERNEL);
88 if (!tx)
89 return ERR_PTR(-ENOMEM);
90
91 tx->base_addr = reg;
92 tx->hw.init = &init;
93
94 init.name = name;
95 init.ops = &mtk_ref2usb_tx_ops;
96 init.parent_names = &parent_name;
97 init.num_parents = 1;
98
99 clk = clk_register(NULL, &tx->hw);
100
101 if (IS_ERR(clk)) {
102 pr_err("Failed to register clk %s: %ld\n", name, PTR_ERR(clk));
103 kfree(tx);
104 }
105
106 return clk;
107}
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index 57020368a693..576bdb7c98b8 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -97,7 +97,7 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
97 .disable = mtk_cg_disable_inv, 97 .disable = mtk_cg_disable_inv,
98}; 98};
99 99
100struct clk *mtk_clk_register_gate( 100struct clk * __init mtk_clk_register_gate(
101 const char *name, 101 const char *name,
102 const char *parent_name, 102 const char *parent_name,
103 struct regmap *regmap, 103 struct regmap *regmap,
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 90eff85f4285..227e356403d9 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -15,21 +15,28 @@
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/of.h> 16#include <linux/of.h>
17#include <linux/of_address.h> 17#include <linux/of_address.h>
18#include <linux/slab.h>
19#include <linux/mfd/syscon.h>
20 18
21#include "clk-mtk.h" 19#include "clk-mtk.h"
22#include "clk-gate.h" 20#include "clk-gate.h"
23 21
24#include <dt-bindings/clock/mt8173-clk.h> 22#include <dt-bindings/clock/mt8173-clk.h>
25 23
24/*
25 * For some clocks, we don't care what their actual rates are. And these
26 * clocks may change their rate on different products or different scenarios.
27 * So we model these clocks' rate as 0, to denote it's not an actual rate.
28 */
29#define DUMMY_RATE 0
30
26static DEFINE_SPINLOCK(mt8173_clk_lock); 31static DEFINE_SPINLOCK(mt8173_clk_lock);
27 32
28static const struct mtk_fixed_factor root_clk_alias[] __initconst = { 33static const struct mtk_fixed_clk fixed_clks[] __initconst = {
29 FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1), 34 FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", DUMMY_RATE),
30 FACTOR(CLK_TOP_DPI, "dpi_ck", "clk_null", 1, 1), 35 FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
31 FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1), 36 FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", DUMMY_RATE),
32 FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1), 37 FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", DUMMY_RATE),
38 FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", DUMMY_RATE),
39 FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", DUMMY_RATE),
33}; 40};
34 41
35static const struct mtk_fixed_factor top_divs[] __initconst = { 42static const struct mtk_fixed_factor top_divs[] __initconst = {
@@ -54,6 +61,7 @@ static const struct mtk_fixed_factor top_divs[] __initconst = {
54 FACTOR(CLK_TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793), 61 FACTOR(CLK_TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793),
55 FACTOR(CLK_TOP_FPC, "fpc_ck", "clk26m", 1, 1), 62 FACTOR(CLK_TOP_FPC, "fpc_ck", "clk26m", 1, 1),
56 63
64 FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "tvdpll_445p5m", 1, 3),
57 FACTOR(CLK_TOP_HDMITXPLL_D2, "hdmitxpll_d2", "hdmitx_dig_cts", 1, 2), 65 FACTOR(CLK_TOP_HDMITXPLL_D2, "hdmitxpll_d2", "hdmitx_dig_cts", 1, 2),
58 FACTOR(CLK_TOP_HDMITXPLL_D3, "hdmitxpll_d3", "hdmitx_dig_cts", 1, 3), 66 FACTOR(CLK_TOP_HDMITXPLL_D3, "hdmitxpll_d3", "hdmitx_dig_cts", 1, 3),
59 67
@@ -590,7 +598,7 @@ static const struct mtk_composite top_muxes[] __initconst = {
590 MUX(CLK_TOP_I2S3_B_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1), 598 MUX(CLK_TOP_I2S3_B_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1),
591}; 599};
592 600
593static const struct mtk_gate_regs infra_cg_regs = { 601static const struct mtk_gate_regs infra_cg_regs __initconst = {
594 .set_ofs = 0x0040, 602 .set_ofs = 0x0040,
595 .clr_ofs = 0x0044, 603 .clr_ofs = 0x0044,
596 .sta_ofs = 0x0048, 604 .sta_ofs = 0x0048,
@@ -612,20 +620,24 @@ static const struct mtk_gate infra_clks[] __initconst = {
612 GATE_ICG(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6), 620 GATE_ICG(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6),
613 GATE_ICG(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7), 621 GATE_ICG(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7),
614 GATE_ICG(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8), 622 GATE_ICG(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8),
615 GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "clk_null", 15), 623 GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "cpum_ck", 15),
616 GATE_ICG(CLK_INFRA_KP, "infra_kp", "axi_sel", 16), 624 GATE_ICG(CLK_INFRA_KP, "infra_kp", "axi_sel", 16),
617 GATE_ICG(CLK_INFRA_CEC, "infra_cec", "clk26m", 18), 625 GATE_ICG(CLK_INFRA_CEC, "infra_cec", "clk26m", 18),
618 GATE_ICG(CLK_INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22), 626 GATE_ICG(CLK_INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22),
619 GATE_ICG(CLK_INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23), 627 GATE_ICG(CLK_INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23),
620}; 628};
621 629
622static const struct mtk_gate_regs peri0_cg_regs = { 630static const struct mtk_fixed_factor infra_divs[] __initconst = {
631 FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2),
632};
633
634static const struct mtk_gate_regs peri0_cg_regs __initconst = {
623 .set_ofs = 0x0008, 635 .set_ofs = 0x0008,
624 .clr_ofs = 0x0010, 636 .clr_ofs = 0x0010,
625 .sta_ofs = 0x0018, 637 .sta_ofs = 0x0018,
626}; 638};
627 639
628static const struct mtk_gate_regs peri1_cg_regs = { 640static const struct mtk_gate_regs peri1_cg_regs __initconst = {
629 .set_ofs = 0x000c, 641 .set_ofs = 0x000c,
630 .clr_ofs = 0x0014, 642 .clr_ofs = 0x0014,
631 .sta_ofs = 0x001c, 643 .sta_ofs = 0x001c,
@@ -701,6 +713,183 @@ static const struct mtk_composite peri_clks[] __initconst = {
701 MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1), 713 MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
702}; 714};
703 715
716static const struct mtk_gate_regs cg_regs_4_8_0 __initconst = {
717 .set_ofs = 0x0004,
718 .clr_ofs = 0x0008,
719 .sta_ofs = 0x0000,
720};
721
722#define GATE_IMG(_id, _name, _parent, _shift) { \
723 .id = _id, \
724 .name = _name, \
725 .parent_name = _parent, \
726 .regs = &cg_regs_4_8_0, \
727 .shift = _shift, \
728 .ops = &mtk_clk_gate_ops_setclr, \
729 }
730
731static const struct mtk_gate img_clks[] __initconst = {
732 GATE_IMG(CLK_IMG_LARB2_SMI, "img_larb2_smi", "mm_sel", 0),
733 GATE_IMG(CLK_IMG_CAM_SMI, "img_cam_smi", "mm_sel", 5),
734 GATE_IMG(CLK_IMG_CAM_CAM, "img_cam_cam", "mm_sel", 6),
735 GATE_IMG(CLK_IMG_SEN_TG, "img_sen_tg", "camtg_sel", 7),
736 GATE_IMG(CLK_IMG_SEN_CAM, "img_sen_cam", "mm_sel", 8),
737 GATE_IMG(CLK_IMG_CAM_SV, "img_cam_sv", "mm_sel", 9),
738 GATE_IMG(CLK_IMG_FD, "img_fd", "mm_sel", 11),
739};
740
741static const struct mtk_gate_regs mm0_cg_regs __initconst = {
742 .set_ofs = 0x0104,
743 .clr_ofs = 0x0108,
744 .sta_ofs = 0x0100,
745};
746
747static const struct mtk_gate_regs mm1_cg_regs __initconst = {
748 .set_ofs = 0x0114,
749 .clr_ofs = 0x0118,
750 .sta_ofs = 0x0110,
751};
752
753#define GATE_MM0(_id, _name, _parent, _shift) { \
754 .id = _id, \
755 .name = _name, \
756 .parent_name = _parent, \
757 .regs = &mm0_cg_regs, \
758 .shift = _shift, \
759 .ops = &mtk_clk_gate_ops_setclr, \
760 }
761
762#define GATE_MM1(_id, _name, _parent, _shift) { \
763 .id = _id, \
764 .name = _name, \
765 .parent_name = _parent, \
766 .regs = &mm1_cg_regs, \
767 .shift = _shift, \
768 .ops = &mtk_clk_gate_ops_setclr, \
769 }
770
771static const struct mtk_gate mm_clks[] __initconst = {
772 /* MM0 */
773 GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
774 GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
775 GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 2),
776 GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 3),
777 GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 4),
778 GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 5),
779 GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 6),
780 GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 7),
781 GATE_MM0(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 8),
782 GATE_MM0(CLK_MM_MDP_TDSHP1, "mm_mdp_tdshp1", "mm_sel", 9),
783 GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
784 GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
785 GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
786 GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
787 GATE_MM0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 15),
788 GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 16),
789 GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 17),
790 GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 18),
791 GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19),
792 GATE_MM0(CLK_MM_DISP_RDMA2, "mm_disp_rdma2", "mm_sel", 20),
793 GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
794 GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
795 GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 23),
796 GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "mm_sel", 24),
797 GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
798 GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
799 GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 27),
800 GATE_MM0(CLK_MM_DISP_SPLIT0, "mm_disp_split0", "mm_sel", 28),
801 GATE_MM0(CLK_MM_DISP_SPLIT1, "mm_disp_split1", "mm_sel", 29),
802 GATE_MM0(CLK_MM_DISP_MERGE, "mm_disp_merge", "mm_sel", 30),
803 GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 31),
804 /* MM1 */
805 GATE_MM1(CLK_MM_DISP_PWM0MM, "mm_disp_pwm0mm", "mm_sel", 0),
806 GATE_MM1(CLK_MM_DISP_PWM026M, "mm_disp_pwm026m", "pwm_sel", 1),
807 GATE_MM1(CLK_MM_DISP_PWM1MM, "mm_disp_pwm1mm", "mm_sel", 2),
808 GATE_MM1(CLK_MM_DISP_PWM126M, "mm_disp_pwm126m", "pwm_sel", 3),
809 GATE_MM1(CLK_MM_DSI0_ENGINE, "mm_dsi0_engine", "mm_sel", 4),
810 GATE_MM1(CLK_MM_DSI0_DIGITAL, "mm_dsi0_digital", "dsi0_dig", 5),
811 GATE_MM1(CLK_MM_DSI1_ENGINE, "mm_dsi1_engine", "mm_sel", 6),
812 GATE_MM1(CLK_MM_DSI1_DIGITAL, "mm_dsi1_digital", "dsi1_dig", 7),
813 GATE_MM1(CLK_MM_DPI_PIXEL, "mm_dpi_pixel", "dpi0_sel", 8),
814 GATE_MM1(CLK_MM_DPI_ENGINE, "mm_dpi_engine", "mm_sel", 9),
815 GATE_MM1(CLK_MM_DPI1_PIXEL, "mm_dpi1_pixel", "lvds_pxl", 10),
816 GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "mm_sel", 11),
817 GATE_MM1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi0_sel", 12),
818 GATE_MM1(CLK_MM_HDMI_PLLCK, "mm_hdmi_pllck", "hdmi_sel", 13),
819 GATE_MM1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll1", 14),
820 GATE_MM1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll2", 15),
821 GATE_MM1(CLK_MM_LVDS_PIXEL, "mm_lvds_pixel", "lvds_pxl", 16),
822 GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvds_cts", 17),
823 GATE_MM1(CLK_MM_SMI_LARB4, "mm_smi_larb4", "mm_sel", 18),
824 GATE_MM1(CLK_MM_HDMI_HDCP, "mm_hdmi_hdcp", "hdcp_sel", 19),
825 GATE_MM1(CLK_MM_HDMI_HDCP24M, "mm_hdmi_hdcp24m", "hdcp_24m_sel", 20),
826};
827
828static const struct mtk_gate_regs vdec0_cg_regs __initconst = {
829 .set_ofs = 0x0000,
830 .clr_ofs = 0x0004,
831 .sta_ofs = 0x0000,
832};
833
834static const struct mtk_gate_regs vdec1_cg_regs __initconst = {
835 .set_ofs = 0x0008,
836 .clr_ofs = 0x000c,
837 .sta_ofs = 0x0008,
838};
839
840#define GATE_VDEC0(_id, _name, _parent, _shift) { \
841 .id = _id, \
842 .name = _name, \
843 .parent_name = _parent, \
844 .regs = &vdec0_cg_regs, \
845 .shift = _shift, \
846 .ops = &mtk_clk_gate_ops_setclr_inv, \
847 }
848
849#define GATE_VDEC1(_id, _name, _parent, _shift) { \
850 .id = _id, \
851 .name = _name, \
852 .parent_name = _parent, \
853 .regs = &vdec1_cg_regs, \
854 .shift = _shift, \
855 .ops = &mtk_clk_gate_ops_setclr_inv, \
856 }
857
858static const struct mtk_gate vdec_clks[] __initconst = {
859 GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0),
860 GATE_VDEC1(CLK_VDEC_LARB_CKEN, "vdec_larb_cken", "mm_sel", 0),
861};
862
863#define GATE_VENC(_id, _name, _parent, _shift) { \
864 .id = _id, \
865 .name = _name, \
866 .parent_name = _parent, \
867 .regs = &cg_regs_4_8_0, \
868 .shift = _shift, \
869 .ops = &mtk_clk_gate_ops_setclr_inv, \
870 }
871
872static const struct mtk_gate venc_clks[] __initconst = {
873 GATE_VENC(CLK_VENC_CKE0, "venc_cke0", "mm_sel", 0),
874 GATE_VENC(CLK_VENC_CKE1, "venc_cke1", "venc_sel", 4),
875 GATE_VENC(CLK_VENC_CKE2, "venc_cke2", "venc_sel", 8),
876 GATE_VENC(CLK_VENC_CKE3, "venc_cke3", "venc_sel", 12),
877};
878
879#define GATE_VENCLT(_id, _name, _parent, _shift) { \
880 .id = _id, \
881 .name = _name, \
882 .parent_name = _parent, \
883 .regs = &cg_regs_4_8_0, \
884 .shift = _shift, \
885 .ops = &mtk_clk_gate_ops_setclr_inv, \
886 }
887
888static const struct mtk_gate venclt_clks[] __initconst = {
889 GATE_VENCLT(CLK_VENCLT_CKE0, "venclt_cke0", "mm_sel", 0),
890 GATE_VENCLT(CLK_VENCLT_CKE1, "venclt_cke1", "venclt_sel", 4),
891};
892
704static struct clk_onecell_data *mt8173_top_clk_data __initdata; 893static struct clk_onecell_data *mt8173_top_clk_data __initdata;
705static struct clk_onecell_data *mt8173_pll_clk_data __initdata; 894static struct clk_onecell_data *mt8173_pll_clk_data __initdata;
706 895
@@ -731,7 +920,7 @@ static void __init mtk_topckgen_init(struct device_node *node)
731 920
732 mt8173_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); 921 mt8173_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
733 922
734 mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data); 923 mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
735 mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data); 924 mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
736 mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, 925 mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
737 &mt8173_clk_lock, clk_data); 926 &mt8173_clk_lock, clk_data);
@@ -754,6 +943,7 @@ static void __init mtk_infrasys_init(struct device_node *node)
754 943
755 mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), 944 mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
756 clk_data); 945 clk_data);
946 mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
757 947
758 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); 948 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
759 if (r) 949 if (r)
@@ -792,6 +982,24 @@ static void __init mtk_pericfg_init(struct device_node *node)
792} 982}
793CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init); 983CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init);
794 984
985struct mtk_clk_usb {
986 int id;
987 const char *name;
988 const char *parent;
989 u32 reg_ofs;
990};
991
992#define APMIXED_USB(_id, _name, _parent, _reg_ofs) { \
993 .id = _id, \
994 .name = _name, \
995 .parent = _parent, \
996 .reg_ofs = _reg_ofs, \
997 }
998
999static const struct mtk_clk_usb apmixed_usb[] __initconst = {
1000 APMIXED_USB(CLK_APMIXED_REF2USB_TX, "ref2usb_tx", "clk26m", 0x8),
1001};
1002
795#define MT8173_PLL_FMAX (3000UL * MHZ) 1003#define MT8173_PLL_FMAX (3000UL * MHZ)
796 1004
797#define CON0_MT8173_RST_BAR BIT(24) 1005#define CON0_MT8173_RST_BAR BIT(24)
@@ -852,6 +1060,15 @@ static const struct mtk_pll_data plls[] = {
852static void __init mtk_apmixedsys_init(struct device_node *node) 1060static void __init mtk_apmixedsys_init(struct device_node *node)
853{ 1061{
854 struct clk_onecell_data *clk_data; 1062 struct clk_onecell_data *clk_data;
1063 void __iomem *base;
1064 struct clk *clk;
1065 int r, i;
1066
1067 base = of_iomap(node, 0);
1068 if (!base) {
1069 pr_err("%s(): ioremap failed\n", __func__);
1070 return;
1071 }
855 1072
856 mt8173_pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); 1073 mt8173_pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
857 if (!clk_data) 1074 if (!clk_data)
@@ -859,7 +1076,113 @@ static void __init mtk_apmixedsys_init(struct device_node *node)
859 1076
860 mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); 1077 mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
861 1078
1079 for (i = 0; i < ARRAY_SIZE(apmixed_usb); i++) {
1080 const struct mtk_clk_usb *cku = &apmixed_usb[i];
1081
1082 clk = mtk_clk_register_ref2usb_tx(cku->name, cku->parent,
1083 base + cku->reg_ofs);
1084
1085 if (IS_ERR(clk)) {
1086 pr_err("Failed to register clk %s: %ld\n", cku->name,
1087 PTR_ERR(clk));
1088 continue;
1089 }
1090
1091 clk_data->clks[cku->id] = clk;
1092 }
1093
1094 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
1095 if (r)
1096 pr_err("%s(): could not register clock provider: %d\n",
1097 __func__, r);
1098
862 mtk_clk_enable_critical(); 1099 mtk_clk_enable_critical();
863} 1100}
864CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys", 1101CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys",
865 mtk_apmixedsys_init); 1102 mtk_apmixedsys_init);
1103
1104static void __init mtk_imgsys_init(struct device_node *node)
1105{
1106 struct clk_onecell_data *clk_data;
1107 int r;
1108
1109 clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
1110
1111 mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
1112 clk_data);
1113
1114 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
1115
1116 if (r)
1117 pr_err("%s(): could not register clock provider: %d\n",
1118 __func__, r);
1119}
1120CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init);
1121
1122static void __init mtk_mmsys_init(struct device_node *node)
1123{
1124 struct clk_onecell_data *clk_data;
1125 int r;
1126
1127 clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
1128
1129 mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
1130 clk_data);
1131
1132 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
1133 if (r)
1134 pr_err("%s(): could not register clock provider: %d\n",
1135 __func__, r);
1136}
1137CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init);
1138
1139static void __init mtk_vdecsys_init(struct device_node *node)
1140{
1141 struct clk_onecell_data *clk_data;
1142 int r;
1143
1144 clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
1145
1146 mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
1147 clk_data);
1148
1149 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
1150 if (r)
1151 pr_err("%s(): could not register clock provider: %d\n",
1152 __func__, r);
1153}
1154CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8173-vdecsys", mtk_vdecsys_init);
1155
1156static void __init mtk_vencsys_init(struct device_node *node)
1157{
1158 struct clk_onecell_data *clk_data;
1159 int r;
1160
1161 clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
1162
1163 mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
1164 clk_data);
1165
1166 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
1167 if (r)
1168 pr_err("%s(): could not register clock provider: %d\n",
1169 __func__, r);
1170}
1171CLK_OF_DECLARE(mtk_vencsys, "mediatek,mt8173-vencsys", mtk_vencsys_init);
1172
1173static void __init mtk_vencltsys_init(struct device_node *node)
1174{
1175 struct clk_onecell_data *clk_data;
1176 int r;
1177
1178 clk_data = mtk_alloc_clk_data(CLK_VENCLT_NR_CLK);
1179
1180 mtk_clk_register_gates(node, venclt_clks, ARRAY_SIZE(venclt_clks),
1181 clk_data);
1182
1183 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
1184 if (r)
1185 pr_err("%s(): could not register clock provider: %d\n",
1186 __func__, r);
1187}
1188CLK_OF_DECLARE(mtk_vencltsys, "mediatek,mt8173-vencltsys", mtk_vencltsys_init);
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 18444aea63c9..cf08db6c130c 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -24,7 +24,7 @@
24#include "clk-mtk.h" 24#include "clk-mtk.h"
25#include "clk-gate.h" 25#include "clk-gate.h"
26 26
27struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num) 27struct clk_onecell_data * __init mtk_alloc_clk_data(unsigned int clk_num)
28{ 28{
29 int i; 29 int i;
30 struct clk_onecell_data *clk_data; 30 struct clk_onecell_data *clk_data;
@@ -49,8 +49,31 @@ err_out:
49 return NULL; 49 return NULL;
50} 50}
51 51
52void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num, 52void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
53 struct clk_onecell_data *clk_data) 53 int num, struct clk_onecell_data *clk_data)
54{
55 int i;
56 struct clk *clk;
57
58 for (i = 0; i < num; i++) {
59 const struct mtk_fixed_clk *rc = &clks[i];
60
61 clk = clk_register_fixed_rate(NULL, rc->name, rc->parent,
62 rc->parent ? 0 : CLK_IS_ROOT, rc->rate);
63
64 if (IS_ERR(clk)) {
65 pr_err("Failed to register clk %s: %ld\n",
66 rc->name, PTR_ERR(clk));
67 continue;
68 }
69
70 if (clk_data)
71 clk_data->clks[rc->id] = clk;
72 }
73}
74
75void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
76 int num, struct clk_onecell_data *clk_data)
54{ 77{
55 int i; 78 int i;
56 struct clk *clk; 79 struct clk *clk;
@@ -72,7 +95,8 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
72 } 95 }
73} 96}
74 97
75int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks, 98int __init mtk_clk_register_gates(struct device_node *node,
99 const struct mtk_gate *clks,
76 int num, struct clk_onecell_data *clk_data) 100 int num, struct clk_onecell_data *clk_data)
77{ 101{
78 int i; 102 int i;
@@ -111,7 +135,7 @@ int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks
111 return 0; 135 return 0;
112} 136}
113 137
114struct clk *mtk_clk_register_composite(const struct mtk_composite *mc, 138struct clk * __init mtk_clk_register_composite(const struct mtk_composite *mc,
115 void __iomem *base, spinlock_t *lock) 139 void __iomem *base, spinlock_t *lock)
116{ 140{
117 struct clk *clk; 141 struct clk *clk;
@@ -196,7 +220,7 @@ err_out:
196 return ERR_PTR(ret); 220 return ERR_PTR(ret);
197} 221}
198 222
199void mtk_clk_register_composites(const struct mtk_composite *mcs, 223void __init mtk_clk_register_composites(const struct mtk_composite *mcs,
200 int num, void __iomem *base, spinlock_t *lock, 224 int num, void __iomem *base, spinlock_t *lock,
201 struct clk_onecell_data *clk_data) 225 struct clk_onecell_data *clk_data)
202{ 226{
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index c5cbecb3d218..32d2e455eb3f 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -26,6 +26,23 @@ struct clk;
26 26
27#define MHZ (1000 * 1000) 27#define MHZ (1000 * 1000)
28 28
29struct mtk_fixed_clk {
30 int id;
31 const char *name;
32 const char *parent;
33 unsigned long rate;
34};
35
36#define FIXED_CLK(_id, _name, _parent, _rate) { \
37 .id = _id, \
38 .name = _name, \
39 .parent = _parent, \
40 .rate = _rate, \
41 }
42
43void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
44 int num, struct clk_onecell_data *clk_data);
45
29struct mtk_fixed_factor { 46struct mtk_fixed_factor {
30 int id; 47 int id;
31 const char *name; 48 const char *name;
@@ -42,7 +59,7 @@ struct mtk_fixed_factor {
42 .div = _div, \ 59 .div = _div, \
43 } 60 }
44 61
45extern void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, 62void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
46 int num, struct clk_onecell_data *clk_data); 63 int num, struct clk_onecell_data *clk_data);
47 64
48struct mtk_composite { 65struct mtk_composite {
@@ -159,10 +176,13 @@ struct mtk_pll_data {
159 const struct mtk_pll_div_table *div_table; 176 const struct mtk_pll_div_table *div_table;
160}; 177};
161 178
162void __init mtk_clk_register_plls(struct device_node *node, 179void mtk_clk_register_plls(struct device_node *node,
163 const struct mtk_pll_data *plls, int num_plls, 180 const struct mtk_pll_data *plls, int num_plls,
164 struct clk_onecell_data *clk_data); 181 struct clk_onecell_data *clk_data);
165 182
183struct clk *mtk_clk_register_ref2usb_tx(const char *name,
184 const char *parent_name, void __iomem *reg);
185
166#ifdef CONFIG_RESET_CONTROLLER 186#ifdef CONFIG_RESET_CONTROLLER
167void mtk_register_reset_controller(struct device_node *np, 187void mtk_register_reset_controller(struct device_node *np,
168 unsigned int num_regs, int regofs); 188 unsigned int num_regs, int regofs);
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index 622e7b6c62b4..966cab1348da 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -317,7 +317,7 @@ void __init mtk_clk_register_plls(struct device_node *node,
317 const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data) 317 const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
318{ 318{
319 void __iomem *base; 319 void __iomem *base;
320 int r, i; 320 int i;
321 struct clk *clk; 321 struct clk *clk;
322 322
323 base = of_iomap(node, 0); 323 base = of_iomap(node, 0);
@@ -339,9 +339,4 @@ void __init mtk_clk_register_plls(struct device_node *node,
339 339
340 clk_data->clks[pll->id] = clk; 340 clk_data->clks[pll->id] = clk;
341 } 341 }
342
343 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
344 if (r)
345 pr_err("%s(): could not register clock provider: %d\n",
346 __func__, r);
347} 342}
diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c
index 85da8b983256..5837eb8a212f 100644
--- a/drivers/clk/mvebu/clk-cpu.c
+++ b/drivers/clk/mvebu/clk-cpu.c
@@ -197,7 +197,6 @@ static void __init of_cpu_clk_setup(struct device_node *node)
197 for_each_node_by_type(dn, "cpu") { 197 for_each_node_by_type(dn, "cpu") {
198 struct clk_init_data init; 198 struct clk_init_data init;
199 struct clk *clk; 199 struct clk *clk;
200 struct clk *parent_clk;
201 char *clk_name = kzalloc(5, GFP_KERNEL); 200 char *clk_name = kzalloc(5, GFP_KERNEL);
202 int cpu, err; 201 int cpu, err;
203 202
@@ -209,9 +208,8 @@ static void __init of_cpu_clk_setup(struct device_node *node)
209 goto bail_out; 208 goto bail_out;
210 209
211 sprintf(clk_name, "cpu%d", cpu); 210 sprintf(clk_name, "cpu%d", cpu);
212 parent_clk = of_clk_get(node, 0);
213 211
214 cpuclk[cpu].parent_name = __clk_get_name(parent_clk); 212 cpuclk[cpu].parent_name = of_clk_get_parent_name(node, 0);
215 cpuclk[cpu].clk_name = clk_name; 213 cpuclk[cpu].clk_name = clk_name;
216 cpuclk[cpu].cpu = cpu; 214 cpuclk[cpu].cpu = cpu;
217 cpuclk[cpu].reg_base = clock_complex_base; 215 cpuclk[cpu].reg_base = clock_complex_base;
diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c
index 4a22429cd7a2..28aac67e7b92 100644
--- a/drivers/clk/mvebu/common.c
+++ b/drivers/clk/mvebu/common.c
@@ -165,7 +165,7 @@ void __init mvebu_coreclk_setup(struct device_node *np,
165 clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name, 165 clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name,
166 cpuclk_name, 0, mult, div); 166 cpuclk_name, 0, mult, div);
167 WARN_ON(IS_ERR(clk_data.clks[2+n])); 167 WARN_ON(IS_ERR(clk_data.clks[2+n]));
168 }; 168 }
169 169
170 /* Register optional refclk */ 170 /* Register optional refclk */
171 if (desc->get_refclk_freq) { 171 if (desc->get_refclk_freq) {
diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c
index 73f0240569ac..f8dd10f6df3d 100644
--- a/drivers/clk/mxs/clk-frac.c
+++ b/drivers/clk/mxs/clk-frac.c
@@ -41,11 +41,13 @@ static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
41{ 41{
42 struct clk_frac *frac = to_clk_frac(hw); 42 struct clk_frac *frac = to_clk_frac(hw);
43 u32 div; 43 u32 div;
44 u64 tmp_rate;
44 45
45 div = readl_relaxed(frac->reg) >> frac->shift; 46 div = readl_relaxed(frac->reg) >> frac->shift;
46 div &= (1 << frac->width) - 1; 47 div &= (1 << frac->width) - 1;
47 48
48 return (parent_rate >> frac->width) * div; 49 tmp_rate = (u64)parent_rate * div;
50 return tmp_rate >> frac->width;
49} 51}
50 52
51static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate, 53static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -54,7 +56,7 @@ static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
54 struct clk_frac *frac = to_clk_frac(hw); 56 struct clk_frac *frac = to_clk_frac(hw);
55 unsigned long parent_rate = *prate; 57 unsigned long parent_rate = *prate;
56 u32 div; 58 u32 div;
57 u64 tmp; 59 u64 tmp, tmp_rate, result;
58 60
59 if (rate > parent_rate) 61 if (rate > parent_rate)
60 return -EINVAL; 62 return -EINVAL;
@@ -67,7 +69,11 @@ static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
67 if (!div) 69 if (!div)
68 return -EINVAL; 70 return -EINVAL;
69 71
70 return (parent_rate >> frac->width) * div; 72 tmp_rate = (u64)parent_rate * div;
73 result = tmp_rate >> frac->width;
74 if ((result << frac->width) < tmp_rate)
75 result += 1;
76 return result;
71} 77}
72 78
73static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate, 79static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/drivers/clk/nxp/clk-lpc18xx-ccu.c b/drivers/clk/nxp/clk-lpc18xx-ccu.c
index eeaee97da110..13aabbb3acbe 100644
--- a/drivers/clk/nxp/clk-lpc18xx-ccu.c
+++ b/drivers/clk/nxp/clk-lpc18xx-ccu.c
@@ -179,9 +179,22 @@ static void lpc18xx_ccu_gate_disable(struct clk_hw *hw)
179 179
180static int lpc18xx_ccu_gate_is_enabled(struct clk_hw *hw) 180static int lpc18xx_ccu_gate_is_enabled(struct clk_hw *hw)
181{ 181{
182 struct clk_gate *gate = to_clk_gate(hw); 182 const struct clk_hw *parent;
183
184 /*
185 * The branch clock registers are only accessible
186 * if the base (parent) clock is enabled. Register
187 * access with a disabled base clock will hang the
188 * system.
189 */
190 parent = clk_hw_get_parent(hw);
191 if (!parent)
192 return 0;
193
194 if (!clk_hw_is_enabled(parent))
195 return 0;
183 196
184 return clk_readl(gate->reg) & LPC18XX_CCU_RUN; 197 return clk_gate_ops.is_enabled(hw);
185} 198}
186 199
187static const struct clk_ops lpc18xx_ccu_gate_ops = { 200static const struct clk_ops lpc18xx_ccu_gate_ops = {
diff --git a/drivers/clk/nxp/clk-lpc18xx-cgu.c b/drivers/clk/nxp/clk-lpc18xx-cgu.c
index e0a3cb8970ab..c924572fc9bc 100644
--- a/drivers/clk/nxp/clk-lpc18xx-cgu.c
+++ b/drivers/clk/nxp/clk-lpc18xx-cgu.c
@@ -480,6 +480,42 @@ static const struct clk_ops lpc18xx_pll1_ops = {
480 .recalc_rate = lpc18xx_pll1_recalc_rate, 480 .recalc_rate = lpc18xx_pll1_recalc_rate,
481}; 481};
482 482
483static int lpc18xx_cgu_gate_enable(struct clk_hw *hw)
484{
485 return clk_gate_ops.enable(hw);
486}
487
488static void lpc18xx_cgu_gate_disable(struct clk_hw *hw)
489{
490 clk_gate_ops.disable(hw);
491}
492
493static int lpc18xx_cgu_gate_is_enabled(struct clk_hw *hw)
494{
495 const struct clk_hw *parent;
496
497 /*
498 * The consumer of base clocks needs know if the
499 * base clock is really enabled before it can be
500 * accessed. It is therefore necessary to verify
501 * this all the way up.
502 */
503 parent = clk_hw_get_parent(hw);
504 if (!parent)
505 return 0;
506
507 if (!clk_hw_is_enabled(parent))
508 return 0;
509
510 return clk_gate_ops.is_enabled(hw);
511}
512
513static const struct clk_ops lpc18xx_gate_ops = {
514 .enable = lpc18xx_cgu_gate_enable,
515 .disable = lpc18xx_cgu_gate_disable,
516 .is_enabled = lpc18xx_cgu_gate_is_enabled,
517};
518
483static struct lpc18xx_cgu_pll_clk lpc18xx_cgu_src_clk_plls[] = { 519static struct lpc18xx_cgu_pll_clk lpc18xx_cgu_src_clk_plls[] = {
484 LPC1XX_CGU_CLK_PLL(PLL0USB, pll0_src_ids, pll0_ops), 520 LPC1XX_CGU_CLK_PLL(PLL0USB, pll0_src_ids, pll0_ops),
485 LPC1XX_CGU_CLK_PLL(PLL0AUDIO, pll0_src_ids, pll0_ops), 521 LPC1XX_CGU_CLK_PLL(PLL0AUDIO, pll0_src_ids, pll0_ops),
@@ -510,7 +546,7 @@ static struct clk *lpc18xx_cgu_register_div(struct lpc18xx_cgu_src_clk_div *clk,
510 return clk_register_composite(NULL, name, parents, clk->n_parents, 546 return clk_register_composite(NULL, name, parents, clk->n_parents,
511 &clk->mux.hw, &clk_mux_ops, 547 &clk->mux.hw, &clk_mux_ops,
512 &clk->div.hw, &clk_divider_ops, 548 &clk->div.hw, &clk_divider_ops,
513 &clk->gate.hw, &clk_gate_ops, 0); 549 &clk->gate.hw, &lpc18xx_gate_ops, 0);
514} 550}
515 551
516 552
@@ -538,7 +574,7 @@ static struct clk *lpc18xx_register_base_clk(struct lpc18xx_cgu_base_clk *clk,
538 return clk_register_composite(NULL, name, parents, clk->n_parents, 574 return clk_register_composite(NULL, name, parents, clk->n_parents,
539 &clk->mux.hw, &clk_mux_ops, 575 &clk->mux.hw, &clk_mux_ops,
540 NULL, NULL, 576 NULL, NULL,
541 &clk->gate.hw, &clk_gate_ops, 0); 577 &clk->gate.hw, &lpc18xx_gate_ops, 0);
542} 578}
543 579
544 580
@@ -557,7 +593,7 @@ static struct clk *lpc18xx_cgu_register_pll(struct lpc18xx_cgu_pll_clk *clk,
557 return clk_register_composite(NULL, name, parents, clk->n_parents, 593 return clk_register_composite(NULL, name, parents, clk->n_parents,
558 &clk->mux.hw, &clk_mux_ops, 594 &clk->mux.hw, &clk_mux_ops,
559 &clk->pll.hw, clk->pll_ops, 595 &clk->pll.hw, clk->pll_ops,
560 &clk->gate.hw, &clk_gate_ops, 0); 596 &clk->gate.hw, &lpc18xx_gate_ops, 0);
561} 597}
562 598
563static void __init lpc18xx_cgu_register_source_clks(struct device_node *np, 599static void __init lpc18xx_cgu_register_source_clks(struct device_node *np,
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 59d16668bdf5..ee4c83aab4f4 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -1,3 +1,7 @@
1config QCOM_GDSC
2 bool
3 select PM_GENERIC_DOMAINS if PM
4
1config COMMON_CLK_QCOM 5config COMMON_CLK_QCOM
2 tristate "Support for Qualcomm's clock controllers" 6 tristate "Support for Qualcomm's clock controllers"
3 depends on OF 7 depends on OF
@@ -7,6 +11,7 @@ config COMMON_CLK_QCOM
7 11
8config APQ_GCC_8084 12config APQ_GCC_8084
9 tristate "APQ8084 Global Clock Controller" 13 tristate "APQ8084 Global Clock Controller"
14 select QCOM_GDSC
10 depends on COMMON_CLK_QCOM 15 depends on COMMON_CLK_QCOM
11 help 16 help
12 Support for the global clock controller on apq8084 devices. 17 Support for the global clock controller on apq8084 devices.
@@ -16,6 +21,7 @@ config APQ_GCC_8084
16config APQ_MMCC_8084 21config APQ_MMCC_8084
17 tristate "APQ8084 Multimedia Clock Controller" 22 tristate "APQ8084 Multimedia Clock Controller"
18 select APQ_GCC_8084 23 select APQ_GCC_8084
24 select QCOM_GDSC
19 depends on COMMON_CLK_QCOM 25 depends on COMMON_CLK_QCOM
20 help 26 help
21 Support for the multimedia clock controller on apq8084 devices. 27 Support for the multimedia clock controller on apq8084 devices.
@@ -49,6 +55,7 @@ config MSM_GCC_8660
49 55
50config MSM_GCC_8916 56config MSM_GCC_8916
51 tristate "MSM8916 Global Clock Controller" 57 tristate "MSM8916 Global Clock Controller"
58 select QCOM_GDSC
52 depends on COMMON_CLK_QCOM 59 depends on COMMON_CLK_QCOM
53 help 60 help
54 Support for the global clock controller on msm8916 devices. 61 Support for the global clock controller on msm8916 devices.
@@ -83,6 +90,7 @@ config MSM_MMCC_8960
83 90
84config MSM_GCC_8974 91config MSM_GCC_8974
85 tristate "MSM8974 Global Clock Controller" 92 tristate "MSM8974 Global Clock Controller"
93 select QCOM_GDSC
86 depends on COMMON_CLK_QCOM 94 depends on COMMON_CLK_QCOM
87 help 95 help
88 Support for the global clock controller on msm8974 devices. 96 Support for the global clock controller on msm8974 devices.
@@ -92,6 +100,7 @@ config MSM_GCC_8974
92config MSM_MMCC_8974 100config MSM_MMCC_8974
93 tristate "MSM8974 Multimedia Clock Controller" 101 tristate "MSM8974 Multimedia Clock Controller"
94 select MSM_GCC_8974 102 select MSM_GCC_8974
103 select QCOM_GDSC
95 depends on COMMON_CLK_QCOM 104 depends on COMMON_CLK_QCOM
96 help 105 help
97 Support for the multimedia clock controller on msm8974 devices. 106 Support for the multimedia clock controller on msm8974 devices.
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 50b337a24a87..fe6252349e55 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -9,6 +9,7 @@ clk-qcom-y += clk-branch.o
9clk-qcom-y += clk-regmap-divider.o 9clk-qcom-y += clk-regmap-divider.o
10clk-qcom-y += clk-regmap-mux.o 10clk-qcom-y += clk-regmap-mux.o
11clk-qcom-y += reset.o 11clk-qcom-y += reset.o
12clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
12 13
13obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o 14obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
14obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o 15obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c
index bccedc4b5756..bfbb28f450c2 100644
--- a/drivers/clk/qcom/clk-rcg.c
+++ b/drivers/clk/qcom/clk-rcg.c
@@ -542,6 +542,200 @@ static int clk_rcg_bypass_set_rate(struct clk_hw *hw, unsigned long rate,
542 return __clk_rcg_set_rate(rcg, rcg->freq_tbl); 542 return __clk_rcg_set_rate(rcg, rcg->freq_tbl);
543} 543}
544 544
545static int clk_rcg_bypass2_determine_rate(struct clk_hw *hw,
546 struct clk_rate_request *req)
547{
548 struct clk_hw *p;
549
550 p = req->best_parent_hw;
551 req->best_parent_rate = clk_hw_round_rate(p, req->rate);
552 req->rate = req->best_parent_rate;
553
554 return 0;
555}
556
557static int clk_rcg_bypass2_set_rate(struct clk_hw *hw, unsigned long rate,
558 unsigned long parent_rate)
559{
560 struct clk_rcg *rcg = to_clk_rcg(hw);
561 struct freq_tbl f = { 0 };
562 u32 ns, src;
563 int i, ret, num_parents = clk_hw_get_num_parents(hw);
564
565 ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
566 if (ret)
567 return ret;
568
569 src = ns_to_src(&rcg->s, ns);
570 f.pre_div = ns_to_pre_div(&rcg->p, ns) + 1;
571
572 for (i = 0; i < num_parents; i++) {
573 if (src == rcg->s.parent_map[i].cfg) {
574 f.src = rcg->s.parent_map[i].src;
575 return __clk_rcg_set_rate(rcg, &f);
576 }
577 }
578
579 return -EINVAL;
580}
581
582static int clk_rcg_bypass2_set_rate_and_parent(struct clk_hw *hw,
583 unsigned long rate, unsigned long parent_rate, u8 index)
584{
585 /* Read the hardware to determine parent during set_rate */
586 return clk_rcg_bypass2_set_rate(hw, rate, parent_rate);
587}
588
589struct frac_entry {
590 int num;
591 int den;
592};
593
594static const struct frac_entry pixel_table[] = {
595 { 1, 2 },
596 { 1, 3 },
597 { 3, 16 },
598 { }
599};
600
601static int clk_rcg_pixel_determine_rate(struct clk_hw *hw,
602 struct clk_rate_request *req)
603{
604 int delta = 100000;
605 const struct frac_entry *frac = pixel_table;
606 unsigned long request, src_rate;
607
608 for (; frac->num; frac++) {
609 request = (req->rate * frac->den) / frac->num;
610
611 src_rate = clk_hw_round_rate(req->best_parent_hw, request);
612
613 if ((src_rate < (request - delta)) ||
614 (src_rate > (request + delta)))
615 continue;
616
617 req->best_parent_rate = src_rate;
618 req->rate = (src_rate * frac->num) / frac->den;
619 return 0;
620 }
621
622 return -EINVAL;
623}
624
625static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
626 unsigned long parent_rate)
627{
628 struct clk_rcg *rcg = to_clk_rcg(hw);
629 int delta = 100000;
630 const struct frac_entry *frac = pixel_table;
631 unsigned long request;
632 struct freq_tbl f = { 0 };
633 u32 ns, src;
634 int i, ret, num_parents = clk_hw_get_num_parents(hw);
635
636 ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
637 if (ret)
638 return ret;
639
640 src = ns_to_src(&rcg->s, ns);
641 f.pre_div = ns_to_pre_div(&rcg->p, ns) + 1;
642
643 for (i = 0; i < num_parents; i++) {
644 if (src == rcg->s.parent_map[i].cfg) {
645 f.src = rcg->s.parent_map[i].src;
646 break;
647 }
648 }
649
650 /* let us find appropriate m/n values for this */
651 for (; frac->num; frac++) {
652 request = (rate * frac->den) / frac->num;
653
654 if ((parent_rate < (request - delta)) ||
655 (parent_rate > (request + delta)))
656 continue;
657
658 f.m = frac->num;
659 f.n = frac->den;
660
661 return __clk_rcg_set_rate(rcg, &f);
662 }
663
664 return -EINVAL;
665}
666
667static int clk_rcg_pixel_set_rate_and_parent(struct clk_hw *hw,
668 unsigned long rate, unsigned long parent_rate, u8 index)
669{
670 return clk_rcg_pixel_set_rate(hw, rate, parent_rate);
671}
672
673static int clk_rcg_esc_determine_rate(struct clk_hw *hw,
674 struct clk_rate_request *req)
675{
676 struct clk_rcg *rcg = to_clk_rcg(hw);
677 int pre_div_max = BIT(rcg->p.pre_div_width);
678 int div;
679 unsigned long src_rate;
680
681 if (req->rate == 0)
682 return -EINVAL;
683
684 src_rate = clk_hw_get_rate(req->best_parent_hw);
685
686 div = src_rate / req->rate;
687
688 if (div >= 1 && div <= pre_div_max) {
689 req->best_parent_rate = src_rate;
690 req->rate = src_rate / div;
691 return 0;
692 }
693
694 return -EINVAL;
695}
696
697static int clk_rcg_esc_set_rate(struct clk_hw *hw, unsigned long rate,
698 unsigned long parent_rate)
699{
700 struct clk_rcg *rcg = to_clk_rcg(hw);
701 struct freq_tbl f = { 0 };
702 int pre_div_max = BIT(rcg->p.pre_div_width);
703 int div;
704 u32 ns;
705 int i, ret, num_parents = clk_hw_get_num_parents(hw);
706
707 if (rate == 0)
708 return -EINVAL;
709
710 ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
711 if (ret)
712 return ret;
713
714 ns = ns_to_src(&rcg->s, ns);
715
716 for (i = 0; i < num_parents; i++) {
717 if (ns == rcg->s.parent_map[i].cfg) {
718 f.src = rcg->s.parent_map[i].src;
719 break;
720 }
721 }
722
723 div = parent_rate / rate;
724
725 if (div >= 1 && div <= pre_div_max) {
726 f.pre_div = div;
727 return __clk_rcg_set_rate(rcg, &f);
728 }
729
730 return -EINVAL;
731}
732
733static int clk_rcg_esc_set_rate_and_parent(struct clk_hw *hw,
734 unsigned long rate, unsigned long parent_rate, u8 index)
735{
736 return clk_rcg_esc_set_rate(hw, rate, parent_rate);
737}
738
545/* 739/*
546 * This type of clock has a glitch-free mux that switches between the output of 740 * This type of clock has a glitch-free mux that switches between the output of
547 * the M/N counter and an always on clock source (XO). When clk_set_rate() is 741 * the M/N counter and an always on clock source (XO). When clk_set_rate() is
@@ -639,6 +833,42 @@ const struct clk_ops clk_rcg_bypass_ops = {
639}; 833};
640EXPORT_SYMBOL_GPL(clk_rcg_bypass_ops); 834EXPORT_SYMBOL_GPL(clk_rcg_bypass_ops);
641 835
836const struct clk_ops clk_rcg_bypass2_ops = {
837 .enable = clk_enable_regmap,
838 .disable = clk_disable_regmap,
839 .get_parent = clk_rcg_get_parent,
840 .set_parent = clk_rcg_set_parent,
841 .recalc_rate = clk_rcg_recalc_rate,
842 .determine_rate = clk_rcg_bypass2_determine_rate,
843 .set_rate = clk_rcg_bypass2_set_rate,
844 .set_rate_and_parent = clk_rcg_bypass2_set_rate_and_parent,
845};
846EXPORT_SYMBOL_GPL(clk_rcg_bypass2_ops);
847
848const struct clk_ops clk_rcg_pixel_ops = {
849 .enable = clk_enable_regmap,
850 .disable = clk_disable_regmap,
851 .get_parent = clk_rcg_get_parent,
852 .set_parent = clk_rcg_set_parent,
853 .recalc_rate = clk_rcg_recalc_rate,
854 .determine_rate = clk_rcg_pixel_determine_rate,
855 .set_rate = clk_rcg_pixel_set_rate,
856 .set_rate_and_parent = clk_rcg_pixel_set_rate_and_parent,
857};
858EXPORT_SYMBOL_GPL(clk_rcg_pixel_ops);
859
860const struct clk_ops clk_rcg_esc_ops = {
861 .enable = clk_enable_regmap,
862 .disable = clk_disable_regmap,
863 .get_parent = clk_rcg_get_parent,
864 .set_parent = clk_rcg_set_parent,
865 .recalc_rate = clk_rcg_recalc_rate,
866 .determine_rate = clk_rcg_esc_determine_rate,
867 .set_rate = clk_rcg_esc_set_rate,
868 .set_rate_and_parent = clk_rcg_esc_set_rate_and_parent,
869};
870EXPORT_SYMBOL_GPL(clk_rcg_esc_ops);
871
642const struct clk_ops clk_rcg_lcc_ops = { 872const struct clk_ops clk_rcg_lcc_ops = {
643 .enable = clk_rcg_lcc_enable, 873 .enable = clk_rcg_lcc_enable,
644 .disable = clk_rcg_lcc_disable, 874 .disable = clk_rcg_lcc_disable,
diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index 56028bb31d87..4b1e94bdf29e 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -106,6 +106,9 @@ struct clk_rcg {
106 106
107extern const struct clk_ops clk_rcg_ops; 107extern const struct clk_ops clk_rcg_ops;
108extern const struct clk_ops clk_rcg_bypass_ops; 108extern const struct clk_ops clk_rcg_bypass_ops;
109extern const struct clk_ops clk_rcg_bypass2_ops;
110extern const struct clk_ops clk_rcg_pixel_ops;
111extern const struct clk_ops clk_rcg_esc_ops;
109extern const struct clk_ops clk_rcg_lcc_ops; 112extern const struct clk_ops clk_rcg_lcc_ops;
110 113
111#define to_clk_rcg(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg, clkr) 114#define to_clk_rcg(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg, clkr)
@@ -153,8 +156,8 @@ extern const struct clk_ops clk_dyn_rcg_ops;
153 * @hid_width: number of bits in half integer divider 156 * @hid_width: number of bits in half integer divider
154 * @parent_map: map from software's parent index to hardware's src_sel field 157 * @parent_map: map from software's parent index to hardware's src_sel field
155 * @freq_tbl: frequency table 158 * @freq_tbl: frequency table
159 * @current_freq: last cached frequency when using branches with shared RCGs
156 * @clkr: regmap clock handle 160 * @clkr: regmap clock handle
157 * @lock: register lock
158 * 161 *
159 */ 162 */
160struct clk_rcg2 { 163struct clk_rcg2 {
@@ -163,14 +166,17 @@ struct clk_rcg2 {
163 u8 hid_width; 166 u8 hid_width;
164 const struct parent_map *parent_map; 167 const struct parent_map *parent_map;
165 const struct freq_tbl *freq_tbl; 168 const struct freq_tbl *freq_tbl;
169 unsigned long current_freq;
166 struct clk_regmap clkr; 170 struct clk_regmap clkr;
167}; 171};
168 172
169#define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr) 173#define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr)
170 174
171extern const struct clk_ops clk_rcg2_ops; 175extern const struct clk_ops clk_rcg2_ops;
176extern const struct clk_ops clk_rcg2_shared_ops;
172extern const struct clk_ops clk_edp_pixel_ops; 177extern const struct clk_ops clk_edp_pixel_ops;
173extern const struct clk_ops clk_byte_ops; 178extern const struct clk_ops clk_byte_ops;
179extern const struct clk_ops clk_byte2_ops;
174extern const struct clk_ops clk_pixel_ops; 180extern const struct clk_ops clk_pixel_ops;
175 181
176#endif 182#endif
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 9aec1761fd29..b544bb302f79 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -300,6 +300,85 @@ const struct clk_ops clk_rcg2_ops = {
300}; 300};
301EXPORT_SYMBOL_GPL(clk_rcg2_ops); 301EXPORT_SYMBOL_GPL(clk_rcg2_ops);
302 302
303static int clk_rcg2_shared_force_enable(struct clk_hw *hw, unsigned long rate)
304{
305 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
306 const char *name = clk_hw_get_name(hw);
307 int ret, count;
308
309 /* force enable RCG */
310 ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
311 CMD_ROOT_EN, CMD_ROOT_EN);
312 if (ret)
313 return ret;
314
315 /* wait for RCG to turn ON */
316 for (count = 500; count > 0; count--) {
317 ret = clk_rcg2_is_enabled(hw);
318 if (ret)
319 break;
320 udelay(1);
321 }
322 if (!count)
323 pr_err("%s: RCG did not turn on\n", name);
324
325 /* set clock rate */
326 ret = __clk_rcg2_set_rate(hw, rate);
327 if (ret)
328 return ret;
329
330 /* clear force enable RCG */
331 return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
332 CMD_ROOT_EN, 0);
333}
334
335static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
336 unsigned long parent_rate)
337{
338 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
339
340 /* cache the rate */
341 rcg->current_freq = rate;
342
343 if (!__clk_is_enabled(hw->clk))
344 return 0;
345
346 return clk_rcg2_shared_force_enable(hw, rcg->current_freq);
347}
348
349static unsigned long
350clk_rcg2_shared_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
351{
352 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
353
354 return rcg->current_freq = clk_rcg2_recalc_rate(hw, parent_rate);
355}
356
357static int clk_rcg2_shared_enable(struct clk_hw *hw)
358{
359 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
360
361 return clk_rcg2_shared_force_enable(hw, rcg->current_freq);
362}
363
364static void clk_rcg2_shared_disable(struct clk_hw *hw)
365{
366 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
367
368 /* switch to XO, which is the lowest entry in the freq table */
369 clk_rcg2_shared_set_rate(hw, rcg->freq_tbl[0].freq, 0);
370}
371
372const struct clk_ops clk_rcg2_shared_ops = {
373 .enable = clk_rcg2_shared_enable,
374 .disable = clk_rcg2_shared_disable,
375 .get_parent = clk_rcg2_get_parent,
376 .recalc_rate = clk_rcg2_shared_recalc_rate,
377 .determine_rate = clk_rcg2_determine_rate,
378 .set_rate = clk_rcg2_shared_set_rate,
379};
380EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
381
303struct frac_entry { 382struct frac_entry {
304 int num; 383 int num;
305 int den; 384 int den;
@@ -485,6 +564,76 @@ const struct clk_ops clk_byte_ops = {
485}; 564};
486EXPORT_SYMBOL_GPL(clk_byte_ops); 565EXPORT_SYMBOL_GPL(clk_byte_ops);
487 566
567static int clk_byte2_determine_rate(struct clk_hw *hw,
568 struct clk_rate_request *req)
569{
570 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
571 unsigned long parent_rate, div;
572 u32 mask = BIT(rcg->hid_width) - 1;
573 struct clk_hw *p;
574 unsigned long rate = req->rate;
575
576 if (rate == 0)
577 return -EINVAL;
578
579 p = req->best_parent_hw;
580 req->best_parent_rate = parent_rate = clk_hw_round_rate(p, rate);
581
582 div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
583 div = min_t(u32, div, mask);
584
585 req->rate = calc_rate(parent_rate, 0, 0, 0, div);
586
587 return 0;
588}
589
590static int clk_byte2_set_rate(struct clk_hw *hw, unsigned long rate,
591 unsigned long parent_rate)
592{
593 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
594 struct freq_tbl f = { 0 };
595 unsigned long div;
596 int i, num_parents = clk_hw_get_num_parents(hw);
597 u32 mask = BIT(rcg->hid_width) - 1;
598 u32 cfg;
599
600 div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
601 div = min_t(u32, div, mask);
602
603 f.pre_div = div;
604
605 regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
606 cfg &= CFG_SRC_SEL_MASK;
607 cfg >>= CFG_SRC_SEL_SHIFT;
608
609 for (i = 0; i < num_parents; i++) {
610 if (cfg == rcg->parent_map[i].cfg) {
611 f.src = rcg->parent_map[i].src;
612 return clk_rcg2_configure(rcg, &f);
613 }
614 }
615
616 return -EINVAL;
617}
618
619static int clk_byte2_set_rate_and_parent(struct clk_hw *hw,
620 unsigned long rate, unsigned long parent_rate, u8 index)
621{
622 /* Read the hardware to determine parent during set_rate */
623 return clk_byte2_set_rate(hw, rate, parent_rate);
624}
625
626const struct clk_ops clk_byte2_ops = {
627 .is_enabled = clk_rcg2_is_enabled,
628 .get_parent = clk_rcg2_get_parent,
629 .set_parent = clk_rcg2_set_parent,
630 .recalc_rate = clk_rcg2_recalc_rate,
631 .set_rate = clk_byte2_set_rate,
632 .set_rate_and_parent = clk_byte2_set_rate_and_parent,
633 .determine_rate = clk_byte2_determine_rate,
634};
635EXPORT_SYMBOL_GPL(clk_byte2_ops);
636
488static const struct frac_entry frac_table_pixel[] = { 637static const struct frac_entry frac_table_pixel[] = {
489 { 3, 8 }, 638 { 3, 8 },
490 { 2, 9 }, 639 { 2, 9 },
@@ -496,14 +645,9 @@ static const struct frac_entry frac_table_pixel[] = {
496static int clk_pixel_determine_rate(struct clk_hw *hw, 645static int clk_pixel_determine_rate(struct clk_hw *hw,
497 struct clk_rate_request *req) 646 struct clk_rate_request *req)
498{ 647{
499 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
500 unsigned long request, src_rate; 648 unsigned long request, src_rate;
501 int delta = 100000; 649 int delta = 100000;
502 const struct freq_tbl *f = rcg->freq_tbl;
503 const struct frac_entry *frac = frac_table_pixel; 650 const struct frac_entry *frac = frac_table_pixel;
504 int index = qcom_find_src_index(hw, rcg->parent_map, f->src);
505
506 req->best_parent_hw = clk_hw_get_parent_by_index(hw, index);
507 651
508 for (; frac->num; frac++) { 652 for (; frac->num; frac++) {
509 request = (req->rate * frac->den) / frac->num; 653 request = (req->rate * frac->den) / frac->num;
@@ -525,12 +669,23 @@ static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
525 unsigned long parent_rate) 669 unsigned long parent_rate)
526{ 670{
527 struct clk_rcg2 *rcg = to_clk_rcg2(hw); 671 struct clk_rcg2 *rcg = to_clk_rcg2(hw);
528 struct freq_tbl f = *rcg->freq_tbl; 672 struct freq_tbl f = { 0 };
529 const struct frac_entry *frac = frac_table_pixel; 673 const struct frac_entry *frac = frac_table_pixel;
530 unsigned long request; 674 unsigned long request;
531 int delta = 100000; 675 int delta = 100000;
532 u32 mask = BIT(rcg->hid_width) - 1; 676 u32 mask = BIT(rcg->hid_width) - 1;
533 u32 hid_div; 677 u32 hid_div, cfg;
678 int i, num_parents = clk_hw_get_num_parents(hw);
679
680 regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
681 cfg &= CFG_SRC_SEL_MASK;
682 cfg >>= CFG_SRC_SEL_SHIFT;
683
684 for (i = 0; i < num_parents; i++)
685 if (cfg == rcg->parent_map[i].cfg) {
686 f.src = rcg->parent_map[i].src;
687 break;
688 }
534 689
535 for (; frac->num; frac++) { 690 for (; frac->num; frac++) {
536 request = (rate * frac->den) / frac->num; 691 request = (rate * frac->den) / frac->num;
@@ -555,7 +710,6 @@ static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
555static int clk_pixel_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, 710static int clk_pixel_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
556 unsigned long parent_rate, u8 index) 711 unsigned long parent_rate, u8 index)
557{ 712{
558 /* Parent index is set statically in frequency table */
559 return clk_pixel_set_rate(hw, rate, parent_rate); 713 return clk_pixel_set_rate(hw, rate, parent_rate);
560} 714}
561 715
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index 2dedceefd21d..8fa477293ae0 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -22,6 +22,7 @@
22#include "clk-rcg.h" 22#include "clk-rcg.h"
23#include "clk-regmap.h" 23#include "clk-regmap.h"
24#include "reset.h" 24#include "reset.h"
25#include "gdsc.h"
25 26
26struct qcom_cc { 27struct qcom_cc {
27 struct qcom_reset_controller reset; 28 struct qcom_reset_controller reset;
@@ -72,6 +73,21 @@ qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc)
72} 73}
73EXPORT_SYMBOL_GPL(qcom_cc_map); 74EXPORT_SYMBOL_GPL(qcom_cc_map);
74 75
76static void qcom_cc_del_clk_provider(void *data)
77{
78 of_clk_del_provider(data);
79}
80
81static void qcom_cc_reset_unregister(void *data)
82{
83 reset_controller_unregister(data);
84}
85
86static void qcom_cc_gdsc_unregister(void *data)
87{
88 gdsc_unregister(data);
89}
90
75int qcom_cc_really_probe(struct platform_device *pdev, 91int qcom_cc_really_probe(struct platform_device *pdev,
76 const struct qcom_cc_desc *desc, struct regmap *regmap) 92 const struct qcom_cc_desc *desc, struct regmap *regmap)
77{ 93{
@@ -110,6 +126,8 @@ int qcom_cc_really_probe(struct platform_device *pdev,
110 if (ret) 126 if (ret)
111 return ret; 127 return ret;
112 128
129 devm_add_action(dev, qcom_cc_del_clk_provider, pdev->dev.of_node);
130
113 reset = &cc->reset; 131 reset = &cc->reset;
114 reset->rcdev.of_node = dev->of_node; 132 reset->rcdev.of_node = dev->of_node;
115 reset->rcdev.ops = &qcom_reset_ops; 133 reset->rcdev.ops = &qcom_reset_ops;
@@ -117,13 +135,24 @@ int qcom_cc_really_probe(struct platform_device *pdev,
117 reset->rcdev.nr_resets = desc->num_resets; 135 reset->rcdev.nr_resets = desc->num_resets;
118 reset->regmap = regmap; 136 reset->regmap = regmap;
119 reset->reset_map = desc->resets; 137 reset->reset_map = desc->resets;
120 platform_set_drvdata(pdev, &reset->rcdev);
121 138
122 ret = reset_controller_register(&reset->rcdev); 139 ret = reset_controller_register(&reset->rcdev);
123 if (ret) 140 if (ret)
124 of_clk_del_provider(dev->of_node); 141 return ret;
142
143 devm_add_action(dev, qcom_cc_reset_unregister, &reset->rcdev);
144
145 if (desc->gdscs && desc->num_gdscs) {
146 ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs,
147 &reset->rcdev, regmap);
148 if (ret)
149 return ret;
150 }
151
152 devm_add_action(dev, qcom_cc_gdsc_unregister, dev);
125 153
126 return ret; 154
155 return 0;
127} 156}
128EXPORT_SYMBOL_GPL(qcom_cc_really_probe); 157EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
129 158
@@ -139,11 +168,4 @@ int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc)
139} 168}
140EXPORT_SYMBOL_GPL(qcom_cc_probe); 169EXPORT_SYMBOL_GPL(qcom_cc_probe);
141 170
142void qcom_cc_remove(struct platform_device *pdev)
143{
144 of_clk_del_provider(pdev->dev.of_node);
145 reset_controller_unregister(platform_get_drvdata(pdev));
146}
147EXPORT_SYMBOL_GPL(qcom_cc_remove);
148
149MODULE_LICENSE("GPL v2"); 171MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
index 7a0e73713063..7c1fba3ebc03 100644
--- a/drivers/clk/qcom/common.h
+++ b/drivers/clk/qcom/common.h
@@ -28,6 +28,8 @@ struct qcom_cc_desc {
28 size_t num_clks; 28 size_t num_clks;
29 const struct qcom_reset_map *resets; 29 const struct qcom_reset_map *resets;
30 size_t num_resets; 30 size_t num_resets;
31 struct gdsc **gdscs;
32 size_t num_gdscs;
31}; 33};
32 34
33extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, 35extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
@@ -43,6 +45,4 @@ extern int qcom_cc_really_probe(struct platform_device *pdev,
43extern int qcom_cc_probe(struct platform_device *pdev, 45extern int qcom_cc_probe(struct platform_device *pdev,
44 const struct qcom_cc_desc *desc); 46 const struct qcom_cc_desc *desc);
45 47
46extern void qcom_cc_remove(struct platform_device *pdev);
47
48#endif 48#endif
diff --git a/drivers/clk/qcom/gcc-apq8084.c b/drivers/clk/qcom/gcc-apq8084.c
index 3563019b8e3c..1567c3a79534 100644
--- a/drivers/clk/qcom/gcc-apq8084.c
+++ b/drivers/clk/qcom/gcc-apq8084.c
@@ -31,6 +31,7 @@
31#include "clk-rcg.h" 31#include "clk-rcg.h"
32#include "clk-branch.h" 32#include "clk-branch.h"
33#include "reset.h" 33#include "reset.h"
34#include "gdsc.h"
34 35
35enum { 36enum {
36 P_XO, 37 P_XO,
@@ -3254,6 +3255,38 @@ static struct clk_branch gcc_usb_hsic_system_clk = {
3254 }, 3255 },
3255}; 3256};
3256 3257
3258static struct gdsc usb_hs_hsic_gdsc = {
3259 .gdscr = 0x404,
3260 .pd = {
3261 .name = "usb_hs_hsic",
3262 },
3263 .pwrsts = PWRSTS_OFF_ON,
3264};
3265
3266static struct gdsc pcie0_gdsc = {
3267 .gdscr = 0x1ac4,
3268 .pd = {
3269 .name = "pcie0",
3270 },
3271 .pwrsts = PWRSTS_OFF_ON,
3272};
3273
3274static struct gdsc pcie1_gdsc = {
3275 .gdscr = 0x1b44,
3276 .pd = {
3277 .name = "pcie1",
3278 },
3279 .pwrsts = PWRSTS_OFF_ON,
3280};
3281
3282static struct gdsc usb30_gdsc = {
3283 .gdscr = 0x1e84,
3284 .pd = {
3285 .name = "usb30",
3286 },
3287 .pwrsts = PWRSTS_OFF_ON,
3288};
3289
3257static struct clk_regmap *gcc_apq8084_clocks[] = { 3290static struct clk_regmap *gcc_apq8084_clocks[] = {
3258 [GPLL0] = &gpll0.clkr, 3291 [GPLL0] = &gpll0.clkr,
3259 [GPLL0_VOTE] = &gpll0_vote, 3292 [GPLL0_VOTE] = &gpll0_vote,
@@ -3447,6 +3480,13 @@ static struct clk_regmap *gcc_apq8084_clocks[] = {
3447 [GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr, 3480 [GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr,
3448}; 3481};
3449 3482
3483static struct gdsc *gcc_apq8084_gdscs[] = {
3484 [USB_HS_HSIC_GDSC] = &usb_hs_hsic_gdsc,
3485 [PCIE0_GDSC] = &pcie0_gdsc,
3486 [PCIE1_GDSC] = &pcie1_gdsc,
3487 [USB30_GDSC] = &usb30_gdsc,
3488};
3489
3450static const struct qcom_reset_map gcc_apq8084_resets[] = { 3490static const struct qcom_reset_map gcc_apq8084_resets[] = {
3451 [GCC_SYSTEM_NOC_BCR] = { 0x0100 }, 3491 [GCC_SYSTEM_NOC_BCR] = { 0x0100 },
3452 [GCC_CONFIG_NOC_BCR] = { 0x0140 }, 3492 [GCC_CONFIG_NOC_BCR] = { 0x0140 },
@@ -3555,6 +3595,8 @@ static const struct qcom_cc_desc gcc_apq8084_desc = {
3555 .num_clks = ARRAY_SIZE(gcc_apq8084_clocks), 3595 .num_clks = ARRAY_SIZE(gcc_apq8084_clocks),
3556 .resets = gcc_apq8084_resets, 3596 .resets = gcc_apq8084_resets,
3557 .num_resets = ARRAY_SIZE(gcc_apq8084_resets), 3597 .num_resets = ARRAY_SIZE(gcc_apq8084_resets),
3598 .gdscs = gcc_apq8084_gdscs,
3599 .num_gdscs = ARRAY_SIZE(gcc_apq8084_gdscs),
3558}; 3600};
3559 3601
3560static const struct of_device_id gcc_apq8084_match_table[] = { 3602static const struct of_device_id gcc_apq8084_match_table[] = {
@@ -3581,15 +3623,8 @@ static int gcc_apq8084_probe(struct platform_device *pdev)
3581 return qcom_cc_probe(pdev, &gcc_apq8084_desc); 3623 return qcom_cc_probe(pdev, &gcc_apq8084_desc);
3582} 3624}
3583 3625
3584static int gcc_apq8084_remove(struct platform_device *pdev)
3585{
3586 qcom_cc_remove(pdev);
3587 return 0;
3588}
3589
3590static struct platform_driver gcc_apq8084_driver = { 3626static struct platform_driver gcc_apq8084_driver = {
3591 .probe = gcc_apq8084_probe, 3627 .probe = gcc_apq8084_probe,
3592 .remove = gcc_apq8084_remove,
3593 .driver = { 3628 .driver = {
3594 .name = "gcc-apq8084", 3629 .name = "gcc-apq8084",
3595 .of_match_table = gcc_apq8084_match_table, 3630 .of_match_table = gcc_apq8084_match_table,
diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c
index 40e480220cd3..16fc64c082a5 100644
--- a/drivers/clk/qcom/gcc-ipq806x.c
+++ b/drivers/clk/qcom/gcc-ipq806x.c
@@ -3058,15 +3058,8 @@ static int gcc_ipq806x_probe(struct platform_device *pdev)
3058 return 0; 3058 return 0;
3059} 3059}
3060 3060
3061static int gcc_ipq806x_remove(struct platform_device *pdev)
3062{
3063 qcom_cc_remove(pdev);
3064 return 0;
3065}
3066
3067static struct platform_driver gcc_ipq806x_driver = { 3061static struct platform_driver gcc_ipq806x_driver = {
3068 .probe = gcc_ipq806x_probe, 3062 .probe = gcc_ipq806x_probe,
3069 .remove = gcc_ipq806x_remove,
3070 .driver = { 3063 .driver = {
3071 .name = "gcc-ipq806x", 3064 .name = "gcc-ipq806x",
3072 .of_match_table = gcc_ipq806x_match_table, 3065 .of_match_table = gcc_ipq806x_match_table,
diff --git a/drivers/clk/qcom/gcc-msm8660.c b/drivers/clk/qcom/gcc-msm8660.c
index b02826ed770a..f110bb5a1df3 100644
--- a/drivers/clk/qcom/gcc-msm8660.c
+++ b/drivers/clk/qcom/gcc-msm8660.c
@@ -2735,15 +2735,8 @@ static int gcc_msm8660_probe(struct platform_device *pdev)
2735 return qcom_cc_probe(pdev, &gcc_msm8660_desc); 2735 return qcom_cc_probe(pdev, &gcc_msm8660_desc);
2736} 2736}
2737 2737
2738static int gcc_msm8660_remove(struct platform_device *pdev)
2739{
2740 qcom_cc_remove(pdev);
2741 return 0;
2742}
2743
2744static struct platform_driver gcc_msm8660_driver = { 2738static struct platform_driver gcc_msm8660_driver = {
2745 .probe = gcc_msm8660_probe, 2739 .probe = gcc_msm8660_probe,
2746 .remove = gcc_msm8660_remove,
2747 .driver = { 2740 .driver = {
2748 .name = "gcc-msm8660", 2741 .name = "gcc-msm8660",
2749 .of_match_table = gcc_msm8660_match_table, 2742 .of_match_table = gcc_msm8660_match_table,
diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c
index 22a4e1e732c0..d0a0313d6bef 100644
--- a/drivers/clk/qcom/gcc-msm8916.c
+++ b/drivers/clk/qcom/gcc-msm8916.c
@@ -31,6 +31,7 @@
31#include "clk-rcg.h" 31#include "clk-rcg.h"
32#include "clk-branch.h" 32#include "clk-branch.h"
33#include "reset.h" 33#include "reset.h"
34#include "gdsc.h"
34 35
35enum { 36enum {
36 P_XO, 37 P_XO,
@@ -44,6 +45,9 @@ enum {
44 P_SLEEP_CLK, 45 P_SLEEP_CLK,
45 P_DSI0_PHYPLL_BYTE, 46 P_DSI0_PHYPLL_BYTE,
46 P_DSI0_PHYPLL_DSI, 47 P_DSI0_PHYPLL_DSI,
48 P_EXT_PRI_I2S,
49 P_EXT_SEC_I2S,
50 P_EXT_MCLK,
47}; 51};
48 52
49static const struct parent_map gcc_xo_gpll0_map[] = { 53static const struct parent_map gcc_xo_gpll0_map[] = {
@@ -190,6 +194,76 @@ static const char * const gcc_xo_gpll0a_gpll1_gpll2[] = {
190 "gpll2_vote", 194 "gpll2_vote",
191}; 195};
192 196
197static const struct parent_map gcc_xo_gpll0_gpll1_sleep_map[] = {
198 { P_XO, 0 },
199 { P_GPLL0, 1 },
200 { P_GPLL1, 2 },
201 { P_SLEEP_CLK, 6 }
202};
203
204static const char * const gcc_xo_gpll0_gpll1_sleep[] = {
205 "xo",
206 "gpll0_vote",
207 "gpll1_vote",
208 "sleep_clk",
209};
210
211static const struct parent_map gcc_xo_gpll1_epi2s_emclk_sleep_map[] = {
212 { P_XO, 0 },
213 { P_GPLL1, 1 },
214 { P_EXT_PRI_I2S, 2 },
215 { P_EXT_MCLK, 3 },
216 { P_SLEEP_CLK, 6 }
217};
218
219static const char * const gcc_xo_gpll1_epi2s_emclk_sleep[] = {
220 "xo",
221 "gpll1_vote",
222 "ext_pri_i2s",
223 "ext_mclk",
224 "sleep_clk",
225};
226
227static const struct parent_map gcc_xo_gpll1_esi2s_emclk_sleep_map[] = {
228 { P_XO, 0 },
229 { P_GPLL1, 1 },
230 { P_EXT_SEC_I2S, 2 },
231 { P_EXT_MCLK, 3 },
232 { P_SLEEP_CLK, 6 }
233};
234
235static const char * const gcc_xo_gpll1_esi2s_emclk_sleep[] = {
236 "xo",
237 "gpll1_vote",
238 "ext_sec_i2s",
239 "ext_mclk",
240 "sleep_clk",
241};
242
243static const struct parent_map gcc_xo_sleep_map[] = {
244 { P_XO, 0 },
245 { P_SLEEP_CLK, 6 }
246};
247
248static const char * const gcc_xo_sleep[] = {
249 "xo",
250 "sleep_clk",
251};
252
253static const struct parent_map gcc_xo_gpll1_emclk_sleep_map[] = {
254 { P_XO, 0 },
255 { P_GPLL1, 1 },
256 { P_EXT_MCLK, 2 },
257 { P_SLEEP_CLK, 6 }
258};
259
260static const char * const gcc_xo_gpll1_emclk_sleep[] = {
261 "xo",
262 "gpll1_vote",
263 "ext_mclk",
264 "sleep_clk",
265};
266
193#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 267#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
194 268
195static struct clk_pll gpll0 = { 269static struct clk_pll gpll0 = {
@@ -906,21 +980,15 @@ static struct clk_rcg2 gp3_clk_src = {
906 }, 980 },
907}; 981};
908 982
909static struct freq_tbl ftbl_gcc_mdss_byte0_clk[] = {
910 { .src = P_DSI0_PHYPLL_BYTE },
911 { }
912};
913
914static struct clk_rcg2 byte0_clk_src = { 983static struct clk_rcg2 byte0_clk_src = {
915 .cmd_rcgr = 0x4d044, 984 .cmd_rcgr = 0x4d044,
916 .hid_width = 5, 985 .hid_width = 5,
917 .parent_map = gcc_xo_gpll0a_dsibyte_map, 986 .parent_map = gcc_xo_gpll0a_dsibyte_map,
918 .freq_tbl = ftbl_gcc_mdss_byte0_clk,
919 .clkr.hw.init = &(struct clk_init_data){ 987 .clkr.hw.init = &(struct clk_init_data){
920 .name = "byte0_clk_src", 988 .name = "byte0_clk_src",
921 .parent_names = gcc_xo_gpll0a_dsibyte, 989 .parent_names = gcc_xo_gpll0a_dsibyte,
922 .num_parents = 3, 990 .num_parents = 3,
923 .ops = &clk_byte_ops, 991 .ops = &clk_byte2_ops,
924 .flags = CLK_SET_RATE_PARENT, 992 .flags = CLK_SET_RATE_PARENT,
925 }, 993 },
926}; 994};
@@ -968,17 +1036,11 @@ static struct clk_rcg2 mdp_clk_src = {
968 }, 1036 },
969}; 1037};
970 1038
971static struct freq_tbl ftbl_gcc_mdss_pclk[] = {
972 { .src = P_DSI0_PHYPLL_DSI },
973 { }
974};
975
976static struct clk_rcg2 pclk0_clk_src = { 1039static struct clk_rcg2 pclk0_clk_src = {
977 .cmd_rcgr = 0x4d000, 1040 .cmd_rcgr = 0x4d000,
978 .mnd_width = 8, 1041 .mnd_width = 8,
979 .hid_width = 5, 1042 .hid_width = 5,
980 .parent_map = gcc_xo_gpll0a_dsiphy_map, 1043 .parent_map = gcc_xo_gpll0a_dsiphy_map,
981 .freq_tbl = ftbl_gcc_mdss_pclk,
982 .clkr.hw.init = &(struct clk_init_data){ 1044 .clkr.hw.init = &(struct clk_init_data){
983 .name = "pclk0_clk_src", 1045 .name = "pclk0_clk_src",
984 .parent_names = gcc_xo_gpll0a_dsiphy, 1046 .parent_names = gcc_xo_gpll0a_dsiphy,
@@ -1094,6 +1156,30 @@ static struct clk_rcg2 apss_tcu_clk_src = {
1094 }, 1156 },
1095}; 1157};
1096 1158
1159static const struct freq_tbl ftbl_gcc_bimc_gpu_clk[] = {
1160 F(19200000, P_XO, 1, 0, 0),
1161 F(100000000, P_GPLL0, 8, 0, 0),
1162 F(200000000, P_GPLL0, 4, 0, 0),
1163 F(266500000, P_BIMC, 4, 0, 0),
1164 F(400000000, P_GPLL0, 2, 0, 0),
1165 F(533000000, P_BIMC, 2, 0, 0),
1166 { }
1167};
1168
1169static struct clk_rcg2 bimc_gpu_clk_src = {
1170 .cmd_rcgr = 0x31028,
1171 .hid_width = 5,
1172 .parent_map = gcc_xo_gpll0_bimc_map,
1173 .freq_tbl = ftbl_gcc_bimc_gpu_clk,
1174 .clkr.hw.init = &(struct clk_init_data){
1175 .name = "bimc_gpu_clk_src",
1176 .parent_names = gcc_xo_gpll0_bimc,
1177 .num_parents = 3,
1178 .flags = CLK_GET_RATE_NOCACHE,
1179 .ops = &clk_rcg2_shared_ops,
1180 },
1181};
1182
1097static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = { 1183static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
1098 F(80000000, P_GPLL0, 10, 0, 0), 1184 F(80000000, P_GPLL0, 10, 0, 0),
1099 { } 1185 { }
@@ -1112,6 +1198,305 @@ static struct clk_rcg2 usb_hs_system_clk_src = {
1112 }, 1198 },
1113}; 1199};
1114 1200
1201static const struct freq_tbl ftbl_gcc_ultaudio_ahb_clk[] = {
1202 F(3200000, P_XO, 6, 0, 0),
1203 F(6400000, P_XO, 3, 0, 0),
1204 F(9600000, P_XO, 2, 0, 0),
1205 F(19200000, P_XO, 1, 0, 0),
1206 F(40000000, P_GPLL0, 10, 1, 2),
1207 F(66670000, P_GPLL0, 12, 0, 0),
1208 F(80000000, P_GPLL0, 10, 0, 0),
1209 F(100000000, P_GPLL0, 8, 0, 0),
1210 { }
1211};
1212
1213static struct clk_rcg2 ultaudio_ahbfabric_clk_src = {
1214 .cmd_rcgr = 0x1c010,
1215 .hid_width = 5,
1216 .mnd_width = 8,
1217 .parent_map = gcc_xo_gpll0_gpll1_sleep_map,
1218 .freq_tbl = ftbl_gcc_ultaudio_ahb_clk,
1219 .clkr.hw.init = &(struct clk_init_data){
1220 .name = "ultaudio_ahbfabric_clk_src",
1221 .parent_names = gcc_xo_gpll0_gpll1_sleep,
1222 .num_parents = 4,
1223 .ops = &clk_rcg2_ops,
1224 },
1225};
1226
1227static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_clk = {
1228 .halt_reg = 0x1c028,
1229 .clkr = {
1230 .enable_reg = 0x1c028,
1231 .enable_mask = BIT(0),
1232 .hw.init = &(struct clk_init_data){
1233 .name = "gcc_ultaudio_ahbfabric_ixfabric_clk",
1234 .parent_names = (const char *[]){
1235 "ultaudio_ahbfabric_clk_src",
1236 },
1237 .num_parents = 1,
1238 .flags = CLK_SET_RATE_PARENT,
1239 .ops = &clk_branch2_ops,
1240 },
1241 },
1242};
1243
1244static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_lpm_clk = {
1245 .halt_reg = 0x1c024,
1246 .clkr = {
1247 .enable_reg = 0x1c024,
1248 .enable_mask = BIT(0),
1249 .hw.init = &(struct clk_init_data){
1250 .name = "gcc_ultaudio_ahbfabric_ixfabric_lpm_clk",
1251 .parent_names = (const char *[]){
1252 "ultaudio_ahbfabric_clk_src",
1253 },
1254 .num_parents = 1,
1255 .flags = CLK_SET_RATE_PARENT,
1256 .ops = &clk_branch2_ops,
1257 },
1258 },
1259};
1260
1261static const struct freq_tbl ftbl_gcc_ultaudio_lpaif_i2s_clk[] = {
1262 F(256000, P_XO, 5, 1, 15),
1263 F(512000, P_XO, 5, 2, 15),
1264 F(705600, P_GPLL1, 16, 1, 80),
1265 F(768000, P_XO, 5, 1, 5),
1266 F(800000, P_XO, 5, 5, 24),
1267 F(1024000, P_GPLL1, 14, 1, 63),
1268 F(1152000, P_XO, 1, 3, 50),
1269 F(1411200, P_GPLL1, 16, 1, 40),
1270 F(1536000, P_XO, 1, 2, 25),
1271 F(1600000, P_XO, 12, 0, 0),
1272 F(2048000, P_GPLL1, 9, 1, 49),
1273 F(2400000, P_XO, 8, 0, 0),
1274 F(2822400, P_GPLL1, 16, 1, 20),
1275 F(3072000, P_GPLL1, 14, 1, 21),
1276 F(4096000, P_GPLL1, 9, 2, 49),
1277 F(4800000, P_XO, 4, 0, 0),
1278 F(5644800, P_GPLL1, 16, 1, 10),
1279 F(6144000, P_GPLL1, 7, 1, 21),
1280 F(8192000, P_GPLL1, 9, 4, 49),
1281 F(9600000, P_XO, 2, 0, 0),
1282 F(11289600, P_GPLL1, 16, 1, 5),
1283 F(12288000, P_GPLL1, 7, 2, 21),
1284 { }
1285};
1286
1287static struct clk_rcg2 ultaudio_lpaif_pri_i2s_clk_src = {
1288 .cmd_rcgr = 0x1c054,
1289 .hid_width = 5,
1290 .mnd_width = 8,
1291 .parent_map = gcc_xo_gpll1_epi2s_emclk_sleep_map,
1292 .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
1293 .clkr.hw.init = &(struct clk_init_data){
1294 .name = "ultaudio_lpaif_pri_i2s_clk_src",
1295 .parent_names = gcc_xo_gpll1_epi2s_emclk_sleep,
1296 .num_parents = 5,
1297 .ops = &clk_rcg2_ops,
1298 },
1299};
1300
1301static struct clk_branch gcc_ultaudio_lpaif_pri_i2s_clk = {
1302 .halt_reg = 0x1c068,
1303 .clkr = {
1304 .enable_reg = 0x1c068,
1305 .enable_mask = BIT(0),
1306 .hw.init = &(struct clk_init_data){
1307 .name = "gcc_ultaudio_lpaif_pri_i2s_clk",
1308 .parent_names = (const char *[]){
1309 "ultaudio_lpaif_pri_i2s_clk_src",
1310 },
1311 .num_parents = 1,
1312 .flags = CLK_SET_RATE_PARENT,
1313 .ops = &clk_branch2_ops,
1314 },
1315 },
1316};
1317
1318static struct clk_rcg2 ultaudio_lpaif_sec_i2s_clk_src = {
1319 .cmd_rcgr = 0x1c06c,
1320 .hid_width = 5,
1321 .mnd_width = 8,
1322 .parent_map = gcc_xo_gpll1_esi2s_emclk_sleep_map,
1323 .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
1324 .clkr.hw.init = &(struct clk_init_data){
1325 .name = "ultaudio_lpaif_sec_i2s_clk_src",
1326 .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep,
1327 .num_parents = 5,
1328 .ops = &clk_rcg2_ops,
1329 },
1330};
1331
1332static struct clk_branch gcc_ultaudio_lpaif_sec_i2s_clk = {
1333 .halt_reg = 0x1c080,
1334 .clkr = {
1335 .enable_reg = 0x1c080,
1336 .enable_mask = BIT(0),
1337 .hw.init = &(struct clk_init_data){
1338 .name = "gcc_ultaudio_lpaif_sec_i2s_clk",
1339 .parent_names = (const char *[]){
1340 "ultaudio_lpaif_sec_i2s_clk_src",
1341 },
1342 .num_parents = 1,
1343 .flags = CLK_SET_RATE_PARENT,
1344 .ops = &clk_branch2_ops,
1345 },
1346 },
1347};
1348
1349static struct clk_rcg2 ultaudio_lpaif_aux_i2s_clk_src = {
1350 .cmd_rcgr = 0x1c084,
1351 .hid_width = 5,
1352 .mnd_width = 8,
1353 .parent_map = gcc_xo_gpll1_emclk_sleep_map,
1354 .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
1355 .clkr.hw.init = &(struct clk_init_data){
1356 .name = "ultaudio_lpaif_aux_i2s_clk_src",
1357 .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep,
1358 .num_parents = 5,
1359 .ops = &clk_rcg2_ops,
1360 },
1361};
1362
1363static struct clk_branch gcc_ultaudio_lpaif_aux_i2s_clk = {
1364 .halt_reg = 0x1c098,
1365 .clkr = {
1366 .enable_reg = 0x1c098,
1367 .enable_mask = BIT(0),
1368 .hw.init = &(struct clk_init_data){
1369 .name = "gcc_ultaudio_lpaif_aux_i2s_clk",
1370 .parent_names = (const char *[]){
1371 "ultaudio_lpaif_aux_i2s_clk_src",
1372 },
1373 .num_parents = 1,
1374 .flags = CLK_SET_RATE_PARENT,
1375 .ops = &clk_branch2_ops,
1376 },
1377 },
1378};
1379
1380static const struct freq_tbl ftbl_gcc_ultaudio_xo_clk[] = {
1381 F(19200000, P_XO, 1, 0, 0),
1382 { }
1383};
1384
1385static struct clk_rcg2 ultaudio_xo_clk_src = {
1386 .cmd_rcgr = 0x1c034,
1387 .hid_width = 5,
1388 .parent_map = gcc_xo_sleep_map,
1389 .freq_tbl = ftbl_gcc_ultaudio_xo_clk,
1390 .clkr.hw.init = &(struct clk_init_data){
1391 .name = "ultaudio_xo_clk_src",
1392 .parent_names = gcc_xo_sleep,
1393 .num_parents = 2,
1394 .ops = &clk_rcg2_ops,
1395 },
1396};
1397
1398static struct clk_branch gcc_ultaudio_avsync_xo_clk = {
1399 .halt_reg = 0x1c04c,
1400 .clkr = {
1401 .enable_reg = 0x1c04c,
1402 .enable_mask = BIT(0),
1403 .hw.init = &(struct clk_init_data){
1404 .name = "gcc_ultaudio_avsync_xo_clk",
1405 .parent_names = (const char *[]){
1406 "ultaudio_xo_clk_src",
1407 },
1408 .num_parents = 1,
1409 .flags = CLK_SET_RATE_PARENT,
1410 .ops = &clk_branch2_ops,
1411 },
1412 },
1413};
1414
1415static struct clk_branch gcc_ultaudio_stc_xo_clk = {
1416 .halt_reg = 0x1c050,
1417 .clkr = {
1418 .enable_reg = 0x1c050,
1419 .enable_mask = BIT(0),
1420 .hw.init = &(struct clk_init_data){
1421 .name = "gcc_ultaudio_stc_xo_clk",
1422 .parent_names = (const char *[]){
1423 "ultaudio_xo_clk_src",
1424 },
1425 .num_parents = 1,
1426 .flags = CLK_SET_RATE_PARENT,
1427 .ops = &clk_branch2_ops,
1428 },
1429 },
1430};
1431
1432static const struct freq_tbl ftbl_codec_clk[] = {
1433 F(19200000, P_XO, 1, 0, 0),
1434 F(11289600, P_EXT_MCLK, 1, 0, 0),
1435 { }
1436};
1437
1438static struct clk_rcg2 codec_digcodec_clk_src = {
1439 .cmd_rcgr = 0x1c09c,
1440 .hid_width = 5,
1441 .parent_map = gcc_xo_gpll1_emclk_sleep_map,
1442 .freq_tbl = ftbl_codec_clk,
1443 .clkr.hw.init = &(struct clk_init_data){
1444 .name = "codec_digcodec_clk_src",
1445 .parent_names = gcc_xo_gpll1_emclk_sleep,
1446 .num_parents = 4,
1447 .ops = &clk_rcg2_ops,
1448 },
1449};
1450
1451static struct clk_branch gcc_codec_digcodec_clk = {
1452 .halt_reg = 0x1c0b0,
1453 .clkr = {
1454 .enable_reg = 0x1c0b0,
1455 .enable_mask = BIT(0),
1456 .hw.init = &(struct clk_init_data){
1457 .name = "gcc_ultaudio_codec_digcodec_clk",
1458 .parent_names = (const char *[]){
1459 "codec_digcodec_clk_src",
1460 },
1461 .num_parents = 1,
1462 .flags = CLK_SET_RATE_PARENT,
1463 .ops = &clk_branch2_ops,
1464 },
1465 },
1466};
1467
1468static struct clk_branch gcc_ultaudio_pcnoc_mport_clk = {
1469 .halt_reg = 0x1c000,
1470 .clkr = {
1471 .enable_reg = 0x1c000,
1472 .enable_mask = BIT(0),
1473 .hw.init = &(struct clk_init_data){
1474 .name = "gcc_ultaudio_pcnoc_mport_clk",
1475 .parent_names = (const char *[]){
1476 "pcnoc_bfdcd_clk_src",
1477 },
1478 .num_parents = 1,
1479 .ops = &clk_branch2_ops,
1480 },
1481 },
1482};
1483
1484static struct clk_branch gcc_ultaudio_pcnoc_sway_clk = {
1485 .halt_reg = 0x1c004,
1486 .clkr = {
1487 .enable_reg = 0x1c004,
1488 .enable_mask = BIT(0),
1489 .hw.init = &(struct clk_init_data){
1490 .name = "gcc_ultaudio_pcnoc_sway_clk",
1491 .parent_names = (const char *[]){
1492 "pcnoc_bfdcd_clk_src",
1493 },
1494 .num_parents = 1,
1495 .ops = &clk_branch2_ops,
1496 },
1497 },
1498};
1499
1115static const struct freq_tbl ftbl_gcc_venus0_vcodec0_clk[] = { 1500static const struct freq_tbl ftbl_gcc_venus0_vcodec0_clk[] = {
1116 F(100000000, P_GPLL0, 8, 0, 0), 1501 F(100000000, P_GPLL0, 8, 0, 0),
1117 F(160000000, P_GPLL0, 5, 0, 0), 1502 F(160000000, P_GPLL0, 5, 0, 0),
@@ -2358,6 +2743,51 @@ static struct clk_branch gcc_sdcc2_apps_clk = {
2358 }, 2743 },
2359}; 2744};
2360 2745
2746static struct clk_rcg2 bimc_ddr_clk_src = {
2747 .cmd_rcgr = 0x32004,
2748 .hid_width = 5,
2749 .parent_map = gcc_xo_gpll0_bimc_map,
2750 .clkr.hw.init = &(struct clk_init_data){
2751 .name = "bimc_ddr_clk_src",
2752 .parent_names = gcc_xo_gpll0_bimc,
2753 .num_parents = 3,
2754 .ops = &clk_rcg2_ops,
2755 .flags = CLK_GET_RATE_NOCACHE,
2756 },
2757};
2758
2759static struct clk_branch gcc_apss_tcu_clk = {
2760 .halt_reg = 0x12018,
2761 .clkr = {
2762 .enable_reg = 0x4500c,
2763 .enable_mask = BIT(1),
2764 .hw.init = &(struct clk_init_data){
2765 .name = "gcc_apss_tcu_clk",
2766 .parent_names = (const char *[]){
2767 "bimc_ddr_clk_src",
2768 },
2769 .num_parents = 1,
2770 .ops = &clk_branch2_ops,
2771 },
2772 },
2773};
2774
2775static struct clk_branch gcc_gfx_tcu_clk = {
2776 .halt_reg = 0x12020,
2777 .clkr = {
2778 .enable_reg = 0x4500c,
2779 .enable_mask = BIT(2),
2780 .hw.init = &(struct clk_init_data){
2781 .name = "gcc_gfx_tcu_clk",
2782 .parent_names = (const char *[]){
2783 "bimc_ddr_clk_src",
2784 },
2785 .num_parents = 1,
2786 .ops = &clk_branch2_ops,
2787 },
2788 },
2789};
2790
2361static struct clk_branch gcc_gtcu_ahb_clk = { 2791static struct clk_branch gcc_gtcu_ahb_clk = {
2362 .halt_reg = 0x12044, 2792 .halt_reg = 0x12044,
2363 .clkr = { 2793 .clkr = {
@@ -2375,6 +2805,40 @@ static struct clk_branch gcc_gtcu_ahb_clk = {
2375 }, 2805 },
2376}; 2806};
2377 2807
2808static struct clk_branch gcc_bimc_gfx_clk = {
2809 .halt_reg = 0x31024,
2810 .clkr = {
2811 .enable_reg = 0x31024,
2812 .enable_mask = BIT(0),
2813 .hw.init = &(struct clk_init_data){
2814 .name = "gcc_bimc_gfx_clk",
2815 .parent_names = (const char *[]){
2816 "bimc_gpu_clk_src",
2817 },
2818 .num_parents = 1,
2819 .flags = CLK_SET_RATE_PARENT,
2820 .ops = &clk_branch2_ops,
2821 },
2822 },
2823};
2824
2825static struct clk_branch gcc_bimc_gpu_clk = {
2826 .halt_reg = 0x31040,
2827 .clkr = {
2828 .enable_reg = 0x31040,
2829 .enable_mask = BIT(0),
2830 .hw.init = &(struct clk_init_data){
2831 .name = "gcc_bimc_gpu_clk",
2832 .parent_names = (const char *[]){
2833 "bimc_gpu_clk_src",
2834 },
2835 .num_parents = 1,
2836 .flags = CLK_SET_RATE_PARENT,
2837 .ops = &clk_branch2_ops,
2838 },
2839 },
2840};
2841
2378static struct clk_branch gcc_jpeg_tbu_clk = { 2842static struct clk_branch gcc_jpeg_tbu_clk = {
2379 .halt_reg = 0x12034, 2843 .halt_reg = 0x12034,
2380 .clkr = { 2844 .clkr = {
@@ -2562,6 +3026,46 @@ static struct clk_branch gcc_venus0_vcodec0_clk = {
2562 }, 3026 },
2563}; 3027};
2564 3028
3029static struct gdsc venus_gdsc = {
3030 .gdscr = 0x4c018,
3031 .pd = {
3032 .name = "venus",
3033 },
3034 .pwrsts = PWRSTS_OFF_ON,
3035};
3036
3037static struct gdsc mdss_gdsc = {
3038 .gdscr = 0x4d078,
3039 .pd = {
3040 .name = "mdss",
3041 },
3042 .pwrsts = PWRSTS_OFF_ON,
3043};
3044
3045static struct gdsc jpeg_gdsc = {
3046 .gdscr = 0x5701c,
3047 .pd = {
3048 .name = "jpeg",
3049 },
3050 .pwrsts = PWRSTS_OFF_ON,
3051};
3052
3053static struct gdsc vfe_gdsc = {
3054 .gdscr = 0x58034,
3055 .pd = {
3056 .name = "vfe",
3057 },
3058 .pwrsts = PWRSTS_OFF_ON,
3059};
3060
3061static struct gdsc oxili_gdsc = {
3062 .gdscr = 0x5901c,
3063 .pd = {
3064 .name = "oxili",
3065 },
3066 .pwrsts = PWRSTS_OFF_ON,
3067};
3068
2565static struct clk_regmap *gcc_msm8916_clocks[] = { 3069static struct clk_regmap *gcc_msm8916_clocks[] = {
2566 [GPLL0] = &gpll0.clkr, 3070 [GPLL0] = &gpll0.clkr,
2567 [GPLL0_VOTE] = &gpll0_vote, 3071 [GPLL0_VOTE] = &gpll0_vote,
@@ -2701,6 +3205,36 @@ static struct clk_regmap *gcc_msm8916_clocks[] = {
2701 [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr, 3205 [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr,
2702 [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr, 3206 [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr,
2703 [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr, 3207 [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr,
3208 [BIMC_DDR_CLK_SRC] = &bimc_ddr_clk_src.clkr,
3209 [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr,
3210 [GCC_GFX_TCU_CLK] = &gcc_gfx_tcu_clk.clkr,
3211 [BIMC_GPU_CLK_SRC] = &bimc_gpu_clk_src.clkr,
3212 [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
3213 [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr,
3214 [ULTAUDIO_AHBFABRIC_CLK_SRC] = &ultaudio_ahbfabric_clk_src.clkr,
3215 [ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC] = &ultaudio_lpaif_pri_i2s_clk_src.clkr,
3216 [ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC] = &ultaudio_lpaif_sec_i2s_clk_src.clkr,
3217 [ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC] = &ultaudio_lpaif_aux_i2s_clk_src.clkr,
3218 [ULTAUDIO_XO_CLK_SRC] = &ultaudio_xo_clk_src.clkr,
3219 [CODEC_DIGCODEC_CLK_SRC] = &codec_digcodec_clk_src.clkr,
3220 [GCC_ULTAUDIO_PCNOC_MPORT_CLK] = &gcc_ultaudio_pcnoc_mport_clk.clkr,
3221 [GCC_ULTAUDIO_PCNOC_SWAY_CLK] = &gcc_ultaudio_pcnoc_sway_clk.clkr,
3222 [GCC_ULTAUDIO_AVSYNC_XO_CLK] = &gcc_ultaudio_avsync_xo_clk.clkr,
3223 [GCC_ULTAUDIO_STC_XO_CLK] = &gcc_ultaudio_stc_xo_clk.clkr,
3224 [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_clk.clkr,
3225 [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_lpm_clk.clkr,
3226 [GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK] = &gcc_ultaudio_lpaif_pri_i2s_clk.clkr,
3227 [GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK] = &gcc_ultaudio_lpaif_sec_i2s_clk.clkr,
3228 [GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK] = &gcc_ultaudio_lpaif_aux_i2s_clk.clkr,
3229 [GCC_CODEC_DIGCODEC_CLK] = &gcc_codec_digcodec_clk.clkr,
3230};
3231
3232static struct gdsc *gcc_msm8916_gdscs[] = {
3233 [VENUS_GDSC] = &venus_gdsc,
3234 [MDSS_GDSC] = &mdss_gdsc,
3235 [JPEG_GDSC] = &jpeg_gdsc,
3236 [VFE_GDSC] = &vfe_gdsc,
3237 [OXILI_GDSC] = &oxili_gdsc,
2704}; 3238};
2705 3239
2706static const struct qcom_reset_map gcc_msm8916_resets[] = { 3240static const struct qcom_reset_map gcc_msm8916_resets[] = {
@@ -2810,6 +3344,8 @@ static const struct qcom_cc_desc gcc_msm8916_desc = {
2810 .num_clks = ARRAY_SIZE(gcc_msm8916_clocks), 3344 .num_clks = ARRAY_SIZE(gcc_msm8916_clocks),
2811 .resets = gcc_msm8916_resets, 3345 .resets = gcc_msm8916_resets,
2812 .num_resets = ARRAY_SIZE(gcc_msm8916_resets), 3346 .num_resets = ARRAY_SIZE(gcc_msm8916_resets),
3347 .gdscs = gcc_msm8916_gdscs,
3348 .num_gdscs = ARRAY_SIZE(gcc_msm8916_gdscs),
2813}; 3349};
2814 3350
2815static const struct of_device_id gcc_msm8916_match_table[] = { 3351static const struct of_device_id gcc_msm8916_match_table[] = {
@@ -2836,15 +3372,8 @@ static int gcc_msm8916_probe(struct platform_device *pdev)
2836 return qcom_cc_probe(pdev, &gcc_msm8916_desc); 3372 return qcom_cc_probe(pdev, &gcc_msm8916_desc);
2837} 3373}
2838 3374
2839static int gcc_msm8916_remove(struct platform_device *pdev)
2840{
2841 qcom_cc_remove(pdev);
2842 return 0;
2843}
2844
2845static struct platform_driver gcc_msm8916_driver = { 3375static struct platform_driver gcc_msm8916_driver = {
2846 .probe = gcc_msm8916_probe, 3376 .probe = gcc_msm8916_probe,
2847 .remove = gcc_msm8916_remove,
2848 .driver = { 3377 .driver = {
2849 .name = "gcc-msm8916", 3378 .name = "gcc-msm8916",
2850 .of_match_table = gcc_msm8916_match_table, 3379 .of_match_table = gcc_msm8916_match_table,
diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
index aa294b1bad34..66c18bc97857 100644
--- a/drivers/clk/qcom/gcc-msm8960.c
+++ b/drivers/clk/qcom/gcc-msm8960.c
@@ -3506,6 +3506,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
3506 struct clk *clk; 3506 struct clk *clk;
3507 struct device *dev = &pdev->dev; 3507 struct device *dev = &pdev->dev;
3508 const struct of_device_id *match; 3508 const struct of_device_id *match;
3509 struct platform_device *tsens;
3510 int ret;
3509 3511
3510 match = of_match_device(gcc_msm8960_match_table, &pdev->dev); 3512 match = of_match_device(gcc_msm8960_match_table, &pdev->dev);
3511 if (!match) 3513 if (!match)
@@ -3520,12 +3522,26 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
3520 if (IS_ERR(clk)) 3522 if (IS_ERR(clk))
3521 return PTR_ERR(clk); 3523 return PTR_ERR(clk);
3522 3524
3523 return qcom_cc_probe(pdev, match->data); 3525 ret = qcom_cc_probe(pdev, match->data);
3526 if (ret)
3527 return ret;
3528
3529 tsens = platform_device_register_data(&pdev->dev, "qcom-tsens", -1,
3530 NULL, 0);
3531 if (IS_ERR(tsens))
3532 return PTR_ERR(tsens);
3533
3534 platform_set_drvdata(pdev, tsens);
3535
3536 return 0;
3524} 3537}
3525 3538
3526static int gcc_msm8960_remove(struct platform_device *pdev) 3539static int gcc_msm8960_remove(struct platform_device *pdev)
3527{ 3540{
3528 qcom_cc_remove(pdev); 3541 struct platform_device *tsens = platform_get_drvdata(pdev);
3542
3543 platform_device_unregister(tsens);
3544
3529 return 0; 3545 return 0;
3530} 3546}
3531 3547
diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c
index 2bcf87538f9d..28abb8f8f293 100644
--- a/drivers/clk/qcom/gcc-msm8974.c
+++ b/drivers/clk/qcom/gcc-msm8974.c
@@ -31,6 +31,7 @@
31#include "clk-rcg.h" 31#include "clk-rcg.h"
32#include "clk-branch.h" 32#include "clk-branch.h"
33#include "reset.h" 33#include "reset.h"
34#include "gdsc.h"
34 35
35enum { 36enum {
36 P_XO, 37 P_XO,
@@ -2432,6 +2433,14 @@ static struct clk_branch gcc_usb_hsic_system_clk = {
2432 }, 2433 },
2433}; 2434};
2434 2435
2436static struct gdsc usb_hs_hsic_gdsc = {
2437 .gdscr = 0x404,
2438 .pd = {
2439 .name = "usb_hs_hsic",
2440 },
2441 .pwrsts = PWRSTS_OFF_ON,
2442};
2443
2435static struct clk_regmap *gcc_msm8974_clocks[] = { 2444static struct clk_regmap *gcc_msm8974_clocks[] = {
2436 [GPLL0] = &gpll0.clkr, 2445 [GPLL0] = &gpll0.clkr,
2437 [GPLL0_VOTE] = &gpll0_vote, 2446 [GPLL0_VOTE] = &gpll0_vote,
@@ -2661,6 +2670,10 @@ static const struct qcom_reset_map gcc_msm8974_resets[] = {
2661 [GCC_VENUS_RESTART] = { 0x1740 }, 2670 [GCC_VENUS_RESTART] = { 0x1740 },
2662}; 2671};
2663 2672
2673static struct gdsc *gcc_msm8974_gdscs[] = {
2674 [USB_HS_HSIC_GDSC] = &usb_hs_hsic_gdsc,
2675};
2676
2664static const struct regmap_config gcc_msm8974_regmap_config = { 2677static const struct regmap_config gcc_msm8974_regmap_config = {
2665 .reg_bits = 32, 2678 .reg_bits = 32,
2666 .reg_stride = 4, 2679 .reg_stride = 4,
@@ -2675,6 +2688,8 @@ static const struct qcom_cc_desc gcc_msm8974_desc = {
2675 .num_clks = ARRAY_SIZE(gcc_msm8974_clocks), 2688 .num_clks = ARRAY_SIZE(gcc_msm8974_clocks),
2676 .resets = gcc_msm8974_resets, 2689 .resets = gcc_msm8974_resets,
2677 .num_resets = ARRAY_SIZE(gcc_msm8974_resets), 2690 .num_resets = ARRAY_SIZE(gcc_msm8974_resets),
2691 .gdscs = gcc_msm8974_gdscs,
2692 .num_gdscs = ARRAY_SIZE(gcc_msm8974_gdscs),
2678}; 2693};
2679 2694
2680static const struct of_device_id gcc_msm8974_match_table[] = { 2695static const struct of_device_id gcc_msm8974_match_table[] = {
@@ -2729,15 +2744,8 @@ static int gcc_msm8974_probe(struct platform_device *pdev)
2729 return qcom_cc_probe(pdev, &gcc_msm8974_desc); 2744 return qcom_cc_probe(pdev, &gcc_msm8974_desc);
2730} 2745}
2731 2746
2732static int gcc_msm8974_remove(struct platform_device *pdev)
2733{
2734 qcom_cc_remove(pdev);
2735 return 0;
2736}
2737
2738static struct platform_driver gcc_msm8974_driver = { 2747static struct platform_driver gcc_msm8974_driver = {
2739 .probe = gcc_msm8974_probe, 2748 .probe = gcc_msm8974_probe,
2740 .remove = gcc_msm8974_remove,
2741 .driver = { 2749 .driver = {
2742 .name = "gcc-msm8974", 2750 .name = "gcc-msm8974",
2743 .of_match_table = gcc_msm8974_match_table, 2751 .of_match_table = gcc_msm8974_match_table,
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
new file mode 100644
index 000000000000..da9fad8b642b
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.c
@@ -0,0 +1,237 @@
1/*
2 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
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 and
6 * only version 2 as published by the Free Software Foundation.
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/bitops.h>
15#include <linux/delay.h>
16#include <linux/err.h>
17#include <linux/jiffies.h>
18#include <linux/kernel.h>
19#include <linux/pm_domain.h>
20#include <linux/regmap.h>
21#include <linux/reset-controller.h>
22#include <linux/slab.h>
23#include "gdsc.h"
24
25#define PWR_ON_MASK BIT(31)
26#define EN_REST_WAIT_MASK GENMASK_ULL(23, 20)
27#define EN_FEW_WAIT_MASK GENMASK_ULL(19, 16)
28#define CLK_DIS_WAIT_MASK GENMASK_ULL(15, 12)
29#define SW_OVERRIDE_MASK BIT(2)
30#define HW_CONTROL_MASK BIT(1)
31#define SW_COLLAPSE_MASK BIT(0)
32
33/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
34#define EN_REST_WAIT_VAL (0x2 << 20)
35#define EN_FEW_WAIT_VAL (0x8 << 16)
36#define CLK_DIS_WAIT_VAL (0x2 << 12)
37
38#define RETAIN_MEM BIT(14)
39#define RETAIN_PERIPH BIT(13)
40
41#define TIMEOUT_US 100
42
43#define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd)
44
45static int gdsc_is_enabled(struct gdsc *sc)
46{
47 u32 val;
48 int ret;
49
50 ret = regmap_read(sc->regmap, sc->gdscr, &val);
51 if (ret)
52 return ret;
53
54 return !!(val & PWR_ON_MASK);
55}
56
57static int gdsc_toggle_logic(struct gdsc *sc, bool en)
58{
59 int ret;
60 u32 val = en ? 0 : SW_COLLAPSE_MASK;
61 u32 check = en ? PWR_ON_MASK : 0;
62 unsigned long timeout;
63
64 ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
65 if (ret)
66 return ret;
67
68 timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
69 do {
70 ret = regmap_read(sc->regmap, sc->gdscr, &val);
71 if (ret)
72 return ret;
73
74 if ((val & PWR_ON_MASK) == check)
75 return 0;
76 } while (time_before(jiffies, timeout));
77
78 ret = regmap_read(sc->regmap, sc->gdscr, &val);
79 if (ret)
80 return ret;
81
82 if ((val & PWR_ON_MASK) == check)
83 return 0;
84
85 return -ETIMEDOUT;
86}
87
88static inline int gdsc_deassert_reset(struct gdsc *sc)
89{
90 int i;
91
92 for (i = 0; i < sc->reset_count; i++)
93 sc->rcdev->ops->deassert(sc->rcdev, sc->resets[i]);
94 return 0;
95}
96
97static inline int gdsc_assert_reset(struct gdsc *sc)
98{
99 int i;
100
101 for (i = 0; i < sc->reset_count; i++)
102 sc->rcdev->ops->assert(sc->rcdev, sc->resets[i]);
103 return 0;
104}
105
106static inline void gdsc_force_mem_on(struct gdsc *sc)
107{
108 int i;
109 u32 mask = RETAIN_MEM | RETAIN_PERIPH;
110
111 for (i = 0; i < sc->cxc_count; i++)
112 regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
113}
114
115static inline void gdsc_clear_mem_on(struct gdsc *sc)
116{
117 int i;
118 u32 mask = RETAIN_MEM | RETAIN_PERIPH;
119
120 for (i = 0; i < sc->cxc_count; i++)
121 regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0);
122}
123
124static int gdsc_enable(struct generic_pm_domain *domain)
125{
126 struct gdsc *sc = domain_to_gdsc(domain);
127 int ret;
128
129 if (sc->pwrsts == PWRSTS_ON)
130 return gdsc_deassert_reset(sc);
131
132 ret = gdsc_toggle_logic(sc, true);
133 if (ret)
134 return ret;
135
136 if (sc->pwrsts & PWRSTS_OFF)
137 gdsc_force_mem_on(sc);
138
139 /*
140 * If clocks to this power domain were already on, they will take an
141 * additional 4 clock cycles to re-enable after the power domain is
142 * enabled. Delay to account for this. A delay is also needed to ensure
143 * clocks are not enabled within 400ns of enabling power to the
144 * memories.
145 */
146 udelay(1);
147
148 return 0;
149}
150
151static int gdsc_disable(struct generic_pm_domain *domain)
152{
153 struct gdsc *sc = domain_to_gdsc(domain);
154
155 if (sc->pwrsts == PWRSTS_ON)
156 return gdsc_assert_reset(sc);
157
158 if (sc->pwrsts & PWRSTS_OFF)
159 gdsc_clear_mem_on(sc);
160
161 return gdsc_toggle_logic(sc, false);
162}
163
164static int gdsc_init(struct gdsc *sc)
165{
166 u32 mask, val;
167 int on, ret;
168
169 /*
170 * Disable HW trigger: collapse/restore occur based on registers writes.
171 * Disable SW override: Use hardware state-machine for sequencing.
172 * Configure wait time between states.
173 */
174 mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK |
175 EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK;
176 val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
177 ret = regmap_update_bits(sc->regmap, sc->gdscr, mask, val);
178 if (ret)
179 return ret;
180
181 /* Force gdsc ON if only ON state is supported */
182 if (sc->pwrsts == PWRSTS_ON) {
183 ret = gdsc_toggle_logic(sc, true);
184 if (ret)
185 return ret;
186 }
187
188 on = gdsc_is_enabled(sc);
189 if (on < 0)
190 return on;
191
192 if (on || (sc->pwrsts & PWRSTS_RET))
193 gdsc_force_mem_on(sc);
194 else
195 gdsc_clear_mem_on(sc);
196
197 sc->pd.power_off = gdsc_disable;
198 sc->pd.power_on = gdsc_enable;
199 pm_genpd_init(&sc->pd, NULL, !on);
200
201 return 0;
202}
203
204int gdsc_register(struct device *dev, struct gdsc **scs, size_t num,
205 struct reset_controller_dev *rcdev, struct regmap *regmap)
206{
207 int i, ret;
208 struct genpd_onecell_data *data;
209
210 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
211 if (!data)
212 return -ENOMEM;
213
214 data->domains = devm_kcalloc(dev, num, sizeof(*data->domains),
215 GFP_KERNEL);
216 if (!data->domains)
217 return -ENOMEM;
218
219 data->num_domains = num;
220 for (i = 0; i < num; i++) {
221 if (!scs[i])
222 continue;
223 scs[i]->regmap = regmap;
224 scs[i]->rcdev = rcdev;
225 ret = gdsc_init(scs[i]);
226 if (ret)
227 return ret;
228 data->domains[i] = &scs[i]->pd;
229 }
230
231 return of_genpd_add_provider_onecell(dev->of_node, data);
232}
233
234void gdsc_unregister(struct device *dev)
235{
236 of_genpd_del_provider(dev->of_node);
237}
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
new file mode 100644
index 000000000000..5ded26884f08
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.h
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
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 and
6 * only version 2 as published by the Free Software Foundation.
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#ifndef __QCOM_GDSC_H__
15#define __QCOM_GDSC_H__
16
17#include <linux/err.h>
18#include <linux/pm_domain.h>
19
20struct regmap;
21struct reset_controller_dev;
22
23/* Powerdomain allowable state bitfields */
24#define PWRSTS_OFF BIT(0)
25#define PWRSTS_RET BIT(1)
26#define PWRSTS_ON BIT(2)
27#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON)
28#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
29
30/**
31 * struct gdsc - Globally Distributed Switch Controller
32 * @pd: generic power domain
33 * @regmap: regmap for MMIO accesses
34 * @gdscr: gsdc control register
35 * @cxcs: offsets of branch registers to toggle mem/periph bits in
36 * @cxc_count: number of @cxcs
37 * @pwrsts: Possible powerdomain power states
38 * @resets: ids of resets associated with this gdsc
39 * @reset_count: number of @resets
40 * @rcdev: reset controller
41 */
42struct gdsc {
43 struct generic_pm_domain pd;
44 struct regmap *regmap;
45 unsigned int gdscr;
46 unsigned int *cxcs;
47 unsigned int cxc_count;
48 const u8 pwrsts;
49 struct reset_controller_dev *rcdev;
50 unsigned int *resets;
51 unsigned int reset_count;
52};
53
54#ifdef CONFIG_QCOM_GDSC
55int gdsc_register(struct device *, struct gdsc **, size_t n,
56 struct reset_controller_dev *, struct regmap *);
57void gdsc_unregister(struct device *);
58#else
59static inline int gdsc_register(struct device *d, struct gdsc **g, size_t n,
60 struct reset_controller_dev *rcdev,
61 struct regmap *r)
62{
63 return -ENOSYS;
64}
65
66static inline void gdsc_unregister(struct device *d) {};
67#endif /* CONFIG_QCOM_GDSC */
68#endif /* __QCOM_GDSC_H__ */
diff --git a/drivers/clk/qcom/lcc-ipq806x.c b/drivers/clk/qcom/lcc-ipq806x.c
index 93ad42b14366..db3998e5e2d8 100644
--- a/drivers/clk/qcom/lcc-ipq806x.c
+++ b/drivers/clk/qcom/lcc-ipq806x.c
@@ -452,15 +452,8 @@ static int lcc_ipq806x_probe(struct platform_device *pdev)
452 return qcom_cc_really_probe(pdev, &lcc_ipq806x_desc, regmap); 452 return qcom_cc_really_probe(pdev, &lcc_ipq806x_desc, regmap);
453} 453}
454 454
455static int lcc_ipq806x_remove(struct platform_device *pdev)
456{
457 qcom_cc_remove(pdev);
458 return 0;
459}
460
461static struct platform_driver lcc_ipq806x_driver = { 455static struct platform_driver lcc_ipq806x_driver = {
462 .probe = lcc_ipq806x_probe, 456 .probe = lcc_ipq806x_probe,
463 .remove = lcc_ipq806x_remove,
464 .driver = { 457 .driver = {
465 .name = "lcc-ipq806x", 458 .name = "lcc-ipq806x",
466 .of_match_table = lcc_ipq806x_match_table, 459 .of_match_table = lcc_ipq806x_match_table,
diff --git a/drivers/clk/qcom/lcc-msm8960.c b/drivers/clk/qcom/lcc-msm8960.c
index ecb96c284675..4fcf9d1d233c 100644
--- a/drivers/clk/qcom/lcc-msm8960.c
+++ b/drivers/clk/qcom/lcc-msm8960.c
@@ -565,15 +565,8 @@ static int lcc_msm8960_probe(struct platform_device *pdev)
565 return qcom_cc_really_probe(pdev, &lcc_msm8960_desc, regmap); 565 return qcom_cc_really_probe(pdev, &lcc_msm8960_desc, regmap);
566} 566}
567 567
568static int lcc_msm8960_remove(struct platform_device *pdev)
569{
570 qcom_cc_remove(pdev);
571 return 0;
572}
573
574static struct platform_driver lcc_msm8960_driver = { 568static struct platform_driver lcc_msm8960_driver = {
575 .probe = lcc_msm8960_probe, 569 .probe = lcc_msm8960_probe,
576 .remove = lcc_msm8960_remove,
577 .driver = { 570 .driver = {
578 .name = "lcc-msm8960", 571 .name = "lcc-msm8960",
579 .of_match_table = lcc_msm8960_match_table, 572 .of_match_table = lcc_msm8960_match_table,
diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c
index f0ee6bde11af..30777f9f1a43 100644
--- a/drivers/clk/qcom/mmcc-apq8084.c
+++ b/drivers/clk/qcom/mmcc-apq8084.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014, The Linux Foundation. All rights reserved. 2 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
3 * 3 *
4 * This software is licensed under the terms of the GNU General Public 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 5 * License version 2, as published by the Free Software Foundation, and
@@ -26,6 +26,7 @@
26#include "clk-rcg.h" 26#include "clk-rcg.h"
27#include "clk-branch.h" 27#include "clk-branch.h"
28#include "reset.h" 28#include "reset.h"
29#include "gdsc.h"
29 30
30enum { 31enum {
31 P_XO, 32 P_XO,
@@ -571,17 +572,11 @@ static struct clk_rcg2 jpeg2_clk_src = {
571 }, 572 },
572}; 573};
573 574
574static struct freq_tbl pixel_freq_tbl[] = {
575 { .src = P_DSI0PLL },
576 { }
577};
578
579static struct clk_rcg2 pclk0_clk_src = { 575static struct clk_rcg2 pclk0_clk_src = {
580 .cmd_rcgr = 0x2000, 576 .cmd_rcgr = 0x2000,
581 .mnd_width = 8, 577 .mnd_width = 8,
582 .hid_width = 5, 578 .hid_width = 5,
583 .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, 579 .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
584 .freq_tbl = pixel_freq_tbl,
585 .clkr.hw.init = &(struct clk_init_data){ 580 .clkr.hw.init = &(struct clk_init_data){
586 .name = "pclk0_clk_src", 581 .name = "pclk0_clk_src",
587 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 582 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -596,7 +591,6 @@ static struct clk_rcg2 pclk1_clk_src = {
596 .mnd_width = 8, 591 .mnd_width = 8,
597 .hid_width = 5, 592 .hid_width = 5,
598 .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, 593 .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
599 .freq_tbl = pixel_freq_tbl,
600 .clkr.hw.init = &(struct clk_init_data){ 594 .clkr.hw.init = &(struct clk_init_data){
601 .name = "pclk1_clk_src", 595 .name = "pclk1_clk_src",
602 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 596 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -844,21 +838,15 @@ static struct clk_rcg2 cpp_clk_src = {
844 }, 838 },
845}; 839};
846 840
847static struct freq_tbl byte_freq_tbl[] = {
848 { .src = P_DSI0PLL_BYTE },
849 { }
850};
851
852static struct clk_rcg2 byte0_clk_src = { 841static struct clk_rcg2 byte0_clk_src = {
853 .cmd_rcgr = 0x2120, 842 .cmd_rcgr = 0x2120,
854 .hid_width = 5, 843 .hid_width = 5,
855 .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map, 844 .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
856 .freq_tbl = byte_freq_tbl,
857 .clkr.hw.init = &(struct clk_init_data){ 845 .clkr.hw.init = &(struct clk_init_data){
858 .name = "byte0_clk_src", 846 .name = "byte0_clk_src",
859 .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, 847 .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
860 .num_parents = 6, 848 .num_parents = 6,
861 .ops = &clk_byte_ops, 849 .ops = &clk_byte2_ops,
862 .flags = CLK_SET_RATE_PARENT, 850 .flags = CLK_SET_RATE_PARENT,
863 }, 851 },
864}; 852};
@@ -867,12 +855,11 @@ static struct clk_rcg2 byte1_clk_src = {
867 .cmd_rcgr = 0x2140, 855 .cmd_rcgr = 0x2140,
868 .hid_width = 5, 856 .hid_width = 5,
869 .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map, 857 .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
870 .freq_tbl = byte_freq_tbl,
871 .clkr.hw.init = &(struct clk_init_data){ 858 .clkr.hw.init = &(struct clk_init_data){
872 .name = "byte1_clk_src", 859 .name = "byte1_clk_src",
873 .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, 860 .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
874 .num_parents = 6, 861 .num_parents = 6,
875 .ops = &clk_byte_ops, 862 .ops = &clk_byte2_ops,
876 .flags = CLK_SET_RATE_PARENT, 863 .flags = CLK_SET_RATE_PARENT,
877 }, 864 },
878}; 865};
@@ -3077,6 +3064,76 @@ static const struct pll_config mmpll3_config = {
3077 .aux_output_mask = BIT(1), 3064 .aux_output_mask = BIT(1),
3078}; 3065};
3079 3066
3067static struct gdsc venus0_gdsc = {
3068 .gdscr = 0x1024,
3069 .pd = {
3070 .name = "venus0",
3071 },
3072 .pwrsts = PWRSTS_OFF_ON,
3073};
3074
3075static struct gdsc venus0_core0_gdsc = {
3076 .gdscr = 0x1040,
3077 .pd = {
3078 .name = "venus0_core0",
3079 },
3080 .pwrsts = PWRSTS_OFF_ON,
3081};
3082
3083static struct gdsc venus0_core1_gdsc = {
3084 .gdscr = 0x1044,
3085 .pd = {
3086 .name = "venus0_core1",
3087 },
3088 .pwrsts = PWRSTS_OFF_ON,
3089};
3090
3091static struct gdsc mdss_gdsc = {
3092 .gdscr = 0x2304,
3093 .cxcs = (unsigned int []){ 0x231c, 0x2320 },
3094 .cxc_count = 2,
3095 .pd = {
3096 .name = "mdss",
3097 },
3098 .pwrsts = PWRSTS_OFF_ON,
3099};
3100
3101static struct gdsc camss_jpeg_gdsc = {
3102 .gdscr = 0x35a4,
3103 .pd = {
3104 .name = "camss_jpeg",
3105 },
3106 .pwrsts = PWRSTS_OFF_ON,
3107};
3108
3109static struct gdsc camss_vfe_gdsc = {
3110 .gdscr = 0x36a4,
3111 .cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x36b0 },
3112 .cxc_count = 3,
3113 .pd = {
3114 .name = "camss_vfe",
3115 },
3116 .pwrsts = PWRSTS_OFF_ON,
3117};
3118
3119static struct gdsc oxili_gdsc = {
3120 .gdscr = 0x4024,
3121 .cxcs = (unsigned int []){ 0x4028 },
3122 .cxc_count = 1,
3123 .pd = {
3124 .name = "oxili",
3125 },
3126 .pwrsts = PWRSTS_OFF_ON,
3127};
3128
3129static struct gdsc oxilicx_gdsc = {
3130 .gdscr = 0x4034,
3131 .pd = {
3132 .name = "oxilicx",
3133 },
3134 .pwrsts = PWRSTS_OFF_ON,
3135};
3136
3080static struct clk_regmap *mmcc_apq8084_clocks[] = { 3137static struct clk_regmap *mmcc_apq8084_clocks[] = {
3081 [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr, 3138 [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr,
3082 [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr, 3139 [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr,
@@ -3294,6 +3351,17 @@ static const struct qcom_reset_map mmcc_apq8084_resets[] = {
3294 [MMSSNOCAXI_RESET] = { 0x5060 }, 3351 [MMSSNOCAXI_RESET] = { 0x5060 },
3295}; 3352};
3296 3353
3354static struct gdsc *mmcc_apq8084_gdscs[] = {
3355 [VENUS0_GDSC] = &venus0_gdsc,
3356 [VENUS0_CORE0_GDSC] = &venus0_core0_gdsc,
3357 [VENUS0_CORE1_GDSC] = &venus0_core1_gdsc,
3358 [MDSS_GDSC] = &mdss_gdsc,
3359 [CAMSS_JPEG_GDSC] = &camss_jpeg_gdsc,
3360 [CAMSS_VFE_GDSC] = &camss_vfe_gdsc,
3361 [OXILI_GDSC] = &oxili_gdsc,
3362 [OXILICX_GDSC] = &oxilicx_gdsc,
3363};
3364
3297static const struct regmap_config mmcc_apq8084_regmap_config = { 3365static const struct regmap_config mmcc_apq8084_regmap_config = {
3298 .reg_bits = 32, 3366 .reg_bits = 32,
3299 .reg_stride = 4, 3367 .reg_stride = 4,
@@ -3308,6 +3376,8 @@ static const struct qcom_cc_desc mmcc_apq8084_desc = {
3308 .num_clks = ARRAY_SIZE(mmcc_apq8084_clocks), 3376 .num_clks = ARRAY_SIZE(mmcc_apq8084_clocks),
3309 .resets = mmcc_apq8084_resets, 3377 .resets = mmcc_apq8084_resets,
3310 .num_resets = ARRAY_SIZE(mmcc_apq8084_resets), 3378 .num_resets = ARRAY_SIZE(mmcc_apq8084_resets),
3379 .gdscs = mmcc_apq8084_gdscs,
3380 .num_gdscs = ARRAY_SIZE(mmcc_apq8084_gdscs),
3311}; 3381};
3312 3382
3313static const struct of_device_id mmcc_apq8084_match_table[] = { 3383static const struct of_device_id mmcc_apq8084_match_table[] = {
@@ -3332,15 +3402,8 @@ static int mmcc_apq8084_probe(struct platform_device *pdev)
3332 return 0; 3402 return 0;
3333} 3403}
3334 3404
3335static int mmcc_apq8084_remove(struct platform_device *pdev)
3336{
3337 qcom_cc_remove(pdev);
3338 return 0;
3339}
3340
3341static struct platform_driver mmcc_apq8084_driver = { 3405static struct platform_driver mmcc_apq8084_driver = {
3342 .probe = mmcc_apq8084_probe, 3406 .probe = mmcc_apq8084_probe,
3343 .remove = mmcc_apq8084_remove,
3344 .driver = { 3407 .driver = {
3345 .name = "mmcc-apq8084", 3408 .name = "mmcc-apq8084",
3346 .of_match_table = mmcc_apq8084_match_table, 3409 .of_match_table = mmcc_apq8084_match_table,
diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c
index bad02aebf959..00e36192a1de 100644
--- a/drivers/clk/qcom/mmcc-msm8960.c
+++ b/drivers/clk/qcom/mmcc-msm8960.c
@@ -41,6 +41,10 @@ enum {
41 P_PLL3, 41 P_PLL3,
42 P_PLL15, 42 P_PLL15,
43 P_HDMI_PLL, 43 P_HDMI_PLL,
44 P_DSI1_PLL_DSICLK,
45 P_DSI2_PLL_DSICLK,
46 P_DSI1_PLL_BYTECLK,
47 P_DSI2_PLL_BYTECLK,
44}; 48};
45 49
46#define F_MN(f, s, _m, _n) { .freq = f, .src = s, .m = _m, .n = _n } 50#define F_MN(f, s, _m, _n) { .freq = f, .src = s, .m = _m, .n = _n }
@@ -85,6 +89,30 @@ static const char * const mmcc_pxo_pll8_pll2_pll3[] = {
85 "pll3", 89 "pll3",
86}; 90};
87 91
92static const struct parent_map mmcc_pxo_dsi2_dsi1_map[] = {
93 { P_PXO, 0 },
94 { P_DSI2_PLL_DSICLK, 1 },
95 { P_DSI1_PLL_DSICLK, 3 },
96};
97
98static const char * const mmcc_pxo_dsi2_dsi1[] = {
99 "pxo",
100 "dsi2pll",
101 "dsi1pll",
102};
103
104static const struct parent_map mmcc_pxo_dsi1_dsi2_byte_map[] = {
105 { P_PXO, 0 },
106 { P_DSI1_PLL_BYTECLK, 1 },
107 { P_DSI2_PLL_BYTECLK, 2 },
108};
109
110static const char * const mmcc_pxo_dsi1_dsi2_byte[] = {
111 "pxo",
112 "dsi1pllbyte",
113 "dsi2pllbyte",
114};
115
88static struct clk_pll pll2 = { 116static struct clk_pll pll2 = {
89 .l_reg = 0x320, 117 .l_reg = 0x320,
90 .m_reg = 0x324, 118 .m_reg = 0x324,
@@ -2042,6 +2070,350 @@ static struct clk_branch dsi2_s_ahb_clk = {
2042 }, 2070 },
2043}; 2071};
2044 2072
2073static struct clk_rcg dsi1_src = {
2074 .ns_reg = 0x0054,
2075 .md_reg = 0x0050,
2076 .mn = {
2077 .mnctr_en_bit = 5,
2078 .mnctr_reset_bit = 7,
2079 .mnctr_mode_shift = 6,
2080 .n_val_shift = 24,
2081 .m_val_shift = 8,
2082 .width = 8,
2083 },
2084 .p = {
2085 .pre_div_shift = 14,
2086 .pre_div_width = 2,
2087 },
2088 .s = {
2089 .src_sel_shift = 0,
2090 .parent_map = mmcc_pxo_dsi2_dsi1_map,
2091 },
2092 .clkr = {
2093 .enable_reg = 0x004c,
2094 .enable_mask = BIT(2),
2095 .hw.init = &(struct clk_init_data){
2096 .name = "dsi1_src",
2097 .parent_names = mmcc_pxo_dsi2_dsi1,
2098 .num_parents = 3,
2099 .ops = &clk_rcg_bypass2_ops,
2100 .flags = CLK_SET_RATE_PARENT,
2101 },
2102 },
2103};
2104
2105static struct clk_branch dsi1_clk = {
2106 .halt_reg = 0x01d0,
2107 .halt_bit = 2,
2108 .clkr = {
2109 .enable_reg = 0x004c,
2110 .enable_mask = BIT(0),
2111 .hw.init = &(struct clk_init_data){
2112 .name = "dsi1_clk",
2113 .parent_names = (const char *[]){ "dsi1_src" },
2114 .num_parents = 1,
2115 .ops = &clk_branch_ops,
2116 .flags = CLK_SET_RATE_PARENT,
2117 },
2118 },
2119};
2120
2121static struct clk_rcg dsi2_src = {
2122 .ns_reg = 0x012c,
2123 .md_reg = 0x00a8,
2124 .mn = {
2125 .mnctr_en_bit = 5,
2126 .mnctr_reset_bit = 7,
2127 .mnctr_mode_shift = 6,
2128 .n_val_shift = 24,
2129 .m_val_shift = 8,
2130 .width = 8,
2131 },
2132 .p = {
2133 .pre_div_shift = 14,
2134 .pre_div_width = 2,
2135 },
2136 .s = {
2137 .src_sel_shift = 0,
2138 .parent_map = mmcc_pxo_dsi2_dsi1_map,
2139 },
2140 .clkr = {
2141 .enable_reg = 0x003c,
2142 .enable_mask = BIT(2),
2143 .hw.init = &(struct clk_init_data){
2144 .name = "dsi2_src",
2145 .parent_names = mmcc_pxo_dsi2_dsi1,
2146 .num_parents = 3,
2147 .ops = &clk_rcg_bypass2_ops,
2148 .flags = CLK_SET_RATE_PARENT,
2149 },
2150 },
2151};
2152
2153static struct clk_branch dsi2_clk = {
2154 .halt_reg = 0x01d0,
2155 .halt_bit = 20,
2156 .clkr = {
2157 .enable_reg = 0x003c,
2158 .enable_mask = BIT(0),
2159 .hw.init = &(struct clk_init_data){
2160 .name = "dsi2_clk",
2161 .parent_names = (const char *[]){ "dsi2_src" },
2162 .num_parents = 1,
2163 .ops = &clk_branch_ops,
2164 .flags = CLK_SET_RATE_PARENT,
2165 },
2166 },
2167};
2168
2169static struct clk_rcg dsi1_byte_src = {
2170 .ns_reg = 0x00b0,
2171 .p = {
2172 .pre_div_shift = 12,
2173 .pre_div_width = 4,
2174 },
2175 .s = {
2176 .src_sel_shift = 0,
2177 .parent_map = mmcc_pxo_dsi1_dsi2_byte_map,
2178 },
2179 .clkr = {
2180 .enable_reg = 0x0090,
2181 .enable_mask = BIT(2),
2182 .hw.init = &(struct clk_init_data){
2183 .name = "dsi1_byte_src",
2184 .parent_names = mmcc_pxo_dsi1_dsi2_byte,
2185 .num_parents = 3,
2186 .ops = &clk_rcg_bypass2_ops,
2187 .flags = CLK_SET_RATE_PARENT,
2188 },
2189 },
2190};
2191
2192static struct clk_branch dsi1_byte_clk = {
2193 .halt_reg = 0x01cc,
2194 .halt_bit = 21,
2195 .clkr = {
2196 .enable_reg = 0x0090,
2197 .enable_mask = BIT(0),
2198 .hw.init = &(struct clk_init_data){
2199 .name = "dsi1_byte_clk",
2200 .parent_names = (const char *[]){ "dsi1_byte_src" },
2201 .num_parents = 1,
2202 .ops = &clk_branch_ops,
2203 .flags = CLK_SET_RATE_PARENT,
2204 },
2205 },
2206};
2207
2208static struct clk_rcg dsi2_byte_src = {
2209 .ns_reg = 0x012c,
2210 .p = {
2211 .pre_div_shift = 12,
2212 .pre_div_width = 4,
2213 },
2214 .s = {
2215 .src_sel_shift = 0,
2216 .parent_map = mmcc_pxo_dsi1_dsi2_byte_map,
2217 },
2218 .clkr = {
2219 .enable_reg = 0x0130,
2220 .enable_mask = BIT(2),
2221 .hw.init = &(struct clk_init_data){
2222 .name = "dsi2_byte_src",
2223 .parent_names = mmcc_pxo_dsi1_dsi2_byte,
2224 .num_parents = 3,
2225 .ops = &clk_rcg_bypass2_ops,
2226 .flags = CLK_SET_RATE_PARENT,
2227 },
2228 },
2229};
2230
2231static struct clk_branch dsi2_byte_clk = {
2232 .halt_reg = 0x01cc,
2233 .halt_bit = 20,
2234 .clkr = {
2235 .enable_reg = 0x00b4,
2236 .enable_mask = BIT(0),
2237 .hw.init = &(struct clk_init_data){
2238 .name = "dsi2_byte_clk",
2239 .parent_names = (const char *[]){ "dsi2_byte_src" },
2240 .num_parents = 1,
2241 .ops = &clk_branch_ops,
2242 .flags = CLK_SET_RATE_PARENT,
2243 },
2244 },
2245};
2246
2247static struct clk_rcg dsi1_esc_src = {
2248 .ns_reg = 0x0011c,
2249 .p = {
2250 .pre_div_shift = 12,
2251 .pre_div_width = 4,
2252 },
2253 .s = {
2254 .src_sel_shift = 0,
2255 .parent_map = mmcc_pxo_dsi1_dsi2_byte_map,
2256 },
2257 .clkr = {
2258 .enable_reg = 0x00cc,
2259 .enable_mask = BIT(2),
2260 .hw.init = &(struct clk_init_data){
2261 .name = "dsi1_esc_src",
2262 .parent_names = mmcc_pxo_dsi1_dsi2_byte,
2263 .num_parents = 3,
2264 .ops = &clk_rcg_esc_ops,
2265 },
2266 },
2267};
2268
2269static struct clk_branch dsi1_esc_clk = {
2270 .halt_reg = 0x01e8,
2271 .halt_bit = 1,
2272 .clkr = {
2273 .enable_reg = 0x00cc,
2274 .enable_mask = BIT(0),
2275 .hw.init = &(struct clk_init_data){
2276 .name = "dsi1_esc_clk",
2277 .parent_names = (const char *[]){ "dsi1_esc_src" },
2278 .num_parents = 1,
2279 .ops = &clk_branch_ops,
2280 .flags = CLK_SET_RATE_PARENT,
2281 },
2282 },
2283};
2284
2285static struct clk_rcg dsi2_esc_src = {
2286 .ns_reg = 0x0150,
2287 .p = {
2288 .pre_div_shift = 12,
2289 .pre_div_width = 4,
2290 },
2291 .s = {
2292 .src_sel_shift = 0,
2293 .parent_map = mmcc_pxo_dsi1_dsi2_byte_map,
2294 },
2295 .clkr = {
2296 .enable_reg = 0x013c,
2297 .enable_mask = BIT(2),
2298 .hw.init = &(struct clk_init_data){
2299 .name = "dsi2_esc_src",
2300 .parent_names = mmcc_pxo_dsi1_dsi2_byte,
2301 .num_parents = 3,
2302 .ops = &clk_rcg_esc_ops,
2303 },
2304 },
2305};
2306
2307static struct clk_branch dsi2_esc_clk = {
2308 .halt_reg = 0x01e8,
2309 .halt_bit = 3,
2310 .clkr = {
2311 .enable_reg = 0x013c,
2312 .enable_mask = BIT(0),
2313 .hw.init = &(struct clk_init_data){
2314 .name = "dsi2_esc_clk",
2315 .parent_names = (const char *[]){ "dsi2_esc_src" },
2316 .num_parents = 1,
2317 .ops = &clk_branch_ops,
2318 .flags = CLK_SET_RATE_PARENT,
2319 },
2320 },
2321};
2322
2323static struct clk_rcg dsi1_pixel_src = {
2324 .ns_reg = 0x0138,
2325 .md_reg = 0x0134,
2326 .mn = {
2327 .mnctr_en_bit = 5,
2328 .mnctr_reset_bit = 7,
2329 .mnctr_mode_shift = 6,
2330 .n_val_shift = 16,
2331 .m_val_shift = 8,
2332 .width = 8,
2333 },
2334 .p = {
2335 .pre_div_shift = 12,
2336 .pre_div_width = 4,
2337 },
2338 .s = {
2339 .src_sel_shift = 0,
2340 .parent_map = mmcc_pxo_dsi2_dsi1_map,
2341 },
2342 .clkr = {
2343 .enable_reg = 0x0130,
2344 .enable_mask = BIT(2),
2345 .hw.init = &(struct clk_init_data){
2346 .name = "dsi1_pixel_src",
2347 .parent_names = mmcc_pxo_dsi2_dsi1,
2348 .num_parents = 3,
2349 .ops = &clk_rcg_pixel_ops,
2350 },
2351 },
2352};
2353
2354static struct clk_branch dsi1_pixel_clk = {
2355 .halt_reg = 0x01d0,
2356 .halt_bit = 6,
2357 .clkr = {
2358 .enable_reg = 0x0130,
2359 .enable_mask = BIT(0),
2360 .hw.init = &(struct clk_init_data){
2361 .name = "mdp_pclk1_clk",
2362 .parent_names = (const char *[]){ "dsi1_pixel_src" },
2363 .num_parents = 1,
2364 .ops = &clk_branch_ops,
2365 .flags = CLK_SET_RATE_PARENT,
2366 },
2367 },
2368};
2369
2370static struct clk_rcg dsi2_pixel_src = {
2371 .ns_reg = 0x00e4,
2372 .md_reg = 0x00b8,
2373 .mn = {
2374 .mnctr_en_bit = 5,
2375 .mnctr_reset_bit = 7,
2376 .mnctr_mode_shift = 6,
2377 .n_val_shift = 16,
2378 .m_val_shift = 8,
2379 .width = 8,
2380 },
2381 .p = {
2382 .pre_div_shift = 12,
2383 .pre_div_width = 4,
2384 },
2385 .s = {
2386 .src_sel_shift = 0,
2387 .parent_map = mmcc_pxo_dsi2_dsi1_map,
2388 },
2389 .clkr = {
2390 .enable_reg = 0x0094,
2391 .enable_mask = BIT(2),
2392 .hw.init = &(struct clk_init_data){
2393 .name = "dsi2_pixel_src",
2394 .parent_names = mmcc_pxo_dsi2_dsi1,
2395 .num_parents = 3,
2396 .ops = &clk_rcg_pixel_ops,
2397 },
2398 },
2399};
2400
2401static struct clk_branch dsi2_pixel_clk = {
2402 .halt_reg = 0x01d0,
2403 .halt_bit = 19,
2404 .clkr = {
2405 .enable_reg = 0x0094,
2406 .enable_mask = BIT(0),
2407 .hw.init = &(struct clk_init_data){
2408 .name = "mdp_pclk2_clk",
2409 .parent_names = (const char *[]){ "dsi2_pixel_src" },
2410 .num_parents = 1,
2411 .ops = &clk_branch_ops,
2412 .flags = CLK_SET_RATE_PARENT,
2413 },
2414 },
2415};
2416
2045static struct clk_branch gfx2d0_ahb_clk = { 2417static struct clk_branch gfx2d0_ahb_clk = {
2046 .hwcg_reg = 0x0038, 2418 .hwcg_reg = 0x0038,
2047 .hwcg_bit = 28, 2419 .hwcg_bit = 28,
@@ -2325,6 +2697,8 @@ static struct clk_regmap *mmcc_msm8960_clks[] = {
2325 [CSI2_SRC] = &csi2_src.clkr, 2697 [CSI2_SRC] = &csi2_src.clkr,
2326 [CSI2_CLK] = &csi2_clk.clkr, 2698 [CSI2_CLK] = &csi2_clk.clkr,
2327 [CSI2_PHY_CLK] = &csi2_phy_clk.clkr, 2699 [CSI2_PHY_CLK] = &csi2_phy_clk.clkr,
2700 [DSI_SRC] = &dsi1_src.clkr,
2701 [DSI_CLK] = &dsi1_clk.clkr,
2328 [CSI_PIX_CLK] = &csi_pix_clk.clkr, 2702 [CSI_PIX_CLK] = &csi_pix_clk.clkr,
2329 [CSI_RDI_CLK] = &csi_rdi_clk.clkr, 2703 [CSI_RDI_CLK] = &csi_rdi_clk.clkr,
2330 [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr, 2704 [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr,
@@ -2345,6 +2719,18 @@ static struct clk_regmap *mmcc_msm8960_clks[] = {
2345 [MDP_SRC] = &mdp_src.clkr, 2719 [MDP_SRC] = &mdp_src.clkr,
2346 [MDP_CLK] = &mdp_clk.clkr, 2720 [MDP_CLK] = &mdp_clk.clkr,
2347 [MDP_LUT_CLK] = &mdp_lut_clk.clkr, 2721 [MDP_LUT_CLK] = &mdp_lut_clk.clkr,
2722 [DSI2_PIXEL_SRC] = &dsi2_pixel_src.clkr,
2723 [DSI2_PIXEL_CLK] = &dsi2_pixel_clk.clkr,
2724 [DSI2_SRC] = &dsi2_src.clkr,
2725 [DSI2_CLK] = &dsi2_clk.clkr,
2726 [DSI1_BYTE_SRC] = &dsi1_byte_src.clkr,
2727 [DSI1_BYTE_CLK] = &dsi1_byte_clk.clkr,
2728 [DSI2_BYTE_SRC] = &dsi2_byte_src.clkr,
2729 [DSI2_BYTE_CLK] = &dsi2_byte_clk.clkr,
2730 [DSI1_ESC_SRC] = &dsi1_esc_src.clkr,
2731 [DSI1_ESC_CLK] = &dsi1_esc_clk.clkr,
2732 [DSI2_ESC_SRC] = &dsi2_esc_src.clkr,
2733 [DSI2_ESC_CLK] = &dsi2_esc_clk.clkr,
2348 [ROT_SRC] = &rot_src.clkr, 2734 [ROT_SRC] = &rot_src.clkr,
2349 [ROT_CLK] = &rot_clk.clkr, 2735 [ROT_CLK] = &rot_clk.clkr,
2350 [TV_ENC_CLK] = &tv_enc_clk.clkr, 2736 [TV_ENC_CLK] = &tv_enc_clk.clkr,
@@ -2359,6 +2745,8 @@ static struct clk_regmap *mmcc_msm8960_clks[] = {
2359 [VFE_CSI_CLK] = &vfe_csi_clk.clkr, 2745 [VFE_CSI_CLK] = &vfe_csi_clk.clkr,
2360 [VPE_SRC] = &vpe_src.clkr, 2746 [VPE_SRC] = &vpe_src.clkr,
2361 [VPE_CLK] = &vpe_clk.clkr, 2747 [VPE_CLK] = &vpe_clk.clkr,
2748 [DSI_PIXEL_SRC] = &dsi1_pixel_src.clkr,
2749 [DSI_PIXEL_CLK] = &dsi1_pixel_clk.clkr,
2362 [CAMCLK0_SRC] = &camclk0_src.clkr, 2750 [CAMCLK0_SRC] = &camclk0_src.clkr,
2363 [CAMCLK0_CLK] = &camclk0_clk.clkr, 2751 [CAMCLK0_CLK] = &camclk0_clk.clkr,
2364 [CAMCLK1_SRC] = &camclk1_src.clkr, 2752 [CAMCLK1_SRC] = &camclk1_src.clkr,
@@ -2490,6 +2878,8 @@ static struct clk_regmap *mmcc_apq8064_clks[] = {
2490 [CSI2_SRC] = &csi2_src.clkr, 2878 [CSI2_SRC] = &csi2_src.clkr,
2491 [CSI2_CLK] = &csi2_clk.clkr, 2879 [CSI2_CLK] = &csi2_clk.clkr,
2492 [CSI2_PHY_CLK] = &csi2_phy_clk.clkr, 2880 [CSI2_PHY_CLK] = &csi2_phy_clk.clkr,
2881 [DSI_SRC] = &dsi1_src.clkr,
2882 [DSI_CLK] = &dsi1_clk.clkr,
2493 [CSI_PIX_CLK] = &csi_pix_clk.clkr, 2883 [CSI_PIX_CLK] = &csi_pix_clk.clkr,
2494 [CSI_RDI_CLK] = &csi_rdi_clk.clkr, 2884 [CSI_RDI_CLK] = &csi_rdi_clk.clkr,
2495 [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr, 2885 [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr,
@@ -2506,6 +2896,18 @@ static struct clk_regmap *mmcc_apq8064_clks[] = {
2506 [MDP_SRC] = &mdp_src.clkr, 2896 [MDP_SRC] = &mdp_src.clkr,
2507 [MDP_CLK] = &mdp_clk.clkr, 2897 [MDP_CLK] = &mdp_clk.clkr,
2508 [MDP_LUT_CLK] = &mdp_lut_clk.clkr, 2898 [MDP_LUT_CLK] = &mdp_lut_clk.clkr,
2899 [DSI2_PIXEL_SRC] = &dsi2_pixel_src.clkr,
2900 [DSI2_PIXEL_CLK] = &dsi2_pixel_clk.clkr,
2901 [DSI2_SRC] = &dsi2_src.clkr,
2902 [DSI2_CLK] = &dsi2_clk.clkr,
2903 [DSI1_BYTE_SRC] = &dsi1_byte_src.clkr,
2904 [DSI1_BYTE_CLK] = &dsi1_byte_clk.clkr,
2905 [DSI2_BYTE_SRC] = &dsi2_byte_src.clkr,
2906 [DSI2_BYTE_CLK] = &dsi2_byte_clk.clkr,
2907 [DSI1_ESC_SRC] = &dsi1_esc_src.clkr,
2908 [DSI1_ESC_CLK] = &dsi1_esc_clk.clkr,
2909 [DSI2_ESC_SRC] = &dsi2_esc_src.clkr,
2910 [DSI2_ESC_CLK] = &dsi2_esc_clk.clkr,
2509 [ROT_SRC] = &rot_src.clkr, 2911 [ROT_SRC] = &rot_src.clkr,
2510 [ROT_CLK] = &rot_clk.clkr, 2912 [ROT_CLK] = &rot_clk.clkr,
2511 [TV_DAC_CLK] = &tv_dac_clk.clkr, 2913 [TV_DAC_CLK] = &tv_dac_clk.clkr,
@@ -2519,6 +2921,8 @@ static struct clk_regmap *mmcc_apq8064_clks[] = {
2519 [VFE_CSI_CLK] = &vfe_csi_clk.clkr, 2921 [VFE_CSI_CLK] = &vfe_csi_clk.clkr,
2520 [VPE_SRC] = &vpe_src.clkr, 2922 [VPE_SRC] = &vpe_src.clkr,
2521 [VPE_CLK] = &vpe_clk.clkr, 2923 [VPE_CLK] = &vpe_clk.clkr,
2924 [DSI_PIXEL_SRC] = &dsi1_pixel_src.clkr,
2925 [DSI_PIXEL_CLK] = &dsi1_pixel_clk.clkr,
2522 [CAMCLK0_SRC] = &camclk0_src.clkr, 2926 [CAMCLK0_SRC] = &camclk0_src.clkr,
2523 [CAMCLK0_CLK] = &camclk0_clk.clkr, 2927 [CAMCLK0_CLK] = &camclk0_clk.clkr,
2524 [CAMCLK1_SRC] = &camclk1_src.clkr, 2928 [CAMCLK1_SRC] = &camclk1_src.clkr,
@@ -2686,15 +3090,8 @@ static int mmcc_msm8960_probe(struct platform_device *pdev)
2686 return qcom_cc_really_probe(pdev, match->data, regmap); 3090 return qcom_cc_really_probe(pdev, match->data, regmap);
2687} 3091}
2688 3092
2689static int mmcc_msm8960_remove(struct platform_device *pdev)
2690{
2691 qcom_cc_remove(pdev);
2692 return 0;
2693}
2694
2695static struct platform_driver mmcc_msm8960_driver = { 3093static struct platform_driver mmcc_msm8960_driver = {
2696 .probe = mmcc_msm8960_probe, 3094 .probe = mmcc_msm8960_probe,
2697 .remove = mmcc_msm8960_remove,
2698 .driver = { 3095 .driver = {
2699 .name = "mmcc-msm8960", 3096 .name = "mmcc-msm8960",
2700 .of_match_table = mmcc_msm8960_match_table, 3097 .of_match_table = mmcc_msm8960_match_table,
diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c
index 0987bf443e1f..9d790bcadf25 100644
--- a/drivers/clk/qcom/mmcc-msm8974.c
+++ b/drivers/clk/qcom/mmcc-msm8974.c
@@ -31,6 +31,7 @@
31#include "clk-rcg.h" 31#include "clk-rcg.h"
32#include "clk-branch.h" 32#include "clk-branch.h"
33#include "reset.h" 33#include "reset.h"
34#include "gdsc.h"
34 35
35enum { 36enum {
36 P_XO, 37 P_XO,
@@ -522,17 +523,11 @@ static struct clk_rcg2 jpeg2_clk_src = {
522 }, 523 },
523}; 524};
524 525
525static struct freq_tbl pixel_freq_tbl[] = {
526 { .src = P_DSI0PLL },
527 { }
528};
529
530static struct clk_rcg2 pclk0_clk_src = { 526static struct clk_rcg2 pclk0_clk_src = {
531 .cmd_rcgr = 0x2000, 527 .cmd_rcgr = 0x2000,
532 .mnd_width = 8, 528 .mnd_width = 8,
533 .hid_width = 5, 529 .hid_width = 5,
534 .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, 530 .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
535 .freq_tbl = pixel_freq_tbl,
536 .clkr.hw.init = &(struct clk_init_data){ 531 .clkr.hw.init = &(struct clk_init_data){
537 .name = "pclk0_clk_src", 532 .name = "pclk0_clk_src",
538 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 533 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -547,7 +542,6 @@ static struct clk_rcg2 pclk1_clk_src = {
547 .mnd_width = 8, 542 .mnd_width = 8,
548 .hid_width = 5, 543 .hid_width = 5,
549 .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, 544 .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
550 .freq_tbl = pixel_freq_tbl,
551 .clkr.hw.init = &(struct clk_init_data){ 545 .clkr.hw.init = &(struct clk_init_data){
552 .name = "pclk1_clk_src", 546 .name = "pclk1_clk_src",
553 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, 547 .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -785,7 +779,7 @@ static struct clk_rcg2 byte0_clk_src = {
785 .name = "byte0_clk_src", 779 .name = "byte0_clk_src",
786 .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, 780 .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
787 .num_parents = 6, 781 .num_parents = 6,
788 .ops = &clk_byte_ops, 782 .ops = &clk_byte2_ops,
789 .flags = CLK_SET_RATE_PARENT, 783 .flags = CLK_SET_RATE_PARENT,
790 }, 784 },
791}; 785};
@@ -799,7 +793,7 @@ static struct clk_rcg2 byte1_clk_src = {
799 .name = "byte1_clk_src", 793 .name = "byte1_clk_src",
800 .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, 794 .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
801 .num_parents = 6, 795 .num_parents = 6,
802 .ops = &clk_byte_ops, 796 .ops = &clk_byte2_ops,
803 .flags = CLK_SET_RATE_PARENT, 797 .flags = CLK_SET_RATE_PARENT,
804 }, 798 },
805}; 799};
@@ -2349,6 +2343,66 @@ static struct pll_config mmpll3_config = {
2349 .aux_output_mask = BIT(1), 2343 .aux_output_mask = BIT(1),
2350}; 2344};
2351 2345
2346static struct gdsc venus0_gdsc = {
2347 .gdscr = 0x1024,
2348 .cxcs = (unsigned int []){ 0x1028 },
2349 .cxc_count = 1,
2350 .resets = (unsigned int []){ VENUS0_RESET },
2351 .reset_count = 1,
2352 .pd = {
2353 .name = "venus0",
2354 },
2355 .pwrsts = PWRSTS_ON,
2356};
2357
2358static struct gdsc mdss_gdsc = {
2359 .gdscr = 0x2304,
2360 .cxcs = (unsigned int []){ 0x231c, 0x2320 },
2361 .cxc_count = 2,
2362 .pd = {
2363 .name = "mdss",
2364 },
2365 .pwrsts = PWRSTS_RET_ON,
2366};
2367
2368static struct gdsc camss_jpeg_gdsc = {
2369 .gdscr = 0x35a4,
2370 .cxcs = (unsigned int []){ 0x35a8, 0x35ac, 0x35b0 },
2371 .cxc_count = 3,
2372 .pd = {
2373 .name = "camss_jpeg",
2374 },
2375 .pwrsts = PWRSTS_OFF_ON,
2376};
2377
2378static struct gdsc camss_vfe_gdsc = {
2379 .gdscr = 0x36a4,
2380 .cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x3704, 0x3714, 0x36b0 },
2381 .cxc_count = 5,
2382 .pd = {
2383 .name = "camss_vfe",
2384 },
2385 .pwrsts = PWRSTS_OFF_ON,
2386};
2387
2388static struct gdsc oxili_gdsc = {
2389 .gdscr = 0x4024,
2390 .cxcs = (unsigned int []){ 0x4028 },
2391 .cxc_count = 1,
2392 .pd = {
2393 .name = "oxili",
2394 },
2395 .pwrsts = PWRSTS_OFF_ON,
2396};
2397
2398static struct gdsc oxilicx_gdsc = {
2399 .gdscr = 0x4034,
2400 .pd = {
2401 .name = "oxilicx",
2402 },
2403 .pwrsts = PWRSTS_OFF_ON,
2404};
2405
2352static struct clk_regmap *mmcc_msm8974_clocks[] = { 2406static struct clk_regmap *mmcc_msm8974_clocks[] = {
2353 [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr, 2407 [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr,
2354 [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr, 2408 [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr,
@@ -2525,6 +2579,15 @@ static const struct qcom_reset_map mmcc_msm8974_resets[] = {
2525 [OCMEMNOC_RESET] = { 0x50b0 }, 2579 [OCMEMNOC_RESET] = { 0x50b0 },
2526}; 2580};
2527 2581
2582static struct gdsc *mmcc_msm8974_gdscs[] = {
2583 [VENUS0_GDSC] = &venus0_gdsc,
2584 [MDSS_GDSC] = &mdss_gdsc,
2585 [CAMSS_JPEG_GDSC] = &camss_jpeg_gdsc,
2586 [CAMSS_VFE_GDSC] = &camss_vfe_gdsc,
2587 [OXILI_GDSC] = &oxili_gdsc,
2588 [OXILICX_GDSC] = &oxilicx_gdsc,
2589};
2590
2528static const struct regmap_config mmcc_msm8974_regmap_config = { 2591static const struct regmap_config mmcc_msm8974_regmap_config = {
2529 .reg_bits = 32, 2592 .reg_bits = 32,
2530 .reg_stride = 4, 2593 .reg_stride = 4,
@@ -2539,6 +2602,8 @@ static const struct qcom_cc_desc mmcc_msm8974_desc = {
2539 .num_clks = ARRAY_SIZE(mmcc_msm8974_clocks), 2602 .num_clks = ARRAY_SIZE(mmcc_msm8974_clocks),
2540 .resets = mmcc_msm8974_resets, 2603 .resets = mmcc_msm8974_resets,
2541 .num_resets = ARRAY_SIZE(mmcc_msm8974_resets), 2604 .num_resets = ARRAY_SIZE(mmcc_msm8974_resets),
2605 .gdscs = mmcc_msm8974_gdscs,
2606 .num_gdscs = ARRAY_SIZE(mmcc_msm8974_gdscs),
2542}; 2607};
2543 2608
2544static const struct of_device_id mmcc_msm8974_match_table[] = { 2609static const struct of_device_id mmcc_msm8974_match_table[] = {
@@ -2550,6 +2615,7 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table);
2550static int mmcc_msm8974_probe(struct platform_device *pdev) 2615static int mmcc_msm8974_probe(struct platform_device *pdev)
2551{ 2616{
2552 struct regmap *regmap; 2617 struct regmap *regmap;
2618 int ret;
2553 2619
2554 regmap = qcom_cc_map(pdev, &mmcc_msm8974_desc); 2620 regmap = qcom_cc_map(pdev, &mmcc_msm8974_desc);
2555 if (IS_ERR(regmap)) 2621 if (IS_ERR(regmap))
@@ -2558,12 +2624,16 @@ static int mmcc_msm8974_probe(struct platform_device *pdev)
2558 clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true); 2624 clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true);
2559 clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false); 2625 clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false);
2560 2626
2561 return qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap); 2627 ret = qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap);
2628 if (ret)
2629 return ret;
2630
2631 return pm_genpd_add_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd);
2562} 2632}
2563 2633
2564static int mmcc_msm8974_remove(struct platform_device *pdev) 2634static int mmcc_msm8974_remove(struct platform_device *pdev)
2565{ 2635{
2566 qcom_cc_remove(pdev); 2636 pm_genpd_remove_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd);
2567 return 0; 2637 return 0;
2568} 2638}
2569 2639
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index bc24e5a002e7..2685644826a0 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -41,6 +41,8 @@ static unsigned long rockchip_mmc_recalc(struct clk_hw *hw,
41#define ROCKCHIP_MMC_DEGREE_MASK 0x3 41#define ROCKCHIP_MMC_DEGREE_MASK 0x3
42#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 42#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
43#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 43#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
44#define ROCKCHIP_MMC_INIT_STATE_RESET 0x1
45#define ROCKCHIP_MMC_INIT_STATE_SHIFT 1
44 46
45#define PSECS_PER_SEC 1000000000000LL 47#define PSECS_PER_SEC 1000000000000LL
46 48
@@ -159,6 +161,15 @@ struct clk *rockchip_clk_register_mmc(const char *name,
159 mmc_clock->reg = reg; 161 mmc_clock->reg = reg;
160 mmc_clock->shift = shift; 162 mmc_clock->shift = shift;
161 163
164 /*
165 * Assert init_state to soft reset the CLKGEN
166 * for mmc tuning phase and degree
167 */
168 if (mmc_clock->shift == ROCKCHIP_MMC_INIT_STATE_SHIFT)
169 writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_RESET,
170 ROCKCHIP_MMC_INIT_STATE_RESET,
171 mmc_clock->shift), mmc_clock->reg);
172
162 clk = clk_register(NULL, &mmc_clock->hw); 173 clk = clk_register(NULL, &mmc_clock->hw);
163 if (IS_ERR(clk)) 174 if (IS_ERR(clk))
164 goto err_free; 175 goto err_free;
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 7737a1df1e4b..4881eb8a1576 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -126,11 +126,32 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
126#define RK3066_PLLCON3_PWRDOWN (1 << 1) 126#define RK3066_PLLCON3_PWRDOWN (1 << 1)
127#define RK3066_PLLCON3_BYPASS (1 << 0) 127#define RK3066_PLLCON3_BYPASS (1 << 0)
128 128
129static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,
130 struct rockchip_pll_rate_table *rate)
131{
132 u32 pllcon;
133
134 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
135 rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
136 & RK3066_PLLCON0_NR_MASK) + 1;
137 rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
138 & RK3066_PLLCON0_OD_MASK) + 1;
139
140 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
141 rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
142 & RK3066_PLLCON1_NF_MASK) + 1;
143
144 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
145 rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
146 & RK3066_PLLCON2_NB_MASK) + 1;
147}
148
129static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw, 149static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
130 unsigned long prate) 150 unsigned long prate)
131{ 151{
132 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 152 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
133 u64 nf, nr, no, rate64 = prate; 153 struct rockchip_pll_rate_table cur;
154 u64 rate64 = prate;
134 u32 pllcon; 155 u32 pllcon;
135 156
136 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3)); 157 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
@@ -140,53 +161,31 @@ static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
140 return prate; 161 return prate;
141 } 162 }
142 163
143 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1)); 164 rockchip_rk3066_pll_get_params(pll, &cur);
144 nf = (pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK;
145
146 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
147 nr = (pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK;
148 no = (pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK;
149 165
150 rate64 *= (nf + 1); 166 rate64 *= cur.nf;
151 do_div(rate64, nr + 1); 167 do_div(rate64, cur.nr);
152 do_div(rate64, no + 1); 168 do_div(rate64, cur.no);
153 169
154 return (unsigned long)rate64; 170 return (unsigned long)rate64;
155} 171}
156 172
157static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, 173static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
158 unsigned long prate) 174 const struct rockchip_pll_rate_table *rate)
159{ 175{
160 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
161 const struct rockchip_pll_rate_table *rate;
162 unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
163 struct regmap *grf = rockchip_clk_get_grf();
164 struct clk_mux *pll_mux = &pll->pll_mux;
165 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; 176 const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
177 struct clk_mux *pll_mux = &pll->pll_mux;
178 struct rockchip_pll_rate_table cur;
166 int rate_change_remuxed = 0; 179 int rate_change_remuxed = 0;
167 int cur_parent; 180 int cur_parent;
168 int ret; 181 int ret;
169 182
170 if (IS_ERR(grf)) {
171 pr_debug("%s: grf regmap not available, aborting rate change\n",
172 __func__);
173 return PTR_ERR(grf);
174 }
175
176 pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
177 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
178
179 /* Get required rate settings from table */
180 rate = rockchip_get_pll_settings(pll, drate);
181 if (!rate) {
182 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
183 drate, clk_hw_get_name(hw));
184 return -EINVAL;
185 }
186
187 pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n", 183 pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
188 __func__, rate->rate, rate->nr, rate->no, rate->nf); 184 __func__, rate->rate, rate->nr, rate->no, rate->nf);
189 185
186 rockchip_rk3066_pll_get_params(pll, &cur);
187 cur.rate = 0;
188
190 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); 189 cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
191 if (cur_parent == PLL_MODE_NORM) { 190 if (cur_parent == PLL_MODE_NORM) {
192 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); 191 pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
@@ -219,9 +218,9 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
219 /* wait for the pll to lock */ 218 /* wait for the pll to lock */
220 ret = rockchip_pll_wait_lock(pll); 219 ret = rockchip_pll_wait_lock(pll);
221 if (ret) { 220 if (ret) {
222 pr_warn("%s: pll did not lock, trying to restore old rate %lu\n", 221 pr_warn("%s: pll update unsucessful, trying to restore old params\n",
223 __func__, old_rate); 222 __func__);
224 rockchip_rk3066_pll_set_rate(hw, old_rate, prate); 223 rockchip_rk3066_pll_set_params(pll, &cur);
225 } 224 }
226 225
227 if (rate_change_remuxed) 226 if (rate_change_remuxed)
@@ -230,6 +229,34 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
230 return ret; 229 return ret;
231} 230}
232 231
232static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
233 unsigned long prate)
234{
235 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
236 const struct rockchip_pll_rate_table *rate;
237 unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
238 struct regmap *grf = rockchip_clk_get_grf();
239
240 if (IS_ERR(grf)) {
241 pr_debug("%s: grf regmap not available, aborting rate change\n",
242 __func__);
243 return PTR_ERR(grf);
244 }
245
246 pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
247 __func__, clk_hw_get_name(hw), old_rate, drate, prate);
248
249 /* Get required rate settings from table */
250 rate = rockchip_get_pll_settings(pll, drate);
251 if (!rate) {
252 pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
253 drate, clk_hw_get_name(hw));
254 return -EINVAL;
255 }
256
257 return rockchip_rk3066_pll_set_params(pll, rate);
258}
259
233static int rockchip_rk3066_pll_enable(struct clk_hw *hw) 260static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
234{ 261{
235 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 262 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
@@ -261,9 +288,8 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
261{ 288{
262 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 289 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
263 const struct rockchip_pll_rate_table *rate; 290 const struct rockchip_pll_rate_table *rate;
264 unsigned int nf, nr, no, nb; 291 struct rockchip_pll_rate_table cur;
265 unsigned long drate; 292 unsigned long drate;
266 u32 pllcon;
267 293
268 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) 294 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
269 return; 295 return;
@@ -275,34 +301,21 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
275 if (!rate) 301 if (!rate)
276 return; 302 return;
277 303
278 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0)); 304 rockchip_rk3066_pll_get_params(pll, &cur);
279 nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1;
280 no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1;
281
282 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
283 nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1;
284
285 pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
286 nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT) & RK3066_PLLCON2_NB_MASK) + 1;
287 305
288 pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n", 306 pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",
289 __func__, clk_hw_get_name(hw), drate, rate->nr, nr, 307 __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
290 rate->no, no, rate->nf, nf, rate->nb, nb); 308 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
291 if (rate->nr != nr || rate->no != no || rate->nf != nf 309 if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
292 || rate->nb != nb) { 310 || rate->nb != cur.nb) {
293 struct clk_hw *parent = clk_hw_get_parent(hw); 311 struct regmap *grf = rockchip_clk_get_grf();
294 unsigned long prate; 312
295 313 if (IS_ERR(grf))
296 if (!parent) {
297 pr_warn("%s: parent of %s not available\n",
298 __func__, clk_hw_get_name(hw));
299 return; 314 return;
300 }
301 315
302 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", 316 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
303 __func__, clk_hw_get_name(hw)); 317 __func__, clk_hw_get_name(hw));
304 prate = clk_hw_get_rate(parent); 318 rockchip_rk3066_pll_set_params(pll, rate);
305 rockchip_rk3066_pll_set_rate(hw, drate, prate);
306 } 319 }
307} 320}
308 321
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 24938815655f..be6c7fd8315d 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -135,9 +135,11 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name,
135 div->flags = div_flags; 135 div->flags = div_flags;
136 div->reg = base + muxdiv_offset; 136 div->reg = base + muxdiv_offset;
137 div->mshift = 16; 137 div->mshift = 16;
138 div->mmask = 0xffff0000; 138 div->mwidth = 16;
139 div->mmask = GENMASK(div->mwidth - 1, 0) << div->mshift;
139 div->nshift = 0; 140 div->nshift = 0;
140 div->nmask = 0xffff; 141 div->nwidth = 16;
142 div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift;
141 div->lock = lock; 143 div->lock = lock;
142 div_ops = &clk_fractional_divider_ops; 144 div_ops = &clk_fractional_divider_ops;
143 145
diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c
index 8524e667097e..55f8e2e24ab8 100644
--- a/drivers/clk/samsung/clk-exynos7.c
+++ b/drivers/clk/samsung/clk-exynos7.c
@@ -32,39 +32,41 @@
32#define DIV_TOPC0 0x0600 32#define DIV_TOPC0 0x0600
33#define DIV_TOPC1 0x0604 33#define DIV_TOPC1 0x0604
34#define DIV_TOPC3 0x060C 34#define DIV_TOPC3 0x060C
35#define ENABLE_ACLK_TOPC0 0x0800
35#define ENABLE_ACLK_TOPC1 0x0804 36#define ENABLE_ACLK_TOPC1 0x0804
37#define ENABLE_SCLK_TOPC1 0x0A04
36 38
37static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = { 39static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = {
38 FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_bus0_pll_ctrl", 1, 2, 0), 40 FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_topc_bus0_pll", 1, 2, 0),
39 FFACTOR(0, "ffac_topc_bus0_pll_div4", 41 FFACTOR(0, "ffac_topc_bus0_pll_div4",
40 "ffac_topc_bus0_pll_div2", 1, 2, 0), 42 "ffac_topc_bus0_pll_div2", 1, 2, 0),
41 FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_bus1_pll_ctrl", 1, 2, 0), 43 FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_topc_bus1_pll", 1, 2, 0),
42 FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_cc_pll_ctrl", 1, 2, 0), 44 FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_topc_cc_pll", 1, 2, 0),
43 FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_mfc_pll_ctrl", 1, 2, 0), 45 FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_topc_mfc_pll", 1, 2, 0),
44}; 46};
45 47
46/* List of parent clocks for Muxes in CMU_TOPC */ 48/* List of parent clocks for Muxes in CMU_TOPC */
47PNAME(mout_aud_pll_ctrl_p) = { "fin_pll", "fout_aud_pll" }; 49PNAME(mout_topc_aud_pll_ctrl_p) = { "fin_pll", "fout_aud_pll" };
48PNAME(mout_bus0_pll_ctrl_p) = { "fin_pll", "fout_bus0_pll" }; 50PNAME(mout_topc_bus0_pll_ctrl_p) = { "fin_pll", "fout_bus0_pll" };
49PNAME(mout_bus1_pll_ctrl_p) = { "fin_pll", "fout_bus1_pll" }; 51PNAME(mout_topc_bus1_pll_ctrl_p) = { "fin_pll", "fout_bus1_pll" };
50PNAME(mout_cc_pll_ctrl_p) = { "fin_pll", "fout_cc_pll" }; 52PNAME(mout_topc_cc_pll_ctrl_p) = { "fin_pll", "fout_cc_pll" };
51PNAME(mout_mfc_pll_ctrl_p) = { "fin_pll", "fout_mfc_pll" }; 53PNAME(mout_topc_mfc_pll_ctrl_p) = { "fin_pll", "fout_mfc_pll" };
52 54
53PNAME(mout_topc_group2) = { "mout_sclk_bus0_pll_cmuc", 55PNAME(mout_topc_group2) = { "mout_topc_bus0_pll_half",
54 "mout_sclk_bus1_pll_cmuc", "mout_sclk_cc_pll_cmuc", 56 "mout_topc_bus1_pll_half", "mout_topc_cc_pll_half",
55 "mout_sclk_mfc_pll_cmuc" }; 57 "mout_topc_mfc_pll_half" };
56 58
57PNAME(mout_sclk_bus0_pll_cmuc_p) = { "mout_bus0_pll_ctrl", 59PNAME(mout_topc_bus0_pll_half_p) = { "mout_topc_bus0_pll",
58 "ffac_topc_bus0_pll_div2", "ffac_topc_bus0_pll_div4"}; 60 "ffac_topc_bus0_pll_div2", "ffac_topc_bus0_pll_div4"};
59PNAME(mout_sclk_bus1_pll_cmuc_p) = { "mout_bus1_pll_ctrl", 61PNAME(mout_topc_bus1_pll_half_p) = { "mout_topc_bus1_pll",
60 "ffac_topc_bus1_pll_div2"}; 62 "ffac_topc_bus1_pll_div2"};
61PNAME(mout_sclk_cc_pll_cmuc_p) = { "mout_cc_pll_ctrl", 63PNAME(mout_topc_cc_pll_half_p) = { "mout_topc_cc_pll",
62 "ffac_topc_cc_pll_div2"}; 64 "ffac_topc_cc_pll_div2"};
63PNAME(mout_sclk_mfc_pll_cmuc_p) = { "mout_mfc_pll_ctrl", 65PNAME(mout_topc_mfc_pll_half_p) = { "mout_topc_mfc_pll",
64 "ffac_topc_mfc_pll_div2"}; 66 "ffac_topc_mfc_pll_div2"};
65 67
66 68
67PNAME(mout_sclk_bus0_pll_out_p) = {"mout_bus0_pll_ctrl", 69PNAME(mout_topc_bus0_pll_out_p) = {"mout_topc_bus0_pll",
68 "ffac_topc_bus0_pll_div2"}; 70 "ffac_topc_bus0_pll_div2"};
69 71
70static unsigned long topc_clk_regs[] __initdata = { 72static unsigned long topc_clk_regs[] __initdata = {
@@ -88,23 +90,27 @@ static unsigned long topc_clk_regs[] __initdata = {
88}; 90};
89 91
90static struct samsung_mux_clock topc_mux_clks[] __initdata = { 92static struct samsung_mux_clock topc_mux_clks[] __initdata = {
91 MUX(0, "mout_bus0_pll_ctrl", mout_bus0_pll_ctrl_p, MUX_SEL_TOPC0, 0, 1), 93 MUX(0, "mout_topc_bus0_pll", mout_topc_bus0_pll_ctrl_p,
92 MUX(0, "mout_bus1_pll_ctrl", mout_bus1_pll_ctrl_p, MUX_SEL_TOPC0, 4, 1), 94 MUX_SEL_TOPC0, 0, 1),
93 MUX(0, "mout_cc_pll_ctrl", mout_cc_pll_ctrl_p, MUX_SEL_TOPC0, 8, 1), 95 MUX(0, "mout_topc_bus1_pll", mout_topc_bus1_pll_ctrl_p,
94 MUX(0, "mout_mfc_pll_ctrl", mout_mfc_pll_ctrl_p, MUX_SEL_TOPC0, 12, 1), 96 MUX_SEL_TOPC0, 4, 1),
95 97 MUX(0, "mout_topc_cc_pll", mout_topc_cc_pll_ctrl_p,
96 MUX(0, "mout_sclk_bus0_pll_cmuc", mout_sclk_bus0_pll_cmuc_p, 98 MUX_SEL_TOPC0, 8, 1),
99 MUX(0, "mout_topc_mfc_pll", mout_topc_mfc_pll_ctrl_p,
100 MUX_SEL_TOPC0, 12, 1),
101 MUX(0, "mout_topc_bus0_pll_half", mout_topc_bus0_pll_half_p,
97 MUX_SEL_TOPC0, 16, 2), 102 MUX_SEL_TOPC0, 16, 2),
98 MUX(0, "mout_sclk_bus1_pll_cmuc", mout_sclk_bus1_pll_cmuc_p, 103 MUX(0, "mout_topc_bus1_pll_half", mout_topc_bus1_pll_half_p,
99 MUX_SEL_TOPC0, 20, 1), 104 MUX_SEL_TOPC0, 20, 1),
100 MUX(0, "mout_sclk_cc_pll_cmuc", mout_sclk_cc_pll_cmuc_p, 105 MUX(0, "mout_topc_cc_pll_half", mout_topc_cc_pll_half_p,
101 MUX_SEL_TOPC0, 24, 1), 106 MUX_SEL_TOPC0, 24, 1),
102 MUX(0, "mout_sclk_mfc_pll_cmuc", mout_sclk_mfc_pll_cmuc_p, 107 MUX(0, "mout_topc_mfc_pll_half", mout_topc_mfc_pll_half_p,
103 MUX_SEL_TOPC0, 28, 1), 108 MUX_SEL_TOPC0, 28, 1),
104 109
105 MUX(0, "mout_sclk_bus0_pll_out", mout_sclk_bus0_pll_out_p, 110 MUX(0, "mout_topc_aud_pll", mout_topc_aud_pll_ctrl_p,
111 MUX_SEL_TOPC1, 0, 1),
112 MUX(0, "mout_topc_bus0_pll_out", mout_topc_bus0_pll_out_p,
106 MUX_SEL_TOPC1, 16, 1), 113 MUX_SEL_TOPC1, 16, 1),
107 MUX(0, "mout_aud_pll_ctrl", mout_aud_pll_ctrl_p, MUX_SEL_TOPC1, 0, 1),
108 114
109 MUX(0, "mout_aclk_ccore_133", mout_topc_group2, MUX_SEL_TOPC2, 4, 2), 115 MUX(0, "mout_aclk_ccore_133", mout_topc_group2, MUX_SEL_TOPC2, 4, 2),
110 116
@@ -121,16 +127,16 @@ static struct samsung_div_clock topc_div_clks[] __initdata = {
121 DIV(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66", 127 DIV(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66",
122 DIV_TOPC1, 24, 4), 128 DIV_TOPC1, 24, 4),
123 129
124 DIV(DOUT_SCLK_BUS0_PLL, "dout_sclk_bus0_pll", "mout_sclk_bus0_pll_out", 130 DIV(DOUT_SCLK_BUS0_PLL, "dout_sclk_bus0_pll", "mout_topc_bus0_pll_out",
125 DIV_TOPC3, 0, 3), 131 DIV_TOPC3, 0, 4),
126 DIV(DOUT_SCLK_BUS1_PLL, "dout_sclk_bus1_pll", "mout_bus1_pll_ctrl", 132 DIV(DOUT_SCLK_BUS1_PLL, "dout_sclk_bus1_pll", "mout_topc_bus1_pll",
127 DIV_TOPC3, 8, 3), 133 DIV_TOPC3, 8, 4),
128 DIV(DOUT_SCLK_CC_PLL, "dout_sclk_cc_pll", "mout_cc_pll_ctrl", 134 DIV(DOUT_SCLK_CC_PLL, "dout_sclk_cc_pll", "mout_topc_cc_pll",
129 DIV_TOPC3, 12, 3), 135 DIV_TOPC3, 12, 4),
130 DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_mfc_pll_ctrl", 136 DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_topc_mfc_pll",
131 DIV_TOPC3, 16, 3), 137 DIV_TOPC3, 16, 4),
132 DIV(DOUT_SCLK_AUD_PLL, "dout_sclk_aud_pll", "mout_aud_pll_ctrl", 138 DIV(DOUT_SCLK_AUD_PLL, "dout_sclk_aud_pll", "mout_topc_aud_pll",
133 DIV_TOPC3, 28, 3), 139 DIV_TOPC3, 28, 4),
134}; 140};
135 141
136static struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initdata = { 142static struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initdata = {
@@ -139,8 +145,33 @@ static struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initdata = {
139}; 145};
140 146
141static struct samsung_gate_clock topc_gate_clks[] __initdata = { 147static struct samsung_gate_clock topc_gate_clks[] __initdata = {
148 GATE(ACLK_CCORE_133, "aclk_ccore_133", "dout_aclk_ccore_133",
149 ENABLE_ACLK_TOPC0, 4, 0, 0),
150
142 GATE(ACLK_MSCL_532, "aclk_mscl_532", "dout_aclk_mscl_532", 151 GATE(ACLK_MSCL_532, "aclk_mscl_532", "dout_aclk_mscl_532",
143 ENABLE_ACLK_TOPC1, 20, 0, 0), 152 ENABLE_ACLK_TOPC1, 20, 0, 0),
153
154 GATE(ACLK_PERIS_66, "aclk_peris_66", "dout_aclk_peris_66",
155 ENABLE_ACLK_TOPC1, 24, 0, 0),
156
157 GATE(SCLK_AUD_PLL, "sclk_aud_pll", "dout_sclk_aud_pll",
158 ENABLE_SCLK_TOPC1, 20, 0, 0),
159 GATE(SCLK_MFC_PLL_B, "sclk_mfc_pll_b", "dout_sclk_mfc_pll",
160 ENABLE_SCLK_TOPC1, 17, 0, 0),
161 GATE(SCLK_MFC_PLL_A, "sclk_mfc_pll_a", "dout_sclk_mfc_pll",
162 ENABLE_SCLK_TOPC1, 16, 0, 0),
163 GATE(SCLK_BUS1_PLL_B, "sclk_bus1_pll_b", "dout_sclk_bus1_pll",
164 ENABLE_SCLK_TOPC1, 13, 0, 0),
165 GATE(SCLK_BUS1_PLL_A, "sclk_bus1_pll_a", "dout_sclk_bus1_pll",
166 ENABLE_SCLK_TOPC1, 12, 0, 0),
167 GATE(SCLK_BUS0_PLL_B, "sclk_bus0_pll_b", "dout_sclk_bus0_pll",
168 ENABLE_SCLK_TOPC1, 5, 0, 0),
169 GATE(SCLK_BUS0_PLL_A, "sclk_bus0_pll_a", "dout_sclk_bus0_pll",
170 ENABLE_SCLK_TOPC1, 4, 0, 0),
171 GATE(SCLK_CC_PLL_B, "sclk_cc_pll_b", "dout_sclk_cc_pll",
172 ENABLE_SCLK_TOPC1, 1, 0, 0),
173 GATE(SCLK_CC_PLL_A, "sclk_cc_pll_a", "dout_sclk_cc_pll",
174 ENABLE_SCLK_TOPC1, 0, 0, 0),
144}; 175};
145 176
146static struct samsung_pll_clock topc_pll_clks[] __initdata = { 177static struct samsung_pll_clock topc_pll_clks[] __initdata = {
@@ -193,36 +224,37 @@ CLK_OF_DECLARE(exynos7_clk_topc, "samsung,exynos7-clock-topc",
193#define DIV_TOP0_PERIC1 0x0634 224#define DIV_TOP0_PERIC1 0x0634
194#define DIV_TOP0_PERIC2 0x0638 225#define DIV_TOP0_PERIC2 0x0638
195#define DIV_TOP0_PERIC3 0x063C 226#define DIV_TOP0_PERIC3 0x063C
227#define ENABLE_ACLK_TOP03 0x080C
196#define ENABLE_SCLK_TOP0_PERIC0 0x0A30 228#define ENABLE_SCLK_TOP0_PERIC0 0x0A30
197#define ENABLE_SCLK_TOP0_PERIC1 0x0A34 229#define ENABLE_SCLK_TOP0_PERIC1 0x0A34
198#define ENABLE_SCLK_TOP0_PERIC2 0x0A38 230#define ENABLE_SCLK_TOP0_PERIC2 0x0A38
199#define ENABLE_SCLK_TOP0_PERIC3 0x0A3C 231#define ENABLE_SCLK_TOP0_PERIC3 0x0A3C
200 232
201/* List of parent clocks for Muxes in CMU_TOP0 */ 233/* List of parent clocks for Muxes in CMU_TOP0 */
202PNAME(mout_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" }; 234PNAME(mout_top0_bus0_pll_user_p) = { "fin_pll", "sclk_bus0_pll_a" };
203PNAME(mout_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll" }; 235PNAME(mout_top0_bus1_pll_user_p) = { "fin_pll", "sclk_bus1_pll_a" };
204PNAME(mout_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll" }; 236PNAME(mout_top0_cc_pll_user_p) = { "fin_pll", "sclk_cc_pll_a" };
205PNAME(mout_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll" }; 237PNAME(mout_top0_mfc_pll_user_p) = { "fin_pll", "sclk_mfc_pll_a" };
206PNAME(mout_aud_pll_p) = { "fin_pll", "dout_sclk_aud_pll" }; 238PNAME(mout_top0_aud_pll_user_p) = { "fin_pll", "sclk_aud_pll" };
207 239
208PNAME(mout_top0_half_bus0_pll_p) = {"mout_top0_bus0_pll", 240PNAME(mout_top0_bus0_pll_half_p) = {"mout_top0_bus0_pll_user",
209 "ffac_top0_bus0_pll_div2"}; 241 "ffac_top0_bus0_pll_div2"};
210PNAME(mout_top0_half_bus1_pll_p) = {"mout_top0_bus1_pll", 242PNAME(mout_top0_bus1_pll_half_p) = {"mout_top0_bus1_pll_user",
211 "ffac_top0_bus1_pll_div2"}; 243 "ffac_top0_bus1_pll_div2"};
212PNAME(mout_top0_half_cc_pll_p) = {"mout_top0_cc_pll", 244PNAME(mout_top0_cc_pll_half_p) = {"mout_top0_cc_pll_user",
213 "ffac_top0_cc_pll_div2"}; 245 "ffac_top0_cc_pll_div2"};
214PNAME(mout_top0_half_mfc_pll_p) = {"mout_top0_mfc_pll", 246PNAME(mout_top0_mfc_pll_half_p) = {"mout_top0_mfc_pll_user",
215 "ffac_top0_mfc_pll_div2"}; 247 "ffac_top0_mfc_pll_div2"};
216 248
217PNAME(mout_top0_group1) = {"mout_top0_half_bus0_pll", 249PNAME(mout_top0_group1) = {"mout_top0_bus0_pll_half",
218 "mout_top0_half_bus1_pll", "mout_top0_half_cc_pll", 250 "mout_top0_bus1_pll_half", "mout_top0_cc_pll_half",
219 "mout_top0_half_mfc_pll"}; 251 "mout_top0_mfc_pll_half"};
220PNAME(mout_top0_group3) = {"ioclk_audiocdclk0", 252PNAME(mout_top0_group3) = {"ioclk_audiocdclk0",
221 "ioclk_audiocdclk1", "ioclk_spdif_extclk", 253 "ioclk_audiocdclk1", "ioclk_spdif_extclk",
222 "mout_top0_aud_pll", "mout_top0_half_bus0_pll", 254 "mout_top0_aud_pll_user", "mout_top0_bus0_pll_half",
223 "mout_top0_half_bus1_pll"}; 255 "mout_top0_bus1_pll_half"};
224PNAME(mout_top0_group4) = {"ioclk_audiocdclk1", "mout_top0_aud_pll", 256PNAME(mout_top0_group4) = {"ioclk_audiocdclk1", "mout_top0_aud_pll_user",
225 "mout_top0_half_bus0_pll", "mout_top0_half_bus1_pll"}; 257 "mout_top0_bus0_pll_half", "mout_top0_bus1_pll_half"};
226 258
227static unsigned long top0_clk_regs[] __initdata = { 259static unsigned long top0_clk_regs[] __initdata = {
228 MUX_SEL_TOP00, 260 MUX_SEL_TOP00,
@@ -244,19 +276,24 @@ static unsigned long top0_clk_regs[] __initdata = {
244}; 276};
245 277
246static struct samsung_mux_clock top0_mux_clks[] __initdata = { 278static struct samsung_mux_clock top0_mux_clks[] __initdata = {
247 MUX(0, "mout_top0_aud_pll", mout_aud_pll_p, MUX_SEL_TOP00, 0, 1), 279 MUX(0, "mout_top0_aud_pll_user", mout_top0_aud_pll_user_p,
248 MUX(0, "mout_top0_mfc_pll", mout_mfc_pll_p, MUX_SEL_TOP00, 4, 1), 280 MUX_SEL_TOP00, 0, 1),
249 MUX(0, "mout_top0_cc_pll", mout_cc_pll_p, MUX_SEL_TOP00, 8, 1), 281 MUX(0, "mout_top0_mfc_pll_user", mout_top0_mfc_pll_user_p,
250 MUX(0, "mout_top0_bus1_pll", mout_bus1_pll_p, MUX_SEL_TOP00, 12, 1), 282 MUX_SEL_TOP00, 4, 1),
251 MUX(0, "mout_top0_bus0_pll", mout_bus0_pll_p, MUX_SEL_TOP00, 16, 1), 283 MUX(0, "mout_top0_cc_pll_user", mout_top0_cc_pll_user_p,
252 284 MUX_SEL_TOP00, 8, 1),
253 MUX(0, "mout_top0_half_mfc_pll", mout_top0_half_mfc_pll_p, 285 MUX(0, "mout_top0_bus1_pll_user", mout_top0_bus1_pll_user_p,
286 MUX_SEL_TOP00, 12, 1),
287 MUX(0, "mout_top0_bus0_pll_user", mout_top0_bus0_pll_user_p,
288 MUX_SEL_TOP00, 16, 1),
289
290 MUX(0, "mout_top0_mfc_pll_half", mout_top0_mfc_pll_half_p,
254 MUX_SEL_TOP01, 4, 1), 291 MUX_SEL_TOP01, 4, 1),
255 MUX(0, "mout_top0_half_cc_pll", mout_top0_half_cc_pll_p, 292 MUX(0, "mout_top0_cc_pll_half", mout_top0_cc_pll_half_p,
256 MUX_SEL_TOP01, 8, 1), 293 MUX_SEL_TOP01, 8, 1),
257 MUX(0, "mout_top0_half_bus1_pll", mout_top0_half_bus1_pll_p, 294 MUX(0, "mout_top0_bus1_pll_half", mout_top0_bus1_pll_half_p,
258 MUX_SEL_TOP01, 12, 1), 295 MUX_SEL_TOP01, 12, 1),
259 MUX(0, "mout_top0_half_bus0_pll", mout_top0_half_bus0_pll_p, 296 MUX(0, "mout_top0_bus0_pll_half", mout_top0_bus0_pll_half_p,
260 MUX_SEL_TOP01, 16, 1), 297 MUX_SEL_TOP01, 16, 1),
261 298
262 MUX(0, "mout_aclk_peric1_66", mout_top0_group1, MUX_SEL_TOP03, 12, 2), 299 MUX(0, "mout_aclk_peric1_66", mout_top0_group1, MUX_SEL_TOP03, 12, 2),
@@ -302,6 +339,11 @@ static struct samsung_div_clock top0_div_clks[] __initdata = {
302}; 339};
303 340
304static struct samsung_gate_clock top0_gate_clks[] __initdata = { 341static struct samsung_gate_clock top0_gate_clks[] __initdata = {
342 GATE(CLK_ACLK_PERIC0_66, "aclk_peric0_66", "dout_aclk_peric0_66",
343 ENABLE_ACLK_TOP03, 20, CLK_SET_RATE_PARENT, 0),
344 GATE(CLK_ACLK_PERIC1_66, "aclk_peric1_66", "dout_aclk_peric1_66",
345 ENABLE_ACLK_TOP03, 12, CLK_SET_RATE_PARENT, 0),
346
305 GATE(CLK_SCLK_SPDIF, "sclk_spdif", "dout_sclk_spdif", 347 GATE(CLK_SCLK_SPDIF, "sclk_spdif", "dout_sclk_spdif",
306 ENABLE_SCLK_TOP0_PERIC0, 4, CLK_SET_RATE_PARENT, 0), 348 ENABLE_SCLK_TOP0_PERIC0, 4, CLK_SET_RATE_PARENT, 0),
307 GATE(CLK_SCLK_PCM1, "sclk_pcm1", "dout_sclk_pcm1", 349 GATE(CLK_SCLK_PCM1, "sclk_pcm1", "dout_sclk_pcm1",
@@ -331,10 +373,12 @@ static struct samsung_gate_clock top0_gate_clks[] __initdata = {
331}; 373};
332 374
333static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = { 375static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = {
334 FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll", 1, 2, 0), 376 FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll_user",
335 FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll", 1, 2, 0), 377 1, 2, 0),
336 FFACTOR(0, "ffac_top0_cc_pll_div2", "mout_top0_cc_pll", 1, 2, 0), 378 FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll_user",
337 FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll", 1, 2, 0), 379 1, 2, 0),
380 FFACTOR(0, "ffac_top0_cc_pll_div2", "mout_top0_cc_pll_user", 1, 2, 0),
381 FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll_user", 1, 2, 0),
338}; 382};
339 383
340static struct samsung_cmu_info top0_cmu_info __initdata = { 384static struct samsung_cmu_info top0_cmu_info __initdata = {
@@ -365,31 +409,34 @@ CLK_OF_DECLARE(exynos7_clk_top0, "samsung,exynos7-clock-top0",
365#define MUX_SEL_TOP13 0x020C 409#define MUX_SEL_TOP13 0x020C
366#define MUX_SEL_TOP1_FSYS0 0x0224 410#define MUX_SEL_TOP1_FSYS0 0x0224
367#define MUX_SEL_TOP1_FSYS1 0x0228 411#define MUX_SEL_TOP1_FSYS1 0x0228
412#define MUX_SEL_TOP1_FSYS11 0x022C
368#define DIV_TOP13 0x060C 413#define DIV_TOP13 0x060C
369#define DIV_TOP1_FSYS0 0x0624 414#define DIV_TOP1_FSYS0 0x0624
370#define DIV_TOP1_FSYS1 0x0628 415#define DIV_TOP1_FSYS1 0x0628
416#define DIV_TOP1_FSYS11 0x062C
371#define ENABLE_ACLK_TOP13 0x080C 417#define ENABLE_ACLK_TOP13 0x080C
372#define ENABLE_SCLK_TOP1_FSYS0 0x0A24 418#define ENABLE_SCLK_TOP1_FSYS0 0x0A24
373#define ENABLE_SCLK_TOP1_FSYS1 0x0A28 419#define ENABLE_SCLK_TOP1_FSYS1 0x0A28
420#define ENABLE_SCLK_TOP1_FSYS11 0x0A2C
374 421
375/* List of parent clocks for Muxes in CMU_TOP1 */ 422/* List of parent clocks for Muxes in CMU_TOP1 */
376PNAME(mout_top1_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" }; 423PNAME(mout_top1_bus0_pll_user_p) = { "fin_pll", "sclk_bus0_pll_b" };
377PNAME(mout_top1_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll_b" }; 424PNAME(mout_top1_bus1_pll_user_p) = { "fin_pll", "sclk_bus1_pll_b" };
378PNAME(mout_top1_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll_b" }; 425PNAME(mout_top1_cc_pll_user_p) = { "fin_pll", "sclk_cc_pll_b" };
379PNAME(mout_top1_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll_b" }; 426PNAME(mout_top1_mfc_pll_user_p) = { "fin_pll", "sclk_mfc_pll_b" };
380 427
381PNAME(mout_top1_half_bus0_pll_p) = {"mout_top1_bus0_pll", 428PNAME(mout_top1_bus0_pll_half_p) = {"mout_top1_bus0_pll_user",
382 "ffac_top1_bus0_pll_div2"}; 429 "ffac_top1_bus0_pll_div2"};
383PNAME(mout_top1_half_bus1_pll_p) = {"mout_top1_bus1_pll", 430PNAME(mout_top1_bus1_pll_half_p) = {"mout_top1_bus1_pll_user",
384 "ffac_top1_bus1_pll_div2"}; 431 "ffac_top1_bus1_pll_div2"};
385PNAME(mout_top1_half_cc_pll_p) = {"mout_top1_cc_pll", 432PNAME(mout_top1_cc_pll_half_p) = {"mout_top1_cc_pll_user",
386 "ffac_top1_cc_pll_div2"}; 433 "ffac_top1_cc_pll_div2"};
387PNAME(mout_top1_half_mfc_pll_p) = {"mout_top1_mfc_pll", 434PNAME(mout_top1_mfc_pll_half_p) = {"mout_top1_mfc_pll_user",
388 "ffac_top1_mfc_pll_div2"}; 435 "ffac_top1_mfc_pll_div2"};
389 436
390PNAME(mout_top1_group1) = {"mout_top1_half_bus0_pll", 437PNAME(mout_top1_group1) = {"mout_top1_bus0_pll_half",
391 "mout_top1_half_bus1_pll", "mout_top1_half_cc_pll", 438 "mout_top1_bus1_pll_half", "mout_top1_cc_pll_half",
392 "mout_top1_half_mfc_pll"}; 439 "mout_top1_mfc_pll_half"};
393 440
394static unsigned long top1_clk_regs[] __initdata = { 441static unsigned long top1_clk_regs[] __initdata = {
395 MUX_SEL_TOP10, 442 MUX_SEL_TOP10,
@@ -397,40 +444,54 @@ static unsigned long top1_clk_regs[] __initdata = {
397 MUX_SEL_TOP13, 444 MUX_SEL_TOP13,
398 MUX_SEL_TOP1_FSYS0, 445 MUX_SEL_TOP1_FSYS0,
399 MUX_SEL_TOP1_FSYS1, 446 MUX_SEL_TOP1_FSYS1,
447 MUX_SEL_TOP1_FSYS11,
400 DIV_TOP13, 448 DIV_TOP13,
401 DIV_TOP1_FSYS0, 449 DIV_TOP1_FSYS0,
402 DIV_TOP1_FSYS1, 450 DIV_TOP1_FSYS1,
451 DIV_TOP1_FSYS11,
403 ENABLE_ACLK_TOP13, 452 ENABLE_ACLK_TOP13,
404 ENABLE_SCLK_TOP1_FSYS0, 453 ENABLE_SCLK_TOP1_FSYS0,
405 ENABLE_SCLK_TOP1_FSYS1, 454 ENABLE_SCLK_TOP1_FSYS1,
455 ENABLE_SCLK_TOP1_FSYS11,
406}; 456};
407 457
408static struct samsung_mux_clock top1_mux_clks[] __initdata = { 458static struct samsung_mux_clock top1_mux_clks[] __initdata = {
409 MUX(0, "mout_top1_mfc_pll", mout_top1_mfc_pll_p, MUX_SEL_TOP10, 4, 1), 459 MUX(0, "mout_top1_mfc_pll_user", mout_top1_mfc_pll_user_p,
410 MUX(0, "mout_top1_cc_pll", mout_top1_cc_pll_p, MUX_SEL_TOP10, 8, 1), 460 MUX_SEL_TOP10, 4, 1),
411 MUX(0, "mout_top1_bus1_pll", mout_top1_bus1_pll_p, 461 MUX(0, "mout_top1_cc_pll_user", mout_top1_cc_pll_user_p,
462 MUX_SEL_TOP10, 8, 1),
463 MUX(0, "mout_top1_bus1_pll_user", mout_top1_bus1_pll_user_p,
412 MUX_SEL_TOP10, 12, 1), 464 MUX_SEL_TOP10, 12, 1),
413 MUX(0, "mout_top1_bus0_pll", mout_top1_bus0_pll_p, 465 MUX(0, "mout_top1_bus0_pll_user", mout_top1_bus0_pll_user_p,
414 MUX_SEL_TOP10, 16, 1), 466 MUX_SEL_TOP10, 16, 1),
415 467
416 MUX(0, "mout_top1_half_mfc_pll", mout_top1_half_mfc_pll_p, 468 MUX(0, "mout_top1_mfc_pll_half", mout_top1_mfc_pll_half_p,
417 MUX_SEL_TOP11, 4, 1), 469 MUX_SEL_TOP11, 4, 1),
418 MUX(0, "mout_top1_half_cc_pll", mout_top1_half_cc_pll_p, 470 MUX(0, "mout_top1_cc_pll_half", mout_top1_cc_pll_half_p,
419 MUX_SEL_TOP11, 8, 1), 471 MUX_SEL_TOP11, 8, 1),
420 MUX(0, "mout_top1_half_bus1_pll", mout_top1_half_bus1_pll_p, 472 MUX(0, "mout_top1_bus1_pll_half", mout_top1_bus1_pll_half_p,
421 MUX_SEL_TOP11, 12, 1), 473 MUX_SEL_TOP11, 12, 1),
422 MUX(0, "mout_top1_half_bus0_pll", mout_top1_half_bus0_pll_p, 474 MUX(0, "mout_top1_bus0_pll_half", mout_top1_bus0_pll_half_p,
423 MUX_SEL_TOP11, 16, 1), 475 MUX_SEL_TOP11, 16, 1),
424 476
425 MUX(0, "mout_aclk_fsys1_200", mout_top1_group1, MUX_SEL_TOP13, 24, 2), 477 MUX(0, "mout_aclk_fsys1_200", mout_top1_group1, MUX_SEL_TOP13, 24, 2),
426 MUX(0, "mout_aclk_fsys0_200", mout_top1_group1, MUX_SEL_TOP13, 28, 2), 478 MUX(0, "mout_aclk_fsys0_200", mout_top1_group1, MUX_SEL_TOP13, 28, 2),
427 479
428 MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 24, 2), 480 MUX(0, "mout_sclk_phy_fsys0_26m", mout_top1_group1,
481 MUX_SEL_TOP1_FSYS0, 0, 2),
482 MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 16, 2),
429 MUX(0, "mout_sclk_usbdrd300", mout_top1_group1, 483 MUX(0, "mout_sclk_usbdrd300", mout_top1_group1,
430 MUX_SEL_TOP1_FSYS0, 28, 2), 484 MUX_SEL_TOP1_FSYS0, 28, 2),
431 485
432 MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 24, 2), 486 MUX(0, "mout_sclk_phy_fsys1", mout_top1_group1,
433 MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 28, 2), 487 MUX_SEL_TOP1_FSYS1, 0, 2),
488 MUX(0, "mout_sclk_ufsunipro20", mout_top1_group1,
489 MUX_SEL_TOP1_FSYS1, 16, 2),
490
491 MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS11, 0, 2),
492 MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS11, 12, 2),
493 MUX(0, "mout_sclk_phy_fsys1_26m", mout_top1_group1,
494 MUX_SEL_TOP1_FSYS11, 24, 2),
434}; 495};
435 496
436static struct samsung_div_clock top1_div_clks[] __initdata = { 497static struct samsung_div_clock top1_div_clks[] __initdata = {
@@ -439,34 +500,61 @@ static struct samsung_div_clock top1_div_clks[] __initdata = {
439 DIV(DOUT_ACLK_FSYS0_200, "dout_aclk_fsys0_200", "mout_aclk_fsys0_200", 500 DIV(DOUT_ACLK_FSYS0_200, "dout_aclk_fsys0_200", "mout_aclk_fsys0_200",
440 DIV_TOP13, 28, 4), 501 DIV_TOP13, 28, 4),
441 502
503 DIV(DOUT_SCLK_PHY_FSYS1, "dout_sclk_phy_fsys1",
504 "mout_sclk_phy_fsys1", DIV_TOP1_FSYS1, 0, 6),
505
506 DIV(DOUT_SCLK_UFSUNIPRO20, "dout_sclk_ufsunipro20",
507 "mout_sclk_ufsunipro20",
508 DIV_TOP1_FSYS1, 16, 6),
509
442 DIV(DOUT_SCLK_MMC2, "dout_sclk_mmc2", "mout_sclk_mmc2", 510 DIV(DOUT_SCLK_MMC2, "dout_sclk_mmc2", "mout_sclk_mmc2",
443 DIV_TOP1_FSYS0, 24, 4), 511 DIV_TOP1_FSYS0, 16, 10),
444 DIV(0, "dout_sclk_usbdrd300", "mout_sclk_usbdrd300", 512 DIV(0, "dout_sclk_usbdrd300", "mout_sclk_usbdrd300",
445 DIV_TOP1_FSYS0, 28, 4), 513 DIV_TOP1_FSYS0, 28, 4),
446 514
447 DIV(DOUT_SCLK_MMC1, "dout_sclk_mmc1", "mout_sclk_mmc1", 515 DIV(DOUT_SCLK_MMC1, "dout_sclk_mmc1", "mout_sclk_mmc1",
448 DIV_TOP1_FSYS1, 24, 4), 516 DIV_TOP1_FSYS11, 0, 10),
449 DIV(DOUT_SCLK_MMC0, "dout_sclk_mmc0", "mout_sclk_mmc0", 517 DIV(DOUT_SCLK_MMC0, "dout_sclk_mmc0", "mout_sclk_mmc0",
450 DIV_TOP1_FSYS1, 28, 4), 518 DIV_TOP1_FSYS11, 12, 10),
519
520 DIV(DOUT_SCLK_PHY_FSYS1_26M, "dout_sclk_phy_fsys1_26m",
521 "mout_sclk_phy_fsys1_26m", DIV_TOP1_FSYS11, 24, 6),
451}; 522};
452 523
453static struct samsung_gate_clock top1_gate_clks[] __initdata = { 524static struct samsung_gate_clock top1_gate_clks[] __initdata = {
454 GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2", 525 GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2",
455 ENABLE_SCLK_TOP1_FSYS0, 24, CLK_SET_RATE_PARENT, 0), 526 ENABLE_SCLK_TOP1_FSYS0, 16, CLK_SET_RATE_PARENT, 0),
456 GATE(0, "sclk_usbdrd300", "dout_sclk_usbdrd300", 527 GATE(0, "sclk_usbdrd300", "dout_sclk_usbdrd300",
457 ENABLE_SCLK_TOP1_FSYS0, 28, 0, 0), 528 ENABLE_SCLK_TOP1_FSYS0, 28, 0, 0),
458 529
530 GATE(CLK_SCLK_PHY_FSYS1, "sclk_phy_fsys1", "dout_sclk_phy_fsys1",
531 ENABLE_SCLK_TOP1_FSYS1, 0, CLK_SET_RATE_PARENT, 0),
532
533 GATE(CLK_SCLK_UFSUNIPRO20, "sclk_ufsunipro20", "dout_sclk_ufsunipro20",
534 ENABLE_SCLK_TOP1_FSYS1, 16, CLK_SET_RATE_PARENT, 0),
535
459 GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_sclk_mmc1", 536 GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_sclk_mmc1",
460 ENABLE_SCLK_TOP1_FSYS1, 24, CLK_SET_RATE_PARENT, 0), 537 ENABLE_SCLK_TOP1_FSYS11, 0, CLK_SET_RATE_PARENT, 0),
461 GATE(CLK_SCLK_MMC0, "sclk_mmc0", "dout_sclk_mmc0", 538 GATE(CLK_SCLK_MMC0, "sclk_mmc0", "dout_sclk_mmc0",
462 ENABLE_SCLK_TOP1_FSYS1, 28, CLK_SET_RATE_PARENT, 0), 539 ENABLE_SCLK_TOP1_FSYS11, 12, CLK_SET_RATE_PARENT, 0),
540
541 GATE(CLK_ACLK_FSYS0_200, "aclk_fsys0_200", "dout_aclk_fsys0_200",
542 ENABLE_ACLK_TOP13, 28, CLK_SET_RATE_PARENT, 0),
543 GATE(CLK_ACLK_FSYS1_200, "aclk_fsys1_200", "dout_aclk_fsys1_200",
544 ENABLE_ACLK_TOP13, 24, CLK_SET_RATE_PARENT, 0),
545
546 GATE(CLK_SCLK_PHY_FSYS1_26M, "sclk_phy_fsys1_26m",
547 "dout_sclk_phy_fsys1_26m", ENABLE_SCLK_TOP1_FSYS11,
548 24, CLK_SET_RATE_PARENT, 0),
463}; 549};
464 550
465static struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initdata = { 551static struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initdata = {
466 FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll", 1, 2, 0), 552 FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll_user",
467 FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll", 1, 2, 0), 553 1, 2, 0),
468 FFACTOR(0, "ffac_top1_cc_pll_div2", "mout_top1_cc_pll", 1, 2, 0), 554 FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll_user",
469 FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll", 1, 2, 0), 555 1, 2, 0),
556 FFACTOR(0, "ffac_top1_cc_pll_div2", "mout_top1_cc_pll_user", 1, 2, 0),
557 FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll_user", 1, 2, 0),
470}; 558};
471 559
472static struct samsung_cmu_info top1_cmu_info __initdata = { 560static struct samsung_cmu_info top1_cmu_info __initdata = {
@@ -501,7 +589,7 @@ CLK_OF_DECLARE(exynos7_clk_top1, "samsung,exynos7-clock-top1",
501/* 589/*
502 * List of parent clocks for Muxes in CMU_CCORE 590 * List of parent clocks for Muxes in CMU_CCORE
503 */ 591 */
504PNAME(mout_aclk_ccore_133_p) = { "fin_pll", "dout_aclk_ccore_133" }; 592PNAME(mout_aclk_ccore_133_user_p) = { "fin_pll", "aclk_ccore_133" };
505 593
506static unsigned long ccore_clk_regs[] __initdata = { 594static unsigned long ccore_clk_regs[] __initdata = {
507 MUX_SEL_CCORE, 595 MUX_SEL_CCORE,
@@ -509,7 +597,7 @@ static unsigned long ccore_clk_regs[] __initdata = {
509}; 597};
510 598
511static struct samsung_mux_clock ccore_mux_clks[] __initdata = { 599static struct samsung_mux_clock ccore_mux_clks[] __initdata = {
512 MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_p, 600 MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_user_p,
513 MUX_SEL_CCORE, 1, 1), 601 MUX_SEL_CCORE, 1, 1),
514}; 602};
515 603
@@ -542,8 +630,8 @@ CLK_OF_DECLARE(exynos7_clk_ccore, "samsung,exynos7-clock-ccore",
542#define ENABLE_SCLK_PERIC0 0x0A00 630#define ENABLE_SCLK_PERIC0 0x0A00
543 631
544/* List of parent clocks for Muxes in CMU_PERIC0 */ 632/* List of parent clocks for Muxes in CMU_PERIC0 */
545PNAME(mout_aclk_peric0_66_p) = { "fin_pll", "dout_aclk_peric0_66" }; 633PNAME(mout_aclk_peric0_66_user_p) = { "fin_pll", "aclk_peric0_66" };
546PNAME(mout_sclk_uart0_p) = { "fin_pll", "sclk_uart0" }; 634PNAME(mout_sclk_uart0_user_p) = { "fin_pll", "sclk_uart0" };
547 635
548static unsigned long peric0_clk_regs[] __initdata = { 636static unsigned long peric0_clk_regs[] __initdata = {
549 MUX_SEL_PERIC0, 637 MUX_SEL_PERIC0,
@@ -552,9 +640,9 @@ static unsigned long peric0_clk_regs[] __initdata = {
552}; 640};
553 641
554static struct samsung_mux_clock peric0_mux_clks[] __initdata = { 642static struct samsung_mux_clock peric0_mux_clks[] __initdata = {
555 MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_p, 643 MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_user_p,
556 MUX_SEL_PERIC0, 0, 1), 644 MUX_SEL_PERIC0, 0, 1),
557 MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_p, 645 MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_user_p,
558 MUX_SEL_PERIC0, 16, 1), 646 MUX_SEL_PERIC0, 16, 1),
559}; 647};
560 648
@@ -611,15 +699,15 @@ CLK_OF_DECLARE(exynos7_clk_peric0, "samsung,exynos7-clock-peric0",
611 exynos7_clk_peric0_init); 699 exynos7_clk_peric0_init);
612 700
613/* List of parent clocks for Muxes in CMU_PERIC1 */ 701/* List of parent clocks for Muxes in CMU_PERIC1 */
614PNAME(mout_aclk_peric1_66_p) = { "fin_pll", "dout_aclk_peric1_66" }; 702PNAME(mout_aclk_peric1_66_user_p) = { "fin_pll", "aclk_peric1_66" };
615PNAME(mout_sclk_uart1_p) = { "fin_pll", "sclk_uart1" }; 703PNAME(mout_sclk_uart1_user_p) = { "fin_pll", "sclk_uart1" };
616PNAME(mout_sclk_uart2_p) = { "fin_pll", "sclk_uart2" }; 704PNAME(mout_sclk_uart2_user_p) = { "fin_pll", "sclk_uart2" };
617PNAME(mout_sclk_uart3_p) = { "fin_pll", "sclk_uart3" }; 705PNAME(mout_sclk_uart3_user_p) = { "fin_pll", "sclk_uart3" };
618PNAME(mout_sclk_spi0_p) = { "fin_pll", "sclk_spi0" }; 706PNAME(mout_sclk_spi0_user_p) = { "fin_pll", "sclk_spi0" };
619PNAME(mout_sclk_spi1_p) = { "fin_pll", "sclk_spi1" }; 707PNAME(mout_sclk_spi1_user_p) = { "fin_pll", "sclk_spi1" };
620PNAME(mout_sclk_spi2_p) = { "fin_pll", "sclk_spi2" }; 708PNAME(mout_sclk_spi2_user_p) = { "fin_pll", "sclk_spi2" };
621PNAME(mout_sclk_spi3_p) = { "fin_pll", "sclk_spi3" }; 709PNAME(mout_sclk_spi3_user_p) = { "fin_pll", "sclk_spi3" };
622PNAME(mout_sclk_spi4_p) = { "fin_pll", "sclk_spi4" }; 710PNAME(mout_sclk_spi4_user_p) = { "fin_pll", "sclk_spi4" };
623 711
624static unsigned long peric1_clk_regs[] __initdata = { 712static unsigned long peric1_clk_regs[] __initdata = {
625 MUX_SEL_PERIC10, 713 MUX_SEL_PERIC10,
@@ -630,24 +718,24 @@ static unsigned long peric1_clk_regs[] __initdata = {
630}; 718};
631 719
632static struct samsung_mux_clock peric1_mux_clks[] __initdata = { 720static struct samsung_mux_clock peric1_mux_clks[] __initdata = {
633 MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_p, 721 MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_user_p,
634 MUX_SEL_PERIC10, 0, 1), 722 MUX_SEL_PERIC10, 0, 1),
635 723
636 MUX_F(0, "mout_sclk_spi0_user", mout_sclk_spi0_p, 724 MUX_F(0, "mout_sclk_spi0_user", mout_sclk_spi0_user_p,
637 MUX_SEL_PERIC11, 0, 1, CLK_SET_RATE_PARENT, 0), 725 MUX_SEL_PERIC11, 0, 1, CLK_SET_RATE_PARENT, 0),
638 MUX_F(0, "mout_sclk_spi1_user", mout_sclk_spi1_p, 726 MUX_F(0, "mout_sclk_spi1_user", mout_sclk_spi1_user_p,
639 MUX_SEL_PERIC11, 4, 1, CLK_SET_RATE_PARENT, 0), 727 MUX_SEL_PERIC11, 4, 1, CLK_SET_RATE_PARENT, 0),
640 MUX_F(0, "mout_sclk_spi2_user", mout_sclk_spi2_p, 728 MUX_F(0, "mout_sclk_spi2_user", mout_sclk_spi2_user_p,
641 MUX_SEL_PERIC11, 8, 1, CLK_SET_RATE_PARENT, 0), 729 MUX_SEL_PERIC11, 8, 1, CLK_SET_RATE_PARENT, 0),
642 MUX_F(0, "mout_sclk_spi3_user", mout_sclk_spi3_p, 730 MUX_F(0, "mout_sclk_spi3_user", mout_sclk_spi3_user_p,
643 MUX_SEL_PERIC11, 12, 1, CLK_SET_RATE_PARENT, 0), 731 MUX_SEL_PERIC11, 12, 1, CLK_SET_RATE_PARENT, 0),
644 MUX_F(0, "mout_sclk_spi4_user", mout_sclk_spi4_p, 732 MUX_F(0, "mout_sclk_spi4_user", mout_sclk_spi4_user_p,
645 MUX_SEL_PERIC11, 16, 1, CLK_SET_RATE_PARENT, 0), 733 MUX_SEL_PERIC11, 16, 1, CLK_SET_RATE_PARENT, 0),
646 MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_p, 734 MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_user_p,
647 MUX_SEL_PERIC11, 20, 1), 735 MUX_SEL_PERIC11, 20, 1),
648 MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_p, 736 MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_user_p,
649 MUX_SEL_PERIC11, 24, 1), 737 MUX_SEL_PERIC11, 24, 1),
650 MUX(0, "mout_sclk_uart3_user", mout_sclk_uart3_p, 738 MUX(0, "mout_sclk_uart3_user", mout_sclk_uart3_user_p,
651 MUX_SEL_PERIC11, 28, 1), 739 MUX_SEL_PERIC11, 28, 1),
652}; 740};
653 741
@@ -735,7 +823,7 @@ CLK_OF_DECLARE(exynos7_clk_peric1, "samsung,exynos7-clock-peric1",
735#define ENABLE_SCLK_PERIS_SECURE_CHIPID 0x0A10 823#define ENABLE_SCLK_PERIS_SECURE_CHIPID 0x0A10
736 824
737/* List of parent clocks for Muxes in CMU_PERIS */ 825/* List of parent clocks for Muxes in CMU_PERIS */
738PNAME(mout_aclk_peris_66_p) = { "fin_pll", "dout_aclk_peris_66" }; 826PNAME(mout_aclk_peris_66_user_p) = { "fin_pll", "aclk_peris_66" };
739 827
740static unsigned long peris_clk_regs[] __initdata = { 828static unsigned long peris_clk_regs[] __initdata = {
741 MUX_SEL_PERIS, 829 MUX_SEL_PERIS,
@@ -747,7 +835,7 @@ static unsigned long peris_clk_regs[] __initdata = {
747 835
748static struct samsung_mux_clock peris_mux_clks[] __initdata = { 836static struct samsung_mux_clock peris_mux_clks[] __initdata = {
749 MUX(0, "mout_aclk_peris_66_user", 837 MUX(0, "mout_aclk_peris_66_user",
750 mout_aclk_peris_66_p, MUX_SEL_PERIS, 0, 1), 838 mout_aclk_peris_66_user_p, MUX_SEL_PERIS, 0, 1),
751}; 839};
752 840
753static struct samsung_gate_clock peris_gate_clks[] __initdata = { 841static struct samsung_gate_clock peris_gate_clks[] __initdata = {
@@ -795,17 +883,17 @@ CLK_OF_DECLARE(exynos7_clk_peris, "samsung,exynos7-clock-peris",
795/* 883/*
796 * List of parent clocks for Muxes in CMU_FSYS0 884 * List of parent clocks for Muxes in CMU_FSYS0
797 */ 885 */
798PNAME(mout_aclk_fsys0_200_p) = { "fin_pll", "dout_aclk_fsys0_200" }; 886PNAME(mout_aclk_fsys0_200_user_p) = { "fin_pll", "aclk_fsys0_200" };
799PNAME(mout_sclk_mmc2_p) = { "fin_pll", "sclk_mmc2" }; 887PNAME(mout_sclk_mmc2_user_p) = { "fin_pll", "sclk_mmc2" };
800 888
801PNAME(mout_sclk_usbdrd300_p) = { "fin_pll", "sclk_usbdrd300" }; 889PNAME(mout_sclk_usbdrd300_user_p) = { "fin_pll", "sclk_usbdrd300" };
802PNAME(mout_phyclk_usbdrd300_udrd30_phyclk_p) = { "fin_pll", 890PNAME(mout_phyclk_usbdrd300_udrd30_phyclk_user_p) = { "fin_pll",
803 "phyclk_usbdrd300_udrd30_phyclock" }; 891 "phyclk_usbdrd300_udrd30_phyclock" };
804PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_p) = { "fin_pll", 892PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_user_p) = { "fin_pll",
805 "phyclk_usbdrd300_udrd30_pipe_pclk" }; 893 "phyclk_usbdrd300_udrd30_pipe_pclk" };
806 894
807/* fixed rate clocks used in the FSYS0 block */ 895/* fixed rate clocks used in the FSYS0 block */
808struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = { 896static struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = {
809 FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL, 897 FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL,
810 CLK_IS_ROOT, 60000000), 898 CLK_IS_ROOT, 60000000),
811 FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL, 899 FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL,
@@ -824,29 +912,30 @@ static unsigned long fsys0_clk_regs[] __initdata = {
824}; 912};
825 913
826static struct samsung_mux_clock fsys0_mux_clks[] __initdata = { 914static struct samsung_mux_clock fsys0_mux_clks[] __initdata = {
827 MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_p, 915 MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_user_p,
828 MUX_SEL_FSYS00, 24, 1), 916 MUX_SEL_FSYS00, 24, 1),
829 917
830 MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_p, MUX_SEL_FSYS01, 24, 1), 918 MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_user_p,
831 MUX(0, "mout_sclk_usbdrd300_user", mout_sclk_usbdrd300_p, 919 MUX_SEL_FSYS01, 24, 1),
920 MUX(0, "mout_sclk_usbdrd300_user", mout_sclk_usbdrd300_user_p,
832 MUX_SEL_FSYS01, 28, 1), 921 MUX_SEL_FSYS01, 28, 1),
833 922
834 MUX(0, "mout_phyclk_usbdrd300_udrd30_pipe_pclk_user", 923 MUX(0, "mout_phyclk_usbdrd300_udrd30_pipe_pclk_user",
835 mout_phyclk_usbdrd300_udrd30_pipe_pclk_p, 924 mout_phyclk_usbdrd300_udrd30_pipe_pclk_user_p,
836 MUX_SEL_FSYS02, 24, 1), 925 MUX_SEL_FSYS02, 24, 1),
837 MUX(0, "mout_phyclk_usbdrd300_udrd30_phyclk_user", 926 MUX(0, "mout_phyclk_usbdrd300_udrd30_phyclk_user",
838 mout_phyclk_usbdrd300_udrd30_phyclk_p, 927 mout_phyclk_usbdrd300_udrd30_phyclk_user_p,
839 MUX_SEL_FSYS02, 28, 1), 928 MUX_SEL_FSYS02, 28, 1),
840}; 929};
841 930
842static struct samsung_gate_clock fsys0_gate_clks[] __initdata = { 931static struct samsung_gate_clock fsys0_gate_clks[] __initdata = {
843 GATE(ACLK_AXIUS_USBDRD30X_FSYS0X, "aclk_axius_usbdrd30x_fsys0x",
844 "mout_aclk_fsys0_200_user",
845 ENABLE_ACLK_FSYS00, 19, 0, 0),
846 GATE(ACLK_PDMA1, "aclk_pdma1", "mout_aclk_fsys0_200_user", 932 GATE(ACLK_PDMA1, "aclk_pdma1", "mout_aclk_fsys0_200_user",
847 ENABLE_ACLK_FSYS00, 3, 0, 0), 933 ENABLE_ACLK_FSYS00, 3, 0, 0),
848 GATE(ACLK_PDMA0, "aclk_pdma0", "mout_aclk_fsys0_200_user", 934 GATE(ACLK_PDMA0, "aclk_pdma0", "mout_aclk_fsys0_200_user",
849 ENABLE_ACLK_FSYS00, 4, 0, 0), 935 ENABLE_ACLK_FSYS00, 4, 0, 0),
936 GATE(ACLK_AXIUS_USBDRD30X_FSYS0X, "aclk_axius_usbdrd30x_fsys0x",
937 "mout_aclk_fsys0_200_user",
938 ENABLE_ACLK_FSYS00, 19, 0, 0),
850 939
851 GATE(ACLK_USBDRD300, "aclk_usbdrd300", "mout_aclk_fsys0_200_user", 940 GATE(ACLK_USBDRD300, "aclk_usbdrd300", "mout_aclk_fsys0_200_user",
852 ENABLE_ACLK_FSYS01, 29, 0, 0), 941 ENABLE_ACLK_FSYS01, 29, 0, 0),
@@ -874,11 +963,13 @@ static struct samsung_gate_clock fsys0_gate_clks[] __initdata = {
874}; 963};
875 964
876static struct samsung_cmu_info fsys0_cmu_info __initdata = { 965static struct samsung_cmu_info fsys0_cmu_info __initdata = {
966 .fixed_clks = fixed_rate_clks_fsys0,
967 .nr_fixed_clks = ARRAY_SIZE(fixed_rate_clks_fsys0),
877 .mux_clks = fsys0_mux_clks, 968 .mux_clks = fsys0_mux_clks,
878 .nr_mux_clks = ARRAY_SIZE(fsys0_mux_clks), 969 .nr_mux_clks = ARRAY_SIZE(fsys0_mux_clks),
879 .gate_clks = fsys0_gate_clks, 970 .gate_clks = fsys0_gate_clks,
880 .nr_gate_clks = ARRAY_SIZE(fsys0_gate_clks), 971 .nr_gate_clks = ARRAY_SIZE(fsys0_gate_clks),
881 .nr_clk_ids = TOP1_NR_CLK, 972 .nr_clk_ids = FSYS0_NR_CLK,
882 .clk_regs = fsys0_clk_regs, 973 .clk_regs = fsys0_clk_regs,
883 .nr_clk_regs = ARRAY_SIZE(fsys0_clk_regs), 974 .nr_clk_regs = ARRAY_SIZE(fsys0_clk_regs),
884}; 975};
@@ -894,42 +985,122 @@ CLK_OF_DECLARE(exynos7_clk_fsys0, "samsung,exynos7-clock-fsys0",
894/* Register Offset definitions for CMU_FSYS1 (0x156E0000) */ 985/* Register Offset definitions for CMU_FSYS1 (0x156E0000) */
895#define MUX_SEL_FSYS10 0x0200 986#define MUX_SEL_FSYS10 0x0200
896#define MUX_SEL_FSYS11 0x0204 987#define MUX_SEL_FSYS11 0x0204
988#define MUX_SEL_FSYS12 0x0208
989#define DIV_FSYS1 0x0600
897#define ENABLE_ACLK_FSYS1 0x0800 990#define ENABLE_ACLK_FSYS1 0x0800
991#define ENABLE_PCLK_FSYS1 0x0900
992#define ENABLE_SCLK_FSYS11 0x0A04
993#define ENABLE_SCLK_FSYS12 0x0A08
994#define ENABLE_SCLK_FSYS13 0x0A0C
898 995
899/* 996/*
900 * List of parent clocks for Muxes in CMU_FSYS1 997 * List of parent clocks for Muxes in CMU_FSYS1
901 */ 998 */
902PNAME(mout_aclk_fsys1_200_p) = { "fin_pll", "dout_aclk_fsys1_200" }; 999PNAME(mout_aclk_fsys1_200_user_p) = { "fin_pll", "aclk_fsys1_200" };
903PNAME(mout_sclk_mmc0_p) = { "fin_pll", "sclk_mmc0" }; 1000PNAME(mout_fsys1_group_p) = { "fin_pll", "fin_pll_26m",
904PNAME(mout_sclk_mmc1_p) = { "fin_pll", "sclk_mmc1" }; 1001 "sclk_phy_fsys1_26m" };
1002PNAME(mout_sclk_mmc0_user_p) = { "fin_pll", "sclk_mmc0" };
1003PNAME(mout_sclk_mmc1_user_p) = { "fin_pll", "sclk_mmc1" };
1004PNAME(mout_sclk_ufsunipro20_user_p) = { "fin_pll", "sclk_ufsunipro20" };
1005PNAME(mout_phyclk_ufs20_tx0_user_p) = { "fin_pll", "phyclk_ufs20_tx0_symbol" };
1006PNAME(mout_phyclk_ufs20_rx0_user_p) = { "fin_pll", "phyclk_ufs20_rx0_symbol" };
1007PNAME(mout_phyclk_ufs20_rx1_user_p) = { "fin_pll", "phyclk_ufs20_rx1_symbol" };
1008
1009/* fixed rate clocks used in the FSYS1 block */
1010static struct samsung_fixed_rate_clock fixed_rate_clks_fsys1[] __initdata = {
1011 FRATE(PHYCLK_UFS20_TX0_SYMBOL, "phyclk_ufs20_tx0_symbol", NULL,
1012 CLK_IS_ROOT, 300000000),
1013 FRATE(PHYCLK_UFS20_RX0_SYMBOL, "phyclk_ufs20_rx0_symbol", NULL,
1014 CLK_IS_ROOT, 300000000),
1015 FRATE(PHYCLK_UFS20_RX1_SYMBOL, "phyclk_ufs20_rx1_symbol", NULL,
1016 CLK_IS_ROOT, 300000000),
1017};
905 1018
906static unsigned long fsys1_clk_regs[] __initdata = { 1019static unsigned long fsys1_clk_regs[] __initdata = {
907 MUX_SEL_FSYS10, 1020 MUX_SEL_FSYS10,
908 MUX_SEL_FSYS11, 1021 MUX_SEL_FSYS11,
1022 MUX_SEL_FSYS12,
1023 DIV_FSYS1,
909 ENABLE_ACLK_FSYS1, 1024 ENABLE_ACLK_FSYS1,
1025 ENABLE_PCLK_FSYS1,
1026 ENABLE_SCLK_FSYS11,
1027 ENABLE_SCLK_FSYS12,
1028 ENABLE_SCLK_FSYS13,
910}; 1029};
911 1030
912static struct samsung_mux_clock fsys1_mux_clks[] __initdata = { 1031static struct samsung_mux_clock fsys1_mux_clks[] __initdata = {
913 MUX(0, "mout_aclk_fsys1_200_user", mout_aclk_fsys1_200_p, 1032 MUX(MOUT_FSYS1_PHYCLK_SEL1, "mout_fsys1_phyclk_sel1",
1033 mout_fsys1_group_p, MUX_SEL_FSYS10, 16, 2),
1034 MUX(0, "mout_fsys1_phyclk_sel0", mout_fsys1_group_p,
1035 MUX_SEL_FSYS10, 20, 2),
1036 MUX(0, "mout_aclk_fsys1_200_user", mout_aclk_fsys1_200_user_p,
914 MUX_SEL_FSYS10, 28, 1), 1037 MUX_SEL_FSYS10, 28, 1),
915 1038
916 MUX(0, "mout_sclk_mmc1_user", mout_sclk_mmc1_p, MUX_SEL_FSYS11, 24, 1), 1039 MUX(0, "mout_sclk_mmc1_user", mout_sclk_mmc1_user_p,
917 MUX(0, "mout_sclk_mmc0_user", mout_sclk_mmc0_p, MUX_SEL_FSYS11, 28, 1), 1040 MUX_SEL_FSYS11, 24, 1),
1041 MUX(0, "mout_sclk_mmc0_user", mout_sclk_mmc0_user_p,
1042 MUX_SEL_FSYS11, 28, 1),
1043 MUX(0, "mout_sclk_ufsunipro20_user", mout_sclk_ufsunipro20_user_p,
1044 MUX_SEL_FSYS11, 20, 1),
1045
1046 MUX(0, "mout_phyclk_ufs20_rx1_symbol_user",
1047 mout_phyclk_ufs20_rx1_user_p, MUX_SEL_FSYS12, 16, 1),
1048 MUX(0, "mout_phyclk_ufs20_rx0_symbol_user",
1049 mout_phyclk_ufs20_rx0_user_p, MUX_SEL_FSYS12, 24, 1),
1050 MUX(0, "mout_phyclk_ufs20_tx0_symbol_user",
1051 mout_phyclk_ufs20_tx0_user_p, MUX_SEL_FSYS12, 28, 1),
1052};
1053
1054static struct samsung_div_clock fsys1_div_clks[] __initdata = {
1055 DIV(DOUT_PCLK_FSYS1, "dout_pclk_fsys1", "mout_aclk_fsys1_200_user",
1056 DIV_FSYS1, 0, 2),
918}; 1057};
919 1058
920static struct samsung_gate_clock fsys1_gate_clks[] __initdata = { 1059static struct samsung_gate_clock fsys1_gate_clks[] __initdata = {
1060 GATE(SCLK_UFSUNIPRO20_USER, "sclk_ufsunipro20_user",
1061 "mout_sclk_ufsunipro20_user",
1062 ENABLE_SCLK_FSYS11, 20, 0, 0),
1063
921 GATE(ACLK_MMC1, "aclk_mmc1", "mout_aclk_fsys1_200_user", 1064 GATE(ACLK_MMC1, "aclk_mmc1", "mout_aclk_fsys1_200_user",
922 ENABLE_ACLK_FSYS1, 29, 0, 0), 1065 ENABLE_ACLK_FSYS1, 29, 0, 0),
923 GATE(ACLK_MMC0, "aclk_mmc0", "mout_aclk_fsys1_200_user", 1066 GATE(ACLK_MMC0, "aclk_mmc0", "mout_aclk_fsys1_200_user",
924 ENABLE_ACLK_FSYS1, 30, 0, 0), 1067 ENABLE_ACLK_FSYS1, 30, 0, 0),
1068
1069 GATE(ACLK_UFS20_LINK, "aclk_ufs20_link", "dout_pclk_fsys1",
1070 ENABLE_ACLK_FSYS1, 31, 0, 0),
1071 GATE(PCLK_GPIO_FSYS1, "pclk_gpio_fsys1", "mout_aclk_fsys1_200_user",
1072 ENABLE_PCLK_FSYS1, 30, 0, 0),
1073
1074 GATE(PHYCLK_UFS20_RX1_SYMBOL_USER, "phyclk_ufs20_rx1_symbol_user",
1075 "mout_phyclk_ufs20_rx1_symbol_user",
1076 ENABLE_SCLK_FSYS12, 16, 0, 0),
1077 GATE(PHYCLK_UFS20_RX0_SYMBOL_USER, "phyclk_ufs20_rx0_symbol_user",
1078 "mout_phyclk_ufs20_rx0_symbol_user",
1079 ENABLE_SCLK_FSYS12, 24, 0, 0),
1080 GATE(PHYCLK_UFS20_TX0_SYMBOL_USER, "phyclk_ufs20_tx0_symbol_user",
1081 "mout_phyclk_ufs20_tx0_symbol_user",
1082 ENABLE_SCLK_FSYS12, 28, 0, 0),
1083
1084 GATE(OSCCLK_PHY_CLKOUT_EMBEDDED_COMBO_PHY,
1085 "oscclk_phy_clkout_embedded_combo_phy",
1086 "fin_pll",
1087 ENABLE_SCLK_FSYS12, 4, CLK_IGNORE_UNUSED, 0),
1088
1089 GATE(SCLK_COMBO_PHY_EMBEDDED_26M, "sclk_combo_phy_embedded_26m",
1090 "mout_fsys1_phyclk_sel1",
1091 ENABLE_SCLK_FSYS13, 24, CLK_IGNORE_UNUSED, 0),
925}; 1092};
926 1093
927static struct samsung_cmu_info fsys1_cmu_info __initdata = { 1094static struct samsung_cmu_info fsys1_cmu_info __initdata = {
1095 .fixed_clks = fixed_rate_clks_fsys1,
1096 .nr_fixed_clks = ARRAY_SIZE(fixed_rate_clks_fsys1),
928 .mux_clks = fsys1_mux_clks, 1097 .mux_clks = fsys1_mux_clks,
929 .nr_mux_clks = ARRAY_SIZE(fsys1_mux_clks), 1098 .nr_mux_clks = ARRAY_SIZE(fsys1_mux_clks),
1099 .div_clks = fsys1_div_clks,
1100 .nr_div_clks = ARRAY_SIZE(fsys1_div_clks),
930 .gate_clks = fsys1_gate_clks, 1101 .gate_clks = fsys1_gate_clks,
931 .nr_gate_clks = ARRAY_SIZE(fsys1_gate_clks), 1102 .nr_gate_clks = ARRAY_SIZE(fsys1_gate_clks),
932 .nr_clk_ids = TOP1_NR_CLK, 1103 .nr_clk_ids = FSYS1_NR_CLK,
933 .clk_regs = fsys1_clk_regs, 1104 .clk_regs = fsys1_clk_regs,
934 .nr_clk_regs = ARRAY_SIZE(fsys1_clk_regs), 1105 .nr_clk_regs = ARRAY_SIZE(fsys1_clk_regs),
935}; 1106};
diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c
index b1df7b2f1e97..4abf21172625 100644
--- a/drivers/clk/shmobile/clk-mstp.c
+++ b/drivers/clk/shmobile/clk-mstp.c
@@ -214,7 +214,7 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
214 break; 214 break;
215 215
216 if (clkidx >= MSTP_MAX_CLOCKS) { 216 if (clkidx >= MSTP_MAX_CLOCKS) {
217 pr_err("%s: invalid clock %s %s index %u)\n", 217 pr_err("%s: invalid clock %s %s index %u\n",
218 __func__, np->name, name, clkidx); 218 __func__, np->name, name, clkidx);
219 continue; 219 continue;
220 } 220 }
diff --git a/drivers/clk/shmobile/clk-r8a7778.c b/drivers/clk/shmobile/clk-r8a7778.c
index 87c1d2f2fb57..b1741551fff2 100644
--- a/drivers/clk/shmobile/clk-r8a7778.c
+++ b/drivers/clk/shmobile/clk-r8a7778.c
@@ -20,10 +20,10 @@ struct r8a7778_cpg {
20}; 20};
21 21
22/* PLL multipliers per bits 11, 12, and 18 of MODEMR */ 22/* PLL multipliers per bits 11, 12, and 18 of MODEMR */
23struct { 23static const struct {
24 unsigned long plla_mult; 24 unsigned long plla_mult;
25 unsigned long pllb_mult; 25 unsigned long pllb_mult;
26} r8a7778_rates[] __initdata = { 26} r8a7778_rates[] __initconst = {
27 [0] = { 21, 21 }, 27 [0] = { 21, 21 },
28 [1] = { 24, 24 }, 28 [1] = { 24, 24 },
29 [2] = { 28, 28 }, 29 [2] = { 28, 28 },
@@ -34,10 +34,10 @@ struct {
34}; 34};
35 35
36/* Clock dividers per bits 1 and 2 of MODEMR */ 36/* Clock dividers per bits 1 and 2 of MODEMR */
37struct { 37static const struct {
38 const char *name; 38 const char *name;
39 unsigned int div[4]; 39 unsigned int div[4];
40} r8a7778_divs[6] __initdata = { 40} r8a7778_divs[6] __initconst = {
41 { "b", { 12, 12, 16, 18 } }, 41 { "b", { 12, 12, 16, 18 } },
42 { "out", { 12, 12, 16, 18 } }, 42 { "out", { 12, 12, 16, 18 } },
43 { "p", { 16, 12, 16, 12 } }, 43 { "p", { 16, 12, 16, 12 } },
diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
index a98e21fe773a..957aae63e7cc 100644
--- a/drivers/clk/sirf/clk-atlas7.c
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -205,18 +205,11 @@
205#define SIRFSOC_CLKC_LEAF_CLK_EN7_SET 0x0530 205#define SIRFSOC_CLKC_LEAF_CLK_EN7_SET 0x0530
206#define SIRFSOC_CLKC_LEAF_CLK_EN8_SET 0x0548 206#define SIRFSOC_CLKC_LEAF_CLK_EN8_SET 0x0548
207 207
208 208#define SIRFSOC_NOC_CLK_IDLEREQ_SET 0x02D0
209static void __iomem *sirfsoc_clk_vbase; 209#define SIRFSOC_NOC_CLK_IDLEREQ_CLR 0x02D4
210static struct clk_onecell_data clk_data; 210#define SIRFSOC_NOC_CLK_SLVRDY_SET 0x02E8
211 211#define SIRFSOC_NOC_CLK_SLVRDY_CLR 0x02EC
212static const struct clk_div_table pll_div_table[] = { 212#define SIRFSOC_NOC_CLK_IDLE_STATUS 0x02F4
213 { .val = 0, .div = 1 },
214 { .val = 1, .div = 2 },
215 { .val = 2, .div = 4 },
216 { .val = 3, .div = 8 },
217 { .val = 4, .div = 16 },
218 { .val = 5, .div = 32 },
219};
220 213
221struct clk_pll { 214struct clk_pll {
222 struct clk_hw hw; 215 struct clk_hw hw;
@@ -231,10 +224,18 @@ struct clk_dto {
231}; 224};
232#define to_dtoclk(_hw) container_of(_hw, struct clk_dto, hw) 225#define to_dtoclk(_hw) container_of(_hw, struct clk_dto, hw)
233 226
227enum clk_unit_type {
228 CLK_UNIT_NOC_OTHER,
229 CLK_UNIT_NOC_CLOCK,
230 CLK_UNIT_NOC_SOCKET,
231};
232
234struct clk_unit { 233struct clk_unit {
235 struct clk_hw hw; 234 struct clk_hw hw;
236 u16 regofs; 235 u16 regofs;
237 u16 bit; 236 u16 bit;
237 u32 type;
238 u8 idle_bit;
238 spinlock_t *lock; 239 spinlock_t *lock;
239}; 240};
240#define to_unitclk(_hw) container_of(_hw, struct clk_unit, hw) 241#define to_unitclk(_hw) container_of(_hw, struct clk_unit, hw)
@@ -272,6 +273,8 @@ struct atlas7_unit_init_data {
272 unsigned long flags; 273 unsigned long flags;
273 u32 regofs; 274 u32 regofs;
274 u8 bit; 275 u8 bit;
276 u32 type;
277 u8 idle_bit;
275 spinlock_t *lock; 278 spinlock_t *lock;
276}; 279};
277 280
@@ -284,6 +287,18 @@ struct atlas7_reset_desc {
284 spinlock_t *lock; 287 spinlock_t *lock;
285}; 288};
286 289
290static void __iomem *sirfsoc_clk_vbase;
291static struct clk_onecell_data clk_data;
292
293static const struct clk_div_table pll_div_table[] = {
294 { .val = 0, .div = 1 },
295 { .val = 1, .div = 2 },
296 { .val = 2, .div = 4 },
297 { .val = 3, .div = 8 },
298 { .val = 4, .div = 16 },
299 { .val = 5, .div = 32 },
300};
301
287static DEFINE_SPINLOCK(cpupll_ctrl1_lock); 302static DEFINE_SPINLOCK(cpupll_ctrl1_lock);
288static DEFINE_SPINLOCK(mempll_ctrl1_lock); 303static DEFINE_SPINLOCK(mempll_ctrl1_lock);
289static DEFINE_SPINLOCK(sys0pll_ctrl1_lock); 304static DEFINE_SPINLOCK(sys0pll_ctrl1_lock);
@@ -1040,148 +1055,148 @@ static struct atlas7_mux_init_data mux_list[] __initdata = {
1040 /* new unit should add start from the tail of list */ 1055 /* new unit should add start from the tail of list */
1041static struct atlas7_unit_init_data unit_list[] __initdata = { 1056static struct atlas7_unit_init_data unit_list[] __initdata = {
1042 /* unit_name, parent_name, flags, regofs, bit, lock */ 1057 /* unit_name, parent_name, flags, regofs, bit, lock */
1043 { 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, &root0_gate_lock }, 1058 { 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, 0, 0, &root0_gate_lock },
1044 { 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, &root0_gate_lock }, 1059 { 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, 0, 0, &root0_gate_lock },
1045 { 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, &root0_gate_lock }, 1060 { 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, 0, 0, &root0_gate_lock },
1046 { 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, &root0_gate_lock }, 1061 { 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, 0, 0, &root0_gate_lock },
1047 { 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, &root0_gate_lock }, 1062 { 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, 0, 0, &root0_gate_lock },
1048 { 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, &root0_gate_lock }, 1063 { 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, 0, 0, &root0_gate_lock },
1049 { 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, &root0_gate_lock }, 1064 { 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, 0, 0, &root0_gate_lock },
1050 { 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, &root0_gate_lock }, 1065 { 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, 0, 0, &root0_gate_lock },
1051 { 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, &root0_gate_lock }, 1066 { 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, 0, 0, &root0_gate_lock },
1052 { 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, &root0_gate_lock }, 1067 { 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, 0, 0, &root0_gate_lock },
1053 { 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, &root0_gate_lock }, 1068 { 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, 0, 0, &root0_gate_lock },
1054 { 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, &root0_gate_lock }, 1069 { 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, 0, 0, &root0_gate_lock },
1055 { 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, &root0_gate_lock }, 1070 { 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, 0, 0, &root0_gate_lock },
1056 { 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, &root0_gate_lock }, 1071 { 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, 0, 0, &root0_gate_lock },
1057 { 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, &root0_gate_lock }, 1072 { 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, 0, 0, &root0_gate_lock },
1058 { 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, &root0_gate_lock }, 1073 { 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, 0, 0, &root0_gate_lock },
1059 { 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, &root0_gate_lock }, 1074 { 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, 0, 0, &root0_gate_lock },
1060 { 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, &root0_gate_lock }, 1075 { 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, 0, 0, &root0_gate_lock },
1061 { 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, &root0_gate_lock }, 1076 { 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, 0, 0, &root0_gate_lock },
1062 { 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, &root0_gate_lock }, 1077 { 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, 0, 0, &root0_gate_lock },
1063 { 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, &root0_gate_lock }, 1078 { 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, 0, 0, &root0_gate_lock },
1064 { 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, &root0_gate_lock }, 1079 { 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, 0, 0, &root0_gate_lock },
1065 { 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, &root0_gate_lock }, 1080 { 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, 0, 0, &root0_gate_lock },
1066 { 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, &root1_gate_lock }, 1081 { 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, 0, 0, &root1_gate_lock },
1067 { 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, &root1_gate_lock }, 1082 { 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, 0, 0, &root1_gate_lock },
1068 { 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, &root1_gate_lock }, 1083 { 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, 0, 0, &root1_gate_lock },
1069 { 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, &root1_gate_lock }, 1084 { 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, 0, 0, &root1_gate_lock },
1070 { 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, &root1_gate_lock }, 1085 { 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, 0, 0, &root1_gate_lock },
1071 { 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, &root1_gate_lock }, 1086 { 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, 0, 0, &root1_gate_lock },
1072 { 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, &root1_gate_lock }, 1087 { 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, 0, 0, &root1_gate_lock },
1073 { 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, &root1_gate_lock }, 1088 { 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, 0, 0, &root1_gate_lock },
1074 { 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, &root1_gate_lock }, 1089 { 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, 0, 0, &root1_gate_lock },
1075 { 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, &root1_gate_lock }, 1090 { 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, 0, 0, &root1_gate_lock },
1076 { 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, &root1_gate_lock }, 1091 { 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, 0, 0, &root1_gate_lock },
1077 { 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, &root1_gate_lock }, 1092 { 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, 0, 0, &root1_gate_lock },
1078 { 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, &root1_gate_lock }, 1093 { 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, 0, 0, &root1_gate_lock },
1079 { 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, &root1_gate_lock }, 1094 { 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, 0, 0, &root1_gate_lock },
1080 { 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, &root1_gate_lock }, 1095 { 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, 0, 0, &root1_gate_lock },
1081 { 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, &root1_gate_lock }, 1096 { 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, 0, 0, &root1_gate_lock },
1082 { 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, &root1_gate_lock }, 1097 { 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, 0, 0, &root1_gate_lock },
1083 { 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, &root1_gate_lock }, 1098 { 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, 0, 0, &root1_gate_lock },
1084 { 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, &root1_gate_lock }, 1099 { 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, 0, 0, &root1_gate_lock },
1085 { 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, &root1_gate_lock }, 1100 { 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, 0, 0, &root1_gate_lock },
1086 { 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, &root1_gate_lock }, 1101 { 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, 0, 0, &root1_gate_lock },
1087 { 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, &root1_gate_lock }, 1102 { 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, 0, 0, &root1_gate_lock },
1088 { 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, &root1_gate_lock }, 1103 { 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, 0, 0, &root1_gate_lock },
1089 { 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, &leaf1_gate_lock }, 1104 { 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, CLK_UNIT_NOC_CLOCK, 4, &leaf1_gate_lock },
1090 { 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, &leaf1_gate_lock }, 1105 { 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, 0, 0, &leaf1_gate_lock },
1091 { 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, &leaf1_gate_lock }, 1106 { 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, 0, 0, &leaf1_gate_lock },
1092 { 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, &leaf1_gate_lock }, 1107 { 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, 0, 0, &leaf1_gate_lock },
1093 { 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, &leaf1_gate_lock }, 1108 { 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, 0, 0, &leaf1_gate_lock },
1094 { 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, &leaf1_gate_lock }, 1109 { 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, 0, 0, &leaf1_gate_lock },
1095 { 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, &leaf1_gate_lock }, 1110 { 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, 0, 0, &leaf1_gate_lock },
1096 { 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, &leaf1_gate_lock }, 1111 { 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, CLK_UNIT_NOC_SOCKET, 7, &leaf1_gate_lock },
1097 { 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, &leaf1_gate_lock }, 1112 { 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, CLK_UNIT_NOC_SOCKET, 8, &leaf1_gate_lock },
1098 { 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, &leaf1_gate_lock }, 1113 { 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, CLK_UNIT_NOC_CLOCK, 2, &leaf1_gate_lock },
1099 { 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, &leaf1_gate_lock }, 1114 { 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, 0, 0, &leaf1_gate_lock },
1100 { 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, &leaf1_gate_lock }, 1115 { 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, CLK_UNIT_NOC_SOCKET, 4, &leaf1_gate_lock },
1101 { 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, &leaf1_gate_lock }, 1116 { 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, CLK_UNIT_NOC_SOCKET, 5, &leaf1_gate_lock },
1102 { 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, &leaf1_gate_lock }, 1117 { 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, CLK_UNIT_NOC_SOCKET, 6, &leaf1_gate_lock },
1103 { 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, &leaf1_gate_lock }, 1118 { 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, CLK_UNIT_NOC_SOCKET, 1, &leaf1_gate_lock },
1104 { 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, &leaf1_gate_lock }, 1119 { 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, CLK_UNIT_NOC_SOCKET, 2, &leaf1_gate_lock },
1105 { 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, &leaf1_gate_lock }, 1120 { 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, CLK_UNIT_NOC_SOCKET, 0, &leaf1_gate_lock },
1106 { 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, &leaf1_gate_lock }, 1121 { 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, CLK_UNIT_NOC_CLOCK, 2, &leaf1_gate_lock },
1107 { 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, &leaf1_gate_lock }, 1122 { 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, 0, 0, &leaf1_gate_lock },
1108 { 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, &leaf1_gate_lock }, 1123 { 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, 0, 0, &leaf1_gate_lock },
1109 { 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, &leaf2_gate_lock }, 1124 { 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, CLK_UNIT_NOC_CLOCK, 20, &leaf2_gate_lock },
1110 { 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, &leaf2_gate_lock }, 1125 { 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, 0, 0, &leaf2_gate_lock },
1111 { 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, &leaf2_gate_lock }, 1126 { 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, 0, 0, &leaf2_gate_lock },
1112 { 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, &leaf2_gate_lock }, 1127 { 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, 0, 0, &leaf2_gate_lock },
1113 { 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, &leaf2_gate_lock }, 1128 { 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, 0, 0, &leaf2_gate_lock },
1114 { 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, &leaf2_gate_lock }, 1129 { 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, 0, 0, &leaf2_gate_lock },
1115 { 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, &leaf2_gate_lock }, 1130 { 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, 0, 0, &leaf2_gate_lock },
1116 { 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, &leaf2_gate_lock }, 1131 { 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, 0, 0, &leaf2_gate_lock },
1117 { 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, &leaf2_gate_lock }, 1132 { 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, CLK_UNIT_NOC_CLOCK, 21, &leaf2_gate_lock },
1118 { 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, &leaf2_gate_lock }, 1133 { 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, 0, 0, &leaf2_gate_lock },
1119 { 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, &leaf2_gate_lock }, 1134 { 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, 0, 0, &leaf2_gate_lock },
1120 { 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, &leaf2_gate_lock }, 1135 { 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, 0, 0, &leaf2_gate_lock },
1121 { 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, &leaf2_gate_lock }, 1136 { 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, CLK_UNIT_NOC_CLOCK, 22, &leaf2_gate_lock },
1122 { 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, &leaf2_gate_lock }, 1137 { 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, CLK_UNIT_NOC_CLOCK, 18, &leaf2_gate_lock },
1123 { 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, &leaf2_gate_lock }, 1138 { 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, CLK_UNIT_NOC_CLOCK, 23, &leaf2_gate_lock },
1124 { 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, &leaf2_gate_lock }, 1139 { 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, CLK_UNIT_NOC_CLOCK, 19, &leaf2_gate_lock },
1125 { 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15, &leaf2_gate_lock }, 1140 { 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15, CLK_UNIT_NOC_CLOCK, 17, &leaf2_gate_lock },
1126 { 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, &leaf2_gate_lock }, 1141 { 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, 0, 0, &leaf2_gate_lock },
1127 { 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, &leaf2_gate_lock }, 1142 { 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, 0, 0, &leaf2_gate_lock },
1128 { 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, &leaf2_gate_lock }, 1143 { 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, 0, 0, &leaf2_gate_lock },
1129 { 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, &leaf3_gate_lock }, 1144 { 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, 0, 0, &leaf3_gate_lock },
1130 { 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, &leaf3_gate_lock }, 1145 { 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, CLK_UNIT_NOC_CLOCK, 10, &leaf3_gate_lock },
1131 { 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, &leaf3_gate_lock }, 1146 { 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, CLK_UNIT_NOC_SOCKET, 14, &leaf3_gate_lock },
1132 { 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, &leaf3_gate_lock }, 1147 { 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, CLK_UNIT_NOC_SOCKET, 11, &leaf3_gate_lock },
1133 { 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, &leaf3_gate_lock }, 1148 { 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, CLK_UNIT_NOC_SOCKET, 13, &leaf3_gate_lock },
1134 { 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, &leaf3_gate_lock }, 1149 { 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, CLK_UNIT_NOC_SOCKET, 15, &leaf3_gate_lock },
1135 { 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, &leaf3_gate_lock }, 1150 { 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, CLK_UNIT_NOC_SOCKET, 16, &leaf3_gate_lock },
1136 { 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, &leaf3_gate_lock }, 1151 { 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, CLK_UNIT_NOC_SOCKET, 17, &leaf3_gate_lock },
1137 { 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, &leaf3_gate_lock }, 1152 { 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, CLK_UNIT_NOC_SOCKET, 18, &leaf3_gate_lock },
1138 { 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, &leaf3_gate_lock }, 1153 { 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, CLK_UNIT_NOC_SOCKET, 12, &leaf3_gate_lock },
1139 { 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, &leaf3_gate_lock }, 1154 { 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, 0, 0, &leaf3_gate_lock },
1140 { 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, &leaf3_gate_lock }, 1155 { 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, CLK_UNIT_NOC_CLOCK, 7, &leaf3_gate_lock },
1141 { 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, &leaf3_gate_lock }, 1156 { 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, CLK_UNIT_NOC_CLOCK, 9, &leaf3_gate_lock },
1142 { 99, "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, &leaf3_gate_lock }, 1157 { 99, "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, CLK_UNIT_NOC_CLOCK, 8, &leaf3_gate_lock },
1143 { 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, &leaf3_gate_lock }, 1158 { 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, 0, 0, &leaf3_gate_lock },
1144 { 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, &leaf3_gate_lock }, 1159 { 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, 0, 0, &leaf3_gate_lock },
1145 { 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, &leaf4_gate_lock }, 1160 { 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, CLK_UNIT_NOC_CLOCK, 3, &leaf4_gate_lock },
1146 { 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, &leaf4_gate_lock }, 1161 { 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, CLK_UNIT_NOC_CLOCK, 1, &leaf4_gate_lock },
1147 { 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, &leaf4_gate_lock }, 1162 { 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, CLK_UNIT_NOC_CLOCK, 12, &leaf4_gate_lock },
1148 { 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, &leaf4_gate_lock }, 1163 { 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, CLK_UNIT_NOC_SOCKET, 21, &leaf4_gate_lock },
1149 { 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, &leaf4_gate_lock }, 1164 { 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, CLK_UNIT_NOC_SOCKET, 20, &leaf4_gate_lock },
1150 { 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, &leaf4_gate_lock }, 1165 { 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, CLK_UNIT_NOC_SOCKET, 19, &leaf4_gate_lock },
1151 { 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, &leaf4_gate_lock }, 1166 { 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, 0, 0, &leaf4_gate_lock },
1152 { 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, &leaf4_gate_lock }, 1167 { 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, 0, 0, &leaf4_gate_lock },
1153 { 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, &leaf4_gate_lock }, 1168 { 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, CLK_UNIT_NOC_CLOCK, 13, &leaf4_gate_lock },
1154 { 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, &leaf4_gate_lock }, 1169 { 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, 0, 0, &leaf4_gate_lock },
1155 { 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, &leaf4_gate_lock }, 1170 { 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, CLK_UNIT_NOC_CLOCK, 14, &leaf4_gate_lock },
1156 { 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, &leaf4_gate_lock }, 1171 { 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, CLK_UNIT_NOC_CLOCK, 15, &leaf4_gate_lock },
1157 { 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12, &leaf4_gate_lock }, 1172 { 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12, CLK_UNIT_NOC_CLOCK, 16, &leaf4_gate_lock },
1158 { 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, &leaf4_gate_lock }, 1173 { 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, 0, 0, &leaf4_gate_lock },
1159 { 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, &leaf4_gate_lock }, 1174 { 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, 0, 0, &leaf4_gate_lock },
1160 { 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, &leaf4_gate_lock }, 1175 { 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, 0, 0, &leaf4_gate_lock },
1161 { 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, &leaf5_gate_lock }, 1176 { 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, 0, 0, &leaf5_gate_lock },
1162 { 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, &leaf5_gate_lock }, 1177 { 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, 0, 0, &leaf5_gate_lock },
1163 { 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, &leaf5_gate_lock }, 1178 { 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, 0, 0, &leaf5_gate_lock },
1164 { 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, &leaf5_gate_lock }, 1179 { 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, 0, 0, &leaf5_gate_lock },
1165 { 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, &leaf6_gate_lock }, 1180 { 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, CLK_UNIT_NOC_SOCKET, 9, &leaf6_gate_lock },
1166 { 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, &leaf6_gate_lock }, 1181 { 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, CLK_UNIT_NOC_SOCKET, 10, &leaf6_gate_lock },
1167 { 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, &leaf6_gate_lock }, 1182 { 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, 0, 0, &leaf6_gate_lock },
1168 { 125, "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, &leaf6_gate_lock }, 1183 { 125, "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, 0, 0, &leaf6_gate_lock },
1169 { 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, &leaf7_gate_lock }, 1184 { 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, CLK_UNIT_NOC_CLOCK, 0, &leaf7_gate_lock },
1170 { 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, &leaf7_gate_lock }, 1185 { 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, CLK_UNIT_NOC_CLOCK, 11, &leaf7_gate_lock },
1171 { 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, &leaf7_gate_lock }, 1186 { 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, 0, 0, &leaf7_gate_lock },
1172 { 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, &leaf8_gate_lock }, 1187 { 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, 0, 0, &leaf8_gate_lock },
1173 { 130, "dmac4_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, &leaf8_gate_lock }, 1188 { 130, "dmac4_io", "a7ca_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, 0, 0, &leaf8_gate_lock },
1174 { 131, "uart6_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, &leaf8_gate_lock }, 1189 { 131, "uart6_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, 0, 0, &leaf8_gate_lock },
1175 { 132, "usp3_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, &leaf8_gate_lock }, 1190 { 132, "usp3_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, 0, 0, &leaf8_gate_lock },
1176 { 133, "a7ca_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, &leaf8_gate_lock }, 1191 { 133, "a7ca_io", "noc_btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, 0, 0, &leaf8_gate_lock },
1177 { 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, &leaf8_gate_lock }, 1192 { 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, 0, 0, &leaf8_gate_lock },
1178 { 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, &leaf8_gate_lock }, 1193 { 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, 0, 0, &leaf8_gate_lock },
1179 { 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, &root1_gate_lock }, 1194 { 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, 0, 0, &root1_gate_lock },
1180 { 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, &leaf8_gate_lock }, 1195 { 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, 0, 0, &leaf8_gate_lock },
1181 { 138, "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, &leaf0_gate_lock }, 1196 { 138, "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, 0, 0, &leaf0_gate_lock },
1182 { 139, "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, &leaf0_gate_lock }, 1197 { 139, "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, 0, 0, &leaf0_gate_lock },
1183 { 140, "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, &leaf0_gate_lock }, 1198 { 140, "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, 0, 0, &leaf0_gate_lock },
1184 { 141, "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, &leaf0_gate_lock }, 1199 { 141, "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, 0, 0, &leaf0_gate_lock },
1185}; 1200};
1186 1201
1187static struct clk *atlas7_clks[ARRAY_SIZE(unit_list) + ARRAY_SIZE(mux_list)]; 1202static struct clk *atlas7_clks[ARRAY_SIZE(unit_list) + ARRAY_SIZE(mux_list)];
@@ -1206,20 +1221,44 @@ static int unit_clk_enable(struct clk_hw *hw)
1206 1221
1207 spin_lock_irqsave(clk->lock, flags); 1222 spin_lock_irqsave(clk->lock, flags);
1208 clkc_writel(BIT(clk->bit), reg); 1223 clkc_writel(BIT(clk->bit), reg);
1224 if (clk->type == CLK_UNIT_NOC_CLOCK)
1225 clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_CLR);
1226 else if (clk->type == CLK_UNIT_NOC_SOCKET)
1227 clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_SLVRDY_SET);
1228
1209 spin_unlock_irqrestore(clk->lock, flags); 1229 spin_unlock_irqrestore(clk->lock, flags);
1210 return 0; 1230 return 0;
1211} 1231}
1212 1232
1213static void unit_clk_disable(struct clk_hw *hw) 1233static void unit_clk_disable(struct clk_hw *hw)
1214{ 1234{
1215 u32 reg; 1235 u32 reg;
1236 u32 i = 0;
1216 struct clk_unit *clk = to_unitclk(hw); 1237 struct clk_unit *clk = to_unitclk(hw);
1217 unsigned long flags; 1238 unsigned long flags;
1218 1239
1219 reg = clk->regofs + SIRFSOC_CLKC_ROOT_CLK_EN0_CLR - SIRFSOC_CLKC_ROOT_CLK_EN0_SET; 1240 reg = clk->regofs + SIRFSOC_CLKC_ROOT_CLK_EN0_CLR - SIRFSOC_CLKC_ROOT_CLK_EN0_SET;
1220
1221 spin_lock_irqsave(clk->lock, flags); 1241 spin_lock_irqsave(clk->lock, flags);
1242 if (clk->type == CLK_UNIT_NOC_CLOCK) {
1243 clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_SET);
1244 while (!(clkc_readl(SIRFSOC_NOC_CLK_IDLE_STATUS) &
1245 BIT(clk->idle_bit)) && (i++ < 100)) {
1246 cpu_relax();
1247 udelay(10);
1248 }
1249
1250 if (i == 100) {
1251 pr_err("unit NoC Clock disconnect Error:timeout\n");
1252 /*once timeout, undo idlereq by CLR*/
1253 clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_CLR);
1254 goto err;
1255 }
1256
1257 } else if (clk->type == CLK_UNIT_NOC_SOCKET)
1258 clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_SLVRDY_CLR);
1259
1222 clkc_writel(BIT(clk->bit), reg); 1260 clkc_writel(BIT(clk->bit), reg);
1261err:
1223 spin_unlock_irqrestore(clk->lock, flags); 1262 spin_unlock_irqrestore(clk->lock, flags);
1224} 1263}
1225 1264
@@ -1232,7 +1271,7 @@ static const struct clk_ops unit_clk_ops = {
1232static struct clk * __init 1271static struct clk * __init
1233atlas7_unit_clk_register(struct device *dev, const char *name, 1272atlas7_unit_clk_register(struct device *dev, const char *name,
1234 const char * const parent_name, unsigned long flags, 1273 const char * const parent_name, unsigned long flags,
1235 u32 regofs, u8 bit, spinlock_t *lock) 1274 u32 regofs, u8 bit, u32 type, u8 idle_bit, spinlock_t *lock)
1236{ 1275{
1237 struct clk *clk; 1276 struct clk *clk;
1238 struct clk_unit *unit; 1277 struct clk_unit *unit;
@@ -1251,6 +1290,9 @@ atlas7_unit_clk_register(struct device *dev, const char *name,
1251 unit->hw.init = &init; 1290 unit->hw.init = &init;
1252 unit->regofs = regofs; 1291 unit->regofs = regofs;
1253 unit->bit = bit; 1292 unit->bit = bit;
1293
1294 unit->type = type;
1295 unit->idle_bit = idle_bit;
1254 unit->lock = lock; 1296 unit->lock = lock;
1255 1297
1256 clk = clk_register(dev, &unit->hw); 1298 clk = clk_register(dev, &unit->hw);
@@ -1624,7 +1666,7 @@ static void __init atlas7_clk_init(struct device_node *np)
1624 for (i = 0; i < ARRAY_SIZE(unit_list); i++) { 1666 for (i = 0; i < ARRAY_SIZE(unit_list); i++) {
1625 unit = &unit_list[i]; 1667 unit = &unit_list[i];
1626 atlas7_clks[i] = atlas7_unit_clk_register(NULL, unit->unit_name, unit->parent_name, 1668 atlas7_clks[i] = atlas7_unit_clk_register(NULL, unit->unit_name, unit->parent_name,
1627 unit->flags, unit->regofs, unit->bit, unit->lock); 1669 unit->flags, unit->regofs, unit->bit, unit->type, unit->idle_bit, unit->lock);
1628 BUG_ON(!atlas7_clks[i]); 1670 BUG_ON(!atlas7_clks[i]);
1629 } 1671 }
1630 1672
diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c
index bd355ee33766..24d99594c0b3 100644
--- a/drivers/clk/st/clk-flexgen.c
+++ b/drivers/clk/st/clk-flexgen.c
@@ -268,6 +268,7 @@ static void __init st_of_flexgen_setup(struct device_node *np)
268 int num_parents, i; 268 int num_parents, i;
269 spinlock_t *rlock = NULL; 269 spinlock_t *rlock = NULL;
270 unsigned long flex_flags = 0; 270 unsigned long flex_flags = 0;
271 int ret;
271 272
272 pnode = of_get_parent(np); 273 pnode = of_get_parent(np);
273 if (!pnode) 274 if (!pnode)
@@ -285,13 +286,13 @@ static void __init st_of_flexgen_setup(struct device_node *np)
285 if (!clk_data) 286 if (!clk_data)
286 goto err; 287 goto err;
287 288
288 clk_data->clk_num = of_property_count_strings(np , 289 ret = of_property_count_strings(np, "clock-output-names");
289 "clock-output-names"); 290 if (ret <= 0) {
290 if (clk_data->clk_num <= 0) {
291 pr_err("%s: Failed to get number of output clocks (%d)", 291 pr_err("%s: Failed to get number of output clocks (%d)",
292 __func__, clk_data->clk_num); 292 __func__, clk_data->clk_num);
293 goto err; 293 goto err;
294 } 294 }
295 clk_data->clk_num = ret;
295 296
296 clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), 297 clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *),
297 GFP_KERNEL); 298 GFP_KERNEL);
diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c
index 4f7f6c00b219..5dc5ce217960 100644
--- a/drivers/clk/st/clkgen-mux.c
+++ b/drivers/clk/st/clkgen-mux.c
@@ -17,6 +17,7 @@
17#include <linux/of_address.h> 17#include <linux/of_address.h>
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/clk-provider.h> 19#include <linux/clk-provider.h>
20#include "clkgen.h"
20 21
21static DEFINE_SPINLOCK(clkgena_divmux_lock); 22static DEFINE_SPINLOCK(clkgena_divmux_lock);
22static DEFINE_SPINLOCK(clkgenf_lock); 23static DEFINE_SPINLOCK(clkgenf_lock);
@@ -576,6 +577,7 @@ static struct clkgen_mux_data stih415_a9_mux_data = {
576 .offset = 0, 577 .offset = 0,
577 .shift = 1, 578 .shift = 1,
578 .width = 2, 579 .width = 2,
580 .lock = &clkgen_a9_lock,
579}; 581};
580static struct clkgen_mux_data stih416_a9_mux_data = { 582static struct clkgen_mux_data stih416_a9_mux_data = {
581 .offset = 0, 583 .offset = 0,
@@ -586,6 +588,7 @@ static struct clkgen_mux_data stih407_a9_mux_data = {
586 .offset = 0x1a4, 588 .offset = 0x1a4,
587 .shift = 0, 589 .shift = 0,
588 .width = 2, 590 .width = 2,
591 .lock = &clkgen_a9_lock,
589}; 592};
590 593
591static const struct of_device_id mux_of_match[] = { 594static const struct of_device_id mux_of_match[] = {
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c
index b2a332cf8985..38f6f3a9098e 100644
--- a/drivers/clk/st/clkgen-pll.c
+++ b/drivers/clk/st/clkgen-pll.c
@@ -18,10 +18,12 @@
18#include <linux/of_address.h> 18#include <linux/of_address.h>
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/clk-provider.h> 20#include <linux/clk-provider.h>
21#include <linux/iopoll.h>
21 22
22#include "clkgen.h" 23#include "clkgen.h"
23 24
24static DEFINE_SPINLOCK(clkgena_c32_odf_lock); 25static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
26DEFINE_SPINLOCK(clkgen_a9_lock);
25 27
26/* 28/*
27 * Common PLL configuration register bits for PLL800 and PLL1600 C65 29 * Common PLL configuration register bits for PLL800 and PLL1600 C65
@@ -38,30 +40,46 @@ static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
38#define C32_IDF_MASK (0x7) 40#define C32_IDF_MASK (0x7)
39#define C32_ODF_MASK (0x3f) 41#define C32_ODF_MASK (0x3f)
40#define C32_LDF_MASK (0x7f) 42#define C32_LDF_MASK (0x7f)
43#define C32_CP_MASK (0x1f)
41 44
42#define C32_MAX_ODFS (4) 45#define C32_MAX_ODFS (4)
43 46
47/*
48 * PLL configuration register bits for PLL4600 C28
49 */
50#define C28_NDIV_MASK (0xff)
51#define C28_IDF_MASK (0x7)
52#define C28_ODF_MASK (0x3f)
53
44struct clkgen_pll_data { 54struct clkgen_pll_data {
45 struct clkgen_field pdn_status; 55 struct clkgen_field pdn_status;
56 struct clkgen_field pdn_ctrl;
46 struct clkgen_field locked_status; 57 struct clkgen_field locked_status;
47 struct clkgen_field mdiv; 58 struct clkgen_field mdiv;
48 struct clkgen_field ndiv; 59 struct clkgen_field ndiv;
49 struct clkgen_field pdiv; 60 struct clkgen_field pdiv;
50 struct clkgen_field idf; 61 struct clkgen_field idf;
51 struct clkgen_field ldf; 62 struct clkgen_field ldf;
63 struct clkgen_field cp;
52 unsigned int num_odfs; 64 unsigned int num_odfs;
53 struct clkgen_field odf[C32_MAX_ODFS]; 65 struct clkgen_field odf[C32_MAX_ODFS];
54 struct clkgen_field odf_gate[C32_MAX_ODFS]; 66 struct clkgen_field odf_gate[C32_MAX_ODFS];
67 bool switch2pll_en;
68 struct clkgen_field switch2pll;
69 spinlock_t *lock;
55 const struct clk_ops *ops; 70 const struct clk_ops *ops;
56}; 71};
57 72
58static const struct clk_ops st_pll1600c65_ops; 73static const struct clk_ops st_pll1600c65_ops;
59static const struct clk_ops st_pll800c65_ops; 74static const struct clk_ops st_pll800c65_ops;
60static const struct clk_ops stm_pll3200c32_ops; 75static const struct clk_ops stm_pll3200c32_ops;
76static const struct clk_ops stm_pll3200c32_a9_ops;
61static const struct clk_ops st_pll1200c32_ops; 77static const struct clk_ops st_pll1200c32_ops;
78static const struct clk_ops stm_pll4600c28_ops;
62 79
63static const struct clkgen_pll_data st_pll1600c65_ax = { 80static const struct clkgen_pll_data st_pll1600c65_ax = {
64 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19), 81 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19),
82 .pdn_ctrl = CLKGEN_FIELD(0x10, 0x1, 0),
65 .locked_status = CLKGEN_FIELD(0x0, 0x1, 31), 83 .locked_status = CLKGEN_FIELD(0x0, 0x1, 31),
66 .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK, 0), 84 .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK, 0),
67 .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8), 85 .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8),
@@ -70,6 +88,7 @@ static const struct clkgen_pll_data st_pll1600c65_ax = {
70 88
71static const struct clkgen_pll_data st_pll800c65_ax = { 89static const struct clkgen_pll_data st_pll800c65_ax = {
72 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19), 90 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19),
91 .pdn_ctrl = CLKGEN_FIELD(0xC, 0x1, 1),
73 .locked_status = CLKGEN_FIELD(0x0, 0x1, 31), 92 .locked_status = CLKGEN_FIELD(0x0, 0x1, 31),
74 .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL800_MASK, 0), 93 .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL800_MASK, 0),
75 .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8), 94 .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8),
@@ -79,6 +98,7 @@ static const struct clkgen_pll_data st_pll800c65_ax = {
79 98
80static const struct clkgen_pll_data st_pll3200c32_a1x_0 = { 99static const struct clkgen_pll_data st_pll3200c32_a1x_0 = {
81 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 31), 100 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 31),
101 .pdn_ctrl = CLKGEN_FIELD(0x18, 0x1, 0),
82 .locked_status = CLKGEN_FIELD(0x4, 0x1, 31), 102 .locked_status = CLKGEN_FIELD(0x4, 0x1, 31),
83 .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 0x0), 103 .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 0x0),
84 .idf = CLKGEN_FIELD(0x4, C32_IDF_MASK, 0x0), 104 .idf = CLKGEN_FIELD(0x4, C32_IDF_MASK, 0x0),
@@ -96,6 +116,7 @@ static const struct clkgen_pll_data st_pll3200c32_a1x_0 = {
96 116
97static const struct clkgen_pll_data st_pll3200c32_a1x_1 = { 117static const struct clkgen_pll_data st_pll3200c32_a1x_1 = {
98 .pdn_status = CLKGEN_FIELD(0xC, 0x1, 31), 118 .pdn_status = CLKGEN_FIELD(0xC, 0x1, 31),
119 .pdn_ctrl = CLKGEN_FIELD(0x18, 0x1, 1),
99 .locked_status = CLKGEN_FIELD(0x10, 0x1, 31), 120 .locked_status = CLKGEN_FIELD(0x10, 0x1, 31),
100 .ndiv = CLKGEN_FIELD(0xC, C32_NDIV_MASK, 0x0), 121 .ndiv = CLKGEN_FIELD(0xC, C32_NDIV_MASK, 0x0),
101 .idf = CLKGEN_FIELD(0x10, C32_IDF_MASK, 0x0), 122 .idf = CLKGEN_FIELD(0x10, C32_IDF_MASK, 0x0),
@@ -114,6 +135,7 @@ static const struct clkgen_pll_data st_pll3200c32_a1x_1 = {
114/* 415 specific */ 135/* 415 specific */
115static const struct clkgen_pll_data st_pll3200c32_a9_415 = { 136static const struct clkgen_pll_data st_pll3200c32_a9_415 = {
116 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), 137 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
138 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
117 .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0), 139 .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0),
118 .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 9), 140 .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 9),
119 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 22), 141 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 22),
@@ -125,6 +147,7 @@ static const struct clkgen_pll_data st_pll3200c32_a9_415 = {
125 147
126static const struct clkgen_pll_data st_pll3200c32_ddr_415 = { 148static const struct clkgen_pll_data st_pll3200c32_ddr_415 = {
127 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), 149 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
150 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
128 .locked_status = CLKGEN_FIELD(0x100, 0x1, 0), 151 .locked_status = CLKGEN_FIELD(0x100, 0x1, 0),
129 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), 152 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
130 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), 153 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
@@ -137,7 +160,8 @@ static const struct clkgen_pll_data st_pll3200c32_ddr_415 = {
137}; 160};
138 161
139static const struct clkgen_pll_data st_pll1200c32_gpu_415 = { 162static const struct clkgen_pll_data st_pll1200c32_gpu_415 = {
140 .pdn_status = CLKGEN_FIELD(0x144, 0x1, 3), 163 .pdn_status = CLKGEN_FIELD(0x4, 0x1, 0),
164 .pdn_ctrl = CLKGEN_FIELD(0x4, 0x1, 0),
141 .locked_status = CLKGEN_FIELD(0x168, 0x1, 0), 165 .locked_status = CLKGEN_FIELD(0x168, 0x1, 0),
142 .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3), 166 .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3),
143 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0), 167 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0),
@@ -149,6 +173,7 @@ static const struct clkgen_pll_data st_pll1200c32_gpu_415 = {
149/* 416 specific */ 173/* 416 specific */
150static const struct clkgen_pll_data st_pll3200c32_a9_416 = { 174static const struct clkgen_pll_data st_pll3200c32_a9_416 = {
151 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), 175 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
176 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
152 .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0), 177 .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0),
153 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), 178 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
154 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), 179 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
@@ -160,6 +185,7 @@ static const struct clkgen_pll_data st_pll3200c32_a9_416 = {
160 185
161static const struct clkgen_pll_data st_pll3200c32_ddr_416 = { 186static const struct clkgen_pll_data st_pll3200c32_ddr_416 = {
162 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), 187 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
188 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
163 .locked_status = CLKGEN_FIELD(0x10C, 0x1, 0), 189 .locked_status = CLKGEN_FIELD(0x10C, 0x1, 0),
164 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), 190 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
165 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), 191 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
@@ -173,6 +199,7 @@ static const struct clkgen_pll_data st_pll3200c32_ddr_416 = {
173 199
174static const struct clkgen_pll_data st_pll1200c32_gpu_416 = { 200static const struct clkgen_pll_data st_pll1200c32_gpu_416 = {
175 .pdn_status = CLKGEN_FIELD(0x8E4, 0x1, 3), 201 .pdn_status = CLKGEN_FIELD(0x8E4, 0x1, 3),
202 .pdn_ctrl = CLKGEN_FIELD(0x8E4, 0x1, 3),
176 .locked_status = CLKGEN_FIELD(0x90C, 0x1, 0), 203 .locked_status = CLKGEN_FIELD(0x90C, 0x1, 0),
177 .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3), 204 .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3),
178 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0), 205 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0),
@@ -184,6 +211,7 @@ static const struct clkgen_pll_data st_pll1200c32_gpu_416 = {
184static const struct clkgen_pll_data st_pll3200c32_407_a0 = { 211static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
185 /* 407 A0 */ 212 /* 407 A0 */
186 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8), 213 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8),
214 .pdn_ctrl = CLKGEN_FIELD(0x2a0, 0x1, 8),
187 .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24), 215 .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24),
188 .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16), 216 .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16),
189 .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0), 217 .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0),
@@ -196,6 +224,7 @@ static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
196static const struct clkgen_pll_data st_pll3200c32_cx_0 = { 224static const struct clkgen_pll_data st_pll3200c32_cx_0 = {
197 /* 407 C0 PLL0 */ 225 /* 407 C0 PLL0 */
198 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8), 226 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8),
227 .pdn_ctrl = CLKGEN_FIELD(0x2a0, 0x1, 8),
199 .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24), 228 .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24),
200 .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16), 229 .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16),
201 .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0), 230 .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0),
@@ -208,6 +237,7 @@ static const struct clkgen_pll_data st_pll3200c32_cx_0 = {
208static const struct clkgen_pll_data st_pll3200c32_cx_1 = { 237static const struct clkgen_pll_data st_pll3200c32_cx_1 = {
209 /* 407 C0 PLL1 */ 238 /* 407 C0 PLL1 */
210 .pdn_status = CLKGEN_FIELD(0x2c8, 0x1, 8), 239 .pdn_status = CLKGEN_FIELD(0x2c8, 0x1, 8),
240 .pdn_ctrl = CLKGEN_FIELD(0x2c8, 0x1, 8),
211 .locked_status = CLKGEN_FIELD(0x2c8, 0x1, 24), 241 .locked_status = CLKGEN_FIELD(0x2c8, 0x1, 24),
212 .ndiv = CLKGEN_FIELD(0x2cc, C32_NDIV_MASK, 16), 242 .ndiv = CLKGEN_FIELD(0x2cc, C32_NDIV_MASK, 16),
213 .idf = CLKGEN_FIELD(0x2cc, C32_IDF_MASK, 0x0), 243 .idf = CLKGEN_FIELD(0x2cc, C32_IDF_MASK, 0x0),
@@ -220,13 +250,34 @@ static const struct clkgen_pll_data st_pll3200c32_cx_1 = {
220static const struct clkgen_pll_data st_pll3200c32_407_a9 = { 250static const struct clkgen_pll_data st_pll3200c32_407_a9 = {
221 /* 407 A9 */ 251 /* 407 A9 */
222 .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0), 252 .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0),
253 .pdn_ctrl = CLKGEN_FIELD(0x1a8, 0x1, 0),
223 .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0), 254 .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0),
224 .ndiv = CLKGEN_FIELD(0x1b0, C32_NDIV_MASK, 0), 255 .ndiv = CLKGEN_FIELD(0x1b0, C32_NDIV_MASK, 0),
225 .idf = CLKGEN_FIELD(0x1a8, C32_IDF_MASK, 25), 256 .idf = CLKGEN_FIELD(0x1a8, C32_IDF_MASK, 25),
226 .num_odfs = 1, 257 .num_odfs = 1,
227 .odf = { CLKGEN_FIELD(0x1b0, C32_ODF_MASK, 8) }, 258 .odf = { CLKGEN_FIELD(0x1b0, C32_ODF_MASK, 8) },
228 .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) }, 259 .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) },
229 .ops = &stm_pll3200c32_ops, 260 .switch2pll_en = true,
261 .cp = CLKGEN_FIELD(0x1a8, C32_CP_MASK, 1),
262 .switch2pll = CLKGEN_FIELD(0x1a4, 0x1, 1),
263 .lock = &clkgen_a9_lock,
264 .ops = &stm_pll3200c32_a9_ops,
265};
266
267static struct clkgen_pll_data st_pll4600c28_418_a9 = {
268 /* 418 A9 */
269 .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0),
270 .pdn_ctrl = CLKGEN_FIELD(0x1a8, 0x1, 0),
271 .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0),
272 .ndiv = CLKGEN_FIELD(0x1b0, C28_NDIV_MASK, 0),
273 .idf = CLKGEN_FIELD(0x1a8, C28_IDF_MASK, 25),
274 .num_odfs = 1,
275 .odf = { CLKGEN_FIELD(0x1b0, C28_ODF_MASK, 8) },
276 .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) },
277 .switch2pll_en = true,
278 .switch2pll = CLKGEN_FIELD(0x1a4, 0x1, 1),
279 .lock = &clkgen_a9_lock,
280 .ops = &stm_pll4600c28_ops,
230}; 281};
231 282
232/** 283/**
@@ -252,10 +303,26 @@ struct clkgen_pll {
252 struct clk_hw hw; 303 struct clk_hw hw;
253 struct clkgen_pll_data *data; 304 struct clkgen_pll_data *data;
254 void __iomem *regs_base; 305 void __iomem *regs_base;
306 spinlock_t *lock;
307
308 u32 ndiv;
309 u32 idf;
310 u32 odf;
311 u32 cp;
255}; 312};
256 313
257#define to_clkgen_pll(_hw) container_of(_hw, struct clkgen_pll, hw) 314#define to_clkgen_pll(_hw) container_of(_hw, struct clkgen_pll, hw)
258 315
316struct stm_pll {
317 unsigned long mdiv;
318 unsigned long ndiv;
319 unsigned long pdiv;
320 unsigned long odf;
321 unsigned long idf;
322 unsigned long ldf;
323 unsigned long cp;
324};
325
259static int clkgen_pll_is_locked(struct clk_hw *hw) 326static int clkgen_pll_is_locked(struct clk_hw *hw)
260{ 327{
261 struct clkgen_pll *pll = to_clkgen_pll(hw); 328 struct clkgen_pll *pll = to_clkgen_pll(hw);
@@ -271,6 +338,78 @@ static int clkgen_pll_is_enabled(struct clk_hw *hw)
271 return !poweroff; 338 return !poweroff;
272} 339}
273 340
341static int __clkgen_pll_enable(struct clk_hw *hw)
342{
343 struct clkgen_pll *pll = to_clkgen_pll(hw);
344 void __iomem *base = pll->regs_base;
345 struct clkgen_field *field = &pll->data->locked_status;
346 int ret = 0;
347 u32 reg;
348
349 if (clkgen_pll_is_enabled(hw))
350 return 0;
351
352 CLKGEN_WRITE(pll, pdn_ctrl, 0);
353
354 ret = readl_relaxed_poll_timeout(base + field->offset, reg,
355 !!((reg >> field->shift) & field->mask), 0, 10000);
356
357 if (!ret) {
358 if (pll->data->switch2pll_en)
359 CLKGEN_WRITE(pll, switch2pll, 0);
360
361 pr_debug("%s:%s enabled\n", __clk_get_name(hw->clk), __func__);
362 }
363
364 return ret;
365}
366
367static int clkgen_pll_enable(struct clk_hw *hw)
368{
369 struct clkgen_pll *pll = to_clkgen_pll(hw);
370 unsigned long flags = 0;
371 int ret = 0;
372
373 if (pll->lock)
374 spin_lock_irqsave(pll->lock, flags);
375
376 ret = __clkgen_pll_enable(hw);
377
378 if (pll->lock)
379 spin_unlock_irqrestore(pll->lock, flags);
380
381 return ret;
382}
383
384static void __clkgen_pll_disable(struct clk_hw *hw)
385{
386 struct clkgen_pll *pll = to_clkgen_pll(hw);
387
388 if (!clkgen_pll_is_enabled(hw))
389 return;
390
391 if (pll->data->switch2pll_en)
392 CLKGEN_WRITE(pll, switch2pll, 1);
393
394 CLKGEN_WRITE(pll, pdn_ctrl, 1);
395
396 pr_debug("%s:%s disabled\n", __clk_get_name(hw->clk), __func__);
397}
398
399static void clkgen_pll_disable(struct clk_hw *hw)
400{
401 struct clkgen_pll *pll = to_clkgen_pll(hw);
402 unsigned long flags = 0;
403
404 if (pll->lock)
405 spin_lock_irqsave(pll->lock, flags);
406
407 __clkgen_pll_disable(hw);
408
409 if (pll->lock)
410 spin_unlock_irqrestore(pll->lock, flags);
411}
412
274static unsigned long recalc_stm_pll800c65(struct clk_hw *hw, 413static unsigned long recalc_stm_pll800c65(struct clk_hw *hw,
275 unsigned long parent_rate) 414 unsigned long parent_rate)
276{ 415{
@@ -322,6 +461,67 @@ static unsigned long recalc_stm_pll1600c65(struct clk_hw *hw,
322 return rate; 461 return rate;
323} 462}
324 463
464static int clk_pll3200c32_get_params(unsigned long input, unsigned long output,
465 struct stm_pll *pll)
466{
467 unsigned long i, n;
468 unsigned long deviation = ~0;
469 unsigned long new_freq;
470 long new_deviation;
471 /* Charge pump table: highest ndiv value for cp=6 to 25 */
472 static const unsigned char cp_table[] = {
473 48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
474 128, 136, 144, 152, 160, 168, 176, 184, 192
475 };
476
477 /* Output clock range: 800Mhz to 1600Mhz */
478 if (output < 800000000 || output > 1600000000)
479 return -EINVAL;
480
481 input /= 1000;
482 output /= 1000;
483
484 for (i = 1; i <= 7 && deviation; i++) {
485 n = i * output / (2 * input);
486
487 /* Checks */
488 if (n < 8)
489 continue;
490 if (n > 200)
491 break;
492
493 new_freq = (input * 2 * n) / i;
494
495 new_deviation = abs(new_freq - output);
496
497 if (!new_deviation || new_deviation < deviation) {
498 pll->idf = i;
499 pll->ndiv = n;
500 deviation = new_deviation;
501 }
502 }
503
504 if (deviation == ~0) /* No solution found */
505 return -EINVAL;
506
507 /* Computing recommended charge pump value */
508 for (pll->cp = 6; pll->ndiv > cp_table[pll->cp-6]; (pll->cp)++)
509 ;
510
511 return 0;
512}
513
514static int clk_pll3200c32_get_rate(unsigned long input, struct stm_pll *pll,
515 unsigned long *rate)
516{
517 if (!pll->idf)
518 pll->idf = 1;
519
520 *rate = ((2 * (input / 1000) * pll->ndiv) / pll->idf) * 1000;
521
522 return 0;
523}
524
325static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw, 525static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
326 unsigned long parent_rate) 526 unsigned long parent_rate)
327{ 527{
@@ -344,6 +544,70 @@ static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
344 return rate; 544 return rate;
345} 545}
346 546
547static long round_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate,
548 unsigned long *prate)
549{
550 struct stm_pll params;
551
552 if (!clk_pll3200c32_get_params(*prate, rate, &params))
553 clk_pll3200c32_get_rate(*prate, &params, &rate);
554 else {
555 pr_debug("%s: %s rate %ld Invalid\n", __func__,
556 __clk_get_name(hw->clk), rate);
557 return 0;
558 }
559
560 pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n",
561 __func__, __clk_get_name(hw->clk),
562 rate, (unsigned int)params.ndiv,
563 (unsigned int)params.idf);
564
565 return rate;
566}
567
568static int set_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate,
569 unsigned long parent_rate)
570{
571 struct clkgen_pll *pll = to_clkgen_pll(hw);
572 struct stm_pll params;
573 long hwrate = 0;
574 unsigned long flags = 0;
575
576 if (!rate || !parent_rate)
577 return -EINVAL;
578
579 if (!clk_pll3200c32_get_params(parent_rate, rate, &params))
580 clk_pll3200c32_get_rate(parent_rate, &params, &hwrate);
581
582 pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n",
583 __func__, __clk_get_name(hw->clk),
584 hwrate, (unsigned int)params.ndiv,
585 (unsigned int)params.idf);
586
587 if (!hwrate)
588 return -EINVAL;
589
590 pll->ndiv = params.ndiv;
591 pll->idf = params.idf;
592 pll->cp = params.cp;
593
594 __clkgen_pll_disable(hw);
595
596 if (pll->lock)
597 spin_lock_irqsave(pll->lock, flags);
598
599 CLKGEN_WRITE(pll, ndiv, pll->ndiv);
600 CLKGEN_WRITE(pll, idf, pll->idf);
601 CLKGEN_WRITE(pll, cp, pll->cp);
602
603 if (pll->lock)
604 spin_unlock_irqrestore(pll->lock, flags);
605
606 __clkgen_pll_enable(hw);
607
608 return 0;
609}
610
347static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw, 611static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
348 unsigned long parent_rate) 612 unsigned long parent_rate)
349{ 613{
@@ -371,30 +635,213 @@ static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
371 return rate; 635 return rate;
372} 636}
373 637
638/* PLL output structure
639 * FVCO >> /2 >> FVCOBY2 (no output)
640 * |> Divider (ODF) >> PHI
641 *
642 * FVCOby2 output = (input * 2 * NDIV) / IDF (assuming FRAC_CONTROL==L)
643 *
644 * Rules:
645 * 4Mhz <= INFF input <= 350Mhz
646 * 4Mhz <= INFIN (INFF / IDF) <= 50Mhz
647 * 19.05Mhz <= FVCOby2 output (PHI w ODF=1) <= 3000Mhz
648 * 1 <= i (register/dec value for IDF) <= 7
649 * 8 <= n (register/dec value for NDIV) <= 246
650 */
651
652static int clk_pll4600c28_get_params(unsigned long input, unsigned long output,
653 struct stm_pll *pll)
654{
655
656 unsigned long i, infin, n;
657 unsigned long deviation = ~0;
658 unsigned long new_freq, new_deviation;
659
660 /* Output clock range: 19Mhz to 3000Mhz */
661 if (output < 19000000 || output > 3000000000u)
662 return -EINVAL;
663
664 /* For better jitter, IDF should be smallest and NDIV must be maximum */
665 for (i = 1; i <= 7 && deviation; i++) {
666 /* INFIN checks */
667 infin = input / i;
668 if (infin < 4000000 || infin > 50000000)
669 continue; /* Invalid case */
670
671 n = output / (infin * 2);
672 if (n < 8 || n > 246)
673 continue; /* Invalid case */
674 if (n < 246)
675 n++; /* To work around 'y' when n=x.y */
676
677 for (; n >= 8 && deviation; n--) {
678 new_freq = infin * 2 * n;
679 if (new_freq < output)
680 break; /* Optimization: shorting loop */
681
682 new_deviation = new_freq - output;
683 if (!new_deviation || new_deviation < deviation) {
684 pll->idf = i;
685 pll->ndiv = n;
686 deviation = new_deviation;
687 }
688 }
689 }
690
691 if (deviation == ~0) /* No solution found */
692 return -EINVAL;
693
694 return 0;
695}
696
697static int clk_pll4600c28_get_rate(unsigned long input, struct stm_pll *pll,
698 unsigned long *rate)
699{
700 if (!pll->idf)
701 pll->idf = 1;
702
703 *rate = (input / pll->idf) * 2 * pll->ndiv;
704
705 return 0;
706}
707
708static unsigned long recalc_stm_pll4600c28(struct clk_hw *hw,
709 unsigned long parent_rate)
710{
711 struct clkgen_pll *pll = to_clkgen_pll(hw);
712 struct stm_pll params;
713 unsigned long rate;
714
715 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
716 return 0;
717
718 params.ndiv = CLKGEN_READ(pll, ndiv);
719 params.idf = CLKGEN_READ(pll, idf);
720
721 clk_pll4600c28_get_rate(parent_rate, &params, &rate);
722
723 pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
724
725 return rate;
726}
727
728static long round_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate,
729 unsigned long *prate)
730{
731 struct stm_pll params;
732
733 if (!clk_pll4600c28_get_params(*prate, rate, &params)) {
734 clk_pll4600c28_get_rate(*prate, &params, &rate);
735 } else {
736 pr_debug("%s: %s rate %ld Invalid\n", __func__,
737 __clk_get_name(hw->clk), rate);
738 return 0;
739 }
740
741 pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n",
742 __func__, __clk_get_name(hw->clk),
743 rate, (unsigned int)params.ndiv,
744 (unsigned int)params.idf);
745
746 return rate;
747}
748
749static int set_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate,
750 unsigned long parent_rate)
751{
752 struct clkgen_pll *pll = to_clkgen_pll(hw);
753 struct stm_pll params;
754 long hwrate;
755 unsigned long flags = 0;
756
757 if (!rate || !parent_rate)
758 return -EINVAL;
759
760 if (!clk_pll4600c28_get_params(parent_rate, rate, &params)) {
761 clk_pll4600c28_get_rate(parent_rate, &params, &hwrate);
762 } else {
763 pr_debug("%s: %s rate %ld Invalid\n", __func__,
764 __clk_get_name(hw->clk), rate);
765 return -EINVAL;
766 }
767
768 pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n",
769 __func__, __clk_get_name(hw->clk),
770 hwrate, (unsigned int)params.ndiv,
771 (unsigned int)params.idf);
772
773 if (!hwrate)
774 return -EINVAL;
775
776 pll->ndiv = params.ndiv;
777 pll->idf = params.idf;
778
779 __clkgen_pll_disable(hw);
780
781 if (pll->lock)
782 spin_lock_irqsave(pll->lock, flags);
783
784 CLKGEN_WRITE(pll, ndiv, pll->ndiv);
785 CLKGEN_WRITE(pll, idf, pll->idf);
786
787 if (pll->lock)
788 spin_unlock_irqrestore(pll->lock, flags);
789
790 __clkgen_pll_enable(hw);
791
792 return 0;
793}
794
374static const struct clk_ops st_pll1600c65_ops = { 795static const struct clk_ops st_pll1600c65_ops = {
796 .enable = clkgen_pll_enable,
797 .disable = clkgen_pll_disable,
375 .is_enabled = clkgen_pll_is_enabled, 798 .is_enabled = clkgen_pll_is_enabled,
376 .recalc_rate = recalc_stm_pll1600c65, 799 .recalc_rate = recalc_stm_pll1600c65,
377}; 800};
378 801
379static const struct clk_ops st_pll800c65_ops = { 802static const struct clk_ops st_pll800c65_ops = {
803 .enable = clkgen_pll_enable,
804 .disable = clkgen_pll_disable,
380 .is_enabled = clkgen_pll_is_enabled, 805 .is_enabled = clkgen_pll_is_enabled,
381 .recalc_rate = recalc_stm_pll800c65, 806 .recalc_rate = recalc_stm_pll800c65,
382}; 807};
383 808
384static const struct clk_ops stm_pll3200c32_ops = { 809static const struct clk_ops stm_pll3200c32_ops = {
810 .enable = clkgen_pll_enable,
811 .disable = clkgen_pll_disable,
385 .is_enabled = clkgen_pll_is_enabled, 812 .is_enabled = clkgen_pll_is_enabled,
386 .recalc_rate = recalc_stm_pll3200c32, 813 .recalc_rate = recalc_stm_pll3200c32,
387}; 814};
388 815
816static const struct clk_ops stm_pll3200c32_a9_ops = {
817 .enable = clkgen_pll_enable,
818 .disable = clkgen_pll_disable,
819 .is_enabled = clkgen_pll_is_enabled,
820 .recalc_rate = recalc_stm_pll3200c32,
821 .round_rate = round_rate_stm_pll3200c32,
822 .set_rate = set_rate_stm_pll3200c32,
823};
824
389static const struct clk_ops st_pll1200c32_ops = { 825static const struct clk_ops st_pll1200c32_ops = {
826 .enable = clkgen_pll_enable,
827 .disable = clkgen_pll_disable,
390 .is_enabled = clkgen_pll_is_enabled, 828 .is_enabled = clkgen_pll_is_enabled,
391 .recalc_rate = recalc_stm_pll1200c32, 829 .recalc_rate = recalc_stm_pll1200c32,
392}; 830};
393 831
832static const struct clk_ops stm_pll4600c28_ops = {
833 .enable = clkgen_pll_enable,
834 .disable = clkgen_pll_disable,
835 .is_enabled = clkgen_pll_is_enabled,
836 .recalc_rate = recalc_stm_pll4600c28,
837 .round_rate = round_rate_stm_pll4600c28,
838 .set_rate = set_rate_stm_pll4600c28,
839};
840
394static struct clk * __init clkgen_pll_register(const char *parent_name, 841static struct clk * __init clkgen_pll_register(const char *parent_name,
395 struct clkgen_pll_data *pll_data, 842 struct clkgen_pll_data *pll_data,
396 void __iomem *reg, 843 void __iomem *reg,
397 const char *clk_name) 844 const char *clk_name, spinlock_t *lock)
398{ 845{
399 struct clkgen_pll *pll; 846 struct clkgen_pll *pll;
400 struct clk *clk; 847 struct clk *clk;
@@ -414,6 +861,7 @@ static struct clk * __init clkgen_pll_register(const char *parent_name,
414 pll->data = pll_data; 861 pll->data = pll_data;
415 pll->regs_base = reg; 862 pll->regs_base = reg;
416 pll->hw.init = &init; 863 pll->hw.init = &init;
864 pll->lock = lock;
417 865
418 clk = clk_register(NULL, &pll->hw); 866 clk = clk_register(NULL, &pll->hw);
419 if (IS_ERR(clk)) { 867 if (IS_ERR(clk)) {
@@ -500,7 +948,7 @@ static void __init clkgena_c65_pll_setup(struct device_node *np)
500 */ 948 */
501 clk_data->clks[0] = clkgen_pll_register(parent_name, 949 clk_data->clks[0] = clkgen_pll_register(parent_name,
502 (struct clkgen_pll_data *) &st_pll1600c65_ax, 950 (struct clkgen_pll_data *) &st_pll1600c65_ax,
503 reg + CLKGENAx_PLL0_OFFSET, clk_name); 951 reg + CLKGENAx_PLL0_OFFSET, clk_name, NULL);
504 952
505 if (IS_ERR(clk_data->clks[0])) 953 if (IS_ERR(clk_data->clks[0]))
506 goto err; 954 goto err;
@@ -529,7 +977,7 @@ static void __init clkgena_c65_pll_setup(struct device_node *np)
529 */ 977 */
530 clk_data->clks[2] = clkgen_pll_register(parent_name, 978 clk_data->clks[2] = clkgen_pll_register(parent_name,
531 (struct clkgen_pll_data *) &st_pll800c65_ax, 979 (struct clkgen_pll_data *) &st_pll800c65_ax,
532 reg + CLKGENAx_PLL1_OFFSET, clk_name); 980 reg + CLKGENAx_PLL1_OFFSET, clk_name, NULL);
533 981
534 if (IS_ERR(clk_data->clks[2])) 982 if (IS_ERR(clk_data->clks[2]))
535 goto err; 983 goto err;
@@ -556,7 +1004,7 @@ static struct clk * __init clkgen_odf_register(const char *parent_name,
556 struct clk_gate *gate; 1004 struct clk_gate *gate;
557 struct clk_divider *div; 1005 struct clk_divider *div;
558 1006
559 flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_GATE; 1007 flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT;
560 1008
561 gate = kzalloc(sizeof(*gate), GFP_KERNEL); 1009 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
562 if (!gate) 1010 if (!gate)
@@ -635,6 +1083,10 @@ static const struct of_device_id c32_pll_of_match[] = {
635 .compatible = "st,stih407-plls-c32-a9", 1083 .compatible = "st,stih407-plls-c32-a9",
636 .data = &st_pll3200c32_407_a9, 1084 .data = &st_pll3200c32_407_a9,
637 }, 1085 },
1086 {
1087 .compatible = "st,stih418-plls-c28-a9",
1088 .data = &st_pll4600c28_418_a9,
1089 },
638 {} 1090 {}
639}; 1091};
640 1092
@@ -664,7 +1116,8 @@ static void __init clkgen_c32_pll_setup(struct device_node *np)
664 if (!pll_base) 1116 if (!pll_base)
665 return; 1117 return;
666 1118
667 clk = clkgen_pll_register(parent_name, data, pll_base, np->name); 1119 clk = clkgen_pll_register(parent_name, data, pll_base, np->name,
1120 data->lock);
668 if (IS_ERR(clk)) 1121 if (IS_ERR(clk))
669 return; 1122 return;
670 1123
@@ -753,7 +1206,7 @@ static void __init clkgengpu_c32_pll_setup(struct device_node *np)
753 /* 1206 /*
754 * PLL 1200MHz output 1207 * PLL 1200MHz output
755 */ 1208 */
756 clk = clkgen_pll_register(parent_name, data, reg, clk_name); 1209 clk = clkgen_pll_register(parent_name, data, reg, clk_name, data->lock);
757 1210
758 if (!IS_ERR(clk)) 1211 if (!IS_ERR(clk))
759 of_clk_add_provider(np, of_clk_src_simple_get, clk); 1212 of_clk_add_provider(np, of_clk_src_simple_get, clk);
diff --git a/drivers/clk/st/clkgen.h b/drivers/clk/st/clkgen.h
index 35c863295268..f7ec2d9139d6 100644
--- a/drivers/clk/st/clkgen.h
+++ b/drivers/clk/st/clkgen.h
@@ -9,6 +9,8 @@ Copyright (C) 2014 STMicroelectronics
9#ifndef __CLKGEN_INFO_H 9#ifndef __CLKGEN_INFO_H
10#define __CLKGEN_INFO_H 10#define __CLKGEN_INFO_H
11 11
12extern spinlock_t clkgen_a9_lock;
13
12struct clkgen_field { 14struct clkgen_field {
13 unsigned int offset; 15 unsigned int offset;
14 unsigned int mask; 16 unsigned int mask;
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index f5a35b82cc1a..cb4c299214ce 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -3,7 +3,10 @@
3# 3#
4 4
5obj-y += clk-sunxi.o clk-factors.o 5obj-y += clk-sunxi.o clk-factors.o
6obj-y += clk-a10-codec.o
6obj-y += clk-a10-hosc.o 7obj-y += clk-a10-hosc.o
8obj-y += clk-a10-mod1.o
9obj-y += clk-a10-pll2.o
7obj-y += clk-a20-gmac.o 10obj-y += clk-a20-gmac.o
8obj-y += clk-mod0.o 11obj-y += clk-mod0.o
9obj-y += clk-simple-gates.o 12obj-y += clk-simple-gates.o
diff --git a/drivers/clk/sunxi/clk-a10-codec.c b/drivers/clk/sunxi/clk-a10-codec.c
new file mode 100644
index 000000000000..ac321d6a0df5
--- /dev/null
+++ b/drivers/clk/sunxi/clk-a10-codec.c
@@ -0,0 +1,44 @@
1/*
2 * Copyright 2013 Emilio López
3 *
4 * Emilio López <emilio@elopez.com.ar>
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#include <linux/clk-provider.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20
21#define SUN4I_CODEC_GATE 31
22
23static void __init sun4i_codec_clk_setup(struct device_node *node)
24{
25 struct clk *clk;
26 const char *clk_name = node->name, *parent_name;
27 void __iomem *reg;
28
29 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
30 if (IS_ERR(reg))
31 return;
32
33 of_property_read_string(node, "clock-output-names", &clk_name);
34 parent_name = of_clk_get_parent_name(node, 0);
35
36 clk = clk_register_gate(NULL, clk_name, parent_name,
37 CLK_SET_RATE_PARENT, reg,
38 SUN4I_CODEC_GATE, 0, NULL);
39
40 if (!IS_ERR(clk))
41 of_clk_add_provider(node, of_clk_src_simple_get, clk);
42}
43CLK_OF_DECLARE(sun4i_codec, "allwinner,sun4i-a10-codec-clk",
44 sun4i_codec_clk_setup);
diff --git a/drivers/clk/sunxi/clk-a10-mod1.c b/drivers/clk/sunxi/clk-a10-mod1.c
new file mode 100644
index 000000000000..e9d870de165c
--- /dev/null
+++ b/drivers/clk/sunxi/clk-a10-mod1.c
@@ -0,0 +1,81 @@
1/*
2 * Copyright 2013 Emilio López
3 *
4 * Emilio López <emilio@elopez.com.ar>
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#include <linux/clk-provider.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20#include <linux/slab.h>
21
22static DEFINE_SPINLOCK(mod1_lock);
23
24#define SUN4I_MOD1_ENABLE 31
25#define SUN4I_MOD1_MUX 16
26#define SUN4I_MOD1_MUX_WIDTH 2
27#define SUN4I_MOD1_MAX_PARENTS 4
28
29static void __init sun4i_mod1_clk_setup(struct device_node *node)
30{
31 struct clk *clk;
32 struct clk_mux *mux;
33 struct clk_gate *gate;
34 const char *parents[4];
35 const char *clk_name = node->name;
36 void __iomem *reg;
37 int i;
38
39 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
40 if (IS_ERR(reg))
41 return;
42
43 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
44 if (!mux)
45 goto err_unmap;
46
47 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
48 if (!gate)
49 goto err_free_mux;
50
51 of_property_read_string(node, "clock-output-names", &clk_name);
52 i = of_clk_parent_fill(node, parents, SUN4I_MOD1_MAX_PARENTS);
53
54 gate->reg = reg;
55 gate->bit_idx = SUN4I_MOD1_ENABLE;
56 gate->lock = &mod1_lock;
57 mux->reg = reg;
58 mux->shift = SUN4I_MOD1_MUX;
59 mux->mask = BIT(SUN4I_MOD1_MUX_WIDTH) - 1;
60 mux->lock = &mod1_lock;
61
62 clk = clk_register_composite(NULL, clk_name, parents, i,
63 &mux->hw, &clk_mux_ops,
64 NULL, NULL,
65 &gate->hw, &clk_gate_ops, 0);
66 if (IS_ERR(clk))
67 goto err_free_gate;
68
69 of_clk_add_provider(node, of_clk_src_simple_get, clk);
70
71 return;
72
73err_free_gate:
74 kfree(gate);
75err_free_mux:
76 kfree(mux);
77err_unmap:
78 iounmap(reg);
79}
80CLK_OF_DECLARE(sun4i_mod1, "allwinner,sun4i-a10-mod1-clk",
81 sun4i_mod1_clk_setup);
diff --git a/drivers/clk/sunxi/clk-a10-pll2.c b/drivers/clk/sunxi/clk-a10-pll2.c
new file mode 100644
index 000000000000..5484c31ec568
--- /dev/null
+++ b/drivers/clk/sunxi/clk-a10-pll2.c
@@ -0,0 +1,216 @@
1/*
2 * Copyright 2013 Emilio López
3 * Emilio López <emilio@elopez.com.ar>
4 *
5 * Copyright 2015 Maxime Ripard
6 * Maxime Ripard <maxime.ripard@free-electrons.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/clk-provider.h>
20#include <linux/of.h>
21#include <linux/of_address.h>
22#include <linux/slab.h>
23
24#include <dt-bindings/clock/sun4i-a10-pll2.h>
25
26#define SUN4I_PLL2_ENABLE 31
27
28#define SUN4I_PLL2_PRE_DIV_SHIFT 0
29#define SUN4I_PLL2_PRE_DIV_WIDTH 5
30#define SUN4I_PLL2_PRE_DIV_MASK GENMASK(SUN4I_PLL2_PRE_DIV_WIDTH - 1, 0)
31
32#define SUN4I_PLL2_N_SHIFT 8
33#define SUN4I_PLL2_N_WIDTH 7
34#define SUN4I_PLL2_N_MASK GENMASK(SUN4I_PLL2_N_WIDTH - 1, 0)
35
36#define SUN4I_PLL2_POST_DIV_SHIFT 26
37#define SUN4I_PLL2_POST_DIV_WIDTH 4
38#define SUN4I_PLL2_POST_DIV_MASK GENMASK(SUN4I_PLL2_POST_DIV_WIDTH - 1, 0)
39
40#define SUN4I_PLL2_POST_DIV_VALUE 4
41
42#define SUN4I_PLL2_OUTPUTS 4
43
44struct sun4i_pll2_data {
45 u32 post_div_offset;
46 u32 pre_div_flags;
47};
48
49static DEFINE_SPINLOCK(sun4i_a10_pll2_lock);
50
51static void __init sun4i_pll2_setup(struct device_node *node,
52 struct sun4i_pll2_data *data)
53{
54 const char *clk_name = node->name, *parent;
55 struct clk **clks, *base_clk, *prediv_clk;
56 struct clk_onecell_data *clk_data;
57 struct clk_multiplier *mult;
58 struct clk_gate *gate;
59 void __iomem *reg;
60 u32 val;
61
62 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
63 if (IS_ERR(reg))
64 return;
65
66 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
67 if (!clk_data)
68 goto err_unmap;
69
70 clks = kcalloc(SUN4I_PLL2_OUTPUTS, sizeof(struct clk *), GFP_KERNEL);
71 if (!clks)
72 goto err_free_data;
73
74 parent = of_clk_get_parent_name(node, 0);
75 prediv_clk = clk_register_divider(NULL, "pll2-prediv",
76 parent, 0, reg,
77 SUN4I_PLL2_PRE_DIV_SHIFT,
78 SUN4I_PLL2_PRE_DIV_WIDTH,
79 data->pre_div_flags,
80 &sun4i_a10_pll2_lock);
81 if (!prediv_clk) {
82 pr_err("Couldn't register the prediv clock\n");
83 goto err_free_array;
84 }
85
86 /* Setup the gate part of the PLL2 */
87 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
88 if (!gate)
89 goto err_unregister_prediv;
90
91 gate->reg = reg;
92 gate->bit_idx = SUN4I_PLL2_ENABLE;
93 gate->lock = &sun4i_a10_pll2_lock;
94
95 /* Setup the multiplier part of the PLL2 */
96 mult = kzalloc(sizeof(struct clk_multiplier), GFP_KERNEL);
97 if (!mult)
98 goto err_free_gate;
99
100 mult->reg = reg;
101 mult->shift = SUN4I_PLL2_N_SHIFT;
102 mult->width = 7;
103 mult->flags = CLK_MULTIPLIER_ZERO_BYPASS |
104 CLK_MULTIPLIER_ROUND_CLOSEST;
105 mult->lock = &sun4i_a10_pll2_lock;
106
107 parent = __clk_get_name(prediv_clk);
108 base_clk = clk_register_composite(NULL, "pll2-base",
109 &parent, 1,
110 NULL, NULL,
111 &mult->hw, &clk_multiplier_ops,
112 &gate->hw, &clk_gate_ops,
113 CLK_SET_RATE_PARENT);
114 if (!base_clk) {
115 pr_err("Couldn't register the base multiplier clock\n");
116 goto err_free_multiplier;
117 }
118
119 parent = __clk_get_name(base_clk);
120
121 /*
122 * PLL2-1x
123 *
124 * This is supposed to have a post divider, but we won't need
125 * to use it, we just need to initialise it to 4, and use a
126 * fixed divider.
127 */
128 val = readl(reg);
129 val &= ~(SUN4I_PLL2_POST_DIV_MASK << SUN4I_PLL2_POST_DIV_SHIFT);
130 val |= (SUN4I_PLL2_POST_DIV_VALUE - data->post_div_offset) << SUN4I_PLL2_POST_DIV_SHIFT;
131 writel(val, reg);
132
133 of_property_read_string_index(node, "clock-output-names",
134 SUN4I_A10_PLL2_1X, &clk_name);
135 clks[SUN4I_A10_PLL2_1X] = clk_register_fixed_factor(NULL, clk_name,
136 parent,
137 CLK_SET_RATE_PARENT,
138 1,
139 SUN4I_PLL2_POST_DIV_VALUE);
140 WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_1X]));
141
142 /*
143 * PLL2-2x
144 *
145 * This clock doesn't use the post divider, and really is just
146 * a fixed divider from the PLL2 base clock.
147 */
148 of_property_read_string_index(node, "clock-output-names",
149 SUN4I_A10_PLL2_2X, &clk_name);
150 clks[SUN4I_A10_PLL2_2X] = clk_register_fixed_factor(NULL, clk_name,
151 parent,
152 CLK_SET_RATE_PARENT,
153 1, 2);
154 WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_2X]));
155
156 /* PLL2-4x */
157 of_property_read_string_index(node, "clock-output-names",
158 SUN4I_A10_PLL2_4X, &clk_name);
159 clks[SUN4I_A10_PLL2_4X] = clk_register_fixed_factor(NULL, clk_name,
160 parent,
161 CLK_SET_RATE_PARENT,
162 1, 1);
163 WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_4X]));
164
165 /* PLL2-8x */
166 of_property_read_string_index(node, "clock-output-names",
167 SUN4I_A10_PLL2_8X, &clk_name);
168 clks[SUN4I_A10_PLL2_8X] = clk_register_fixed_factor(NULL, clk_name,
169 parent,
170 CLK_SET_RATE_PARENT,
171 2, 1);
172 WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_8X]));
173
174 clk_data->clks = clks;
175 clk_data->clk_num = SUN4I_PLL2_OUTPUTS;
176 of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
177
178 return;
179
180err_free_multiplier:
181 kfree(mult);
182err_free_gate:
183 kfree(gate);
184err_unregister_prediv:
185 clk_unregister_divider(prediv_clk);
186err_free_array:
187 kfree(clks);
188err_free_data:
189 kfree(clk_data);
190err_unmap:
191 iounmap(reg);
192}
193
194static struct sun4i_pll2_data sun4i_a10_pll2_data = {
195 .pre_div_flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
196};
197
198static void __init sun4i_a10_pll2_setup(struct device_node *node)
199{
200 sun4i_pll2_setup(node, &sun4i_a10_pll2_data);
201}
202
203CLK_OF_DECLARE(sun4i_a10_pll2, "allwinner,sun4i-a10-pll2-clk",
204 sun4i_a10_pll2_setup);
205
206static struct sun4i_pll2_data sun5i_a13_pll2_data = {
207 .post_div_offset = 1,
208};
209
210static void __init sun5i_a13_pll2_setup(struct device_node *node)
211{
212 sun4i_pll2_setup(node, &sun5i_a13_pll2_data);
213}
214
215CLK_OF_DECLARE(sun5i_a13_pll2, "allwinner,sun5i-a13-pll2-clk",
216 sun5i_a13_pll2_setup);
diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c
index 6ce91180da1b..0214c6548afd 100644
--- a/drivers/clk/sunxi/clk-simple-gates.c
+++ b/drivers/clk/sunxi/clk-simple-gates.c
@@ -128,6 +128,8 @@ CLK_OF_DECLARE(sun8i_a23_apb1, "allwinner,sun8i-a23-apb1-gates-clk",
128 sunxi_simple_gates_init); 128 sunxi_simple_gates_init);
129CLK_OF_DECLARE(sun8i_a23_apb2, "allwinner,sun8i-a23-apb2-gates-clk", 129CLK_OF_DECLARE(sun8i_a23_apb2, "allwinner,sun8i-a23-apb2-gates-clk",
130 sunxi_simple_gates_init); 130 sunxi_simple_gates_init);
131CLK_OF_DECLARE(sun8i_a33_ahb1, "allwinner,sun8i-a33-ahb1-gates-clk",
132 sunxi_simple_gates_init);
131CLK_OF_DECLARE(sun9i_a80_ahb0, "allwinner,sun9i-a80-ahb0-gates-clk", 133CLK_OF_DECLARE(sun9i_a80_ahb0, "allwinner,sun9i-a80-ahb0-gates-clk",
132 sunxi_simple_gates_init); 134 sunxi_simple_gates_init);
133CLK_OF_DECLARE(sun9i_a80_ahb1, "allwinner,sun9i-a80-ahb1-gates-clk", 135CLK_OF_DECLARE(sun9i_a80_ahb1, "allwinner,sun9i-a80-ahb1-gates-clk",
diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
index 64f3e46d383c..23d042aabb4f 100644
--- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
+++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
@@ -34,6 +34,7 @@ static const struct of_device_id sun6i_a31_apb0_gates_clk_dt_ids[] = {
34 { .compatible = "allwinner,sun8i-a23-apb0-gates-clk", .data = &sun8i_a23_apb0_gates }, 34 { .compatible = "allwinner,sun8i-a23-apb0-gates-clk", .data = &sun8i_a23_apb0_gates },
35 { /* sentinel */ } 35 { /* sentinel */ }
36}; 36};
37MODULE_DEVICE_TABLE(of, sun6i_a31_apb0_gates_clk_dt_ids);
37 38
38static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) 39static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
39{ 40{
diff --git a/drivers/clk/sunxi/clk-sun6i-apb0.c b/drivers/clk/sunxi/clk-sun6i-apb0.c
index 70763600aeae..e703e1895b76 100644
--- a/drivers/clk/sunxi/clk-sun6i-apb0.c
+++ b/drivers/clk/sunxi/clk-sun6i-apb0.c
@@ -61,6 +61,7 @@ static const struct of_device_id sun6i_a31_apb0_clk_dt_ids[] = {
61 { .compatible = "allwinner,sun6i-a31-apb0-clk" }, 61 { .compatible = "allwinner,sun6i-a31-apb0-clk" },
62 { /* sentinel */ } 62 { /* sentinel */ }
63}; 63};
64MODULE_DEVICE_TABLE(of, sun6i_a31_apb0_clk_dt_ids);
64 65
65static struct platform_driver sun6i_a31_apb0_clk_driver = { 66static struct platform_driver sun6i_a31_apb0_clk_driver = {
66 .driver = { 67 .driver = {
diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c
index 806fd019c05d..20887686bdbe 100644
--- a/drivers/clk/sunxi/clk-sun6i-ar100.c
+++ b/drivers/clk/sunxi/clk-sun6i-ar100.c
@@ -219,6 +219,7 @@ static const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = {
219 { .compatible = "allwinner,sun6i-a31-ar100-clk" }, 219 { .compatible = "allwinner,sun6i-a31-ar100-clk" },
220 { /* sentinel */ } 220 { /* sentinel */ }
221}; 221};
222MODULE_DEVICE_TABLE(of, sun6i_a31_ar100_clk_dt_ids);
222 223
223static struct platform_driver sun6i_a31_ar100_clk_driver = { 224static struct platform_driver sun6i_a31_ar100_clk_driver = {
224 .driver = { 225 .driver = {
diff --git a/drivers/clk/sunxi/clk-sun8i-apb0.c b/drivers/clk/sunxi/clk-sun8i-apb0.c
index 155d0022194f..7ae5d2c2cde1 100644
--- a/drivers/clk/sunxi/clk-sun8i-apb0.c
+++ b/drivers/clk/sunxi/clk-sun8i-apb0.c
@@ -52,6 +52,7 @@ static const struct of_device_id sun8i_a23_apb0_clk_dt_ids[] = {
52 { .compatible = "allwinner,sun8i-a23-apb0-clk" }, 52 { .compatible = "allwinner,sun8i-a23-apb0-clk" },
53 { /* sentinel */ } 53 { /* sentinel */ }
54}; 54};
55MODULE_DEVICE_TABLE(of, sun8i_a23_apb0_clk_dt_ids);
55 56
56static struct platform_driver sun8i_a23_apb0_clk_driver = { 57static struct platform_driver sun8i_a23_apb0_clk_driver = {
57 .driver = { 58 .driver = {
diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c
index 3436a948b796..a9b176139aca 100644
--- a/drivers/clk/sunxi/clk-sun9i-mmc.c
+++ b/drivers/clk/sunxi/clk-sun9i-mmc.c
@@ -204,6 +204,7 @@ static const struct of_device_id sun9i_a80_mmc_config_clk_dt_ids[] = {
204 { .compatible = "allwinner,sun9i-a80-mmc-config-clk" }, 204 { .compatible = "allwinner,sun9i-a80-mmc-config-clk" },
205 { /* sentinel */ } 205 { /* sentinel */ }
206}; 206};
207MODULE_DEVICE_TABLE(of, sun9i_a80_mmc_config_clk_dt_ids);
207 208
208static struct platform_driver sun9i_a80_mmc_config_clk_driver = { 209static struct platform_driver sun9i_a80_mmc_config_clk_driver = {
209 .driver = { 210 .driver = {
diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c
index c4e3a52e225b..86a307b17eb0 100644
--- a/drivers/clk/tegra/clk-dfll.c
+++ b/drivers/clk/tegra/clk-dfll.c
@@ -469,56 +469,6 @@ static unsigned long dfll_scale_dvco_rate(int scale_bits,
469} 469}
470 470
471/* 471/*
472 * Monitor control
473 */
474
475/**
476 * dfll_calc_monitored_rate - convert DFLL_MONITOR_DATA_VAL rate into real freq
477 * @monitor_data: value read from the DFLL_MONITOR_DATA_VAL bitfield
478 * @ref_rate: DFLL reference clock rate
479 *
480 * Convert @monitor_data from DFLL_MONITOR_DATA_VAL units into cycles
481 * per second. Returns the converted value.
482 */
483static u64 dfll_calc_monitored_rate(u32 monitor_data,
484 unsigned long ref_rate)
485{
486 return monitor_data * (ref_rate / REF_CLK_CYC_PER_DVCO_SAMPLE);
487}
488
489/**
490 * dfll_read_monitor_rate - return the DFLL's output rate from internal monitor
491 * @td: DFLL instance
492 *
493 * If the DFLL is enabled, return the last rate reported by the DFLL's
494 * internal monitoring hardware. This works in both open-loop and
495 * closed-loop mode, and takes the output scaler setting into account.
496 * Assumes that the monitor was programmed to monitor frequency before
497 * the sample period started. If the driver believes that the DFLL is
498 * currently uninitialized or disabled, it will return 0, since
499 * otherwise the DFLL monitor data register will return the last
500 * measured rate from when the DFLL was active.
501 */
502static u64 dfll_read_monitor_rate(struct tegra_dfll *td)
503{
504 u32 v, s;
505 u64 pre_scaler_rate, post_scaler_rate;
506
507 if (!dfll_is_running(td))
508 return 0;
509
510 v = dfll_readl(td, DFLL_MONITOR_DATA);
511 v = (v & DFLL_MONITOR_DATA_VAL_MASK) >> DFLL_MONITOR_DATA_VAL_SHIFT;
512 pre_scaler_rate = dfll_calc_monitored_rate(v, td->ref_rate);
513
514 s = dfll_readl(td, DFLL_FREQ_REQ);
515 s = (s & DFLL_FREQ_REQ_SCALE_MASK) >> DFLL_FREQ_REQ_SCALE_SHIFT;
516 post_scaler_rate = dfll_scale_dvco_rate(s, pre_scaler_rate);
517
518 return post_scaler_rate;
519}
520
521/*
522 * DFLL mode switching 472 * DFLL mode switching
523 */ 473 */
524 474
@@ -1006,24 +956,25 @@ static unsigned long dfll_clk_recalc_rate(struct clk_hw *hw,
1006 return td->last_unrounded_rate; 956 return td->last_unrounded_rate;
1007} 957}
1008 958
1009static long dfll_clk_round_rate(struct clk_hw *hw, 959/* Must use determine_rate since it allows for rates exceeding 2^31-1 */
1010 unsigned long rate, 960static int dfll_clk_determine_rate(struct clk_hw *hw,
1011 unsigned long *parent_rate) 961 struct clk_rate_request *clk_req)
1012{ 962{
1013 struct tegra_dfll *td = clk_hw_to_dfll(hw); 963 struct tegra_dfll *td = clk_hw_to_dfll(hw);
1014 struct dfll_rate_req req; 964 struct dfll_rate_req req;
1015 int ret; 965 int ret;
1016 966
1017 ret = dfll_calculate_rate_request(td, &req, rate); 967 ret = dfll_calculate_rate_request(td, &req, clk_req->rate);
1018 if (ret) 968 if (ret)
1019 return ret; 969 return ret;
1020 970
1021 /* 971 /*
1022 * Don't return the rounded rate, since it doesn't really matter as 972 * Don't set the rounded rate, since it doesn't really matter as
1023 * the output rate will be voltage controlled anyway, and cpufreq 973 * the output rate will be voltage controlled anyway, and cpufreq
1024 * freaks out if any rounding happens. 974 * freaks out if any rounding happens.
1025 */ 975 */
1026 return rate; 976
977 return 0;
1027} 978}
1028 979
1029static int dfll_clk_set_rate(struct clk_hw *hw, unsigned long rate, 980static int dfll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -1039,7 +990,7 @@ static const struct clk_ops dfll_clk_ops = {
1039 .enable = dfll_clk_enable, 990 .enable = dfll_clk_enable,
1040 .disable = dfll_clk_disable, 991 .disable = dfll_clk_disable,
1041 .recalc_rate = dfll_clk_recalc_rate, 992 .recalc_rate = dfll_clk_recalc_rate,
1042 .round_rate = dfll_clk_round_rate, 993 .determine_rate = dfll_clk_determine_rate,
1043 .set_rate = dfll_clk_set_rate, 994 .set_rate = dfll_clk_set_rate,
1044}; 995};
1045 996
@@ -1101,6 +1052,55 @@ static void dfll_unregister_clk(struct tegra_dfll *td)
1101 */ 1052 */
1102 1053
1103#ifdef CONFIG_DEBUG_FS 1054#ifdef CONFIG_DEBUG_FS
1055/*
1056 * Monitor control
1057 */
1058
1059/**
1060 * dfll_calc_monitored_rate - convert DFLL_MONITOR_DATA_VAL rate into real freq
1061 * @monitor_data: value read from the DFLL_MONITOR_DATA_VAL bitfield
1062 * @ref_rate: DFLL reference clock rate
1063 *
1064 * Convert @monitor_data from DFLL_MONITOR_DATA_VAL units into cycles
1065 * per second. Returns the converted value.
1066 */
1067static u64 dfll_calc_monitored_rate(u32 monitor_data,
1068 unsigned long ref_rate)
1069{
1070 return monitor_data * (ref_rate / REF_CLK_CYC_PER_DVCO_SAMPLE);
1071}
1072
1073/**
1074 * dfll_read_monitor_rate - return the DFLL's output rate from internal monitor
1075 * @td: DFLL instance
1076 *
1077 * If the DFLL is enabled, return the last rate reported by the DFLL's
1078 * internal monitoring hardware. This works in both open-loop and
1079 * closed-loop mode, and takes the output scaler setting into account.
1080 * Assumes that the monitor was programmed to monitor frequency before
1081 * the sample period started. If the driver believes that the DFLL is
1082 * currently uninitialized or disabled, it will return 0, since
1083 * otherwise the DFLL monitor data register will return the last
1084 * measured rate from when the DFLL was active.
1085 */
1086static u64 dfll_read_monitor_rate(struct tegra_dfll *td)
1087{
1088 u32 v, s;
1089 u64 pre_scaler_rate, post_scaler_rate;
1090
1091 if (!dfll_is_running(td))
1092 return 0;
1093
1094 v = dfll_readl(td, DFLL_MONITOR_DATA);
1095 v = (v & DFLL_MONITOR_DATA_VAL_MASK) >> DFLL_MONITOR_DATA_VAL_SHIFT;
1096 pre_scaler_rate = dfll_calc_monitored_rate(v, td->ref_rate);
1097
1098 s = dfll_readl(td, DFLL_FREQ_REQ);
1099 s = (s & DFLL_FREQ_REQ_SCALE_MASK) >> DFLL_FREQ_REQ_SCALE_SHIFT;
1100 post_scaler_rate = dfll_scale_dvco_rate(s, pre_scaler_rate);
1101
1102 return post_scaler_rate;
1103}
1104 1104
1105static int attr_enable_get(void *data, u64 *val) 1105static int attr_enable_get(void *data, u64 *val)
1106{ 1106{
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c
index 138a94b99b5b..e1fe8f35d45c 100644
--- a/drivers/clk/tegra/clk-emc.c
+++ b/drivers/clk/tegra/clk-emc.c
@@ -491,10 +491,8 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
491 for_each_child_of_node(np, node) { 491 for_each_child_of_node(np, node) {
492 err = of_property_read_u32(node, "nvidia,ram-code", 492 err = of_property_read_u32(node, "nvidia,ram-code",
493 &node_ram_code); 493 &node_ram_code);
494 if (err) { 494 if (err)
495 of_node_put(node);
496 continue; 495 continue;
497 }
498 496
499 /* 497 /*
500 * Store timings for all ram codes as we cannot read the 498 * Store timings for all ram codes as we cannot read the
diff --git a/drivers/clk/tegra/clk-tegra-audio.c b/drivers/clk/tegra/clk-tegra-audio.c
index 11e3ad7ad7a3..e2bfa9b368f6 100644
--- a/drivers/clk/tegra/clk-tegra-audio.c
+++ b/drivers/clk/tegra/clk-tegra-audio.c
@@ -125,18 +125,29 @@ static struct tegra_audio2x_clk_initdata audio2x_clks[] = {
125 125
126void __init tegra_audio_clk_init(void __iomem *clk_base, 126void __init tegra_audio_clk_init(void __iomem *clk_base,
127 void __iomem *pmc_base, struct tegra_clk *tegra_clks, 127 void __iomem *pmc_base, struct tegra_clk *tegra_clks,
128 struct tegra_clk_pll_params *pll_a_params) 128 struct tegra_audio_clk_info *audio_info,
129 unsigned int num_plls)
129{ 130{
130 struct clk *clk; 131 struct clk *clk;
131 struct clk **dt_clk; 132 struct clk **dt_clk;
132 int i; 133 int i;
133 134
134 /* PLLA */ 135 if (!audio_info || num_plls < 1) {
135 dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a, tegra_clks); 136 pr_err("No audio data passed to tegra_audio_clk_init\n");
136 if (dt_clk) { 137 WARN_ON(1);
137 clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, 138 return;
138 pmc_base, 0, pll_a_params, NULL); 139 }
139 *dt_clk = clk; 140
141 for (i = 0; i < num_plls; i++) {
142 struct tegra_audio_clk_info *info = &audio_info[i];
143
144 dt_clk = tegra_lookup_dt_id(info->clk_id, tegra_clks);
145 if (dt_clk) {
146 clk = tegra_clk_register_pll(info->name, info->parent,
147 clk_base, pmc_base, 0, info->pll_params,
148 NULL);
149 *dt_clk = clk;
150 }
140 } 151 }
141 152
142 /* PLLA_OUT0 */ 153 /* PLLA_OUT0 */
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index db5871519bf5..b7d03e9add97 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -933,6 +933,10 @@ static u32 mux_pllm_pllc2_c_c3_pllp_plla_idx[] = {
933 [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, 933 [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6,
934}; 934};
935 935
936static struct tegra_audio_clk_info tegra114_audio_plls[] = {
937 { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
938};
939
936static struct clk **clks; 940static struct clk **clks;
937 941
938static unsigned long osc_freq; 942static unsigned long osc_freq;
@@ -1481,7 +1485,9 @@ static void __init tegra114_clock_init(struct device_node *np)
1481 tegra114_fixed_clk_init(clk_base); 1485 tegra114_fixed_clk_init(clk_base);
1482 tegra114_pll_init(clk_base, pmc_base); 1486 tegra114_pll_init(clk_base, pmc_base);
1483 tegra114_periph_clk_init(clk_base, pmc_base); 1487 tegra114_periph_clk_init(clk_base, pmc_base);
1484 tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, &pll_a_params); 1488 tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks,
1489 tegra114_audio_plls,
1490 ARRAY_SIZE(tegra114_audio_plls));
1485 tegra_pmc_clk_init(pmc_base, tegra114_clks); 1491 tegra_pmc_clk_init(pmc_base, tegra114_clks);
1486 tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks, 1492 tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks,
1487 &pll_x_params); 1493 &pll_x_params);
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 824d75883d2b..87975f7adddc 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1417,6 +1417,10 @@ static struct tegra_clk_init_table tegra132_init_table[] __initdata = {
1417 {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, 1417 {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
1418}; 1418};
1419 1419
1420static struct tegra_audio_clk_info tegra124_audio_plls[] = {
1421 { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
1422};
1423
1420/** 1424/**
1421 * tegra124_clock_apply_init_table - initialize clocks on Tegra124 SoCs 1425 * tegra124_clock_apply_init_table - initialize clocks on Tegra124 SoCs
1422 * 1426 *
@@ -1555,7 +1559,9 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
1555 tegra_fixed_clk_init(tegra124_clks); 1559 tegra_fixed_clk_init(tegra124_clks);
1556 tegra124_pll_init(clk_base, pmc_base); 1560 tegra124_pll_init(clk_base, pmc_base);
1557 tegra124_periph_clk_init(clk_base, pmc_base); 1561 tegra124_periph_clk_init(clk_base, pmc_base);
1558 tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params); 1562 tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks,
1563 tegra124_audio_plls,
1564 ARRAY_SIZE(tegra124_audio_plls));
1559 tegra_pmc_clk_init(pmc_base, tegra124_clks); 1565 tegra_pmc_clk_init(pmc_base, tegra124_clks);
1560 1566
1561 /* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */ 1567 /* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index fad561a5896b..b90db615c29e 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -1405,6 +1405,10 @@ static const struct of_device_id pmc_match[] __initconst = {
1405 {}, 1405 {},
1406}; 1406};
1407 1407
1408static struct tegra_audio_clk_info tegra30_audio_plls[] = {
1409 { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
1410};
1411
1408static void __init tegra30_clock_init(struct device_node *np) 1412static void __init tegra30_clock_init(struct device_node *np)
1409{ 1413{
1410 struct device_node *node; 1414 struct device_node *node;
@@ -1442,7 +1446,9 @@ static void __init tegra30_clock_init(struct device_node *np)
1442 tegra30_pll_init(); 1446 tegra30_pll_init();
1443 tegra30_super_clk_init(); 1447 tegra30_super_clk_init();
1444 tegra30_periph_clk_init(); 1448 tegra30_periph_clk_init();
1445 tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks, &pll_a_params); 1449 tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks,
1450 tegra30_audio_plls,
1451 ARRAY_SIZE(tegra30_audio_plls));
1446 tegra_pmc_clk_init(pmc_base, tegra30_clks); 1452 tegra_pmc_clk_init(pmc_base, tegra30_clks);
1447 1453
1448 tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX); 1454 tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX);
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 0621887e06f7..5d2678914160 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -157,7 +157,7 @@ struct div_nmp {
157}; 157};
158 158
159/** 159/**
160 * struct clk_pll_params - PLL parameters 160 * struct tegra_clk_pll_params - PLL parameters
161 * 161 *
162 * @input_min: Minimum input frequency 162 * @input_min: Minimum input frequency
163 * @input_max: Maximum input frequency 163 * @input_max: Maximum input frequency
@@ -168,9 +168,45 @@ struct div_nmp {
168 * @base_reg: PLL base reg offset 168 * @base_reg: PLL base reg offset
169 * @misc_reg: PLL misc reg offset 169 * @misc_reg: PLL misc reg offset
170 * @lock_reg: PLL lock reg offset 170 * @lock_reg: PLL lock reg offset
171 * @lock_bit_idx: Bit index for PLL lock status 171 * @lock_mask: Bitmask for PLL lock status
172 * @lock_enable_bit_idx: Bit index to enable PLL lock 172 * @lock_enable_bit_idx: Bit index to enable PLL lock
173 * @iddq_reg: PLL IDDQ register offset
174 * @iddq_bit_idx: Bit index to enable PLL IDDQ
175 * @aux_reg: AUX register offset
176 * @dyn_ramp_reg: Dynamic ramp control register offset
177 * @ext_misc_reg: Miscellaneous control register offsets
178 * @pmc_divnm_reg: n, m divider PMC override register offset (PLLM)
179 * @pmc_divp_reg: p divider PMC override register offset (PLLM)
180 * @flags: PLL flags
181 * @stepa_shift: Dynamic ramp step A field shift
182 * @stepb_shift: Dynamic ramp step B field shift
173 * @lock_delay: Delay in us if PLL lock is not used 183 * @lock_delay: Delay in us if PLL lock is not used
184 * @max_p: maximum value for the p divider
185 * @pdiv_tohw: mapping of p divider to register values
186 * @div_nmp: offsets and widths on n, m and p fields
187 * @freq_table: array of frequencies supported by PLL
188 * @fixed_rate: PLL rate if it is fixed
189 *
190 * Flags:
191 * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
192 * PLL locking. If not set it will use lock_delay value to wait.
193 * TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs
194 * to be programmed to change output frequency of the PLL.
195 * TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs
196 * to be programmed to change output frequency of the PLL.
197 * TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs
198 * to be programmed to change output frequency of the PLL.
199 * TEGRA_PLLU - PLLU has inverted post divider. This flags indicated
200 * that it is PLLU and invert post divider value.
201 * TEGRA_PLLM - PLLM has additional override settings in PMC. This
202 * flag indicates that it is PLLM and use override settings.
203 * TEGRA_PLL_FIXED - We are not supposed to change output frequency
204 * of some plls.
205 * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
206 * TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the
207 * base register.
208 * TEGRA_PLL_BYPASS - PLL has bypass bit
209 * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
174 */ 210 */
175struct tegra_clk_pll_params { 211struct tegra_clk_pll_params {
176 unsigned long input_min; 212 unsigned long input_min;
@@ -203,38 +239,26 @@ struct tegra_clk_pll_params {
203 unsigned long fixed_rate; 239 unsigned long fixed_rate;
204}; 240};
205 241
242#define TEGRA_PLL_USE_LOCK BIT(0)
243#define TEGRA_PLL_HAS_CPCON BIT(1)
244#define TEGRA_PLL_SET_LFCON BIT(2)
245#define TEGRA_PLL_SET_DCCON BIT(3)
246#define TEGRA_PLLU BIT(4)
247#define TEGRA_PLLM BIT(5)
248#define TEGRA_PLL_FIXED BIT(6)
249#define TEGRA_PLLE_CONFIGURE BIT(7)
250#define TEGRA_PLL_LOCK_MISC BIT(8)
251#define TEGRA_PLL_BYPASS BIT(9)
252#define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10)
253
206/** 254/**
207 * struct tegra_clk_pll - Tegra PLL clock 255 * struct tegra_clk_pll - Tegra PLL clock
208 * 256 *
209 * @hw: handle between common and hardware-specifix interfaces 257 * @hw: handle between common and hardware-specifix interfaces
210 * @clk_base: address of CAR controller 258 * @clk_base: address of CAR controller
211 * @pmc: address of PMC, required to read override bits 259 * @pmc: address of PMC, required to read override bits
212 * @freq_table: array of frequencies supported by PLL
213 * @params: PLL parameters
214 * @flags: PLL flags
215 * @fixed_rate: PLL rate if it is fixed
216 * @lock: register lock 260 * @lock: register lock
217 * 261 * @params: PLL parameters
218 * Flags:
219 * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
220 * PLL locking. If not set it will use lock_delay value to wait.
221 * TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs
222 * to be programmed to change output frequency of the PLL.
223 * TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs
224 * to be programmed to change output frequency of the PLL.
225 * TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs
226 * to be programmed to change output frequency of the PLL.
227 * TEGRA_PLLU - PLLU has inverted post divider. This flags indicated
228 * that it is PLLU and invert post divider value.
229 * TEGRA_PLLM - PLLM has additional override settings in PMC. This
230 * flag indicates that it is PLLM and use override settings.
231 * TEGRA_PLL_FIXED - We are not supposed to change output frequency
232 * of some plls.
233 * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
234 * TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the
235 * base register.
236 * TEGRA_PLL_BYPASS - PLL has bypass bit
237 * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
238 */ 262 */
239struct tegra_clk_pll { 263struct tegra_clk_pll {
240 struct clk_hw hw; 264 struct clk_hw hw;
@@ -246,17 +270,20 @@ struct tegra_clk_pll {
246 270
247#define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw) 271#define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw)
248 272
249#define TEGRA_PLL_USE_LOCK BIT(0) 273/**
250#define TEGRA_PLL_HAS_CPCON BIT(1) 274 * struct tegra_audio_clk_info - Tegra Audio Clk Information
251#define TEGRA_PLL_SET_LFCON BIT(2) 275 *
252#define TEGRA_PLL_SET_DCCON BIT(3) 276 * @name: name for the audio pll
253#define TEGRA_PLLU BIT(4) 277 * @pll_params: pll_params for audio pll
254#define TEGRA_PLLM BIT(5) 278 * @clk_id: clk_ids for the audio pll
255#define TEGRA_PLL_FIXED BIT(6) 279 * @parent: name of the parent of the audio pll
256#define TEGRA_PLLE_CONFIGURE BIT(7) 280 */
257#define TEGRA_PLL_LOCK_MISC BIT(8) 281struct tegra_audio_clk_info {
258#define TEGRA_PLL_BYPASS BIT(9) 282 char *name;
259#define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10) 283 struct tegra_clk_pll_params *pll_params;
284 int clk_id;
285 char *parent;
286};
260 287
261extern const struct clk_ops tegra_clk_pll_ops; 288extern const struct clk_ops tegra_clk_pll_ops;
262extern const struct clk_ops tegra_clk_plle_ops; 289extern const struct clk_ops tegra_clk_plle_ops;
@@ -610,7 +637,8 @@ void tegra_register_devclks(struct tegra_devclk *dev_clks, int num);
610 637
611void tegra_audio_clk_init(void __iomem *clk_base, 638void tegra_audio_clk_init(void __iomem *clk_base,
612 void __iomem *pmc_base, struct tegra_clk *tegra_clks, 639 void __iomem *pmc_base, struct tegra_clk *tegra_clks,
613 struct tegra_clk_pll_params *pll_params); 640 struct tegra_audio_clk_info *audio_info,
641 unsigned int num_plls);
614 642
615void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base, 643void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base,
616 struct tegra_clk *tegra_clks, 644 struct tegra_clk *tegra_clks,
diff --git a/drivers/clk/tegra/cvb.c b/drivers/clk/tegra/cvb.c
index 0204e0861134..69c74eec3a4b 100644
--- a/drivers/clk/tegra/cvb.c
+++ b/drivers/clk/tegra/cvb.c
@@ -78,13 +78,6 @@ static int build_opp_table(const struct cvb_table *d,
78 if (!table->freq || (table->freq > max_freq)) 78 if (!table->freq || (table->freq > max_freq))
79 break; 79 break;
80 80
81 /*
82 * FIXME after clk_round_rate/clk_determine_rate prototypes
83 * have been updated
84 */
85 if (table->freq & (1<<31))
86 continue;
87
88 dfll_mv = get_cvb_voltage( 81 dfll_mv = get_cvb_voltage(
89 speedo_value, d->speedo_scale, &table->coefficients); 82 speedo_value, d->speedo_scale, &table->coefficients);
90 dfll_mv = round_cvb_voltage(dfll_mv, d->voltage_scale, align); 83 dfll_mv = round_cvb_voltage(dfll_mv, d->voltage_scale, align);
diff --git a/drivers/clk/versatile/Kconfig b/drivers/clk/versatile/Kconfig
index 1530c9352a76..fc50b6264bed 100644
--- a/drivers/clk/versatile/Kconfig
+++ b/drivers/clk/versatile/Kconfig
@@ -1,6 +1,6 @@
1config COMMON_CLK_VERSATILE 1config COMMON_CLK_VERSATILE
2 bool "Clock driver for ARM Reference designs" 2 bool "Clock driver for ARM Reference designs"
3 depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64 3 depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64 || COMPILE_TEST
4 ---help--- 4 ---help---
5 Supports clocking on ARM Reference designs: 5 Supports clocking on ARM Reference designs:
6 - Integrator/AP and Integrator/CP 6 - Integrator/AP and Integrator/CP
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index a3893ea2199d..08c5ee976879 100644
--- a/drivers/clk/versatile/clk-icst.c
+++ b/drivers/clk/versatile/clk-icst.c
@@ -157,8 +157,10 @@ struct clk *icst_clk_register(struct device *dev,
157 icst->lockreg = base + desc->lock_offset; 157 icst->lockreg = base + desc->lock_offset;
158 158
159 clk = clk_register(dev, &icst->hw); 159 clk = clk_register(dev, &icst->hw);
160 if (IS_ERR(clk)) 160 if (IS_ERR(clk)) {
161 kfree(pclone);
161 kfree(icst); 162 kfree(icst);
163 }
162 164
163 return clk; 165 return clk;
164} 166}
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index a0cdbf35dcb1..a5d319e4aae6 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -227,10 +227,6 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
227 if (IS_ERR(d->clk) || !old) 227 if (IS_ERR(d->clk) || !old)
228 goto out; 228 goto out;
229 229
230 /* Not requesting clock rates below 1.8432Mhz */
231 if (baud < 115200)
232 baud = 115200;
233
234 clk_disable_unprepare(d->clk); 230 clk_disable_unprepare(d->clk);
235 rate = clk_round_rate(d->clk, baud * 16); 231 rate = clk_round_rate(d->clk, baud * 16);
236 ret = clk_set_rate(d->clk, rate); 232 ret = clk_set_rate(d->clk, rate);
diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
index 0b4cb999a3f7..ab3ee241d10c 100644
--- a/include/dt-bindings/clock/at91.h
+++ b/include/dt-bindings/clock/at91.h
@@ -18,5 +18,6 @@
18#define AT91_PMC_MOSCSELS 16 /* Main Oscillator Selection */ 18#define AT91_PMC_MOSCSELS 16 /* Main Oscillator Selection */
19#define AT91_PMC_MOSCRCS 17 /* Main On-Chip RC */ 19#define AT91_PMC_MOSCRCS 17 /* Main On-Chip RC */
20#define AT91_PMC_CFDEV 18 /* Clock Failure Detector Event */ 20#define AT91_PMC_CFDEV 18 /* Clock Failure Detector Event */
21#define AT91_PMC_GCKRDY 24 /* Generated Clocks */
21 22
22#endif 23#endif
diff --git a/include/dt-bindings/clock/bcm-ns2.h b/include/dt-bindings/clock/bcm-ns2.h
new file mode 100644
index 000000000000..d99c7a2e70cb
--- /dev/null
+++ b/include/dt-bindings/clock/bcm-ns2.h
@@ -0,0 +1,72 @@
1/*
2 * BSD LICENSE
3 *
4 * Copyright(c) 2015 Broadcom Corporation. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Broadcom Corporation nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef _CLOCK_BCM_NS2_H
34#define _CLOCK_BCM_NS2_H
35
36/* GENPLL SCR clock channel ID */
37#define BCM_NS2_GENPLL_SCR 0
38#define BCM_NS2_GENPLL_SCR_SCR_CLK 1
39#define BCM_NS2_GENPLL_SCR_FS_CLK 2
40#define BCM_NS2_GENPLL_SCR_AUDIO_CLK 3
41#define BCM_NS2_GENPLL_SCR_CH3_UNUSED 4
42#define BCM_NS2_GENPLL_SCR_CH4_UNUSED 5
43#define BCM_NS2_GENPLL_SCR_CH5_UNUSED 6
44
45/* GENPLL SW clock channel ID */
46#define BCM_NS2_GENPLL_SW 0
47#define BCM_NS2_GENPLL_SW_RPE_CLK 1
48#define BCM_NS2_GENPLL_SW_250_CLK 2
49#define BCM_NS2_GENPLL_SW_NIC_CLK 3
50#define BCM_NS2_GENPLL_SW_CHIMP_CLK 4
51#define BCM_NS2_GENPLL_SW_PORT_CLK 5
52#define BCM_NS2_GENPLL_SW_SDIO_CLK 6
53
54/* LCPLL DDR clock channel ID */
55#define BCM_NS2_LCPLL_DDR 0
56#define BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK 1
57#define BCM_NS2_LCPLL_DDR_DDR_CLK 2
58#define BCM_NS2_LCPLL_DDR_CH2_UNUSED 3
59#define BCM_NS2_LCPLL_DDR_CH3_UNUSED 4
60#define BCM_NS2_LCPLL_DDR_CH4_UNUSED 5
61#define BCM_NS2_LCPLL_DDR_CH5_UNUSED 6
62
63/* LCPLL PORTS clock channel ID */
64#define BCM_NS2_LCPLL_PORTS 0
65#define BCM_NS2_LCPLL_PORTS_WAN_CLK 1
66#define BCM_NS2_LCPLL_PORTS_RGMII_CLK 2
67#define BCM_NS2_LCPLL_PORTS_CH2_UNUSED 3
68#define BCM_NS2_LCPLL_PORTS_CH3_UNUSED 4
69#define BCM_NS2_LCPLL_PORTS_CH4_UNUSED 5
70#define BCM_NS2_LCPLL_PORTS_CH5_UNUSED 6
71
72#endif /* _CLOCK_BCM_NS2_H */
diff --git a/include/dt-bindings/clock/bcm-nsp.h b/include/dt-bindings/clock/bcm-nsp.h
new file mode 100644
index 000000000000..ad5827cde782
--- /dev/null
+++ b/include/dt-bindings/clock/bcm-nsp.h
@@ -0,0 +1,51 @@
1/*
2 * BSD LICENSE
3 *
4 * Copyright(c) 2015 Broadcom Corporation. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Broadcom Corporation nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef _CLOCK_BCM_NSP_H
34#define _CLOCK_BCM_NSP_H
35
36/* GENPLL clock channel ID */
37#define BCM_NSP_GENPLL 0
38#define BCM_NSP_GENPLL_PHY_CLK 1
39#define BCM_NSP_GENPLL_ENET_SW_CLK 2
40#define BCM_NSP_GENPLL_USB_PHY_REF_CLK 3
41#define BCM_NSP_GENPLL_IPROCFAST_CLK 4
42#define BCM_NSP_GENPLL_SATA1_CLK 5
43#define BCM_NSP_GENPLL_SATA2_CLK 6
44
45/* LCPLL0 clock channel ID */
46#define BCM_NSP_LCPLL0 0
47#define BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK 1
48#define BCM_NSP_LCPLL0_SDIO_CLK 2
49#define BCM_NSP_LCPLL0_DDR_PHY_CLK 3
50
51#endif /* _CLOCK_BCM_NSP_H */
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
new file mode 100644
index 000000000000..d323efac7edf
--- /dev/null
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2015 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#define BCM2835_PLLA 0
15#define BCM2835_PLLB 1
16#define BCM2835_PLLC 2
17#define BCM2835_PLLD 3
18#define BCM2835_PLLH 4
19
20#define BCM2835_PLLA_CORE 5
21#define BCM2835_PLLA_PER 6
22#define BCM2835_PLLB_ARM 7
23#define BCM2835_PLLC_CORE0 8
24#define BCM2835_PLLC_CORE1 9
25#define BCM2835_PLLC_CORE2 10
26#define BCM2835_PLLC_PER 11
27#define BCM2835_PLLD_CORE 12
28#define BCM2835_PLLD_PER 13
29#define BCM2835_PLLH_RCAL 14
30#define BCM2835_PLLH_AUX 15
31#define BCM2835_PLLH_PIX 16
32
33#define BCM2835_CLOCK_TIMER 17
34#define BCM2835_CLOCK_OTP 18
35#define BCM2835_CLOCK_UART 19
36#define BCM2835_CLOCK_VPU 20
37#define BCM2835_CLOCK_V3D 21
38#define BCM2835_CLOCK_ISP 22
39#define BCM2835_CLOCK_H264 23
40#define BCM2835_CLOCK_VEC 24
41#define BCM2835_CLOCK_HSM 25
42#define BCM2835_CLOCK_SDRAM 26
43#define BCM2835_CLOCK_TSENS 27
44#define BCM2835_CLOCK_EMMC 28
45#define BCM2835_CLOCK_PERI_IMAGE 29
46
47#define BCM2835_CLOCK_COUNT 30
diff --git a/include/dt-bindings/clock/exynos7-clk.h b/include/dt-bindings/clock/exynos7-clk.h
index e33c75a3c09d..10c558611085 100644
--- a/include/dt-bindings/clock/exynos7-clk.h
+++ b/include/dt-bindings/clock/exynos7-clk.h
@@ -21,7 +21,18 @@
21#define ACLK_MSCL_532 8 21#define ACLK_MSCL_532 8
22#define DOUT_SCLK_AUD_PLL 9 22#define DOUT_SCLK_AUD_PLL 9
23#define FOUT_AUD_PLL 10 23#define FOUT_AUD_PLL 10
24#define TOPC_NR_CLK 11 24#define SCLK_AUD_PLL 11
25#define SCLK_MFC_PLL_B 12
26#define SCLK_MFC_PLL_A 13
27#define SCLK_BUS1_PLL_B 14
28#define SCLK_BUS1_PLL_A 15
29#define SCLK_BUS0_PLL_B 16
30#define SCLK_BUS0_PLL_A 17
31#define SCLK_CC_PLL_B 18
32#define SCLK_CC_PLL_A 19
33#define ACLK_CCORE_133 20
34#define ACLK_PERIS_66 21
35#define TOPC_NR_CLK 22
25 36
26/* TOP0 */ 37/* TOP0 */
27#define DOUT_ACLK_PERIC1 1 38#define DOUT_ACLK_PERIC1 1
@@ -38,7 +49,9 @@
38#define CLK_SCLK_SPDIF 12 49#define CLK_SCLK_SPDIF 12
39#define CLK_SCLK_PCM1 13 50#define CLK_SCLK_PCM1 13
40#define CLK_SCLK_I2S1 14 51#define CLK_SCLK_I2S1 14
41#define TOP0_NR_CLK 15 52#define CLK_ACLK_PERIC0_66 15
53#define CLK_ACLK_PERIC1_66 16
54#define TOP0_NR_CLK 17
42 55
43/* TOP1 */ 56/* TOP1 */
44#define DOUT_ACLK_FSYS1_200 1 57#define DOUT_ACLK_FSYS1_200 1
@@ -49,7 +62,16 @@
49#define CLK_SCLK_MMC2 6 62#define CLK_SCLK_MMC2 6
50#define CLK_SCLK_MMC1 7 63#define CLK_SCLK_MMC1 7
51#define CLK_SCLK_MMC0 8 64#define CLK_SCLK_MMC0 8
52#define TOP1_NR_CLK 9 65#define CLK_ACLK_FSYS0_200 9
66#define CLK_ACLK_FSYS1_200 10
67#define CLK_SCLK_PHY_FSYS1 11
68#define CLK_SCLK_PHY_FSYS1_26M 12
69#define MOUT_SCLK_UFSUNIPRO20 13
70#define DOUT_SCLK_UFSUNIPRO20 14
71#define CLK_SCLK_UFSUNIPRO20 15
72#define DOUT_SCLK_PHY_FSYS1 16
73#define DOUT_SCLK_PHY_FSYS1_26M 17
74#define TOP1_NR_CLK 18
53 75
54/* CCORE */ 76/* CCORE */
55#define PCLK_RTC 1 77#define PCLK_RTC 1
@@ -124,7 +146,20 @@
124/* FSYS1 */ 146/* FSYS1 */
125#define ACLK_MMC1 1 147#define ACLK_MMC1 1
126#define ACLK_MMC0 2 148#define ACLK_MMC0 2
127#define FSYS1_NR_CLK 3 149#define PHYCLK_UFS20_TX0_SYMBOL 3
150#define PHYCLK_UFS20_RX0_SYMBOL 4
151#define PHYCLK_UFS20_RX1_SYMBOL 5
152#define ACLK_UFS20_LINK 6
153#define SCLK_UFSUNIPRO20_USER 7
154#define PHYCLK_UFS20_RX1_SYMBOL_USER 8
155#define PHYCLK_UFS20_RX0_SYMBOL_USER 9
156#define PHYCLK_UFS20_TX0_SYMBOL_USER 10
157#define OSCCLK_PHY_CLKOUT_EMBEDDED_COMBO_PHY 11
158#define SCLK_COMBO_PHY_EMBEDDED_26M 12
159#define DOUT_PCLK_FSYS1 13
160#define PCLK_GPIO_FSYS1 14
161#define MOUT_FSYS1_PHYCLK_SEL1 15
162#define FSYS1_NR_CLK 16
128 163
129/* MSCL */ 164/* MSCL */
130#define USERMUX_ACLK_MSCL_532 1 165#define USERMUX_ACLK_MSCL_532 1
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index 8de173ff19f3..77985cc43316 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -254,6 +254,7 @@
254#define IMX6QDL_CLK_CAAM_MEM 241 254#define IMX6QDL_CLK_CAAM_MEM 241
255#define IMX6QDL_CLK_CAAM_ACLK 242 255#define IMX6QDL_CLK_CAAM_ACLK 242
256#define IMX6QDL_CLK_CAAM_IPG 243 256#define IMX6QDL_CLK_CAAM_IPG 243
257#define IMX6QDL_CLK_END 244 257#define IMX6QDL_CLK_SPDIF_GCLK 244
258#define IMX6QDL_CLK_END 245
258 259
259#endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ 260#endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
diff --git a/include/dt-bindings/clock/imx6sl-clock.h b/include/dt-bindings/clock/imx6sl-clock.h
index 9ce4e421096f..e14573e293c5 100644
--- a/include/dt-bindings/clock/imx6sl-clock.h
+++ b/include/dt-bindings/clock/imx6sl-clock.h
@@ -174,6 +174,7 @@
174#define IMX6SL_CLK_SSI1_IPG 161 174#define IMX6SL_CLK_SSI1_IPG 161
175#define IMX6SL_CLK_SSI2_IPG 162 175#define IMX6SL_CLK_SSI2_IPG 162
176#define IMX6SL_CLK_SSI3_IPG 163 176#define IMX6SL_CLK_SSI3_IPG 163
177#define IMX6SL_CLK_END 164 177#define IMX6SL_CLK_SPDIF_GCLK 164
178#define IMX6SL_CLK_END 165
178 179
179#endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */ 180#endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */
diff --git a/include/dt-bindings/clock/imx6sx-clock.h b/include/dt-bindings/clock/imx6sx-clock.h
index 995709119ec5..36f0324902a5 100644
--- a/include/dt-bindings/clock/imx6sx-clock.h
+++ b/include/dt-bindings/clock/imx6sx-clock.h
@@ -274,6 +274,7 @@
274#define IMX6SX_PLL5_BYPASS 261 274#define IMX6SX_PLL5_BYPASS 261
275#define IMX6SX_PLL6_BYPASS 262 275#define IMX6SX_PLL6_BYPASS 262
276#define IMX6SX_PLL7_BYPASS 263 276#define IMX6SX_PLL7_BYPASS 263
277#define IMX6SX_CLK_CLK_END 264 277#define IMX6SX_CLK_SPDIF_GCLK 264
278#define IMX6SX_CLK_CLK_END 265
278 279
279#endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */ 280#endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */
diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h
index 728df28b00d5..a4a7a9ce3457 100644
--- a/include/dt-bindings/clock/imx7d-clock.h
+++ b/include/dt-bindings/clock/imx7d-clock.h
@@ -446,5 +446,6 @@
446#define IMX7D_MU_ROOT_CLK 433 446#define IMX7D_MU_ROOT_CLK 433
447#define IMX7D_SEMA4_HS_ROOT_CLK 434 447#define IMX7D_SEMA4_HS_ROOT_CLK 434
448#define IMX7D_PLL_DRAM_TEST_DIV 435 448#define IMX7D_PLL_DRAM_TEST_DIV 435
449#define IMX7D_CLK_END 436 449#define IMX7D_ADC_ROOT_CLK 436
450#define IMX7D_CLK_END 437
450#endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ 451#endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
index 4ad76ed882ad..7956ba1bc974 100644
--- a/include/dt-bindings/clock/mt8173-clk.h
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -18,7 +18,6 @@
18/* TOPCKGEN */ 18/* TOPCKGEN */
19 19
20#define CLK_TOP_CLKPH_MCK_O 1 20#define CLK_TOP_CLKPH_MCK_O 1
21#define CLK_TOP_DPI 2
22#define CLK_TOP_USB_SYSPLL_125M 3 21#define CLK_TOP_USB_SYSPLL_125M 3
23#define CLK_TOP_HDMITX_DIG_CTS 4 22#define CLK_TOP_HDMITX_DIG_CTS 4
24#define CLK_TOP_ARMCA7PLL_754M 5 23#define CLK_TOP_ARMCA7PLL_754M 5
@@ -154,12 +153,16 @@
154#define CLK_TOP_I2S2_M_SEL 135 153#define CLK_TOP_I2S2_M_SEL 135
155#define CLK_TOP_I2S3_M_SEL 136 154#define CLK_TOP_I2S3_M_SEL 136
156#define CLK_TOP_I2S3_B_SEL 137 155#define CLK_TOP_I2S3_B_SEL 137
157#define CLK_TOP_NR_CLK 138 156#define CLK_TOP_DSI0_DIG 138
157#define CLK_TOP_DSI1_DIG 139
158#define CLK_TOP_LVDS_PXL 140
159#define CLK_TOP_LVDS_CTS 141
160#define CLK_TOP_NR_CLK 142
158 161
159/* APMIXED_SYS */ 162/* APMIXED_SYS */
160 163
161#define CLK_APMIXED_ARMCA15PLL 1 164#define CLK_APMIXED_ARMCA15PLL 1
162#define CLK_APMIXED_ARMCA7PLL 2 165#define CLK_APMIXED_ARMCA7PLL 2
163#define CLK_APMIXED_MAINPLL 3 166#define CLK_APMIXED_MAINPLL 3
164#define CLK_APMIXED_UNIVPLL 4 167#define CLK_APMIXED_UNIVPLL 4
165#define CLK_APMIXED_MMPLL 5 168#define CLK_APMIXED_MMPLL 5
@@ -172,7 +175,8 @@
172#define CLK_APMIXED_APLL2 12 175#define CLK_APMIXED_APLL2 12
173#define CLK_APMIXED_LVDSPLL 13 176#define CLK_APMIXED_LVDSPLL 13
174#define CLK_APMIXED_MSDCPLL2 14 177#define CLK_APMIXED_MSDCPLL2 14
175#define CLK_APMIXED_NR_CLK 15 178#define CLK_APMIXED_REF2USB_TX 15
179#define CLK_APMIXED_NR_CLK 16
176 180
177/* INFRA_SYS */ 181/* INFRA_SYS */
178 182
@@ -187,7 +191,8 @@
187#define CLK_INFRA_CEC 9 191#define CLK_INFRA_CEC 9
188#define CLK_INFRA_PMICSPI 10 192#define CLK_INFRA_PMICSPI 10
189#define CLK_INFRA_PMICWRAP 11 193#define CLK_INFRA_PMICWRAP 11
190#define CLK_INFRA_NR_CLK 12 194#define CLK_INFRA_CLK_13M 12
195#define CLK_INFRA_NR_CLK 13
191 196
192/* PERI_SYS */ 197/* PERI_SYS */
193 198
@@ -232,4 +237,91 @@
232#define CLK_PERI_UART3_SEL 39 237#define CLK_PERI_UART3_SEL 39
233#define CLK_PERI_NR_CLK 40 238#define CLK_PERI_NR_CLK 40
234 239
240/* IMG_SYS */
241
242#define CLK_IMG_LARB2_SMI 1
243#define CLK_IMG_CAM_SMI 2
244#define CLK_IMG_CAM_CAM 3
245#define CLK_IMG_SEN_TG 4
246#define CLK_IMG_SEN_CAM 5
247#define CLK_IMG_CAM_SV 6
248#define CLK_IMG_FD 7
249#define CLK_IMG_NR_CLK 8
250
251/* MM_SYS */
252
253#define CLK_MM_SMI_COMMON 1
254#define CLK_MM_SMI_LARB0 2
255#define CLK_MM_CAM_MDP 3
256#define CLK_MM_MDP_RDMA0 4
257#define CLK_MM_MDP_RDMA1 5
258#define CLK_MM_MDP_RSZ0 6
259#define CLK_MM_MDP_RSZ1 7
260#define CLK_MM_MDP_RSZ2 8
261#define CLK_MM_MDP_TDSHP0 9
262#define CLK_MM_MDP_TDSHP1 10
263#define CLK_MM_MDP_WDMA 11
264#define CLK_MM_MDP_WROT0 12
265#define CLK_MM_MDP_WROT1 13
266#define CLK_MM_FAKE_ENG 14
267#define CLK_MM_MUTEX_32K 15
268#define CLK_MM_DISP_OVL0 16
269#define CLK_MM_DISP_OVL1 17
270#define CLK_MM_DISP_RDMA0 18
271#define CLK_MM_DISP_RDMA1 19
272#define CLK_MM_DISP_RDMA2 20
273#define CLK_MM_DISP_WDMA0 21
274#define CLK_MM_DISP_WDMA1 22
275#define CLK_MM_DISP_COLOR0 23
276#define CLK_MM_DISP_COLOR1 24
277#define CLK_MM_DISP_AAL 25
278#define CLK_MM_DISP_GAMMA 26
279#define CLK_MM_DISP_UFOE 27
280#define CLK_MM_DISP_SPLIT0 28
281#define CLK_MM_DISP_SPLIT1 29
282#define CLK_MM_DISP_MERGE 30
283#define CLK_MM_DISP_OD 31
284#define CLK_MM_DISP_PWM0MM 32
285#define CLK_MM_DISP_PWM026M 33
286#define CLK_MM_DISP_PWM1MM 34
287#define CLK_MM_DISP_PWM126M 35
288#define CLK_MM_DSI0_ENGINE 36
289#define CLK_MM_DSI0_DIGITAL 37
290#define CLK_MM_DSI1_ENGINE 38
291#define CLK_MM_DSI1_DIGITAL 39
292#define CLK_MM_DPI_PIXEL 40
293#define CLK_MM_DPI_ENGINE 41
294#define CLK_MM_DPI1_PIXEL 42
295#define CLK_MM_DPI1_ENGINE 43
296#define CLK_MM_HDMI_PIXEL 44
297#define CLK_MM_HDMI_PLLCK 45
298#define CLK_MM_HDMI_AUDIO 46
299#define CLK_MM_HDMI_SPDIF 47
300#define CLK_MM_LVDS_PIXEL 48
301#define CLK_MM_LVDS_CTS 49
302#define CLK_MM_SMI_LARB4 50
303#define CLK_MM_HDMI_HDCP 51
304#define CLK_MM_HDMI_HDCP24M 52
305#define CLK_MM_NR_CLK 53
306
307/* VDEC_SYS */
308
309#define CLK_VDEC_CKEN 1
310#define CLK_VDEC_LARB_CKEN 2
311#define CLK_VDEC_NR_CLK 3
312
313/* VENC_SYS */
314
315#define CLK_VENC_CKE0 1
316#define CLK_VENC_CKE1 2
317#define CLK_VENC_CKE2 3
318#define CLK_VENC_CKE3 4
319#define CLK_VENC_NR_CLK 5
320
321/* VENCLT_SYS */
322
323#define CLK_VENCLT_CKE0 1
324#define CLK_VENCLT_CKE1 2
325#define CLK_VENCLT_NR_CLK 3
326
235#endif /* _DT_BINDINGS_CLK_MT8173_H */ 327#endif /* _DT_BINDINGS_CLK_MT8173_H */
diff --git a/include/dt-bindings/clock/qcom,gcc-apq8084.h b/include/dt-bindings/clock/qcom,gcc-apq8084.h
index 2c0da566c46a..5aa7ebeae411 100644
--- a/include/dt-bindings/clock/qcom,gcc-apq8084.h
+++ b/include/dt-bindings/clock/qcom,gcc-apq8084.h
@@ -348,4 +348,10 @@
348#define GCC_PCIE_1_PIPE_CLK 331 348#define GCC_PCIE_1_PIPE_CLK 331
349#define GCC_PCIE_1_SLV_AXI_CLK 332 349#define GCC_PCIE_1_SLV_AXI_CLK 332
350 350
351/* gdscs */
352#define USB_HS_HSIC_GDSC 0
353#define PCIE0_GDSC 1
354#define PCIE1_GDSC 2
355#define USB30_GDSC 3
356
351#endif 357#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8916.h b/include/dt-bindings/clock/qcom,gcc-msm8916.h
index e430f644dd6c..257e2fbedd94 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8916.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8916.h
@@ -152,5 +152,35 @@
152#define GCC_VENUS0_AHB_CLK 135 152#define GCC_VENUS0_AHB_CLK 135
153#define GCC_VENUS0_AXI_CLK 136 153#define GCC_VENUS0_AXI_CLK 136
154#define GCC_VENUS0_VCODEC0_CLK 137 154#define GCC_VENUS0_VCODEC0_CLK 137
155#define BIMC_DDR_CLK_SRC 138
156#define GCC_APSS_TCU_CLK 139
157#define GCC_GFX_TCU_CLK 140
158#define BIMC_GPU_CLK_SRC 141
159#define GCC_BIMC_GFX_CLK 142
160#define GCC_BIMC_GPU_CLK 143
161#define ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC 144
162#define ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC 145
163#define ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC 146
164#define ULTAUDIO_XO_CLK_SRC 147
165#define ULTAUDIO_AHBFABRIC_CLK_SRC 148
166#define CODEC_DIGCODEC_CLK_SRC 149
167#define GCC_ULTAUDIO_PCNOC_MPORT_CLK 150
168#define GCC_ULTAUDIO_PCNOC_SWAY_CLK 151
169#define GCC_ULTAUDIO_AVSYNC_XO_CLK 152
170#define GCC_ULTAUDIO_STC_XO_CLK 153
171#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK 154
172#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK 155
173#define GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK 156
174#define GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK 157
175#define GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK 158
176#define GCC_CODEC_DIGCODEC_CLK 159
177
178/* Indexes for GDSCs */
179#define BIMC_GDSC 0
180#define VENUS_GDSC 1
181#define MDSS_GDSC 2
182#define JPEG_GDSC 3
183#define VFE_GDSC 4
184#define OXILI_GDSC 5
155 185
156#endif 186#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8974.h b/include/dt-bindings/clock/qcom,gcc-msm8974.h
index 51e51c860fe6..81d32f639190 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8974.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8974.h
@@ -321,4 +321,7 @@
321#define GCC_SDCC1_CDCCAL_SLEEP_CLK 304 321#define GCC_SDCC1_CDCCAL_SLEEP_CLK 304
322#define GCC_SDCC1_CDCCAL_FF_CLK 305 322#define GCC_SDCC1_CDCCAL_FF_CLK 305
323 323
324/* gdscs */
325#define USB_HS_HSIC_GDSC 0
326
324#endif 327#endif
diff --git a/include/dt-bindings/clock/qcom,mmcc-apq8084.h b/include/dt-bindings/clock/qcom,mmcc-apq8084.h
index d72b5b35f15e..03861e3f498e 100644
--- a/include/dt-bindings/clock/qcom,mmcc-apq8084.h
+++ b/include/dt-bindings/clock/qcom,mmcc-apq8084.h
@@ -180,4 +180,14 @@
180#define VPU_SLEEP_CLK 163 180#define VPU_SLEEP_CLK 163
181#define VPU_VDP_CLK 164 181#define VPU_VDP_CLK 164
182 182
183/* GDSCs */
184#define VENUS0_GDSC 0
185#define VENUS0_CORE0_GDSC 1
186#define VENUS0_CORE1_GDSC 2
187#define MDSS_GDSC 3
188#define CAMSS_JPEG_GDSC 4
189#define CAMSS_VFE_GDSC 5
190#define OXILI_GDSC 6
191#define OXILICX_GDSC 7
192
183#endif 193#endif
diff --git a/include/dt-bindings/clock/qcom,mmcc-msm8974.h b/include/dt-bindings/clock/qcom,mmcc-msm8974.h
index 032ed87ef0f3..28651e54c9ae 100644
--- a/include/dt-bindings/clock/qcom,mmcc-msm8974.h
+++ b/include/dt-bindings/clock/qcom,mmcc-msm8974.h
@@ -158,4 +158,12 @@
158#define SPDM_RM_AXI 141 158#define SPDM_RM_AXI 141
159#define SPDM_RM_OCMEMNOC 142 159#define SPDM_RM_OCMEMNOC 142
160 160
161/* gdscs */
162#define VENUS0_GDSC 0
163#define MDSS_GDSC 1
164#define CAMSS_JPEG_GDSC 2
165#define CAMSS_VFE_GDSC 3
166#define OXILI_GDSC 4
167#define OXILICX_GDSC 5
168
161#endif 169#endif
diff --git a/include/dt-bindings/clock/r8a7795-cpg-mssr.h b/include/dt-bindings/clock/r8a7795-cpg-mssr.h
new file mode 100644
index 000000000000..e864aae0a256
--- /dev/null
+++ b/include/dt-bindings/clock/r8a7795-cpg-mssr.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 2015 Renesas Electronics Corp.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9#ifndef __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__
10#define __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__
11
12#include <dt-bindings/clock/renesas-cpg-mssr.h>
13
14/* r8a7795 CPG Core Clocks */
15#define R8A7795_CLK_Z 0
16#define R8A7795_CLK_Z2 1
17#define R8A7795_CLK_ZR 2
18#define R8A7795_CLK_ZG 3
19#define R8A7795_CLK_ZTR 4
20#define R8A7795_CLK_ZTRD2 5
21#define R8A7795_CLK_ZT 6
22#define R8A7795_CLK_ZX 7
23#define R8A7795_CLK_S0D1 8
24#define R8A7795_CLK_S0D4 9
25#define R8A7795_CLK_S1D1 10
26#define R8A7795_CLK_S1D2 11
27#define R8A7795_CLK_S1D4 12
28#define R8A7795_CLK_S2D1 13
29#define R8A7795_CLK_S2D2 14
30#define R8A7795_CLK_S2D4 15
31#define R8A7795_CLK_S3D1 16
32#define R8A7795_CLK_S3D2 17
33#define R8A7795_CLK_S3D4 18
34#define R8A7795_CLK_LB 19
35#define R8A7795_CLK_CL 20
36#define R8A7795_CLK_ZB3 21
37#define R8A7795_CLK_ZB3D2 22
38#define R8A7795_CLK_CR 23
39#define R8A7795_CLK_CRD2 24
40#define R8A7795_CLK_SD0H 25
41#define R8A7795_CLK_SD0 26
42#define R8A7795_CLK_SD1H 27
43#define R8A7795_CLK_SD1 28
44#define R8A7795_CLK_SD2H 29
45#define R8A7795_CLK_SD2 30
46#define R8A7795_CLK_SD3H 31
47#define R8A7795_CLK_SD3 32
48#define R8A7795_CLK_SSP2 33
49#define R8A7795_CLK_SSP1 34
50#define R8A7795_CLK_SSPRS 35
51#define R8A7795_CLK_RPC 36
52#define R8A7795_CLK_RPCD2 37
53#define R8A7795_CLK_MSO 38
54#define R8A7795_CLK_CANFD 39
55#define R8A7795_CLK_HDMI 40
56#define R8A7795_CLK_CSI0 41
57#define R8A7795_CLK_CSIREF 42
58#define R8A7795_CLK_CP 43
59#define R8A7795_CLK_CPEX 44
60#define R8A7795_CLK_R 45
61#define R8A7795_CLK_OSC 46
62
63#endif /* __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/renesas-cpg-mssr.h b/include/dt-bindings/clock/renesas-cpg-mssr.h
new file mode 100644
index 000000000000..569a3cc33ffb
--- /dev/null
+++ b/include/dt-bindings/clock/renesas-cpg-mssr.h
@@ -0,0 +1,15 @@
1/*
2 * Copyright (C) 2015 Renesas Electronics Corp.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9#ifndef __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__
10#define __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__
11
12#define CPG_CORE 0 /* Core Clock */
13#define CPG_MOD 1 /* Module Clock */
14
15#endif /* __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/sun4i-a10-pll2.h b/include/dt-bindings/clock/sun4i-a10-pll2.h
new file mode 100644
index 000000000000..071c8112d531
--- /dev/null
+++ b/include/dt-bindings/clock/sun4i-a10-pll2.h
@@ -0,0 +1,53 @@
1/*
2 * Copyright 2015 Maxime Ripard
3 *
4 * Maxime Ripard <maxime.ripard@free-electrons.com>
5 *
6 * This file is dual-licensed: you can use it either under the terms
7 * of the GPL or the X11 license, at your option. Note that this dual
8 * licensing only applies to this file, and not this project as a
9 * whole.
10 *
11 * a) This file is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version.
15 *
16 * This file is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * Or, alternatively,
22 *
23 * b) Permission is hereby granted, free of charge, to any person
24 * obtaining a copy of this software and associated documentation
25 * files (the "Software"), to deal in the Software without
26 * restriction, including without limitation the rights to use,
27 * copy, modify, merge, publish, distribute, sublicense, and/or
28 * sell copies of the Software, and to permit persons to whom the
29 * Software is furnished to do so, subject to the following
30 * conditions:
31 *
32 * The above copyright notice and this permission notice shall be
33 * included in all copies or substantial portions of the Software.
34 *
35 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
36 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
37 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
38 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
39 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
40 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
41 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
42 * OTHER DEALINGS IN THE SOFTWARE.
43 */
44
45#ifndef __DT_BINDINGS_CLOCK_SUN4I_A10_PLL2_H_
46#define __DT_BINDINGS_CLOCK_SUN4I_A10_PLL2_H_
47
48#define SUN4I_A10_PLL2_1X 0
49#define SUN4I_A10_PLL2_2X 1
50#define SUN4I_A10_PLL2_4X 2
51#define SUN4I_A10_PLL2_8X 3
52
53#endif /* __DT_BINDINGS_CLOCK_SUN4I_A10_PLL2_H_ */
diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
index d19763439472..56c16aaea112 100644
--- a/include/dt-bindings/clock/vf610-clock.h
+++ b/include/dt-bindings/clock/vf610-clock.h
@@ -194,6 +194,7 @@
194#define VF610_PLL7_BYPASS 181 194#define VF610_PLL7_BYPASS 181
195#define VF610_CLK_SNVS 182 195#define VF610_CLK_SNVS 182
196#define VF610_CLK_DAP 183 196#define VF610_CLK_DAP 183
197#define VF610_CLK_END 184 197#define VF610_CLK_OCOTP 184
198#define VF610_CLK_END 185
198 199
199#endif /* __DT_BINDINGS_CLOCK_VF610_H */ 200#endif /* __DT_BINDINGS_CLOCK_VF610_H */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 3ecc07d0da77..c56988ac63f7 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -500,13 +500,14 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
500 * 500 *
501 * Clock with adjustable fractional divider affecting its output frequency. 501 * Clock with adjustable fractional divider affecting its output frequency.
502 */ 502 */
503
504struct clk_fractional_divider { 503struct clk_fractional_divider {
505 struct clk_hw hw; 504 struct clk_hw hw;
506 void __iomem *reg; 505 void __iomem *reg;
507 u8 mshift; 506 u8 mshift;
507 u8 mwidth;
508 u32 mmask; 508 u32 mmask;
509 u8 nshift; 509 u8 nshift;
510 u8 nwidth;
510 u32 nmask; 511 u32 nmask;
511 u8 flags; 512 u8 flags;
512 spinlock_t *lock; 513 spinlock_t *lock;
@@ -518,6 +519,41 @@ struct clk *clk_register_fractional_divider(struct device *dev,
518 void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth, 519 void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
519 u8 clk_divider_flags, spinlock_t *lock); 520 u8 clk_divider_flags, spinlock_t *lock);
520 521
522/**
523 * struct clk_multiplier - adjustable multiplier clock
524 *
525 * @hw: handle between common and hardware-specific interfaces
526 * @reg: register containing the multiplier
527 * @shift: shift to the multiplier bit field
528 * @width: width of the multiplier bit field
529 * @lock: register lock
530 *
531 * Clock with an adjustable multiplier affecting its output frequency.
532 * Implements .recalc_rate, .set_rate and .round_rate
533 *
534 * Flags:
535 * CLK_MULTIPLIER_ZERO_BYPASS - By default, the multiplier is the value read
536 * from the register, with 0 being a valid value effectively
537 * zeroing the output clock rate. If CLK_MULTIPLIER_ZERO_BYPASS is
538 * set, then a null multiplier will be considered as a bypass,
539 * leaving the parent rate unmodified.
540 * CLK_MULTIPLIER_ROUND_CLOSEST - Makes the best calculated divider to be
541 * rounded to the closest integer instead of the down one.
542 */
543struct clk_multiplier {
544 struct clk_hw hw;
545 void __iomem *reg;
546 u8 shift;
547 u8 width;
548 u8 flags;
549 spinlock_t *lock;
550};
551
552#define CLK_MULTIPLIER_ZERO_BYPASS BIT(0)
553#define CLK_MULTIPLIER_ROUND_CLOSEST BIT(1)
554
555extern const struct clk_ops clk_multiplier_ops;
556
521/*** 557/***
522 * struct clk_composite - aggregate clock of mux, divider and gate clocks 558 * struct clk_composite - aggregate clock of mux, divider and gate clocks
523 * 559 *
@@ -606,7 +642,7 @@ void clk_unregister(struct clk *clk);
606void devm_clk_unregister(struct device *dev, struct clk *clk); 642void devm_clk_unregister(struct device *dev, struct clk *clk);
607 643
608/* helper functions */ 644/* helper functions */
609const char *__clk_get_name(struct clk *clk); 645const char *__clk_get_name(const struct clk *clk);
610const char *clk_hw_get_name(const struct clk_hw *hw); 646const char *clk_hw_get_name(const struct clk_hw *hw);
611struct clk_hw *__clk_get_hw(struct clk *clk); 647struct clk_hw *__clk_get_hw(struct clk *clk);
612unsigned int clk_hw_get_num_parents(const struct clk_hw *hw); 648unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
@@ -618,6 +654,7 @@ unsigned long clk_hw_get_rate(const struct clk_hw *hw);
618unsigned long __clk_get_flags(struct clk *clk); 654unsigned long __clk_get_flags(struct clk *clk);
619unsigned long clk_hw_get_flags(const struct clk_hw *hw); 655unsigned long clk_hw_get_flags(const struct clk_hw *hw);
620bool clk_hw_is_prepared(const struct clk_hw *hw); 656bool clk_hw_is_prepared(const struct clk_hw *hw);
657bool clk_hw_is_enabled(const struct clk_hw *hw);
621bool __clk_is_enabled(struct clk *clk); 658bool __clk_is_enabled(struct clk *clk);
622struct clk *__clk_lookup(const char *name); 659struct clk *__clk_lookup(const char *name);
623int __clk_mux_determine_rate(struct clk_hw *hw, 660int __clk_mux_determine_rate(struct clk_hw *hw,
@@ -690,6 +727,15 @@ static inline struct clk *of_clk_src_onecell_get(
690{ 727{
691 return ERR_PTR(-ENOENT); 728 return ERR_PTR(-ENOENT);
692} 729}
730static inline int of_clk_get_parent_count(struct device_node *np)
731{
732 return 0;
733}
734static inline int of_clk_parent_fill(struct device_node *np,
735 const char **parents, unsigned int size)
736{
737 return 0;
738}
693static inline const char *of_clk_get_parent_name(struct device_node *np, 739static inline const char *of_clk_get_parent_name(struct device_node *np,
694 int index) 740 int index)
695{ 741{
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index 7669f7618f39..1e6932222e11 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -164,6 +164,7 @@ extern void __iomem *at91_pmc_base;
164#define AT91_PMC_MOSCSELS (1 << 16) /* Main Oscillator Selection [some SAM9] */ 164#define AT91_PMC_MOSCSELS (1 << 16) /* Main Oscillator Selection [some SAM9] */
165#define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */ 165#define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */
166#define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */ 166#define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */
167#define AT91_PMC_GCKRDY (1 << 24) /* Generated Clocks */
167#define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */ 168#define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */
168 169
169#define AT91_PMC_PLLICPR 0x80 /* PLL Charge Pump Current Register */ 170#define AT91_PMC_PLLICPR 0x80 /* PLL Charge Pump Current Register */
@@ -182,13 +183,18 @@ extern void __iomem *at91_pmc_base;
182#define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Enable Register 1 */ 183#define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Enable Register 1 */
183 184
184#define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9 and SAMA5] */ 185#define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9 and SAMA5] */
185#define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */ 186#define AT91_PMC_PCR_PID_MASK 0x3f
186#define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */ 187#define AT91_PMC_PCR_GCKCSS_OFFSET 8
187#define AT91_PMC_PCR_DIV(n) ((n) << 16) /* Divisor Value */ 188#define AT91_PMC_PCR_GCKCSS_MASK (0x7 << AT91_PMC_PCR_GCKCSS_OFFSET)
188#define AT91_PMC_PCR_DIV0 0x0 /* Peripheral clock is MCK */ 189#define AT91_PMC_PCR_GCKCSS(n) ((n) << AT91_PMC_PCR_GCKCSS_OFFSET) /* GCK Clock Source Selection */
189#define AT91_PMC_PCR_DIV2 0x1 /* Peripheral clock is MCK/2 */ 190#define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */
190#define AT91_PMC_PCR_DIV4 0x2 /* Peripheral clock is MCK/4 */ 191#define AT91_PMC_PCR_DIV_OFFSET 16
191#define AT91_PMC_PCR_DIV8 0x3 /* Peripheral clock is MCK/8 */ 192#define AT91_PMC_PCR_DIV_MASK (0x3 << AT91_PMC_PCR_DIV_OFFSET)
192#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ 193#define AT91_PMC_PCR_DIV(n) ((n) << AT91_PMC_PCR_DIV_OFFSET) /* Divisor Value */
194#define AT91_PMC_PCR_GCKDIV_OFFSET 20
195#define AT91_PMC_PCR_GCKDIV_MASK (0xff << AT91_PMC_PCR_GCKDIV_OFFSET)
196#define AT91_PMC_PCR_GCKDIV(n) ((n) << AT91_PMC_PCR_GCKDIV_OFFSET) /* Generated Clock Divisor Value */
197#define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */
198#define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */
193 199
194#endif 200#endif