aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Turquette <mturquette@baylibre.com>2015-06-17 16:20:43 -0400
committerMichael Turquette <mturquette@baylibre.com>2015-06-17 16:20:43 -0400
commitb2d8bc21ce68b65d7cbaa5c929aac1630acf69fc (patch)
tree682862a4cf6a3fa701d5c19a95303f10754c8ce7
parentd4a4f75cd8f29cd9464a5a32e9224a91571d6649 (diff)
parent46965688acd0f9599a3c3ecce82109b3b24153a9 (diff)
Merge remote-tracking branch 'clk/clk-next' into clk-next
-rw-r--r--Documentation/clk.txt27
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt23
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt30
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt30
-rw-r--r--Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt23
-rw-r--r--Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt40
-rw-r--r--Documentation/devicetree/bindings/clock/clock-bindings.txt7
-rw-r--r--Documentation/devicetree/bindings/clock/csr,atlas7-car.txt55
-rw-r--r--Documentation/devicetree/bindings/clock/emev2-clock.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/marvell,pxa1928.txt21
-rw-r--r--Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt1
-rw-r--r--Documentation/devicetree/bindings/clock/ti,cdce925.txt42
-rw-r--r--arch/arm/boot/dts/atlas7.dtsi15
-rw-r--r--drivers/clk/Kconfig20
-rw-r--r--drivers/clk/Makefile7
-rw-r--r--drivers/clk/at91/clk-main.c2
-rw-r--r--drivers/clk/at91/clk-master.c2
-rw-r--r--drivers/clk/at91/clk-programmable.c2
-rw-r--r--drivers/clk/at91/clk-slow.c4
-rw-r--r--drivers/clk/at91/clk-smd.c2
-rw-r--r--drivers/clk/at91/clk-usb.c2
-rw-r--r--drivers/clk/at91/pmc.c2
-rw-r--r--drivers/clk/bcm/clk-kona-setup.c4
-rw-r--r--drivers/clk/bcm/clk-kona.c2
-rw-r--r--drivers/clk/bcm/clk-kona.h2
-rw-r--r--drivers/clk/berlin/berlin2-pll.c9
-rw-r--r--drivers/clk/clk-asm9260.c2
-rw-r--r--drivers/clk/clk-axm5516.c2
-rw-r--r--drivers/clk/clk-cdce706.c5
-rw-r--r--drivers/clk/clk-cdce925.c749
-rw-r--r--drivers/clk/clk-composite.c6
-rw-r--r--drivers/clk/clk-conf.c7
-rw-r--r--drivers/clk/clk-divider.c6
-rw-r--r--drivers/clk/clk-fixed-factor.c12
-rw-r--r--drivers/clk/clk-fixed-rate.c6
-rw-r--r--drivers/clk/clk-fractional-divider.c4
-rw-r--r--drivers/clk/clk-gate.c6
-rw-r--r--drivers/clk/clk-gpio-gate.c3
-rw-r--r--drivers/clk/clk-ls1x.c6
-rw-r--r--drivers/clk/clk-max-gen.c2
-rw-r--r--drivers/clk/clk-moxart.c4
-rw-r--r--drivers/clk/clk-mux.c6
-rw-r--r--drivers/clk/clk-si5351.c26
-rw-r--r--drivers/clk/clk-u300.c1
-rw-r--r--drivers/clk/clk-xgene.c22
-rw-r--r--drivers/clk/clk.c1607
-rw-r--r--drivers/clk/hisilicon/Kconfig6
-rw-r--r--drivers/clk/hisilicon/Makefile3
-rw-r--r--drivers/clk/hisilicon/clk-hi3620.c70
-rw-r--r--drivers/clk/hisilicon/clk-hi6220.c284
-rw-r--r--drivers/clk/hisilicon/clk-hix5hd2.c11
-rw-r--r--drivers/clk/hisilicon/clk.c29
-rw-r--r--drivers/clk/hisilicon/clk.h41
-rw-r--r--drivers/clk/hisilicon/clkdivider-hi6220.c156
-rw-r--r--drivers/clk/mediatek/Makefile4
-rw-r--r--drivers/clk/mediatek/clk-gate.c137
-rw-r--r--drivers/clk/mediatek/clk-gate.h49
-rw-r--r--drivers/clk/mediatek/clk-mt8135.c644
-rw-r--r--drivers/clk/mediatek/clk-mt8173.c830
-rw-r--r--drivers/clk/mediatek/clk-mtk.c220
-rw-r--r--drivers/clk/mediatek/clk-mtk.h169
-rw-r--r--drivers/clk/mediatek/clk-pll.c332
-rw-r--r--drivers/clk/mediatek/reset.c97
-rw-r--r--drivers/clk/meson/Makefile6
-rw-r--r--drivers/clk/meson/clk-cpu.c242
-rw-r--r--drivers/clk/meson/clk-pll.c227
-rw-r--r--drivers/clk/meson/clkc.c250
-rw-r--r--drivers/clk/meson/clkc.h187
-rw-r--r--drivers/clk/meson/meson8b-clkc.c196
-rw-r--r--drivers/clk/mmp/Makefile2
-rw-r--r--drivers/clk/mmp/clk-apbc.c2
-rw-r--r--drivers/clk/mmp/clk-apmu.c2
-rw-r--r--drivers/clk/mmp/clk-mmp2.c4
-rw-r--r--drivers/clk/mmp/clk-of-mmp2.c10
-rw-r--r--drivers/clk/mmp/clk-of-pxa168.c8
-rw-r--r--drivers/clk/mmp/clk-of-pxa1928.c265
-rw-r--r--drivers/clk/mmp/clk-of-pxa910.c12
-rw-r--r--drivers/clk/mvebu/armada-370.c1
-rw-r--r--drivers/clk/mxs/clk-imx23.c12
-rw-r--r--drivers/clk/mxs/clk-imx28.c18
-rw-r--r--drivers/clk/mxs/clk.h2
-rw-r--r--drivers/clk/pistachio/clk-pll.c115
-rw-r--r--drivers/clk/pxa/clk-pxa.h4
-rw-r--r--drivers/clk/rockchip/clk-cpu.c2
-rw-r--r--drivers/clk/rockchip/clk-mmc-phase.c2
-rw-r--r--drivers/clk/rockchip/clk-pll.c8
-rw-r--r--drivers/clk/rockchip/clk-rk3188.c2
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c2
-rw-r--r--drivers/clk/rockchip/clk.c8
-rw-r--r--drivers/clk/rockchip/clk.h20
-rw-r--r--drivers/clk/samsung/clk-exynos5260.c100
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c10
-rw-r--r--drivers/clk/samsung/clk-exynos5433.c81
-rw-r--r--drivers/clk/samsung/clk-pll.c4
-rw-r--r--drivers/clk/samsung/clk-s3c2410-dclk.c6
-rw-r--r--drivers/clk/samsung/clk-s5pv210.c88
-rw-r--r--drivers/clk/samsung/clk.c15
-rw-r--r--drivers/clk/samsung/clk.h18
-rw-r--r--drivers/clk/shmobile/clk-emev2.c2
-rw-r--r--drivers/clk/sirf/Makefile2
-rw-r--r--drivers/clk/sirf/clk-atlas7.c1632
-rw-r--r--drivers/clk/sirf/clk-common.c16
-rw-r--r--drivers/clk/socfpga/Makefile1
-rw-r--r--drivers/clk/socfpga/clk-gate-a10.c190
-rw-r--r--drivers/clk/socfpga/clk-gate.c12
-rw-r--r--drivers/clk/socfpga/clk-periph-a10.c138
-rw-r--r--drivers/clk/socfpga/clk-periph.c2
-rw-r--r--drivers/clk/socfpga/clk-pll-a10.c129
-rw-r--r--drivers/clk/socfpga/clk-pll.c7
-rw-r--r--drivers/clk/socfpga/clk.c7
-rw-r--r--drivers/clk/socfpga/clk.h11
-rw-r--r--drivers/clk/st/clk-flexgen.c8
-rw-r--r--drivers/clk/st/clkgen-fsyn.c4
-rw-r--r--drivers/clk/st/clkgen-mux.c16
-rw-r--r--drivers/clk/st/clkgen-pll.c10
-rw-r--r--drivers/clk/ti/clk-dra7-atl.c9
-rw-r--r--drivers/clk/ti/clk.c4
-rw-r--r--drivers/clk/ti/clockdomain.c2
-rw-r--r--drivers/clk/ti/dpll.c2
-rw-r--r--drivers/clk/ti/fapll.c6
-rw-r--r--drivers/clk/ux500/u8500_clk.c7
-rw-r--r--drivers/clk/ux500/u8500_of_clk.c4
-rw-r--r--drivers/clk/versatile/clk-sp810.c4
-rw-r--r--drivers/clk/zynq/clkc.c25
-rw-r--r--include/dt-bindings/clock/hi6220-clock.h173
-rw-r--r--include/dt-bindings/clock/marvell,mmp2.h1
-rw-r--r--include/dt-bindings/clock/marvell,pxa168.h3
-rw-r--r--include/dt-bindings/clock/marvell,pxa1928.h57
-rw-r--r--include/dt-bindings/clock/marvell,pxa910.h4
-rw-r--r--include/dt-bindings/clock/meson8b-clkc.h25
-rw-r--r--include/dt-bindings/clock/mt8135-clk.h194
-rw-r--r--include/dt-bindings/clock/mt8173-clk.h235
-rw-r--r--include/dt-bindings/reset-controller/mt8135-resets.h64
-rw-r--r--include/dt-bindings/reset-controller/mt8173-resets.h63
-rw-r--r--include/linux/clk-provider.h14
135 files changed, 9661 insertions, 1293 deletions
diff --git a/Documentation/clk.txt b/Documentation/clk.txt
index 0e4f90aa1c13..f463bdc37f88 100644
--- a/Documentation/clk.txt
+++ b/Documentation/clk.txt
@@ -230,30 +230,7 @@ clk_register(...)
230 230
231See the basic clock types in drivers/clk/clk-*.c for examples. 231See the basic clock types in drivers/clk/clk-*.c for examples.
232 232
233 Part 5 - static initialization of clock data 233 Part 5 - Disabling clock gating of unused clocks
234
235For platforms with many clocks (often numbering into the hundreds) it
236may be desirable to statically initialize some clock data. This
237presents a problem since the definition of struct clk should be hidden
238from everyone except for the clock core in drivers/clk/clk.c.
239
240To get around this problem struct clk's definition is exposed in
241include/linux/clk-private.h along with some macros for more easily
242initializing instances of the basic clock types. These clocks must
243still be initialized with the common clock framework via a call to
244__clk_init.
245
246clk-private.h must NEVER be included by code which implements struct
247clk_ops callbacks, nor must it be included by any logic which pokes
248around inside of struct clk at run-time. To do so is a layering
249violation.
250
251To better enforce this policy, always follow this simple rule: any
252statically initialized clock data MUST be defined in a separate file
253from the logic that implements its ops. Basically separate the logic
254from the data and all is well.
255
256 Part 6 - Disabling clock gating of unused clocks
257 234
258Sometimes during development it can be useful to be able to bypass the 235Sometimes during development it can be useful to be able to bypass the
259default disabling of unused clocks. For example, if drivers aren't enabling 236default disabling of unused clocks. For example, if drivers aren't enabling
@@ -264,7 +241,7 @@ are sorted out.
264To bypass this disabling, include "clk_ignore_unused" in the bootargs to the 241To bypass this disabling, include "clk_ignore_unused" in the bootargs to the
265kernel. 242kernel.
266 243
267 Part 7 - Locking 244 Part 6 - Locking
268 245
269The common clock framework uses two global locks, the prepare lock and the 246The common clock framework uses two global locks, the prepare lock and the
270enable lock. 247enable lock.
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
new file mode 100644
index 000000000000..936166fbee09
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
@@ -0,0 +1,23 @@
1Mediatek apmixedsys controller
2==============================
3
4The Mediatek apmixedsys controller provides the PLLs to the system.
5
6Required Properties:
7
8- compatible: Should be:
9 - "mediatek,mt8135-apmixedsys"
10 - "mediatek,mt8173-apmixedsys"
11- #clock-cells: Must be 1
12
13The apmixedsys controller uses the common clk binding from
14Documentation/devicetree/bindings/clock/clock-bindings.txt
15The available clocks are defined in dt-bindings/clock/mt*-clk.h.
16
17Example:
18
19apmixedsys: clock-controller@10209000 {
20 compatible = "mediatek,mt8173-apmixedsys";
21 reg = <0 0x10209000 0 0x1000>;
22 #clock-cells = <1>;
23};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
new file mode 100644
index 000000000000..f6cd3e4192ff
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
@@ -0,0 +1,30 @@
1Mediatek infracfg controller
2============================
3
4The Mediatek infracfg controller provides various clocks and reset
5outputs to the system.
6
7Required Properties:
8
9- compatible: Should be:
10 - "mediatek,mt8135-infracfg", "syscon"
11 - "mediatek,mt8173-infracfg", "syscon"
12- #clock-cells: Must be 1
13- #reset-cells: Must be 1
14
15The infracfg controller uses the common clk binding from
16Documentation/devicetree/bindings/clock/clock-bindings.txt
17The available clocks are defined in dt-bindings/clock/mt*-clk.h.
18Also it uses the common reset controller binding from
19Documentation/devicetree/bindings/reset/reset.txt.
20The available reset outputs are defined in
21dt-bindings/reset-controller/mt*-resets.h
22
23Example:
24
25infracfg: power-controller@10001000 {
26 compatible = "mediatek,mt8173-infracfg", "syscon";
27 reg = <0 0x10001000 0 0x1000>;
28 #clock-cells = <1>;
29 #reset-cells = <1>;
30};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
new file mode 100644
index 000000000000..f25b85499a6f
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
@@ -0,0 +1,30 @@
1Mediatek pericfg controller
2===========================
3
4The Mediatek pericfg controller provides various clocks and reset
5outputs to the system.
6
7Required Properties:
8
9- compatible: Should be:
10 - "mediatek,mt8135-pericfg", "syscon"
11 - "mediatek,mt8173-pericfg", "syscon"
12- #clock-cells: Must be 1
13- #reset-cells: Must be 1
14
15The pericfg controller uses the common clk binding from
16Documentation/devicetree/bindings/clock/clock-bindings.txt
17The available clocks are defined in dt-bindings/clock/mt*-clk.h.
18Also it uses the common reset controller binding from
19Documentation/devicetree/bindings/reset/reset.txt.
20The available reset outputs are defined in
21dt-bindings/reset-controller/mt*-resets.h
22
23Example:
24
25pericfg: power-controller@10003000 {
26 compatible = "mediatek,mt8173-pericfg", "syscon";
27 reg = <0 0x10003000 0 0x1000>;
28 #clock-cells = <1>;
29 #reset-cells = <1>;
30};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
new file mode 100644
index 000000000000..f9e917994ced
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
@@ -0,0 +1,23 @@
1Mediatek topckgen controller
2============================
3
4The Mediatek topckgen controller provides various clocks to the system.
5
6Required Properties:
7
8- compatible: Should be:
9 - "mediatek,mt8135-topckgen"
10 - "mediatek,mt8173-topckgen"
11- #clock-cells: Must be 1
12
13The topckgen controller uses the common clk binding from
14Documentation/devicetree/bindings/clock/clock-bindings.txt
15The available clocks are defined in dt-bindings/clock/mt*-clk.h.
16
17Example:
18
19topckgen: power-controller@10000000 {
20 compatible = "mediatek,mt8173-topckgen";
21 reg = <0 0x10000000 0 0x1000>;
22 #clock-cells = <1>;
23};
diff --git a/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
new file mode 100644
index 000000000000..2b7b3fa588d7
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
@@ -0,0 +1,40 @@
1* Amlogic Meson8b Clock and Reset Unit
2
3The Amlogic Meson8b clock controller generates and supplies clock to various
4controllers within the SoC.
5
6Required Properties:
7
8- compatible: should be "amlogic,meson8b-clkc"
9- reg: it must be composed by two tuples:
10 0) physical base address of the xtal register and length of memory
11 mapped region.
12 1) physical base address of the clock controller and length of memory
13 mapped region.
14
15- #clock-cells: should be 1.
16
17Each clock is assigned an identifier and client nodes can use this identifier
18to specify the clock which they consume. All available clocks are defined as
19preprocessor macros in the dt-bindings/clock/meson8b-clkc.h header and can be
20used in device tree sources.
21
22Example: Clock controller node:
23
24 clkc: clock-controller@c1104000 {
25 #clock-cells = <1>;
26 compatible = "amlogic,meson8b-clkc";
27 reg = <0xc1108000 0x4>, <0xc1104000 0x460>;
28 };
29
30
31Example: UART controller node that consumes the clock generated by the clock
32 controller:
33
34 uart_AO: serial@c81004c0 {
35 compatible = "amlogic,meson-uart";
36 reg = <0xc81004c0 0x14>;
37 interrupts = <0 90 1>;
38 clocks = <&clkc CLKID_CLK81>;
39 status = "disabled";
40 };
diff --git a/Documentation/devicetree/bindings/clock/clock-bindings.txt b/Documentation/devicetree/bindings/clock/clock-bindings.txt
index 06fc6d541c89..2ec489eebe72 100644
--- a/Documentation/devicetree/bindings/clock/clock-bindings.txt
+++ b/Documentation/devicetree/bindings/clock/clock-bindings.txt
@@ -138,9 +138,10 @@ Some platforms may require initial configuration of default parent clocks
138and clock frequencies. Such a configuration can be specified in a device tree 138and clock frequencies. Such a configuration can be specified in a device tree
139node through assigned-clocks, assigned-clock-parents and assigned-clock-rates 139node through assigned-clocks, assigned-clock-parents and assigned-clock-rates
140properties. The assigned-clock-parents property should contain a list of parent 140properties. The assigned-clock-parents property should contain a list of parent
141clocks in form of phandle and clock specifier pairs, the assigned-clock-parents 141clocks in the form of a phandle and clock specifier pair and the
142property the list of assigned clock frequency values - corresponding to clocks 142assigned-clock-rates property should contain a list of frequencies in Hz. Both
143listed in the assigned-clocks property. 143these properties should correspond to the clocks listed in the assigned-clocks
144property.
144 145
145To skip setting parent or rate of a clock its corresponding entry should be 146To skip setting parent or rate of a clock its corresponding entry should be
146set to 0, or can be omitted if it is not followed by any non-zero entry. 147set to 0, or can be omitted if it is not followed by any non-zero entry.
diff --git a/Documentation/devicetree/bindings/clock/csr,atlas7-car.txt b/Documentation/devicetree/bindings/clock/csr,atlas7-car.txt
new file mode 100644
index 000000000000..54d6d1358339
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/csr,atlas7-car.txt
@@ -0,0 +1,55 @@
1* Clock and reset bindings for CSR atlas7
2
3Required properties:
4- compatible: Should be "sirf,atlas7-car"
5- reg: Address and length of the register set
6- #clock-cells: Should be <1>
7- #reset-cells: Should be <1>
8
9The clock consumer should specify the desired clock by having the clock
10ID in its "clocks" phandle cell.
11The ID list atlas7_clks defined in drivers/clk/sirf/clk-atlas7.c
12
13The reset consumer should specify the desired reset by having the reset
14ID in its "reset" phandle cell.
15The ID list atlas7_reset_unit defined in drivers/clk/sirf/clk-atlas7.c
16
17Examples: Clock and reset controller node:
18
19car: clock-controller@18620000 {
20 compatible = "sirf,atlas7-car";
21 reg = <0x18620000 0x1000>;
22 #clock-cells = <1>;
23 #reset-cells = <1>;
24};
25
26Examples: Consumers using clock or reset:
27
28timer@10dc0000 {
29 compatible = "sirf,macro-tick";
30 reg = <0x10dc0000 0x1000>;
31 clocks = <&car 54>;
32 interrupts = <0 0 0>,
33 <0 1 0>,
34 <0 2 0>,
35 <0 49 0>,
36 <0 50 0>,
37 <0 51 0>;
38};
39
40uart1: uart@18020000 {
41 cell-index = <1>;
42 compatible = "sirf,macro-uart";
43 reg = <0x18020000 0x1000>;
44 clocks = <&clks 95>;
45 interrupts = <0 18 0>;
46 fifosize = <32>;
47};
48
49vpp@13110000 {
50 compatible = "sirf,prima2-vpp";
51 reg = <0x13110000 0x10000>;
52 interrupts = <0 31 0>;
53 clocks = <&car 85>;
54 resets = <&car 29>;
55};
diff --git a/Documentation/devicetree/bindings/clock/emev2-clock.txt b/Documentation/devicetree/bindings/clock/emev2-clock.txt
index 60bbb1a8c69a..268ca615459e 100644
--- a/Documentation/devicetree/bindings/clock/emev2-clock.txt
+++ b/Documentation/devicetree/bindings/clock/emev2-clock.txt
@@ -52,7 +52,7 @@ usia_u0_sclk: usia_u0_sclk {
52 52
53Example of consumer: 53Example of consumer:
54 54
55uart@e1020000 { 55serial@e1020000 {
56 compatible = "renesas,em-uart"; 56 compatible = "renesas,em-uart";
57 reg = <0xe1020000 0x38>; 57 reg = <0xe1020000 0x38>;
58 interrupts = <0 8 0>; 58 interrupts = <0 8 0>;
diff --git a/Documentation/devicetree/bindings/clock/marvell,pxa1928.txt b/Documentation/devicetree/bindings/clock/marvell,pxa1928.txt
new file mode 100644
index 000000000000..809c5a2d8d9d
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/marvell,pxa1928.txt
@@ -0,0 +1,21 @@
1* Marvell PXA1928 Clock Controllers
2
3The PXA1928 clock subsystem generates and supplies clock to various
4controllers within the PXA1928 SoC. The PXA1928 contains 3 clock controller
5blocks called APMU, MPMU, and APBC roughly corresponding to internal buses.
6
7Required Properties:
8
9- compatible: should be one of the following.
10 - "marvell,pxa1928-apmu" - APMU controller compatible
11 - "marvell,pxa1928-mpmu" - MPMU controller compatible
12 - "marvell,pxa1928-apbc" - APBC controller compatible
13- reg: physical base address of the clock controller and length of memory mapped
14 region.
15- #clock-cells: should be 1.
16- #reset-cells: should be 1.
17
18Each clock is assigned an identifier and client nodes use the clock controller
19phandle and this identifier to specify the clock which they consume.
20
21All these identifiers can be found in <dt-bindings/clock/marvell,pxa1928.h>.
diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
index 31c7c0c1ce8f..660e64912cce 100644
--- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
+++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
@@ -19,6 +19,7 @@ ID Clock Peripheral
199 pex1 PCIe Cntrl 1 199 pex1 PCIe Cntrl 1
2015 sata0 SATA Host 0 2015 sata0 SATA Host 0
2117 sdio SDHCI Host 2117 sdio SDHCI Host
2223 crypto CESA (crypto engine)
2225 tdm Time Division Mplx 2325 tdm Time Division Mplx
2328 ddr DDR Cntrl 2428 ddr DDR Cntrl
2430 sata1 SATA Host 0 2530 sata1 SATA Host 0
diff --git a/Documentation/devicetree/bindings/clock/ti,cdce925.txt b/Documentation/devicetree/bindings/clock/ti,cdce925.txt
new file mode 100644
index 000000000000..4c7669ad681b
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti,cdce925.txt
@@ -0,0 +1,42 @@
1Binding for TO CDCE925 programmable I2C clock synthesizers.
2
3Reference
4This binding uses the common clock binding[1].
5
6[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
7[2] http://www.ti.com/product/cdce925
8
9The driver provides clock sources for each output Y1 through Y5.
10
11Required properties:
12 - compatible: Shall be "ti,cdce925"
13 - reg: I2C device address.
14 - clocks: Points to a fixed parent clock that provides the input frequency.
15 - #clock-cells: From common clock bindings: Shall be 1.
16
17Optional properties:
18 - xtal-load-pf: Crystal load-capacitor value to fine-tune performance on a
19 board, or to compensate for external influences.
20
21For both PLL1 and PLL2 an optional child node can be used to specify spread
22spectrum clocking parameters for a board.
23 - spread-spectrum: SSC mode as defined in the data sheet.
24 - spread-spectrum-center: Use "centered" mode instead of "max" mode. When
25 present, the clock runs at the requested frequency on average. Otherwise
26 the requested frequency is the maximum value of the SCC range.
27
28
29Example:
30
31 clockgen: cdce925pw@64 {
32 compatible = "cdce925";
33 reg = <0x64>;
34 clocks = <&xtal_27Mhz>;
35 #clock-cells = <1>;
36 xtal-load-pf = <5>;
37 /* PLL options to get SSC 1% centered */
38 PLL2 {
39 spread-spectrum = <4>;
40 spread-spectrum-center;
41 };
42 };
diff --git a/arch/arm/boot/dts/atlas7.dtsi b/arch/arm/boot/dts/atlas7.dtsi
index a753178abc85..5dfd3a44bf82 100644
--- a/arch/arm/boot/dts/atlas7.dtsi
+++ b/arch/arm/boot/dts/atlas7.dtsi
@@ -38,6 +38,21 @@
38 }; 38 };
39 }; 39 };
40 40
41 clocks {
42 xinw {
43 compatible = "fixed-clock";
44 #clock-cells = <0>;
45 clock-frequency = <32768>;
46 clock-output-names = "xinw";
47 };
48 xin {
49 compatible = "fixed-clock";
50 #clock-cells = <0>;
51 clock-frequency = <26000000>;
52 clock-output-names = "xin";
53 };
54 };
55
41 noc { 56 noc {
42 compatible = "simple-bus"; 57 compatible = "simple-bus";
43 #address-cells = <1>; 58 #address-cells = <1>;
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 9897f353bf1a..1dd4f9d8bcb6 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -78,6 +78,23 @@ config COMMON_CLK_SI570
78 This driver supports Silicon Labs 570/571/598/599 programmable 78 This driver supports Silicon Labs 570/571/598/599 programmable
79 clock generators. 79 clock generators.
80 80
81config COMMON_CLK_CDCE925
82 tristate "Clock driver for TI CDCE925 devices"
83 depends on I2C
84 depends on OF
85 select REGMAP_I2C
86 help
87 ---help---
88 This driver supports the TI CDCE925 programmable clock synthesizer.
89 The chip contains two PLLs with spread-spectrum clocking support and
90 five output dividers. The driver only supports the following setup,
91 and uses a fixed setting for the output muxes.
92 Y1 is derived from the input clock
93 Y2 and Y3 derive from PLL1
94 Y4 and Y5 derive from PLL2
95 Given a target output frequency, the driver will set the PLL and
96 divider to best approximate the desired output.
97
81config COMMON_CLK_S2MPS11 98config COMMON_CLK_S2MPS11
82 tristate "Clock driver for S2MPS1X/S5M8767 MFD" 99 tristate "Clock driver for S2MPS1X/S5M8767 MFD"
83 depends on MFD_SEC_CORE 100 depends on MFD_SEC_CORE
@@ -150,11 +167,12 @@ config COMMON_CLK_CDCE706
150 ---help--- 167 ---help---
151 This driver supports TI CDCE706 programmable 3-PLL clock synthesizer. 168 This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
152 169
170source "drivers/clk/bcm/Kconfig"
171source "drivers/clk/hisilicon/Kconfig"
153source "drivers/clk/qcom/Kconfig" 172source "drivers/clk/qcom/Kconfig"
154 173
155endmenu 174endmenu
156 175
157source "drivers/clk/bcm/Kconfig"
158source "drivers/clk/mvebu/Kconfig" 176source "drivers/clk/mvebu/Kconfig"
159 177
160source "drivers/clk/samsung/Kconfig" 178source "drivers/clk/samsung/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 3d00c25382c5..3233f0e8bf43 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -38,6 +38,7 @@ obj-$(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_SI570) += clk-si570.o 40obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
41obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o
41obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o 42obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
42obj-$(CONFIG_ARCH_U300) += clk-u300.o 43obj-$(CONFIG_ARCH_U300) += clk-u300.o
43obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o 44obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
@@ -47,14 +48,14 @@ obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
47obj-$(CONFIG_COMMON_CLK_AT91) += at91/ 48obj-$(CONFIG_COMMON_CLK_AT91) += at91/
48obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm/ 49obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm/
49obj-$(CONFIG_ARCH_BERLIN) += berlin/ 50obj-$(CONFIG_ARCH_BERLIN) += berlin/
50obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/ 51obj-$(CONFIG_ARCH_HISI) += hisilicon/
51obj-$(CONFIG_ARCH_HIP04) += hisilicon/
52obj-$(CONFIG_ARCH_HIX5HD2) += hisilicon/
53obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ 52obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
53obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
54ifeq ($(CONFIG_COMMON_CLK), y) 54ifeq ($(CONFIG_COMMON_CLK), y)
55obj-$(CONFIG_ARCH_MMP) += mmp/ 55obj-$(CONFIG_ARCH_MMP) += mmp/
56endif 56endif
57obj-$(CONFIG_PLAT_ORION) += mvebu/ 57obj-$(CONFIG_PLAT_ORION) += mvebu/
58obj-$(CONFIG_ARCH_MESON) += meson/
58obj-$(CONFIG_ARCH_MXS) += mxs/ 59obj-$(CONFIG_ARCH_MXS) += mxs/
59obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ 60obj-$(CONFIG_MACH_PISTACHIO) += pistachio/
60obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ 61obj-$(CONFIG_COMMON_CLK_PXA) += pxa/
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
index 59fa3cc96c9e..c2400456a044 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -614,7 +614,7 @@ void __init of_at91sam9x5_clk_main_setup(struct device_node *np,
614 const char *name = np->name; 614 const char *name = np->name;
615 int i; 615 int i;
616 616
617 num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 617 num_parents = of_clk_get_parent_count(np);
618 if (num_parents <= 0 || num_parents > 2) 618 if (num_parents <= 0 || num_parents > 2)
619 return; 619 return;
620 620
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index c1af80bcdf20..f98eafe9b12d 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -224,7 +224,7 @@ of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc,
224 const char *name = np->name; 224 const char *name = np->name;
225 struct clk_master_characteristics *characteristics; 225 struct clk_master_characteristics *characteristics;
226 226
227 num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 227 num_parents = of_clk_get_parent_count(np);
228 if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX) 228 if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX)
229 return; 229 return;
230 230
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index 86c8a073dcc3..8c86c0f7847a 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -237,7 +237,7 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc,
237 const char *name; 237 const char *name;
238 struct device_node *progclknp; 238 struct device_node *progclknp;
239 239
240 num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 240 num_parents = of_clk_get_parent_count(np);
241 if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX) 241 if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX)
242 return; 242 return;
243 243
diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c
index 2f13bd5246b5..98a84a865fe1 100644
--- a/drivers/clk/at91/clk-slow.c
+++ b/drivers/clk/at91/clk-slow.c
@@ -373,7 +373,7 @@ void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
373 const char *name = np->name; 373 const char *name = np->name;
374 int i; 374 int i;
375 375
376 num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 376 num_parents = of_clk_get_parent_count(np);
377 if (num_parents <= 0 || num_parents > 2) 377 if (num_parents <= 0 || num_parents > 2)
378 return; 378 return;
379 379
@@ -451,7 +451,7 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np,
451 const char *name = np->name; 451 const char *name = np->name;
452 int i; 452 int i;
453 453
454 num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 454 num_parents = of_clk_get_parent_count(np);
455 if (num_parents != 2) 455 if (num_parents != 2)
456 return; 456 return;
457 457
diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c
index 144d47ecfe63..3817ea865ca2 100644
--- a/drivers/clk/at91/clk-smd.c
+++ b/drivers/clk/at91/clk-smd.c
@@ -150,7 +150,7 @@ void __init of_at91sam9x5_clk_smd_setup(struct device_node *np,
150 const char *parent_names[SMD_SOURCE_MAX]; 150 const char *parent_names[SMD_SOURCE_MAX];
151 const char *name = np->name; 151 const char *name = np->name;
152 152
153 num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 153 num_parents = of_clk_get_parent_count(np);
154 if (num_parents <= 0 || num_parents > SMD_SOURCE_MAX) 154 if (num_parents <= 0 || num_parents > SMD_SOURCE_MAX)
155 return; 155 return;
156 156
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c
index 0b7c3e8840ba..b0cbd2b1ff59 100644
--- a/drivers/clk/at91/clk-usb.c
+++ b/drivers/clk/at91/clk-usb.c
@@ -378,7 +378,7 @@ void __init of_at91sam9x5_clk_usb_setup(struct device_node *np,
378 const char *parent_names[USB_SOURCE_MAX]; 378 const char *parent_names[USB_SOURCE_MAX];
379 const char *name = np->name; 379 const char *name = np->name;
380 380
381 num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 381 num_parents = of_clk_get_parent_count(np);
382 if (num_parents <= 0 || num_parents > USB_SOURCE_MAX) 382 if (num_parents <= 0 || num_parents > USB_SOURCE_MAX)
383 return; 383 return;
384 384
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 3f27d21fb729..39be2be82b0a 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -153,7 +153,7 @@ static int pmc_irq_domain_xlate(struct irq_domain *d,
153 return 0; 153 return 0;
154} 154}
155 155
156static struct irq_domain_ops pmc_irq_ops = { 156static const struct irq_domain_ops pmc_irq_ops = {
157 .map = pmc_irq_map, 157 .map = pmc_irq_map,
158 .xlate = pmc_irq_domain_xlate, 158 .xlate = pmc_irq_domain_xlate,
159}; 159};
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c
index e5aededdd322..deaa7f962b84 100644
--- a/drivers/clk/bcm/clk-kona-setup.c
+++ b/drivers/clk/bcm/clk-kona-setup.c
@@ -21,8 +21,6 @@
21#define selector_clear_exists(sel) ((sel)->width = 0) 21#define selector_clear_exists(sel) ((sel)->width = 0)
22#define trigger_clear_exists(trig) FLAG_CLEAR(trig, TRIG, EXISTS) 22#define trigger_clear_exists(trig) FLAG_CLEAR(trig, TRIG, EXISTS)
23 23
24LIST_HEAD(ccu_list); /* The list of set up CCUs */
25
26/* Validity checking */ 24/* Validity checking */
27 25
28static bool ccu_data_offsets_valid(struct ccu_data *ccu) 26static bool ccu_data_offsets_valid(struct ccu_data *ccu)
@@ -773,7 +771,6 @@ static void kona_ccu_teardown(struct ccu_data *ccu)
773 771
774 of_clk_del_provider(ccu->node); /* safe if never added */ 772 of_clk_del_provider(ccu->node); /* safe if never added */
775 ccu_clks_teardown(ccu); 773 ccu_clks_teardown(ccu);
776 list_del(&ccu->links);
777 of_node_put(ccu->node); 774 of_node_put(ccu->node);
778 ccu->node = NULL; 775 ccu->node = NULL;
779 iounmap(ccu->base); 776 iounmap(ccu->base);
@@ -847,7 +844,6 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu,
847 goto out_err; 844 goto out_err;
848 } 845 }
849 ccu->node = of_node_get(node); 846 ccu->node = of_node_get(node);
850 list_add_tail(&ccu->links, &ccu_list);
851 847
852 /* 848 /*
853 * Set up each defined kona clock and save the result in 849 * Set up each defined kona clock and save the result in
diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c
index a0ef4f75d457..79a98506c433 100644
--- a/drivers/clk/bcm/clk-kona.c
+++ b/drivers/clk/bcm/clk-kona.c
@@ -1240,7 +1240,7 @@ static bool __kona_clk_init(struct kona_clk *bcm_clk)
1240 default: 1240 default:
1241 BUG(); 1241 BUG();
1242 } 1242 }
1243 return -EINVAL; 1243 return false;
1244} 1244}
1245 1245
1246/* Set a CCU and all its clocks into their desired initial state */ 1246/* Set a CCU and all its clocks into their desired initial state */
diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h
index 6849a64baf6d..906576ec97b6 100644
--- a/drivers/clk/bcm/clk-kona.h
+++ b/drivers/clk/bcm/clk-kona.h
@@ -480,7 +480,6 @@ struct ccu_data {
480 spinlock_t lock; /* serialization lock */ 480 spinlock_t lock; /* serialization lock */
481 bool write_enabled; /* write access is currently enabled */ 481 bool write_enabled; /* write access is currently enabled */
482 struct ccu_policy policy; 482 struct ccu_policy policy;
483 struct list_head links; /* for ccu_list */
484 struct device_node *node; 483 struct device_node *node;
485 struct clk_onecell_data clk_data; 484 struct clk_onecell_data clk_data;
486 const char *name; 485 const char *name;
@@ -492,7 +491,6 @@ struct ccu_data {
492#define KONA_CCU_COMMON(_prefix, _name, _ccuname) \ 491#define KONA_CCU_COMMON(_prefix, _name, _ccuname) \
493 .name = #_name "_ccu", \ 492 .name = #_name "_ccu", \
494 .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \ 493 .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \
495 .links = LIST_HEAD_INIT(_name ## _ccu_data.links), \
496 .clk_data = { \ 494 .clk_data = { \
497 .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT, \ 495 .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT, \
498 } 496 }
diff --git a/drivers/clk/berlin/berlin2-pll.c b/drivers/clk/berlin/berlin2-pll.c
index bdc506b03824..f4b8d324b083 100644
--- a/drivers/clk/berlin/berlin2-pll.c
+++ b/drivers/clk/berlin/berlin2-pll.c
@@ -25,14 +25,7 @@
25#include <asm/div64.h> 25#include <asm/div64.h>
26 26
27#include "berlin2-div.h" 27#include "berlin2-div.h"
28 28#include "berlin2-pll.h"
29struct berlin2_pll_map {
30 const u8 vcodiv[16];
31 u8 mult;
32 u8 fbdiv_shift;
33 u8 rfdiv_shift;
34 u8 divsel_shift;
35};
36 29
37struct berlin2_pll { 30struct berlin2_pll {
38 struct clk_hw hw; 31 struct clk_hw hw;
diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c
index 88f4ff6916fe..90897af8d9f7 100644
--- a/drivers/clk/clk-asm9260.c
+++ b/drivers/clk/clk-asm9260.c
@@ -274,7 +274,7 @@ static void __init asm9260_acc_init(struct device_node *np)
274 u32 accuracy = 0; 274 u32 accuracy = 0;
275 275
276 base = of_io_request_and_map(np, 0, np->name); 276 base = of_io_request_and_map(np, 0, np->name);
277 if (!base) 277 if (IS_ERR(base))
278 panic("%s: unable to map resource", np->name); 278 panic("%s: unable to map resource", np->name);
279 279
280 /* register pll */ 280 /* register pll */
diff --git a/drivers/clk/clk-axm5516.c b/drivers/clk/clk-axm5516.c
index 0f6368ceec4c..c7c91a5ecf8b 100644
--- a/drivers/clk/clk-axm5516.c
+++ b/drivers/clk/clk-axm5516.c
@@ -556,7 +556,7 @@ static int axmclk_probe(struct platform_device *pdev)
556 return PTR_ERR(regmap); 556 return PTR_ERR(regmap);
557 557
558 num_clks = ARRAY_SIZE(axmclk_clocks); 558 num_clks = ARRAY_SIZE(axmclk_clocks);
559 pr_info("axmclk: supporting %u clocks\n", num_clks); 559 pr_info("axmclk: supporting %zu clocks\n", num_clks);
560 priv = devm_kzalloc(dev, sizeof(*priv) + sizeof(*priv->clks) * num_clks, 560 priv = devm_kzalloc(dev, sizeof(*priv) + sizeof(*priv->clks) * num_clks,
561 GFP_KERNEL); 561 GFP_KERNEL);
562 if (!priv) 562 if (!priv)
diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c
index b8e4f8a822e9..f01164fada5d 100644
--- a/drivers/clk/clk-cdce706.c
+++ b/drivers/clk/clk-cdce706.c
@@ -94,7 +94,7 @@ static const char * const cdce706_source_name[] = {
94 "clk_in0", "clk_in1", 94 "clk_in0", "clk_in1",
95}; 95};
96 96
97static const char *cdce706_clkin_name[] = { 97static const char * const cdce706_clkin_name[] = {
98 "clk_in", 98 "clk_in",
99}; 99};
100 100
@@ -102,7 +102,7 @@ static const char * const cdce706_pll_name[] = {
102 "pll1", "pll2", "pll3", 102 "pll1", "pll2", "pll3",
103}; 103};
104 104
105static const char *cdce706_divider_parent_name[] = { 105static const char * const cdce706_divider_parent_name[] = {
106 "clk_in", "pll1", "pll2", "pll2", "pll3", 106 "clk_in", "pll1", "pll2", "pll2", "pll3",
107}; 107};
108 108
@@ -666,6 +666,7 @@ static int cdce706_probe(struct i2c_client *client,
666 666
667static int cdce706_remove(struct i2c_client *client) 667static int cdce706_remove(struct i2c_client *client)
668{ 668{
669 of_clk_del_provider(client->dev.of_node);
669 return 0; 670 return 0;
670} 671}
671 672
diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c
new file mode 100644
index 000000000000..85fafb41e6ca
--- /dev/null
+++ b/drivers/clk/clk-cdce925.c
@@ -0,0 +1,749 @@
1/*
2 * Driver for TI Dual PLL CDCE925 clock synthesizer
3 *
4 * This driver always connects the Y1 to the input clock, Y2/Y3 to PLL1
5 * and Y4/Y5 to PLL2. PLL frequency is set on a first-come-first-serve
6 * basis. Clients can directly request any frequency that the chip can
7 * deliver using the standard clk framework. In addition, the device can
8 * be configured and activated via the devicetree.
9 *
10 * Copyright (C) 2014, Topic Embedded Products
11 * Licenced under GPL
12 */
13#include <linux/clk-provider.h>
14#include <linux/delay.h>
15#include <linux/module.h>
16#include <linux/i2c.h>
17#include <linux/regmap.h>
18#include <linux/slab.h>
19#include <linux/gcd.h>
20
21/* The chip has 2 PLLs which can be routed through dividers to 5 outputs.
22 * Model this as 2 PLL clocks which are parents to the outputs.
23 */
24#define NUMBER_OF_PLLS 2
25#define NUMBER_OF_OUTPUTS 5
26
27#define CDCE925_REG_GLOBAL1 0x01
28#define CDCE925_REG_Y1SPIPDIVH 0x02
29#define CDCE925_REG_PDIVL 0x03
30#define CDCE925_REG_XCSEL 0x05
31/* PLL parameters start at 0x10, steps of 0x10 */
32#define CDCE925_OFFSET_PLL 0x10
33/* Add CDCE925_OFFSET_PLL * (pll) to these registers before sending */
34#define CDCE925_PLL_MUX_OUTPUTS 0x14
35#define CDCE925_PLL_MULDIV 0x18
36
37#define CDCE925_PLL_FREQUENCY_MIN 80000000ul
38#define CDCE925_PLL_FREQUENCY_MAX 230000000ul
39struct clk_cdce925_chip;
40
41struct clk_cdce925_output {
42 struct clk_hw hw;
43 struct clk_cdce925_chip *chip;
44 u8 index;
45 u16 pdiv; /* 1..127 for Y2-Y5; 1..1023 for Y1 */
46};
47#define to_clk_cdce925_output(_hw) \
48 container_of(_hw, struct clk_cdce925_output, hw)
49
50struct clk_cdce925_pll {
51 struct clk_hw hw;
52 struct clk_cdce925_chip *chip;
53 u8 index;
54 u16 m; /* 1..511 */
55 u16 n; /* 1..4095 */
56};
57#define to_clk_cdce925_pll(_hw) container_of(_hw, struct clk_cdce925_pll, hw)
58
59struct clk_cdce925_chip {
60 struct regmap *regmap;
61 struct i2c_client *i2c_client;
62 struct clk_cdce925_pll pll[NUMBER_OF_PLLS];
63 struct clk_cdce925_output clk[NUMBER_OF_OUTPUTS];
64 struct clk *dt_clk[NUMBER_OF_OUTPUTS];
65 struct clk_onecell_data onecell;
66};
67
68/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
69
70static unsigned long cdce925_pll_calculate_rate(unsigned long parent_rate,
71 u16 n, u16 m)
72{
73 if ((!m || !n) || (m == n))
74 return parent_rate; /* In bypass mode runs at same frequency */
75 return mult_frac(parent_rate, (unsigned long)n, (unsigned long)m);
76}
77
78static unsigned long cdce925_pll_recalc_rate(struct clk_hw *hw,
79 unsigned long parent_rate)
80{
81 /* Output frequency of PLL is Fout = (Fin/Pdiv)*(N/M) */
82 struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw);
83
84 return cdce925_pll_calculate_rate(parent_rate, data->n, data->m);
85}
86
87static void cdce925_pll_find_rate(unsigned long rate,
88 unsigned long parent_rate, u16 *n, u16 *m)
89{
90 unsigned long un;
91 unsigned long um;
92 unsigned long g;
93
94 if (rate <= parent_rate) {
95 /* Can always deliver parent_rate in bypass mode */
96 rate = parent_rate;
97 *n = 0;
98 *m = 0;
99 } else {
100 /* In PLL mode, need to apply min/max range */
101 if (rate < CDCE925_PLL_FREQUENCY_MIN)
102 rate = CDCE925_PLL_FREQUENCY_MIN;
103 else if (rate > CDCE925_PLL_FREQUENCY_MAX)
104 rate = CDCE925_PLL_FREQUENCY_MAX;
105
106 g = gcd(rate, parent_rate);
107 um = parent_rate / g;
108 un = rate / g;
109 /* When outside hw range, reduce to fit (rounding errors) */
110 while ((un > 4095) || (um > 511)) {
111 un >>= 1;
112 um >>= 1;
113 }
114 if (un == 0)
115 un = 1;
116 if (um == 0)
117 um = 1;
118
119 *n = un;
120 *m = um;
121 }
122}
123
124static long cdce925_pll_round_rate(struct clk_hw *hw, unsigned long rate,
125 unsigned long *parent_rate)
126{
127 u16 n, m;
128
129 cdce925_pll_find_rate(rate, *parent_rate, &n, &m);
130 return (long)cdce925_pll_calculate_rate(*parent_rate, n, m);
131}
132
133static int cdce925_pll_set_rate(struct clk_hw *hw, unsigned long rate,
134 unsigned long parent_rate)
135{
136 struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw);
137
138 if (!rate || (rate == parent_rate)) {
139 data->m = 0; /* Bypass mode */
140 data->n = 0;
141 return 0;
142 }
143
144 if ((rate < CDCE925_PLL_FREQUENCY_MIN) ||
145 (rate > CDCE925_PLL_FREQUENCY_MAX)) {
146 pr_debug("%s: rate %lu outside PLL range.\n", __func__, rate);
147 return -EINVAL;
148 }
149
150 if (rate < parent_rate) {
151 pr_debug("%s: rate %lu less than parent rate %lu.\n", __func__,
152 rate, parent_rate);
153 return -EINVAL;
154 }
155
156 cdce925_pll_find_rate(rate, parent_rate, &data->n, &data->m);
157 return 0;
158}
159
160
161/* calculate p = max(0, 4 - int(log2 (n/m))) */
162static u8 cdce925_pll_calc_p(u16 n, u16 m)
163{
164 u8 p;
165 u16 r = n / m;
166
167 if (r >= 16)
168 return 0;
169 p = 4;
170 while (r > 1) {
171 r >>= 1;
172 --p;
173 }
174 return p;
175}
176
177/* Returns VCO range bits for VCO1_0_RANGE */
178static u8 cdce925_pll_calc_range_bits(struct clk_hw *hw, u16 n, u16 m)
179{
180 struct clk *parent = clk_get_parent(hw->clk);
181 unsigned long rate = clk_get_rate(parent);
182
183 rate = mult_frac(rate, (unsigned long)n, (unsigned long)m);
184 if (rate >= 175000000)
185 return 0x3;
186 if (rate >= 150000000)
187 return 0x02;
188 if (rate >= 125000000)
189 return 0x01;
190 return 0x00;
191}
192
193/* I2C clock, hence everything must happen in (un)prepare because this
194 * may sleep */
195static int cdce925_pll_prepare(struct clk_hw *hw)
196{
197 struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw);
198 u16 n = data->n;
199 u16 m = data->m;
200 u16 r;
201 u8 q;
202 u8 p;
203 u16 nn;
204 u8 pll[4]; /* Bits are spread out over 4 byte registers */
205 u8 reg_ofs = data->index * CDCE925_OFFSET_PLL;
206 unsigned i;
207
208 if ((!m || !n) || (m == n)) {
209 /* Set PLL mux to bypass mode, leave the rest as is */
210 regmap_update_bits(data->chip->regmap,
211 reg_ofs + CDCE925_PLL_MUX_OUTPUTS, 0x80, 0x80);
212 } else {
213 /* According to data sheet: */
214 /* p = max(0, 4 - int(log2 (n/m))) */
215 p = cdce925_pll_calc_p(n, m);
216 /* nn = n * 2^p */
217 nn = n * BIT(p);
218 /* q = int(nn/m) */
219 q = nn / m;
220 if ((q < 16) || (1 > 64)) {
221 pr_debug("%s invalid q=%d\n", __func__, q);
222 return -EINVAL;
223 }
224 r = nn - (m*q);
225 if (r > 511) {
226 pr_debug("%s invalid r=%d\n", __func__, r);
227 return -EINVAL;
228 }
229 pr_debug("%s n=%d m=%d p=%d q=%d r=%d\n", __func__,
230 n, m, p, q, r);
231 /* encode into register bits */
232 pll[0] = n >> 4;
233 pll[1] = ((n & 0x0F) << 4) | ((r >> 5) & 0x0F);
234 pll[2] = ((r & 0x1F) << 3) | ((q >> 3) & 0x07);
235 pll[3] = ((q & 0x07) << 5) | (p << 2) |
236 cdce925_pll_calc_range_bits(hw, n, m);
237 /* Write to registers */
238 for (i = 0; i < ARRAY_SIZE(pll); ++i)
239 regmap_write(data->chip->regmap,
240 reg_ofs + CDCE925_PLL_MULDIV + i, pll[i]);
241 /* Enable PLL */
242 regmap_update_bits(data->chip->regmap,
243 reg_ofs + CDCE925_PLL_MUX_OUTPUTS, 0x80, 0x00);
244 }
245
246 return 0;
247}
248
249static void cdce925_pll_unprepare(struct clk_hw *hw)
250{
251 struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw);
252 u8 reg_ofs = data->index * CDCE925_OFFSET_PLL;
253
254 regmap_update_bits(data->chip->regmap,
255 reg_ofs + CDCE925_PLL_MUX_OUTPUTS, 0x80, 0x80);
256}
257
258static const struct clk_ops cdce925_pll_ops = {
259 .prepare = cdce925_pll_prepare,
260 .unprepare = cdce925_pll_unprepare,
261 .recalc_rate = cdce925_pll_recalc_rate,
262 .round_rate = cdce925_pll_round_rate,
263 .set_rate = cdce925_pll_set_rate,
264};
265
266
267static void cdce925_clk_set_pdiv(struct clk_cdce925_output *data, u16 pdiv)
268{
269 switch (data->index) {
270 case 0:
271 regmap_update_bits(data->chip->regmap,
272 CDCE925_REG_Y1SPIPDIVH,
273 0x03, (pdiv >> 8) & 0x03);
274 regmap_write(data->chip->regmap, 0x03, pdiv & 0xFF);
275 break;
276 case 1:
277 regmap_update_bits(data->chip->regmap, 0x16, 0x7F, pdiv);
278 break;
279 case 2:
280 regmap_update_bits(data->chip->regmap, 0x17, 0x7F, pdiv);
281 break;
282 case 3:
283 regmap_update_bits(data->chip->regmap, 0x26, 0x7F, pdiv);
284 break;
285 case 4:
286 regmap_update_bits(data->chip->regmap, 0x27, 0x7F, pdiv);
287 break;
288 }
289}
290
291static void cdce925_clk_activate(struct clk_cdce925_output *data)
292{
293 switch (data->index) {
294 case 0:
295 regmap_update_bits(data->chip->regmap,
296 CDCE925_REG_Y1SPIPDIVH, 0x0c, 0x0c);
297 break;
298 case 1:
299 case 2:
300 regmap_update_bits(data->chip->regmap, 0x14, 0x03, 0x03);
301 break;
302 case 3:
303 case 4:
304 regmap_update_bits(data->chip->regmap, 0x24, 0x03, 0x03);
305 break;
306 }
307}
308
309static int cdce925_clk_prepare(struct clk_hw *hw)
310{
311 struct clk_cdce925_output *data = to_clk_cdce925_output(hw);
312
313 cdce925_clk_set_pdiv(data, data->pdiv);
314 cdce925_clk_activate(data);
315 return 0;
316}
317
318static void cdce925_clk_unprepare(struct clk_hw *hw)
319{
320 struct clk_cdce925_output *data = to_clk_cdce925_output(hw);
321
322 /* Disable clock by setting divider to "0" */
323 cdce925_clk_set_pdiv(data, 0);
324}
325
326static unsigned long cdce925_clk_recalc_rate(struct clk_hw *hw,
327 unsigned long parent_rate)
328{
329 struct clk_cdce925_output *data = to_clk_cdce925_output(hw);
330
331 if (data->pdiv)
332 return parent_rate / data->pdiv;
333 return 0;
334}
335
336static u16 cdce925_calc_divider(unsigned long rate,
337 unsigned long parent_rate)
338{
339 unsigned long divider;
340
341 if (!rate)
342 return 0;
343 if (rate >= parent_rate)
344 return 1;
345
346 divider = DIV_ROUND_CLOSEST(parent_rate, rate);
347 if (divider > 0x7F)
348 divider = 0x7F;
349
350 return (u16)divider;
351}
352
353static unsigned long cdce925_clk_best_parent_rate(
354 struct clk_hw *hw, unsigned long rate)
355{
356 struct clk *pll = clk_get_parent(hw->clk);
357 struct clk *root = clk_get_parent(pll);
358 unsigned long root_rate = clk_get_rate(root);
359 unsigned long best_rate_error = rate;
360 u16 pdiv_min;
361 u16 pdiv_max;
362 u16 pdiv_best;
363 u16 pdiv_now;
364
365 if (root_rate % rate == 0)
366 return root_rate; /* Don't need the PLL, use bypass */
367
368 pdiv_min = (u16)max(1ul, DIV_ROUND_UP(CDCE925_PLL_FREQUENCY_MIN, rate));
369 pdiv_max = (u16)min(127ul, CDCE925_PLL_FREQUENCY_MAX / rate);
370
371 if (pdiv_min > pdiv_max)
372 return 0; /* No can do? */
373
374 pdiv_best = pdiv_min;
375 for (pdiv_now = pdiv_min; pdiv_now < pdiv_max; ++pdiv_now) {
376 unsigned long target_rate = rate * pdiv_now;
377 long pll_rate = clk_round_rate(pll, target_rate);
378 unsigned long actual_rate;
379 unsigned long rate_error;
380
381 if (pll_rate <= 0)
382 continue;
383 actual_rate = pll_rate / pdiv_now;
384 rate_error = abs((long)actual_rate - (long)rate);
385 if (rate_error < best_rate_error) {
386 pdiv_best = pdiv_now;
387 best_rate_error = rate_error;
388 }
389 /* TODO: Consider PLL frequency based on smaller n/m values
390 * and pick the better one if the error is equal */
391 }
392
393 return rate * pdiv_best;
394}
395
396static long cdce925_clk_round_rate(struct clk_hw *hw, unsigned long rate,
397 unsigned long *parent_rate)
398{
399 unsigned long l_parent_rate = *parent_rate;
400 u16 divider = cdce925_calc_divider(rate, l_parent_rate);
401
402 if (l_parent_rate / divider != rate) {
403 l_parent_rate = cdce925_clk_best_parent_rate(hw, rate);
404 divider = cdce925_calc_divider(rate, l_parent_rate);
405 *parent_rate = l_parent_rate;
406 }
407
408 if (divider)
409 return (long)(l_parent_rate / divider);
410 return 0;
411}
412
413static int cdce925_clk_set_rate(struct clk_hw *hw, unsigned long rate,
414 unsigned long parent_rate)
415{
416 struct clk_cdce925_output *data = to_clk_cdce925_output(hw);
417
418 data->pdiv = cdce925_calc_divider(rate, parent_rate);
419
420 return 0;
421}
422
423static const struct clk_ops cdce925_clk_ops = {
424 .prepare = cdce925_clk_prepare,
425 .unprepare = cdce925_clk_unprepare,
426 .recalc_rate = cdce925_clk_recalc_rate,
427 .round_rate = cdce925_clk_round_rate,
428 .set_rate = cdce925_clk_set_rate,
429};
430
431
432static u16 cdce925_y1_calc_divider(unsigned long rate,
433 unsigned long parent_rate)
434{
435 unsigned long divider;
436
437 if (!rate)
438 return 0;
439 if (rate >= parent_rate)
440 return 1;
441
442 divider = DIV_ROUND_CLOSEST(parent_rate, rate);
443 if (divider > 0x3FF) /* Y1 has 10-bit divider */
444 divider = 0x3FF;
445
446 return (u16)divider;
447}
448
449static long cdce925_clk_y1_round_rate(struct clk_hw *hw, unsigned long rate,
450 unsigned long *parent_rate)
451{
452 unsigned long l_parent_rate = *parent_rate;
453 u16 divider = cdce925_y1_calc_divider(rate, l_parent_rate);
454
455 if (divider)
456 return (long)(l_parent_rate / divider);
457 return 0;
458}
459
460static int cdce925_clk_y1_set_rate(struct clk_hw *hw, unsigned long rate,
461 unsigned long parent_rate)
462{
463 struct clk_cdce925_output *data = to_clk_cdce925_output(hw);
464
465 data->pdiv = cdce925_y1_calc_divider(rate, parent_rate);
466
467 return 0;
468}
469
470static const struct clk_ops cdce925_clk_y1_ops = {
471 .prepare = cdce925_clk_prepare,
472 .unprepare = cdce925_clk_unprepare,
473 .recalc_rate = cdce925_clk_recalc_rate,
474 .round_rate = cdce925_clk_y1_round_rate,
475 .set_rate = cdce925_clk_y1_set_rate,
476};
477
478
479static struct regmap_config cdce925_regmap_config = {
480 .name = "configuration0",
481 .reg_bits = 8,
482 .val_bits = 8,
483 .cache_type = REGCACHE_RBTREE,
484 .max_register = 0x2F,
485};
486
487#define CDCE925_I2C_COMMAND_BLOCK_TRANSFER 0x00
488#define CDCE925_I2C_COMMAND_BYTE_TRANSFER 0x80
489
490static int cdce925_regmap_i2c_write(
491 void *context, const void *data, size_t count)
492{
493 struct device *dev = context;
494 struct i2c_client *i2c = to_i2c_client(dev);
495 int ret;
496 u8 reg_data[2];
497
498 if (count != 2)
499 return -ENOTSUPP;
500
501 /* First byte is command code */
502 reg_data[0] = CDCE925_I2C_COMMAND_BYTE_TRANSFER | ((u8 *)data)[0];
503 reg_data[1] = ((u8 *)data)[1];
504
505 dev_dbg(&i2c->dev, "%s(%zu) %#x %#x\n", __func__, count,
506 reg_data[0], reg_data[1]);
507
508 ret = i2c_master_send(i2c, reg_data, count);
509 if (likely(ret == count))
510 return 0;
511 else if (ret < 0)
512 return ret;
513 else
514 return -EIO;
515}
516
517static int cdce925_regmap_i2c_read(void *context,
518 const void *reg, size_t reg_size, void *val, size_t val_size)
519{
520 struct device *dev = context;
521 struct i2c_client *i2c = to_i2c_client(dev);
522 struct i2c_msg xfer[2];
523 int ret;
524 u8 reg_data[2];
525
526 if (reg_size != 1)
527 return -ENOTSUPP;
528
529 xfer[0].addr = i2c->addr;
530 xfer[0].flags = 0;
531 xfer[0].buf = reg_data;
532 if (val_size == 1) {
533 reg_data[0] =
534 CDCE925_I2C_COMMAND_BYTE_TRANSFER | ((u8 *)reg)[0];
535 xfer[0].len = 1;
536 } else {
537 reg_data[0] =
538 CDCE925_I2C_COMMAND_BLOCK_TRANSFER | ((u8 *)reg)[0];
539 reg_data[1] = val_size;
540 xfer[0].len = 2;
541 }
542
543 xfer[1].addr = i2c->addr;
544 xfer[1].flags = I2C_M_RD;
545 xfer[1].len = val_size;
546 xfer[1].buf = val;
547
548 ret = i2c_transfer(i2c->adapter, xfer, 2);
549 if (likely(ret == 2)) {
550 dev_dbg(&i2c->dev, "%s(%zu, %zu) %#x %#x\n", __func__,
551 reg_size, val_size, reg_data[0], *((u8 *)val));
552 return 0;
553 } else if (ret < 0)
554 return ret;
555 else
556 return -EIO;
557}
558
559/* The CDCE925 uses a funky way to read/write registers. Bulk mode is
560 * just weird, so just use the single byte mode exclusively. */
561static struct regmap_bus regmap_cdce925_bus = {
562 .write = cdce925_regmap_i2c_write,
563 .read = cdce925_regmap_i2c_read,
564};
565
566static int cdce925_probe(struct i2c_client *client,
567 const struct i2c_device_id *id)
568{
569 struct clk_cdce925_chip *data;
570 struct device_node *node = client->dev.of_node;
571 const char *parent_name;
572 const char *pll_clk_name[NUMBER_OF_PLLS] = {NULL,};
573 struct clk_init_data init;
574 struct clk *clk;
575 u32 value;
576 int i;
577 int err;
578 struct device_node *np_output;
579 char child_name[6];
580
581 dev_dbg(&client->dev, "%s\n", __func__);
582 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
583 if (!data)
584 return -ENOMEM;
585
586 data->i2c_client = client;
587 data->regmap = devm_regmap_init(&client->dev, &regmap_cdce925_bus,
588 &client->dev, &cdce925_regmap_config);
589 if (IS_ERR(data->regmap)) {
590 dev_err(&client->dev, "failed to allocate register map\n");
591 return PTR_ERR(data->regmap);
592 }
593 i2c_set_clientdata(client, data);
594
595 parent_name = of_clk_get_parent_name(node, 0);
596 if (!parent_name) {
597 dev_err(&client->dev, "missing parent clock\n");
598 return -ENODEV;
599 }
600 dev_dbg(&client->dev, "parent is: %s\n", parent_name);
601
602 if (of_property_read_u32(node, "xtal-load-pf", &value) == 0)
603 regmap_write(data->regmap,
604 CDCE925_REG_XCSEL, (value << 3) & 0xF8);
605 /* PWDN bit */
606 regmap_update_bits(data->regmap, CDCE925_REG_GLOBAL1, BIT(4), 0);
607
608 /* Set input source for Y1 to be the XTAL */
609 regmap_update_bits(data->regmap, 0x02, BIT(7), 0);
610
611 init.ops = &cdce925_pll_ops;
612 init.flags = 0;
613 init.parent_names = &parent_name;
614 init.num_parents = parent_name ? 1 : 0;
615
616 /* Register PLL clocks */
617 for (i = 0; i < NUMBER_OF_PLLS; ++i) {
618 pll_clk_name[i] = kasprintf(GFP_KERNEL, "%s.pll%d",
619 client->dev.of_node->name, i);
620 init.name = pll_clk_name[i];
621 data->pll[i].chip = data;
622 data->pll[i].hw.init = &init;
623 data->pll[i].index = i;
624 clk = devm_clk_register(&client->dev, &data->pll[i].hw);
625 if (IS_ERR(clk)) {
626 dev_err(&client->dev, "Failed register PLL %d\n", i);
627 err = PTR_ERR(clk);
628 goto error;
629 }
630 sprintf(child_name, "PLL%d", i+1);
631 np_output = of_get_child_by_name(node, child_name);
632 if (!np_output)
633 continue;
634 if (!of_property_read_u32(np_output,
635 "clock-frequency", &value)) {
636 err = clk_set_rate(clk, value);
637 if (err)
638 dev_err(&client->dev,
639 "unable to set PLL frequency %ud\n",
640 value);
641 }
642 if (!of_property_read_u32(np_output,
643 "spread-spectrum", &value)) {
644 u8 flag = of_property_read_bool(np_output,
645 "spread-spectrum-center") ? 0x80 : 0x00;
646 regmap_update_bits(data->regmap,
647 0x16 + (i*CDCE925_OFFSET_PLL),
648 0x80, flag);
649 regmap_update_bits(data->regmap,
650 0x12 + (i*CDCE925_OFFSET_PLL),
651 0x07, value & 0x07);
652 }
653 }
654
655 /* Register output clock Y1 */
656 init.ops = &cdce925_clk_y1_ops;
657 init.flags = 0;
658 init.num_parents = 1;
659 init.parent_names = &parent_name; /* Mux Y1 to input */
660 init.name = kasprintf(GFP_KERNEL, "%s.Y1", client->dev.of_node->name);
661 data->clk[0].chip = data;
662 data->clk[0].hw.init = &init;
663 data->clk[0].index = 0;
664 data->clk[0].pdiv = 1;
665 clk = devm_clk_register(&client->dev, &data->clk[0].hw);
666 kfree(init.name); /* clock framework made a copy of the name */
667 if (IS_ERR(clk)) {
668 dev_err(&client->dev, "clock registration Y1 failed\n");
669 err = PTR_ERR(clk);
670 goto error;
671 }
672 data->dt_clk[0] = clk;
673
674 /* Register output clocks Y2 .. Y5*/
675 init.ops = &cdce925_clk_ops;
676 init.flags = CLK_SET_RATE_PARENT;
677 init.num_parents = 1;
678 for (i = 1; i < NUMBER_OF_OUTPUTS; ++i) {
679 init.name = kasprintf(GFP_KERNEL, "%s.Y%d",
680 client->dev.of_node->name, i+1);
681 data->clk[i].chip = data;
682 data->clk[i].hw.init = &init;
683 data->clk[i].index = i;
684 data->clk[i].pdiv = 1;
685 switch (i) {
686 case 1:
687 case 2:
688 /* Mux Y2/3 to PLL1 */
689 init.parent_names = &pll_clk_name[0];
690 break;
691 case 3:
692 case 4:
693 /* Mux Y4/5 to PLL2 */
694 init.parent_names = &pll_clk_name[1];
695 break;
696 }
697 clk = devm_clk_register(&client->dev, &data->clk[i].hw);
698 kfree(init.name); /* clock framework made a copy of the name */
699 if (IS_ERR(clk)) {
700 dev_err(&client->dev, "clock registration failed\n");
701 err = PTR_ERR(clk);
702 goto error;
703 }
704 data->dt_clk[i] = clk;
705 }
706
707 /* Register the output clocks */
708 data->onecell.clk_num = NUMBER_OF_OUTPUTS;
709 data->onecell.clks = data->dt_clk;
710 err = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
711 &data->onecell);
712 if (err)
713 dev_err(&client->dev, "unable to add OF clock provider\n");
714
715 err = 0;
716
717error:
718 for (i = 0; i < NUMBER_OF_PLLS; ++i)
719 /* clock framework made a copy of the name */
720 kfree(pll_clk_name[i]);
721
722 return err;
723}
724
725static const struct i2c_device_id cdce925_id[] = {
726 { "cdce925", 0 },
727 { }
728};
729MODULE_DEVICE_TABLE(i2c, cdce925_id);
730
731static const struct of_device_id clk_cdce925_of_match[] = {
732 { .compatible = "ti,cdce925" },
733 { },
734};
735MODULE_DEVICE_TABLE(of, clk_cdce925_of_match);
736
737static struct i2c_driver cdce925_driver = {
738 .driver = {
739 .name = "cdce925",
740 .of_match_table = of_match_ptr(clk_cdce925_of_match),
741 },
742 .probe = cdce925_probe,
743 .id_table = cdce925_id,
744};
745module_i2c_driver(cdce925_driver);
746
747MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>");
748MODULE_DESCRIPTION("cdce925 driver");
749MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 956b7e54fa1c..616f5aef3c26 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -188,7 +188,7 @@ static void clk_composite_disable(struct clk_hw *hw)
188} 188}
189 189
190struct clk *clk_register_composite(struct device *dev, const char *name, 190struct clk *clk_register_composite(struct device *dev, const char *name,
191 const char **parent_names, int num_parents, 191 const char * const *parent_names, int num_parents,
192 struct clk_hw *mux_hw, const struct clk_ops *mux_ops, 192 struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
193 struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 193 struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
194 struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 194 struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
@@ -200,10 +200,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
200 struct clk_ops *clk_composite_ops; 200 struct clk_ops *clk_composite_ops;
201 201
202 composite = kzalloc(sizeof(*composite), GFP_KERNEL); 202 composite = kzalloc(sizeof(*composite), GFP_KERNEL);
203 if (!composite) { 203 if (!composite)
204 pr_err("%s: could not allocate composite clk\n", __func__);
205 return ERR_PTR(-ENOMEM); 204 return ERR_PTR(-ENOMEM);
206 }
207 205
208 init.name = name; 206 init.name = name;
209 init.flags = flags | CLK_IS_BASIC; 207 init.flags = flags | CLK_IS_BASIC;
diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
index 48a65b2b4027..43a218f35b19 100644
--- a/drivers/clk/clk-conf.c
+++ b/drivers/clk/clk-conf.c
@@ -106,8 +106,9 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
106 106
107 rc = clk_set_rate(clk, rate); 107 rc = clk_set_rate(clk, rate);
108 if (rc < 0) 108 if (rc < 0)
109 pr_err("clk: couldn't set %s clock rate: %d\n", 109 pr_err("clk: couldn't set %s clk rate to %d (%d), current rate: %ld\n",
110 __clk_get_name(clk), rc); 110 __clk_get_name(clk), rate, rc,
111 clk_get_rate(clk));
111 clk_put(clk); 112 clk_put(clk);
112 } 113 }
113 index++; 114 index++;
@@ -124,7 +125,7 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
124 * and sets any specified clock parents and rates. The @clk_supplier argument 125 * and sets any specified clock parents and rates. The @clk_supplier argument
125 * should be set to true if @node may be also a clock supplier of any clock 126 * should be set to true if @node may be also a clock supplier of any clock
126 * listed in its 'assigned-clocks' or 'assigned-clock-parents' properties. 127 * listed in its 'assigned-clocks' or 'assigned-clock-parents' properties.
127 * If @clk_supplier is false the function exits returnning 0 as soon as it 128 * If @clk_supplier is false the function exits returning 0 as soon as it
128 * determines the @node is also a supplier of any of the clocks. 129 * determines the @node is also a supplier of any of the clocks.
129 */ 130 */
130int of_clk_set_defaults(struct device_node *node, bool clk_supplier) 131int of_clk_set_defaults(struct device_node *node, bool clk_supplier)
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 25006a8bb8e6..706b5783c360 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -430,11 +430,9 @@ static struct clk *_register_divider(struct device *dev, const char *name,
430 } 430 }
431 431
432 /* allocate the divider */ 432 /* allocate the divider */
433 div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL); 433 div = kzalloc(sizeof(*div), GFP_KERNEL);
434 if (!div) { 434 if (!div)
435 pr_err("%s: could not allocate divider clk\n", __func__);
436 return ERR_PTR(-ENOMEM); 435 return ERR_PTR(-ENOMEM);
437 }
438 436
439 init.name = name; 437 init.name = name;
440 init.ops = &clk_divider_ops; 438 init.ops = &clk_divider_ops;
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c
index d9e3f671c2ea..fccabe497f6e 100644
--- a/drivers/clk/clk-fixed-factor.c
+++ b/drivers/clk/clk-fixed-factor.c
@@ -55,10 +55,16 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
55static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate, 55static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,
56 unsigned long parent_rate) 56 unsigned long parent_rate)
57{ 57{
58 /*
59 * We must report success but we can do so unconditionally because
60 * clk_factor_round_rate returns values that ensure this call is a
61 * nop.
62 */
63
58 return 0; 64 return 0;
59} 65}
60 66
61struct clk_ops clk_fixed_factor_ops = { 67const struct clk_ops clk_fixed_factor_ops = {
62 .round_rate = clk_factor_round_rate, 68 .round_rate = clk_factor_round_rate,
63 .set_rate = clk_factor_set_rate, 69 .set_rate = clk_factor_set_rate,
64 .recalc_rate = clk_factor_recalc_rate, 70 .recalc_rate = clk_factor_recalc_rate,
@@ -74,10 +80,8 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
74 struct clk *clk; 80 struct clk *clk;
75 81
76 fix = kmalloc(sizeof(*fix), GFP_KERNEL); 82 fix = kmalloc(sizeof(*fix), GFP_KERNEL);
77 if (!fix) { 83 if (!fix)
78 pr_err("%s: could not allocate fixed factor clk\n", __func__);
79 return ERR_PTR(-ENOMEM); 84 return ERR_PTR(-ENOMEM);
80 }
81 85
82 /* struct clk_fixed_factor assignments */ 86 /* struct clk_fixed_factor assignments */
83 fix->mult = mult; 87 fix->mult = mult;
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c
index 0fc56ab6e844..f85ec8d1711f 100644
--- a/drivers/clk/clk-fixed-rate.c
+++ b/drivers/clk/clk-fixed-rate.c
@@ -65,11 +65,9 @@ struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
65 struct clk_init_data init; 65 struct clk_init_data init;
66 66
67 /* allocate fixed-rate clock */ 67 /* allocate fixed-rate clock */
68 fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL); 68 fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
69 if (!fixed) { 69 if (!fixed)
70 pr_err("%s: could not allocate fixed clk\n", __func__);
71 return ERR_PTR(-ENOMEM); 70 return ERR_PTR(-ENOMEM);
72 }
73 71
74 init.name = name; 72 init.name = name;
75 init.ops = &clk_fixed_rate_ops; 73 init.ops = &clk_fixed_rate_ops;
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 6aa72d9d79ba..140eb5844dc4 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -109,10 +109,8 @@ struct clk *clk_register_fractional_divider(struct device *dev,
109 struct clk *clk; 109 struct clk *clk;
110 110
111 fd = kzalloc(sizeof(*fd), GFP_KERNEL); 111 fd = kzalloc(sizeof(*fd), GFP_KERNEL);
112 if (!fd) { 112 if (!fd)
113 dev_err(dev, "could not allocate fractional divider clk\n");
114 return ERR_PTR(-ENOMEM); 113 return ERR_PTR(-ENOMEM);
115 }
116 114
117 init.name = name; 115 init.name = name;
118 init.ops = &clk_fractional_divider_ops; 116 init.ops = &clk_fractional_divider_ops;
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 3f0e4200cb5d..551dd0672794 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -135,11 +135,9 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
135 } 135 }
136 136
137 /* allocate the gate */ 137 /* allocate the gate */
138 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); 138 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
139 if (!gate) { 139 if (!gate)
140 pr_err("%s: could not allocate gated clk\n", __func__);
141 return ERR_PTR(-ENOMEM); 140 return ERR_PTR(-ENOMEM);
142 }
143 141
144 init.name = name; 142 init.name = name;
145 init.ops = &clk_gate_ops; 143 init.ops = &clk_gate_ops;
diff --git a/drivers/clk/clk-gpio-gate.c b/drivers/clk/clk-gpio-gate.c
index a71cabedda93..f564e624fb93 100644
--- a/drivers/clk/clk-gpio-gate.c
+++ b/drivers/clk/clk-gpio-gate.c
@@ -189,7 +189,7 @@ static struct clk *of_clk_gpio_gate_delayed_register_get(
189/** 189/**
190 * of_gpio_gate_clk_setup() - Setup function for gpio controlled clock 190 * of_gpio_gate_clk_setup() - Setup function for gpio controlled clock
191 */ 191 */
192void __init of_gpio_gate_clk_setup(struct device_node *node) 192static void __init of_gpio_gate_clk_setup(struct device_node *node)
193{ 193{
194 struct clk_gpio_gate_delayed_register_data *data; 194 struct clk_gpio_gate_delayed_register_data *data;
195 195
@@ -203,6 +203,5 @@ void __init of_gpio_gate_clk_setup(struct device_node *node)
203 203
204 of_clk_add_provider(node, of_clk_gpio_gate_delayed_register_get, data); 204 of_clk_add_provider(node, of_clk_gpio_gate_delayed_register_get, data);
205} 205}
206EXPORT_SYMBOL_GPL(of_gpio_gate_clk_setup);
207CLK_OF_DECLARE(gpio_gate_clk, "gpio-gate-clock", of_gpio_gate_clk_setup); 206CLK_OF_DECLARE(gpio_gate_clk, "gpio-gate-clock", of_gpio_gate_clk_setup);
208#endif 207#endif
diff --git a/drivers/clk/clk-ls1x.c b/drivers/clk/clk-ls1x.c
index ca80103ac188..d4c61985f448 100644
--- a/drivers/clk/clk-ls1x.c
+++ b/drivers/clk/clk-ls1x.c
@@ -80,9 +80,9 @@ static struct clk *__init clk_register_pll(struct device *dev,
80 return clk; 80 return clk;
81} 81}
82 82
83static const char const *cpu_parents[] = { "cpu_clk_div", "osc_33m_clk", }; 83static const char * const cpu_parents[] = { "cpu_clk_div", "osc_33m_clk", };
84static const char const *ahb_parents[] = { "ahb_clk_div", "osc_33m_clk", }; 84static const char * const ahb_parents[] = { "ahb_clk_div", "osc_33m_clk", };
85static const char const *dc_parents[] = { "dc_clk_div", "osc_33m_clk", }; 85static const char * const dc_parents[] = { "dc_clk_div", "osc_33m_clk", };
86 86
87void __init ls1x_clk_init(void) 87void __init ls1x_clk_init(void)
88{ 88{
diff --git a/drivers/clk/clk-max-gen.c b/drivers/clk/clk-max-gen.c
index 6505049d50f1..35af9cb6da4f 100644
--- a/drivers/clk/clk-max-gen.c
+++ b/drivers/clk/clk-max-gen.c
@@ -31,6 +31,8 @@
31#include <linux/of.h> 31#include <linux/of.h>
32#include <linux/export.h> 32#include <linux/export.h>
33 33
34#include "clk-max-gen.h"
35
34struct max_gen_clk { 36struct max_gen_clk {
35 struct regmap *regmap; 37 struct regmap *regmap;
36 u32 mask; 38 u32 mask;
diff --git a/drivers/clk/clk-moxart.c b/drivers/clk/clk-moxart.c
index 30a3b6999e10..5181b89c3cb2 100644
--- a/drivers/clk/clk-moxart.c
+++ b/drivers/clk/clk-moxart.c
@@ -15,7 +15,7 @@
15#include <linux/of_address.h> 15#include <linux/of_address.h>
16#include <linux/clkdev.h> 16#include <linux/clkdev.h>
17 17
18void __init moxart_of_pll_clk_init(struct device_node *node) 18static void __init moxart_of_pll_clk_init(struct device_node *node)
19{ 19{
20 static void __iomem *base; 20 static void __iomem *base;
21 struct clk *clk, *ref_clk; 21 struct clk *clk, *ref_clk;
@@ -53,7 +53,7 @@ void __init moxart_of_pll_clk_init(struct device_node *node)
53CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock", 53CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
54 moxart_of_pll_clk_init); 54 moxart_of_pll_clk_init);
55 55
56void __init moxart_of_apb_clk_init(struct device_node *node) 56static void __init moxart_of_apb_clk_init(struct device_node *node)
57{ 57{
58 static void __iomem *base; 58 static void __iomem *base;
59 struct clk *clk, *pll_clk; 59 struct clk *clk, *pll_clk;
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 69a094c3783d..6066a01b20ea 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -114,7 +114,8 @@ const struct clk_ops clk_mux_ro_ops = {
114EXPORT_SYMBOL_GPL(clk_mux_ro_ops); 114EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
115 115
116struct clk *clk_register_mux_table(struct device *dev, const char *name, 116struct clk *clk_register_mux_table(struct device *dev, const char *name,
117 const char **parent_names, u8 num_parents, unsigned long flags, 117 const char * const *parent_names, u8 num_parents,
118 unsigned long flags,
118 void __iomem *reg, u8 shift, u32 mask, 119 void __iomem *reg, u8 shift, u32 mask,
119 u8 clk_mux_flags, u32 *table, spinlock_t *lock) 120 u8 clk_mux_flags, u32 *table, spinlock_t *lock)
120{ 121{
@@ -166,7 +167,8 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
166EXPORT_SYMBOL_GPL(clk_register_mux_table); 167EXPORT_SYMBOL_GPL(clk_register_mux_table);
167 168
168struct clk *clk_register_mux(struct device *dev, const char *name, 169struct clk *clk_register_mux(struct device *dev, const char *name,
169 const char **parent_names, u8 num_parents, unsigned long flags, 170 const char * const *parent_names, u8 num_parents,
171 unsigned long flags,
170 void __iomem *reg, u8 shift, u8 width, 172 void __iomem *reg, u8 shift, u8 width,
171 u8 clk_mux_flags, spinlock_t *lock) 173 u8 clk_mux_flags, spinlock_t *lock)
172{ 174{
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 30335d3b99af..e39e1e680b3c 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -552,7 +552,8 @@ static const struct clk_ops si5351_pll_ops = {
552 * MSx_P2[19:0] = 128 * b - c * floor(128 * b/c) = (128*b) mod c 552 * MSx_P2[19:0] = 128 * b - c * floor(128 * b/c) = (128*b) mod c
553 * MSx_P3[19:0] = c 553 * MSx_P3[19:0] = c
554 * 554 *
555 * MS[6,7] are integer (P1) divide only, P2 = 0, P3 = 0 555 * MS[6,7] are integer (P1) divide only, P1 = divide value,
556 * P2 and P3 are not applicable
556 * 557 *
557 * for 150MHz < fOUT <= 160MHz: 558 * for 150MHz < fOUT <= 160MHz:
558 * 559 *
@@ -606,9 +607,6 @@ static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw,
606 if (!hwdata->params.valid) 607 if (!hwdata->params.valid)
607 si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params); 608 si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
608 609
609 if (hwdata->params.p3 == 0)
610 return parent_rate;
611
612 /* 610 /*
613 * multisync0-5: fOUT = (128 * P3 * fIN) / (P1*P3 + P2 + 512*P3) 611 * multisync0-5: fOUT = (128 * P3 * fIN) / (P1*P3 + P2 + 512*P3)
614 * multisync6-7: fOUT = fIN / P1 612 * multisync6-7: fOUT = fIN / P1
@@ -616,6 +614,8 @@ static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw,
616 rate = parent_rate; 614 rate = parent_rate;
617 if (hwdata->num > 5) { 615 if (hwdata->num > 5) {
618 m = hwdata->params.p1; 616 m = hwdata->params.p1;
617 } else if (hwdata->params.p3 == 0) {
618 return parent_rate;
619 } else if ((si5351_reg_read(hwdata->drvdata, reg + 2) & 619 } else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
620 SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) { 620 SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) {
621 m = 4; 621 m = 4;
@@ -679,6 +679,16 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
679 c = 1; 679 c = 1;
680 680
681 *parent_rate = a * rate; 681 *parent_rate = a * rate;
682 } else if (hwdata->num >= 6) {
683 /* determine the closest integer divider */
684 a = DIV_ROUND_CLOSEST(*parent_rate, rate);
685 if (a < SI5351_MULTISYNTH_A_MIN)
686 a = SI5351_MULTISYNTH_A_MIN;
687 if (a > SI5351_MULTISYNTH67_A_MAX)
688 a = SI5351_MULTISYNTH67_A_MAX;
689
690 b = 0;
691 c = 1;
682 } else { 692 } else {
683 unsigned long rfrac, denom; 693 unsigned long rfrac, denom;
684 694
@@ -692,9 +702,7 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
692 a = *parent_rate / rate; 702 a = *parent_rate / rate;
693 if (a < SI5351_MULTISYNTH_A_MIN) 703 if (a < SI5351_MULTISYNTH_A_MIN)
694 a = SI5351_MULTISYNTH_A_MIN; 704 a = SI5351_MULTISYNTH_A_MIN;
695 if (hwdata->num >= 6 && a > SI5351_MULTISYNTH67_A_MAX) 705 if (a > SI5351_MULTISYNTH_A_MAX)
696 a = SI5351_MULTISYNTH67_A_MAX;
697 else if (a > SI5351_MULTISYNTH_A_MAX)
698 a = SI5351_MULTISYNTH_A_MAX; 706 a = SI5351_MULTISYNTH_A_MAX;
699 707
700 /* find best approximation for b/c = fVCO mod fOUT */ 708 /* find best approximation for b/c = fVCO mod fOUT */
@@ -723,6 +731,10 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
723 hwdata->params.p3 = 1; 731 hwdata->params.p3 = 1;
724 hwdata->params.p2 = 0; 732 hwdata->params.p2 = 0;
725 hwdata->params.p1 = 0; 733 hwdata->params.p1 = 0;
734 } else if (hwdata->num >= 6) {
735 hwdata->params.p3 = 0;
736 hwdata->params.p2 = 0;
737 hwdata->params.p1 = a;
726 } else { 738 } else {
727 hwdata->params.p3 = c; 739 hwdata->params.p3 = c;
728 hwdata->params.p2 = (128 * b) % c; 740 hwdata->params.p2 = (128 * b) % c;
diff --git a/drivers/clk/clk-u300.c b/drivers/clk/clk-u300.c
index 406bfc1375b2..18bf5e576b93 100644
--- a/drivers/clk/clk-u300.c
+++ b/drivers/clk/clk-u300.c
@@ -12,6 +12,7 @@
12#include <linux/clk-provider.h> 12#include <linux/clk-provider.h>
13#include <linux/spinlock.h> 13#include <linux/spinlock.h>
14#include <linux/of.h> 14#include <linux/of.h>
15#include <linux/platform_data/clk-u300.h>
15 16
16/* APP side SYSCON registers */ 17/* APP side SYSCON registers */
17/* CLK Control Register 16bit (R/W) */ 18/* CLK Control Register 16bit (R/W) */
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index dd8a62d8f11f..f26b3ac36b27 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -42,12 +42,12 @@
42 42
43static DEFINE_SPINLOCK(clk_lock); 43static DEFINE_SPINLOCK(clk_lock);
44 44
45static inline u32 xgene_clk_read(void *csr) 45static inline u32 xgene_clk_read(void __iomem *csr)
46{ 46{
47 return readl_relaxed(csr); 47 return readl_relaxed(csr);
48} 48}
49 49
50static inline void xgene_clk_write(u32 data, void *csr) 50static inline void xgene_clk_write(u32 data, void __iomem *csr)
51{ 51{
52 return writel_relaxed(data, csr); 52 return writel_relaxed(data, csr);
53} 53}
@@ -119,7 +119,7 @@ static unsigned long xgene_clk_pll_recalc_rate(struct clk_hw *hw,
119 return fvco / nout; 119 return fvco / nout;
120} 120}
121 121
122const struct clk_ops xgene_clk_pll_ops = { 122static const struct clk_ops xgene_clk_pll_ops = {
123 .is_enabled = xgene_clk_pll_is_enabled, 123 .is_enabled = xgene_clk_pll_is_enabled,
124 .recalc_rate = xgene_clk_pll_recalc_rate, 124 .recalc_rate = xgene_clk_pll_recalc_rate,
125}; 125};
@@ -167,7 +167,7 @@ static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_ty
167{ 167{
168 const char *clk_name = np->full_name; 168 const char *clk_name = np->full_name;
169 struct clk *clk; 169 struct clk *clk;
170 void *reg; 170 void __iomem *reg;
171 171
172 reg = of_iomap(np, 0); 172 reg = of_iomap(np, 0);
173 if (reg == NULL) { 173 if (reg == NULL) {
@@ -222,20 +222,22 @@ static int xgene_clk_enable(struct clk_hw *hw)
222 struct xgene_clk *pclk = to_xgene_clk(hw); 222 struct xgene_clk *pclk = to_xgene_clk(hw);
223 unsigned long flags = 0; 223 unsigned long flags = 0;
224 u32 data; 224 u32 data;
225 phys_addr_t reg;
225 226
226 if (pclk->lock) 227 if (pclk->lock)
227 spin_lock_irqsave(pclk->lock, flags); 228 spin_lock_irqsave(pclk->lock, flags);
228 229
229 if (pclk->param.csr_reg != NULL) { 230 if (pclk->param.csr_reg != NULL) {
230 pr_debug("%s clock enabled\n", pclk->name); 231 pr_debug("%s clock enabled\n", pclk->name);
232 reg = __pa(pclk->param.csr_reg);
231 /* First enable the clock */ 233 /* First enable the clock */
232 data = xgene_clk_read(pclk->param.csr_reg + 234 data = xgene_clk_read(pclk->param.csr_reg +
233 pclk->param.reg_clk_offset); 235 pclk->param.reg_clk_offset);
234 data |= pclk->param.reg_clk_mask; 236 data |= pclk->param.reg_clk_mask;
235 xgene_clk_write(data, pclk->param.csr_reg + 237 xgene_clk_write(data, pclk->param.csr_reg +
236 pclk->param.reg_clk_offset); 238 pclk->param.reg_clk_offset);
237 pr_debug("%s clock PADDR base 0x%016LX clk offset 0x%08X mask 0x%08X value 0x%08X\n", 239 pr_debug("%s clock PADDR base %pa clk offset 0x%08X mask 0x%08X value 0x%08X\n",
238 pclk->name, __pa(pclk->param.csr_reg), 240 pclk->name, &reg,
239 pclk->param.reg_clk_offset, pclk->param.reg_clk_mask, 241 pclk->param.reg_clk_offset, pclk->param.reg_clk_mask,
240 data); 242 data);
241 243
@@ -245,8 +247,8 @@ static int xgene_clk_enable(struct clk_hw *hw)
245 data &= ~pclk->param.reg_csr_mask; 247 data &= ~pclk->param.reg_csr_mask;
246 xgene_clk_write(data, pclk->param.csr_reg + 248 xgene_clk_write(data, pclk->param.csr_reg +
247 pclk->param.reg_csr_offset); 249 pclk->param.reg_csr_offset);
248 pr_debug("%s CSR RESET PADDR base 0x%016LX csr offset 0x%08X mask 0x%08X value 0x%08X\n", 250 pr_debug("%s CSR RESET PADDR base %pa csr offset 0x%08X mask 0x%08X value 0x%08X\n",
249 pclk->name, __pa(pclk->param.csr_reg), 251 pclk->name, &reg,
250 pclk->param.reg_csr_offset, pclk->param.reg_csr_mask, 252 pclk->param.reg_csr_offset, pclk->param.reg_csr_mask,
251 data); 253 data);
252 } 254 }
@@ -386,7 +388,7 @@ static long xgene_clk_round_rate(struct clk_hw *hw, unsigned long rate,
386 return parent_rate / divider; 388 return parent_rate / divider;
387} 389}
388 390
389const struct clk_ops xgene_clk_ops = { 391static const struct clk_ops xgene_clk_ops = {
390 .enable = xgene_clk_enable, 392 .enable = xgene_clk_enable,
391 .disable = xgene_clk_disable, 393 .disable = xgene_clk_disable,
392 .is_enabled = xgene_clk_is_enabled, 394 .is_enabled = xgene_clk_is_enabled,
@@ -456,7 +458,7 @@ static void __init xgene_devclk_init(struct device_node *np)
456 parameters.csr_reg = NULL; 458 parameters.csr_reg = NULL;
457 parameters.divider_reg = NULL; 459 parameters.divider_reg = NULL;
458 for (i = 0; i < 2; i++) { 460 for (i = 0; i < 2; i++) {
459 void *map_res; 461 void __iomem *map_res;
460 rc = of_address_to_resource(np, i, &res); 462 rc = of_address_to_resource(np, i, &res);
461 if (rc != 0) { 463 if (rc != 0) {
462 if (i == 0) { 464 if (i == 0) {
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 5b0f41868b42..1cf479b9f3b4 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -21,6 +21,7 @@
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/sched.h> 23#include <linux/sched.h>
24#include <linux/clkdev.h>
24 25
25#include "clk.h" 26#include "clk.h"
26 27
@@ -37,13 +38,6 @@ static HLIST_HEAD(clk_root_list);
37static HLIST_HEAD(clk_orphan_list); 38static HLIST_HEAD(clk_orphan_list);
38static LIST_HEAD(clk_notifier_list); 39static LIST_HEAD(clk_notifier_list);
39 40
40static long clk_core_get_accuracy(struct clk_core *clk);
41static unsigned long clk_core_get_rate(struct clk_core *clk);
42static int clk_core_get_phase(struct clk_core *clk);
43static bool clk_core_is_prepared(struct clk_core *clk);
44static bool clk_core_is_enabled(struct clk_core *clk);
45static struct clk_core *clk_core_lookup(const char *name);
46
47/*** private data structures ***/ 41/*** private data structures ***/
48 42
49struct clk_core { 43struct clk_core {
@@ -68,11 +62,11 @@ struct clk_core {
68 int phase; 62 int phase;
69 struct hlist_head children; 63 struct hlist_head children;
70 struct hlist_node child_node; 64 struct hlist_node child_node;
71 struct hlist_node debug_node;
72 struct hlist_head clks; 65 struct hlist_head clks;
73 unsigned int notifier_count; 66 unsigned int notifier_count;
74#ifdef CONFIG_DEBUG_FS 67#ifdef CONFIG_DEBUG_FS
75 struct dentry *dentry; 68 struct dentry *dentry;
69 struct hlist_node debug_node;
76#endif 70#endif
77 struct kref ref; 71 struct kref ref;
78}; 72};
@@ -145,382 +139,71 @@ static void clk_enable_unlock(unsigned long flags)
145 spin_unlock_irqrestore(&enable_lock, flags); 139 spin_unlock_irqrestore(&enable_lock, flags);
146} 140}
147 141
148/*** debugfs support ***/ 142static bool clk_core_is_prepared(struct clk_core *core)
149
150#ifdef CONFIG_DEBUG_FS
151#include <linux/debugfs.h>
152
153static struct dentry *rootdir;
154static int inited = 0;
155static DEFINE_MUTEX(clk_debug_lock);
156static HLIST_HEAD(clk_debug_list);
157
158static struct hlist_head *all_lists[] = {
159 &clk_root_list,
160 &clk_orphan_list,
161 NULL,
162};
163
164static struct hlist_head *orphan_list[] = {
165 &clk_orphan_list,
166 NULL,
167};
168
169static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
170 int level)
171{
172 if (!c)
173 return;
174
175 seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d\n",
176 level * 3 + 1, "",
177 30 - level * 3, c->name,
178 c->enable_count, c->prepare_count, clk_core_get_rate(c),
179 clk_core_get_accuracy(c), clk_core_get_phase(c));
180}
181
182static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
183 int level)
184{
185 struct clk_core *child;
186
187 if (!c)
188 return;
189
190 clk_summary_show_one(s, c, level);
191
192 hlist_for_each_entry(child, &c->children, child_node)
193 clk_summary_show_subtree(s, child, level + 1);
194}
195
196static int clk_summary_show(struct seq_file *s, void *data)
197{
198 struct clk_core *c;
199 struct hlist_head **lists = (struct hlist_head **)s->private;
200
201 seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy phase\n");
202 seq_puts(s, "----------------------------------------------------------------------------------------\n");
203
204 clk_prepare_lock();
205
206 for (; *lists; lists++)
207 hlist_for_each_entry(c, *lists, child_node)
208 clk_summary_show_subtree(s, c, 0);
209
210 clk_prepare_unlock();
211
212 return 0;
213}
214
215
216static int clk_summary_open(struct inode *inode, struct file *file)
217{ 143{
218 return single_open(file, clk_summary_show, inode->i_private); 144 /*
219} 145 * .is_prepared is optional for clocks that can prepare
220 146 * fall back to software usage counter if it is missing
221static const struct file_operations clk_summary_fops = { 147 */
222 .open = clk_summary_open, 148 if (!core->ops->is_prepared)
223 .read = seq_read, 149 return core->prepare_count;
224 .llseek = seq_lseek,
225 .release = single_release,
226};
227
228static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
229{
230 if (!c)
231 return;
232
233 seq_printf(s, "\"%s\": { ", c->name);
234 seq_printf(s, "\"enable_count\": %d,", c->enable_count);
235 seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
236 seq_printf(s, "\"rate\": %lu", clk_core_get_rate(c));
237 seq_printf(s, "\"accuracy\": %lu", clk_core_get_accuracy(c));
238 seq_printf(s, "\"phase\": %d", clk_core_get_phase(c));
239}
240
241static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
242{
243 struct clk_core *child;
244
245 if (!c)
246 return;
247
248 clk_dump_one(s, c, level);
249
250 hlist_for_each_entry(child, &c->children, child_node) {
251 seq_printf(s, ",");
252 clk_dump_subtree(s, child, level + 1);
253 }
254
255 seq_printf(s, "}");
256}
257
258static int clk_dump(struct seq_file *s, void *data)
259{
260 struct clk_core *c;
261 bool first_node = true;
262 struct hlist_head **lists = (struct hlist_head **)s->private;
263
264 seq_printf(s, "{");
265
266 clk_prepare_lock();
267
268 for (; *lists; lists++) {
269 hlist_for_each_entry(c, *lists, child_node) {
270 if (!first_node)
271 seq_puts(s, ",");
272 first_node = false;
273 clk_dump_subtree(s, c, 0);
274 }
275 }
276
277 clk_prepare_unlock();
278
279 seq_printf(s, "}");
280 return 0;
281}
282
283
284static int clk_dump_open(struct inode *inode, struct file *file)
285{
286 return single_open(file, clk_dump, inode->i_private);
287}
288
289static const struct file_operations clk_dump_fops = {
290 .open = clk_dump_open,
291 .read = seq_read,
292 .llseek = seq_lseek,
293 .release = single_release,
294};
295
296static int clk_debug_create_one(struct clk_core *clk, struct dentry *pdentry)
297{
298 struct dentry *d;
299 int ret = -ENOMEM;
300
301 if (!clk || !pdentry) {
302 ret = -EINVAL;
303 goto out;
304 }
305
306 d = debugfs_create_dir(clk->name, pdentry);
307 if (!d)
308 goto out;
309
310 clk->dentry = d;
311
312 d = debugfs_create_u32("clk_rate", S_IRUGO, clk->dentry,
313 (u32 *)&clk->rate);
314 if (!d)
315 goto err_out;
316
317 d = debugfs_create_u32("clk_accuracy", S_IRUGO, clk->dentry,
318 (u32 *)&clk->accuracy);
319 if (!d)
320 goto err_out;
321
322 d = debugfs_create_u32("clk_phase", S_IRUGO, clk->dentry,
323 (u32 *)&clk->phase);
324 if (!d)
325 goto err_out;
326
327 d = debugfs_create_x32("clk_flags", S_IRUGO, clk->dentry,
328 (u32 *)&clk->flags);
329 if (!d)
330 goto err_out;
331
332 d = debugfs_create_u32("clk_prepare_count", S_IRUGO, clk->dentry,
333 (u32 *)&clk->prepare_count);
334 if (!d)
335 goto err_out;
336
337 d = debugfs_create_u32("clk_enable_count", S_IRUGO, clk->dentry,
338 (u32 *)&clk->enable_count);
339 if (!d)
340 goto err_out;
341
342 d = debugfs_create_u32("clk_notifier_count", S_IRUGO, clk->dentry,
343 (u32 *)&clk->notifier_count);
344 if (!d)
345 goto err_out;
346
347 if (clk->ops->debug_init) {
348 ret = clk->ops->debug_init(clk->hw, clk->dentry);
349 if (ret)
350 goto err_out;
351 }
352
353 ret = 0;
354 goto out;
355
356err_out:
357 debugfs_remove_recursive(clk->dentry);
358 clk->dentry = NULL;
359out:
360 return ret;
361}
362
363/**
364 * clk_debug_register - add a clk node to the debugfs clk tree
365 * @clk: the clk being added to the debugfs clk tree
366 *
367 * Dynamically adds a clk to the debugfs clk tree if debugfs has been
368 * initialized. Otherwise it bails out early since the debugfs clk tree
369 * will be created lazily by clk_debug_init as part of a late_initcall.
370 */
371static int clk_debug_register(struct clk_core *clk)
372{
373 int ret = 0;
374
375 mutex_lock(&clk_debug_lock);
376 hlist_add_head(&clk->debug_node, &clk_debug_list);
377
378 if (!inited)
379 goto unlock;
380
381 ret = clk_debug_create_one(clk, rootdir);
382unlock:
383 mutex_unlock(&clk_debug_lock);
384
385 return ret;
386}
387
388 /**
389 * clk_debug_unregister - remove a clk node from the debugfs clk tree
390 * @clk: the clk being removed from the debugfs clk tree
391 *
392 * Dynamically removes a clk and all it's children clk nodes from the
393 * debugfs clk tree if clk->dentry points to debugfs created by
394 * clk_debug_register in __clk_init.
395 */
396static void clk_debug_unregister(struct clk_core *clk)
397{
398 mutex_lock(&clk_debug_lock);
399 hlist_del_init(&clk->debug_node);
400 debugfs_remove_recursive(clk->dentry);
401 clk->dentry = NULL;
402 mutex_unlock(&clk_debug_lock);
403}
404
405struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode,
406 void *data, const struct file_operations *fops)
407{
408 struct dentry *d = NULL;
409
410 if (hw->core->dentry)
411 d = debugfs_create_file(name, mode, hw->core->dentry, data,
412 fops);
413 150
414 return d; 151 return core->ops->is_prepared(core->hw);
415} 152}
416EXPORT_SYMBOL_GPL(clk_debugfs_add_file);
417 153
418/** 154static bool clk_core_is_enabled(struct clk_core *core)
419 * clk_debug_init - lazily create the debugfs clk tree visualization
420 *
421 * clks are often initialized very early during boot before memory can
422 * be dynamically allocated and well before debugfs is setup.
423 * clk_debug_init walks the clk tree hierarchy while holding
424 * prepare_lock and creates the topology as part of a late_initcall,
425 * thus insuring that clks initialized very early will still be
426 * represented in the debugfs clk tree. This function should only be
427 * called once at boot-time, and all other clks added dynamically will
428 * be done so with clk_debug_register.
429 */
430static int __init clk_debug_init(void)
431{ 155{
432 struct clk_core *clk; 156 /*
433 struct dentry *d; 157 * .is_enabled is only mandatory for clocks that gate
434 158 * fall back to software usage counter if .is_enabled is missing
435 rootdir = debugfs_create_dir("clk", NULL); 159 */
436 160 if (!core->ops->is_enabled)
437 if (!rootdir) 161 return core->enable_count;
438 return -ENOMEM;
439
440 d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, &all_lists,
441 &clk_summary_fops);
442 if (!d)
443 return -ENOMEM;
444
445 d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, &all_lists,
446 &clk_dump_fops);
447 if (!d)
448 return -ENOMEM;
449
450 d = debugfs_create_file("clk_orphan_summary", S_IRUGO, rootdir,
451 &orphan_list, &clk_summary_fops);
452 if (!d)
453 return -ENOMEM;
454
455 d = debugfs_create_file("clk_orphan_dump", S_IRUGO, rootdir,
456 &orphan_list, &clk_dump_fops);
457 if (!d)
458 return -ENOMEM;
459
460 mutex_lock(&clk_debug_lock);
461 hlist_for_each_entry(clk, &clk_debug_list, debug_node)
462 clk_debug_create_one(clk, rootdir);
463
464 inited = 1;
465 mutex_unlock(&clk_debug_lock);
466 162
467 return 0; 163 return core->ops->is_enabled(core->hw);
468} 164}
469late_initcall(clk_debug_init);
470#else
471static inline int clk_debug_register(struct clk_core *clk) { return 0; }
472static inline void clk_debug_reparent(struct clk_core *clk,
473 struct clk_core *new_parent)
474{
475}
476static inline void clk_debug_unregister(struct clk_core *clk)
477{
478}
479#endif
480 165
481/* caller must hold prepare_lock */ 166static void clk_unprepare_unused_subtree(struct clk_core *core)
482static void clk_unprepare_unused_subtree(struct clk_core *clk)
483{ 167{
484 struct clk_core *child; 168 struct clk_core *child;
485 169
486 lockdep_assert_held(&prepare_lock); 170 lockdep_assert_held(&prepare_lock);
487 171
488 hlist_for_each_entry(child, &clk->children, child_node) 172 hlist_for_each_entry(child, &core->children, child_node)
489 clk_unprepare_unused_subtree(child); 173 clk_unprepare_unused_subtree(child);
490 174
491 if (clk->prepare_count) 175 if (core->prepare_count)
492 return; 176 return;
493 177
494 if (clk->flags & CLK_IGNORE_UNUSED) 178 if (core->flags & CLK_IGNORE_UNUSED)
495 return; 179 return;
496 180
497 if (clk_core_is_prepared(clk)) { 181 if (clk_core_is_prepared(core)) {
498 trace_clk_unprepare(clk); 182 trace_clk_unprepare(core);
499 if (clk->ops->unprepare_unused) 183 if (core->ops->unprepare_unused)
500 clk->ops->unprepare_unused(clk->hw); 184 core->ops->unprepare_unused(core->hw);
501 else if (clk->ops->unprepare) 185 else if (core->ops->unprepare)
502 clk->ops->unprepare(clk->hw); 186 core->ops->unprepare(core->hw);
503 trace_clk_unprepare_complete(clk); 187 trace_clk_unprepare_complete(core);
504 } 188 }
505} 189}
506 190
507/* caller must hold prepare_lock */ 191static void clk_disable_unused_subtree(struct clk_core *core)
508static void clk_disable_unused_subtree(struct clk_core *clk)
509{ 192{
510 struct clk_core *child; 193 struct clk_core *child;
511 unsigned long flags; 194 unsigned long flags;
512 195
513 lockdep_assert_held(&prepare_lock); 196 lockdep_assert_held(&prepare_lock);
514 197
515 hlist_for_each_entry(child, &clk->children, child_node) 198 hlist_for_each_entry(child, &core->children, child_node)
516 clk_disable_unused_subtree(child); 199 clk_disable_unused_subtree(child);
517 200
518 flags = clk_enable_lock(); 201 flags = clk_enable_lock();
519 202
520 if (clk->enable_count) 203 if (core->enable_count)
521 goto unlock_out; 204 goto unlock_out;
522 205
523 if (clk->flags & CLK_IGNORE_UNUSED) 206 if (core->flags & CLK_IGNORE_UNUSED)
524 goto unlock_out; 207 goto unlock_out;
525 208
526 /* 209 /*
@@ -528,13 +211,13 @@ static void clk_disable_unused_subtree(struct clk_core *clk)
528 * sequence. call .disable_unused if available, otherwise fall 211 * sequence. call .disable_unused if available, otherwise fall
529 * back to .disable 212 * back to .disable
530 */ 213 */
531 if (clk_core_is_enabled(clk)) { 214 if (clk_core_is_enabled(core)) {
532 trace_clk_disable(clk); 215 trace_clk_disable(core);
533 if (clk->ops->disable_unused) 216 if (core->ops->disable_unused)
534 clk->ops->disable_unused(clk->hw); 217 core->ops->disable_unused(core->hw);
535 else if (clk->ops->disable) 218 else if (core->ops->disable)
536 clk->ops->disable(clk->hw); 219 core->ops->disable(core->hw);
537 trace_clk_disable_complete(clk); 220 trace_clk_disable_complete(core);
538 } 221 }
539 222
540unlock_out: 223unlock_out:
@@ -551,7 +234,7 @@ __setup("clk_ignore_unused", clk_ignore_unused_setup);
551 234
552static int clk_disable_unused(void) 235static int clk_disable_unused(void)
553{ 236{
554 struct clk_core *clk; 237 struct clk_core *core;
555 238
556 if (clk_ignore_unused) { 239 if (clk_ignore_unused) {
557 pr_warn("clk: Not disabling unused clocks\n"); 240 pr_warn("clk: Not disabling unused clocks\n");
@@ -560,17 +243,17 @@ static int clk_disable_unused(void)
560 243
561 clk_prepare_lock(); 244 clk_prepare_lock();
562 245
563 hlist_for_each_entry(clk, &clk_root_list, child_node) 246 hlist_for_each_entry(core, &clk_root_list, child_node)
564 clk_disable_unused_subtree(clk); 247 clk_disable_unused_subtree(core);
565 248
566 hlist_for_each_entry(clk, &clk_orphan_list, child_node) 249 hlist_for_each_entry(core, &clk_orphan_list, child_node)
567 clk_disable_unused_subtree(clk); 250 clk_disable_unused_subtree(core);
568 251
569 hlist_for_each_entry(clk, &clk_root_list, child_node) 252 hlist_for_each_entry(core, &clk_root_list, child_node)
570 clk_unprepare_unused_subtree(clk); 253 clk_unprepare_unused_subtree(core);
571 254
572 hlist_for_each_entry(clk, &clk_orphan_list, child_node) 255 hlist_for_each_entry(core, &clk_orphan_list, child_node)
573 clk_unprepare_unused_subtree(clk); 256 clk_unprepare_unused_subtree(core);
574 257
575 clk_prepare_unlock(); 258 clk_prepare_unlock();
576 259
@@ -608,18 +291,61 @@ struct clk *__clk_get_parent(struct clk *clk)
608} 291}
609EXPORT_SYMBOL_GPL(__clk_get_parent); 292EXPORT_SYMBOL_GPL(__clk_get_parent);
610 293
611static struct clk_core *clk_core_get_parent_by_index(struct clk_core *clk, 294static struct clk_core *__clk_lookup_subtree(const char *name,
295 struct clk_core *core)
296{
297 struct clk_core *child;
298 struct clk_core *ret;
299
300 if (!strcmp(core->name, name))
301 return core;
302
303 hlist_for_each_entry(child, &core->children, child_node) {
304 ret = __clk_lookup_subtree(name, child);
305 if (ret)
306 return ret;
307 }
308
309 return NULL;
310}
311
312static struct clk_core *clk_core_lookup(const char *name)
313{
314 struct clk_core *root_clk;
315 struct clk_core *ret;
316
317 if (!name)
318 return NULL;
319
320 /* search the 'proper' clk tree first */
321 hlist_for_each_entry(root_clk, &clk_root_list, child_node) {
322 ret = __clk_lookup_subtree(name, root_clk);
323 if (ret)
324 return ret;
325 }
326
327 /* if not found, then search the orphan tree */
328 hlist_for_each_entry(root_clk, &clk_orphan_list, child_node) {
329 ret = __clk_lookup_subtree(name, root_clk);
330 if (ret)
331 return ret;
332 }
333
334 return NULL;
335}
336
337static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
612 u8 index) 338 u8 index)
613{ 339{
614 if (!clk || index >= clk->num_parents) 340 if (!core || index >= core->num_parents)
615 return NULL; 341 return NULL;
616 else if (!clk->parents) 342 else if (!core->parents)
617 return clk_core_lookup(clk->parent_names[index]); 343 return clk_core_lookup(core->parent_names[index]);
618 else if (!clk->parents[index]) 344 else if (!core->parents[index])
619 return clk->parents[index] = 345 return core->parents[index] =
620 clk_core_lookup(clk->parent_names[index]); 346 clk_core_lookup(core->parent_names[index]);
621 else 347 else
622 return clk->parents[index]; 348 return core->parents[index];
623} 349}
624 350
625struct clk *clk_get_parent_by_index(struct clk *clk, u8 index) 351struct clk *clk_get_parent_by_index(struct clk *clk, u8 index)
@@ -640,21 +366,21 @@ unsigned int __clk_get_enable_count(struct clk *clk)
640 return !clk ? 0 : clk->core->enable_count; 366 return !clk ? 0 : clk->core->enable_count;
641} 367}
642 368
643static unsigned long clk_core_get_rate_nolock(struct clk_core *clk) 369static unsigned long clk_core_get_rate_nolock(struct clk_core *core)
644{ 370{
645 unsigned long ret; 371 unsigned long ret;
646 372
647 if (!clk) { 373 if (!core) {
648 ret = 0; 374 ret = 0;
649 goto out; 375 goto out;
650 } 376 }
651 377
652 ret = clk->rate; 378 ret = core->rate;
653 379
654 if (clk->flags & CLK_IS_ROOT) 380 if (core->flags & CLK_IS_ROOT)
655 goto out; 381 goto out;
656 382
657 if (!clk->parent) 383 if (!core->parent)
658 ret = 0; 384 ret = 0;
659 385
660out: 386out:
@@ -670,12 +396,12 @@ unsigned long __clk_get_rate(struct clk *clk)
670} 396}
671EXPORT_SYMBOL_GPL(__clk_get_rate); 397EXPORT_SYMBOL_GPL(__clk_get_rate);
672 398
673static unsigned long __clk_get_accuracy(struct clk_core *clk) 399static unsigned long __clk_get_accuracy(struct clk_core *core)
674{ 400{
675 if (!clk) 401 if (!core)
676 return 0; 402 return 0;
677 403
678 return clk->accuracy; 404 return core->accuracy;
679} 405}
680 406
681unsigned long __clk_get_flags(struct clk *clk) 407unsigned long __clk_get_flags(struct clk *clk)
@@ -684,27 +410,6 @@ unsigned long __clk_get_flags(struct clk *clk)
684} 410}
685EXPORT_SYMBOL_GPL(__clk_get_flags); 411EXPORT_SYMBOL_GPL(__clk_get_flags);
686 412
687static bool clk_core_is_prepared(struct clk_core *clk)
688{
689 int ret;
690
691 if (!clk)
692 return false;
693
694 /*
695 * .is_prepared is optional for clocks that can prepare
696 * fall back to software usage counter if it is missing
697 */
698 if (!clk->ops->is_prepared) {
699 ret = clk->prepare_count ? 1 : 0;
700 goto out;
701 }
702
703 ret = clk->ops->is_prepared(clk->hw);
704out:
705 return !!ret;
706}
707
708bool __clk_is_prepared(struct clk *clk) 413bool __clk_is_prepared(struct clk *clk)
709{ 414{
710 if (!clk) 415 if (!clk)
@@ -713,27 +418,6 @@ bool __clk_is_prepared(struct clk *clk)
713 return clk_core_is_prepared(clk->core); 418 return clk_core_is_prepared(clk->core);
714} 419}
715 420
716static bool clk_core_is_enabled(struct clk_core *clk)
717{
718 int ret;
719
720 if (!clk)
721 return false;
722
723 /*
724 * .is_enabled is only mandatory for clocks that gate
725 * fall back to software usage counter if .is_enabled is missing
726 */
727 if (!clk->ops->is_enabled) {
728 ret = clk->enable_count ? 1 : 0;
729 goto out;
730 }
731
732 ret = clk->ops->is_enabled(clk->hw);
733out:
734 return !!ret;
735}
736
737bool __clk_is_enabled(struct clk *clk) 421bool __clk_is_enabled(struct clk *clk)
738{ 422{
739 if (!clk) 423 if (!clk)
@@ -743,49 +427,6 @@ bool __clk_is_enabled(struct clk *clk)
743} 427}
744EXPORT_SYMBOL_GPL(__clk_is_enabled); 428EXPORT_SYMBOL_GPL(__clk_is_enabled);
745 429
746static struct clk_core *__clk_lookup_subtree(const char *name,
747 struct clk_core *clk)
748{
749 struct clk_core *child;
750 struct clk_core *ret;
751
752 if (!strcmp(clk->name, name))
753 return clk;
754
755 hlist_for_each_entry(child, &clk->children, child_node) {
756 ret = __clk_lookup_subtree(name, child);
757 if (ret)
758 return ret;
759 }
760
761 return NULL;
762}
763
764static struct clk_core *clk_core_lookup(const char *name)
765{
766 struct clk_core *root_clk;
767 struct clk_core *ret;
768
769 if (!name)
770 return NULL;
771
772 /* search the 'proper' clk tree first */
773 hlist_for_each_entry(root_clk, &clk_root_list, child_node) {
774 ret = __clk_lookup_subtree(name, root_clk);
775 if (ret)
776 return ret;
777 }
778
779 /* if not found, then search the orphan tree */
780 hlist_for_each_entry(root_clk, &clk_orphan_list, child_node) {
781 ret = __clk_lookup_subtree(name, root_clk);
782 if (ret)
783 return ret;
784 }
785
786 return NULL;
787}
788
789static bool mux_is_better_rate(unsigned long rate, unsigned long now, 430static bool mux_is_better_rate(unsigned long rate, unsigned long now,
790 unsigned long best, unsigned long flags) 431 unsigned long best, unsigned long flags)
791{ 432{
@@ -853,7 +494,7 @@ struct clk *__clk_lookup(const char *name)
853 return !core ? NULL : core->hw->clk; 494 return !core ? NULL : core->hw->clk;
854} 495}
855 496
856static void clk_core_get_boundaries(struct clk_core *clk, 497static void clk_core_get_boundaries(struct clk_core *core,
857 unsigned long *min_rate, 498 unsigned long *min_rate,
858 unsigned long *max_rate) 499 unsigned long *max_rate)
859{ 500{
@@ -862,10 +503,10 @@ static void clk_core_get_boundaries(struct clk_core *clk,
862 *min_rate = 0; 503 *min_rate = 0;
863 *max_rate = ULONG_MAX; 504 *max_rate = ULONG_MAX;
864 505
865 hlist_for_each_entry(clk_user, &clk->clks, clks_node) 506 hlist_for_each_entry(clk_user, &core->clks, clks_node)
866 *min_rate = max(*min_rate, clk_user->min_rate); 507 *min_rate = max(*min_rate, clk_user->min_rate);
867 508
868 hlist_for_each_entry(clk_user, &clk->clks, clks_node) 509 hlist_for_each_entry(clk_user, &core->clks, clks_node)
869 *max_rate = min(*max_rate, clk_user->max_rate); 510 *max_rate = min(*max_rate, clk_user->max_rate);
870} 511}
871 512
@@ -901,26 +542,28 @@ EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest);
901 542
902/*** clk api ***/ 543/*** clk api ***/
903 544
904static void clk_core_unprepare(struct clk_core *clk) 545static void clk_core_unprepare(struct clk_core *core)
905{ 546{
906 if (!clk) 547 lockdep_assert_held(&prepare_lock);
548
549 if (!core)
907 return; 550 return;
908 551
909 if (WARN_ON(clk->prepare_count == 0)) 552 if (WARN_ON(core->prepare_count == 0))
910 return; 553 return;
911 554
912 if (--clk->prepare_count > 0) 555 if (--core->prepare_count > 0)
913 return; 556 return;
914 557
915 WARN_ON(clk->enable_count > 0); 558 WARN_ON(core->enable_count > 0);
916 559
917 trace_clk_unprepare(clk); 560 trace_clk_unprepare(core);
918 561
919 if (clk->ops->unprepare) 562 if (core->ops->unprepare)
920 clk->ops->unprepare(clk->hw); 563 core->ops->unprepare(core->hw);
921 564
922 trace_clk_unprepare_complete(clk); 565 trace_clk_unprepare_complete(core);
923 clk_core_unprepare(clk->parent); 566 clk_core_unprepare(core->parent);
924} 567}
925 568
926/** 569/**
@@ -945,32 +588,34 @@ void clk_unprepare(struct clk *clk)
945} 588}
946EXPORT_SYMBOL_GPL(clk_unprepare); 589EXPORT_SYMBOL_GPL(clk_unprepare);
947 590
948static int clk_core_prepare(struct clk_core *clk) 591static int clk_core_prepare(struct clk_core *core)
949{ 592{
950 int ret = 0; 593 int ret = 0;
951 594
952 if (!clk) 595 lockdep_assert_held(&prepare_lock);
596
597 if (!core)
953 return 0; 598 return 0;
954 599
955 if (clk->prepare_count == 0) { 600 if (core->prepare_count == 0) {
956 ret = clk_core_prepare(clk->parent); 601 ret = clk_core_prepare(core->parent);
957 if (ret) 602 if (ret)
958 return ret; 603 return ret;
959 604
960 trace_clk_prepare(clk); 605 trace_clk_prepare(core);
961 606
962 if (clk->ops->prepare) 607 if (core->ops->prepare)
963 ret = clk->ops->prepare(clk->hw); 608 ret = core->ops->prepare(core->hw);
964 609
965 trace_clk_prepare_complete(clk); 610 trace_clk_prepare_complete(core);
966 611
967 if (ret) { 612 if (ret) {
968 clk_core_unprepare(clk->parent); 613 clk_core_unprepare(core->parent);
969 return ret; 614 return ret;
970 } 615 }
971 } 616 }
972 617
973 clk->prepare_count++; 618 core->prepare_count++;
974 619
975 return 0; 620 return 0;
976} 621}
@@ -1002,33 +647,27 @@ int clk_prepare(struct clk *clk)
1002} 647}
1003EXPORT_SYMBOL_GPL(clk_prepare); 648EXPORT_SYMBOL_GPL(clk_prepare);
1004 649
1005static void clk_core_disable(struct clk_core *clk) 650static void clk_core_disable(struct clk_core *core)
1006{ 651{
1007 if (!clk) 652 lockdep_assert_held(&enable_lock);
653
654 if (!core)
1008 return; 655 return;
1009 656
1010 if (WARN_ON(clk->enable_count == 0)) 657 if (WARN_ON(core->enable_count == 0))
1011 return; 658 return;
1012 659
1013 if (--clk->enable_count > 0) 660 if (--core->enable_count > 0)
1014 return; 661 return;
1015 662
1016 trace_clk_disable(clk); 663 trace_clk_disable(core);
1017 664
1018 if (clk->ops->disable) 665 if (core->ops->disable)
1019 clk->ops->disable(clk->hw); 666 core->ops->disable(core->hw);
1020 667
1021 trace_clk_disable_complete(clk); 668 trace_clk_disable_complete(core);
1022 669
1023 clk_core_disable(clk->parent); 670 clk_core_disable(core->parent);
1024}
1025
1026static void __clk_disable(struct clk *clk)
1027{
1028 if (!clk)
1029 return;
1030
1031 clk_core_disable(clk->core);
1032} 671}
1033 672
1034/** 673/**
@@ -1051,52 +690,46 @@ void clk_disable(struct clk *clk)
1051 return; 690 return;
1052 691
1053 flags = clk_enable_lock(); 692 flags = clk_enable_lock();
1054 __clk_disable(clk); 693 clk_core_disable(clk->core);
1055 clk_enable_unlock(flags); 694 clk_enable_unlock(flags);
1056} 695}
1057EXPORT_SYMBOL_GPL(clk_disable); 696EXPORT_SYMBOL_GPL(clk_disable);
1058 697
1059static int clk_core_enable(struct clk_core *clk) 698static int clk_core_enable(struct clk_core *core)
1060{ 699{
1061 int ret = 0; 700 int ret = 0;
1062 701
1063 if (!clk) 702 lockdep_assert_held(&enable_lock);
703
704 if (!core)
1064 return 0; 705 return 0;
1065 706
1066 if (WARN_ON(clk->prepare_count == 0)) 707 if (WARN_ON(core->prepare_count == 0))
1067 return -ESHUTDOWN; 708 return -ESHUTDOWN;
1068 709
1069 if (clk->enable_count == 0) { 710 if (core->enable_count == 0) {
1070 ret = clk_core_enable(clk->parent); 711 ret = clk_core_enable(core->parent);
1071 712
1072 if (ret) 713 if (ret)
1073 return ret; 714 return ret;
1074 715
1075 trace_clk_enable(clk); 716 trace_clk_enable(core);
1076 717
1077 if (clk->ops->enable) 718 if (core->ops->enable)
1078 ret = clk->ops->enable(clk->hw); 719 ret = core->ops->enable(core->hw);
1079 720
1080 trace_clk_enable_complete(clk); 721 trace_clk_enable_complete(core);
1081 722
1082 if (ret) { 723 if (ret) {
1083 clk_core_disable(clk->parent); 724 clk_core_disable(core->parent);
1084 return ret; 725 return ret;
1085 } 726 }
1086 } 727 }
1087 728
1088 clk->enable_count++; 729 core->enable_count++;
1089 return 0; 730 return 0;
1090} 731}
1091 732
1092static int __clk_enable(struct clk *clk)
1093{
1094 if (!clk)
1095 return 0;
1096
1097 return clk_core_enable(clk->core);
1098}
1099
1100/** 733/**
1101 * clk_enable - ungate a clock 734 * clk_enable - ungate a clock
1102 * @clk: the clk being ungated 735 * @clk: the clk being ungated
@@ -1115,15 +748,18 @@ int clk_enable(struct clk *clk)
1115 unsigned long flags; 748 unsigned long flags;
1116 int ret; 749 int ret;
1117 750
751 if (!clk)
752 return 0;
753
1118 flags = clk_enable_lock(); 754 flags = clk_enable_lock();
1119 ret = __clk_enable(clk); 755 ret = clk_core_enable(clk->core);
1120 clk_enable_unlock(flags); 756 clk_enable_unlock(flags);
1121 757
1122 return ret; 758 return ret;
1123} 759}
1124EXPORT_SYMBOL_GPL(clk_enable); 760EXPORT_SYMBOL_GPL(clk_enable);
1125 761
1126static unsigned long clk_core_round_rate_nolock(struct clk_core *clk, 762static unsigned long clk_core_round_rate_nolock(struct clk_core *core,
1127 unsigned long rate, 763 unsigned long rate,
1128 unsigned long min_rate, 764 unsigned long min_rate,
1129 unsigned long max_rate) 765 unsigned long max_rate)
@@ -1134,25 +770,25 @@ static unsigned long clk_core_round_rate_nolock(struct clk_core *clk,
1134 770
1135 lockdep_assert_held(&prepare_lock); 771 lockdep_assert_held(&prepare_lock);
1136 772
1137 if (!clk) 773 if (!core)
1138 return 0; 774 return 0;
1139 775
1140 parent = clk->parent; 776 parent = core->parent;
1141 if (parent) 777 if (parent)
1142 parent_rate = parent->rate; 778 parent_rate = parent->rate;
1143 779
1144 if (clk->ops->determine_rate) { 780 if (core->ops->determine_rate) {
1145 parent_hw = parent ? parent->hw : NULL; 781 parent_hw = parent ? parent->hw : NULL;
1146 return clk->ops->determine_rate(clk->hw, rate, 782 return core->ops->determine_rate(core->hw, rate,
1147 min_rate, max_rate, 783 min_rate, max_rate,
1148 &parent_rate, &parent_hw); 784 &parent_rate, &parent_hw);
1149 } else if (clk->ops->round_rate) 785 } else if (core->ops->round_rate)
1150 return clk->ops->round_rate(clk->hw, rate, &parent_rate); 786 return core->ops->round_rate(core->hw, rate, &parent_rate);
1151 else if (clk->flags & CLK_SET_RATE_PARENT) 787 else if (core->flags & CLK_SET_RATE_PARENT)
1152 return clk_core_round_rate_nolock(clk->parent, rate, min_rate, 788 return clk_core_round_rate_nolock(core->parent, rate, min_rate,
1153 max_rate); 789 max_rate);
1154 else 790 else
1155 return clk->rate; 791 return core->rate;
1156} 792}
1157 793
1158/** 794/**
@@ -1162,8 +798,7 @@ static unsigned long clk_core_round_rate_nolock(struct clk_core *clk,
1162 * @min_rate: returned rate must be greater than this rate 798 * @min_rate: returned rate must be greater than this rate
1163 * @max_rate: returned rate must be less than this rate 799 * @max_rate: returned rate must be less than this rate
1164 * 800 *
1165 * Caller must hold prepare_lock. Useful for clk_ops such as .set_rate and 801 * Useful for clk_ops such as .set_rate and .determine_rate.
1166 * .determine_rate.
1167 */ 802 */
1168unsigned long __clk_determine_rate(struct clk_hw *hw, 803unsigned long __clk_determine_rate(struct clk_hw *hw,
1169 unsigned long rate, 804 unsigned long rate,
@@ -1182,7 +817,7 @@ EXPORT_SYMBOL_GPL(__clk_determine_rate);
1182 * @clk: round the rate of this clock 817 * @clk: round the rate of this clock
1183 * @rate: the rate which is to be rounded 818 * @rate: the rate which is to be rounded
1184 * 819 *
1185 * Caller must hold prepare_lock. Useful for clk_ops such as .set_rate 820 * Useful for clk_ops such as .set_rate
1186 */ 821 */
1187unsigned long __clk_round_rate(struct clk *clk, unsigned long rate) 822unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
1188{ 823{
@@ -1224,7 +859,7 @@ EXPORT_SYMBOL_GPL(clk_round_rate);
1224 859
1225/** 860/**
1226 * __clk_notify - call clk notifier chain 861 * __clk_notify - call clk notifier chain
1227 * @clk: struct clk * that is changing rate 862 * @core: clk that is changing rate
1228 * @msg: clk notifier type (see include/linux/clk.h) 863 * @msg: clk notifier type (see include/linux/clk.h)
1229 * @old_rate: old clk rate 864 * @old_rate: old clk rate
1230 * @new_rate: new clk rate 865 * @new_rate: new clk rate
@@ -1236,7 +871,7 @@ EXPORT_SYMBOL_GPL(clk_round_rate);
1236 * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if 871 * called if all went well, or NOTIFY_STOP or NOTIFY_BAD immediately if
1237 * a driver returns that. 872 * a driver returns that.
1238 */ 873 */
1239static int __clk_notify(struct clk_core *clk, unsigned long msg, 874static int __clk_notify(struct clk_core *core, unsigned long msg,
1240 unsigned long old_rate, unsigned long new_rate) 875 unsigned long old_rate, unsigned long new_rate)
1241{ 876{
1242 struct clk_notifier *cn; 877 struct clk_notifier *cn;
@@ -1247,7 +882,7 @@ static int __clk_notify(struct clk_core *clk, unsigned long msg,
1247 cnd.new_rate = new_rate; 882 cnd.new_rate = new_rate;
1248 883
1249 list_for_each_entry(cn, &clk_notifier_list, node) { 884 list_for_each_entry(cn, &clk_notifier_list, node) {
1250 if (cn->clk->core == clk) { 885 if (cn->clk->core == core) {
1251 cnd.clk = cn->clk; 886 cnd.clk = cn->clk;
1252 ret = srcu_notifier_call_chain(&cn->notifier_head, msg, 887 ret = srcu_notifier_call_chain(&cn->notifier_head, msg,
1253 &cnd); 888 &cnd);
@@ -1259,44 +894,42 @@ static int __clk_notify(struct clk_core *clk, unsigned long msg,
1259 894
1260/** 895/**
1261 * __clk_recalc_accuracies 896 * __clk_recalc_accuracies
1262 * @clk: first clk in the subtree 897 * @core: first clk in the subtree
1263 * 898 *
1264 * Walks the subtree of clks starting with clk and recalculates accuracies as 899 * Walks the subtree of clks starting with clk and recalculates accuracies as
1265 * it goes. Note that if a clk does not implement the .recalc_accuracy 900 * it goes. Note that if a clk does not implement the .recalc_accuracy
1266 * callback then it is assumed that the clock will take on the accuracy of it's 901 * callback then it is assumed that the clock will take on the accuracy of its
1267 * parent. 902 * parent.
1268 *
1269 * Caller must hold prepare_lock.
1270 */ 903 */
1271static void __clk_recalc_accuracies(struct clk_core *clk) 904static void __clk_recalc_accuracies(struct clk_core *core)
1272{ 905{
1273 unsigned long parent_accuracy = 0; 906 unsigned long parent_accuracy = 0;
1274 struct clk_core *child; 907 struct clk_core *child;
1275 908
1276 lockdep_assert_held(&prepare_lock); 909 lockdep_assert_held(&prepare_lock);
1277 910
1278 if (clk->parent) 911 if (core->parent)
1279 parent_accuracy = clk->parent->accuracy; 912 parent_accuracy = core->parent->accuracy;
1280 913
1281 if (clk->ops->recalc_accuracy) 914 if (core->ops->recalc_accuracy)
1282 clk->accuracy = clk->ops->recalc_accuracy(clk->hw, 915 core->accuracy = core->ops->recalc_accuracy(core->hw,
1283 parent_accuracy); 916 parent_accuracy);
1284 else 917 else
1285 clk->accuracy = parent_accuracy; 918 core->accuracy = parent_accuracy;
1286 919
1287 hlist_for_each_entry(child, &clk->children, child_node) 920 hlist_for_each_entry(child, &core->children, child_node)
1288 __clk_recalc_accuracies(child); 921 __clk_recalc_accuracies(child);
1289} 922}
1290 923
1291static long clk_core_get_accuracy(struct clk_core *clk) 924static long clk_core_get_accuracy(struct clk_core *core)
1292{ 925{
1293 unsigned long accuracy; 926 unsigned long accuracy;
1294 927
1295 clk_prepare_lock(); 928 clk_prepare_lock();
1296 if (clk && (clk->flags & CLK_GET_ACCURACY_NOCACHE)) 929 if (core && (core->flags & CLK_GET_ACCURACY_NOCACHE))
1297 __clk_recalc_accuracies(clk); 930 __clk_recalc_accuracies(core);
1298 931
1299 accuracy = __clk_get_accuracy(clk); 932 accuracy = __clk_get_accuracy(core);
1300 clk_prepare_unlock(); 933 clk_prepare_unlock();
1301 934
1302 return accuracy; 935 return accuracy;
@@ -1320,17 +953,17 @@ long clk_get_accuracy(struct clk *clk)
1320} 953}
1321EXPORT_SYMBOL_GPL(clk_get_accuracy); 954EXPORT_SYMBOL_GPL(clk_get_accuracy);
1322 955
1323static unsigned long clk_recalc(struct clk_core *clk, 956static unsigned long clk_recalc(struct clk_core *core,
1324 unsigned long parent_rate) 957 unsigned long parent_rate)
1325{ 958{
1326 if (clk->ops->recalc_rate) 959 if (core->ops->recalc_rate)
1327 return clk->ops->recalc_rate(clk->hw, parent_rate); 960 return core->ops->recalc_rate(core->hw, parent_rate);
1328 return parent_rate; 961 return parent_rate;
1329} 962}
1330 963
1331/** 964/**
1332 * __clk_recalc_rates 965 * __clk_recalc_rates
1333 * @clk: first clk in the subtree 966 * @core: first clk in the subtree
1334 * @msg: notification type (see include/linux/clk.h) 967 * @msg: notification type (see include/linux/clk.h)
1335 * 968 *
1336 * Walks the subtree of clks starting with clk and recalculates rates as it 969 * Walks the subtree of clks starting with clk and recalculates rates as it
@@ -1339,10 +972,8 @@ static unsigned long clk_recalc(struct clk_core *clk,
1339 * 972 *
1340 * clk_recalc_rates also propagates the POST_RATE_CHANGE notification, 973 * clk_recalc_rates also propagates the POST_RATE_CHANGE notification,
1341 * if necessary. 974 * if necessary.
1342 *
1343 * Caller must hold prepare_lock.
1344 */ 975 */
1345static void __clk_recalc_rates(struct clk_core *clk, unsigned long msg) 976static void __clk_recalc_rates(struct clk_core *core, unsigned long msg)
1346{ 977{
1347 unsigned long old_rate; 978 unsigned long old_rate;
1348 unsigned long parent_rate = 0; 979 unsigned long parent_rate = 0;
@@ -1350,34 +981,34 @@ static void __clk_recalc_rates(struct clk_core *clk, unsigned long msg)
1350 981
1351 lockdep_assert_held(&prepare_lock); 982 lockdep_assert_held(&prepare_lock);
1352 983
1353 old_rate = clk->rate; 984 old_rate = core->rate;
1354 985
1355 if (clk->parent) 986 if (core->parent)
1356 parent_rate = clk->parent->rate; 987 parent_rate = core->parent->rate;
1357 988
1358 clk->rate = clk_recalc(clk, parent_rate); 989 core->rate = clk_recalc(core, parent_rate);
1359 990
1360 /* 991 /*
1361 * ignore NOTIFY_STOP and NOTIFY_BAD return values for POST_RATE_CHANGE 992 * ignore NOTIFY_STOP and NOTIFY_BAD return values for POST_RATE_CHANGE
1362 * & ABORT_RATE_CHANGE notifiers 993 * & ABORT_RATE_CHANGE notifiers
1363 */ 994 */
1364 if (clk->notifier_count && msg) 995 if (core->notifier_count && msg)
1365 __clk_notify(clk, msg, old_rate, clk->rate); 996 __clk_notify(core, msg, old_rate, core->rate);
1366 997
1367 hlist_for_each_entry(child, &clk->children, child_node) 998 hlist_for_each_entry(child, &core->children, child_node)
1368 __clk_recalc_rates(child, msg); 999 __clk_recalc_rates(child, msg);
1369} 1000}
1370 1001
1371static unsigned long clk_core_get_rate(struct clk_core *clk) 1002static unsigned long clk_core_get_rate(struct clk_core *core)
1372{ 1003{
1373 unsigned long rate; 1004 unsigned long rate;
1374 1005
1375 clk_prepare_lock(); 1006 clk_prepare_lock();
1376 1007
1377 if (clk && (clk->flags & CLK_GET_RATE_NOCACHE)) 1008 if (core && (core->flags & CLK_GET_RATE_NOCACHE))
1378 __clk_recalc_rates(clk, 0); 1009 __clk_recalc_rates(core, 0);
1379 1010
1380 rate = clk_core_get_rate_nolock(clk); 1011 rate = clk_core_get_rate_nolock(core);
1381 clk_prepare_unlock(); 1012 clk_prepare_unlock();
1382 1013
1383 return rate; 1014 return rate;
@@ -1400,15 +1031,15 @@ unsigned long clk_get_rate(struct clk *clk)
1400} 1031}
1401EXPORT_SYMBOL_GPL(clk_get_rate); 1032EXPORT_SYMBOL_GPL(clk_get_rate);
1402 1033
1403static int clk_fetch_parent_index(struct clk_core *clk, 1034static int clk_fetch_parent_index(struct clk_core *core,
1404 struct clk_core *parent) 1035 struct clk_core *parent)
1405{ 1036{
1406 int i; 1037 int i;
1407 1038
1408 if (!clk->parents) { 1039 if (!core->parents) {
1409 clk->parents = kcalloc(clk->num_parents, 1040 core->parents = kcalloc(core->num_parents,
1410 sizeof(struct clk *), GFP_KERNEL); 1041 sizeof(struct clk *), GFP_KERNEL);
1411 if (!clk->parents) 1042 if (!core->parents)
1412 return -ENOMEM; 1043 return -ENOMEM;
1413 } 1044 }
1414 1045
@@ -1417,15 +1048,15 @@ static int clk_fetch_parent_index(struct clk_core *clk,
1417 * or if not yet cached, use string name comparison and cache 1048 * or if not yet cached, use string name comparison and cache
1418 * them now to avoid future calls to clk_core_lookup. 1049 * them now to avoid future calls to clk_core_lookup.
1419 */ 1050 */
1420 for (i = 0; i < clk->num_parents; i++) { 1051 for (i = 0; i < core->num_parents; i++) {
1421 if (clk->parents[i] == parent) 1052 if (core->parents[i] == parent)
1422 return i; 1053 return i;
1423 1054
1424 if (clk->parents[i]) 1055 if (core->parents[i])
1425 continue; 1056 continue;
1426 1057
1427 if (!strcmp(clk->parent_names[i], parent->name)) { 1058 if (!strcmp(core->parent_names[i], parent->name)) {
1428 clk->parents[i] = clk_core_lookup(parent->name); 1059 core->parents[i] = clk_core_lookup(parent->name);
1429 return i; 1060 return i;
1430 } 1061 }
1431 } 1062 }
@@ -1433,28 +1064,28 @@ static int clk_fetch_parent_index(struct clk_core *clk,
1433 return -EINVAL; 1064 return -EINVAL;
1434} 1065}
1435 1066
1436static void clk_reparent(struct clk_core *clk, struct clk_core *new_parent) 1067static void clk_reparent(struct clk_core *core, struct clk_core *new_parent)
1437{ 1068{
1438 hlist_del(&clk->child_node); 1069 hlist_del(&core->child_node);
1439 1070
1440 if (new_parent) { 1071 if (new_parent) {
1441 /* avoid duplicate POST_RATE_CHANGE notifications */ 1072 /* avoid duplicate POST_RATE_CHANGE notifications */
1442 if (new_parent->new_child == clk) 1073 if (new_parent->new_child == core)
1443 new_parent->new_child = NULL; 1074 new_parent->new_child = NULL;
1444 1075
1445 hlist_add_head(&clk->child_node, &new_parent->children); 1076 hlist_add_head(&core->child_node, &new_parent->children);
1446 } else { 1077 } else {
1447 hlist_add_head(&clk->child_node, &clk_orphan_list); 1078 hlist_add_head(&core->child_node, &clk_orphan_list);
1448 } 1079 }
1449 1080
1450 clk->parent = new_parent; 1081 core->parent = new_parent;
1451} 1082}
1452 1083
1453static struct clk_core *__clk_set_parent_before(struct clk_core *clk, 1084static struct clk_core *__clk_set_parent_before(struct clk_core *core,
1454 struct clk_core *parent) 1085 struct clk_core *parent)
1455{ 1086{
1456 unsigned long flags; 1087 unsigned long flags;
1457 struct clk_core *old_parent = clk->parent; 1088 struct clk_core *old_parent = core->parent;
1458 1089
1459 /* 1090 /*
1460 * Migrate prepare state between parents and prevent race with 1091 * Migrate prepare state between parents and prevent race with
@@ -1473,17 +1104,17 @@ static struct clk_core *__clk_set_parent_before(struct clk_core *clk,
1473 * 1104 *
1474 * See also: Comment for clk_set_parent() below. 1105 * See also: Comment for clk_set_parent() below.
1475 */ 1106 */
1476 if (clk->prepare_count) { 1107 if (core->prepare_count) {
1477 clk_core_prepare(parent); 1108 clk_core_prepare(parent);
1478 flags = clk_enable_lock(); 1109 flags = clk_enable_lock();
1479 clk_core_enable(parent); 1110 clk_core_enable(parent);
1480 clk_core_enable(clk); 1111 clk_core_enable(core);
1481 clk_enable_unlock(flags); 1112 clk_enable_unlock(flags);
1482 } 1113 }
1483 1114
1484 /* update the clk tree topology */ 1115 /* update the clk tree topology */
1485 flags = clk_enable_lock(); 1116 flags = clk_enable_lock();
1486 clk_reparent(clk, parent); 1117 clk_reparent(core, parent);
1487 clk_enable_unlock(flags); 1118 clk_enable_unlock(flags);
1488 1119
1489 return old_parent; 1120 return old_parent;
@@ -1508,31 +1139,31 @@ static void __clk_set_parent_after(struct clk_core *core,
1508 } 1139 }
1509} 1140}
1510 1141
1511static int __clk_set_parent(struct clk_core *clk, struct clk_core *parent, 1142static int __clk_set_parent(struct clk_core *core, struct clk_core *parent,
1512 u8 p_index) 1143 u8 p_index)
1513{ 1144{
1514 unsigned long flags; 1145 unsigned long flags;
1515 int ret = 0; 1146 int ret = 0;
1516 struct clk_core *old_parent; 1147 struct clk_core *old_parent;
1517 1148
1518 old_parent = __clk_set_parent_before(clk, parent); 1149 old_parent = __clk_set_parent_before(core, parent);
1519 1150
1520 trace_clk_set_parent(clk, parent); 1151 trace_clk_set_parent(core, parent);
1521 1152
1522 /* change clock input source */ 1153 /* change clock input source */
1523 if (parent && clk->ops->set_parent) 1154 if (parent && core->ops->set_parent)
1524 ret = clk->ops->set_parent(clk->hw, p_index); 1155 ret = core->ops->set_parent(core->hw, p_index);
1525 1156
1526 trace_clk_set_parent_complete(clk, parent); 1157 trace_clk_set_parent_complete(core, parent);
1527 1158
1528 if (ret) { 1159 if (ret) {
1529 flags = clk_enable_lock(); 1160 flags = clk_enable_lock();
1530 clk_reparent(clk, old_parent); 1161 clk_reparent(core, old_parent);
1531 clk_enable_unlock(flags); 1162 clk_enable_unlock(flags);
1532 1163
1533 if (clk->prepare_count) { 1164 if (core->prepare_count) {
1534 flags = clk_enable_lock(); 1165 flags = clk_enable_lock();
1535 clk_core_disable(clk); 1166 clk_core_disable(core);
1536 clk_core_disable(parent); 1167 clk_core_disable(parent);
1537 clk_enable_unlock(flags); 1168 clk_enable_unlock(flags);
1538 clk_core_unprepare(parent); 1169 clk_core_unprepare(parent);
@@ -1540,14 +1171,14 @@ static int __clk_set_parent(struct clk_core *clk, struct clk_core *parent,
1540 return ret; 1171 return ret;
1541 } 1172 }
1542 1173
1543 __clk_set_parent_after(clk, parent, old_parent); 1174 __clk_set_parent_after(core, parent, old_parent);
1544 1175
1545 return 0; 1176 return 0;
1546} 1177}
1547 1178
1548/** 1179/**
1549 * __clk_speculate_rates 1180 * __clk_speculate_rates
1550 * @clk: first clk in the subtree 1181 * @core: first clk in the subtree
1551 * @parent_rate: the "future" rate of clk's parent 1182 * @parent_rate: the "future" rate of clk's parent
1552 * 1183 *
1553 * Walks the subtree of clks starting with clk, speculating rates as it 1184 * Walks the subtree of clks starting with clk, speculating rates as it
@@ -1558,10 +1189,8 @@ static int __clk_set_parent(struct clk_core *clk, struct clk_core *parent,
1558 * subtree have subscribed to the notifications. Note that if a clk does not 1189 * subtree have subscribed to the notifications. Note that if a clk does not
1559 * implement the .recalc_rate callback then it is assumed that the clock will 1190 * implement the .recalc_rate callback then it is assumed that the clock will
1560 * take on the rate of its parent. 1191 * take on the rate of its parent.
1561 *
1562 * Caller must hold prepare_lock.
1563 */ 1192 */
1564static int __clk_speculate_rates(struct clk_core *clk, 1193static int __clk_speculate_rates(struct clk_core *core,
1565 unsigned long parent_rate) 1194 unsigned long parent_rate)
1566{ 1195{
1567 struct clk_core *child; 1196 struct clk_core *child;
@@ -1570,19 +1199,19 @@ static int __clk_speculate_rates(struct clk_core *clk,
1570 1199
1571 lockdep_assert_held(&prepare_lock); 1200 lockdep_assert_held(&prepare_lock);
1572 1201
1573 new_rate = clk_recalc(clk, parent_rate); 1202 new_rate = clk_recalc(core, parent_rate);
1574 1203
1575 /* abort rate change if a driver returns NOTIFY_BAD or NOTIFY_STOP */ 1204 /* abort rate change if a driver returns NOTIFY_BAD or NOTIFY_STOP */
1576 if (clk->notifier_count) 1205 if (core->notifier_count)
1577 ret = __clk_notify(clk, PRE_RATE_CHANGE, clk->rate, new_rate); 1206 ret = __clk_notify(core, PRE_RATE_CHANGE, core->rate, new_rate);
1578 1207
1579 if (ret & NOTIFY_STOP_MASK) { 1208 if (ret & NOTIFY_STOP_MASK) {
1580 pr_debug("%s: clk notifier callback for clock %s aborted with error %d\n", 1209 pr_debug("%s: clk notifier callback for clock %s aborted with error %d\n",
1581 __func__, clk->name, ret); 1210 __func__, core->name, ret);
1582 goto out; 1211 goto out;
1583 } 1212 }
1584 1213
1585 hlist_for_each_entry(child, &clk->children, child_node) { 1214 hlist_for_each_entry(child, &core->children, child_node) {
1586 ret = __clk_speculate_rates(child, new_rate); 1215 ret = __clk_speculate_rates(child, new_rate);
1587 if (ret & NOTIFY_STOP_MASK) 1216 if (ret & NOTIFY_STOP_MASK)
1588 break; 1217 break;
@@ -1592,20 +1221,20 @@ out:
1592 return ret; 1221 return ret;
1593} 1222}
1594 1223
1595static void clk_calc_subtree(struct clk_core *clk, unsigned long new_rate, 1224static void clk_calc_subtree(struct clk_core *core, unsigned long new_rate,
1596 struct clk_core *new_parent, u8 p_index) 1225 struct clk_core *new_parent, u8 p_index)
1597{ 1226{
1598 struct clk_core *child; 1227 struct clk_core *child;
1599 1228
1600 clk->new_rate = new_rate; 1229 core->new_rate = new_rate;
1601 clk->new_parent = new_parent; 1230 core->new_parent = new_parent;
1602 clk->new_parent_index = p_index; 1231 core->new_parent_index = p_index;
1603 /* include clk in new parent's PRE_RATE_CHANGE notifications */ 1232 /* include clk in new parent's PRE_RATE_CHANGE notifications */
1604 clk->new_child = NULL; 1233 core->new_child = NULL;
1605 if (new_parent && new_parent != clk->parent) 1234 if (new_parent && new_parent != core->parent)
1606 new_parent->new_child = clk; 1235 new_parent->new_child = core;
1607 1236
1608 hlist_for_each_entry(child, &clk->children, child_node) { 1237 hlist_for_each_entry(child, &core->children, child_node) {
1609 child->new_rate = clk_recalc(child, new_rate); 1238 child->new_rate = clk_recalc(child, new_rate);
1610 clk_calc_subtree(child, child->new_rate, NULL, 0); 1239 clk_calc_subtree(child, child->new_rate, NULL, 0);
1611 } 1240 }
@@ -1615,10 +1244,10 @@ static void clk_calc_subtree(struct clk_core *clk, unsigned long new_rate,
1615 * calculate the new rates returning the topmost clock that has to be 1244 * calculate the new rates returning the topmost clock that has to be
1616 * changed. 1245 * changed.
1617 */ 1246 */
1618static struct clk_core *clk_calc_new_rates(struct clk_core *clk, 1247static struct clk_core *clk_calc_new_rates(struct clk_core *core,
1619 unsigned long rate) 1248 unsigned long rate)
1620{ 1249{
1621 struct clk_core *top = clk; 1250 struct clk_core *top = core;
1622 struct clk_core *old_parent, *parent; 1251 struct clk_core *old_parent, *parent;
1623 struct clk_hw *parent_hw; 1252 struct clk_hw *parent_hw;
1624 unsigned long best_parent_rate = 0; 1253 unsigned long best_parent_rate = 0;
@@ -1629,20 +1258,20 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *clk,
1629 long ret; 1258 long ret;
1630 1259
1631 /* sanity */ 1260 /* sanity */
1632 if (IS_ERR_OR_NULL(clk)) 1261 if (IS_ERR_OR_NULL(core))
1633 return NULL; 1262 return NULL;
1634 1263
1635 /* save parent rate, if it exists */ 1264 /* save parent rate, if it exists */
1636 parent = old_parent = clk->parent; 1265 parent = old_parent = core->parent;
1637 if (parent) 1266 if (parent)
1638 best_parent_rate = parent->rate; 1267 best_parent_rate = parent->rate;
1639 1268
1640 clk_core_get_boundaries(clk, &min_rate, &max_rate); 1269 clk_core_get_boundaries(core, &min_rate, &max_rate);
1641 1270
1642 /* find the closest rate and parent clk/rate */ 1271 /* find the closest rate and parent clk/rate */
1643 if (clk->ops->determine_rate) { 1272 if (core->ops->determine_rate) {
1644 parent_hw = parent ? parent->hw : NULL; 1273 parent_hw = parent ? parent->hw : NULL;
1645 ret = clk->ops->determine_rate(clk->hw, rate, 1274 ret = core->ops->determine_rate(core->hw, rate,
1646 min_rate, 1275 min_rate,
1647 max_rate, 1276 max_rate,
1648 &best_parent_rate, 1277 &best_parent_rate,
@@ -1652,8 +1281,8 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *clk,
1652 1281
1653 new_rate = ret; 1282 new_rate = ret;
1654 parent = parent_hw ? parent_hw->core : NULL; 1283 parent = parent_hw ? parent_hw->core : NULL;
1655 } else if (clk->ops->round_rate) { 1284 } else if (core->ops->round_rate) {
1656 ret = clk->ops->round_rate(clk->hw, rate, 1285 ret = core->ops->round_rate(core->hw, rate,
1657 &best_parent_rate); 1286 &best_parent_rate);
1658 if (ret < 0) 1287 if (ret < 0)
1659 return NULL; 1288 return NULL;
@@ -1661,9 +1290,9 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *clk,
1661 new_rate = ret; 1290 new_rate = ret;
1662 if (new_rate < min_rate || new_rate > max_rate) 1291 if (new_rate < min_rate || new_rate > max_rate)
1663 return NULL; 1292 return NULL;
1664 } else if (!parent || !(clk->flags & CLK_SET_RATE_PARENT)) { 1293 } else if (!parent || !(core->flags & CLK_SET_RATE_PARENT)) {
1665 /* pass-through clock without adjustable parent */ 1294 /* pass-through clock without adjustable parent */
1666 clk->new_rate = clk->rate; 1295 core->new_rate = core->rate;
1667 return NULL; 1296 return NULL;
1668 } else { 1297 } else {
1669 /* pass-through clock with adjustable parent */ 1298 /* pass-through clock with adjustable parent */
@@ -1674,28 +1303,28 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *clk,
1674 1303
1675 /* some clocks must be gated to change parent */ 1304 /* some clocks must be gated to change parent */
1676 if (parent != old_parent && 1305 if (parent != old_parent &&
1677 (clk->flags & CLK_SET_PARENT_GATE) && clk->prepare_count) { 1306 (core->flags & CLK_SET_PARENT_GATE) && core->prepare_count) {
1678 pr_debug("%s: %s not gated but wants to reparent\n", 1307 pr_debug("%s: %s not gated but wants to reparent\n",
1679 __func__, clk->name); 1308 __func__, core->name);
1680 return NULL; 1309 return NULL;
1681 } 1310 }
1682 1311
1683 /* try finding the new parent index */ 1312 /* try finding the new parent index */
1684 if (parent && clk->num_parents > 1) { 1313 if (parent && core->num_parents > 1) {
1685 p_index = clk_fetch_parent_index(clk, parent); 1314 p_index = clk_fetch_parent_index(core, parent);
1686 if (p_index < 0) { 1315 if (p_index < 0) {
1687 pr_debug("%s: clk %s can not be parent of clk %s\n", 1316 pr_debug("%s: clk %s can not be parent of clk %s\n",
1688 __func__, parent->name, clk->name); 1317 __func__, parent->name, core->name);
1689 return NULL; 1318 return NULL;
1690 } 1319 }
1691 } 1320 }
1692 1321
1693 if ((clk->flags & CLK_SET_RATE_PARENT) && parent && 1322 if ((core->flags & CLK_SET_RATE_PARENT) && parent &&
1694 best_parent_rate != parent->rate) 1323 best_parent_rate != parent->rate)
1695 top = clk_calc_new_rates(parent, best_parent_rate); 1324 top = clk_calc_new_rates(parent, best_parent_rate);
1696 1325
1697out: 1326out:
1698 clk_calc_subtree(clk, new_rate, parent, p_index); 1327 clk_calc_subtree(core, new_rate, parent, p_index);
1699 1328
1700 return top; 1329 return top;
1701} 1330}
@@ -1705,33 +1334,33 @@ out:
1705 * so that in case of an error we can walk down the whole tree again and 1334 * so that in case of an error we can walk down the whole tree again and
1706 * abort the change. 1335 * abort the change.
1707 */ 1336 */
1708static struct clk_core *clk_propagate_rate_change(struct clk_core *clk, 1337static struct clk_core *clk_propagate_rate_change(struct clk_core *core,
1709 unsigned long event) 1338 unsigned long event)
1710{ 1339{
1711 struct clk_core *child, *tmp_clk, *fail_clk = NULL; 1340 struct clk_core *child, *tmp_clk, *fail_clk = NULL;
1712 int ret = NOTIFY_DONE; 1341 int ret = NOTIFY_DONE;
1713 1342
1714 if (clk->rate == clk->new_rate) 1343 if (core->rate == core->new_rate)
1715 return NULL; 1344 return NULL;
1716 1345
1717 if (clk->notifier_count) { 1346 if (core->notifier_count) {
1718 ret = __clk_notify(clk, event, clk->rate, clk->new_rate); 1347 ret = __clk_notify(core, event, core->rate, core->new_rate);
1719 if (ret & NOTIFY_STOP_MASK) 1348 if (ret & NOTIFY_STOP_MASK)
1720 fail_clk = clk; 1349 fail_clk = core;
1721 } 1350 }
1722 1351
1723 hlist_for_each_entry(child, &clk->children, child_node) { 1352 hlist_for_each_entry(child, &core->children, child_node) {
1724 /* Skip children who will be reparented to another clock */ 1353 /* Skip children who will be reparented to another clock */
1725 if (child->new_parent && child->new_parent != clk) 1354 if (child->new_parent && child->new_parent != core)
1726 continue; 1355 continue;
1727 tmp_clk = clk_propagate_rate_change(child, event); 1356 tmp_clk = clk_propagate_rate_change(child, event);
1728 if (tmp_clk) 1357 if (tmp_clk)
1729 fail_clk = tmp_clk; 1358 fail_clk = tmp_clk;
1730 } 1359 }
1731 1360
1732 /* handle the new child who might not be in clk->children yet */ 1361 /* handle the new child who might not be in core->children yet */
1733 if (clk->new_child) { 1362 if (core->new_child) {
1734 tmp_clk = clk_propagate_rate_change(clk->new_child, event); 1363 tmp_clk = clk_propagate_rate_change(core->new_child, event);
1735 if (tmp_clk) 1364 if (tmp_clk)
1736 fail_clk = tmp_clk; 1365 fail_clk = tmp_clk;
1737 } 1366 }
@@ -1743,7 +1372,7 @@ static struct clk_core *clk_propagate_rate_change(struct clk_core *clk,
1743 * walk down a subtree and set the new rates notifying the rate 1372 * walk down a subtree and set the new rates notifying the rate
1744 * change on the way 1373 * change on the way
1745 */ 1374 */
1746static void clk_change_rate(struct clk_core *clk) 1375static void clk_change_rate(struct clk_core *core)
1747{ 1376{
1748 struct clk_core *child; 1377 struct clk_core *child;
1749 struct hlist_node *tmp; 1378 struct hlist_node *tmp;
@@ -1752,77 +1381,77 @@ static void clk_change_rate(struct clk_core *clk)
1752 bool skip_set_rate = false; 1381 bool skip_set_rate = false;
1753 struct clk_core *old_parent; 1382 struct clk_core *old_parent;
1754 1383
1755 old_rate = clk->rate; 1384 old_rate = core->rate;
1756 1385
1757 if (clk->new_parent) 1386 if (core->new_parent)
1758 best_parent_rate = clk->new_parent->rate; 1387 best_parent_rate = core->new_parent->rate;
1759 else if (clk->parent) 1388 else if (core->parent)
1760 best_parent_rate = clk->parent->rate; 1389 best_parent_rate = core->parent->rate;
1761 1390
1762 if (clk->new_parent && clk->new_parent != clk->parent) { 1391 if (core->new_parent && core->new_parent != core->parent) {
1763 old_parent = __clk_set_parent_before(clk, clk->new_parent); 1392 old_parent = __clk_set_parent_before(core, core->new_parent);
1764 trace_clk_set_parent(clk, clk->new_parent); 1393 trace_clk_set_parent(core, core->new_parent);
1765 1394
1766 if (clk->ops->set_rate_and_parent) { 1395 if (core->ops->set_rate_and_parent) {
1767 skip_set_rate = true; 1396 skip_set_rate = true;
1768 clk->ops->set_rate_and_parent(clk->hw, clk->new_rate, 1397 core->ops->set_rate_and_parent(core->hw, core->new_rate,
1769 best_parent_rate, 1398 best_parent_rate,
1770 clk->new_parent_index); 1399 core->new_parent_index);
1771 } else if (clk->ops->set_parent) { 1400 } else if (core->ops->set_parent) {
1772 clk->ops->set_parent(clk->hw, clk->new_parent_index); 1401 core->ops->set_parent(core->hw, core->new_parent_index);
1773 } 1402 }
1774 1403
1775 trace_clk_set_parent_complete(clk, clk->new_parent); 1404 trace_clk_set_parent_complete(core, core->new_parent);
1776 __clk_set_parent_after(clk, clk->new_parent, old_parent); 1405 __clk_set_parent_after(core, core->new_parent, old_parent);
1777 } 1406 }
1778 1407
1779 trace_clk_set_rate(clk, clk->new_rate); 1408 trace_clk_set_rate(core, core->new_rate);
1780 1409
1781 if (!skip_set_rate && clk->ops->set_rate) 1410 if (!skip_set_rate && core->ops->set_rate)
1782 clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate); 1411 core->ops->set_rate(core->hw, core->new_rate, best_parent_rate);
1783 1412
1784 trace_clk_set_rate_complete(clk, clk->new_rate); 1413 trace_clk_set_rate_complete(core, core->new_rate);
1785 1414
1786 clk->rate = clk_recalc(clk, best_parent_rate); 1415 core->rate = clk_recalc(core, best_parent_rate);
1787 1416
1788 if (clk->notifier_count && old_rate != clk->rate) 1417 if (core->notifier_count && old_rate != core->rate)
1789 __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); 1418 __clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate);
1790 1419
1791 /* 1420 /*
1792 * Use safe iteration, as change_rate can actually swap parents 1421 * Use safe iteration, as change_rate can actually swap parents
1793 * for certain clock types. 1422 * for certain clock types.
1794 */ 1423 */
1795 hlist_for_each_entry_safe(child, tmp, &clk->children, child_node) { 1424 hlist_for_each_entry_safe(child, tmp, &core->children, child_node) {
1796 /* Skip children who will be reparented to another clock */ 1425 /* Skip children who will be reparented to another clock */
1797 if (child->new_parent && child->new_parent != clk) 1426 if (child->new_parent && child->new_parent != core)
1798 continue; 1427 continue;
1799 clk_change_rate(child); 1428 clk_change_rate(child);
1800 } 1429 }
1801 1430
1802 /* handle the new child who might not be in clk->children yet */ 1431 /* handle the new child who might not be in core->children yet */
1803 if (clk->new_child) 1432 if (core->new_child)
1804 clk_change_rate(clk->new_child); 1433 clk_change_rate(core->new_child);
1805} 1434}
1806 1435
1807static int clk_core_set_rate_nolock(struct clk_core *clk, 1436static int clk_core_set_rate_nolock(struct clk_core *core,
1808 unsigned long req_rate) 1437 unsigned long req_rate)
1809{ 1438{
1810 struct clk_core *top, *fail_clk; 1439 struct clk_core *top, *fail_clk;
1811 unsigned long rate = req_rate; 1440 unsigned long rate = req_rate;
1812 int ret = 0; 1441 int ret = 0;
1813 1442
1814 if (!clk) 1443 if (!core)
1815 return 0; 1444 return 0;
1816 1445
1817 /* bail early if nothing to do */ 1446 /* bail early if nothing to do */
1818 if (rate == clk_core_get_rate_nolock(clk)) 1447 if (rate == clk_core_get_rate_nolock(core))
1819 return 0; 1448 return 0;
1820 1449
1821 if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) 1450 if ((core->flags & CLK_SET_RATE_GATE) && core->prepare_count)
1822 return -EBUSY; 1451 return -EBUSY;
1823 1452
1824 /* calculate new rates and get the topmost changed clock */ 1453 /* calculate new rates and get the topmost changed clock */
1825 top = clk_calc_new_rates(clk, rate); 1454 top = clk_calc_new_rates(core, rate);
1826 if (!top) 1455 if (!top)
1827 return -EINVAL; 1456 return -EINVAL;
1828 1457
@@ -1838,7 +1467,7 @@ static int clk_core_set_rate_nolock(struct clk_core *clk,
1838 /* change the rates */ 1467 /* change the rates */
1839 clk_change_rate(top); 1468 clk_change_rate(top);
1840 1469
1841 clk->req_rate = req_rate; 1470 core->req_rate = req_rate;
1842 1471
1843 return ret; 1472 return ret;
1844} 1473}
@@ -1977,55 +1606,55 @@ EXPORT_SYMBOL_GPL(clk_get_parent);
1977 * .parents array exists, and if so use it to avoid an expensive tree 1606 * .parents array exists, and if so use it to avoid an expensive tree
1978 * traversal. If .parents does not exist then walk the tree. 1607 * traversal. If .parents does not exist then walk the tree.
1979 */ 1608 */
1980static struct clk_core *__clk_init_parent(struct clk_core *clk) 1609static struct clk_core *__clk_init_parent(struct clk_core *core)
1981{ 1610{
1982 struct clk_core *ret = NULL; 1611 struct clk_core *ret = NULL;
1983 u8 index; 1612 u8 index;
1984 1613
1985 /* handle the trivial cases */ 1614 /* handle the trivial cases */
1986 1615
1987 if (!clk->num_parents) 1616 if (!core->num_parents)
1988 goto out; 1617 goto out;
1989 1618
1990 if (clk->num_parents == 1) { 1619 if (core->num_parents == 1) {
1991 if (IS_ERR_OR_NULL(clk->parent)) 1620 if (IS_ERR_OR_NULL(core->parent))
1992 clk->parent = clk_core_lookup(clk->parent_names[0]); 1621 core->parent = clk_core_lookup(core->parent_names[0]);
1993 ret = clk->parent; 1622 ret = core->parent;
1994 goto out; 1623 goto out;
1995 } 1624 }
1996 1625
1997 if (!clk->ops->get_parent) { 1626 if (!core->ops->get_parent) {
1998 WARN(!clk->ops->get_parent, 1627 WARN(!core->ops->get_parent,
1999 "%s: multi-parent clocks must implement .get_parent\n", 1628 "%s: multi-parent clocks must implement .get_parent\n",
2000 __func__); 1629 __func__);
2001 goto out; 1630 goto out;
2002 }; 1631 };
2003 1632
2004 /* 1633 /*
2005 * Do our best to cache parent clocks in clk->parents. This prevents 1634 * Do our best to cache parent clocks in core->parents. This prevents
2006 * unnecessary and expensive lookups. We don't set clk->parent here; 1635 * unnecessary and expensive lookups. We don't set core->parent here;
2007 * that is done by the calling function. 1636 * that is done by the calling function.
2008 */ 1637 */
2009 1638
2010 index = clk->ops->get_parent(clk->hw); 1639 index = core->ops->get_parent(core->hw);
2011 1640
2012 if (!clk->parents) 1641 if (!core->parents)
2013 clk->parents = 1642 core->parents =
2014 kcalloc(clk->num_parents, sizeof(struct clk *), 1643 kcalloc(core->num_parents, sizeof(struct clk *),
2015 GFP_KERNEL); 1644 GFP_KERNEL);
2016 1645
2017 ret = clk_core_get_parent_by_index(clk, index); 1646 ret = clk_core_get_parent_by_index(core, index);
2018 1647
2019out: 1648out:
2020 return ret; 1649 return ret;
2021} 1650}
2022 1651
2023static void clk_core_reparent(struct clk_core *clk, 1652static void clk_core_reparent(struct clk_core *core,
2024 struct clk_core *new_parent) 1653 struct clk_core *new_parent)
2025{ 1654{
2026 clk_reparent(clk, new_parent); 1655 clk_reparent(core, new_parent);
2027 __clk_recalc_accuracies(clk); 1656 __clk_recalc_accuracies(core);
2028 __clk_recalc_rates(clk, POST_RATE_CHANGE); 1657 __clk_recalc_rates(core, POST_RATE_CHANGE);
2029} 1658}
2030 1659
2031/** 1660/**
@@ -2062,61 +1691,61 @@ bool clk_has_parent(struct clk *clk, struct clk *parent)
2062} 1691}
2063EXPORT_SYMBOL_GPL(clk_has_parent); 1692EXPORT_SYMBOL_GPL(clk_has_parent);
2064 1693
2065static int clk_core_set_parent(struct clk_core *clk, struct clk_core *parent) 1694static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
2066{ 1695{
2067 int ret = 0; 1696 int ret = 0;
2068 int p_index = 0; 1697 int p_index = 0;
2069 unsigned long p_rate = 0; 1698 unsigned long p_rate = 0;
2070 1699
2071 if (!clk) 1700 if (!core)
2072 return 0; 1701 return 0;
2073 1702
2074 /* prevent racing with updates to the clock topology */ 1703 /* prevent racing with updates to the clock topology */
2075 clk_prepare_lock(); 1704 clk_prepare_lock();
2076 1705
2077 if (clk->parent == parent) 1706 if (core->parent == parent)
2078 goto out; 1707 goto out;
2079 1708
2080 /* verify ops for for multi-parent clks */ 1709 /* verify ops for for multi-parent clks */
2081 if ((clk->num_parents > 1) && (!clk->ops->set_parent)) { 1710 if ((core->num_parents > 1) && (!core->ops->set_parent)) {
2082 ret = -ENOSYS; 1711 ret = -ENOSYS;
2083 goto out; 1712 goto out;
2084 } 1713 }
2085 1714
2086 /* check that we are allowed to re-parent if the clock is in use */ 1715 /* check that we are allowed to re-parent if the clock is in use */
2087 if ((clk->flags & CLK_SET_PARENT_GATE) && clk->prepare_count) { 1716 if ((core->flags & CLK_SET_PARENT_GATE) && core->prepare_count) {
2088 ret = -EBUSY; 1717 ret = -EBUSY;
2089 goto out; 1718 goto out;
2090 } 1719 }
2091 1720
2092 /* try finding the new parent index */ 1721 /* try finding the new parent index */
2093 if (parent) { 1722 if (parent) {
2094 p_index = clk_fetch_parent_index(clk, parent); 1723 p_index = clk_fetch_parent_index(core, parent);
2095 p_rate = parent->rate; 1724 p_rate = parent->rate;
2096 if (p_index < 0) { 1725 if (p_index < 0) {
2097 pr_debug("%s: clk %s can not be parent of clk %s\n", 1726 pr_debug("%s: clk %s can not be parent of clk %s\n",
2098 __func__, parent->name, clk->name); 1727 __func__, parent->name, core->name);
2099 ret = p_index; 1728 ret = p_index;
2100 goto out; 1729 goto out;
2101 } 1730 }
2102 } 1731 }
2103 1732
2104 /* propagate PRE_RATE_CHANGE notifications */ 1733 /* propagate PRE_RATE_CHANGE notifications */
2105 ret = __clk_speculate_rates(clk, p_rate); 1734 ret = __clk_speculate_rates(core, p_rate);
2106 1735
2107 /* abort if a driver objects */ 1736 /* abort if a driver objects */
2108 if (ret & NOTIFY_STOP_MASK) 1737 if (ret & NOTIFY_STOP_MASK)
2109 goto out; 1738 goto out;
2110 1739
2111 /* do the re-parent */ 1740 /* do the re-parent */
2112 ret = __clk_set_parent(clk, parent, p_index); 1741 ret = __clk_set_parent(core, parent, p_index);
2113 1742
2114 /* propagate rate an accuracy recalculation accordingly */ 1743 /* propagate rate an accuracy recalculation accordingly */
2115 if (ret) { 1744 if (ret) {
2116 __clk_recalc_rates(clk, ABORT_RATE_CHANGE); 1745 __clk_recalc_rates(core, ABORT_RATE_CHANGE);
2117 } else { 1746 } else {
2118 __clk_recalc_rates(clk, POST_RATE_CHANGE); 1747 __clk_recalc_rates(core, POST_RATE_CHANGE);
2119 __clk_recalc_accuracies(clk); 1748 __clk_recalc_accuracies(core);
2120 } 1749 }
2121 1750
2122out: 1751out:
@@ -2201,21 +1830,16 @@ int clk_set_phase(struct clk *clk, int degrees)
2201} 1830}
2202EXPORT_SYMBOL_GPL(clk_set_phase); 1831EXPORT_SYMBOL_GPL(clk_set_phase);
2203 1832
2204static int clk_core_get_phase(struct clk_core *clk) 1833static int clk_core_get_phase(struct clk_core *core)
2205{ 1834{
2206 int ret = 0; 1835 int ret;
2207
2208 if (!clk)
2209 goto out;
2210 1836
2211 clk_prepare_lock(); 1837 clk_prepare_lock();
2212 ret = clk->phase; 1838 ret = core->phase;
2213 clk_prepare_unlock(); 1839 clk_prepare_unlock();
2214 1840
2215out:
2216 return ret; 1841 return ret;
2217} 1842}
2218EXPORT_SYMBOL_GPL(clk_get_phase);
2219 1843
2220/** 1844/**
2221 * clk_get_phase - return the phase shift of a clock signal 1845 * clk_get_phase - return the phase shift of a clock signal
@@ -2231,6 +1855,7 @@ int clk_get_phase(struct clk *clk)
2231 1855
2232 return clk_core_get_phase(clk->core); 1856 return clk_core_get_phase(clk->core);
2233} 1857}
1858EXPORT_SYMBOL_GPL(clk_get_phase);
2234 1859
2235/** 1860/**
2236 * clk_is_match - check if two clk's point to the same hardware clock 1861 * clk_is_match - check if two clk's point to the same hardware clock
@@ -2258,6 +1883,337 @@ bool clk_is_match(const struct clk *p, const struct clk *q)
2258} 1883}
2259EXPORT_SYMBOL_GPL(clk_is_match); 1884EXPORT_SYMBOL_GPL(clk_is_match);
2260 1885
1886/*** debugfs support ***/
1887
1888#ifdef CONFIG_DEBUG_FS
1889#include <linux/debugfs.h>
1890
1891static struct dentry *rootdir;
1892static int inited = 0;
1893static DEFINE_MUTEX(clk_debug_lock);
1894static HLIST_HEAD(clk_debug_list);
1895
1896static struct hlist_head *all_lists[] = {
1897 &clk_root_list,
1898 &clk_orphan_list,
1899 NULL,
1900};
1901
1902static struct hlist_head *orphan_list[] = {
1903 &clk_orphan_list,
1904 NULL,
1905};
1906
1907static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
1908 int level)
1909{
1910 if (!c)
1911 return;
1912
1913 seq_printf(s, "%*s%-*s %11d %12d %11lu %10lu %-3d\n",
1914 level * 3 + 1, "",
1915 30 - level * 3, c->name,
1916 c->enable_count, c->prepare_count, clk_core_get_rate(c),
1917 clk_core_get_accuracy(c), clk_core_get_phase(c));
1918}
1919
1920static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
1921 int level)
1922{
1923 struct clk_core *child;
1924
1925 if (!c)
1926 return;
1927
1928 clk_summary_show_one(s, c, level);
1929
1930 hlist_for_each_entry(child, &c->children, child_node)
1931 clk_summary_show_subtree(s, child, level + 1);
1932}
1933
1934static int clk_summary_show(struct seq_file *s, void *data)
1935{
1936 struct clk_core *c;
1937 struct hlist_head **lists = (struct hlist_head **)s->private;
1938
1939 seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy phase\n");
1940 seq_puts(s, "----------------------------------------------------------------------------------------\n");
1941
1942 clk_prepare_lock();
1943
1944 for (; *lists; lists++)
1945 hlist_for_each_entry(c, *lists, child_node)
1946 clk_summary_show_subtree(s, c, 0);
1947
1948 clk_prepare_unlock();
1949
1950 return 0;
1951}
1952
1953
1954static int clk_summary_open(struct inode *inode, struct file *file)
1955{
1956 return single_open(file, clk_summary_show, inode->i_private);
1957}
1958
1959static const struct file_operations clk_summary_fops = {
1960 .open = clk_summary_open,
1961 .read = seq_read,
1962 .llseek = seq_lseek,
1963 .release = single_release,
1964};
1965
1966static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
1967{
1968 if (!c)
1969 return;
1970
1971 /* This should be JSON format, i.e. elements separated with a comma */
1972 seq_printf(s, "\"%s\": { ", c->name);
1973 seq_printf(s, "\"enable_count\": %d,", c->enable_count);
1974 seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
1975 seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c));
1976 seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c));
1977 seq_printf(s, "\"phase\": %d", clk_core_get_phase(c));
1978}
1979
1980static void clk_dump_subtree(struct seq_file *s, struct clk_core *c, int level)
1981{
1982 struct clk_core *child;
1983
1984 if (!c)
1985 return;
1986
1987 clk_dump_one(s, c, level);
1988
1989 hlist_for_each_entry(child, &c->children, child_node) {
1990 seq_printf(s, ",");
1991 clk_dump_subtree(s, child, level + 1);
1992 }
1993
1994 seq_printf(s, "}");
1995}
1996
1997static int clk_dump(struct seq_file *s, void *data)
1998{
1999 struct clk_core *c;
2000 bool first_node = true;
2001 struct hlist_head **lists = (struct hlist_head **)s->private;
2002
2003 seq_printf(s, "{");
2004
2005 clk_prepare_lock();
2006
2007 for (; *lists; lists++) {
2008 hlist_for_each_entry(c, *lists, child_node) {
2009 if (!first_node)
2010 seq_puts(s, ",");
2011 first_node = false;
2012 clk_dump_subtree(s, c, 0);
2013 }
2014 }
2015
2016 clk_prepare_unlock();
2017
2018 seq_puts(s, "}\n");
2019 return 0;
2020}
2021
2022
2023static int clk_dump_open(struct inode *inode, struct file *file)
2024{
2025 return single_open(file, clk_dump, inode->i_private);
2026}
2027
2028static const struct file_operations clk_dump_fops = {
2029 .open = clk_dump_open,
2030 .read = seq_read,
2031 .llseek = seq_lseek,
2032 .release = single_release,
2033};
2034
2035static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
2036{
2037 struct dentry *d;
2038 int ret = -ENOMEM;
2039
2040 if (!core || !pdentry) {
2041 ret = -EINVAL;
2042 goto out;
2043 }
2044
2045 d = debugfs_create_dir(core->name, pdentry);
2046 if (!d)
2047 goto out;
2048
2049 core->dentry = d;
2050
2051 d = debugfs_create_u32("clk_rate", S_IRUGO, core->dentry,
2052 (u32 *)&core->rate);
2053 if (!d)
2054 goto err_out;
2055
2056 d = debugfs_create_u32("clk_accuracy", S_IRUGO, core->dentry,
2057 (u32 *)&core->accuracy);
2058 if (!d)
2059 goto err_out;
2060
2061 d = debugfs_create_u32("clk_phase", S_IRUGO, core->dentry,
2062 (u32 *)&core->phase);
2063 if (!d)
2064 goto err_out;
2065
2066 d = debugfs_create_x32("clk_flags", S_IRUGO, core->dentry,
2067 (u32 *)&core->flags);
2068 if (!d)
2069 goto err_out;
2070
2071 d = debugfs_create_u32("clk_prepare_count", S_IRUGO, core->dentry,
2072 (u32 *)&core->prepare_count);
2073 if (!d)
2074 goto err_out;
2075
2076 d = debugfs_create_u32("clk_enable_count", S_IRUGO, core->dentry,
2077 (u32 *)&core->enable_count);
2078 if (!d)
2079 goto err_out;
2080
2081 d = debugfs_create_u32("clk_notifier_count", S_IRUGO, core->dentry,
2082 (u32 *)&core->notifier_count);
2083 if (!d)
2084 goto err_out;
2085
2086 if (core->ops->debug_init) {
2087 ret = core->ops->debug_init(core->hw, core->dentry);
2088 if (ret)
2089 goto err_out;
2090 }
2091
2092 ret = 0;
2093 goto out;
2094
2095err_out:
2096 debugfs_remove_recursive(core->dentry);
2097 core->dentry = NULL;
2098out:
2099 return ret;
2100}
2101
2102/**
2103 * clk_debug_register - add a clk node to the debugfs clk directory
2104 * @core: the clk being added to the debugfs clk directory
2105 *
2106 * Dynamically adds a clk to the debugfs clk directory if debugfs has been
2107 * initialized. Otherwise it bails out early since the debugfs clk directory
2108 * will be created lazily by clk_debug_init as part of a late_initcall.
2109 */
2110static int clk_debug_register(struct clk_core *core)
2111{
2112 int ret = 0;
2113
2114 mutex_lock(&clk_debug_lock);
2115 hlist_add_head(&core->debug_node, &clk_debug_list);
2116
2117 if (!inited)
2118 goto unlock;
2119
2120 ret = clk_debug_create_one(core, rootdir);
2121unlock:
2122 mutex_unlock(&clk_debug_lock);
2123
2124 return ret;
2125}
2126
2127 /**
2128 * clk_debug_unregister - remove a clk node from the debugfs clk directory
2129 * @core: the clk being removed from the debugfs clk directory
2130 *
2131 * Dynamically removes a clk and all its child nodes from the
2132 * debugfs clk directory if clk->dentry points to debugfs created by
2133 * clk_debug_register in __clk_init.
2134 */
2135static void clk_debug_unregister(struct clk_core *core)
2136{
2137 mutex_lock(&clk_debug_lock);
2138 hlist_del_init(&core->debug_node);
2139 debugfs_remove_recursive(core->dentry);
2140 core->dentry = NULL;
2141 mutex_unlock(&clk_debug_lock);
2142}
2143
2144struct dentry *clk_debugfs_add_file(struct clk_hw *hw, char *name, umode_t mode,
2145 void *data, const struct file_operations *fops)
2146{
2147 struct dentry *d = NULL;
2148
2149 if (hw->core->dentry)
2150 d = debugfs_create_file(name, mode, hw->core->dentry, data,
2151 fops);
2152
2153 return d;
2154}
2155EXPORT_SYMBOL_GPL(clk_debugfs_add_file);
2156
2157/**
2158 * clk_debug_init - lazily populate the debugfs clk directory
2159 *
2160 * clks are often initialized very early during boot before memory can be
2161 * dynamically allocated and well before debugfs is setup. This function
2162 * populates the debugfs clk directory once at boot-time when we know that
2163 * debugfs is setup. It should only be called once at boot-time, all other clks
2164 * added dynamically will be done so with clk_debug_register.
2165 */
2166static int __init clk_debug_init(void)
2167{
2168 struct clk_core *core;
2169 struct dentry *d;
2170
2171 rootdir = debugfs_create_dir("clk", NULL);
2172
2173 if (!rootdir)
2174 return -ENOMEM;
2175
2176 d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, &all_lists,
2177 &clk_summary_fops);
2178 if (!d)
2179 return -ENOMEM;
2180
2181 d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, &all_lists,
2182 &clk_dump_fops);
2183 if (!d)
2184 return -ENOMEM;
2185
2186 d = debugfs_create_file("clk_orphan_summary", S_IRUGO, rootdir,
2187 &orphan_list, &clk_summary_fops);
2188 if (!d)
2189 return -ENOMEM;
2190
2191 d = debugfs_create_file("clk_orphan_dump", S_IRUGO, rootdir,
2192 &orphan_list, &clk_dump_fops);
2193 if (!d)
2194 return -ENOMEM;
2195
2196 mutex_lock(&clk_debug_lock);
2197 hlist_for_each_entry(core, &clk_debug_list, debug_node)
2198 clk_debug_create_one(core, rootdir);
2199
2200 inited = 1;
2201 mutex_unlock(&clk_debug_lock);
2202
2203 return 0;
2204}
2205late_initcall(clk_debug_init);
2206#else
2207static inline int clk_debug_register(struct clk_core *core) { return 0; }
2208static inline void clk_debug_reparent(struct clk_core *core,
2209 struct clk_core *new_parent)
2210{
2211}
2212static inline void clk_debug_unregister(struct clk_core *core)
2213{
2214}
2215#endif
2216
2261/** 2217/**
2262 * __clk_init - initialize the data structures in a struct clk 2218 * __clk_init - initialize the data structures in a struct clk
2263 * @dev: device initializing this clk, placeholder for now 2219 * @dev: device initializing this clk, placeholder for now
@@ -2271,67 +2227,67 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
2271 int i, ret = 0; 2227 int i, ret = 0;
2272 struct clk_core *orphan; 2228 struct clk_core *orphan;
2273 struct hlist_node *tmp2; 2229 struct hlist_node *tmp2;
2274 struct clk_core *clk; 2230 struct clk_core *core;
2275 unsigned long rate; 2231 unsigned long rate;
2276 2232
2277 if (!clk_user) 2233 if (!clk_user)
2278 return -EINVAL; 2234 return -EINVAL;
2279 2235
2280 clk = clk_user->core; 2236 core = clk_user->core;
2281 2237
2282 clk_prepare_lock(); 2238 clk_prepare_lock();
2283 2239
2284 /* check to see if a clock with this name is already registered */ 2240 /* check to see if a clock with this name is already registered */
2285 if (clk_core_lookup(clk->name)) { 2241 if (clk_core_lookup(core->name)) {
2286 pr_debug("%s: clk %s already initialized\n", 2242 pr_debug("%s: clk %s already initialized\n",
2287 __func__, clk->name); 2243 __func__, core->name);
2288 ret = -EEXIST; 2244 ret = -EEXIST;
2289 goto out; 2245 goto out;
2290 } 2246 }
2291 2247
2292 /* check that clk_ops are sane. See Documentation/clk.txt */ 2248 /* check that clk_ops are sane. See Documentation/clk.txt */
2293 if (clk->ops->set_rate && 2249 if (core->ops->set_rate &&
2294 !((clk->ops->round_rate || clk->ops->determine_rate) && 2250 !((core->ops->round_rate || core->ops->determine_rate) &&
2295 clk->ops->recalc_rate)) { 2251 core->ops->recalc_rate)) {
2296 pr_warning("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n", 2252 pr_warning("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n",
2297 __func__, clk->name); 2253 __func__, core->name);
2298 ret = -EINVAL; 2254 ret = -EINVAL;
2299 goto out; 2255 goto out;
2300 } 2256 }
2301 2257
2302 if (clk->ops->set_parent && !clk->ops->get_parent) { 2258 if (core->ops->set_parent && !core->ops->get_parent) {
2303 pr_warning("%s: %s must implement .get_parent & .set_parent\n", 2259 pr_warning("%s: %s must implement .get_parent & .set_parent\n",
2304 __func__, clk->name); 2260 __func__, core->name);
2305 ret = -EINVAL; 2261 ret = -EINVAL;
2306 goto out; 2262 goto out;
2307 } 2263 }
2308 2264
2309 if (clk->ops->set_rate_and_parent && 2265 if (core->ops->set_rate_and_parent &&
2310 !(clk->ops->set_parent && clk->ops->set_rate)) { 2266 !(core->ops->set_parent && core->ops->set_rate)) {
2311 pr_warn("%s: %s must implement .set_parent & .set_rate\n", 2267 pr_warn("%s: %s must implement .set_parent & .set_rate\n",
2312 __func__, clk->name); 2268 __func__, core->name);
2313 ret = -EINVAL; 2269 ret = -EINVAL;
2314 goto out; 2270 goto out;
2315 } 2271 }
2316 2272
2317 /* throw a WARN if any entries in parent_names are NULL */ 2273 /* throw a WARN if any entries in parent_names are NULL */
2318 for (i = 0; i < clk->num_parents; i++) 2274 for (i = 0; i < core->num_parents; i++)
2319 WARN(!clk->parent_names[i], 2275 WARN(!core->parent_names[i],
2320 "%s: invalid NULL in %s's .parent_names\n", 2276 "%s: invalid NULL in %s's .parent_names\n",
2321 __func__, clk->name); 2277 __func__, core->name);
2322 2278
2323 /* 2279 /*
2324 * Allocate an array of struct clk *'s to avoid unnecessary string 2280 * Allocate an array of struct clk *'s to avoid unnecessary string
2325 * look-ups of clk's possible parents. This can fail for clocks passed 2281 * look-ups of clk's possible parents. This can fail for clocks passed
2326 * in to clk_init during early boot; thus any access to clk->parents[] 2282 * in to clk_init during early boot; thus any access to core->parents[]
2327 * must always check for a NULL pointer and try to populate it if 2283 * must always check for a NULL pointer and try to populate it if
2328 * necessary. 2284 * necessary.
2329 * 2285 *
2330 * If clk->parents is not NULL we skip this entire block. This allows 2286 * If core->parents is not NULL we skip this entire block. This allows
2331 * for clock drivers to statically initialize clk->parents. 2287 * for clock drivers to statically initialize core->parents.
2332 */ 2288 */
2333 if (clk->num_parents > 1 && !clk->parents) { 2289 if (core->num_parents > 1 && !core->parents) {
2334 clk->parents = kcalloc(clk->num_parents, sizeof(struct clk *), 2290 core->parents = kcalloc(core->num_parents, sizeof(struct clk *),
2335 GFP_KERNEL); 2291 GFP_KERNEL);
2336 /* 2292 /*
2337 * clk_core_lookup returns NULL for parents that have not been 2293 * clk_core_lookup returns NULL for parents that have not been
@@ -2339,16 +2295,16 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
2339 * for a NULL pointer. We can always perform lazy lookups for 2295 * for a NULL pointer. We can always perform lazy lookups for
2340 * missing parents later on. 2296 * missing parents later on.
2341 */ 2297 */
2342 if (clk->parents) 2298 if (core->parents)
2343 for (i = 0; i < clk->num_parents; i++) 2299 for (i = 0; i < core->num_parents; i++)
2344 clk->parents[i] = 2300 core->parents[i] =
2345 clk_core_lookup(clk->parent_names[i]); 2301 clk_core_lookup(core->parent_names[i]);
2346 } 2302 }
2347 2303
2348 clk->parent = __clk_init_parent(clk); 2304 core->parent = __clk_init_parent(core);
2349 2305
2350 /* 2306 /*
2351 * Populate clk->parent if parent has already been __clk_init'd. If 2307 * Populate core->parent if parent has already been __clk_init'd. If
2352 * parent has not yet been __clk_init'd then place clk in the orphan 2308 * parent has not yet been __clk_init'd then place clk in the orphan
2353 * list. If clk has set the CLK_IS_ROOT flag then place it in the root 2309 * list. If clk has set the CLK_IS_ROOT flag then place it in the root
2354 * clk list. 2310 * clk list.
@@ -2357,13 +2313,13 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
2357 * clocks and re-parent any that are children of the clock currently 2313 * clocks and re-parent any that are children of the clock currently
2358 * being clk_init'd. 2314 * being clk_init'd.
2359 */ 2315 */
2360 if (clk->parent) 2316 if (core->parent)
2361 hlist_add_head(&clk->child_node, 2317 hlist_add_head(&core->child_node,
2362 &clk->parent->children); 2318 &core->parent->children);
2363 else if (clk->flags & CLK_IS_ROOT) 2319 else if (core->flags & CLK_IS_ROOT)
2364 hlist_add_head(&clk->child_node, &clk_root_list); 2320 hlist_add_head(&core->child_node, &clk_root_list);
2365 else 2321 else
2366 hlist_add_head(&clk->child_node, &clk_orphan_list); 2322 hlist_add_head(&core->child_node, &clk_orphan_list);
2367 2323
2368 /* 2324 /*
2369 * Set clk's accuracy. The preferred method is to use 2325 * Set clk's accuracy. The preferred method is to use
@@ -2372,23 +2328,23 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
2372 * parent (or is orphaned) then accuracy is set to zero (perfect 2328 * parent (or is orphaned) then accuracy is set to zero (perfect
2373 * clock). 2329 * clock).
2374 */ 2330 */
2375 if (clk->ops->recalc_accuracy) 2331 if (core->ops->recalc_accuracy)
2376 clk->accuracy = clk->ops->recalc_accuracy(clk->hw, 2332 core->accuracy = core->ops->recalc_accuracy(core->hw,
2377 __clk_get_accuracy(clk->parent)); 2333 __clk_get_accuracy(core->parent));
2378 else if (clk->parent) 2334 else if (core->parent)
2379 clk->accuracy = clk->parent->accuracy; 2335 core->accuracy = core->parent->accuracy;
2380 else 2336 else
2381 clk->accuracy = 0; 2337 core->accuracy = 0;
2382 2338
2383 /* 2339 /*
2384 * Set clk's phase. 2340 * Set clk's phase.
2385 * Since a phase is by definition relative to its parent, just 2341 * Since a phase is by definition relative to its parent, just
2386 * query the current clock phase, or just assume it's in phase. 2342 * query the current clock phase, or just assume it's in phase.
2387 */ 2343 */
2388 if (clk->ops->get_phase) 2344 if (core->ops->get_phase)
2389 clk->phase = clk->ops->get_phase(clk->hw); 2345 core->phase = core->ops->get_phase(core->hw);
2390 else 2346 else
2391 clk->phase = 0; 2347 core->phase = 0;
2392 2348
2393 /* 2349 /*
2394 * Set clk's rate. The preferred method is to use .recalc_rate. For 2350 * Set clk's rate. The preferred method is to use .recalc_rate. For
@@ -2396,14 +2352,14 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
2396 * parent's rate. If a clock doesn't have a parent (or is orphaned) 2352 * parent's rate. If a clock doesn't have a parent (or is orphaned)
2397 * then rate is set to zero. 2353 * then rate is set to zero.
2398 */ 2354 */
2399 if (clk->ops->recalc_rate) 2355 if (core->ops->recalc_rate)
2400 rate = clk->ops->recalc_rate(clk->hw, 2356 rate = core->ops->recalc_rate(core->hw,
2401 clk_core_get_rate_nolock(clk->parent)); 2357 clk_core_get_rate_nolock(core->parent));
2402 else if (clk->parent) 2358 else if (core->parent)
2403 rate = clk->parent->rate; 2359 rate = core->parent->rate;
2404 else 2360 else
2405 rate = 0; 2361 rate = 0;
2406 clk->rate = clk->req_rate = rate; 2362 core->rate = core->req_rate = rate;
2407 2363
2408 /* 2364 /*
2409 * walk the list of orphan clocks and reparent any that are children of 2365 * walk the list of orphan clocks and reparent any that are children of
@@ -2412,14 +2368,14 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
2412 hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { 2368 hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
2413 if (orphan->num_parents && orphan->ops->get_parent) { 2369 if (orphan->num_parents && orphan->ops->get_parent) {
2414 i = orphan->ops->get_parent(orphan->hw); 2370 i = orphan->ops->get_parent(orphan->hw);
2415 if (!strcmp(clk->name, orphan->parent_names[i])) 2371 if (!strcmp(core->name, orphan->parent_names[i]))
2416 clk_core_reparent(orphan, clk); 2372 clk_core_reparent(orphan, core);
2417 continue; 2373 continue;
2418 } 2374 }
2419 2375
2420 for (i = 0; i < orphan->num_parents; i++) 2376 for (i = 0; i < orphan->num_parents; i++)
2421 if (!strcmp(clk->name, orphan->parent_names[i])) { 2377 if (!strcmp(core->name, orphan->parent_names[i])) {
2422 clk_core_reparent(orphan, clk); 2378 clk_core_reparent(orphan, core);
2423 break; 2379 break;
2424 } 2380 }
2425 } 2381 }
@@ -2432,15 +2388,15 @@ static int __clk_init(struct device *dev, struct clk *clk_user)
2432 * Please consider other ways of solving initialization problems before 2388 * Please consider other ways of solving initialization problems before
2433 * using this callback, as its use is discouraged. 2389 * using this callback, as its use is discouraged.
2434 */ 2390 */
2435 if (clk->ops->init) 2391 if (core->ops->init)
2436 clk->ops->init(clk->hw); 2392 core->ops->init(core->hw);
2437 2393
2438 kref_init(&clk->ref); 2394 kref_init(&core->ref);
2439out: 2395out:
2440 clk_prepare_unlock(); 2396 clk_prepare_unlock();
2441 2397
2442 if (!ret) 2398 if (!ret)
2443 clk_debug_register(clk); 2399 clk_debug_register(core);
2444 2400
2445 return ret; 2401 return ret;
2446} 2402}
@@ -2486,63 +2442,58 @@ void __clk_free_clk(struct clk *clk)
2486 * 2442 *
2487 * clk_register is the primary interface for populating the clock tree with new 2443 * clk_register is the primary interface for populating the clock tree with new
2488 * clock nodes. It returns a pointer to the newly allocated struct clk which 2444 * clock nodes. It returns a pointer to the newly allocated struct clk which
2489 * cannot be dereferenced by driver code but may be used in conjuction with the 2445 * cannot be dereferenced by driver code but may be used in conjunction with the
2490 * rest of the clock API. In the event of an error clk_register will return an 2446 * rest of the clock API. In the event of an error clk_register will return an
2491 * error code; drivers must test for an error code after calling clk_register. 2447 * error code; drivers must test for an error code after calling clk_register.
2492 */ 2448 */
2493struct clk *clk_register(struct device *dev, struct clk_hw *hw) 2449struct clk *clk_register(struct device *dev, struct clk_hw *hw)
2494{ 2450{
2495 int i, ret; 2451 int i, ret;
2496 struct clk_core *clk; 2452 struct clk_core *core;
2497 2453
2498 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 2454 core = kzalloc(sizeof(*core), GFP_KERNEL);
2499 if (!clk) { 2455 if (!core) {
2500 pr_err("%s: could not allocate clk\n", __func__);
2501 ret = -ENOMEM; 2456 ret = -ENOMEM;
2502 goto fail_out; 2457 goto fail_out;
2503 } 2458 }
2504 2459
2505 clk->name = kstrdup_const(hw->init->name, GFP_KERNEL); 2460 core->name = kstrdup_const(hw->init->name, GFP_KERNEL);
2506 if (!clk->name) { 2461 if (!core->name) {
2507 pr_err("%s: could not allocate clk->name\n", __func__);
2508 ret = -ENOMEM; 2462 ret = -ENOMEM;
2509 goto fail_name; 2463 goto fail_name;
2510 } 2464 }
2511 clk->ops = hw->init->ops; 2465 core->ops = hw->init->ops;
2512 if (dev && dev->driver) 2466 if (dev && dev->driver)
2513 clk->owner = dev->driver->owner; 2467 core->owner = dev->driver->owner;
2514 clk->hw = hw; 2468 core->hw = hw;
2515 clk->flags = hw->init->flags; 2469 core->flags = hw->init->flags;
2516 clk->num_parents = hw->init->num_parents; 2470 core->num_parents = hw->init->num_parents;
2517 hw->core = clk; 2471 hw->core = core;
2518 2472
2519 /* allocate local copy in case parent_names is __initdata */ 2473 /* allocate local copy in case parent_names is __initdata */
2520 clk->parent_names = kcalloc(clk->num_parents, sizeof(char *), 2474 core->parent_names = kcalloc(core->num_parents, sizeof(char *),
2521 GFP_KERNEL); 2475 GFP_KERNEL);
2522 2476
2523 if (!clk->parent_names) { 2477 if (!core->parent_names) {
2524 pr_err("%s: could not allocate clk->parent_names\n", __func__);
2525 ret = -ENOMEM; 2478 ret = -ENOMEM;
2526 goto fail_parent_names; 2479 goto fail_parent_names;
2527 } 2480 }
2528 2481
2529 2482
2530 /* copy each string name in case parent_names is __initdata */ 2483 /* copy each string name in case parent_names is __initdata */
2531 for (i = 0; i < clk->num_parents; i++) { 2484 for (i = 0; i < core->num_parents; i++) {
2532 clk->parent_names[i] = kstrdup_const(hw->init->parent_names[i], 2485 core->parent_names[i] = kstrdup_const(hw->init->parent_names[i],
2533 GFP_KERNEL); 2486 GFP_KERNEL);
2534 if (!clk->parent_names[i]) { 2487 if (!core->parent_names[i]) {
2535 pr_err("%s: could not copy parent_names\n", __func__);
2536 ret = -ENOMEM; 2488 ret = -ENOMEM;
2537 goto fail_parent_names_copy; 2489 goto fail_parent_names_copy;
2538 } 2490 }
2539 } 2491 }
2540 2492
2541 INIT_HLIST_HEAD(&clk->clks); 2493 INIT_HLIST_HEAD(&core->clks);
2542 2494
2543 hw->clk = __clk_create_clk(hw, NULL, NULL); 2495 hw->clk = __clk_create_clk(hw, NULL, NULL);
2544 if (IS_ERR(hw->clk)) { 2496 if (IS_ERR(hw->clk)) {
2545 pr_err("%s: could not allocate per-user clk\n", __func__);
2546 ret = PTR_ERR(hw->clk); 2497 ret = PTR_ERR(hw->clk);
2547 goto fail_parent_names_copy; 2498 goto fail_parent_names_copy;
2548 } 2499 }
@@ -2556,35 +2507,32 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
2556 2507
2557fail_parent_names_copy: 2508fail_parent_names_copy:
2558 while (--i >= 0) 2509 while (--i >= 0)
2559 kfree_const(clk->parent_names[i]); 2510 kfree_const(core->parent_names[i]);
2560 kfree(clk->parent_names); 2511 kfree(core->parent_names);
2561fail_parent_names: 2512fail_parent_names:
2562 kfree_const(clk->name); 2513 kfree_const(core->name);
2563fail_name: 2514fail_name:
2564 kfree(clk); 2515 kfree(core);
2565fail_out: 2516fail_out:
2566 return ERR_PTR(ret); 2517 return ERR_PTR(ret);
2567} 2518}
2568EXPORT_SYMBOL_GPL(clk_register); 2519EXPORT_SYMBOL_GPL(clk_register);
2569 2520
2570/* 2521/* Free memory allocated for a clock. */
2571 * Free memory allocated for a clock.
2572 * Caller must hold prepare_lock.
2573 */
2574static void __clk_release(struct kref *ref) 2522static void __clk_release(struct kref *ref)
2575{ 2523{
2576 struct clk_core *clk = container_of(ref, struct clk_core, ref); 2524 struct clk_core *core = container_of(ref, struct clk_core, ref);
2577 int i = clk->num_parents; 2525 int i = core->num_parents;
2578 2526
2579 lockdep_assert_held(&prepare_lock); 2527 lockdep_assert_held(&prepare_lock);
2580 2528
2581 kfree(clk->parents); 2529 kfree(core->parents);
2582 while (--i >= 0) 2530 while (--i >= 0)
2583 kfree_const(clk->parent_names[i]); 2531 kfree_const(core->parent_names[i]);
2584 2532
2585 kfree(clk->parent_names); 2533 kfree(core->parent_names);
2586 kfree_const(clk->name); 2534 kfree_const(core->name);
2587 kfree(clk); 2535 kfree(core);
2588} 2536}
2589 2537
2590/* 2538/*
@@ -3068,6 +3016,27 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
3068} 3016}
3069EXPORT_SYMBOL_GPL(of_clk_get_parent_name); 3017EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
3070 3018
3019/**
3020 * of_clk_parent_fill() - Fill @parents with names of @np's parents and return
3021 * number of parents
3022 * @np: Device node pointer associated with clock provider
3023 * @parents: pointer to char array that hold the parents' names
3024 * @size: size of the @parents array
3025 *
3026 * Return: number of parents for the clock node.
3027 */
3028int of_clk_parent_fill(struct device_node *np, const char **parents,
3029 unsigned int size)
3030{
3031 unsigned int i = 0;
3032
3033 while (i < size && (parents[i] = of_clk_get_parent_name(np, i)) != NULL)
3034 i++;
3035
3036 return i;
3037}
3038EXPORT_SYMBOL_GPL(of_clk_parent_fill);
3039
3071struct clock_provider { 3040struct clock_provider {
3072 of_clk_init_cb_t clk_init_cb; 3041 of_clk_init_cb_t clk_init_cb;
3073 struct device_node *np; 3042 struct device_node *np;
diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
new file mode 100644
index 000000000000..b4165ba75d9f
--- /dev/null
+++ b/drivers/clk/hisilicon/Kconfig
@@ -0,0 +1,6 @@
1config COMMON_CLK_HI6220
2 bool "Hi6220 Clock Driver"
3 depends on ARCH_HISI || COMPILE_TEST
4 default ARCH_HISI
5 help
6 Build the Hisilicon Hi6220 clock driver based on the common clock framework.
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index 038c02f4d0e7..48f0116a032a 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -2,8 +2,9 @@
2# Hisilicon Clock specific Makefile 2# Hisilicon Clock specific Makefile
3# 3#
4 4
5obj-y += clk.o clkgate-separated.o 5obj-y += clk.o clkgate-separated.o clkdivider-hi6220.o
6 6
7obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o 7obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o
8obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o 8obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o
9obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o 9obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o
10obj-$(CONFIG_COMMON_CLK_HI6220) += clk-hi6220.o
diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c
index 472dd2cb10b3..715d34a5ef9b 100644
--- a/drivers/clk/hisilicon/clk-hi3620.c
+++ b/drivers/clk/hisilicon/clk-hi3620.c
@@ -38,44 +38,44 @@
38#include "clk.h" 38#include "clk.h"
39 39
40/* clock parent list */ 40/* clock parent list */
41static const char *timer0_mux_p[] __initdata = { "osc32k", "timerclk01", }; 41static const char *const timer0_mux_p[] __initconst = { "osc32k", "timerclk01", };
42static const char *timer1_mux_p[] __initdata = { "osc32k", "timerclk01", }; 42static const char *const timer1_mux_p[] __initconst = { "osc32k", "timerclk01", };
43static const char *timer2_mux_p[] __initdata = { "osc32k", "timerclk23", }; 43static const char *const timer2_mux_p[] __initconst = { "osc32k", "timerclk23", };
44static const char *timer3_mux_p[] __initdata = { "osc32k", "timerclk23", }; 44static const char *const timer3_mux_p[] __initconst = { "osc32k", "timerclk23", };
45static const char *timer4_mux_p[] __initdata = { "osc32k", "timerclk45", }; 45static const char *const timer4_mux_p[] __initconst = { "osc32k", "timerclk45", };
46static const char *timer5_mux_p[] __initdata = { "osc32k", "timerclk45", }; 46static const char *const timer5_mux_p[] __initconst = { "osc32k", "timerclk45", };
47static const char *timer6_mux_p[] __initdata = { "osc32k", "timerclk67", }; 47static const char *const timer6_mux_p[] __initconst = { "osc32k", "timerclk67", };
48static const char *timer7_mux_p[] __initdata = { "osc32k", "timerclk67", }; 48static const char *const timer7_mux_p[] __initconst = { "osc32k", "timerclk67", };
49static const char *timer8_mux_p[] __initdata = { "osc32k", "timerclk89", }; 49static const char *const timer8_mux_p[] __initconst = { "osc32k", "timerclk89", };
50static const char *timer9_mux_p[] __initdata = { "osc32k", "timerclk89", }; 50static const char *const timer9_mux_p[] __initconst = { "osc32k", "timerclk89", };
51static const char *uart0_mux_p[] __initdata = { "osc26m", "pclk", }; 51static const char *const uart0_mux_p[] __initconst = { "osc26m", "pclk", };
52static const char *uart1_mux_p[] __initdata = { "osc26m", "pclk", }; 52static const char *const uart1_mux_p[] __initconst = { "osc26m", "pclk", };
53static const char *uart2_mux_p[] __initdata = { "osc26m", "pclk", }; 53static const char *const uart2_mux_p[] __initconst = { "osc26m", "pclk", };
54static const char *uart3_mux_p[] __initdata = { "osc26m", "pclk", }; 54static const char *const uart3_mux_p[] __initconst = { "osc26m", "pclk", };
55static const char *uart4_mux_p[] __initdata = { "osc26m", "pclk", }; 55static const char *const uart4_mux_p[] __initconst = { "osc26m", "pclk", };
56static const char *spi0_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; 56static const char *const spi0_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", };
57static const char *spi1_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; 57static const char *const spi1_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", };
58static const char *spi2_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; 58static const char *const spi2_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", };
59/* share axi parent */ 59/* share axi parent */
60static const char *saxi_mux_p[] __initdata = { "armpll3", "armpll2", }; 60static const char *const saxi_mux_p[] __initconst = { "armpll3", "armpll2", };
61static const char *pwm0_mux_p[] __initdata = { "osc32k", "osc26m", }; 61static const char *const pwm0_mux_p[] __initconst = { "osc32k", "osc26m", };
62static const char *pwm1_mux_p[] __initdata = { "osc32k", "osc26m", }; 62static const char *const pwm1_mux_p[] __initconst = { "osc32k", "osc26m", };
63static const char *sd_mux_p[] __initdata = { "armpll2", "armpll3", }; 63static const char *const sd_mux_p[] __initconst = { "armpll2", "armpll3", };
64static const char *mmc1_mux_p[] __initdata = { "armpll2", "armpll3", }; 64static const char *const mmc1_mux_p[] __initconst = { "armpll2", "armpll3", };
65static const char *mmc1_mux2_p[] __initdata = { "osc26m", "mmc1_div", }; 65static const char *const mmc1_mux2_p[] __initconst = { "osc26m", "mmc1_div", };
66static const char *g2d_mux_p[] __initdata = { "armpll2", "armpll3", }; 66static const char *const g2d_mux_p[] __initconst = { "armpll2", "armpll3", };
67static const char *venc_mux_p[] __initdata = { "armpll2", "armpll3", }; 67static const char *const venc_mux_p[] __initconst = { "armpll2", "armpll3", };
68static const char *vdec_mux_p[] __initdata = { "armpll2", "armpll3", }; 68static const char *const vdec_mux_p[] __initconst = { "armpll2", "armpll3", };
69static const char *vpp_mux_p[] __initdata = { "armpll2", "armpll3", }; 69static const char *const vpp_mux_p[] __initconst = { "armpll2", "armpll3", };
70static const char *edc0_mux_p[] __initdata = { "armpll2", "armpll3", }; 70static const char *const edc0_mux_p[] __initconst = { "armpll2", "armpll3", };
71static const char *ldi0_mux_p[] __initdata = { "armpll2", "armpll4", 71static const char *const ldi0_mux_p[] __initconst = { "armpll2", "armpll4",
72 "armpll3", "armpll5", }; 72 "armpll3", "armpll5", };
73static const char *edc1_mux_p[] __initdata = { "armpll2", "armpll3", }; 73static const char *const edc1_mux_p[] __initconst = { "armpll2", "armpll3", };
74static const char *ldi1_mux_p[] __initdata = { "armpll2", "armpll4", 74static const char *const ldi1_mux_p[] __initconst = { "armpll2", "armpll4",
75 "armpll3", "armpll5", }; 75 "armpll3", "armpll5", };
76static const char *rclk_hsic_p[] __initdata = { "armpll3", "armpll2", }; 76static const char *const rclk_hsic_p[] __initconst = { "armpll3", "armpll2", };
77static const char *mmc2_mux_p[] __initdata = { "armpll2", "armpll3", }; 77static const char *const mmc2_mux_p[] __initconst = { "armpll2", "armpll3", };
78static const char *mmc3_mux_p[] __initdata = { "armpll2", "armpll3", }; 78static const char *const mmc3_mux_p[] __initconst = { "armpll2", "armpll3", };
79 79
80 80
81/* fixed rate clocks */ 81/* fixed rate clocks */
diff --git a/drivers/clk/hisilicon/clk-hi6220.c b/drivers/clk/hisilicon/clk-hi6220.c
new file mode 100644
index 000000000000..4563343b6420
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi6220.c
@@ -0,0 +1,284 @@
1/*
2 * Hisilicon Hi6220 clock driver
3 *
4 * Copyright (c) 2015 Hisilicon Limited.
5 *
6 * Author: Bintian Wang <bintian.wang@huawei.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 version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/clk-provider.h>
15#include <linux/clkdev.h>
16#include <linux/io.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <linux/of_device.h>
20#include <linux/slab.h>
21
22#include <dt-bindings/clock/hi6220-clock.h>
23
24#include "clk.h"
25
26
27/* clocks in AO (always on) controller */
28static struct hisi_fixed_rate_clock hi6220_fixed_rate_clks[] __initdata = {
29 { HI6220_REF32K, "ref32k", NULL, CLK_IS_ROOT, 32764, },
30 { HI6220_CLK_TCXO, "clk_tcxo", NULL, CLK_IS_ROOT, 19200000, },
31 { HI6220_MMC1_PAD, "mmc1_pad", NULL, CLK_IS_ROOT, 100000000, },
32 { HI6220_MMC2_PAD, "mmc2_pad", NULL, CLK_IS_ROOT, 100000000, },
33 { HI6220_MMC0_PAD, "mmc0_pad", NULL, CLK_IS_ROOT, 200000000, },
34 { HI6220_PLL_BBP, "bbppll0", NULL, CLK_IS_ROOT, 245760000, },
35 { HI6220_PLL_GPU, "gpupll", NULL, CLK_IS_ROOT, 1000000000,},
36 { HI6220_PLL1_DDR, "ddrpll1", NULL, CLK_IS_ROOT, 1066000000,},
37 { HI6220_PLL_SYS, "syspll", NULL, CLK_IS_ROOT, 1200000000,},
38 { HI6220_PLL_SYS_MEDIA, "media_syspll", NULL, CLK_IS_ROOT, 1200000000,},
39 { HI6220_DDR_SRC, "ddr_sel_src", NULL, CLK_IS_ROOT, 1200000000,},
40 { HI6220_PLL_MEDIA, "media_pll", NULL, CLK_IS_ROOT, 1440000000,},
41 { HI6220_PLL_DDR, "ddrpll0", NULL, CLK_IS_ROOT, 1600000000,},
42};
43
44static struct hisi_fixed_factor_clock hi6220_fixed_factor_clks[] __initdata = {
45 { HI6220_300M, "clk_300m", "syspll", 1, 4, 0, },
46 { HI6220_150M, "clk_150m", "clk_300m", 1, 2, 0, },
47 { HI6220_PICOPHY_SRC, "picophy_src", "clk_150m", 1, 4, 0, },
48 { HI6220_MMC0_SRC_SEL, "mmc0srcsel", "mmc0_sel", 1, 8, 0, },
49 { HI6220_MMC1_SRC_SEL, "mmc1srcsel", "mmc1_sel", 1, 8, 0, },
50 { HI6220_MMC2_SRC_SEL, "mmc2srcsel", "mmc2_sel", 1, 8, 0, },
51 { HI6220_VPU_CODEC, "vpucodec", "codec_jpeg_aclk", 1, 2, 0, },
52 { HI6220_MMC0_SMP, "mmc0_sample", "mmc0_sel", 1, 8, 0, },
53 { HI6220_MMC1_SMP, "mmc1_sample", "mmc1_sel", 1, 8, 0, },
54 { HI6220_MMC2_SMP, "mmc2_sample", "mmc2_sel", 1, 8, 0, },
55};
56
57static struct hisi_gate_clock hi6220_separated_gate_clks_ao[] __initdata = {
58 { HI6220_WDT0_PCLK, "wdt0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 12, 0, },
59 { HI6220_WDT1_PCLK, "wdt1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 13, 0, },
60 { HI6220_WDT2_PCLK, "wdt2_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 14, 0, },
61 { HI6220_TIMER0_PCLK, "timer0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 15, 0, },
62 { HI6220_TIMER1_PCLK, "timer1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 16, 0, },
63 { HI6220_TIMER2_PCLK, "timer2_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 17, 0, },
64 { HI6220_TIMER3_PCLK, "timer3_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 18, 0, },
65 { HI6220_TIMER4_PCLK, "timer4_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 19, 0, },
66 { HI6220_TIMER5_PCLK, "timer5_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 20, 0, },
67 { HI6220_TIMER6_PCLK, "timer6_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 21, 0, },
68 { HI6220_TIMER7_PCLK, "timer7_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 22, 0, },
69 { HI6220_TIMER8_PCLK, "timer8_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 23, 0, },
70 { HI6220_UART0_PCLK, "uart0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 24, 0, },
71};
72
73static void __init hi6220_clk_ao_init(struct device_node *np)
74{
75 struct hisi_clock_data *clk_data_ao;
76
77 clk_data_ao = hisi_clk_init(np, HI6220_AO_NR_CLKS);
78 if (!clk_data_ao)
79 return;
80
81 hisi_clk_register_fixed_rate(hi6220_fixed_rate_clks,
82 ARRAY_SIZE(hi6220_fixed_rate_clks), clk_data_ao);
83
84 hisi_clk_register_fixed_factor(hi6220_fixed_factor_clks,
85 ARRAY_SIZE(hi6220_fixed_factor_clks), clk_data_ao);
86
87 hisi_clk_register_gate_sep(hi6220_separated_gate_clks_ao,
88 ARRAY_SIZE(hi6220_separated_gate_clks_ao), clk_data_ao);
89}
90CLK_OF_DECLARE(hi6220_clk_ao, "hisilicon,hi6220-aoctrl", hi6220_clk_ao_init);
91
92
93/* clocks in sysctrl */
94static const char *mmc0_mux0_p[] __initdata = { "pll_ddr_gate", "syspll", };
95static const char *mmc0_mux1_p[] __initdata = { "mmc0_mux0", "pll_media_gate", };
96static const char *mmc0_src_p[] __initdata = { "mmc0srcsel", "mmc0_div", };
97static const char *mmc1_mux0_p[] __initdata = { "pll_ddr_gate", "syspll", };
98static const char *mmc1_mux1_p[] __initdata = { "mmc1_mux0", "pll_media_gate", };
99static const char *mmc1_src_p[] __initdata = { "mmc1srcsel", "mmc1_div", };
100static const char *mmc2_mux0_p[] __initdata = { "pll_ddr_gate", "syspll", };
101static const char *mmc2_mux1_p[] __initdata = { "mmc2_mux0", "pll_media_gate", };
102static const char *mmc2_src_p[] __initdata = { "mmc2srcsel", "mmc2_div", };
103static const char *mmc0_sample_in[] __initdata = { "mmc0_sample", "mmc0_pad", };
104static const char *mmc1_sample_in[] __initdata = { "mmc1_sample", "mmc1_pad", };
105static const char *mmc2_sample_in[] __initdata = { "mmc2_sample", "mmc2_pad", };
106static const char *uart1_src[] __initdata = { "clk_tcxo", "clk_150m", };
107static const char *uart2_src[] __initdata = { "clk_tcxo", "clk_150m", };
108static const char *uart3_src[] __initdata = { "clk_tcxo", "clk_150m", };
109static const char *uart4_src[] __initdata = { "clk_tcxo", "clk_150m", };
110static const char *hifi_src[] __initdata = { "syspll", "pll_media_gate", };
111
112static struct hisi_gate_clock hi6220_separated_gate_clks_sys[] __initdata = {
113 { HI6220_MMC0_CLK, "mmc0_clk", "mmc0_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 0, 0, },
114 { HI6220_MMC0_CIUCLK, "mmc0_ciuclk", "mmc0_smp_in", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 0, 0, },
115 { HI6220_MMC1_CLK, "mmc1_clk", "mmc1_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 1, 0, },
116 { HI6220_MMC1_CIUCLK, "mmc1_ciuclk", "mmc1_smp_in", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 1, 0, },
117 { HI6220_MMC2_CLK, "mmc2_clk", "mmc2_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 2, 0, },
118 { HI6220_MMC2_CIUCLK, "mmc2_ciuclk", "mmc2_smp_in", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 2, 0, },
119 { HI6220_USBOTG_HCLK, "usbotg_hclk", "clk_bus", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 4, 0, },
120 { HI6220_CLK_PICOPHY, "clk_picophy", "cs_dapb", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 5, 0, },
121 { HI6220_HIFI, "hifi_clk", "hifi_div", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x210, 0, 0, },
122 { HI6220_DACODEC_PCLK, "dacodec_pclk", "clk_bus", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x210, 5, 0, },
123 { HI6220_EDMAC_ACLK, "edmac_aclk", "clk_bus", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x220, 2, 0, },
124 { HI6220_CS_ATB, "cs_atb", "cs_atb_div", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x230, 0, 0, },
125 { HI6220_I2C0_CLK, "i2c0_clk", "clk_150m", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x230, 1, 0, },
126 { HI6220_I2C1_CLK, "i2c1_clk", "clk_150m", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x230, 2, 0, },
127 { HI6220_I2C2_CLK, "i2c2_clk", "clk_150m", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x230, 3, 0, },
128 { HI6220_I2C3_CLK, "i2c3_clk", "clk_150m", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x230, 4, 0, },
129 { HI6220_UART1_PCLK, "uart1_pclk", "uart1_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x230, 5, 0, },
130 { HI6220_UART2_PCLK, "uart2_pclk", "uart2_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x230, 6, 0, },
131 { HI6220_UART3_PCLK, "uart3_pclk", "uart3_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x230, 7, 0, },
132 { HI6220_UART4_PCLK, "uart4_pclk", "uart4_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x230, 8, 0, },
133 { HI6220_SPI_CLK, "spi_clk", "clk_150m", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x230, 9, 0, },
134 { HI6220_TSENSOR_CLK, "tsensor_clk", "clk_bus", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x230, 12, 0, },
135 { HI6220_MMU_CLK, "mmu_clk", "ddrc_axi1", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x240, 11, 0, },
136 { HI6220_HIFI_SEL, "hifi_sel", "hifi_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 0, 0, },
137 { HI6220_MMC0_SYSPLL, "mmc0_syspll", "syspll", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 1, 0, },
138 { HI6220_MMC1_SYSPLL, "mmc1_syspll", "syspll", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 2, 0, },
139 { HI6220_MMC2_SYSPLL, "mmc2_syspll", "syspll", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 3, 0, },
140 { HI6220_MMC0_SEL, "mmc0_sel", "mmc0_mux1", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 6, 0, },
141 { HI6220_MMC1_SEL, "mmc1_sel", "mmc1_mux1", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 7, 0, },
142 { HI6220_BBPPLL_SEL, "bbppll_sel", "pll0_bbp_gate", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 9, 0, },
143 { HI6220_MEDIA_PLL_SRC, "media_pll_src", "pll_media_gate", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 10, 0, },
144 { HI6220_MMC2_SEL, "mmc2_sel", "mmc2_mux1", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 11, 0, },
145 { HI6220_CS_ATB_SYSPLL, "cs_atb_syspll", "syspll", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 12, 0, },
146};
147
148static struct hisi_mux_clock hi6220_mux_clks_sys[] __initdata = {
149 { HI6220_MMC0_SRC, "mmc0_src", mmc0_src_p, ARRAY_SIZE(mmc0_src_p), CLK_SET_RATE_PARENT, 0x4, 0, 1, 0, },
150 { HI6220_MMC0_SMP_IN, "mmc0_smp_in", mmc0_sample_in, ARRAY_SIZE(mmc0_sample_in), CLK_SET_RATE_PARENT, 0x4, 0, 1, 0, },
151 { HI6220_MMC1_SRC, "mmc1_src", mmc1_src_p, ARRAY_SIZE(mmc1_src_p), CLK_SET_RATE_PARENT, 0x4, 2, 1, 0, },
152 { HI6220_MMC1_SMP_IN, "mmc1_smp_in", mmc1_sample_in, ARRAY_SIZE(mmc1_sample_in), CLK_SET_RATE_PARENT, 0x4, 2, 1, 0, },
153 { HI6220_MMC2_SRC, "mmc2_src", mmc2_src_p, ARRAY_SIZE(mmc2_src_p), CLK_SET_RATE_PARENT, 0x4, 4, 1, 0, },
154 { HI6220_MMC2_SMP_IN, "mmc2_smp_in", mmc2_sample_in, ARRAY_SIZE(mmc2_sample_in), CLK_SET_RATE_PARENT, 0x4, 4, 1, 0, },
155 { HI6220_HIFI_SRC, "hifi_src", hifi_src, ARRAY_SIZE(hifi_src), CLK_SET_RATE_PARENT, 0x400, 0, 1, CLK_MUX_HIWORD_MASK,},
156 { HI6220_UART1_SRC, "uart1_src", uart1_src, ARRAY_SIZE(uart1_src), CLK_SET_RATE_PARENT, 0x400, 1, 1, CLK_MUX_HIWORD_MASK,},
157 { HI6220_UART2_SRC, "uart2_src", uart2_src, ARRAY_SIZE(uart2_src), CLK_SET_RATE_PARENT, 0x400, 2, 1, CLK_MUX_HIWORD_MASK,},
158 { HI6220_UART3_SRC, "uart3_src", uart3_src, ARRAY_SIZE(uart3_src), CLK_SET_RATE_PARENT, 0x400, 3, 1, CLK_MUX_HIWORD_MASK,},
159 { HI6220_UART4_SRC, "uart4_src", uart4_src, ARRAY_SIZE(uart4_src), CLK_SET_RATE_PARENT, 0x400, 4, 1, CLK_MUX_HIWORD_MASK,},
160 { HI6220_MMC0_MUX0, "mmc0_mux0", mmc0_mux0_p, ARRAY_SIZE(mmc0_mux0_p), CLK_SET_RATE_PARENT, 0x400, 5, 1, CLK_MUX_HIWORD_MASK,},
161 { HI6220_MMC1_MUX0, "mmc1_mux0", mmc1_mux0_p, ARRAY_SIZE(mmc1_mux0_p), CLK_SET_RATE_PARENT, 0x400, 11, 1, CLK_MUX_HIWORD_MASK,},
162 { HI6220_MMC2_MUX0, "mmc2_mux0", mmc2_mux0_p, ARRAY_SIZE(mmc2_mux0_p), CLK_SET_RATE_PARENT, 0x400, 12, 1, CLK_MUX_HIWORD_MASK,},
163 { HI6220_MMC0_MUX1, "mmc0_mux1", mmc0_mux1_p, ARRAY_SIZE(mmc0_mux1_p), CLK_SET_RATE_PARENT, 0x400, 13, 1, CLK_MUX_HIWORD_MASK,},
164 { HI6220_MMC1_MUX1, "mmc1_mux1", mmc1_mux1_p, ARRAY_SIZE(mmc1_mux1_p), CLK_SET_RATE_PARENT, 0x400, 14, 1, CLK_MUX_HIWORD_MASK,},
165 { HI6220_MMC2_MUX1, "mmc2_mux1", mmc2_mux1_p, ARRAY_SIZE(mmc2_mux1_p), CLK_SET_RATE_PARENT, 0x400, 15, 1, CLK_MUX_HIWORD_MASK,},
166};
167
168static struct hi6220_divider_clock hi6220_div_clks_sys[] __initdata = {
169 { HI6220_CLK_BUS, "clk_bus", "clk_300m", CLK_SET_RATE_PARENT, 0x490, 0, 4, 7, },
170 { HI6220_MMC0_DIV, "mmc0_div", "mmc0_syspll", CLK_SET_RATE_PARENT, 0x494, 0, 6, 7, },
171 { HI6220_MMC1_DIV, "mmc1_div", "mmc1_syspll", CLK_SET_RATE_PARENT, 0x498, 0, 6, 7, },
172 { HI6220_MMC2_DIV, "mmc2_div", "mmc2_syspll", CLK_SET_RATE_PARENT, 0x49c, 0, 6, 7, },
173 { HI6220_HIFI_DIV, "hifi_div", "hifi_sel", CLK_SET_RATE_PARENT, 0x4a0, 0, 4, 7, },
174 { HI6220_BBPPLL0_DIV, "bbppll0_div", "bbppll_sel", CLK_SET_RATE_PARENT, 0x4a0, 8, 6, 15,},
175 { HI6220_CS_DAPB, "cs_dapb", "picophy_src", CLK_SET_RATE_PARENT, 0x4a0, 24, 2, 31,},
176 { HI6220_CS_ATB_DIV, "cs_atb_div", "cs_atb_syspll", CLK_SET_RATE_PARENT, 0x4a4, 0, 4, 7, },
177};
178
179static void __init hi6220_clk_sys_init(struct device_node *np)
180{
181 struct hisi_clock_data *clk_data;
182
183 clk_data = hisi_clk_init(np, HI6220_SYS_NR_CLKS);
184 if (!clk_data)
185 return;
186
187 hisi_clk_register_gate_sep(hi6220_separated_gate_clks_sys,
188 ARRAY_SIZE(hi6220_separated_gate_clks_sys), clk_data);
189
190 hisi_clk_register_mux(hi6220_mux_clks_sys,
191 ARRAY_SIZE(hi6220_mux_clks_sys), clk_data);
192
193 hi6220_clk_register_divider(hi6220_div_clks_sys,
194 ARRAY_SIZE(hi6220_div_clks_sys), clk_data);
195}
196CLK_OF_DECLARE(hi6220_clk_sys, "hisilicon,hi6220-sysctrl", hi6220_clk_sys_init);
197
198
199/* clocks in media controller */
200static const char *clk_1000_1200_src[] __initdata = { "pll_gpu_gate", "media_syspll_src", };
201static const char *clk_1440_1200_src[] __initdata = { "media_syspll_src", "media_pll_src", };
202static const char *clk_1000_1440_src[] __initdata = { "pll_gpu_gate", "media_pll_src", };
203
204static struct hisi_gate_clock hi6220_separated_gate_clks_media[] __initdata = {
205 { HI6220_DSI_PCLK, "dsi_pclk", "vpucodec", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 0, 0, },
206 { HI6220_G3D_PCLK, "g3d_pclk", "vpucodec", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 1, 0, },
207 { HI6220_ACLK_CODEC_VPU, "aclk_codec_vpu", "ade_core_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 3, 0, },
208 { HI6220_ISP_SCLK, "isp_sclk", "isp_sclk_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 5, 0, },
209 { HI6220_ADE_CORE, "ade_core", "ade_core_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 6, 0, },
210 { HI6220_MED_MMU, "media_mmu", "mmu_clk", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 8, 0, },
211 { HI6220_CFG_CSI4PHY, "cfg_csi4phy", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 9, 0, },
212 { HI6220_CFG_CSI2PHY, "cfg_csi2phy", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 10, 0, },
213 { HI6220_ISP_SCLK_GATE, "isp_sclk_gate", "media_pll_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 11, 0, },
214 { HI6220_ISP_SCLK_GATE1, "isp_sclk_gate1", "media_pll_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 12, 0, },
215 { HI6220_ADE_CORE_GATE, "ade_core_gate", "media_pll_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 14, 0, },
216 { HI6220_CODEC_VPU_GATE, "codec_vpu_gate", "clk_1000_1440", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 15, 0, },
217 { HI6220_MED_SYSPLL, "media_syspll_src", "media_syspll", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 17, 0, },
218};
219
220static struct hisi_mux_clock hi6220_mux_clks_media[] __initdata = {
221 { HI6220_1440_1200, "clk_1440_1200", clk_1440_1200_src, ARRAY_SIZE(clk_1440_1200_src), CLK_SET_RATE_PARENT, 0x51c, 0, 1, 0, },
222 { HI6220_1000_1200, "clk_1000_1200", clk_1000_1200_src, ARRAY_SIZE(clk_1000_1200_src), CLK_SET_RATE_PARENT, 0x51c, 1, 1, 0, },
223 { HI6220_1000_1440, "clk_1000_1440", clk_1000_1440_src, ARRAY_SIZE(clk_1000_1440_src), CLK_SET_RATE_PARENT, 0x51c, 6, 1, 0, },
224};
225
226static struct hi6220_divider_clock hi6220_div_clks_media[] __initdata = {
227 { HI6220_CODEC_JPEG, "codec_jpeg_aclk", "media_pll_src", CLK_SET_RATE_PARENT, 0xcbc, 0, 4, 23, },
228 { HI6220_ISP_SCLK_SRC, "isp_sclk_src", "isp_sclk_gate", CLK_SET_RATE_PARENT, 0xcbc, 8, 4, 15, },
229 { HI6220_ISP_SCLK1, "isp_sclk1", "isp_sclk_gate1", CLK_SET_RATE_PARENT, 0xcbc, 24, 4, 31, },
230 { HI6220_ADE_CORE_SRC, "ade_core_src", "ade_core_gate", CLK_SET_RATE_PARENT, 0xcc0, 16, 3, 23, },
231 { HI6220_ADE_PIX_SRC, "ade_pix_src", "clk_1440_1200", CLK_SET_RATE_PARENT, 0xcc0, 24, 6, 31, },
232 { HI6220_G3D_CLK, "g3d_clk", "clk_1000_1200", CLK_SET_RATE_PARENT, 0xcc4, 8, 4, 15, },
233 { HI6220_CODEC_VPU_SRC, "codec_vpu_src", "codec_vpu_gate", CLK_SET_RATE_PARENT, 0xcc4, 24, 6, 31, },
234};
235
236static void __init hi6220_clk_media_init(struct device_node *np)
237{
238 struct hisi_clock_data *clk_data;
239
240 clk_data = hisi_clk_init(np, HI6220_MEDIA_NR_CLKS);
241 if (!clk_data)
242 return;
243
244 hisi_clk_register_gate_sep(hi6220_separated_gate_clks_media,
245 ARRAY_SIZE(hi6220_separated_gate_clks_media), clk_data);
246
247 hisi_clk_register_mux(hi6220_mux_clks_media,
248 ARRAY_SIZE(hi6220_mux_clks_media), clk_data);
249
250 hi6220_clk_register_divider(hi6220_div_clks_media,
251 ARRAY_SIZE(hi6220_div_clks_media), clk_data);
252}
253CLK_OF_DECLARE(hi6220_clk_media, "hisilicon,hi6220-mediactrl", hi6220_clk_media_init);
254
255
256/* clocks in pmctrl */
257static struct hisi_gate_clock hi6220_gate_clks_power[] __initdata = {
258 { HI6220_PLL_GPU_GATE, "pll_gpu_gate", "gpupll", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x8, 0, 0, },
259 { HI6220_PLL1_DDR_GATE, "pll1_ddr_gate", "ddrpll1", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x10, 0, 0, },
260 { HI6220_PLL_DDR_GATE, "pll_ddr_gate", "ddrpll0", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x18, 0, 0, },
261 { HI6220_PLL_MEDIA_GATE, "pll_media_gate", "media_pll", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x38, 0, 0, },
262 { HI6220_PLL0_BBP_GATE, "pll0_bbp_gate", "bbppll0", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x48, 0, 0, },
263};
264
265static struct hi6220_divider_clock hi6220_div_clks_power[] __initdata = {
266 { HI6220_DDRC_SRC, "ddrc_src", "ddr_sel_src", CLK_SET_RATE_PARENT, 0x5a8, 0, 4, 0, },
267 { HI6220_DDRC_AXI1, "ddrc_axi1", "ddrc_src", CLK_SET_RATE_PARENT, 0x5a8, 8, 2, 0, },
268};
269
270static void __init hi6220_clk_power_init(struct device_node *np)
271{
272 struct hisi_clock_data *clk_data;
273
274 clk_data = hisi_clk_init(np, HI6220_POWER_NR_CLKS);
275 if (!clk_data)
276 return;
277
278 hisi_clk_register_gate(hi6220_gate_clks_power,
279 ARRAY_SIZE(hi6220_gate_clks_power), clk_data);
280
281 hi6220_clk_register_divider(hi6220_div_clks_power,
282 ARRAY_SIZE(hi6220_div_clks_power), clk_data);
283}
284CLK_OF_DECLARE(hi6220_clk_power, "hisilicon,hi6220-pmctrl", hi6220_clk_power_init);
diff --git a/drivers/clk/hisilicon/clk-hix5hd2.c b/drivers/clk/hisilicon/clk-hix5hd2.c
index f1d239435826..0aaf29da8491 100644
--- a/drivers/clk/hisilicon/clk-hix5hd2.c
+++ b/drivers/clk/hisilicon/clk-hix5hd2.c
@@ -46,15 +46,15 @@ static struct hisi_fixed_rate_clock hix5hd2_fixed_rate_clks[] __initdata = {
46 { HIX5HD2_FIXED_83M, "83m", NULL, CLK_IS_ROOT, 83333333, }, 46 { HIX5HD2_FIXED_83M, "83m", NULL, CLK_IS_ROOT, 83333333, },
47}; 47};
48 48
49static const char *sfc_mux_p[] __initdata = { 49static const char *const sfc_mux_p[] __initconst = {
50 "24m", "150m", "200m", "100m", "75m", }; 50 "24m", "150m", "200m", "100m", "75m", };
51static u32 sfc_mux_table[] = {0, 4, 5, 6, 7}; 51static u32 sfc_mux_table[] = {0, 4, 5, 6, 7};
52 52
53static const char *sdio_mux_p[] __initdata = { 53static const char *const sdio_mux_p[] __initconst = {
54 "75m", "100m", "50m", "15m", }; 54 "75m", "100m", "50m", "15m", };
55static u32 sdio_mux_table[] = {0, 1, 2, 3}; 55static u32 sdio_mux_table[] = {0, 1, 2, 3};
56 56
57static const char *fephy_mux_p[] __initdata = { "25m", "125m"}; 57static const char *const fephy_mux_p[] __initconst = { "25m", "125m"};
58static u32 fephy_mux_table[] = {0, 1}; 58static u32 fephy_mux_table[] = {0, 1};
59 59
60 60
@@ -252,8 +252,9 @@ static struct clk_ops clk_complex_ops = {
252 .disable = clk_complex_disable, 252 .disable = clk_complex_disable,
253}; 253};
254 254
255void __init hix5hd2_clk_register_complex(struct hix5hd2_complex_clock *clks, 255static void __init
256 int nums, struct hisi_clock_data *data) 256hix5hd2_clk_register_complex(struct hix5hd2_complex_clock *clks, int nums,
257 struct hisi_clock_data *data)
257{ 258{
258 void __iomem *base = data->base; 259 void __iomem *base = data->base;
259 int i; 260 int i;
diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index a078e84f7b05..c90a89739b03 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -232,3 +232,32 @@ void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks,
232 data->clk_data.clks[clks[i].id] = clk; 232 data->clk_data.clks[clks[i].id] = clk;
233 } 233 }
234} 234}
235
236void __init hi6220_clk_register_divider(struct hi6220_divider_clock *clks,
237 int nums, struct hisi_clock_data *data)
238{
239 struct clk *clk;
240 void __iomem *base = data->base;
241 int i;
242
243 for (i = 0; i < nums; i++) {
244 clk = hi6220_register_clkdiv(NULL, clks[i].name,
245 clks[i].parent_name,
246 clks[i].flags,
247 base + clks[i].offset,
248 clks[i].shift,
249 clks[i].width,
250 clks[i].mask_bit,
251 &hisi_clk_lock);
252 if (IS_ERR(clk)) {
253 pr_err("%s: failed to register clock %s\n",
254 __func__, clks[i].name);
255 continue;
256 }
257
258 if (clks[i].alias)
259 clk_register_clkdev(clk, clks[i].alias, NULL);
260
261 data->clk_data.clks[clks[i].id] = clk;
262 }
263}
diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h
index 31083ffc0650..b56fbc1c5f27 100644
--- a/drivers/clk/hisilicon/clk.h
+++ b/drivers/clk/hisilicon/clk.h
@@ -55,7 +55,7 @@ struct hisi_fixed_factor_clock {
55struct hisi_mux_clock { 55struct hisi_mux_clock {
56 unsigned int id; 56 unsigned int id;
57 const char *name; 57 const char *name;
58 const char **parent_names; 58 const char *const *parent_names;
59 u8 num_parents; 59 u8 num_parents;
60 unsigned long flags; 60 unsigned long flags;
61 unsigned long offset; 61 unsigned long offset;
@@ -79,6 +79,18 @@ struct hisi_divider_clock {
79 const char *alias; 79 const char *alias;
80}; 80};
81 81
82struct hi6220_divider_clock {
83 unsigned int id;
84 const char *name;
85 const char *parent_name;
86 unsigned long flags;
87 unsigned long offset;
88 u8 shift;
89 u8 width;
90 u32 mask_bit;
91 const char *alias;
92};
93
82struct hisi_gate_clock { 94struct hisi_gate_clock {
83 unsigned int id; 95 unsigned int id;
84 const char *name; 96 const char *name;
@@ -94,18 +106,23 @@ struct clk *hisi_register_clkgate_sep(struct device *, const char *,
94 const char *, unsigned long, 106 const char *, unsigned long,
95 void __iomem *, u8, 107 void __iomem *, u8,
96 u8, spinlock_t *); 108 u8, spinlock_t *);
109struct clk *hi6220_register_clkdiv(struct device *dev, const char *name,
110 const char *parent_name, unsigned long flags, void __iomem *reg,
111 u8 shift, u8 width, u32 mask_bit, spinlock_t *lock);
97 112
98struct hisi_clock_data __init *hisi_clk_init(struct device_node *, int); 113struct hisi_clock_data *hisi_clk_init(struct device_node *, int);
99void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *, 114void hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *,
100 int, struct hisi_clock_data *); 115 int, struct hisi_clock_data *);
101void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *, 116void hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *,
102 int, struct hisi_clock_data *); 117 int, struct hisi_clock_data *);
103void __init hisi_clk_register_mux(struct hisi_mux_clock *, int, 118void hisi_clk_register_mux(struct hisi_mux_clock *, int,
104 struct hisi_clock_data *); 119 struct hisi_clock_data *);
105void __init hisi_clk_register_divider(struct hisi_divider_clock *, 120void hisi_clk_register_divider(struct hisi_divider_clock *,
121 int, struct hisi_clock_data *);
122void hisi_clk_register_gate(struct hisi_gate_clock *,
123 int, struct hisi_clock_data *);
124void hisi_clk_register_gate_sep(struct hisi_gate_clock *,
125 int, struct hisi_clock_data *);
126void hi6220_clk_register_divider(struct hi6220_divider_clock *,
106 int, struct hisi_clock_data *); 127 int, struct hisi_clock_data *);
107void __init hisi_clk_register_gate(struct hisi_gate_clock *,
108 int, struct hisi_clock_data *);
109void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *,
110 int, struct hisi_clock_data *);
111#endif /* __HISI_CLK_H */ 128#endif /* __HISI_CLK_H */
diff --git a/drivers/clk/hisilicon/clkdivider-hi6220.c b/drivers/clk/hisilicon/clkdivider-hi6220.c
new file mode 100644
index 000000000000..113eee8ed23a
--- /dev/null
+++ b/drivers/clk/hisilicon/clkdivider-hi6220.c
@@ -0,0 +1,156 @@
1/*
2 * Hisilicon hi6220 SoC divider clock driver
3 *
4 * Copyright (c) 2015 Hisilicon Limited.
5 *
6 * Author: Bintian Wang <bintian.wang@huawei.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 version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/clk-provider.h>
16#include <linux/slab.h>
17#include <linux/io.h>
18#include <linux/err.h>
19#include <linux/spinlock.h>
20
21#define div_mask(width) ((1 << (width)) - 1)
22
23/**
24 * struct hi6220_clk_divider - divider clock for hi6220
25 *
26 * @hw: handle between common and hardware-specific interfaces
27 * @reg: register containing divider
28 * @shift: shift to the divider bit field
29 * @width: width of the divider bit field
30 * @mask: mask for setting divider rate
31 * @table: the div table that the divider supports
32 * @lock: register lock
33 */
34struct hi6220_clk_divider {
35 struct clk_hw hw;
36 void __iomem *reg;
37 u8 shift;
38 u8 width;
39 u32 mask;
40 const struct clk_div_table *table;
41 spinlock_t *lock;
42};
43
44#define to_hi6220_clk_divider(_hw) \
45 container_of(_hw, struct hi6220_clk_divider, hw)
46
47static unsigned long hi6220_clkdiv_recalc_rate(struct clk_hw *hw,
48 unsigned long parent_rate)
49{
50 unsigned int val;
51 struct hi6220_clk_divider *dclk = to_hi6220_clk_divider(hw);
52
53 val = readl_relaxed(dclk->reg) >> dclk->shift;
54 val &= div_mask(dclk->width);
55
56 return divider_recalc_rate(hw, parent_rate, val, dclk->table,
57 CLK_DIVIDER_ROUND_CLOSEST);
58}
59
60static long hi6220_clkdiv_round_rate(struct clk_hw *hw, unsigned long rate,
61 unsigned long *prate)
62{
63 struct hi6220_clk_divider *dclk = to_hi6220_clk_divider(hw);
64
65 return divider_round_rate(hw, rate, prate, dclk->table,
66 dclk->width, CLK_DIVIDER_ROUND_CLOSEST);
67}
68
69static int hi6220_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate,
70 unsigned long parent_rate)
71{
72 int value;
73 unsigned long flags = 0;
74 u32 data;
75 struct hi6220_clk_divider *dclk = to_hi6220_clk_divider(hw);
76
77 value = divider_get_val(rate, parent_rate, dclk->table,
78 dclk->width, CLK_DIVIDER_ROUND_CLOSEST);
79
80 if (dclk->lock)
81 spin_lock_irqsave(dclk->lock, flags);
82
83 data = readl_relaxed(dclk->reg);
84 data &= ~(div_mask(dclk->width) << dclk->shift);
85 data |= value << dclk->shift;
86 data |= dclk->mask;
87
88 writel_relaxed(data, dclk->reg);
89
90 if (dclk->lock)
91 spin_unlock_irqrestore(dclk->lock, flags);
92
93 return 0;
94}
95
96static const struct clk_ops hi6220_clkdiv_ops = {
97 .recalc_rate = hi6220_clkdiv_recalc_rate,
98 .round_rate = hi6220_clkdiv_round_rate,
99 .set_rate = hi6220_clkdiv_set_rate,
100};
101
102struct clk *hi6220_register_clkdiv(struct device *dev, const char *name,
103 const char *parent_name, unsigned long flags, void __iomem *reg,
104 u8 shift, u8 width, u32 mask_bit, spinlock_t *lock)
105{
106 struct hi6220_clk_divider *div;
107 struct clk *clk;
108 struct clk_init_data init;
109 struct clk_div_table *table;
110 u32 max_div, min_div;
111 int i;
112
113 /* allocate the divider */
114 div = kzalloc(sizeof(*div), GFP_KERNEL);
115 if (!div)
116 return ERR_PTR(-ENOMEM);
117
118 /* Init the divider table */
119 max_div = div_mask(width) + 1;
120 min_div = 1;
121
122 table = kcalloc(max_div + 1, sizeof(*table), GFP_KERNEL);
123 if (!table) {
124 kfree(div);
125 return ERR_PTR(-ENOMEM);
126 }
127
128 for (i = 0; i < max_div; i++) {
129 table[i].div = min_div + i;
130 table[i].val = table[i].div - 1;
131 }
132
133 init.name = name;
134 init.ops = &hi6220_clkdiv_ops;
135 init.flags = flags;
136 init.parent_names = parent_name ? &parent_name : NULL;
137 init.num_parents = parent_name ? 1 : 0;
138
139 /* struct hi6220_clk_divider assignments */
140 div->reg = reg;
141 div->shift = shift;
142 div->width = width;
143 div->mask = mask_bit ? BIT(mask_bit) : 0;
144 div->lock = lock;
145 div->hw.init = &init;
146 div->table = table;
147
148 /* register the clock */
149 clk = clk_register(dev, &div->hw);
150 if (IS_ERR(clk)) {
151 kfree(table);
152 kfree(div);
153 }
154
155 return clk;
156}
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
new file mode 100644
index 000000000000..8e4b2a4635b9
--- /dev/null
+++ b/drivers/clk/mediatek/Makefile
@@ -0,0 +1,4 @@
1obj-y += clk-mtk.o clk-pll.o clk-gate.o
2obj-$(CONFIG_RESET_CONTROLLER) += reset.o
3obj-y += clk-mt8135.o
4obj-y += clk-mt8173.o
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
new file mode 100644
index 000000000000..57020368a693
--- /dev/null
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -0,0 +1,137 @@
1/*
2 * Copyright (c) 2014 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/of.h>
16#include <linux/of_address.h>
17
18#include <linux/io.h>
19#include <linux/slab.h>
20#include <linux/delay.h>
21#include <linux/clkdev.h>
22
23#include "clk-mtk.h"
24#include "clk-gate.h"
25
26static int mtk_cg_bit_is_cleared(struct clk_hw *hw)
27{
28 struct mtk_clk_gate *cg = to_clk_gate(hw);
29 u32 val;
30
31 regmap_read(cg->regmap, cg->sta_ofs, &val);
32
33 val &= BIT(cg->bit);
34
35 return val == 0;
36}
37
38static int mtk_cg_bit_is_set(struct clk_hw *hw)
39{
40 struct mtk_clk_gate *cg = to_clk_gate(hw);
41 u32 val;
42
43 regmap_read(cg->regmap, cg->sta_ofs, &val);
44
45 val &= BIT(cg->bit);
46
47 return val != 0;
48}
49
50static void mtk_cg_set_bit(struct clk_hw *hw)
51{
52 struct mtk_clk_gate *cg = to_clk_gate(hw);
53
54 regmap_write(cg->regmap, cg->set_ofs, BIT(cg->bit));
55}
56
57static void mtk_cg_clr_bit(struct clk_hw *hw)
58{
59 struct mtk_clk_gate *cg = to_clk_gate(hw);
60
61 regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit));
62}
63
64static int mtk_cg_enable(struct clk_hw *hw)
65{
66 mtk_cg_clr_bit(hw);
67
68 return 0;
69}
70
71static void mtk_cg_disable(struct clk_hw *hw)
72{
73 mtk_cg_set_bit(hw);
74}
75
76static int mtk_cg_enable_inv(struct clk_hw *hw)
77{
78 mtk_cg_set_bit(hw);
79
80 return 0;
81}
82
83static void mtk_cg_disable_inv(struct clk_hw *hw)
84{
85 mtk_cg_clr_bit(hw);
86}
87
88const struct clk_ops mtk_clk_gate_ops_setclr = {
89 .is_enabled = mtk_cg_bit_is_cleared,
90 .enable = mtk_cg_enable,
91 .disable = mtk_cg_disable,
92};
93
94const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
95 .is_enabled = mtk_cg_bit_is_set,
96 .enable = mtk_cg_enable_inv,
97 .disable = mtk_cg_disable_inv,
98};
99
100struct clk *mtk_clk_register_gate(
101 const char *name,
102 const char *parent_name,
103 struct regmap *regmap,
104 int set_ofs,
105 int clr_ofs,
106 int sta_ofs,
107 u8 bit,
108 const struct clk_ops *ops)
109{
110 struct mtk_clk_gate *cg;
111 struct clk *clk;
112 struct clk_init_data init = {};
113
114 cg = kzalloc(sizeof(*cg), GFP_KERNEL);
115 if (!cg)
116 return ERR_PTR(-ENOMEM);
117
118 init.name = name;
119 init.flags = CLK_SET_RATE_PARENT;
120 init.parent_names = parent_name ? &parent_name : NULL;
121 init.num_parents = parent_name ? 1 : 0;
122 init.ops = ops;
123
124 cg->regmap = regmap;
125 cg->set_ofs = set_ofs;
126 cg->clr_ofs = clr_ofs;
127 cg->sta_ofs = sta_ofs;
128 cg->bit = bit;
129
130 cg->hw.init = &init;
131
132 clk = clk_register(NULL, &cg->hw);
133 if (IS_ERR(clk))
134 kfree(cg);
135
136 return clk;
137}
diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h
new file mode 100644
index 000000000000..6b6780b1e9c5
--- /dev/null
+++ b/drivers/clk/mediatek/clk-gate.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (c) 2014 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#ifndef __DRV_CLK_GATE_H
16#define __DRV_CLK_GATE_H
17
18#include <linux/regmap.h>
19#include <linux/clk.h>
20#include <linux/clk-provider.h>
21
22struct mtk_clk_gate {
23 struct clk_hw hw;
24 struct regmap *regmap;
25 int set_ofs;
26 int clr_ofs;
27 int sta_ofs;
28 u8 bit;
29};
30
31static inline struct mtk_clk_gate *to_clk_gate(struct clk_hw *hw)
32{
33 return container_of(hw, struct mtk_clk_gate, hw);
34}
35
36extern const struct clk_ops mtk_clk_gate_ops_setclr;
37extern const struct clk_ops mtk_clk_gate_ops_setclr_inv;
38
39struct clk *mtk_clk_register_gate(
40 const char *name,
41 const char *parent_name,
42 struct regmap *regmap,
43 int set_ofs,
44 int clr_ofs,
45 int sta_ofs,
46 u8 bit,
47 const struct clk_ops *ops);
48
49#endif /* __DRV_CLK_GATE_H */
diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
new file mode 100644
index 000000000000..08b4b849b491
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8135.c
@@ -0,0 +1,644 @@
1/*
2 * Copyright (c) 2014 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/of.h>
16#include <linux/of_address.h>
17#include <linux/slab.h>
18#include <linux/mfd/syscon.h>
19#include <dt-bindings/clock/mt8135-clk.h>
20
21#include "clk-mtk.h"
22#include "clk-gate.h"
23
24static DEFINE_SPINLOCK(mt8135_clk_lock);
25
26static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
27 FACTOR(CLK_TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1),
28 FACTOR(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1),
29 FACTOR(CLK_TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1),
30 FACTOR(CLK_TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1),
31};
32
33static const struct mtk_fixed_factor top_divs[] __initconst = {
34 FACTOR(CLK_TOP_MAINPLL_806M, "mainpll_806m", "mainpll", 1, 2),
35 FACTOR(CLK_TOP_MAINPLL_537P3M, "mainpll_537p3m", "mainpll", 1, 3),
36 FACTOR(CLK_TOP_MAINPLL_322P4M, "mainpll_322p4m", "mainpll", 1, 5),
37 FACTOR(CLK_TOP_MAINPLL_230P3M, "mainpll_230p3m", "mainpll", 1, 7),
38
39 FACTOR(CLK_TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2),
40 FACTOR(CLK_TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3),
41 FACTOR(CLK_TOP_UNIVPLL_249P6M, "univpll_249p6m", "univpll", 1, 5),
42 FACTOR(CLK_TOP_UNIVPLL_178P3M, "univpll_178p3m", "univpll", 1, 7),
43 FACTOR(CLK_TOP_UNIVPLL_48M, "univpll_48m", "univpll", 1, 26),
44
45 FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
46 FACTOR(CLK_TOP_MMPLL_D3, "mmpll_d3", "mmpll", 1, 3),
47 FACTOR(CLK_TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5),
48 FACTOR(CLK_TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7),
49 FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll_d2", 1, 2),
50 FACTOR(CLK_TOP_MMPLL_D6, "mmpll_d6", "mmpll_d3", 1, 2),
51
52 FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll_806m", 1, 1),
53 FACTOR(CLK_TOP_SYSPLL_D4, "syspll_d4", "mainpll_806m", 1, 2),
54 FACTOR(CLK_TOP_SYSPLL_D6, "syspll_d6", "mainpll_806m", 1, 3),
55 FACTOR(CLK_TOP_SYSPLL_D8, "syspll_d8", "mainpll_806m", 1, 4),
56 FACTOR(CLK_TOP_SYSPLL_D10, "syspll_d10", "mainpll_806m", 1, 5),
57 FACTOR(CLK_TOP_SYSPLL_D12, "syspll_d12", "mainpll_806m", 1, 6),
58 FACTOR(CLK_TOP_SYSPLL_D16, "syspll_d16", "mainpll_806m", 1, 8),
59 FACTOR(CLK_TOP_SYSPLL_D24, "syspll_d24", "mainpll_806m", 1, 12),
60
61 FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll_537p3m", 1, 1),
62
63 FACTOR(CLK_TOP_SYSPLL_D2P5, "syspll_d2p5", "mainpll_322p4m", 2, 1),
64 FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll_322p4m", 1, 1),
65
66 FACTOR(CLK_TOP_SYSPLL_D3P5, "syspll_d3p5", "mainpll_230p3m", 2, 1),
67
68 FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2),
69 FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4),
70 FACTOR(CLK_TOP_UNIVPLL1_D6, "univpll1_d6", "univpll_624m", 1, 6),
71 FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8),
72 FACTOR(CLK_TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10),
73
74 FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2),
75 FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4),
76 FACTOR(CLK_TOP_UNIVPLL2_D6, "univpll2_d6", "univpll_416m", 1, 6),
77 FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8),
78
79 FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll_416m", 1, 1),
80 FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1),
81 FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll_178p3m", 1, 1),
82 FACTOR(CLK_TOP_UNIVPLL_D10, "univpll_d10", "univpll_249p6m", 1, 2),
83 FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1),
84
85 FACTOR(CLK_TOP_APLL, "apll_ck", "audpll", 1, 1),
86 FACTOR(CLK_TOP_APLL_D4, "apll_d4", "audpll", 1, 4),
87 FACTOR(CLK_TOP_APLL_D8, "apll_d8", "audpll", 1, 8),
88 FACTOR(CLK_TOP_APLL_D16, "apll_d16", "audpll", 1, 16),
89 FACTOR(CLK_TOP_APLL_D24, "apll_d24", "audpll", 1, 24),
90
91 FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
92 FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
93 FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
94
95 FACTOR(CLK_TOP_LVDSTX_CLKDIG_CT, "lvdstx_clkdig_cts", "lvdspll", 1, 1),
96 FACTOR(CLK_TOP_VPLL_DPIX, "vpll_dpix_ck", "lvdspll", 1, 1),
97
98 FACTOR(CLK_TOP_TVHDMI_H, "tvhdmi_h_ck", "tvdpll", 1, 1),
99
100 FACTOR(CLK_TOP_HDMITX_CLKDIG_D2, "hdmitx_clkdig_d2", "hdmitx_clkdig_cts", 1, 2),
101 FACTOR(CLK_TOP_HDMITX_CLKDIG_D3, "hdmitx_clkdig_d3", "hdmitx_clkdig_cts", 1, 3),
102
103 FACTOR(CLK_TOP_TVHDMI_D2, "tvhdmi_d2", "tvhdmi_h_ck", 1, 2),
104 FACTOR(CLK_TOP_TVHDMI_D4, "tvhdmi_d4", "tvhdmi_h_ck", 1, 4),
105
106 FACTOR(CLK_TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4),
107};
108
109static const char * const axi_parents[] __initconst = {
110 "clk26m",
111 "syspll_d3",
112 "syspll_d4",
113 "syspll_d6",
114 "univpll_d5",
115 "univpll2_d2",
116 "syspll_d3p5"
117};
118
119static const char * const smi_parents[] __initconst = {
120 "clk26m",
121 "clkph_mck",
122 "syspll_d2p5",
123 "syspll_d3",
124 "syspll_d8",
125 "univpll_d5",
126 "univpll1_d2",
127 "univpll1_d6",
128 "mmpll_d3",
129 "mmpll_d4",
130 "mmpll_d5",
131 "mmpll_d6",
132 "mmpll_d7",
133 "vdecpll",
134 "lvdspll"
135};
136
137static const char * const mfg_parents[] __initconst = {
138 "clk26m",
139 "univpll1_d4",
140 "syspll_d2",
141 "syspll_d2p5",
142 "syspll_d3",
143 "univpll_d5",
144 "univpll1_d2",
145 "mmpll_d2",
146 "mmpll_d3",
147 "mmpll_d4",
148 "mmpll_d5",
149 "mmpll_d6",
150 "mmpll_d7"
151};
152
153static const char * const irda_parents[] __initconst = {
154 "clk26m",
155 "univpll2_d8",
156 "univpll1_d6"
157};
158
159static const char * const cam_parents[] __initconst = {
160 "clk26m",
161 "syspll_d3",
162 "syspll_d3p5",
163 "syspll_d4",
164 "univpll_d5",
165 "univpll2_d2",
166 "univpll_d7",
167 "univpll1_d4"
168};
169
170static const char * const aud_intbus_parents[] __initconst = {
171 "clk26m",
172 "syspll_d6",
173 "univpll_d10"
174};
175
176static const char * const jpg_parents[] __initconst = {
177 "clk26m",
178 "syspll_d5",
179 "syspll_d4",
180 "syspll_d3",
181 "univpll_d7",
182 "univpll2_d2",
183 "univpll_d5"
184};
185
186static const char * const disp_parents[] __initconst = {
187 "clk26m",
188 "syspll_d3p5",
189 "syspll_d3",
190 "univpll2_d2",
191 "univpll_d5",
192 "univpll1_d2",
193 "lvdspll",
194 "vdecpll"
195};
196
197static const char * const msdc30_parents[] __initconst = {
198 "clk26m",
199 "syspll_d6",
200 "syspll_d5",
201 "univpll1_d4",
202 "univpll2_d4",
203 "msdcpll"
204};
205
206static const char * const usb20_parents[] __initconst = {
207 "clk26m",
208 "univpll2_d6",
209 "univpll1_d10"
210};
211
212static const char * const venc_parents[] __initconst = {
213 "clk26m",
214 "syspll_d3",
215 "syspll_d8",
216 "univpll_d5",
217 "univpll1_d6",
218 "mmpll_d4",
219 "mmpll_d5",
220 "mmpll_d6"
221};
222
223static const char * const spi_parents[] __initconst = {
224 "clk26m",
225 "syspll_d6",
226 "syspll_d8",
227 "syspll_d10",
228 "univpll1_d6",
229 "univpll1_d8"
230};
231
232static const char * const uart_parents[] __initconst = {
233 "clk26m",
234 "univpll2_d8"
235};
236
237static const char * const mem_parents[] __initconst = {
238 "clk26m",
239 "clkph_mck"
240};
241
242static const char * const camtg_parents[] __initconst = {
243 "clk26m",
244 "univpll_d26",
245 "univpll1_d6",
246 "syspll_d16",
247 "syspll_d8"
248};
249
250static const char * const audio_parents[] __initconst = {
251 "clk26m",
252 "syspll_d24"
253};
254
255static const char * const fix_parents[] __initconst = {
256 "rtc32k",
257 "clk26m",
258 "univpll_d5",
259 "univpll_d7",
260 "univpll1_d2",
261 "univpll1_d4",
262 "univpll1_d6",
263 "univpll1_d8"
264};
265
266static const char * const vdec_parents[] __initconst = {
267 "clk26m",
268 "vdecpll",
269 "clkph_mck",
270 "syspll_d2p5",
271 "syspll_d3",
272 "syspll_d3p5",
273 "syspll_d4",
274 "syspll_d5",
275 "syspll_d6",
276 "syspll_d8",
277 "univpll1_d2",
278 "univpll2_d2",
279 "univpll_d7",
280 "univpll_d10",
281 "univpll2_d4",
282 "lvdspll"
283};
284
285static const char * const ddrphycfg_parents[] __initconst = {
286 "clk26m",
287 "axi_sel",
288 "syspll_d12"
289};
290
291static const char * const dpilvds_parents[] __initconst = {
292 "clk26m",
293 "lvdspll",
294 "lvdspll_d2",
295 "lvdspll_d4",
296 "lvdspll_d8"
297};
298
299static const char * const pmicspi_parents[] __initconst = {
300 "clk26m",
301 "univpll2_d6",
302 "syspll_d8",
303 "syspll_d10",
304 "univpll1_d10",
305 "mempll_mck_d4",
306 "univpll_d26",
307 "syspll_d24"
308};
309
310static const char * const smi_mfg_as_parents[] __initconst = {
311 "clk26m",
312 "smi_sel",
313 "mfg_sel",
314 "mem_sel"
315};
316
317static const char * const gcpu_parents[] __initconst = {
318 "clk26m",
319 "syspll_d4",
320 "univpll_d7",
321 "syspll_d5",
322 "syspll_d6"
323};
324
325static const char * const dpi1_parents[] __initconst = {
326 "clk26m",
327 "tvhdmi_h_ck",
328 "tvhdmi_d2",
329 "tvhdmi_d4"
330};
331
332static const char * const cci_parents[] __initconst = {
333 "clk26m",
334 "mainpll_537p3m",
335 "univpll_d3",
336 "syspll_d2p5",
337 "syspll_d3",
338 "syspll_d5"
339};
340
341static const char * const apll_parents[] __initconst = {
342 "clk26m",
343 "apll_ck",
344 "apll_d4",
345 "apll_d8",
346 "apll_d16",
347 "apll_d24"
348};
349
350static const char * const hdmipll_parents[] __initconst = {
351 "clk26m",
352 "hdmitx_clkdig_cts",
353 "hdmitx_clkdig_d2",
354 "hdmitx_clkdig_d3"
355};
356
357static const struct mtk_composite top_muxes[] __initconst = {
358 /* CLK_CFG_0 */
359 MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
360 0x0140, 0, 3, INVALID_MUX_GATE_BIT),
361 MUX_GATE(CLK_TOP_SMI_SEL, "smi_sel", smi_parents, 0x0140, 8, 4, 15),
362 MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0140, 16, 4, 23),
363 MUX_GATE(CLK_TOP_IRDA_SEL, "irda_sel", irda_parents, 0x0140, 24, 2, 31),
364 /* CLK_CFG_1 */
365 MUX_GATE(CLK_TOP_CAM_SEL, "cam_sel", cam_parents, 0x0144, 0, 3, 7),
366 MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
367 0x0144, 8, 2, 15),
368 MUX_GATE(CLK_TOP_JPG_SEL, "jpg_sel", jpg_parents, 0x0144, 16, 3, 23),
369 MUX_GATE(CLK_TOP_DISP_SEL, "disp_sel", disp_parents, 0x0144, 24, 3, 31),
370 /* CLK_CFG_2 */
371 MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0148, 0, 3, 7),
372 MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0148, 8, 3, 15),
373 MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x0148, 16, 3, 23),
374 MUX_GATE(CLK_TOP_MSDC30_4_SEL, "msdc30_4_sel", msdc30_parents, 0x0148, 24, 3, 31),
375 /* CLK_CFG_3 */
376 MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x014c, 0, 2, 7),
377 /* CLK_CFG_4 */
378 MUX_GATE(CLK_TOP_VENC_SEL, "venc_sel", venc_parents, 0x0150, 8, 3, 15),
379 MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0150, 16, 3, 23),
380 MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0150, 24, 2, 31),
381 /* CLK_CFG_6 */
382 MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0158, 0, 2, 7),
383 MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0158, 8, 3, 15),
384 MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0158, 24, 2, 31),
385 /* CLK_CFG_7 */
386 MUX_GATE(CLK_TOP_FIX_SEL, "fix_sel", fix_parents, 0x015c, 0, 3, 7),
387 MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x015c, 8, 4, 15),
388 MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
389 0x015c, 16, 2, 23),
390 MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x015c, 24, 3, 31),
391 /* CLK_CFG_8 */
392 MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0164, 0, 3, 7),
393 MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0164, 8, 3, 15),
394 MUX_GATE(CLK_TOP_SMI_MFG_AS_SEL, "smi_mfg_as_sel", smi_mfg_as_parents,
395 0x0164, 16, 2, 23),
396 MUX_GATE(CLK_TOP_GCPU_SEL, "gcpu_sel", gcpu_parents, 0x0164, 24, 3, 31),
397 /* CLK_CFG_9 */
398 MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0168, 0, 2, 7),
399 MUX_GATE(CLK_TOP_CCI_SEL, "cci_sel", cci_parents, 0x0168, 8, 3, 15),
400 MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0168, 16, 3, 23),
401 MUX_GATE(CLK_TOP_HDMIPLL_SEL, "hdmipll_sel", hdmipll_parents, 0x0168, 24, 2, 31),
402};
403
404static const struct mtk_gate_regs infra_cg_regs = {
405 .set_ofs = 0x0040,
406 .clr_ofs = 0x0044,
407 .sta_ofs = 0x0048,
408};
409
410#define GATE_ICG(_id, _name, _parent, _shift) { \
411 .id = _id, \
412 .name = _name, \
413 .parent_name = _parent, \
414 .regs = &infra_cg_regs, \
415 .shift = _shift, \
416 .ops = &mtk_clk_gate_ops_setclr, \
417 }
418
419static const struct mtk_gate infra_clks[] __initconst = {
420 GATE_ICG(CLK_INFRA_PMIC_WRAP, "pmic_wrap_ck", "axi_sel", 23),
421 GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22),
422 GATE_ICG(CLK_INFRA_CCIF1_AP_CTRL, "ccif1_ap_ctrl", "axi_sel", 21),
423 GATE_ICG(CLK_INFRA_CCIF0_AP_CTRL, "ccif0_ap_ctrl", "axi_sel", 20),
424 GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16),
425 GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "cpum_tck_in", 15),
426 GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8),
427 GATE_ICG(CLK_INFRA_MFGAXI, "mfgaxi_ck", "axi_sel", 7),
428 GATE_ICG(CLK_INFRA_DEVAPC, "devapc_ck", "axi_sel", 6),
429 GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "aud_intbus_sel", 5),
430 GATE_ICG(CLK_INFRA_MFG_BUS, "mfg_bus_ck", "axi_sel", 2),
431 GATE_ICG(CLK_INFRA_SMI, "smi_ck", "smi_sel", 1),
432 GATE_ICG(CLK_INFRA_DBGCLK, "dbgclk_ck", "axi_sel", 0),
433};
434
435static const struct mtk_gate_regs peri0_cg_regs = {
436 .set_ofs = 0x0008,
437 .clr_ofs = 0x0010,
438 .sta_ofs = 0x0018,
439};
440
441static const struct mtk_gate_regs peri1_cg_regs = {
442 .set_ofs = 0x000c,
443 .clr_ofs = 0x0014,
444 .sta_ofs = 0x001c,
445};
446
447#define GATE_PERI0(_id, _name, _parent, _shift) { \
448 .id = _id, \
449 .name = _name, \
450 .parent_name = _parent, \
451 .regs = &peri0_cg_regs, \
452 .shift = _shift, \
453 .ops = &mtk_clk_gate_ops_setclr, \
454 }
455
456#define GATE_PERI1(_id, _name, _parent, _shift) { \
457 .id = _id, \
458 .name = _name, \
459 .parent_name = _parent, \
460 .regs = &peri1_cg_regs, \
461 .shift = _shift, \
462 .ops = &mtk_clk_gate_ops_setclr, \
463 }
464
465static const struct mtk_gate peri_gates[] __initconst = {
466 /* PERI0 */
467 GATE_PERI0(CLK_PERI_I2C5, "i2c5_ck", "axi_sel", 31),
468 GATE_PERI0(CLK_PERI_I2C4, "i2c4_ck", "axi_sel", 30),
469 GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "axi_sel", 29),
470 GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 28),
471 GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 27),
472 GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 26),
473 GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 25),
474 GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 24),
475 GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 23),
476 GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 22),
477 GATE_PERI0(CLK_PERI_IRDA, "irda_ck", "irda_sel", 21),
478 GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 20),
479 GATE_PERI0(CLK_PERI_MD_HIF, "md_hif_ck", "axi_sel", 19),
480 GATE_PERI0(CLK_PERI_AP_HIF, "ap_hif_ck", "axi_sel", 18),
481 GATE_PERI0(CLK_PERI_MSDC30_3, "msdc30_3_ck", "msdc30_4_sel", 17),
482 GATE_PERI0(CLK_PERI_MSDC30_2, "msdc30_2_ck", "msdc30_3_sel", 16),
483 GATE_PERI0(CLK_PERI_MSDC30_1, "msdc30_1_ck", "msdc30_2_sel", 15),
484 GATE_PERI0(CLK_PERI_MSDC20_2, "msdc20_2_ck", "msdc30_1_sel", 14),
485 GATE_PERI0(CLK_PERI_MSDC20_1, "msdc20_1_ck", "msdc30_0_sel", 13),
486 GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12),
487 GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11),
488 GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10),
489 GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9),
490 GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8),
491 GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7),
492 GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6),
493 GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5),
494 GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4),
495 GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3),
496 GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2),
497 GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1),
498 GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "axi_sel", 0),
499 /* PERI1 */
500 GATE_PERI1(CLK_PERI_USBSLV, "usbslv_ck", "axi_sel", 8),
501 GATE_PERI1(CLK_PERI_USB1_MCU, "usb1_mcu_ck", "axi_sel", 7),
502 GATE_PERI1(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 6),
503 GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "gcpu_sel", 5),
504 GATE_PERI1(CLK_PERI_FHCTL, "fhctl_ck", "clk26m", 4),
505 GATE_PERI1(CLK_PERI_SPI1, "spi1_ck", "spi_sel", 3),
506 GATE_PERI1(CLK_PERI_AUXADC, "auxadc_ck", "clk26m", 2),
507 GATE_PERI1(CLK_PERI_PERI_PWRAP, "peri_pwrap_ck", "axi_sel", 1),
508 GATE_PERI1(CLK_PERI_I2C6, "i2c6_ck", "axi_sel", 0),
509};
510
511static const char * const uart_ck_sel_parents[] __initconst = {
512 "clk26m",
513 "uart_sel",
514};
515
516static const struct mtk_composite peri_clks[] __initconst = {
517 MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1),
518 MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1),
519 MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1),
520 MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
521};
522
523static void __init mtk_topckgen_init(struct device_node *node)
524{
525 struct clk_onecell_data *clk_data;
526 void __iomem *base;
527 int r;
528
529 base = of_iomap(node, 0);
530 if (!base) {
531 pr_err("%s(): ioremap failed\n", __func__);
532 return;
533 }
534
535 clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
536
537 mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
538 mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
539 mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
540 &mt8135_clk_lock, clk_data);
541
542 clk_prepare_enable(clk_data->clks[CLK_TOP_CCI_SEL]);
543
544 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
545 if (r)
546 pr_err("%s(): could not register clock provider: %d\n",
547 __func__, r);
548}
549CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8135-topckgen", mtk_topckgen_init);
550
551static void __init mtk_infrasys_init(struct device_node *node)
552{
553 struct clk_onecell_data *clk_data;
554 int r;
555
556 clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
557
558 mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
559 clk_data);
560
561 clk_prepare_enable(clk_data->clks[CLK_INFRA_M4U]);
562
563 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
564 if (r)
565 pr_err("%s(): could not register clock provider: %d\n",
566 __func__, r);
567
568 mtk_register_reset_controller(node, 2, 0x30);
569}
570CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8135-infracfg", mtk_infrasys_init);
571
572static void __init mtk_pericfg_init(struct device_node *node)
573{
574 struct clk_onecell_data *clk_data;
575 int r;
576 void __iomem *base;
577
578 base = of_iomap(node, 0);
579 if (!base) {
580 pr_err("%s(): ioremap failed\n", __func__);
581 return;
582 }
583
584 clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
585
586 mtk_clk_register_gates(node, peri_gates, ARRAY_SIZE(peri_gates),
587 clk_data);
588 mtk_clk_register_composites(peri_clks, ARRAY_SIZE(peri_clks), base,
589 &mt8135_clk_lock, clk_data);
590
591 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
592 if (r)
593 pr_err("%s(): could not register clock provider: %d\n",
594 __func__, r);
595
596 mtk_register_reset_controller(node, 2, 0);
597}
598CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8135-pericfg", mtk_pericfg_init);
599
600#define MT8135_PLL_FMAX (2000 * MHZ)
601#define CON0_MT8135_RST_BAR BIT(27)
602
603#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
604 .id = _id, \
605 .name = _name, \
606 .reg = _reg, \
607 .pwr_reg = _pwr_reg, \
608 .en_mask = _en_mask, \
609 .flags = _flags, \
610 .rst_bar_mask = CON0_MT8135_RST_BAR, \
611 .fmax = MT8135_PLL_FMAX, \
612 .pcwbits = _pcwbits, \
613 .pd_reg = _pd_reg, \
614 .pd_shift = _pd_shift, \
615 .tuner_reg = _tuner_reg, \
616 .pcw_reg = _pcw_reg, \
617 .pcw_shift = _pcw_shift, \
618 }
619
620static const struct mtk_pll_data plls[] = {
621 PLL(CLK_APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
622 PLL(CLK_APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0),
623 PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0),
624 PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9),
625 PLL(CLK_APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0),
626 PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0),
627 PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x294, 6, 0x0, 0x298, 0),
628 PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x2b0, 0x2c8, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0),
629 PLL(CLK_APMIXED_AUDPLL, "audpll", 0x2e8, 0x300, 0x80000001, 0, 31, 0x2e8, 6, 0x2f8, 0x2ec, 0),
630 PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x304, 0x31c, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x308, 0),
631};
632
633static void __init mtk_apmixedsys_init(struct device_node *node)
634{
635 struct clk_onecell_data *clk_data;
636
637 clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
638 if (!clk_data)
639 return;
640
641 mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
642}
643CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8135-apmixedsys",
644 mtk_apmixedsys_init);
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
new file mode 100644
index 000000000000..4b9e04cdf7e8
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -0,0 +1,830 @@
1/*
2 * Copyright (c) 2014 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/of.h>
16#include <linux/of_address.h>
17#include <linux/slab.h>
18#include <linux/mfd/syscon.h>
19
20#include "clk-mtk.h"
21#include "clk-gate.h"
22
23#include <dt-bindings/clock/mt8173-clk.h>
24
25static DEFINE_SPINLOCK(mt8173_clk_lock);
26
27static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
28 FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1),
29 FACTOR(CLK_TOP_DPI, "dpi_ck", "clk_null", 1, 1),
30 FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1),
31 FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1),
32};
33
34static const struct mtk_fixed_factor top_divs[] __initconst = {
35 FACTOR(CLK_TOP_ARMCA7PLL_754M, "armca7pll_754m", "armca7pll", 1, 2),
36 FACTOR(CLK_TOP_ARMCA7PLL_502M, "armca7pll_502m", "armca7pll", 1, 3),
37
38 FACTOR(CLK_TOP_MAIN_H546M, "main_h546m", "mainpll", 1, 2),
39 FACTOR(CLK_TOP_MAIN_H364M, "main_h364m", "mainpll", 1, 3),
40 FACTOR(CLK_TOP_MAIN_H218P4M, "main_h218p4m", "mainpll", 1, 5),
41 FACTOR(CLK_TOP_MAIN_H156M, "main_h156m", "mainpll", 1, 7),
42
43 FACTOR(CLK_TOP_TVDPLL_445P5M, "tvdpll_445p5m", "tvdpll", 1, 4),
44 FACTOR(CLK_TOP_TVDPLL_594M, "tvdpll_594m", "tvdpll", 1, 3),
45
46 FACTOR(CLK_TOP_UNIV_624M, "univ_624m", "univpll", 1, 2),
47 FACTOR(CLK_TOP_UNIV_416M, "univ_416m", "univpll", 1, 3),
48 FACTOR(CLK_TOP_UNIV_249P6M, "univ_249p6m", "univpll", 1, 5),
49 FACTOR(CLK_TOP_UNIV_178P3M, "univ_178p3m", "univpll", 1, 7),
50 FACTOR(CLK_TOP_UNIV_48M, "univ_48m", "univpll", 1, 26),
51
52 FACTOR(CLK_TOP_CLKRTC_EXT, "clkrtc_ext", "clk32k", 1, 1),
53 FACTOR(CLK_TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793),
54 FACTOR(CLK_TOP_FPC, "fpc_ck", "clk26m", 1, 1),
55
56 FACTOR(CLK_TOP_HDMITXPLL_D2, "hdmitxpll_d2", "hdmitx_dig_cts", 1, 2),
57 FACTOR(CLK_TOP_HDMITXPLL_D3, "hdmitxpll_d3", "hdmitx_dig_cts", 1, 3),
58
59 FACTOR(CLK_TOP_ARMCA7PLL_D2, "armca7pll_d2", "armca7pll_754m", 1, 1),
60 FACTOR(CLK_TOP_ARMCA7PLL_D3, "armca7pll_d3", "armca7pll_502m", 1, 1),
61
62 FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, 1),
63 FACTOR(CLK_TOP_APLL2, "apll2_ck", "apll2", 1, 1),
64
65 FACTOR(CLK_TOP_DMPLL, "dmpll_ck", "clkph_mck_o", 1, 1),
66 FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "clkph_mck_o", 1, 2),
67 FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "clkph_mck_o", 1, 4),
68 FACTOR(CLK_TOP_DMPLL_D8, "dmpll_d8", "clkph_mck_o", 1, 8),
69 FACTOR(CLK_TOP_DMPLL_D16, "dmpll_d16", "clkph_mck_o", 1, 16),
70
71 FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
72 FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
73 FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
74
75 FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1),
76 FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
77
78 FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
79 FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
80 FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
81 FACTOR(CLK_TOP_MSDCPLL2, "msdcpll2_ck", "msdcpll2", 1, 1),
82 FACTOR(CLK_TOP_MSDCPLL2_D2, "msdcpll2_d2", "msdcpll2", 1, 2),
83 FACTOR(CLK_TOP_MSDCPLL2_D4, "msdcpll2_d4", "msdcpll2", 1, 4),
84
85 FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "main_h546m", 1, 1),
86 FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "main_h546m", 1, 2),
87 FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "main_h546m", 1, 4),
88 FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "main_h546m", 1, 8),
89 FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "main_h546m", 1, 16),
90 FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "main_h364m", 1, 1),
91 FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "main_h364m", 1, 2),
92 FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "main_h364m", 1, 4),
93 FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "main_h218p4m", 1, 1),
94 FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "main_h218p4m", 1, 2),
95 FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "main_h218p4m", 1, 4),
96 FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "main_h156m", 1, 1),
97 FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "main_h156m", 1, 2),
98 FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "main_h156m", 1, 4),
99
100 FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll_594m", 1, 1),
101 FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_594m", 1, 2),
102 FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_594m", 1, 4),
103 FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_594m", 1, 8),
104 FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll_594m", 1, 16),
105
106 FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univ_624m", 1, 1),
107 FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univ_624m", 1, 2),
108 FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univ_624m", 1, 4),
109 FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univ_624m", 1, 8),
110 FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univ_416m", 1, 1),
111 FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univ_416m", 1, 2),
112 FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univ_416m", 1, 4),
113 FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univ_416m", 1, 8),
114 FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univ_249p6m", 1, 1),
115 FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univ_249p6m", 1, 2),
116 FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univ_249p6m", 1, 4),
117 FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univ_249p6m", 1, 8),
118 FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univ_178p3m", 1, 1),
119 FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univ_48m", 1, 1),
120 FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univ_48m", 1, 2),
121
122 FACTOR(CLK_TOP_VCODECPLL, "vcodecpll_ck", "vcodecpll", 1, 3),
123 FACTOR(CLK_TOP_VCODECPLL_370P5, "vcodecpll_370p5", "vcodecpll", 1, 4),
124
125 FACTOR(CLK_TOP_VENCPLL, "vencpll_ck", "vencpll", 1, 1),
126 FACTOR(CLK_TOP_VENCPLL_D2, "vencpll_d2", "vencpll", 1, 2),
127 FACTOR(CLK_TOP_VENCPLL_D4, "vencpll_d4", "vencpll", 1, 4),
128};
129
130static const char * const axi_parents[] __initconst = {
131 "clk26m",
132 "syspll1_d2",
133 "syspll_d5",
134 "syspll1_d4",
135 "univpll_d5",
136 "univpll2_d2",
137 "dmpll_d2",
138 "dmpll_d4"
139};
140
141static const char * const mem_parents[] __initconst = {
142 "clk26m",
143 "dmpll_ck"
144};
145
146static const char * const ddrphycfg_parents[] __initconst = {
147 "clk26m",
148 "syspll1_d8"
149};
150
151static const char * const mm_parents[] __initconst = {
152 "clk26m",
153 "vencpll_d2",
154 "main_h364m",
155 "syspll1_d2",
156 "syspll_d5",
157 "syspll1_d4",
158 "univpll1_d2",
159 "univpll2_d2",
160 "dmpll_d2"
161};
162
163static const char * const pwm_parents[] __initconst = {
164 "clk26m",
165 "univpll2_d4",
166 "univpll3_d2",
167 "univpll1_d4"
168};
169
170static const char * const vdec_parents[] __initconst = {
171 "clk26m",
172 "vcodecpll_ck",
173 "tvdpll_445p5m",
174 "univpll_d3",
175 "vencpll_d2",
176 "syspll_d3",
177 "univpll1_d2",
178 "mmpll_d2",
179 "dmpll_d2",
180 "dmpll_d4"
181};
182
183static const char * const venc_parents[] __initconst = {
184 "clk26m",
185 "vcodecpll_ck",
186 "tvdpll_445p5m",
187 "univpll_d3",
188 "vencpll_d2",
189 "syspll_d3",
190 "univpll1_d2",
191 "univpll2_d2",
192 "dmpll_d2",
193 "dmpll_d4"
194};
195
196static const char * const mfg_parents[] __initconst = {
197 "clk26m",
198 "mmpll_ck",
199 "dmpll_ck",
200 "clk26m",
201 "clk26m",
202 "clk26m",
203 "clk26m",
204 "clk26m",
205 "clk26m",
206 "syspll_d3",
207 "syspll1_d2",
208 "syspll_d5",
209 "univpll_d3",
210 "univpll1_d2",
211 "univpll_d5",
212 "univpll2_d2"
213};
214
215static const char * const camtg_parents[] __initconst = {
216 "clk26m",
217 "univpll_d26",
218 "univpll2_d2",
219 "syspll3_d2",
220 "syspll3_d4",
221 "univpll1_d4"
222};
223
224static const char * const uart_parents[] __initconst = {
225 "clk26m",
226 "univpll2_d8"
227};
228
229static const char * const spi_parents[] __initconst = {
230 "clk26m",
231 "syspll3_d2",
232 "syspll1_d4",
233 "syspll4_d2",
234 "univpll3_d2",
235 "univpll2_d4",
236 "univpll1_d8"
237};
238
239static const char * const usb20_parents[] __initconst = {
240 "clk26m",
241 "univpll1_d8",
242 "univpll3_d4"
243};
244
245static const char * const usb30_parents[] __initconst = {
246 "clk26m",
247 "univpll3_d2",
248 "usb_syspll_125m",
249 "univpll2_d4"
250};
251
252static const char * const msdc50_0_h_parents[] __initconst = {
253 "clk26m",
254 "syspll1_d2",
255 "syspll2_d2",
256 "syspll4_d2",
257 "univpll_d5",
258 "univpll1_d4"
259};
260
261static const char * const msdc50_0_parents[] __initconst = {
262 "clk26m",
263 "msdcpll_ck",
264 "msdcpll_d2",
265 "univpll1_d4",
266 "syspll2_d2",
267 "syspll_d7",
268 "msdcpll_d4",
269 "vencpll_d4",
270 "tvdpll_ck",
271 "univpll_d2",
272 "univpll1_d2",
273 "mmpll_ck",
274 "msdcpll2_ck",
275 "msdcpll2_d2",
276 "msdcpll2_d4"
277};
278
279static const char * const msdc30_1_parents[] __initconst = {
280 "clk26m",
281 "univpll2_d2",
282 "msdcpll_d4",
283 "univpll1_d4",
284 "syspll2_d2",
285 "syspll_d7",
286 "univpll_d7",
287 "vencpll_d4"
288};
289
290static const char * const msdc30_2_parents[] __initconst = {
291 "clk26m",
292 "univpll2_d2",
293 "msdcpll_d4",
294 "univpll1_d4",
295 "syspll2_d2",
296 "syspll_d7",
297 "univpll_d7",
298 "vencpll_d2"
299};
300
301static const char * const msdc30_3_parents[] __initconst = {
302 "clk26m",
303 "msdcpll2_ck",
304 "msdcpll2_d2",
305 "univpll2_d2",
306 "msdcpll2_d4",
307 "msdcpll_d4",
308 "univpll1_d4",
309 "syspll2_d2",
310 "syspll_d7",
311 "univpll_d7",
312 "vencpll_d4",
313 "msdcpll_ck",
314 "msdcpll_d2",
315 "msdcpll_d4"
316};
317
318static const char * const audio_parents[] __initconst = {
319 "clk26m",
320 "syspll3_d4",
321 "syspll4_d4",
322 "syspll1_d16"
323};
324
325static const char * const aud_intbus_parents[] __initconst = {
326 "clk26m",
327 "syspll1_d4",
328 "syspll4_d2",
329 "univpll3_d2",
330 "univpll2_d8",
331 "dmpll_d4",
332 "dmpll_d8"
333};
334
335static const char * const pmicspi_parents[] __initconst = {
336 "clk26m",
337 "syspll1_d8",
338 "syspll3_d4",
339 "syspll1_d16",
340 "univpll3_d4",
341 "univpll_d26",
342 "dmpll_d8",
343 "dmpll_d16"
344};
345
346static const char * const scp_parents[] __initconst = {
347 "clk26m",
348 "syspll1_d2",
349 "univpll_d5",
350 "syspll_d5",
351 "dmpll_d2",
352 "dmpll_d4"
353};
354
355static const char * const atb_parents[] __initconst = {
356 "clk26m",
357 "syspll1_d2",
358 "univpll_d5",
359 "dmpll_d2"
360};
361
362static const char * const venc_lt_parents[] __initconst = {
363 "clk26m",
364 "univpll_d3",
365 "vcodecpll_ck",
366 "tvdpll_445p5m",
367 "vencpll_d2",
368 "syspll_d3",
369 "univpll1_d2",
370 "univpll2_d2",
371 "syspll1_d2",
372 "univpll_d5",
373 "vcodecpll_370p5",
374 "dmpll_ck"
375};
376
377static const char * const dpi0_parents[] __initconst = {
378 "clk26m",
379 "tvdpll_d2",
380 "tvdpll_d4",
381 "clk26m",
382 "clk26m",
383 "tvdpll_d8",
384 "tvdpll_d16"
385};
386
387static const char * const irda_parents[] __initconst = {
388 "clk26m",
389 "univpll2_d4",
390 "syspll2_d4"
391};
392
393static const char * const cci400_parents[] __initconst = {
394 "clk26m",
395 "vencpll_ck",
396 "armca7pll_754m",
397 "armca7pll_502m",
398 "univpll_d2",
399 "syspll_d2",
400 "msdcpll_ck",
401 "dmpll_ck"
402};
403
404static const char * const aud_1_parents[] __initconst = {
405 "clk26m",
406 "apll1_ck",
407 "univpll2_d4",
408 "univpll2_d8"
409};
410
411static const char * const aud_2_parents[] __initconst = {
412 "clk26m",
413 "apll2_ck",
414 "univpll2_d4",
415 "univpll2_d8"
416};
417
418static const char * const mem_mfg_in_parents[] __initconst = {
419 "clk26m",
420 "mmpll_ck",
421 "dmpll_ck",
422 "clk26m"
423};
424
425static const char * const axi_mfg_in_parents[] __initconst = {
426 "clk26m",
427 "axi_sel",
428 "dmpll_d2"
429};
430
431static const char * const scam_parents[] __initconst = {
432 "clk26m",
433 "syspll3_d2",
434 "univpll2_d4",
435 "dmpll_d4"
436};
437
438static const char * const spinfi_ifr_parents[] __initconst = {
439 "clk26m",
440 "univpll2_d8",
441 "univpll3_d4",
442 "syspll4_d2",
443 "univpll2_d4",
444 "univpll3_d2",
445 "syspll1_d4",
446 "univpll1_d4"
447};
448
449static const char * const hdmi_parents[] __initconst = {
450 "clk26m",
451 "hdmitx_dig_cts",
452 "hdmitxpll_d2",
453 "hdmitxpll_d3"
454};
455
456static const char * const dpilvds_parents[] __initconst = {
457 "clk26m",
458 "lvdspll",
459 "lvdspll_d2",
460 "lvdspll_d4",
461 "lvdspll_d8",
462 "fpc_ck"
463};
464
465static const char * const msdc50_2_h_parents[] __initconst = {
466 "clk26m",
467 "syspll1_d2",
468 "syspll2_d2",
469 "syspll4_d2",
470 "univpll_d5",
471 "univpll1_d4"
472};
473
474static const char * const hdcp_parents[] __initconst = {
475 "clk26m",
476 "syspll4_d2",
477 "syspll3_d4",
478 "univpll2_d4"
479};
480
481static const char * const hdcp_24m_parents[] __initconst = {
482 "clk26m",
483 "univpll_d26",
484 "univpll_d52",
485 "univpll2_d8"
486};
487
488static const char * const rtc_parents[] __initconst = {
489 "clkrtc_int",
490 "clkrtc_ext",
491 "clk26m",
492 "univpll3_d8"
493};
494
495static const char * const i2s0_m_ck_parents[] __initconst = {
496 "apll1_div1",
497 "apll2_div1"
498};
499
500static const char * const i2s1_m_ck_parents[] __initconst = {
501 "apll1_div2",
502 "apll2_div2"
503};
504
505static const char * const i2s2_m_ck_parents[] __initconst = {
506 "apll1_div3",
507 "apll2_div3"
508};
509
510static const char * const i2s3_m_ck_parents[] __initconst = {
511 "apll1_div4",
512 "apll2_div4"
513};
514
515static const char * const i2s3_b_ck_parents[] __initconst = {
516 "apll1_div5",
517 "apll2_div5"
518};
519
520static const struct mtk_composite top_muxes[] __initconst = {
521 /* CLK_CFG_0 */
522 MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
523 MUX(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0040, 8, 1),
524 MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, 0x0040, 16, 1, 23),
525 MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents, 0x0040, 24, 4, 31),
526 /* CLK_CFG_1 */
527 MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7),
528 MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15),
529 MUX_GATE(CLK_TOP_VENC_SEL, "venc_sel", venc_parents, 0x0050, 16, 4, 23),
530 MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 24, 4, 31),
531 /* CLK_CFG_2 */
532 MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0060, 0, 3, 7),
533 MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 8, 1, 15),
534 MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0060, 16, 3, 23),
535 MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x0060, 24, 2, 31),
536 /* CLK_CFG_3 */
537 MUX_GATE(CLK_TOP_USB30_SEL, "usb30_sel", usb30_parents, 0x0070, 0, 2, 7),
538 MUX_GATE(CLK_TOP_MSDC50_0_H_SEL, "msdc50_0_h_sel", msdc50_0_h_parents, 0x0070, 8, 3, 15),
539 MUX_GATE(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel", msdc50_0_parents, 0x0070, 16, 4, 23),
540 MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_1_parents, 0x0070, 24, 3, 31),
541 /* CLK_CFG_4 */
542 MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_2_parents, 0x0080, 0, 3, 7),
543 MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_3_parents, 0x0080, 8, 4, 15),
544 MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0080, 16, 2, 23),
545 MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, 0x0080, 24, 3, 31),
546 /* CLK_CFG_5 */
547 MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0090, 0, 3, 7 /* 7:5 */),
548 MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x0090, 8, 3, 15),
549 MUX_GATE(CLK_TOP_ATB_SEL, "atb_sel", atb_parents, 0x0090, 16, 2, 23),
550 MUX_GATE(CLK_TOP_VENC_LT_SEL, "venclt_sel", venc_lt_parents, 0x0090, 24, 4, 31),
551 /* CLK_CFG_6 */
552 MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x00a0, 0, 3, 7),
553 MUX_GATE(CLK_TOP_IRDA_SEL, "irda_sel", irda_parents, 0x00a0, 8, 2, 15),
554 MUX_GATE(CLK_TOP_CCI400_SEL, "cci400_sel", cci400_parents, 0x00a0, 16, 3, 23),
555 MUX_GATE(CLK_TOP_AUD_1_SEL, "aud_1_sel", aud_1_parents, 0x00a0, 24, 2, 31),
556 /* CLK_CFG_7 */
557 MUX_GATE(CLK_TOP_AUD_2_SEL, "aud_2_sel", aud_2_parents, 0x00b0, 0, 2, 7),
558 MUX_GATE(CLK_TOP_MEM_MFG_IN_SEL, "mem_mfg_in_sel", mem_mfg_in_parents, 0x00b0, 8, 2, 15),
559 MUX_GATE(CLK_TOP_AXI_MFG_IN_SEL, "axi_mfg_in_sel", axi_mfg_in_parents, 0x00b0, 16, 2, 23),
560 MUX_GATE(CLK_TOP_SCAM_SEL, "scam_sel", scam_parents, 0x00b0, 24, 2, 31),
561 /* CLK_CFG_12 */
562 MUX_GATE(CLK_TOP_SPINFI_IFR_SEL, "spinfi_ifr_sel", spinfi_ifr_parents, 0x00c0, 0, 3, 7),
563 MUX_GATE(CLK_TOP_HDMI_SEL, "hdmi_sel", hdmi_parents, 0x00c0, 8, 2, 15),
564 MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x00c0, 24, 3, 31),
565 /* CLK_CFG_13 */
566 MUX_GATE(CLK_TOP_MSDC50_2_H_SEL, "msdc50_2_h_sel", msdc50_2_h_parents, 0x00d0, 0, 3, 7),
567 MUX_GATE(CLK_TOP_HDCP_SEL, "hdcp_sel", hdcp_parents, 0x00d0, 8, 2, 15),
568 MUX_GATE(CLK_TOP_HDCP_24M_SEL, "hdcp_24m_sel", hdcp_24m_parents, 0x00d0, 16, 2, 23),
569 MUX(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00d0, 24, 2),
570
571 DIV_GATE(CLK_TOP_APLL1_DIV0, "apll1_div0", "aud_1_sel", 0x12c, 8, 0x120, 4, 24),
572 DIV_GATE(CLK_TOP_APLL1_DIV1, "apll1_div1", "aud_1_sel", 0x12c, 9, 0x124, 8, 0),
573 DIV_GATE(CLK_TOP_APLL1_DIV2, "apll1_div2", "aud_1_sel", 0x12c, 10, 0x124, 8, 8),
574 DIV_GATE(CLK_TOP_APLL1_DIV3, "apll1_div3", "aud_1_sel", 0x12c, 11, 0x124, 8, 16),
575 DIV_GATE(CLK_TOP_APLL1_DIV4, "apll1_div4", "aud_1_sel", 0x12c, 12, 0x124, 8, 24),
576 DIV_GATE(CLK_TOP_APLL1_DIV5, "apll1_div5", "apll1_div4", 0x12c, 13, 0x12c, 4, 0),
577
578 DIV_GATE(CLK_TOP_APLL2_DIV0, "apll2_div0", "aud_2_sel", 0x12c, 16, 0x120, 4, 28),
579 DIV_GATE(CLK_TOP_APLL2_DIV1, "apll2_div1", "aud_2_sel", 0x12c, 17, 0x128, 8, 0),
580 DIV_GATE(CLK_TOP_APLL2_DIV2, "apll2_div2", "aud_2_sel", 0x12c, 18, 0x128, 8, 8),
581 DIV_GATE(CLK_TOP_APLL2_DIV3, "apll2_div3", "aud_2_sel", 0x12c, 19, 0x128, 8, 16),
582 DIV_GATE(CLK_TOP_APLL2_DIV4, "apll2_div4", "aud_2_sel", 0x12c, 20, 0x128, 8, 24),
583 DIV_GATE(CLK_TOP_APLL2_DIV5, "apll2_div5", "apll2_div4", 0x12c, 21, 0x12c, 4, 4),
584
585 MUX(CLK_TOP_I2S0_M_SEL, "i2s0_m_ck_sel", i2s0_m_ck_parents, 0x120, 4, 1),
586 MUX(CLK_TOP_I2S1_M_SEL, "i2s1_m_ck_sel", i2s1_m_ck_parents, 0x120, 5, 1),
587 MUX(CLK_TOP_I2S2_M_SEL, "i2s2_m_ck_sel", i2s2_m_ck_parents, 0x120, 6, 1),
588 MUX(CLK_TOP_I2S3_M_SEL, "i2s3_m_ck_sel", i2s3_m_ck_parents, 0x120, 7, 1),
589 MUX(CLK_TOP_I2S3_B_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1),
590};
591
592static const struct mtk_gate_regs infra_cg_regs = {
593 .set_ofs = 0x0040,
594 .clr_ofs = 0x0044,
595 .sta_ofs = 0x0048,
596};
597
598#define GATE_ICG(_id, _name, _parent, _shift) { \
599 .id = _id, \
600 .name = _name, \
601 .parent_name = _parent, \
602 .regs = &infra_cg_regs, \
603 .shift = _shift, \
604 .ops = &mtk_clk_gate_ops_setclr, \
605 }
606
607static const struct mtk_gate infra_clks[] __initconst = {
608 GATE_ICG(CLK_INFRA_DBGCLK, "infra_dbgclk", "axi_sel", 0),
609 GATE_ICG(CLK_INFRA_SMI, "infra_smi", "mm_sel", 1),
610 GATE_ICG(CLK_INFRA_AUDIO, "infra_audio", "aud_intbus_sel", 5),
611 GATE_ICG(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6),
612 GATE_ICG(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7),
613 GATE_ICG(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8),
614 GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "clk_null", 15),
615 GATE_ICG(CLK_INFRA_KP, "infra_kp", "axi_sel", 16),
616 GATE_ICG(CLK_INFRA_CEC, "infra_cec", "clk26m", 18),
617 GATE_ICG(CLK_INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22),
618 GATE_ICG(CLK_INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23),
619};
620
621static const struct mtk_gate_regs peri0_cg_regs = {
622 .set_ofs = 0x0008,
623 .clr_ofs = 0x0010,
624 .sta_ofs = 0x0018,
625};
626
627static const struct mtk_gate_regs peri1_cg_regs = {
628 .set_ofs = 0x000c,
629 .clr_ofs = 0x0014,
630 .sta_ofs = 0x001c,
631};
632
633#define GATE_PERI0(_id, _name, _parent, _shift) { \
634 .id = _id, \
635 .name = _name, \
636 .parent_name = _parent, \
637 .regs = &peri0_cg_regs, \
638 .shift = _shift, \
639 .ops = &mtk_clk_gate_ops_setclr, \
640 }
641
642#define GATE_PERI1(_id, _name, _parent, _shift) { \
643 .id = _id, \
644 .name = _name, \
645 .parent_name = _parent, \
646 .regs = &peri1_cg_regs, \
647 .shift = _shift, \
648 .ops = &mtk_clk_gate_ops_setclr, \
649 }
650
651static const struct mtk_gate peri_gates[] __initconst = {
652 /* PERI0 */
653 GATE_PERI0(CLK_PERI_NFI, "peri_nfi", "axi_sel", 0),
654 GATE_PERI0(CLK_PERI_THERM, "peri_therm", "axi_sel", 1),
655 GATE_PERI0(CLK_PERI_PWM1, "peri_pwm1", "axi_sel", 2),
656 GATE_PERI0(CLK_PERI_PWM2, "peri_pwm2", "axi_sel", 3),
657 GATE_PERI0(CLK_PERI_PWM3, "peri_pwm3", "axi_sel", 4),
658 GATE_PERI0(CLK_PERI_PWM4, "peri_pwm4", "axi_sel", 5),
659 GATE_PERI0(CLK_PERI_PWM5, "peri_pwm5", "axi_sel", 6),
660 GATE_PERI0(CLK_PERI_PWM6, "peri_pwm6", "axi_sel", 7),
661 GATE_PERI0(CLK_PERI_PWM7, "peri_pwm7", "axi_sel", 8),
662 GATE_PERI0(CLK_PERI_PWM, "peri_pwm", "axi_sel", 9),
663 GATE_PERI0(CLK_PERI_USB0, "peri_usb0", "usb20_sel", 10),
664 GATE_PERI0(CLK_PERI_USB1, "peri_usb1", "usb20_sel", 11),
665 GATE_PERI0(CLK_PERI_AP_DMA, "peri_ap_dma", "axi_sel", 12),
666 GATE_PERI0(CLK_PERI_MSDC30_0, "peri_msdc30_0", "msdc50_0_sel", 13),
667 GATE_PERI0(CLK_PERI_MSDC30_1, "peri_msdc30_1", "msdc30_1_sel", 14),
668 GATE_PERI0(CLK_PERI_MSDC30_2, "peri_msdc30_2", "msdc30_2_sel", 15),
669 GATE_PERI0(CLK_PERI_MSDC30_3, "peri_msdc30_3", "msdc30_3_sel", 16),
670 GATE_PERI0(CLK_PERI_NLI_ARB, "peri_nli_arb", "axi_sel", 17),
671 GATE_PERI0(CLK_PERI_IRDA, "peri_irda", "irda_sel", 18),
672 GATE_PERI0(CLK_PERI_UART0, "peri_uart0", "axi_sel", 19),
673 GATE_PERI0(CLK_PERI_UART1, "peri_uart1", "axi_sel", 20),
674 GATE_PERI0(CLK_PERI_UART2, "peri_uart2", "axi_sel", 21),
675 GATE_PERI0(CLK_PERI_UART3, "peri_uart3", "axi_sel", 22),
676 GATE_PERI0(CLK_PERI_I2C0, "peri_i2c0", "axi_sel", 23),
677 GATE_PERI0(CLK_PERI_I2C1, "peri_i2c1", "axi_sel", 24),
678 GATE_PERI0(CLK_PERI_I2C2, "peri_i2c2", "axi_sel", 25),
679 GATE_PERI0(CLK_PERI_I2C3, "peri_i2c3", "axi_sel", 26),
680 GATE_PERI0(CLK_PERI_I2C4, "peri_i2c4", "axi_sel", 27),
681 GATE_PERI0(CLK_PERI_AUXADC, "peri_auxadc", "clk26m", 28),
682 GATE_PERI0(CLK_PERI_SPI0, "peri_spi0", "spi_sel", 29),
683 GATE_PERI0(CLK_PERI_I2C5, "peri_i2c5", "axi_sel", 30),
684 GATE_PERI0(CLK_PERI_NFIECC, "peri_nfiecc", "axi_sel", 31),
685 /* PERI1 */
686 GATE_PERI1(CLK_PERI_SPI, "peri_spi", "spi_sel", 0),
687 GATE_PERI1(CLK_PERI_IRRX, "peri_irrx", "spi_sel", 1),
688 GATE_PERI1(CLK_PERI_I2C6, "peri_i2c6", "axi_sel", 2),
689};
690
691static const char * const uart_ck_sel_parents[] __initconst = {
692 "clk26m",
693 "uart_sel",
694};
695
696static const struct mtk_composite peri_clks[] __initconst = {
697 MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1),
698 MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1),
699 MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1),
700 MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
701};
702
703static void __init mtk_topckgen_init(struct device_node *node)
704{
705 struct clk_onecell_data *clk_data;
706 void __iomem *base;
707 int r;
708
709 base = of_iomap(node, 0);
710 if (!base) {
711 pr_err("%s(): ioremap failed\n", __func__);
712 return;
713 }
714
715 clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
716
717 mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
718 mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
719 mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
720 &mt8173_clk_lock, clk_data);
721
722 clk_prepare_enable(clk_data->clks[CLK_TOP_CCI400_SEL]);
723
724 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
725 if (r)
726 pr_err("%s(): could not register clock provider: %d\n",
727 __func__, r);
728}
729CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8173-topckgen", mtk_topckgen_init);
730
731static void __init mtk_infrasys_init(struct device_node *node)
732{
733 struct clk_onecell_data *clk_data;
734 int r;
735
736 clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
737
738 mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
739 clk_data);
740
741 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
742 if (r)
743 pr_err("%s(): could not register clock provider: %d\n",
744 __func__, r);
745
746 mtk_register_reset_controller(node, 2, 0x30);
747}
748CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8173-infracfg", mtk_infrasys_init);
749
750static void __init mtk_pericfg_init(struct device_node *node)
751{
752 struct clk_onecell_data *clk_data;
753 int r;
754 void __iomem *base;
755
756 base = of_iomap(node, 0);
757 if (!base) {
758 pr_err("%s(): ioremap failed\n", __func__);
759 return;
760 }
761
762 clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
763
764 mtk_clk_register_gates(node, peri_gates, ARRAY_SIZE(peri_gates),
765 clk_data);
766 mtk_clk_register_composites(peri_clks, ARRAY_SIZE(peri_clks), base,
767 &mt8173_clk_lock, clk_data);
768
769 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
770 if (r)
771 pr_err("%s(): could not register clock provider: %d\n",
772 __func__, r);
773
774 mtk_register_reset_controller(node, 2, 0);
775}
776CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init);
777
778#define MT8173_PLL_FMAX (3000UL * MHZ)
779
780#define CON0_MT8173_RST_BAR BIT(24)
781
782#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, \
783 _tuner_reg, _pcw_reg, _pcw_shift) { \
784 .id = _id, \
785 .name = _name, \
786 .reg = _reg, \
787 .pwr_reg = _pwr_reg, \
788 .en_mask = _en_mask, \
789 .flags = _flags, \
790 .rst_bar_mask = CON0_MT8173_RST_BAR, \
791 .fmax = MT8173_PLL_FMAX, \
792 .pcwbits = _pcwbits, \
793 .pd_reg = _pd_reg, \
794 .pd_shift = _pd_shift, \
795 .tuner_reg = _tuner_reg, \
796 .pcw_reg = _pcw_reg, \
797 .pcw_shift = _pcw_shift, \
798 }
799
800static const struct mtk_pll_data plls[] = {
801 PLL(CLK_APMIXED_ARMCA15PLL, "armca15pll", 0x200, 0x20c, 0x00000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
802 PLL(CLK_APMIXED_ARMCA7PLL, "armca7pll", 0x210, 0x21c, 0x00000001, 0, 21, 0x214, 24, 0x0, 0x214, 0),
803 PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x220, 0x22c, 0xf0000101, HAVE_RST_BAR, 21, 0x220, 4, 0x0, 0x224, 0),
804 PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x230, 0x23c, 0xfe000001, HAVE_RST_BAR, 7, 0x230, 4, 0x0, 0x234, 14),
805 PLL(CLK_APMIXED_MMPLL, "mmpll", 0x240, 0x24c, 0x00000001, 0, 21, 0x244, 24, 0x0, 0x244, 0),
806 PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x250, 0x25c, 0x00000001, 0, 21, 0x250, 4, 0x0, 0x254, 0),
807 PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x260, 0x26c, 0x00000001, 0, 21, 0x260, 4, 0x0, 0x264, 0),
808 PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x270, 0x27c, 0x00000001, 0, 21, 0x270, 4, 0x0, 0x274, 0),
809 PLL(CLK_APMIXED_MPLL, "mpll", 0x280, 0x28c, 0x00000001, 0, 21, 0x280, 4, 0x0, 0x284, 0),
810 PLL(CLK_APMIXED_VCODECPLL, "vcodecpll", 0x290, 0x29c, 0x00000001, 0, 21, 0x290, 4, 0x0, 0x294, 0),
811 PLL(CLK_APMIXED_APLL1, "apll1", 0x2a0, 0x2b0, 0x00000001, 0, 31, 0x2a0, 4, 0x2a4, 0x2a4, 0),
812 PLL(CLK_APMIXED_APLL2, "apll2", 0x2b4, 0x2c4, 0x00000001, 0, 31, 0x2b4, 4, 0x2b8, 0x2b8, 0),
813 PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x2d0, 0x2dc, 0x00000001, 0, 21, 0x2d0, 4, 0x0, 0x2d4, 0),
814 PLL(CLK_APMIXED_MSDCPLL2, "msdcpll2", 0x2f0, 0x2fc, 0x00000001, 0, 21, 0x2f0, 4, 0x0, 0x2f4, 0),
815};
816
817static void __init mtk_apmixedsys_init(struct device_node *node)
818{
819 struct clk_onecell_data *clk_data;
820
821 clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
822 if (!clk_data)
823 return;
824
825 mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
826
827 clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMCA15PLL]);
828}
829CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys",
830 mtk_apmixedsys_init);
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
new file mode 100644
index 000000000000..18444aea63c9
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -0,0 +1,220 @@
1/*
2 * Copyright (c) 2014 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/of.h>
16#include <linux/of_address.h>
17#include <linux/err.h>
18#include <linux/io.h>
19#include <linux/slab.h>
20#include <linux/delay.h>
21#include <linux/clkdev.h>
22#include <linux/mfd/syscon.h>
23
24#include "clk-mtk.h"
25#include "clk-gate.h"
26
27struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
28{
29 int i;
30 struct clk_onecell_data *clk_data;
31
32 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
33 if (!clk_data)
34 return NULL;
35
36 clk_data->clks = kcalloc(clk_num, sizeof(*clk_data->clks), GFP_KERNEL);
37 if (!clk_data->clks)
38 goto err_out;
39
40 clk_data->clk_num = clk_num;
41
42 for (i = 0; i < clk_num; i++)
43 clk_data->clks[i] = ERR_PTR(-ENOENT);
44
45 return clk_data;
46err_out:
47 kfree(clk_data);
48
49 return NULL;
50}
51
52void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
53 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_factor *ff = &clks[i];
60
61 clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
62 CLK_SET_RATE_PARENT, ff->mult, ff->div);
63
64 if (IS_ERR(clk)) {
65 pr_err("Failed to register clk %s: %ld\n",
66 ff->name, PTR_ERR(clk));
67 continue;
68 }
69
70 if (clk_data)
71 clk_data->clks[ff->id] = clk;
72 }
73}
74
75int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks,
76 int num, struct clk_onecell_data *clk_data)
77{
78 int i;
79 struct clk *clk;
80 struct regmap *regmap;
81
82 if (!clk_data)
83 return -ENOMEM;
84
85 regmap = syscon_node_to_regmap(node);
86 if (IS_ERR(regmap)) {
87 pr_err("Cannot find regmap for %s: %ld\n", node->full_name,
88 PTR_ERR(regmap));
89 return PTR_ERR(regmap);
90 }
91
92 for (i = 0; i < num; i++) {
93 const struct mtk_gate *gate = &clks[i];
94
95 clk = mtk_clk_register_gate(gate->name, gate->parent_name,
96 regmap,
97 gate->regs->set_ofs,
98 gate->regs->clr_ofs,
99 gate->regs->sta_ofs,
100 gate->shift, gate->ops);
101
102 if (IS_ERR(clk)) {
103 pr_err("Failed to register clk %s: %ld\n",
104 gate->name, PTR_ERR(clk));
105 continue;
106 }
107
108 clk_data->clks[gate->id] = clk;
109 }
110
111 return 0;
112}
113
114struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
115 void __iomem *base, spinlock_t *lock)
116{
117 struct clk *clk;
118 struct clk_mux *mux = NULL;
119 struct clk_gate *gate = NULL;
120 struct clk_divider *div = NULL;
121 struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *div_hw = NULL;
122 const struct clk_ops *mux_ops = NULL, *gate_ops = NULL, *div_ops = NULL;
123 const char * const *parent_names;
124 const char *parent;
125 int num_parents;
126 int ret;
127
128 if (mc->mux_shift >= 0) {
129 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
130 if (!mux)
131 return ERR_PTR(-ENOMEM);
132
133 mux->reg = base + mc->mux_reg;
134 mux->mask = BIT(mc->mux_width) - 1;
135 mux->shift = mc->mux_shift;
136 mux->lock = lock;
137
138 mux_hw = &mux->hw;
139 mux_ops = &clk_mux_ops;
140
141 parent_names = mc->parent_names;
142 num_parents = mc->num_parents;
143 } else {
144 parent = mc->parent;
145 parent_names = &parent;
146 num_parents = 1;
147 }
148
149 if (mc->gate_shift >= 0) {
150 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
151 if (!gate) {
152 ret = -ENOMEM;
153 goto err_out;
154 }
155
156 gate->reg = base + mc->gate_reg;
157 gate->bit_idx = mc->gate_shift;
158 gate->flags = CLK_GATE_SET_TO_DISABLE;
159 gate->lock = lock;
160
161 gate_hw = &gate->hw;
162 gate_ops = &clk_gate_ops;
163 }
164
165 if (mc->divider_shift >= 0) {
166 div = kzalloc(sizeof(*div), GFP_KERNEL);
167 if (!div) {
168 ret = -ENOMEM;
169 goto err_out;
170 }
171
172 div->reg = base + mc->divider_reg;
173 div->shift = mc->divider_shift;
174 div->width = mc->divider_width;
175 div->lock = lock;
176
177 div_hw = &div->hw;
178 div_ops = &clk_divider_ops;
179 }
180
181 clk = clk_register_composite(NULL, mc->name, parent_names, num_parents,
182 mux_hw, mux_ops,
183 div_hw, div_ops,
184 gate_hw, gate_ops,
185 mc->flags);
186
187 if (IS_ERR(clk)) {
188 kfree(gate);
189 kfree(mux);
190 }
191
192 return clk;
193err_out:
194 kfree(mux);
195
196 return ERR_PTR(ret);
197}
198
199void mtk_clk_register_composites(const struct mtk_composite *mcs,
200 int num, void __iomem *base, spinlock_t *lock,
201 struct clk_onecell_data *clk_data)
202{
203 struct clk *clk;
204 int i;
205
206 for (i = 0; i < num; i++) {
207 const struct mtk_composite *mc = &mcs[i];
208
209 clk = mtk_clk_register_composite(mc, base, lock);
210
211 if (IS_ERR(clk)) {
212 pr_err("Failed to register clk %s: %ld\n",
213 mc->name, PTR_ERR(clk));
214 continue;
215 }
216
217 if (clk_data)
218 clk_data->clks[mc->id] = clk;
219 }
220}
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
new file mode 100644
index 000000000000..9dda9d8ad10b
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -0,0 +1,169 @@
1/*
2 * Copyright (c) 2014 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#ifndef __DRV_CLK_MTK_H
16#define __DRV_CLK_MTK_H
17
18#include <linux/regmap.h>
19#include <linux/bitops.h>
20#include <linux/clk.h>
21#include <linux/clk-provider.h>
22
23#define MAX_MUX_GATE_BIT 31
24#define INVALID_MUX_GATE_BIT (MAX_MUX_GATE_BIT + 1)
25
26#define MHZ (1000 * 1000)
27
28struct mtk_fixed_factor {
29 int id;
30 const char *name;
31 const char *parent_name;
32 int mult;
33 int div;
34};
35
36#define FACTOR(_id, _name, _parent, _mult, _div) { \
37 .id = _id, \
38 .name = _name, \
39 .parent_name = _parent, \
40 .mult = _mult, \
41 .div = _div, \
42 }
43
44extern void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
45 int num, struct clk_onecell_data *clk_data);
46
47struct mtk_composite {
48 int id;
49 const char *name;
50 const char * const *parent_names;
51 const char *parent;
52 unsigned flags;
53
54 uint32_t mux_reg;
55 uint32_t divider_reg;
56 uint32_t gate_reg;
57
58 signed char mux_shift;
59 signed char mux_width;
60 signed char gate_shift;
61
62 signed char divider_shift;
63 signed char divider_width;
64
65 signed char num_parents;
66};
67
68#define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate) { \
69 .id = _id, \
70 .name = _name, \
71 .mux_reg = _reg, \
72 .mux_shift = _shift, \
73 .mux_width = _width, \
74 .gate_reg = _reg, \
75 .gate_shift = _gate, \
76 .divider_shift = -1, \
77 .parent_names = _parents, \
78 .num_parents = ARRAY_SIZE(_parents), \
79 .flags = CLK_SET_RATE_PARENT, \
80 }
81
82#define MUX(_id, _name, _parents, _reg, _shift, _width) { \
83 .id = _id, \
84 .name = _name, \
85 .mux_reg = _reg, \
86 .mux_shift = _shift, \
87 .mux_width = _width, \
88 .gate_shift = -1, \
89 .divider_shift = -1, \
90 .parent_names = _parents, \
91 .num_parents = ARRAY_SIZE(_parents), \
92 .flags = CLK_SET_RATE_PARENT, \
93 }
94
95#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \
96 .id = _id, \
97 .parent = _parent, \
98 .name = _name, \
99 .divider_reg = _div_reg, \
100 .divider_shift = _div_shift, \
101 .divider_width = _div_width, \
102 .gate_reg = _gate_reg, \
103 .gate_shift = _gate_shift, \
104 .mux_shift = -1, \
105 .flags = 0, \
106 }
107
108struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
109 void __iomem *base, spinlock_t *lock);
110
111void mtk_clk_register_composites(const struct mtk_composite *mcs,
112 int num, void __iomem *base, spinlock_t *lock,
113 struct clk_onecell_data *clk_data);
114
115struct mtk_gate_regs {
116 u32 sta_ofs;
117 u32 clr_ofs;
118 u32 set_ofs;
119};
120
121struct mtk_gate {
122 int id;
123 const char *name;
124 const char *parent_name;
125 const struct mtk_gate_regs *regs;
126 int shift;
127 const struct clk_ops *ops;
128};
129
130int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks,
131 int num, struct clk_onecell_data *clk_data);
132
133struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
134
135#define HAVE_RST_BAR BIT(0)
136
137struct mtk_pll_data {
138 int id;
139 const char *name;
140 uint32_t reg;
141 uint32_t pwr_reg;
142 uint32_t en_mask;
143 uint32_t pd_reg;
144 uint32_t tuner_reg;
145 int pd_shift;
146 unsigned int flags;
147 const struct clk_ops *ops;
148 u32 rst_bar_mask;
149 unsigned long fmax;
150 int pcwbits;
151 uint32_t pcw_reg;
152 int pcw_shift;
153};
154
155void __init mtk_clk_register_plls(struct device_node *node,
156 const struct mtk_pll_data *plls, int num_plls,
157 struct clk_onecell_data *clk_data);
158
159#ifdef CONFIG_RESET_CONTROLLER
160void mtk_register_reset_controller(struct device_node *np,
161 unsigned int num_regs, int regofs);
162#else
163static inline void mtk_register_reset_controller(struct device_node *np,
164 unsigned int num_regs, int regofs)
165{
166}
167#endif
168
169#endif /* __DRV_CLK_MTK_H */
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
new file mode 100644
index 000000000000..44409e98c52f
--- /dev/null
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -0,0 +1,332 @@
1/*
2 * Copyright (c) 2014 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/of.h>
16#include <linux/of_address.h>
17#include <linux/io.h>
18#include <linux/slab.h>
19#include <linux/clkdev.h>
20#include <linux/delay.h>
21
22#include "clk-mtk.h"
23
24#define REG_CON0 0
25#define REG_CON1 4
26
27#define CON0_BASE_EN BIT(0)
28#define CON0_PWR_ON BIT(0)
29#define CON0_ISO_EN BIT(1)
30#define CON0_PCW_CHG BIT(31)
31
32#define AUDPLL_TUNER_EN BIT(31)
33
34#define POSTDIV_MASK 0x7
35#define INTEGER_BITS 7
36
37/*
38 * MediaTek PLLs are configured through their pcw value. The pcw value describes
39 * a divider in the PLL feedback loop which consists of 7 bits for the integer
40 * part and the remaining bits (if present) for the fractional part. Also they
41 * have a 3 bit power-of-two post divider.
42 */
43
44struct mtk_clk_pll {
45 struct clk_hw hw;
46 void __iomem *base_addr;
47 void __iomem *pd_addr;
48 void __iomem *pwr_addr;
49 void __iomem *tuner_addr;
50 void __iomem *pcw_addr;
51 const struct mtk_pll_data *data;
52};
53
54static inline struct mtk_clk_pll *to_mtk_clk_pll(struct clk_hw *hw)
55{
56 return container_of(hw, struct mtk_clk_pll, hw);
57}
58
59static int mtk_pll_is_prepared(struct clk_hw *hw)
60{
61 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
62
63 return (readl(pll->base_addr + REG_CON0) & CON0_BASE_EN) != 0;
64}
65
66static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
67 u32 pcw, int postdiv)
68{
69 int pcwbits = pll->data->pcwbits;
70 int pcwfbits;
71 u64 vco;
72 u8 c = 0;
73
74 /* The fractional part of the PLL divider. */
75 pcwfbits = pcwbits > INTEGER_BITS ? pcwbits - INTEGER_BITS : 0;
76
77 vco = (u64)fin * pcw;
78
79 if (pcwfbits && (vco & GENMASK(pcwfbits - 1, 0)))
80 c = 1;
81
82 vco >>= pcwfbits;
83
84 if (c)
85 vco++;
86
87 return ((unsigned long)vco + postdiv - 1) / postdiv;
88}
89
90static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
91 int postdiv)
92{
93 u32 con1, pd, val;
94 int pll_en;
95
96 /* set postdiv */
97 pd = readl(pll->pd_addr);
98 pd &= ~(POSTDIV_MASK << pll->data->pd_shift);
99 pd |= (ffs(postdiv) - 1) << pll->data->pd_shift;
100 writel(pd, pll->pd_addr);
101
102 pll_en = readl(pll->base_addr + REG_CON0) & CON0_BASE_EN;
103
104 /* set pcw */
105 val = readl(pll->pcw_addr);
106
107 val &= ~GENMASK(pll->data->pcw_shift + pll->data->pcwbits - 1,
108 pll->data->pcw_shift);
109 val |= pcw << pll->data->pcw_shift;
110 writel(val, pll->pcw_addr);
111
112 con1 = readl(pll->base_addr + REG_CON1);
113
114 if (pll_en)
115 con1 |= CON0_PCW_CHG;
116
117 writel(con1, pll->base_addr + REG_CON1);
118 if (pll->tuner_addr)
119 writel(con1 + 1, pll->tuner_addr);
120
121 if (pll_en)
122 udelay(20);
123}
124
125/*
126 * mtk_pll_calc_values - calculate good values for a given input frequency.
127 * @pll: The pll
128 * @pcw: The pcw value (output)
129 * @postdiv: The post divider (output)
130 * @freq: The desired target frequency
131 * @fin: The input frequency
132 *
133 */
134static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
135 u32 freq, u32 fin)
136{
137 unsigned long fmin = 1000 * MHZ;
138 u64 _pcw;
139 u32 val;
140
141 if (freq > pll->data->fmax)
142 freq = pll->data->fmax;
143
144 for (val = 0; val < 4; val++) {
145 *postdiv = 1 << val;
146 if (freq * *postdiv >= fmin)
147 break;
148 }
149
150 /* _pcw = freq * postdiv / fin * 2^pcwfbits */
151 _pcw = ((u64)freq << val) << (pll->data->pcwbits - INTEGER_BITS);
152 do_div(_pcw, fin);
153
154 *pcw = (u32)_pcw;
155}
156
157static int mtk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
158 unsigned long parent_rate)
159{
160 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
161 u32 pcw = 0;
162 u32 postdiv;
163
164 mtk_pll_calc_values(pll, &pcw, &postdiv, rate, parent_rate);
165 mtk_pll_set_rate_regs(pll, pcw, postdiv);
166
167 return 0;
168}
169
170static unsigned long mtk_pll_recalc_rate(struct clk_hw *hw,
171 unsigned long parent_rate)
172{
173 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
174 u32 postdiv;
175 u32 pcw;
176
177 postdiv = (readl(pll->pd_addr) >> pll->data->pd_shift) & POSTDIV_MASK;
178 postdiv = 1 << postdiv;
179
180 pcw = readl(pll->pcw_addr) >> pll->data->pcw_shift;
181 pcw &= GENMASK(pll->data->pcwbits - 1, 0);
182
183 return __mtk_pll_recalc_rate(pll, parent_rate, pcw, postdiv);
184}
185
186static long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
187 unsigned long *prate)
188{
189 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
190 u32 pcw = 0;
191 int postdiv;
192
193 mtk_pll_calc_values(pll, &pcw, &postdiv, rate, *prate);
194
195 return __mtk_pll_recalc_rate(pll, *prate, pcw, postdiv);
196}
197
198static int mtk_pll_prepare(struct clk_hw *hw)
199{
200 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
201 u32 r;
202
203 r = readl(pll->pwr_addr) | CON0_PWR_ON;
204 writel(r, pll->pwr_addr);
205 udelay(1);
206
207 r = readl(pll->pwr_addr) & ~CON0_ISO_EN;
208 writel(r, pll->pwr_addr);
209 udelay(1);
210
211 r = readl(pll->base_addr + REG_CON0);
212 r |= pll->data->en_mask;
213 writel(r, pll->base_addr + REG_CON0);
214
215 if (pll->tuner_addr) {
216 r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN;
217 writel(r, pll->tuner_addr);
218 }
219
220 udelay(20);
221
222 if (pll->data->flags & HAVE_RST_BAR) {
223 r = readl(pll->base_addr + REG_CON0);
224 r |= pll->data->rst_bar_mask;
225 writel(r, pll->base_addr + REG_CON0);
226 }
227
228 return 0;
229}
230
231static void mtk_pll_unprepare(struct clk_hw *hw)
232{
233 struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
234 u32 r;
235
236 if (pll->data->flags & HAVE_RST_BAR) {
237 r = readl(pll->base_addr + REG_CON0);
238 r &= ~pll->data->rst_bar_mask;
239 writel(r, pll->base_addr + REG_CON0);
240 }
241
242 if (pll->tuner_addr) {
243 r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN;
244 writel(r, pll->tuner_addr);
245 }
246
247 r = readl(pll->base_addr + REG_CON0);
248 r &= ~CON0_BASE_EN;
249 writel(r, pll->base_addr + REG_CON0);
250
251 r = readl(pll->pwr_addr) | CON0_ISO_EN;
252 writel(r, pll->pwr_addr);
253
254 r = readl(pll->pwr_addr) & ~CON0_PWR_ON;
255 writel(r, pll->pwr_addr);
256}
257
258static const struct clk_ops mtk_pll_ops = {
259 .is_prepared = mtk_pll_is_prepared,
260 .prepare = mtk_pll_prepare,
261 .unprepare = mtk_pll_unprepare,
262 .recalc_rate = mtk_pll_recalc_rate,
263 .round_rate = mtk_pll_round_rate,
264 .set_rate = mtk_pll_set_rate,
265};
266
267static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
268 void __iomem *base)
269{
270 struct mtk_clk_pll *pll;
271 struct clk_init_data init = {};
272 struct clk *clk;
273 const char *parent_name = "clk26m";
274
275 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
276 if (!pll)
277 return ERR_PTR(-ENOMEM);
278
279 pll->base_addr = base + data->reg;
280 pll->pwr_addr = base + data->pwr_reg;
281 pll->pd_addr = base + data->pd_reg;
282 pll->pcw_addr = base + data->pcw_reg;
283 if (data->tuner_reg)
284 pll->tuner_addr = base + data->tuner_reg;
285 pll->hw.init = &init;
286 pll->data = data;
287
288 init.name = data->name;
289 init.ops = &mtk_pll_ops;
290 init.parent_names = &parent_name;
291 init.num_parents = 1;
292
293 clk = clk_register(NULL, &pll->hw);
294
295 if (IS_ERR(clk))
296 kfree(pll);
297
298 return clk;
299}
300
301void __init mtk_clk_register_plls(struct device_node *node,
302 const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
303{
304 void __iomem *base;
305 int r, i;
306 struct clk *clk;
307
308 base = of_iomap(node, 0);
309 if (!base) {
310 pr_err("%s(): ioremap failed\n", __func__);
311 return;
312 }
313
314 for (i = 0; i < num_plls; i++) {
315 const struct mtk_pll_data *pll = &plls[i];
316
317 clk = mtk_clk_register_pll(pll, base);
318
319 if (IS_ERR(clk)) {
320 pr_err("Failed to register clk %s: %ld\n",
321 pll->name, PTR_ERR(clk));
322 continue;
323 }
324
325 clk_data->clks[pll->id] = clk;
326 }
327
328 r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
329 if (r)
330 pr_err("%s(): could not register clock provider: %d\n",
331 __func__, r);
332}
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
new file mode 100644
index 000000000000..9e9fe4b19ac4
--- /dev/null
+++ b/drivers/clk/mediatek/reset.c
@@ -0,0 +1,97 @@
1/*
2 * Copyright (c) 2014 MediaTek Inc.
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 * 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/mfd/syscon.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/platform_device.h>
18#include <linux/regmap.h>
19#include <linux/reset-controller.h>
20#include <linux/slab.h>
21
22#include "clk-mtk.h"
23
24struct mtk_reset {
25 struct regmap *regmap;
26 int regofs;
27 struct reset_controller_dev rcdev;
28};
29
30static int mtk_reset_assert(struct reset_controller_dev *rcdev,
31 unsigned long id)
32{
33 struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
34
35 return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
36 BIT(id % 32), ~0);
37}
38
39static int mtk_reset_deassert(struct reset_controller_dev *rcdev,
40 unsigned long id)
41{
42 struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
43
44 return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
45 BIT(id % 32), 0);
46}
47
48static int mtk_reset(struct reset_controller_dev *rcdev,
49 unsigned long id)
50{
51 int ret;
52
53 ret = mtk_reset_assert(rcdev, id);
54 if (ret)
55 return ret;
56
57 return mtk_reset_deassert(rcdev, id);
58}
59
60static struct reset_control_ops mtk_reset_ops = {
61 .assert = mtk_reset_assert,
62 .deassert = mtk_reset_deassert,
63 .reset = mtk_reset,
64};
65
66void mtk_register_reset_controller(struct device_node *np,
67 unsigned int num_regs, int regofs)
68{
69 struct mtk_reset *data;
70 int ret;
71 struct regmap *regmap;
72
73 regmap = syscon_node_to_regmap(np);
74 if (IS_ERR(regmap)) {
75 pr_err("Cannot find regmap for %s: %ld\n", np->full_name,
76 PTR_ERR(regmap));
77 return;
78 }
79
80 data = kzalloc(sizeof(*data), GFP_KERNEL);
81 if (!data)
82 return;
83
84 data->regmap = regmap;
85 data->regofs = regofs;
86 data->rcdev.owner = THIS_MODULE;
87 data->rcdev.nr_resets = num_regs * 32;
88 data->rcdev.ops = &mtk_reset_ops;
89 data->rcdev.of_node = np;
90
91 ret = reset_controller_register(&data->rcdev);
92 if (ret) {
93 pr_err("could not register reset controller: %d\n", ret);
94 kfree(data);
95 return;
96 }
97}
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
new file mode 100644
index 000000000000..6d45531df9ab
--- /dev/null
+++ b/drivers/clk/meson/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for Meson specific clk
3#
4
5obj-y += clkc.o clk-pll.o clk-cpu.o
6obj-y += meson8b-clkc.o
diff --git a/drivers/clk/meson/clk-cpu.c b/drivers/clk/meson/clk-cpu.c
new file mode 100644
index 000000000000..71ad493b94df
--- /dev/null
+++ b/drivers/clk/meson/clk-cpu.c
@@ -0,0 +1,242 @@
1/*
2 * Copyright (c) 2015 Endless Mobile, Inc.
3 * Author: Carlo Caione <carlo@endlessm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * CPU clock path:
20 *
21 * +-[/N]-----|3|
22 * MUX2 +--[/3]-+----------|2| MUX1
23 * [sys_pll]---|1| |--[/2]------------|1|-|1|
24 * | |---+------------------|0| | |----- [a5_clk]
25 * +--|0| | |
26 * [xtal]---+-------------------------------|0|
27 *
28 *
29 *
30 */
31
32#include <linux/delay.h>
33#include <linux/err.h>
34#include <linux/io.h>
35#include <linux/module.h>
36#include <linux/of_address.h>
37#include <linux/slab.h>
38#include <linux/clk-provider.h>
39
40#define MESON_CPU_CLK_CNTL1 0x00
41#define MESON_CPU_CLK_CNTL 0x40
42
43#define MESON_CPU_CLK_MUX1 BIT(7)
44#define MESON_CPU_CLK_MUX2 BIT(0)
45
46#define MESON_N_WIDTH 9
47#define MESON_N_SHIFT 20
48#define MESON_SEL_WIDTH 2
49#define MESON_SEL_SHIFT 2
50
51#include "clkc.h"
52
53struct meson_clk_cpu {
54 struct notifier_block clk_nb;
55 const struct clk_div_table *div_table;
56 struct clk_hw hw;
57 void __iomem *base;
58 u16 reg_off;
59};
60#define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw)
61#define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb)
62
63static long meson_clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
64 unsigned long *prate)
65{
66 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
67
68 return divider_round_rate(hw, rate, prate, clk_cpu->div_table,
69 MESON_N_WIDTH, CLK_DIVIDER_ROUND_CLOSEST);
70}
71
72static int meson_clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
73 unsigned long parent_rate)
74{
75 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
76 unsigned int div, sel, N = 0;
77 u32 reg;
78
79 div = DIV_ROUND_UP(parent_rate, rate);
80
81 if (div <= 3) {
82 sel = div - 1;
83 } else {
84 sel = 3;
85 N = div / 2;
86 }
87
88 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
89 reg = PARM_SET(MESON_N_WIDTH, MESON_N_SHIFT, reg, N);
90 writel(reg, clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
91
92 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
93 reg = PARM_SET(MESON_SEL_WIDTH, MESON_SEL_SHIFT, reg, sel);
94 writel(reg, clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
95
96 return 0;
97}
98
99static unsigned long meson_clk_cpu_recalc_rate(struct clk_hw *hw,
100 unsigned long parent_rate)
101{
102 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
103 unsigned int N, sel;
104 unsigned int div = 1;
105 u32 reg;
106
107 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
108 N = PARM_GET(MESON_N_WIDTH, MESON_N_SHIFT, reg);
109
110 reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
111 sel = PARM_GET(MESON_SEL_WIDTH, MESON_SEL_SHIFT, reg);
112
113 if (sel < 3)
114 div = sel + 1;
115 else
116 div = 2 * N;
117
118 return parent_rate / div;
119}
120
121static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
122 struct clk_notifier_data *ndata)
123{
124 u32 cpu_clk_cntl;
125
126 /* switch MUX1 to xtal */
127 cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
128 + MESON_CPU_CLK_CNTL);
129 cpu_clk_cntl &= ~MESON_CPU_CLK_MUX1;
130 writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
131 + MESON_CPU_CLK_CNTL);
132 udelay(100);
133
134 /* switch MUX2 to sys-pll */
135 cpu_clk_cntl |= MESON_CPU_CLK_MUX2;
136 writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
137 + MESON_CPU_CLK_CNTL);
138
139 return 0;
140}
141
142static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
143 struct clk_notifier_data *ndata)
144{
145 u32 cpu_clk_cntl;
146
147 /* switch MUX1 to divisors' output */
148 cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
149 + MESON_CPU_CLK_CNTL);
150 cpu_clk_cntl |= MESON_CPU_CLK_MUX1;
151 writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
152 + MESON_CPU_CLK_CNTL);
153 udelay(100);
154
155 return 0;
156}
157
158/*
159 * This clock notifier is called when the frequency of the of the parent
160 * PLL clock is to be changed. We use the xtal input as temporary parent
161 * while the PLL frequency is stabilized.
162 */
163static int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
164 unsigned long event, void *data)
165{
166 struct clk_notifier_data *ndata = data;
167 struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_nb(nb);
168 int ret = 0;
169
170 if (event == PRE_RATE_CHANGE)
171 ret = meson_clk_cpu_pre_rate_change(clk_cpu, ndata);
172 else if (event == POST_RATE_CHANGE)
173 ret = meson_clk_cpu_post_rate_change(clk_cpu, ndata);
174
175 return notifier_from_errno(ret);
176}
177
178static const struct clk_ops meson_clk_cpu_ops = {
179 .recalc_rate = meson_clk_cpu_recalc_rate,
180 .round_rate = meson_clk_cpu_round_rate,
181 .set_rate = meson_clk_cpu_set_rate,
182};
183
184struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
185 void __iomem *reg_base,
186 spinlock_t *lock)
187{
188 struct clk *clk;
189 struct clk *pclk;
190 struct meson_clk_cpu *clk_cpu;
191 struct clk_init_data init;
192 int ret;
193
194 clk_cpu = kzalloc(sizeof(*clk_cpu), GFP_KERNEL);
195 if (!clk_cpu)
196 return ERR_PTR(-ENOMEM);
197
198 clk_cpu->base = reg_base;
199 clk_cpu->reg_off = clk_conf->reg_off;
200 clk_cpu->div_table = clk_conf->conf.div_table;
201 clk_cpu->clk_nb.notifier_call = meson_clk_cpu_notifier_cb;
202
203 init.name = clk_conf->clk_name;
204 init.ops = &meson_clk_cpu_ops;
205 init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE;
206 init.flags |= CLK_SET_RATE_PARENT;
207 init.parent_names = clk_conf->clks_parent;
208 init.num_parents = 1;
209
210 clk_cpu->hw.init = &init;
211
212 pclk = __clk_lookup(clk_conf->clks_parent[0]);
213 if (!pclk) {
214 pr_err("%s: could not lookup parent clock %s\n",
215 __func__, clk_conf->clks_parent[0]);
216 ret = -EINVAL;
217 goto free_clk;
218 }
219
220 ret = clk_notifier_register(pclk, &clk_cpu->clk_nb);
221 if (ret) {
222 pr_err("%s: failed to register clock notifier for %s\n",
223 __func__, clk_conf->clk_name);
224 goto free_clk;
225 }
226
227 clk = clk_register(NULL, &clk_cpu->hw);
228 if (IS_ERR(clk)) {
229 ret = PTR_ERR(clk);
230 goto unregister_clk_nb;
231 }
232
233 return clk;
234
235unregister_clk_nb:
236 clk_notifier_unregister(pclk, &clk_cpu->clk_nb);
237free_clk:
238 kfree(clk_cpu);
239
240 return ERR_PTR(ret);
241}
242
diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
new file mode 100644
index 000000000000..664edf0708ea
--- /dev/null
+++ b/drivers/clk/meson/clk-pll.c
@@ -0,0 +1,227 @@
1/*
2 * Copyright (c) 2015 Endless Mobile, Inc.
3 * Author: Carlo Caione <carlo@endlessm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * In the most basic form, a Meson PLL is composed as follows:
20 *
21 * PLL
22 * +------------------------------+
23 * | |
24 * in -----[ /N ]---[ *M ]---[ >>OD ]----->> out
25 * | ^ ^ |
26 * +------------------------------+
27 * | |
28 * FREF VCO
29 *
30 * out = (in * M / N) >> OD
31 */
32
33#include <linux/clk-provider.h>
34#include <linux/delay.h>
35#include <linux/err.h>
36#include <linux/io.h>
37#include <linux/module.h>
38#include <linux/of_address.h>
39#include <linux/slab.h>
40#include <linux/string.h>
41
42#include "clkc.h"
43
44#define MESON_PLL_RESET BIT(29)
45#define MESON_PLL_LOCK BIT(31)
46
47struct meson_clk_pll {
48 struct clk_hw hw;
49 void __iomem *base;
50 struct pll_conf *conf;
51 unsigned int rate_count;
52 spinlock_t *lock;
53};
54#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
55
56static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
57 unsigned long parent_rate)
58{
59 struct meson_clk_pll *pll = to_meson_clk_pll(hw);
60 struct parm *p;
61 unsigned long parent_rate_mhz = parent_rate / 1000000;
62 unsigned long rate_mhz;
63 u16 n, m, od;
64 u32 reg;
65
66 p = &pll->conf->n;
67 reg = readl(pll->base + p->reg_off);
68 n = PARM_GET(p->width, p->shift, reg);
69
70 p = &pll->conf->m;
71 reg = readl(pll->base + p->reg_off);
72 m = PARM_GET(p->width, p->shift, reg);
73
74 p = &pll->conf->od;
75 reg = readl(pll->base + p->reg_off);
76 od = PARM_GET(p->width, p->shift, reg);
77
78 rate_mhz = (parent_rate_mhz * m / n) >> od;
79
80 return rate_mhz * 1000000;
81}
82
83static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
84 unsigned long *parent_rate)
85{
86 struct meson_clk_pll *pll = to_meson_clk_pll(hw);
87 const struct pll_rate_table *rate_table = pll->conf->rate_table;
88 int i;
89
90 for (i = 0; i < pll->rate_count; i++) {
91 if (rate <= rate_table[i].rate)
92 return rate_table[i].rate;
93 }
94
95 /* else return the smallest value */
96 return rate_table[0].rate;
97}
98
99static const struct pll_rate_table *meson_clk_get_pll_settings(struct meson_clk_pll *pll,
100 unsigned long rate)
101{
102 const struct pll_rate_table *rate_table = pll->conf->rate_table;
103 int i;
104
105 for (i = 0; i < pll->rate_count; i++) {
106 if (rate == rate_table[i].rate)
107 return &rate_table[i];
108 }
109 return NULL;
110}
111
112static int meson_clk_pll_wait_lock(struct meson_clk_pll *pll,
113 struct parm *p_n)
114{
115 int delay = 24000000;
116 u32 reg;
117
118 while (delay > 0) {
119 reg = readl(pll->base + p_n->reg_off);
120
121 if (reg & MESON_PLL_LOCK)
122 return 0;
123 delay--;
124 }
125 return -ETIMEDOUT;
126}
127
128static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
129 unsigned long parent_rate)
130{
131 struct meson_clk_pll *pll = to_meson_clk_pll(hw);
132 struct parm *p;
133 const struct pll_rate_table *rate_set;
134 unsigned long old_rate;
135 int ret = 0;
136 u32 reg;
137
138 if (parent_rate == 0 || rate == 0)
139 return -EINVAL;
140
141 old_rate = rate;
142
143 rate_set = meson_clk_get_pll_settings(pll, rate);
144 if (!rate_set)
145 return -EINVAL;
146
147 /* PLL reset */
148 p = &pll->conf->n;
149 reg = readl(pll->base + p->reg_off);
150 writel(reg | MESON_PLL_RESET, pll->base + p->reg_off);
151
152 reg = PARM_SET(p->width, p->shift, reg, rate_set->n);
153 writel(reg, pll->base + p->reg_off);
154
155 p = &pll->conf->m;
156 reg = readl(pll->base + p->reg_off);
157 reg = PARM_SET(p->width, p->shift, reg, rate_set->m);
158 writel(reg, pll->base + p->reg_off);
159
160 p = &pll->conf->od;
161 reg = readl(pll->base + p->reg_off);
162 reg = PARM_SET(p->width, p->shift, reg, rate_set->od);
163 writel(reg, pll->base + p->reg_off);
164
165 p = &pll->conf->n;
166 ret = meson_clk_pll_wait_lock(pll, p);
167 if (ret) {
168 pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
169 __func__, old_rate);
170 meson_clk_pll_set_rate(hw, old_rate, parent_rate);
171 }
172
173 return ret;
174}
175
176static const struct clk_ops meson_clk_pll_ops = {
177 .recalc_rate = meson_clk_pll_recalc_rate,
178 .round_rate = meson_clk_pll_round_rate,
179 .set_rate = meson_clk_pll_set_rate,
180};
181
182static const struct clk_ops meson_clk_pll_ro_ops = {
183 .recalc_rate = meson_clk_pll_recalc_rate,
184};
185
186struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf,
187 void __iomem *reg_base,
188 spinlock_t *lock)
189{
190 struct clk *clk;
191 struct meson_clk_pll *clk_pll;
192 struct clk_init_data init;
193
194 clk_pll = kzalloc(sizeof(*clk_pll), GFP_KERNEL);
195 if (!clk_pll)
196 return ERR_PTR(-ENOMEM);
197
198 clk_pll->base = reg_base + clk_conf->reg_off;
199 clk_pll->lock = lock;
200 clk_pll->conf = clk_conf->conf.pll;
201
202 init.name = clk_conf->clk_name;
203 init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE;
204
205 init.parent_names = &clk_conf->clks_parent[0];
206 init.num_parents = 1;
207 init.ops = &meson_clk_pll_ro_ops;
208
209 /* If no rate_table is specified we assume the PLL is read-only */
210 if (clk_pll->conf->rate_table) {
211 int len;
212
213 for (len = 0; clk_pll->conf->rate_table[len].rate != 0; )
214 len++;
215
216 clk_pll->rate_count = len;
217 init.ops = &meson_clk_pll_ops;
218 }
219
220 clk_pll->hw.init = &init;
221
222 clk = clk_register(NULL, &clk_pll->hw);
223 if (IS_ERR(clk))
224 kfree(clk_pll);
225
226 return clk;
227}
diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c
new file mode 100644
index 000000000000..b8c511c5e7a7
--- /dev/null
+++ b/drivers/clk/meson/clkc.c
@@ -0,0 +1,250 @@
1/*
2 * Copyright (c) 2015 Endless Mobile, Inc.
3 * Author: Carlo Caione <carlo@endlessm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <linux/clk.h>
19#include <linux/clk-provider.h>
20#include <linux/mfd/syscon.h>
21#include <linux/slab.h>
22
23#include "clkc.h"
24
25static DEFINE_SPINLOCK(clk_lock);
26
27static struct clk **clks;
28static struct clk_onecell_data clk_data;
29
30struct clk ** __init meson_clk_init(struct device_node *np,
31 unsigned long nr_clks)
32{
33 clks = kcalloc(nr_clks, sizeof(*clks), GFP_KERNEL);
34 if (!clks)
35 return ERR_PTR(-ENOMEM);
36
37 clk_data.clks = clks;
38 clk_data.clk_num = nr_clks;
39 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
40
41 return clks;
42}
43
44static void meson_clk_add_lookup(struct clk *clk, unsigned int id)
45{
46 if (clks && id)
47 clks[id] = clk;
48}
49
50static struct clk * __init
51meson_clk_register_composite(const struct clk_conf *clk_conf,
52 void __iomem *clk_base)
53{
54 struct clk *clk;
55 struct clk_mux *mux = NULL;
56 struct clk_divider *div = NULL;
57 struct clk_gate *gate = NULL;
58 const struct clk_ops *mux_ops = NULL;
59 const struct composite_conf *composite_conf;
60
61 composite_conf = clk_conf->conf.composite;
62
63 if (clk_conf->num_parents > 1) {
64 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
65 if (!mux)
66 return ERR_PTR(-ENOMEM);
67
68 mux->reg = clk_base + clk_conf->reg_off
69 + composite_conf->mux_parm.reg_off;
70 mux->shift = composite_conf->mux_parm.shift;
71 mux->mask = BIT(composite_conf->mux_parm.width) - 1;
72 mux->flags = composite_conf->mux_flags;
73 mux->lock = &clk_lock;
74 mux->table = composite_conf->mux_table;
75 mux_ops = (composite_conf->mux_flags & CLK_MUX_READ_ONLY) ?
76 &clk_mux_ro_ops : &clk_mux_ops;
77 }
78
79 if (MESON_PARM_APPLICABLE(&composite_conf->div_parm)) {
80 div = kzalloc(sizeof(*div), GFP_KERNEL);
81 if (!div) {
82 clk = ERR_PTR(-ENOMEM);
83 goto error;
84 }
85
86 div->reg = clk_base + clk_conf->reg_off
87 + composite_conf->div_parm.reg_off;
88 div->shift = composite_conf->div_parm.shift;
89 div->width = composite_conf->div_parm.width;
90 div->lock = &clk_lock;
91 div->flags = composite_conf->div_flags;
92 div->table = composite_conf->div_table;
93 }
94
95 if (MESON_PARM_APPLICABLE(&composite_conf->gate_parm)) {
96 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
97 if (!gate) {
98 clk = ERR_PTR(-ENOMEM);
99 goto error;
100 }
101
102 gate->reg = clk_base + clk_conf->reg_off
103 + composite_conf->div_parm.reg_off;
104 gate->bit_idx = composite_conf->gate_parm.shift;
105 gate->flags = composite_conf->gate_flags;
106 gate->lock = &clk_lock;
107 }
108
109 clk = clk_register_composite(NULL, clk_conf->clk_name,
110 clk_conf->clks_parent,
111 clk_conf->num_parents,
112 mux ? &mux->hw : NULL, mux_ops,
113 div ? &div->hw : NULL, &clk_divider_ops,
114 gate ? &gate->hw : NULL, &clk_gate_ops,
115 clk_conf->flags);
116 if (IS_ERR(clk))
117 goto error;
118
119 return clk;
120
121error:
122 kfree(gate);
123 kfree(div);
124 kfree(mux);
125
126 return clk;
127}
128
129static struct clk * __init
130meson_clk_register_fixed_factor(const struct clk_conf *clk_conf,
131 void __iomem *clk_base)
132{
133 struct clk *clk;
134 const struct fixed_fact_conf *fixed_fact_conf;
135 const struct parm *p;
136 unsigned int mult, div;
137 u32 reg;
138
139 fixed_fact_conf = &clk_conf->conf.fixed_fact;
140
141 mult = clk_conf->conf.fixed_fact.mult;
142 div = clk_conf->conf.fixed_fact.div;
143
144 if (!mult) {
145 mult = 1;
146 p = &fixed_fact_conf->mult_parm;
147 if (MESON_PARM_APPLICABLE(p)) {
148 reg = readl(clk_base + clk_conf->reg_off + p->reg_off);
149 mult = PARM_GET(p->width, p->shift, reg);
150 }
151 }
152
153 if (!div) {
154 div = 1;
155 p = &fixed_fact_conf->div_parm;
156 if (MESON_PARM_APPLICABLE(p)) {
157 reg = readl(clk_base + clk_conf->reg_off + p->reg_off);
158 mult = PARM_GET(p->width, p->shift, reg);
159 }
160 }
161
162 clk = clk_register_fixed_factor(NULL,
163 clk_conf->clk_name,
164 clk_conf->clks_parent[0],
165 clk_conf->flags,
166 mult, div);
167
168 return clk;
169}
170
171static struct clk * __init
172meson_clk_register_fixed_rate(const struct clk_conf *clk_conf,
173 void __iomem *clk_base)
174{
175 struct clk *clk;
176 const struct fixed_rate_conf *fixed_rate_conf;
177 const struct parm *r;
178 unsigned long rate;
179 u32 reg;
180
181 fixed_rate_conf = &clk_conf->conf.fixed_rate;
182 rate = fixed_rate_conf->rate;
183
184 if (!rate) {
185 r = &fixed_rate_conf->rate_parm;
186 reg = readl(clk_base + clk_conf->reg_off + r->reg_off);
187 rate = PARM_GET(r->width, r->shift, reg);
188 }
189
190 rate *= 1000000;
191
192 clk = clk_register_fixed_rate(NULL,
193 clk_conf->clk_name,
194 clk_conf->num_parents
195 ? clk_conf->clks_parent[0] : NULL,
196 clk_conf->flags, rate);
197
198 return clk;
199}
200
201void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
202 size_t nr_confs,
203 void __iomem *clk_base)
204{
205 unsigned int i;
206 struct clk *clk = NULL;
207
208 for (i = 0; i < nr_confs; i++) {
209 const struct clk_conf *clk_conf = &clk_confs[i];
210
211 switch (clk_conf->clk_type) {
212 case CLK_FIXED_RATE:
213 clk = meson_clk_register_fixed_rate(clk_conf,
214 clk_base);
215 break;
216 case CLK_FIXED_FACTOR:
217 clk = meson_clk_register_fixed_factor(clk_conf,
218 clk_base);
219 break;
220 case CLK_COMPOSITE:
221 clk = meson_clk_register_composite(clk_conf,
222 clk_base);
223 break;
224 case CLK_CPU:
225 clk = meson_clk_register_cpu(clk_conf, clk_base,
226 &clk_lock);
227 break;
228 case CLK_PLL:
229 clk = meson_clk_register_pll(clk_conf, clk_base,
230 &clk_lock);
231 break;
232 default:
233 clk = NULL;
234 }
235
236 if (!clk) {
237 pr_err("%s: unknown clock type %d\n", __func__,
238 clk_conf->clk_type);
239 continue;
240 }
241
242 if (IS_ERR(clk)) {
243 pr_warn("%s: Unable to create %s clock\n", __func__,
244 clk_conf->clk_name);
245 continue;
246 }
247
248 meson_clk_add_lookup(clk, clk_conf->clk_id);
249 }
250}
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
new file mode 100644
index 000000000000..609ae92cc13f
--- /dev/null
+++ b/drivers/clk/meson/clkc.h
@@ -0,0 +1,187 @@
1/*
2 * Copyright (c) 2015 Endless Mobile, Inc.
3 * Author: Carlo Caione <carlo@endlessm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef __CLKC_H
19#define __CLKC_H
20
21#define PMASK(width) GENMASK(width - 1, 0)
22#define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
23#define CLRPMASK(width, shift) (~SETPMASK(width, shift))
24
25#define PARM_GET(width, shift, reg) \
26 (((reg) & SETPMASK(width, shift)) >> (shift))
27#define PARM_SET(width, shift, reg, val) \
28 (((reg) & CLRPMASK(width, shift)) | (val << (shift)))
29
30#define MESON_PARM_APPLICABLE(p) (!!((p)->width))
31
32struct parm {
33 u16 reg_off;
34 u8 shift;
35 u8 width;
36};
37#define PARM(_r, _s, _w) \
38 { \
39 .reg_off = (_r), \
40 .shift = (_s), \
41 .width = (_w), \
42 } \
43
44struct pll_rate_table {
45 unsigned long rate;
46 u16 m;
47 u16 n;
48 u16 od;
49};
50#define PLL_RATE(_r, _m, _n, _od) \
51 { \
52 .rate = (_r), \
53 .m = (_m), \
54 .n = (_n), \
55 .od = (_od), \
56 } \
57
58struct pll_conf {
59 const struct pll_rate_table *rate_table;
60 struct parm m;
61 struct parm n;
62 struct parm od;
63};
64
65struct fixed_fact_conf {
66 unsigned int div;
67 unsigned int mult;
68 struct parm div_parm;
69 struct parm mult_parm;
70};
71
72struct fixed_rate_conf {
73 unsigned long rate;
74 struct parm rate_parm;
75};
76
77struct composite_conf {
78 struct parm mux_parm;
79 struct parm div_parm;
80 struct parm gate_parm;
81 struct clk_div_table *div_table;
82 u32 *mux_table;
83 u8 mux_flags;
84 u8 div_flags;
85 u8 gate_flags;
86};
87
88#define PNAME(x) static const char *x[]
89
90enum clk_type {
91 CLK_FIXED_FACTOR,
92 CLK_FIXED_RATE,
93 CLK_COMPOSITE,
94 CLK_CPU,
95 CLK_PLL,
96};
97
98struct clk_conf {
99 u16 reg_off;
100 enum clk_type clk_type;
101 unsigned int clk_id;
102 const char *clk_name;
103 const char **clks_parent;
104 int num_parents;
105 unsigned long flags;
106 union {
107 struct fixed_fact_conf fixed_fact;
108 struct fixed_rate_conf fixed_rate;
109 const struct composite_conf *composite;
110 struct pll_conf *pll;
111 const struct clk_div_table *div_table;
112 } conf;
113};
114
115#define FIXED_RATE_P(_ro, _ci, _cn, _f, _c) \
116 { \
117 .reg_off = (_ro), \
118 .clk_type = CLK_FIXED_RATE, \
119 .clk_id = (_ci), \
120 .clk_name = (_cn), \
121 .flags = (_f), \
122 .conf.fixed_rate.rate_parm = _c, \
123 } \
124
125#define FIXED_RATE(_ci, _cn, _f, _r) \
126 { \
127 .clk_type = CLK_FIXED_RATE, \
128 .clk_id = (_ci), \
129 .clk_name = (_cn), \
130 .flags = (_f), \
131 .conf.fixed_rate.rate = (_r), \
132 } \
133
134#define PLL(_ro, _ci, _cn, _cp, _f, _c) \
135 { \
136 .reg_off = (_ro), \
137 .clk_type = CLK_PLL, \
138 .clk_id = (_ci), \
139 .clk_name = (_cn), \
140 .clks_parent = (_cp), \
141 .num_parents = ARRAY_SIZE(_cp), \
142 .flags = (_f), \
143 .conf.pll = (_c), \
144 } \
145
146#define FIXED_FACTOR_DIV(_ci, _cn, _cp, _f, _d) \
147 { \
148 .clk_type = CLK_FIXED_FACTOR, \
149 .clk_id = (_ci), \
150 .clk_name = (_cn), \
151 .clks_parent = (_cp), \
152 .num_parents = ARRAY_SIZE(_cp), \
153 .conf.fixed_fact.div = (_d), \
154 } \
155
156#define CPU(_ro, _ci, _cn, _cp, _dt) \
157 { \
158 .reg_off = (_ro), \
159 .clk_type = CLK_CPU, \
160 .clk_id = (_ci), \
161 .clk_name = (_cn), \
162 .clks_parent = (_cp), \
163 .num_parents = ARRAY_SIZE(_cp), \
164 .conf.div_table = (_dt), \
165 } \
166
167#define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c) \
168 { \
169 .reg_off = (_ro), \
170 .clk_type = CLK_COMPOSITE, \
171 .clk_id = (_ci), \
172 .clk_name = (_cn), \
173 .clks_parent = (_cp), \
174 .num_parents = ARRAY_SIZE(_cp), \
175 .flags = (_f), \
176 .conf.composite = (_c), \
177 } \
178
179struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks);
180void meson_clk_register_clks(const struct clk_conf *clk_confs,
181 unsigned int nr_confs, void __iomem *clk_base);
182struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
183 void __iomem *reg_base, spinlock_t *lock);
184struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf,
185 void __iomem *reg_base, spinlock_t *lock);
186
187#endif /* __CLKC_H */
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
new file mode 100644
index 000000000000..61f6d55c4ac7
--- /dev/null
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -0,0 +1,196 @@
1/*
2 * Copyright (c) 2015 Endless Mobile, Inc.
3 * Author: Carlo Caione <carlo@endlessm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <linux/clk-provider.h>
19#include <linux/kernel.h>
20#include <linux/of.h>
21#include <linux/of_address.h>
22#include <linux/slab.h>
23#include <dt-bindings/clock/meson8b-clkc.h>
24
25#include "clkc.h"
26
27#define MESON8B_REG_CTL0_ADDR 0x0000
28#define MESON8B_REG_SYS_CPU_CNTL1 0x015c
29#define MESON8B_REG_HHI_MPEG 0x0174
30#define MESON8B_REG_MALI 0x01b0
31#define MESON8B_REG_PLL_FIXED 0x0280
32#define MESON8B_REG_PLL_SYS 0x0300
33#define MESON8B_REG_PLL_VID 0x0320
34
35static const struct pll_rate_table sys_pll_rate_table[] = {
36 PLL_RATE(312000000, 52, 1, 2),
37 PLL_RATE(336000000, 56, 1, 2),
38 PLL_RATE(360000000, 60, 1, 2),
39 PLL_RATE(384000000, 64, 1, 2),
40 PLL_RATE(408000000, 68, 1, 2),
41 PLL_RATE(432000000, 72, 1, 2),
42 PLL_RATE(456000000, 76, 1, 2),
43 PLL_RATE(480000000, 80, 1, 2),
44 PLL_RATE(504000000, 84, 1, 2),
45 PLL_RATE(528000000, 88, 1, 2),
46 PLL_RATE(552000000, 92, 1, 2),
47 PLL_RATE(576000000, 96, 1, 2),
48 PLL_RATE(600000000, 50, 1, 1),
49 PLL_RATE(624000000, 52, 1, 1),
50 PLL_RATE(648000000, 54, 1, 1),
51 PLL_RATE(672000000, 56, 1, 1),
52 PLL_RATE(696000000, 58, 1, 1),
53 PLL_RATE(720000000, 60, 1, 1),
54 PLL_RATE(744000000, 62, 1, 1),
55 PLL_RATE(768000000, 64, 1, 1),
56 PLL_RATE(792000000, 66, 1, 1),
57 PLL_RATE(816000000, 68, 1, 1),
58 PLL_RATE(840000000, 70, 1, 1),
59 PLL_RATE(864000000, 72, 1, 1),
60 PLL_RATE(888000000, 74, 1, 1),
61 PLL_RATE(912000000, 76, 1, 1),
62 PLL_RATE(936000000, 78, 1, 1),
63 PLL_RATE(960000000, 80, 1, 1),
64 PLL_RATE(984000000, 82, 1, 1),
65 PLL_RATE(1008000000, 84, 1, 1),
66 PLL_RATE(1032000000, 86, 1, 1),
67 PLL_RATE(1056000000, 88, 1, 1),
68 PLL_RATE(1080000000, 90, 1, 1),
69 PLL_RATE(1104000000, 92, 1, 1),
70 PLL_RATE(1128000000, 94, 1, 1),
71 PLL_RATE(1152000000, 96, 1, 1),
72 PLL_RATE(1176000000, 98, 1, 1),
73 PLL_RATE(1200000000, 50, 1, 0),
74 PLL_RATE(1224000000, 51, 1, 0),
75 PLL_RATE(1248000000, 52, 1, 0),
76 PLL_RATE(1272000000, 53, 1, 0),
77 PLL_RATE(1296000000, 54, 1, 0),
78 PLL_RATE(1320000000, 55, 1, 0),
79 PLL_RATE(1344000000, 56, 1, 0),
80 PLL_RATE(1368000000, 57, 1, 0),
81 PLL_RATE(1392000000, 58, 1, 0),
82 PLL_RATE(1416000000, 59, 1, 0),
83 PLL_RATE(1440000000, 60, 1, 0),
84 PLL_RATE(1464000000, 61, 1, 0),
85 PLL_RATE(1488000000, 62, 1, 0),
86 PLL_RATE(1512000000, 63, 1, 0),
87 PLL_RATE(1536000000, 64, 1, 0),
88 { /* sentinel */ },
89};
90
91static const struct clk_div_table cpu_div_table[] = {
92 { .val = 1, .div = 1 },
93 { .val = 2, .div = 2 },
94 { .val = 3, .div = 3 },
95 { .val = 2, .div = 4 },
96 { .val = 3, .div = 6 },
97 { .val = 4, .div = 8 },
98 { .val = 5, .div = 10 },
99 { .val = 6, .div = 12 },
100 { .val = 7, .div = 14 },
101 { .val = 8, .div = 16 },
102 { /* sentinel */ },
103};
104
105PNAME(p_xtal) = { "xtal" };
106PNAME(p_fclk_div) = { "fixed_pll" };
107PNAME(p_cpu_clk) = { "sys_pll" };
108PNAME(p_clk81) = { "fclk_div3", "fclk_div4", "fclk_div5" };
109PNAME(p_mali) = { "fclk_div3", "fclk_div4", "fclk_div5",
110 "fclk_div7", "zero" };
111
112static u32 mux_table_clk81[] = { 6, 5, 7 };
113static u32 mux_table_mali[] = { 6, 5, 7, 4, 0 };
114
115static struct pll_conf pll_confs = {
116 .m = PARM(0x00, 0, 9),
117 .n = PARM(0x00, 9, 5),
118 .od = PARM(0x00, 16, 2),
119};
120
121static struct pll_conf sys_pll_conf = {
122 .m = PARM(0x00, 0, 9),
123 .n = PARM(0x00, 9, 5),
124 .od = PARM(0x00, 16, 2),
125 .rate_table = sys_pll_rate_table,
126};
127
128static const struct composite_conf clk81_conf __initconst = {
129 .mux_table = mux_table_clk81,
130 .mux_flags = CLK_MUX_READ_ONLY,
131 .mux_parm = PARM(0x00, 12, 3),
132 .div_parm = PARM(0x00, 0, 7),
133 .gate_parm = PARM(0x00, 7, 1),
134};
135
136static const struct composite_conf mali_conf __initconst = {
137 .mux_table = mux_table_mali,
138 .mux_parm = PARM(0x00, 9, 3),
139 .div_parm = PARM(0x00, 0, 7),
140 .gate_parm = PARM(0x00, 8, 1),
141};
142
143static const struct clk_conf meson8b_xtal_conf __initconst =
144 FIXED_RATE_P(MESON8B_REG_CTL0_ADDR, CLKID_XTAL, "xtal",
145 CLK_IS_ROOT, PARM(0x00, 4, 7));
146
147static const struct clk_conf meson8b_clk_confs[] __initconst = {
148 FIXED_RATE(CLKID_ZERO, "zero", CLK_IS_ROOT, 0),
149 PLL(MESON8B_REG_PLL_FIXED, CLKID_PLL_FIXED, "fixed_pll",
150 p_xtal, 0, &pll_confs),
151 PLL(MESON8B_REG_PLL_VID, CLKID_PLL_VID, "vid_pll",
152 p_xtal, 0, &pll_confs),
153 PLL(MESON8B_REG_PLL_SYS, CLKID_PLL_SYS, "sys_pll",
154 p_xtal, 0, &sys_pll_conf),
155 FIXED_FACTOR_DIV(CLKID_FCLK_DIV2, "fclk_div2", p_fclk_div, 0, 2),
156 FIXED_FACTOR_DIV(CLKID_FCLK_DIV3, "fclk_div3", p_fclk_div, 0, 3),
157 FIXED_FACTOR_DIV(CLKID_FCLK_DIV4, "fclk_div4", p_fclk_div, 0, 4),
158 FIXED_FACTOR_DIV(CLKID_FCLK_DIV5, "fclk_div5", p_fclk_div, 0, 5),
159 FIXED_FACTOR_DIV(CLKID_FCLK_DIV7, "fclk_div7", p_fclk_div, 0, 7),
160 CPU(MESON8B_REG_SYS_CPU_CNTL1, CLKID_CPUCLK, "a5_clk", p_cpu_clk,
161 cpu_div_table),
162 COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
163 CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf),
164 COMPOSITE(MESON8B_REG_MALI, CLKID_MALI, "mali", p_mali,
165 CLK_IGNORE_UNUSED, &mali_conf),
166};
167
168static void __init meson8b_clkc_init(struct device_node *np)
169{
170 void __iomem *clk_base;
171
172 if (!meson_clk_init(np, CLK_NR_CLKS))
173 return;
174
175 /* XTAL */
176 clk_base = of_iomap(np, 0);
177 if (!clk_base) {
178 pr_err("%s: Unable to map xtal base\n", __func__);
179 return;
180 }
181
182 meson_clk_register_clks(&meson8b_xtal_conf, 1, clk_base);
183 iounmap(clk_base);
184
185 /* Generic clocks and PLLs */
186 clk_base = of_iomap(np, 1);
187 if (!clk_base) {
188 pr_err("%s: Unable to map clk base\n", __func__);
189 return;
190 }
191
192 meson_clk_register_clks(meson8b_clk_confs,
193 ARRAY_SIZE(meson8b_clk_confs),
194 clk_base);
195}
196CLK_OF_DECLARE(meson8b_clock, "amlogic,meson8b-clkc", meson8b_clkc_init);
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 3caaf7cc169c..9d4bc41e4239 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -12,3 +12,5 @@ obj-$(CONFIG_MACH_MMP2_DT) += clk-of-mmp2.o
12obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o 12obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
13obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o 13obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
14obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o 14obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o
15
16obj-y += clk-of-pxa1928.o
diff --git a/drivers/clk/mmp/clk-apbc.c b/drivers/clk/mmp/clk-apbc.c
index d14120eaa71f..09d41c717c52 100644
--- a/drivers/clk/mmp/clk-apbc.c
+++ b/drivers/clk/mmp/clk-apbc.c
@@ -115,7 +115,7 @@ static void clk_apbc_unprepare(struct clk_hw *hw)
115 spin_unlock_irqrestore(apbc->lock, flags); 115 spin_unlock_irqrestore(apbc->lock, flags);
116} 116}
117 117
118struct clk_ops clk_apbc_ops = { 118static struct clk_ops clk_apbc_ops = {
119 .prepare = clk_apbc_prepare, 119 .prepare = clk_apbc_prepare,
120 .unprepare = clk_apbc_unprepare, 120 .unprepare = clk_apbc_unprepare,
121}; 121};
diff --git a/drivers/clk/mmp/clk-apmu.c b/drivers/clk/mmp/clk-apmu.c
index abe182b2377f..cdcf2d7f321e 100644
--- a/drivers/clk/mmp/clk-apmu.c
+++ b/drivers/clk/mmp/clk-apmu.c
@@ -61,7 +61,7 @@ static void clk_apmu_disable(struct clk_hw *hw)
61 spin_unlock_irqrestore(apmu->lock, flags); 61 spin_unlock_irqrestore(apmu->lock, flags);
62} 62}
63 63
64struct clk_ops clk_apmu_ops = { 64static struct clk_ops clk_apmu_ops = {
65 .enable = clk_apmu_enable, 65 .enable = clk_apmu_enable,
66 .disable = clk_apmu_disable, 66 .disable = clk_apmu_disable,
67}; 67};
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c
index 5c90a4230fa3..09d2832fbd78 100644
--- a/drivers/clk/mmp/clk-mmp2.c
+++ b/drivers/clk/mmp/clk-mmp2.c
@@ -63,10 +63,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = {
63}; 63};
64 64
65static struct mmp_clk_factor_tbl uart_factor_tbl[] = { 65static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
66 {.num = 14634, .den = 2165}, /*14.745MHZ */ 66 {.num = 8125, .den = 1536}, /*14.745MHZ */
67 {.num = 3521, .den = 689}, /*19.23MHZ */ 67 {.num = 3521, .den = 689}, /*19.23MHZ */
68 {.num = 9679, .den = 5728}, /*58.9824MHZ */
69 {.num = 15850, .den = 9451}, /*59.429MHZ */
70}; 68};
71 69
72static const char *uart_parent[] = {"uart_pll", "vctcxo"}; 70static const char *uart_parent[] = {"uart_pll", "vctcxo"};
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index 2cbc2b43ae52..251533d87c65 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -30,6 +30,7 @@
30#define APBC_TWSI4 0x7c 30#define APBC_TWSI4 0x7c
31#define APBC_TWSI5 0x80 31#define APBC_TWSI5 0x80
32#define APBC_KPC 0x18 32#define APBC_KPC 0x18
33#define APBC_TIMER 0x24
33#define APBC_UART0 0x2c 34#define APBC_UART0 0x2c
34#define APBC_UART1 0x30 35#define APBC_UART1 0x30
35#define APBC_UART2 0x34 36#define APBC_UART2 0x34
@@ -98,10 +99,8 @@ static struct mmp_clk_factor_masks uart_factor_masks = {
98}; 99};
99 100
100static struct mmp_clk_factor_tbl uart_factor_tbl[] = { 101static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
101 {.num = 14634, .den = 2165}, /*14.745MHZ */ 102 {.num = 8125, .den = 1536}, /*14.745MHZ */
102 {.num = 3521, .den = 689}, /*19.23MHZ */ 103 {.num = 3521, .den = 689}, /*19.23MHZ */
103 {.num = 9679, .den = 5728}, /*58.9824MHZ */
104 {.num = 15850, .den = 9451}, /*59.429MHZ */
105}; 104};
106 105
107static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit) 106static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
@@ -134,6 +133,9 @@ static DEFINE_SPINLOCK(ssp2_lock);
134static DEFINE_SPINLOCK(ssp3_lock); 133static DEFINE_SPINLOCK(ssp3_lock);
135static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"}; 134static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"};
136 135
136static DEFINE_SPINLOCK(timer_lock);
137static const char *timer_parent_names[] = {"clk32", "vctcxo_2", "vctcxo_4", "vctcxo"};
138
137static DEFINE_SPINLOCK(reset_lock); 139static DEFINE_SPINLOCK(reset_lock);
138 140
139static struct mmp_param_mux_clk apbc_mux_clks[] = { 141static struct mmp_param_mux_clk apbc_mux_clks[] = {
@@ -145,6 +147,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
145 {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock}, 147 {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock},
146 {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock}, 148 {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock},
147 {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock}, 149 {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock},
150 {0, "timer_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, &timer_lock},
148}; 151};
149 152
150static struct mmp_param_gate_clk apbc_gate_clks[] = { 153static struct mmp_param_gate_clk apbc_gate_clks[] = {
@@ -170,6 +173,7 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = {
170 {MMP2_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x7, 0x3, 0x0, 0, &ssp1_lock}, 173 {MMP2_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x7, 0x3, 0x0, 0, &ssp1_lock},
171 {MMP2_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x7, 0x3, 0x0, 0, &ssp2_lock}, 174 {MMP2_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x7, 0x3, 0x0, 0, &ssp2_lock},
172 {MMP2_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x7, 0x3, 0x0, 0, &ssp3_lock}, 175 {MMP2_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x7, 0x3, 0x0, 0, &ssp3_lock},
176 {MMP2_CLK_TIMER, "timer_clk", "timer_mux", CLK_SET_RATE_PARENT, APBC_TIMER, 0x7, 0x3, 0x0, 0, &timer_lock},
173}; 177};
174 178
175static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit) 179static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
index 5b1810dc4bd2..64eaf4141c69 100644
--- a/drivers/clk/mmp/clk-of-pxa168.c
+++ b/drivers/clk/mmp/clk-of-pxa168.c
@@ -32,6 +32,7 @@
32#define APBC_PWM1 0x10 32#define APBC_PWM1 0x10
33#define APBC_PWM2 0x14 33#define APBC_PWM2 0x14
34#define APBC_PWM3 0x18 34#define APBC_PWM3 0x18
35#define APBC_TIMER 0x34
35#define APBC_SSP0 0x81c 36#define APBC_SSP0 0x81c
36#define APBC_SSP1 0x820 37#define APBC_SSP1 0x820
37#define APBC_SSP2 0x84c 38#define APBC_SSP2 0x84c
@@ -58,6 +59,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
58 {PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, 59 {PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
59 {PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, 60 {PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
60 {PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000}, 61 {PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000},
62 {PXA168_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000},
61}; 63};
62 64
63static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { 65static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
@@ -70,6 +72,7 @@ static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
70 {PXA168_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0}, 72 {PXA168_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
71 {PXA168_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0}, 73 {PXA168_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
72 {PXA168_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0}, 74 {PXA168_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
75 {PXA168_CLK_PLL1_192, "pll1_192", "pll1_96", 1, 2, 0},
73 {PXA168_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0}, 76 {PXA168_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
74 {PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0}, 77 {PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
75 {PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0}, 78 {PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
@@ -119,6 +122,9 @@ static DEFINE_SPINLOCK(ssp3_lock);
119static DEFINE_SPINLOCK(ssp4_lock); 122static DEFINE_SPINLOCK(ssp4_lock);
120static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; 123static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
121 124
125static DEFINE_SPINLOCK(timer_lock);
126static const char *timer_parent_names[] = {"pll1_48", "clk32", "pll1_96", "pll1_192"};
127
122static DEFINE_SPINLOCK(reset_lock); 128static DEFINE_SPINLOCK(reset_lock);
123 129
124static struct mmp_param_mux_clk apbc_mux_clks[] = { 130static struct mmp_param_mux_clk apbc_mux_clks[] = {
@@ -130,6 +136,7 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
130 {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock}, 136 {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock},
131 {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock}, 137 {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock},
132 {0, "ssp4_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP4, 4, 3, 0, &ssp4_lock}, 138 {0, "ssp4_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP4, 4, 3, 0, &ssp4_lock},
139 {0, "timer_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), CLK_SET_RATE_PARENT, APBC_TIMER, 4, 3, 0, &timer_lock},
133}; 140};
134 141
135static struct mmp_param_gate_clk apbc_gate_clks[] = { 142static struct mmp_param_gate_clk apbc_gate_clks[] = {
@@ -151,6 +158,7 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = {
151 {PXA168_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x3, 0x3, 0x0, 0, &ssp2_lock}, 158 {PXA168_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x3, 0x3, 0x0, 0, &ssp2_lock},
152 {PXA168_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x3, 0x3, 0x0, 0, &ssp3_lock}, 159 {PXA168_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x3, 0x3, 0x0, 0, &ssp3_lock},
153 {PXA168_CLK_SSP4, "ssp4_clk", "ssp4_mux", CLK_SET_RATE_PARENT, APBC_SSP4, 0x3, 0x3, 0x0, 0, &ssp4_lock}, 160 {PXA168_CLK_SSP4, "ssp4_clk", "ssp4_mux", CLK_SET_RATE_PARENT, APBC_SSP4, 0x3, 0x3, 0x0, 0, &ssp4_lock},
161 {PXA168_CLK_TIMER, "timer_clk", "timer_mux", CLK_SET_RATE_PARENT, APBC_TIMER, 0x3, 0x3, 0x0, 0, &timer_lock},
154}; 162};
155 163
156static void pxa168_apb_periph_clk_init(struct pxa168_clk_unit *pxa_unit) 164static void pxa168_apb_periph_clk_init(struct pxa168_clk_unit *pxa_unit)
diff --git a/drivers/clk/mmp/clk-of-pxa1928.c b/drivers/clk/mmp/clk-of-pxa1928.c
new file mode 100644
index 000000000000..433a5ae1eae0
--- /dev/null
+++ b/drivers/clk/mmp/clk-of-pxa1928.c
@@ -0,0 +1,265 @@
1/*
2 * pxa1928 clock framework source file
3 *
4 * Copyright (C) 2015 Linaro, Ltd.
5 * Rob Herring <robh@kernel.org>
6 *
7 * Based on drivers/clk/mmp/clk-of-mmp2.c:
8 * Copyright (C) 2012 Marvell
9 * Chao Xie <xiechao.mail@gmail.com>
10 *
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * warranty of any kind, whether express or implied.
14 */
15#include <linux/kernel.h>
16#include <linux/io.h>
17#include <linux/of_address.h>
18#include <linux/slab.h>
19#include <linux/spinlock.h>
20
21#include <dt-bindings/clock/marvell,pxa1928.h>
22
23#include "clk.h"
24#include "reset.h"
25
26#define MPMU_UART_PLL 0x14
27
28struct pxa1928_clk_unit {
29 struct mmp_clk_unit unit;
30 void __iomem *mpmu_base;
31 void __iomem *apmu_base;
32 void __iomem *apbc_base;
33 void __iomem *apbcp_base;
34};
35
36static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
37 {0, "clk32", NULL, CLK_IS_ROOT, 32768},
38 {0, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
39 {0, "pll1_624", NULL, CLK_IS_ROOT, 624000000},
40 {0, "pll5p", NULL, CLK_IS_ROOT, 832000000},
41 {0, "pll5", NULL, CLK_IS_ROOT, 1248000000},
42 {0, "usb_pll", NULL, CLK_IS_ROOT, 480000000},
43};
44
45static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
46 {0, "pll1_d2", "pll1_624", 1, 2, 0},
47 {0, "pll1_d9", "pll1_624", 1, 9, 0},
48 {0, "pll1_d12", "pll1_624", 1, 12, 0},
49 {0, "pll1_d16", "pll1_624", 1, 16, 0},
50 {0, "pll1_d20", "pll1_624", 1, 20, 0},
51 {0, "pll1_416", "pll1_624", 2, 3, 0},
52 {0, "vctcxo_d2", "vctcxo", 1, 2, 0},
53 {0, "vctcxo_d4", "vctcxo", 1, 4, 0},
54};
55
56static struct mmp_clk_factor_masks uart_factor_masks = {
57 .factor = 2,
58 .num_mask = 0x1fff,
59 .den_mask = 0x1fff,
60 .num_shift = 16,
61 .den_shift = 0,
62};
63
64static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
65 {.num = 832, .den = 234}, /*58.5MHZ */
66 {.num = 1, .den = 1}, /*26MHZ */
67};
68
69static void pxa1928_pll_init(struct pxa1928_clk_unit *pxa_unit)
70{
71 struct clk *clk;
72 struct mmp_clk_unit *unit = &pxa_unit->unit;
73
74 mmp_register_fixed_rate_clks(unit, fixed_rate_clks,
75 ARRAY_SIZE(fixed_rate_clks));
76
77 mmp_register_fixed_factor_clks(unit, fixed_factor_clks,
78 ARRAY_SIZE(fixed_factor_clks));
79
80 clk = mmp_clk_register_factor("uart_pll", "pll1_416",
81 CLK_SET_RATE_PARENT,
82 pxa_unit->mpmu_base + MPMU_UART_PLL,
83 &uart_factor_masks, uart_factor_tbl,
84 ARRAY_SIZE(uart_factor_tbl), NULL);
85}
86
87static DEFINE_SPINLOCK(uart0_lock);
88static DEFINE_SPINLOCK(uart1_lock);
89static DEFINE_SPINLOCK(uart2_lock);
90static DEFINE_SPINLOCK(uart3_lock);
91static const char *uart_parent_names[] = {"uart_pll", "vctcxo"};
92
93static DEFINE_SPINLOCK(ssp0_lock);
94static DEFINE_SPINLOCK(ssp1_lock);
95static const char *ssp_parent_names[] = {"vctcxo_d4", "vctcxo_d2", "vctcxo", "pll1_d12"};
96
97static DEFINE_SPINLOCK(reset_lock);
98
99static struct mmp_param_mux_clk apbc_mux_clks[] = {
100 {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART0 * 4, 4, 3, 0, &uart0_lock},
101 {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART1 * 4, 4, 3, 0, &uart1_lock},
102 {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART2 * 4, 4, 3, 0, &uart2_lock},
103 {0, "uart3_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_UART3 * 4, 4, 3, 0, &uart3_lock},
104 {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_SSP0 * 4, 4, 3, 0, &ssp0_lock},
105 {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_SSP1 * 4, 4, 3, 0, &ssp1_lock},
106};
107
108static struct mmp_param_gate_clk apbc_gate_clks[] = {
109 {PXA1928_CLK_TWSI0, "twsi0_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI0 * 4, 0x3, 0x3, 0x0, 0, &reset_lock},
110 {PXA1928_CLK_TWSI1, "twsi1_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI1 * 4, 0x3, 0x3, 0x0, 0, &reset_lock},
111 {PXA1928_CLK_TWSI2, "twsi2_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI2 * 4, 0x3, 0x3, 0x0, 0, &reset_lock},
112 {PXA1928_CLK_TWSI3, "twsi3_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI3 * 4, 0x3, 0x3, 0x0, 0, &reset_lock},
113 {PXA1928_CLK_TWSI4, "twsi4_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI4 * 4, 0x3, 0x3, 0x0, 0, &reset_lock},
114 {PXA1928_CLK_TWSI5, "twsi5_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_TWSI5 * 4, 0x3, 0x3, 0x0, 0, &reset_lock},
115 {PXA1928_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_GPIO * 4, 0x3, 0x3, 0x0, 0, &reset_lock},
116 {PXA1928_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, PXA1928_CLK_KPC * 4, 0x3, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
117 {PXA1928_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, PXA1928_CLK_RTC * 4, 0x83, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
118 {PXA1928_CLK_PWM0, "pwm0_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM0 * 4, 0x3, 0x3, 0x0, 0, &reset_lock},
119 {PXA1928_CLK_PWM1, "pwm1_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM1 * 4, 0x3, 0x3, 0x0, 0, &reset_lock},
120 {PXA1928_CLK_PWM2, "pwm2_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM2 * 4, 0x3, 0x3, 0x0, 0, &reset_lock},
121 {PXA1928_CLK_PWM3, "pwm3_clk", "vctcxo", CLK_SET_RATE_PARENT, PXA1928_CLK_PWM3 * 4, 0x3, 0x3, 0x0, 0, &reset_lock},
122 /* The gate clocks has mux parent. */
123 {PXA1928_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART0 * 4, 0x3, 0x3, 0x0, 0, &uart0_lock},
124 {PXA1928_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART1 * 4, 0x3, 0x3, 0x0, 0, &uart1_lock},
125 {PXA1928_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART2 * 4, 0x3, 0x3, 0x0, 0, &uart2_lock},
126 {PXA1928_CLK_UART3, "uart3_clk", "uart3_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_UART3 * 4, 0x3, 0x3, 0x0, 0, &uart3_lock},
127 {PXA1928_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_SSP0 * 4, 0x3, 0x3, 0x0, 0, &ssp0_lock},
128 {PXA1928_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, PXA1928_CLK_SSP1 * 4, 0x3, 0x3, 0x0, 0, &ssp1_lock},
129};
130
131static void pxa1928_apb_periph_clk_init(struct pxa1928_clk_unit *pxa_unit)
132{
133 struct mmp_clk_unit *unit = &pxa_unit->unit;
134
135 mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base,
136 ARRAY_SIZE(apbc_mux_clks));
137
138 mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base,
139 ARRAY_SIZE(apbc_gate_clks));
140}
141
142static DEFINE_SPINLOCK(sdh0_lock);
143static DEFINE_SPINLOCK(sdh1_lock);
144static DEFINE_SPINLOCK(sdh2_lock);
145static DEFINE_SPINLOCK(sdh3_lock);
146static DEFINE_SPINLOCK(sdh4_lock);
147static const char *sdh_parent_names[] = {"pll1_624", "pll5p", "pll5", "pll1_416"};
148
149static DEFINE_SPINLOCK(usb_lock);
150
151static struct mmp_param_mux_clk apmu_mux_clks[] = {
152 {0, "sdh_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, PXA1928_CLK_SDH0 * 4, 8, 2, 0, &sdh0_lock},
153};
154
155static struct mmp_param_div_clk apmu_div_clks[] = {
156 {0, "sdh_div", "sdh_mux", 0, PXA1928_CLK_SDH0 * 4, 10, 4, CLK_DIVIDER_ONE_BASED, &sdh0_lock},
157};
158
159static struct mmp_param_gate_clk apmu_gate_clks[] = {
160 {PXA1928_CLK_USB, "usb_clk", "usb_pll", 0, PXA1928_CLK_USB * 4, 0x9, 0x9, 0x0, 0, &usb_lock},
161 {PXA1928_CLK_HSIC, "hsic_clk", "usb_pll", 0, PXA1928_CLK_HSIC * 4, 0x9, 0x9, 0x0, 0, &usb_lock},
162 /* The gate clocks has mux parent. */
163 {PXA1928_CLK_SDH0, "sdh0_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH0 * 4, 0x1b, 0x1b, 0x0, 0, &sdh0_lock},
164 {PXA1928_CLK_SDH1, "sdh1_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH1 * 4, 0x1b, 0x1b, 0x0, 0, &sdh1_lock},
165 {PXA1928_CLK_SDH2, "sdh2_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH2 * 4, 0x1b, 0x1b, 0x0, 0, &sdh2_lock},
166 {PXA1928_CLK_SDH3, "sdh3_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH3 * 4, 0x1b, 0x1b, 0x0, 0, &sdh3_lock},
167 {PXA1928_CLK_SDH4, "sdh4_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH4 * 4, 0x1b, 0x1b, 0x0, 0, &sdh4_lock},
168};
169
170static void pxa1928_axi_periph_clk_init(struct pxa1928_clk_unit *pxa_unit)
171{
172 struct mmp_clk_unit *unit = &pxa_unit->unit;
173
174 mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base,
175 ARRAY_SIZE(apmu_mux_clks));
176
177 mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base,
178 ARRAY_SIZE(apmu_div_clks));
179
180 mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base,
181 ARRAY_SIZE(apmu_gate_clks));
182}
183
184static void pxa1928_clk_reset_init(struct device_node *np,
185 struct pxa1928_clk_unit *pxa_unit)
186{
187 struct mmp_clk_reset_cell *cells;
188 int i, base, nr_resets;
189
190 nr_resets = ARRAY_SIZE(apbc_gate_clks);
191 cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL);
192 if (!cells)
193 return;
194
195 base = 0;
196 for (i = 0; i < nr_resets; i++) {
197 cells[base + i].clk_id = apbc_gate_clks[i].id;
198 cells[base + i].reg =
199 pxa_unit->apbc_base + apbc_gate_clks[i].offset;
200 cells[base + i].flags = 0;
201 cells[base + i].lock = apbc_gate_clks[i].lock;
202 cells[base + i].bits = 0x4;
203 }
204
205 mmp_clk_reset_register(np, cells, nr_resets);
206}
207
208static void __init pxa1928_mpmu_clk_init(struct device_node *np)
209{
210 struct pxa1928_clk_unit *pxa_unit;
211
212 pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL);
213 if (!pxa_unit)
214 return;
215
216 pxa_unit->mpmu_base = of_iomap(np, 0);
217 if (!pxa_unit->mpmu_base) {
218 pr_err("failed to map mpmu registers\n");
219 return;
220 }
221
222 pxa1928_pll_init(pxa_unit);
223}
224CLK_OF_DECLARE(pxa1928_mpmu_clk, "marvell,pxa1928-mpmu", pxa1928_mpmu_clk_init);
225
226static void __init pxa1928_apmu_clk_init(struct device_node *np)
227{
228 struct pxa1928_clk_unit *pxa_unit;
229
230 pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL);
231 if (!pxa_unit)
232 return;
233
234 pxa_unit->apmu_base = of_iomap(np, 0);
235 if (!pxa_unit->apmu_base) {
236 pr_err("failed to map apmu registers\n");
237 return;
238 }
239
240 mmp_clk_init(np, &pxa_unit->unit, PXA1928_APMU_NR_CLKS);
241
242 pxa1928_axi_periph_clk_init(pxa_unit);
243}
244CLK_OF_DECLARE(pxa1928_apmu_clk, "marvell,pxa1928-apmu", pxa1928_apmu_clk_init);
245
246static void __init pxa1928_apbc_clk_init(struct device_node *np)
247{
248 struct pxa1928_clk_unit *pxa_unit;
249
250 pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL);
251 if (!pxa_unit)
252 return;
253
254 pxa_unit->apbc_base = of_iomap(np, 0);
255 if (!pxa_unit->apbc_base) {
256 pr_err("failed to map apbc registers\n");
257 return;
258 }
259
260 mmp_clk_init(np, &pxa_unit->unit, PXA1928_APBC_NR_CLKS);
261
262 pxa1928_apb_periph_clk_init(pxa_unit);
263 pxa1928_clk_reset_init(np, pxa_unit);
264}
265CLK_OF_DECLARE(pxa1928_apbc_clk, "marvell,pxa1928-apbc", pxa1928_apbc_clk_init);
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
index 5e3c80dad336..13d6173326a4 100644
--- a/drivers/clk/mmp/clk-of-pxa910.c
+++ b/drivers/clk/mmp/clk-of-pxa910.c
@@ -35,6 +35,8 @@
35#define APBC_SSP0 0x1c 35#define APBC_SSP0 0x1c
36#define APBC_SSP1 0x20 36#define APBC_SSP1 0x20
37#define APBC_SSP2 0x4c 37#define APBC_SSP2 0x4c
38#define APBC_TIMER0 0x30
39#define APBC_TIMER1 0x44
38#define APBCP_TWSI1 0x28 40#define APBCP_TWSI1 0x28
39#define APBCP_UART2 0x1c 41#define APBCP_UART2 0x1c
40#define APMU_SDH0 0x54 42#define APMU_SDH0 0x54
@@ -57,6 +59,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
57 {PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, 59 {PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
58 {PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, 60 {PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
59 {PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000}, 61 {PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000},
62 {PXA910_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000},
60}; 63};
61 64
62static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { 65static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
@@ -69,6 +72,7 @@ static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
69 {PXA910_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0}, 72 {PXA910_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
70 {PXA910_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0}, 73 {PXA910_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
71 {PXA910_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0}, 74 {PXA910_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
75 {PXA910_CLK_PLL1_192, "pll1_192", "pll1_96", 1, 2, 0},
72 {PXA910_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0}, 76 {PXA910_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
73 {PXA910_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0}, 77 {PXA910_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
74 {PXA910_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0}, 78 {PXA910_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
@@ -115,6 +119,10 @@ static DEFINE_SPINLOCK(ssp0_lock);
115static DEFINE_SPINLOCK(ssp1_lock); 119static DEFINE_SPINLOCK(ssp1_lock);
116static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; 120static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
117 121
122static DEFINE_SPINLOCK(timer0_lock);
123static DEFINE_SPINLOCK(timer1_lock);
124static const char *timer_parent_names[] = {"pll1_48", "clk32", "pll1_96"};
125
118static DEFINE_SPINLOCK(reset_lock); 126static DEFINE_SPINLOCK(reset_lock);
119 127
120static struct mmp_param_mux_clk apbc_mux_clks[] = { 128static struct mmp_param_mux_clk apbc_mux_clks[] = {
@@ -122,6 +130,8 @@ static struct mmp_param_mux_clk apbc_mux_clks[] = {
122 {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock}, 130 {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock},
123 {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock}, 131 {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock},
124 {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock}, 132 {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock},
133 {0, "timer0_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), CLK_SET_RATE_PARENT, APBC_TIMER0, 4, 3, 0, &timer0_lock},
134 {0, "timer1_mux", timer_parent_names, ARRAY_SIZE(timer_parent_names), CLK_SET_RATE_PARENT, APBC_TIMER1, 4, 3, 0, &timer1_lock},
125}; 135};
126 136
127static struct mmp_param_mux_clk apbcp_mux_clks[] = { 137static struct mmp_param_mux_clk apbcp_mux_clks[] = {
@@ -142,6 +152,8 @@ static struct mmp_param_gate_clk apbc_gate_clks[] = {
142 {PXA910_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x3, 0x3, 0x0, 0, &uart1_lock}, 152 {PXA910_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x3, 0x3, 0x0, 0, &uart1_lock},
143 {PXA910_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x3, 0x3, 0x0, 0, &ssp0_lock}, 153 {PXA910_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x3, 0x3, 0x0, 0, &ssp0_lock},
144 {PXA910_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x3, 0x3, 0x0, 0, &ssp1_lock}, 154 {PXA910_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x3, 0x3, 0x0, 0, &ssp1_lock},
155 {PXA910_CLK_TIMER0, "timer0_clk", "timer0_mux", CLK_SET_RATE_PARENT, APBC_TIMER0, 0x3, 0x3, 0x0, 0, &timer0_lock},
156 {PXA910_CLK_TIMER1, "timer1_clk", "timer1_mux", CLK_SET_RATE_PARENT, APBC_TIMER1, 0x3, 0x3, 0x0, 0, &timer1_lock},
145}; 157};
146 158
147static struct mmp_param_gate_clk apbcp_gate_clks[] = { 159static struct mmp_param_gate_clk apbcp_gate_clks[] = {
diff --git a/drivers/clk/mvebu/armada-370.c b/drivers/clk/mvebu/armada-370.c
index 756f0f39d6a3..c19fd77e6c27 100644
--- a/drivers/clk/mvebu/armada-370.c
+++ b/drivers/clk/mvebu/armada-370.c
@@ -163,6 +163,7 @@ static const struct clk_gating_soc_desc a370_gating_desc[] __initconst = {
163 { "pex1", "pex1_en", 9, 0 }, 163 { "pex1", "pex1_en", 9, 0 },
164 { "sata0", NULL, 15, 0 }, 164 { "sata0", NULL, 15, 0 },
165 { "sdio", NULL, 17, 0 }, 165 { "sdio", NULL, 17, 0 },
166 { "crypto", NULL, 23, 0 },
166 { "tdm", NULL, 25, 0 }, 167 { "tdm", NULL, 25, 0 },
167 { "ddr", NULL, 28, CLK_IGNORE_UNUSED }, 168 { "ddr", NULL, 28, CLK_IGNORE_UNUSED },
168 { "sata1", NULL, 30, 0 }, 169 { "sata1", NULL, 30, 0 },
diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c
index 22d136aa699f..32216f9b7f03 100644
--- a/drivers/clk/mxs/clk-imx23.c
+++ b/drivers/clk/mxs/clk-imx23.c
@@ -77,12 +77,12 @@ static void __init clk_misc_init(void)
77 writel_relaxed(30 << BP_FRAC_IOFRAC, FRAC + SET); 77 writel_relaxed(30 << BP_FRAC_IOFRAC, FRAC + SET);
78} 78}
79 79
80static const char *sel_pll[] __initdata = { "pll", "ref_xtal", }; 80static const char *const sel_pll[] __initconst = { "pll", "ref_xtal", };
81static const char *sel_cpu[] __initdata = { "ref_cpu", "ref_xtal", }; 81static const char *const sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
82static const char *sel_pix[] __initdata = { "ref_pix", "ref_xtal", }; 82static const char *const sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
83static const char *sel_io[] __initdata = { "ref_io", "ref_xtal", }; 83static const char *const sel_io[] __initconst = { "ref_io", "ref_xtal", };
84static const char *cpu_sels[] __initdata = { "cpu_pll", "cpu_xtal", }; 84static const char *const cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
85static const char *emi_sels[] __initdata = { "emi_pll", "emi_xtal", }; 85static const char *const emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
86 86
87enum imx23_clk { 87enum imx23_clk {
88 ref_xtal, pll, ref_cpu, ref_emi, ref_pix, ref_io, saif_sel, 88 ref_xtal, pll, ref_cpu, ref_emi, ref_pix, ref_io, saif_sel,
diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c
index b1be3746ce95..a68670868baa 100644
--- a/drivers/clk/mxs/clk-imx28.c
+++ b/drivers/clk/mxs/clk-imx28.c
@@ -125,15 +125,15 @@ static void __init clk_misc_init(void)
125 writel_relaxed(val, FRAC0); 125 writel_relaxed(val, FRAC0);
126} 126}
127 127
128static const char *sel_cpu[] __initdata = { "ref_cpu", "ref_xtal", }; 128static const char *const sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
129static const char *sel_io0[] __initdata = { "ref_io0", "ref_xtal", }; 129static const char *const sel_io0[] __initconst = { "ref_io0", "ref_xtal", };
130static const char *sel_io1[] __initdata = { "ref_io1", "ref_xtal", }; 130static const char *const sel_io1[] __initconst = { "ref_io1", "ref_xtal", };
131static const char *sel_pix[] __initdata = { "ref_pix", "ref_xtal", }; 131static const char *const sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
132static const char *sel_gpmi[] __initdata = { "ref_gpmi", "ref_xtal", }; 132static const char *const sel_gpmi[] __initconst = { "ref_gpmi", "ref_xtal", };
133static const char *sel_pll0[] __initdata = { "pll0", "ref_xtal", }; 133static const char *const sel_pll0[] __initconst = { "pll0", "ref_xtal", };
134static const char *cpu_sels[] __initdata = { "cpu_pll", "cpu_xtal", }; 134static const char *const cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
135static const char *emi_sels[] __initdata = { "emi_pll", "emi_xtal", }; 135static const char *const emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
136static const char *ptp_sels[] __initdata = { "ref_xtal", "pll0", }; 136static const char *const ptp_sels[] __initconst = { "ref_xtal", "pll0", };
137 137
138enum imx28_clk { 138enum imx28_clk {
139 ref_xtal, pll0, pll1, pll2, ref_cpu, ref_emi, ref_io0, ref_io1, 139 ref_xtal, pll0, pll1, pll2, ref_cpu, ref_emi, ref_io0, ref_io1,
diff --git a/drivers/clk/mxs/clk.h b/drivers/clk/mxs/clk.h
index ef10ad9b5daa..f07d821dd75d 100644
--- a/drivers/clk/mxs/clk.h
+++ b/drivers/clk/mxs/clk.h
@@ -49,7 +49,7 @@ static inline struct clk *mxs_clk_gate(const char *name,
49} 49}
50 50
51static inline struct clk *mxs_clk_mux(const char *name, void __iomem *reg, 51static inline struct clk *mxs_clk_mux(const char *name, void __iomem *reg,
52 u8 shift, u8 width, const char **parent_names, int num_parents) 52 u8 shift, u8 width, const char *const *parent_names, int num_parents)
53{ 53{
54 return clk_register_mux(NULL, name, parent_names, num_parents, 54 return clk_register_mux(NULL, name, parent_names, num_parents,
55 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 55 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
diff --git a/drivers/clk/pistachio/clk-pll.c b/drivers/clk/pistachio/clk-pll.c
index de537560bf70..e17dada0dd21 100644
--- a/drivers/clk/pistachio/clk-pll.c
+++ b/drivers/clk/pistachio/clk-pll.c
@@ -6,9 +6,12 @@
6 * version 2, as published by the Free Software Foundation. 6 * version 2, as published by the Free Software Foundation.
7 */ 7 */
8 8
9#define pr_fmt(fmt) "%s: " fmt, __func__
10
9#include <linux/clk-provider.h> 11#include <linux/clk-provider.h>
10#include <linux/io.h> 12#include <linux/io.h>
11#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/printk.h>
12#include <linux/slab.h> 15#include <linux/slab.h>
13 16
14#include "clk.h" 17#include "clk.h"
@@ -50,6 +53,18 @@
50#define PLL_CTRL4 0x10 53#define PLL_CTRL4 0x10
51#define PLL_FRAC_CTRL4_BYPASS BIT(28) 54#define PLL_FRAC_CTRL4_BYPASS BIT(28)
52 55
56#define MIN_PFD 9600000UL
57#define MIN_VCO_LA 400000000UL
58#define MAX_VCO_LA 1600000000UL
59#define MIN_VCO_FRAC_INT 600000000UL
60#define MAX_VCO_FRAC_INT 1600000000UL
61#define MIN_VCO_FRAC_FRAC 600000000UL
62#define MAX_VCO_FRAC_FRAC 2400000000UL
63#define MIN_OUTPUT_LA 8000000UL
64#define MAX_OUTPUT_LA 1600000000UL
65#define MIN_OUTPUT_FRAC 12000000UL
66#define MAX_OUTPUT_FRAC 1600000000UL
67
53struct pistachio_clk_pll { 68struct pistachio_clk_pll {
54 struct clk_hw hw; 69 struct clk_hw hw;
55 void __iomem *base; 70 void __iomem *base;
@@ -67,6 +82,12 @@ static inline void pll_writel(struct pistachio_clk_pll *pll, u32 val, u32 reg)
67 writel(val, pll->base + reg); 82 writel(val, pll->base + reg);
68} 83}
69 84
85static inline void pll_lock(struct pistachio_clk_pll *pll)
86{
87 while (!(pll_readl(pll, PLL_STATUS) & PLL_STATUS_LOCK))
88 cpu_relax();
89}
90
70static inline u32 do_div_round_closest(u64 dividend, u32 divisor) 91static inline u32 do_div_round_closest(u64 dividend, u32 divisor)
71{ 92{
72 dividend += divisor / 2; 93 dividend += divisor / 2;
@@ -124,6 +145,8 @@ static int pll_gf40lp_frac_enable(struct clk_hw *hw)
124 val &= ~PLL_FRAC_CTRL4_BYPASS; 145 val &= ~PLL_FRAC_CTRL4_BYPASS;
125 pll_writel(pll, val, PLL_CTRL4); 146 pll_writel(pll, val, PLL_CTRL4);
126 147
148 pll_lock(pll);
149
127 return 0; 150 return 0;
128} 151}
129 152
@@ -149,16 +172,29 @@ static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
149{ 172{
150 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 173 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
151 struct pistachio_pll_rate_table *params; 174 struct pistachio_pll_rate_table *params;
152 bool was_enabled; 175 int enabled = pll_gf40lp_frac_is_enabled(hw);
153 u32 val; 176 u32 val, vco, old_postdiv1, old_postdiv2;
177 const char *name = __clk_get_name(hw->clk);
178
179 if (rate < MIN_OUTPUT_FRAC || rate > MAX_OUTPUT_FRAC)
180 return -EINVAL;
154 181
155 params = pll_get_params(pll, parent_rate, rate); 182 params = pll_get_params(pll, parent_rate, rate);
156 if (!params) 183 if (!params || !params->refdiv)
157 return -EINVAL; 184 return -EINVAL;
158 185
159 was_enabled = pll_gf40lp_frac_is_enabled(hw); 186 vco = params->fref * params->fbdiv / params->refdiv;
160 if (!was_enabled) 187 if (vco < MIN_VCO_FRAC_FRAC || vco > MAX_VCO_FRAC_FRAC)
161 pll_gf40lp_frac_enable(hw); 188 pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco,
189 MIN_VCO_FRAC_FRAC, MAX_VCO_FRAC_FRAC);
190
191 val = params->fref / params->refdiv;
192 if (val < MIN_PFD)
193 pr_warn("%s: PFD %u is too low (min %lu)\n",
194 name, val, MIN_PFD);
195 if (val > vco / 16)
196 pr_warn("%s: PFD %u is too high (max %u)\n",
197 name, val, vco / 16);
162 198
163 val = pll_readl(pll, PLL_CTRL1); 199 val = pll_readl(pll, PLL_CTRL1);
164 val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) | 200 val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
@@ -168,6 +204,19 @@ static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
168 pll_writel(pll, val, PLL_CTRL1); 204 pll_writel(pll, val, PLL_CTRL1);
169 205
170 val = pll_readl(pll, PLL_CTRL2); 206 val = pll_readl(pll, PLL_CTRL2);
207
208 old_postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) &
209 PLL_FRAC_CTRL2_POSTDIV1_MASK;
210 old_postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) &
211 PLL_FRAC_CTRL2_POSTDIV2_MASK;
212 if (enabled &&
213 (params->postdiv1 != old_postdiv1 ||
214 params->postdiv2 != old_postdiv2))
215 pr_warn("%s: changing postdiv while PLL is enabled\n", name);
216
217 if (params->postdiv2 > params->postdiv1)
218 pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
219
171 val &= ~((PLL_FRAC_CTRL2_FRAC_MASK << PLL_FRAC_CTRL2_FRAC_SHIFT) | 220 val &= ~((PLL_FRAC_CTRL2_FRAC_MASK << PLL_FRAC_CTRL2_FRAC_SHIFT) |
172 (PLL_FRAC_CTRL2_POSTDIV1_MASK << 221 (PLL_FRAC_CTRL2_POSTDIV1_MASK <<
173 PLL_FRAC_CTRL2_POSTDIV1_SHIFT) | 222 PLL_FRAC_CTRL2_POSTDIV1_SHIFT) |
@@ -178,11 +227,8 @@ static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
178 (params->postdiv2 << PLL_FRAC_CTRL2_POSTDIV2_SHIFT); 227 (params->postdiv2 << PLL_FRAC_CTRL2_POSTDIV2_SHIFT);
179 pll_writel(pll, val, PLL_CTRL2); 228 pll_writel(pll, val, PLL_CTRL2);
180 229
181 while (!(pll_readl(pll, PLL_STATUS) & PLL_STATUS_LOCK)) 230 if (enabled)
182 cpu_relax(); 231 pll_lock(pll);
183
184 if (!was_enabled)
185 pll_gf40lp_frac_disable(hw);
186 232
187 return 0; 233 return 0;
188} 234}
@@ -241,6 +287,8 @@ static int pll_gf40lp_laint_enable(struct clk_hw *hw)
241 val &= ~PLL_INT_CTRL2_BYPASS; 287 val &= ~PLL_INT_CTRL2_BYPASS;
242 pll_writel(pll, val, PLL_CTRL2); 288 pll_writel(pll, val, PLL_CTRL2);
243 289
290 pll_lock(pll);
291
244 return 0; 292 return 0;
245} 293}
246 294
@@ -266,18 +314,44 @@ static int pll_gf40lp_laint_set_rate(struct clk_hw *hw, unsigned long rate,
266{ 314{
267 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 315 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
268 struct pistachio_pll_rate_table *params; 316 struct pistachio_pll_rate_table *params;
269 bool was_enabled; 317 int enabled = pll_gf40lp_laint_is_enabled(hw);
270 u32 val; 318 u32 val, vco, old_postdiv1, old_postdiv2;
319 const char *name = __clk_get_name(hw->clk);
320
321 if (rate < MIN_OUTPUT_LA || rate > MAX_OUTPUT_LA)
322 return -EINVAL;
271 323
272 params = pll_get_params(pll, parent_rate, rate); 324 params = pll_get_params(pll, parent_rate, rate);
273 if (!params) 325 if (!params || !params->refdiv)
274 return -EINVAL; 326 return -EINVAL;
275 327
276 was_enabled = pll_gf40lp_laint_is_enabled(hw); 328 vco = params->fref * params->fbdiv / params->refdiv;
277 if (!was_enabled) 329 if (vco < MIN_VCO_LA || vco > MAX_VCO_LA)
278 pll_gf40lp_laint_enable(hw); 330 pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco,
331 MIN_VCO_LA, MAX_VCO_LA);
332
333 val = params->fref / params->refdiv;
334 if (val < MIN_PFD)
335 pr_warn("%s: PFD %u is too low (min %lu)\n",
336 name, val, MIN_PFD);
337 if (val > vco / 16)
338 pr_warn("%s: PFD %u is too high (max %u)\n",
339 name, val, vco / 16);
279 340
280 val = pll_readl(pll, PLL_CTRL1); 341 val = pll_readl(pll, PLL_CTRL1);
342
343 old_postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) &
344 PLL_INT_CTRL1_POSTDIV1_MASK;
345 old_postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) &
346 PLL_INT_CTRL1_POSTDIV2_MASK;
347 if (enabled &&
348 (params->postdiv1 != old_postdiv1 ||
349 params->postdiv2 != old_postdiv2))
350 pr_warn("%s: changing postdiv while PLL is enabled\n", name);
351
352 if (params->postdiv2 > params->postdiv1)
353 pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
354
281 val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) | 355 val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
282 (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT) | 356 (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT) |
283 (PLL_INT_CTRL1_POSTDIV1_MASK << PLL_INT_CTRL1_POSTDIV1_SHIFT) | 357 (PLL_INT_CTRL1_POSTDIV1_MASK << PLL_INT_CTRL1_POSTDIV1_SHIFT) |
@@ -288,11 +362,8 @@ static int pll_gf40lp_laint_set_rate(struct clk_hw *hw, unsigned long rate,
288 (params->postdiv2 << PLL_INT_CTRL1_POSTDIV2_SHIFT); 362 (params->postdiv2 << PLL_INT_CTRL1_POSTDIV2_SHIFT);
289 pll_writel(pll, val, PLL_CTRL1); 363 pll_writel(pll, val, PLL_CTRL1);
290 364
291 while (!(pll_readl(pll, PLL_STATUS) & PLL_STATUS_LOCK)) 365 if (enabled)
292 cpu_relax(); 366 pll_lock(pll);
293
294 if (!was_enabled)
295 pll_gf40lp_laint_disable(hw);
296 367
297 return 0; 368 return 0;
298} 369}
diff --git a/drivers/clk/pxa/clk-pxa.h b/drivers/clk/pxa/clk-pxa.h
index b04c5b9c0ea8..d1de805df867 100644
--- a/drivers/clk/pxa/clk-pxa.h
+++ b/drivers/clk/pxa/clk-pxa.h
@@ -14,7 +14,7 @@
14#define _CLK_PXA_ 14#define _CLK_PXA_
15 15
16#define PARENTS(name) \ 16#define PARENTS(name) \
17 static const char *name ## _parents[] __initdata 17 static const char *const name ## _parents[] __initconst
18#define MUX_RO_RATE_RO_OPS(name, clk_name) \ 18#define MUX_RO_RATE_RO_OPS(name, clk_name) \
19 static struct clk_hw name ## _mux_hw; \ 19 static struct clk_hw name ## _mux_hw; \
20 static struct clk_hw name ## _rate_hw; \ 20 static struct clk_hw name ## _rate_hw; \
@@ -72,7 +72,7 @@ struct desc_clk_cken {
72 const char *name; 72 const char *name;
73 const char *dev_id; 73 const char *dev_id;
74 const char *con_id; 74 const char *con_id;
75 const char **parent_names; 75 const char * const *parent_names;
76 struct clk_fixed_factor lp; 76 struct clk_fixed_factor lp;
77 struct clk_fixed_factor hp; 77 struct clk_fixed_factor hp;
78 struct clk_gate gate; 78 struct clk_gate gate;
diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c
index 8539c4fd34cc..fb7721bd37e6 100644
--- a/drivers/clk/rockchip/clk-cpu.c
+++ b/drivers/clk/rockchip/clk-cpu.c
@@ -231,7 +231,7 @@ static int rockchip_cpuclk_notifier_cb(struct notifier_block *nb,
231} 231}
232 232
233struct clk *rockchip_clk_register_cpuclk(const char *name, 233struct clk *rockchip_clk_register_cpuclk(const char *name,
234 const char **parent_names, u8 num_parents, 234 const char *const *parent_names, u8 num_parents,
235 const struct rockchip_cpuclk_reg_data *reg_data, 235 const struct rockchip_cpuclk_reg_data *reg_data,
236 const struct rockchip_cpuclk_rate_table *rates, 236 const struct rockchip_cpuclk_rate_table *rates,
237 int nrates, void __iomem *reg_base, spinlock_t *lock) 237 int nrates, void __iomem *reg_base, spinlock_t *lock)
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index c842e3b60f21..e9f8df324e7c 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -120,7 +120,7 @@ static const struct clk_ops rockchip_mmc_clk_ops = {
120}; 120};
121 121
122struct clk *rockchip_clk_register_mmc(const char *name, 122struct clk *rockchip_clk_register_mmc(const char *name,
123 const char **parent_names, u8 num_parents, 123 const char *const *parent_names, u8 num_parents,
124 void __iomem *reg, int shift) 124 void __iomem *reg, int shift)
125{ 125{
126 struct clk_init_data init; 126 struct clk_init_data init;
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index f8d3baf275b2..76027261f7ed 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -329,10 +329,10 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
329 */ 329 */
330 330
331struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, 331struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
332 const char *name, const char **parent_names, u8 num_parents, 332 const char *name, const char *const *parent_names,
333 void __iomem *base, int con_offset, int grf_lock_offset, 333 u8 num_parents, void __iomem *base, int con_offset,
334 int lock_shift, int mode_offset, int mode_shift, 334 int grf_lock_offset, int lock_shift, int mode_offset,
335 struct rockchip_pll_rate_table *rate_table, 335 int mode_shift, struct rockchip_pll_rate_table *rate_table,
336 u8 clk_pll_flags, spinlock_t *lock) 336 u8 clk_pll_flags, spinlock_t *lock)
337{ 337{
338 const char *pll_parents[3]; 338 const char *pll_parents[3];
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index 556ce041d371..e4f9d472f1ff 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -26,7 +26,7 @@ enum rk3188_plls {
26 apll, cpll, dpll, gpll, 26 apll, cpll, dpll, gpll,
27}; 27};
28 28
29struct rockchip_pll_rate_table rk3188_pll_rates[] = { 29static struct rockchip_pll_rate_table rk3188_pll_rates[] = {
30 RK3066_PLL_RATE(2208000000, 1, 92, 1), 30 RK3066_PLL_RATE(2208000000, 1, 92, 1),
31 RK3066_PLL_RATE(2184000000, 1, 91, 1), 31 RK3066_PLL_RATE(2184000000, 1, 91, 1),
32 RK3066_PLL_RATE(2160000000, 1, 90, 1), 32 RK3066_PLL_RATE(2160000000, 1, 90, 1),
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index d17eb4528a28..4f817ed9e6ee 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -27,7 +27,7 @@ enum rk3288_plls {
27 apll, dpll, cpll, gpll, npll, 27 apll, dpll, cpll, gpll, npll,
28}; 28};
29 29
30struct rockchip_pll_rate_table rk3288_pll_rates[] = { 30static struct rockchip_pll_rate_table rk3288_pll_rates[] = {
31 RK3066_PLL_RATE(2208000000, 1, 92, 1), 31 RK3066_PLL_RATE(2208000000, 1, 92, 1),
32 RK3066_PLL_RATE(2184000000, 1, 91, 1), 32 RK3066_PLL_RATE(2184000000, 1, 91, 1),
33 RK3066_PLL_RATE(2160000000, 1, 90, 1), 33 RK3066_PLL_RATE(2160000000, 1, 90, 1),
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index edb5d489ae61..052b94db0ff9 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -39,7 +39,7 @@
39 * sometimes without one of those components. 39 * sometimes without one of those components.
40 */ 40 */
41static struct clk *rockchip_clk_register_branch(const char *name, 41static struct clk *rockchip_clk_register_branch(const char *name,
42 const char **parent_names, u8 num_parents, void __iomem *base, 42 const char *const *parent_names, u8 num_parents, void __iomem *base,
43 int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags, 43 int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
44 u8 div_shift, u8 div_width, u8 div_flags, 44 u8 div_shift, u8 div_width, u8 div_flags,
45 struct clk_div_table *div_table, int gate_offset, 45 struct clk_div_table *div_table, int gate_offset,
@@ -103,8 +103,8 @@ static struct clk *rockchip_clk_register_branch(const char *name,
103} 103}
104 104
105static struct clk *rockchip_clk_register_frac_branch(const char *name, 105static struct clk *rockchip_clk_register_frac_branch(const char *name,
106 const char **parent_names, u8 num_parents, void __iomem *base, 106 const char *const *parent_names, u8 num_parents,
107 int muxdiv_offset, u8 div_flags, 107 void __iomem *base, int muxdiv_offset, u8 div_flags,
108 int gate_offset, u8 gate_shift, u8 gate_flags, 108 int gate_offset, u8 gate_shift, u8 gate_flags,
109 unsigned long flags, spinlock_t *lock) 109 unsigned long flags, spinlock_t *lock)
110{ 110{
@@ -297,7 +297,7 @@ void __init rockchip_clk_register_branches(
297} 297}
298 298
299void __init rockchip_clk_register_armclk(unsigned int lookup_id, 299void __init rockchip_clk_register_armclk(unsigned int lookup_id,
300 const char *name, const char **parent_names, 300 const char *name, const char *const *parent_names,
301 u8 num_parents, 301 u8 num_parents,
302 const struct rockchip_cpuclk_reg_data *reg_data, 302 const struct rockchip_cpuclk_reg_data *reg_data,
303 const struct rockchip_cpuclk_rate_table *rates, 303 const struct rockchip_cpuclk_rate_table *rates,
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index e63cafe893e1..6b092673048a 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -108,7 +108,7 @@ struct rockchip_pll_rate_table {
108struct rockchip_pll_clock { 108struct rockchip_pll_clock {
109 unsigned int id; 109 unsigned int id;
110 const char *name; 110 const char *name;
111 const char **parent_names; 111 const char *const *parent_names;
112 u8 num_parents; 112 u8 num_parents;
113 unsigned long flags; 113 unsigned long flags;
114 int con_offset; 114 int con_offset;
@@ -140,10 +140,10 @@ struct rockchip_pll_clock {
140 } 140 }
141 141
142struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, 142struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
143 const char *name, const char **parent_names, u8 num_parents, 143 const char *name, const char *const *parent_names,
144 void __iomem *base, int con_offset, int grf_lock_offset, 144 u8 num_parents, void __iomem *base, int con_offset,
145 int lock_shift, int reg_mode, int mode_shift, 145 int grf_lock_offset, int lock_shift, int reg_mode,
146 struct rockchip_pll_rate_table *rate_table, 146 int mode_shift, struct rockchip_pll_rate_table *rate_table,
147 u8 clk_pll_flags, spinlock_t *lock); 147 u8 clk_pll_flags, spinlock_t *lock);
148 148
149struct rockchip_cpuclk_clksel { 149struct rockchip_cpuclk_clksel {
@@ -173,16 +173,16 @@ struct rockchip_cpuclk_reg_data {
173}; 173};
174 174
175struct clk *rockchip_clk_register_cpuclk(const char *name, 175struct clk *rockchip_clk_register_cpuclk(const char *name,
176 const char **parent_names, u8 num_parents, 176 const char *const *parent_names, u8 num_parents,
177 const struct rockchip_cpuclk_reg_data *reg_data, 177 const struct rockchip_cpuclk_reg_data *reg_data,
178 const struct rockchip_cpuclk_rate_table *rates, 178 const struct rockchip_cpuclk_rate_table *rates,
179 int nrates, void __iomem *reg_base, spinlock_t *lock); 179 int nrates, void __iomem *reg_base, spinlock_t *lock);
180 180
181struct clk *rockchip_clk_register_mmc(const char *name, 181struct clk *rockchip_clk_register_mmc(const char *name,
182 const char **parent_names, u8 num_parents, 182 const char *const *parent_names, u8 num_parents,
183 void __iomem *reg, int shift); 183 void __iomem *reg, int shift);
184 184
185#define PNAME(x) static const char *x[] __initdata 185#define PNAME(x) static const char *const x[] __initconst
186 186
187enum rockchip_clk_branch_type { 187enum rockchip_clk_branch_type {
188 branch_composite, 188 branch_composite,
@@ -197,7 +197,7 @@ struct rockchip_clk_branch {
197 unsigned int id; 197 unsigned int id;
198 enum rockchip_clk_branch_type branch_type; 198 enum rockchip_clk_branch_type branch_type;
199 const char *name; 199 const char *name;
200 const char **parent_names; 200 const char *const *parent_names;
201 u8 num_parents; 201 u8 num_parents;
202 unsigned long flags; 202 unsigned long flags;
203 int muxdiv_offset; 203 int muxdiv_offset;
@@ -403,7 +403,7 @@ void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list,
403void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list, 403void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list,
404 unsigned int nr_pll, int grf_lock_offset); 404 unsigned int nr_pll, int grf_lock_offset);
405void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name, 405void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name,
406 const char **parent_names, u8 num_parents, 406 const char *const *parent_names, u8 num_parents,
407 const struct rockchip_cpuclk_reg_data *reg_data, 407 const struct rockchip_cpuclk_reg_data *reg_data,
408 const struct rockchip_cpuclk_rate_table *rates, 408 const struct rockchip_cpuclk_rate_table *rates,
409 int nrates); 409 int nrates);
diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c
index e2e5193d1049..06f96eb7cf93 100644
--- a/drivers/clk/samsung/clk-exynos5260.c
+++ b/drivers/clk/samsung/clk-exynos5260.c
@@ -94,7 +94,7 @@ PNAME(mout_aud_pll_user_p) = {"fin_pll", "fout_aud_pll"};
94PNAME(mout_sclk_aud_i2s_p) = {"mout_aud_pll_user", "ioclk_i2s_cdclk"}; 94PNAME(mout_sclk_aud_i2s_p) = {"mout_aud_pll_user", "ioclk_i2s_cdclk"};
95PNAME(mout_sclk_aud_pcm_p) = {"mout_aud_pll_user", "ioclk_pcm_extclk"}; 95PNAME(mout_sclk_aud_pcm_p) = {"mout_aud_pll_user", "ioclk_pcm_extclk"};
96 96
97struct samsung_mux_clock aud_mux_clks[] __initdata = { 97static struct samsung_mux_clock aud_mux_clks[] __initdata = {
98 MUX(AUD_MOUT_AUD_PLL_USER, "mout_aud_pll_user", mout_aud_pll_user_p, 98 MUX(AUD_MOUT_AUD_PLL_USER, "mout_aud_pll_user", mout_aud_pll_user_p,
99 MUX_SEL_AUD, 0, 1), 99 MUX_SEL_AUD, 0, 1),
100 MUX(AUD_MOUT_SCLK_AUD_I2S, "mout_sclk_aud_i2s", mout_sclk_aud_i2s_p, 100 MUX(AUD_MOUT_SCLK_AUD_I2S, "mout_sclk_aud_i2s", mout_sclk_aud_i2s_p,
@@ -103,7 +103,7 @@ struct samsung_mux_clock aud_mux_clks[] __initdata = {
103 MUX_SEL_AUD, 8, 1), 103 MUX_SEL_AUD, 8, 1),
104}; 104};
105 105
106struct samsung_div_clock aud_div_clks[] __initdata = { 106static struct samsung_div_clock aud_div_clks[] __initdata = {
107 DIV(AUD_DOUT_ACLK_AUD_131, "dout_aclk_aud_131", "mout_aud_pll_user", 107 DIV(AUD_DOUT_ACLK_AUD_131, "dout_aclk_aud_131", "mout_aud_pll_user",
108 DIV_AUD0, 0, 4), 108 DIV_AUD0, 0, 4),
109 109
@@ -115,7 +115,7 @@ struct samsung_div_clock aud_div_clks[] __initdata = {
115 DIV_AUD1, 12, 4), 115 DIV_AUD1, 12, 4),
116}; 116};
117 117
118struct samsung_gate_clock aud_gate_clks[] __initdata = { 118static struct samsung_gate_clock aud_gate_clks[] __initdata = {
119 GATE(AUD_SCLK_I2S, "sclk_aud_i2s", "dout_sclk_aud_i2s", 119 GATE(AUD_SCLK_I2S, "sclk_aud_i2s", "dout_sclk_aud_i2s",
120 EN_SCLK_AUD, 0, CLK_SET_RATE_PARENT, 0), 120 EN_SCLK_AUD, 0, CLK_SET_RATE_PARENT, 0),
121 GATE(AUD_SCLK_PCM, "sclk_aud_pcm", "dout_sclk_aud_pcm", 121 GATE(AUD_SCLK_PCM, "sclk_aud_pcm", "dout_sclk_aud_pcm",
@@ -135,7 +135,7 @@ struct samsung_gate_clock aud_gate_clks[] __initdata = {
135 135
136static void __init exynos5260_clk_aud_init(struct device_node *np) 136static void __init exynos5260_clk_aud_init(struct device_node *np)
137{ 137{
138 struct samsung_cmu_info cmu = {0}; 138 struct samsung_cmu_info cmu = { NULL };
139 139
140 cmu.mux_clks = aud_mux_clks; 140 cmu.mux_clks = aud_mux_clks;
141 cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks); 141 cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks);
@@ -203,7 +203,7 @@ PNAME(mout_phyclk_mipi_dphy_4lmrxclk_esc0_user_p) = {"fin_pll",
203PNAME(mout_sclk_hdmi_spdif_p) = {"fin_pll", "ioclk_spdif_extclk", 203PNAME(mout_sclk_hdmi_spdif_p) = {"fin_pll", "ioclk_spdif_extclk",
204 "dout_aclk_peri_aud", "phyclk_hdmi_phy_ref_cko"}; 204 "dout_aclk_peri_aud", "phyclk_hdmi_phy_ref_cko"};
205 205
206struct samsung_mux_clock disp_mux_clks[] __initdata = { 206static struct samsung_mux_clock disp_mux_clks[] __initdata = {
207 MUX(DISP_MOUT_ACLK_DISP_333_USER, "mout_aclk_disp_333_user", 207 MUX(DISP_MOUT_ACLK_DISP_333_USER, "mout_aclk_disp_333_user",
208 mout_aclk_disp_333_user_p, 208 mout_aclk_disp_333_user_p,
209 MUX_SEL_DISP0, 0, 1), 209 MUX_SEL_DISP0, 0, 1),
@@ -272,7 +272,7 @@ struct samsung_mux_clock disp_mux_clks[] __initdata = {
272 MUX_SEL_DISP4, 4, 2), 272 MUX_SEL_DISP4, 4, 2),
273}; 273};
274 274
275struct samsung_div_clock disp_div_clks[] __initdata = { 275static struct samsung_div_clock disp_div_clks[] __initdata = {
276 DIV(DISP_DOUT_PCLK_DISP_111, "dout_pclk_disp_111", 276 DIV(DISP_DOUT_PCLK_DISP_111, "dout_pclk_disp_111",
277 "mout_aclk_disp_222_user", 277 "mout_aclk_disp_222_user",
278 DIV_DISP, 8, 4), 278 DIV_DISP, 8, 4),
@@ -285,7 +285,7 @@ struct samsung_div_clock disp_div_clks[] __initdata = {
285 DIV_DISP, 16, 4), 285 DIV_DISP, 16, 4),
286}; 286};
287 287
288struct samsung_gate_clock disp_gate_clks[] __initdata = { 288static struct samsung_gate_clock disp_gate_clks[] __initdata = {
289 GATE(DISP_MOUT_HDMI_PHY_PIXEL_USER, "sclk_hdmi_link_i_pixel", 289 GATE(DISP_MOUT_HDMI_PHY_PIXEL_USER, "sclk_hdmi_link_i_pixel",
290 "mout_phyclk_hdmi_phy_pixel_clko_user", 290 "mout_phyclk_hdmi_phy_pixel_clko_user",
291 EN_SCLK_DISP0, 26, CLK_SET_RATE_PARENT, 0), 291 EN_SCLK_DISP0, 26, CLK_SET_RATE_PARENT, 0),
@@ -325,7 +325,7 @@ struct samsung_gate_clock disp_gate_clks[] __initdata = {
325 325
326static void __init exynos5260_clk_disp_init(struct device_node *np) 326static void __init exynos5260_clk_disp_init(struct device_node *np)
327{ 327{
328 struct samsung_cmu_info cmu = {0}; 328 struct samsung_cmu_info cmu = { NULL };
329 329
330 cmu.mux_clks = disp_mux_clks; 330 cmu.mux_clks = disp_mux_clks;
331 cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks); 331 cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks);
@@ -363,13 +363,13 @@ static unsigned long egl_clk_regs[] __initdata = {
363PNAME(mout_egl_b_p) = {"mout_egl_pll", "dout_bus_pll"}; 363PNAME(mout_egl_b_p) = {"mout_egl_pll", "dout_bus_pll"};
364PNAME(mout_egl_pll_p) = {"fin_pll", "fout_egl_pll"}; 364PNAME(mout_egl_pll_p) = {"fin_pll", "fout_egl_pll"};
365 365
366struct samsung_mux_clock egl_mux_clks[] __initdata = { 366static struct samsung_mux_clock egl_mux_clks[] __initdata = {
367 MUX(EGL_MOUT_EGL_PLL, "mout_egl_pll", mout_egl_pll_p, 367 MUX(EGL_MOUT_EGL_PLL, "mout_egl_pll", mout_egl_pll_p,
368 MUX_SEL_EGL, 4, 1), 368 MUX_SEL_EGL, 4, 1),
369 MUX(EGL_MOUT_EGL_B, "mout_egl_b", mout_egl_b_p, MUX_SEL_EGL, 16, 1), 369 MUX(EGL_MOUT_EGL_B, "mout_egl_b", mout_egl_b_p, MUX_SEL_EGL, 16, 1),
370}; 370};
371 371
372struct samsung_div_clock egl_div_clks[] __initdata = { 372static struct samsung_div_clock egl_div_clks[] __initdata = {
373 DIV(EGL_DOUT_EGL1, "dout_egl1", "mout_egl_b", DIV_EGL, 0, 3), 373 DIV(EGL_DOUT_EGL1, "dout_egl1", "mout_egl_b", DIV_EGL, 0, 3),
374 DIV(EGL_DOUT_EGL2, "dout_egl2", "dout_egl1", DIV_EGL, 4, 3), 374 DIV(EGL_DOUT_EGL2, "dout_egl2", "dout_egl1", DIV_EGL, 4, 3),
375 DIV(EGL_DOUT_ACLK_EGL, "dout_aclk_egl", "dout_egl2", DIV_EGL, 8, 3), 375 DIV(EGL_DOUT_ACLK_EGL, "dout_aclk_egl", "dout_egl2", DIV_EGL, 8, 3),
@@ -389,7 +389,7 @@ static struct samsung_pll_clock egl_pll_clks[] __initdata = {
389 389
390static void __init exynos5260_clk_egl_init(struct device_node *np) 390static void __init exynos5260_clk_egl_init(struct device_node *np)
391{ 391{
392 struct samsung_cmu_info cmu = {0}; 392 struct samsung_cmu_info cmu = { NULL };
393 393
394 cmu.pll_clks = egl_pll_clks; 394 cmu.pll_clks = egl_pll_clks;
395 cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks); 395 cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks);
@@ -433,7 +433,7 @@ PNAME(mout_phyclk_usbdrd30_pipe_pclk_user_p) = {"fin_pll",
433PNAME(mout_phyclk_usbdrd30_phyclock_user_p) = {"fin_pll", 433PNAME(mout_phyclk_usbdrd30_phyclock_user_p) = {"fin_pll",
434 "phyclk_usbdrd30_udrd30_phyclock"}; 434 "phyclk_usbdrd30_udrd30_phyclock"};
435 435
436struct samsung_mux_clock fsys_mux_clks[] __initdata = { 436static struct samsung_mux_clock fsys_mux_clks[] __initdata = {
437 MUX(FSYS_MOUT_PHYCLK_USBDRD30_PHYCLOCK_USER, 437 MUX(FSYS_MOUT_PHYCLK_USBDRD30_PHYCLOCK_USER,
438 "mout_phyclk_usbdrd30_phyclock_user", 438 "mout_phyclk_usbdrd30_phyclock_user",
439 mout_phyclk_usbdrd30_phyclock_user_p, 439 mout_phyclk_usbdrd30_phyclock_user_p,
@@ -456,7 +456,7 @@ struct samsung_mux_clock fsys_mux_clks[] __initdata = {
456 MUX_SEL_FSYS1, 16, 1), 456 MUX_SEL_FSYS1, 16, 1),
457}; 457};
458 458
459struct samsung_gate_clock fsys_gate_clks[] __initdata = { 459static struct samsung_gate_clock fsys_gate_clks[] __initdata = {
460 GATE(FSYS_PHYCLK_USBHOST20, "phyclk_usbhost20_phyclock", 460 GATE(FSYS_PHYCLK_USBHOST20, "phyclk_usbhost20_phyclock",
461 "mout_phyclk_usbdrd30_phyclock_user", 461 "mout_phyclk_usbdrd30_phyclock_user",
462 EN_SCLK_FSYS, 1, 0, 0), 462 EN_SCLK_FSYS, 1, 0, 0),
@@ -491,7 +491,7 @@ struct samsung_gate_clock fsys_gate_clks[] __initdata = {
491 491
492static void __init exynos5260_clk_fsys_init(struct device_node *np) 492static void __init exynos5260_clk_fsys_init(struct device_node *np)
493{ 493{
494 struct samsung_cmu_info cmu = {0}; 494 struct samsung_cmu_info cmu = { NULL };
495 495
496 cmu.mux_clks = fsys_mux_clks; 496 cmu.mux_clks = fsys_mux_clks;
497 cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks); 497 cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks);
@@ -537,18 +537,18 @@ static unsigned long g2d_clk_regs[] __initdata = {
537 537
538PNAME(mout_aclk_g2d_333_user_p) = {"fin_pll", "dout_aclk_g2d_333"}; 538PNAME(mout_aclk_g2d_333_user_p) = {"fin_pll", "dout_aclk_g2d_333"};
539 539
540struct samsung_mux_clock g2d_mux_clks[] __initdata = { 540static struct samsung_mux_clock g2d_mux_clks[] __initdata = {
541 MUX(G2D_MOUT_ACLK_G2D_333_USER, "mout_aclk_g2d_333_user", 541 MUX(G2D_MOUT_ACLK_G2D_333_USER, "mout_aclk_g2d_333_user",
542 mout_aclk_g2d_333_user_p, 542 mout_aclk_g2d_333_user_p,
543 MUX_SEL_G2D, 0, 1), 543 MUX_SEL_G2D, 0, 1),
544}; 544};
545 545
546struct samsung_div_clock g2d_div_clks[] __initdata = { 546static struct samsung_div_clock g2d_div_clks[] __initdata = {
547 DIV(G2D_DOUT_PCLK_G2D_83, "dout_pclk_g2d_83", "mout_aclk_g2d_333_user", 547 DIV(G2D_DOUT_PCLK_G2D_83, "dout_pclk_g2d_83", "mout_aclk_g2d_333_user",
548 DIV_G2D, 0, 3), 548 DIV_G2D, 0, 3),
549}; 549};
550 550
551struct samsung_gate_clock g2d_gate_clks[] __initdata = { 551static struct samsung_gate_clock g2d_gate_clks[] __initdata = {
552 GATE(G2D_CLK_G2D, "clk_g2d", "mout_aclk_g2d_333_user", 552 GATE(G2D_CLK_G2D, "clk_g2d", "mout_aclk_g2d_333_user",
553 EN_IP_G2D, 4, 0, 0), 553 EN_IP_G2D, 4, 0, 0),
554 GATE(G2D_CLK_JPEG, "clk_jpeg", "mout_aclk_g2d_333_user", 554 GATE(G2D_CLK_JPEG, "clk_jpeg", "mout_aclk_g2d_333_user",
@@ -580,7 +580,7 @@ struct samsung_gate_clock g2d_gate_clks[] __initdata = {
580 580
581static void __init exynos5260_clk_g2d_init(struct device_node *np) 581static void __init exynos5260_clk_g2d_init(struct device_node *np)
582{ 582{
583 struct samsung_cmu_info cmu = {0}; 583 struct samsung_cmu_info cmu = { NULL };
584 584
585 cmu.mux_clks = g2d_mux_clks; 585 cmu.mux_clks = g2d_mux_clks;
586 cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks); 586 cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks);
@@ -617,17 +617,17 @@ static unsigned long g3d_clk_regs[] __initdata = {
617 617
618PNAME(mout_g3d_pll_p) = {"fin_pll", "fout_g3d_pll"}; 618PNAME(mout_g3d_pll_p) = {"fin_pll", "fout_g3d_pll"};
619 619
620struct samsung_mux_clock g3d_mux_clks[] __initdata = { 620static struct samsung_mux_clock g3d_mux_clks[] __initdata = {
621 MUX(G3D_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p, 621 MUX(G3D_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p,
622 MUX_SEL_G3D, 0, 1), 622 MUX_SEL_G3D, 0, 1),
623}; 623};
624 624
625struct samsung_div_clock g3d_div_clks[] __initdata = { 625static struct samsung_div_clock g3d_div_clks[] __initdata = {
626 DIV(G3D_DOUT_PCLK_G3D, "dout_pclk_g3d", "dout_aclk_g3d", DIV_G3D, 0, 3), 626 DIV(G3D_DOUT_PCLK_G3D, "dout_pclk_g3d", "dout_aclk_g3d", DIV_G3D, 0, 3),
627 DIV(G3D_DOUT_ACLK_G3D, "dout_aclk_g3d", "mout_g3d_pll", DIV_G3D, 4, 3), 627 DIV(G3D_DOUT_ACLK_G3D, "dout_aclk_g3d", "mout_g3d_pll", DIV_G3D, 4, 3),
628}; 628};
629 629
630struct samsung_gate_clock g3d_gate_clks[] __initdata = { 630static struct samsung_gate_clock g3d_gate_clks[] __initdata = {
631 GATE(G3D_CLK_G3D, "clk_g3d", "dout_aclk_g3d", EN_IP_G3D, 2, 0, 0), 631 GATE(G3D_CLK_G3D, "clk_g3d", "dout_aclk_g3d", EN_IP_G3D, 2, 0, 0),
632 GATE(G3D_CLK_G3D_HPM, "clk_g3d_hpm", "dout_aclk_g3d", 632 GATE(G3D_CLK_G3D_HPM, "clk_g3d_hpm", "dout_aclk_g3d",
633 EN_IP_G3D, 3, 0, 0), 633 EN_IP_G3D, 3, 0, 0),
@@ -641,7 +641,7 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = {
641 641
642static void __init exynos5260_clk_g3d_init(struct device_node *np) 642static void __init exynos5260_clk_g3d_init(struct device_node *np)
643{ 643{
644 struct samsung_cmu_info cmu = {0}; 644 struct samsung_cmu_info cmu = { NULL };
645 645
646 cmu.pll_clks = g3d_pll_clks; 646 cmu.pll_clks = g3d_pll_clks;
647 cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks); 647 cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks);
@@ -694,7 +694,7 @@ PNAME(mout_aclk_m2m_400_user_p) = {"fin_pll", "dout_aclk_gscl_400"};
694PNAME(mout_aclk_gscl_fimc_user_p) = {"fin_pll", "dout_aclk_gscl_400"}; 694PNAME(mout_aclk_gscl_fimc_user_p) = {"fin_pll", "dout_aclk_gscl_400"};
695PNAME(mout_aclk_csis_p) = {"dout_aclk_csis_200", "mout_aclk_gscl_fimc_user"}; 695PNAME(mout_aclk_csis_p) = {"dout_aclk_csis_200", "mout_aclk_gscl_fimc_user"};
696 696
697struct samsung_mux_clock gscl_mux_clks[] __initdata = { 697static struct samsung_mux_clock gscl_mux_clks[] __initdata = {
698 MUX(GSCL_MOUT_ACLK_GSCL_333_USER, "mout_aclk_gscl_333_user", 698 MUX(GSCL_MOUT_ACLK_GSCL_333_USER, "mout_aclk_gscl_333_user",
699 mout_aclk_gscl_333_user_p, 699 mout_aclk_gscl_333_user_p,
700 MUX_SEL_GSCL, 0, 1), 700 MUX_SEL_GSCL, 0, 1),
@@ -708,7 +708,7 @@ struct samsung_mux_clock gscl_mux_clks[] __initdata = {
708 MUX_SEL_GSCL, 24, 1), 708 MUX_SEL_GSCL, 24, 1),
709}; 709};
710 710
711struct samsung_div_clock gscl_div_clks[] __initdata = { 711static struct samsung_div_clock gscl_div_clks[] __initdata = {
712 DIV(GSCL_DOUT_PCLK_M2M_100, "dout_pclk_m2m_100", 712 DIV(GSCL_DOUT_PCLK_M2M_100, "dout_pclk_m2m_100",
713 "mout_aclk_m2m_400_user", 713 "mout_aclk_m2m_400_user",
714 DIV_GSCL, 0, 3), 714 DIV_GSCL, 0, 3),
@@ -717,7 +717,7 @@ struct samsung_div_clock gscl_div_clks[] __initdata = {
717 DIV_GSCL, 4, 3), 717 DIV_GSCL, 4, 3),
718}; 718};
719 719
720struct samsung_gate_clock gscl_gate_clks[] __initdata = { 720static struct samsung_gate_clock gscl_gate_clks[] __initdata = {
721 GATE(GSCL_SCLK_CSIS0_WRAP, "sclk_csis0_wrap", "dout_aclk_csis_200", 721 GATE(GSCL_SCLK_CSIS0_WRAP, "sclk_csis0_wrap", "dout_aclk_csis_200",
722 EN_SCLK_GSCL_FIMC, 0, CLK_SET_RATE_PARENT, 0), 722 EN_SCLK_GSCL_FIMC, 0, CLK_SET_RATE_PARENT, 0),
723 GATE(GSCL_SCLK_CSIS1_WRAP, "sclk_csis1_wrap", "dout_aclk_csis_200", 723 GATE(GSCL_SCLK_CSIS1_WRAP, "sclk_csis1_wrap", "dout_aclk_csis_200",
@@ -776,7 +776,7 @@ struct samsung_gate_clock gscl_gate_clks[] __initdata = {
776 776
777static void __init exynos5260_clk_gscl_init(struct device_node *np) 777static void __init exynos5260_clk_gscl_init(struct device_node *np)
778{ 778{
779 struct samsung_cmu_info cmu = {0}; 779 struct samsung_cmu_info cmu = { NULL };
780 780
781 cmu.mux_clks = gscl_mux_clks; 781 cmu.mux_clks = gscl_mux_clks;
782 cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks); 782 cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks);
@@ -813,14 +813,14 @@ static unsigned long isp_clk_regs[] __initdata = {
813PNAME(mout_isp_400_user_p) = {"fin_pll", "dout_aclk_isp1_400"}; 813PNAME(mout_isp_400_user_p) = {"fin_pll", "dout_aclk_isp1_400"};
814PNAME(mout_isp_266_user_p) = {"fin_pll", "dout_aclk_isp1_266"}; 814PNAME(mout_isp_266_user_p) = {"fin_pll", "dout_aclk_isp1_266"};
815 815
816struct samsung_mux_clock isp_mux_clks[] __initdata = { 816static struct samsung_mux_clock isp_mux_clks[] __initdata = {
817 MUX(ISP_MOUT_ISP_266_USER, "mout_isp_266_user", mout_isp_266_user_p, 817 MUX(ISP_MOUT_ISP_266_USER, "mout_isp_266_user", mout_isp_266_user_p,
818 MUX_SEL_ISP0, 0, 1), 818 MUX_SEL_ISP0, 0, 1),
819 MUX(ISP_MOUT_ISP_400_USER, "mout_isp_400_user", mout_isp_400_user_p, 819 MUX(ISP_MOUT_ISP_400_USER, "mout_isp_400_user", mout_isp_400_user_p,
820 MUX_SEL_ISP0, 4, 1), 820 MUX_SEL_ISP0, 4, 1),
821}; 821};
822 822
823struct samsung_div_clock isp_div_clks[] __initdata = { 823static struct samsung_div_clock isp_div_clks[] __initdata = {
824 DIV(ISP_DOUT_PCLK_ISP_66, "dout_pclk_isp_66", "mout_kfc", 824 DIV(ISP_DOUT_PCLK_ISP_66, "dout_pclk_isp_66", "mout_kfc",
825 DIV_ISP, 0, 3), 825 DIV_ISP, 0, 3),
826 DIV(ISP_DOUT_PCLK_ISP_133, "dout_pclk_isp_133", "mout_kfc", 826 DIV(ISP_DOUT_PCLK_ISP_133, "dout_pclk_isp_133", "mout_kfc",
@@ -832,7 +832,7 @@ struct samsung_div_clock isp_div_clks[] __initdata = {
832 DIV(ISP_DOUT_SCLK_MPWM, "dout_sclk_mpwm", "mout_kfc", DIV_ISP, 20, 2), 832 DIV(ISP_DOUT_SCLK_MPWM, "dout_sclk_mpwm", "mout_kfc", DIV_ISP, 20, 2),
833}; 833};
834 834
835struct samsung_gate_clock isp_gate_clks[] __initdata = { 835static struct samsung_gate_clock isp_gate_clks[] __initdata = {
836 GATE(ISP_CLK_GIC, "clk_isp_gic", "mout_aclk_isp1_266", 836 GATE(ISP_CLK_GIC, "clk_isp_gic", "mout_aclk_isp1_266",
837 EN_IP_ISP0, 15, 0, 0), 837 EN_IP_ISP0, 15, 0, 0),
838 838
@@ -895,7 +895,7 @@ struct samsung_gate_clock isp_gate_clks[] __initdata = {
895 895
896static void __init exynos5260_clk_isp_init(struct device_node *np) 896static void __init exynos5260_clk_isp_init(struct device_node *np)
897{ 897{
898 struct samsung_cmu_info cmu = {0}; 898 struct samsung_cmu_info cmu = { NULL };
899 899
900 cmu.mux_clks = isp_mux_clks; 900 cmu.mux_clks = isp_mux_clks;
901 cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks); 901 cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks);
@@ -934,13 +934,13 @@ static unsigned long kfc_clk_regs[] __initdata = {
934PNAME(mout_kfc_pll_p) = {"fin_pll", "fout_kfc_pll"}; 934PNAME(mout_kfc_pll_p) = {"fin_pll", "fout_kfc_pll"};
935PNAME(mout_kfc_p) = {"mout_kfc_pll", "dout_media_pll"}; 935PNAME(mout_kfc_p) = {"mout_kfc_pll", "dout_media_pll"};
936 936
937struct samsung_mux_clock kfc_mux_clks[] __initdata = { 937static struct samsung_mux_clock kfc_mux_clks[] __initdata = {
938 MUX(KFC_MOUT_KFC_PLL, "mout_kfc_pll", mout_kfc_pll_p, 938 MUX(KFC_MOUT_KFC_PLL, "mout_kfc_pll", mout_kfc_pll_p,
939 MUX_SEL_KFC0, 0, 1), 939 MUX_SEL_KFC0, 0, 1),
940 MUX(KFC_MOUT_KFC, "mout_kfc", mout_kfc_p, MUX_SEL_KFC2, 0, 1), 940 MUX(KFC_MOUT_KFC, "mout_kfc", mout_kfc_p, MUX_SEL_KFC2, 0, 1),
941}; 941};
942 942
943struct samsung_div_clock kfc_div_clks[] __initdata = { 943static struct samsung_div_clock kfc_div_clks[] __initdata = {
944 DIV(KFC_DOUT_KFC1, "dout_kfc1", "mout_kfc", DIV_KFC, 0, 3), 944 DIV(KFC_DOUT_KFC1, "dout_kfc1", "mout_kfc", DIV_KFC, 0, 3),
945 DIV(KFC_DOUT_KFC2, "dout_kfc2", "dout_kfc1", DIV_KFC, 4, 3), 945 DIV(KFC_DOUT_KFC2, "dout_kfc2", "dout_kfc1", DIV_KFC, 4, 3),
946 DIV(KFC_DOUT_KFC_ATCLK, "dout_kfc_atclk", "dout_kfc2", DIV_KFC, 8, 3), 946 DIV(KFC_DOUT_KFC_ATCLK, "dout_kfc_atclk", "dout_kfc2", DIV_KFC, 8, 3),
@@ -959,7 +959,7 @@ static struct samsung_pll_clock kfc_pll_clks[] __initdata = {
959 959
960static void __init exynos5260_clk_kfc_init(struct device_node *np) 960static void __init exynos5260_clk_kfc_init(struct device_node *np)
961{ 961{
962 struct samsung_cmu_info cmu = {0}; 962 struct samsung_cmu_info cmu = { NULL };
963 963
964 cmu.pll_clks = kfc_pll_clks; 964 cmu.pll_clks = kfc_pll_clks;
965 cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks); 965 cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks);
@@ -993,18 +993,18 @@ static unsigned long mfc_clk_regs[] __initdata = {
993 993
994PNAME(mout_aclk_mfc_333_user_p) = {"fin_pll", "dout_aclk_mfc_333"}; 994PNAME(mout_aclk_mfc_333_user_p) = {"fin_pll", "dout_aclk_mfc_333"};
995 995
996struct samsung_mux_clock mfc_mux_clks[] __initdata = { 996static struct samsung_mux_clock mfc_mux_clks[] __initdata = {
997 MUX(MFC_MOUT_ACLK_MFC_333_USER, "mout_aclk_mfc_333_user", 997 MUX(MFC_MOUT_ACLK_MFC_333_USER, "mout_aclk_mfc_333_user",
998 mout_aclk_mfc_333_user_p, 998 mout_aclk_mfc_333_user_p,
999 MUX_SEL_MFC, 0, 1), 999 MUX_SEL_MFC, 0, 1),
1000}; 1000};
1001 1001
1002struct samsung_div_clock mfc_div_clks[] __initdata = { 1002static struct samsung_div_clock mfc_div_clks[] __initdata = {
1003 DIV(MFC_DOUT_PCLK_MFC_83, "dout_pclk_mfc_83", "mout_aclk_mfc_333_user", 1003 DIV(MFC_DOUT_PCLK_MFC_83, "dout_pclk_mfc_83", "mout_aclk_mfc_333_user",
1004 DIV_MFC, 0, 3), 1004 DIV_MFC, 0, 3),
1005}; 1005};
1006 1006
1007struct samsung_gate_clock mfc_gate_clks[] __initdata = { 1007static struct samsung_gate_clock mfc_gate_clks[] __initdata = {
1008 GATE(MFC_CLK_MFC, "clk_mfc", "mout_aclk_mfc_333_user", 1008 GATE(MFC_CLK_MFC, "clk_mfc", "mout_aclk_mfc_333_user",
1009 EN_IP_MFC, 1, 0, 0), 1009 EN_IP_MFC, 1, 0, 0),
1010 GATE(MFC_CLK_SMMU2_MFCM0, "clk_smmu2_mfcm0", "mout_aclk_mfc_333_user", 1010 GATE(MFC_CLK_SMMU2_MFCM0, "clk_smmu2_mfcm0", "mout_aclk_mfc_333_user",
@@ -1015,7 +1015,7 @@ struct samsung_gate_clock mfc_gate_clks[] __initdata = {
1015 1015
1016static void __init exynos5260_clk_mfc_init(struct device_node *np) 1016static void __init exynos5260_clk_mfc_init(struct device_node *np)
1017{ 1017{
1018 struct samsung_cmu_info cmu = {0}; 1018 struct samsung_cmu_info cmu = { NULL };
1019 1019
1020 cmu.mux_clks = mfc_mux_clks; 1020 cmu.mux_clks = mfc_mux_clks;
1021 cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks); 1021 cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks);
@@ -1078,7 +1078,7 @@ PNAME(mout_mif_drex2x_p) = {"dout_mem_pll", "dout_bus_pll"};
1078PNAME(mout_clkm_phy_p) = {"mout_mif_drex", "dout_media_pll"}; 1078PNAME(mout_clkm_phy_p) = {"mout_mif_drex", "dout_media_pll"};
1079PNAME(mout_clk2x_phy_p) = {"mout_mif_drex2x", "dout_media_pll"}; 1079PNAME(mout_clk2x_phy_p) = {"mout_mif_drex2x", "dout_media_pll"};
1080 1080
1081struct samsung_mux_clock mif_mux_clks[] __initdata = { 1081static struct samsung_mux_clock mif_mux_clks[] __initdata = {
1082 MUX(MIF_MOUT_MEM_PLL, "mout_mem_pll", mout_mem_pll_p, 1082 MUX(MIF_MOUT_MEM_PLL, "mout_mem_pll", mout_mem_pll_p,
1083 MUX_SEL_MIF, 0, 1), 1083 MUX_SEL_MIF, 0, 1),
1084 MUX(MIF_MOUT_BUS_PLL, "mout_bus_pll", mout_bus_pll_p, 1084 MUX(MIF_MOUT_BUS_PLL, "mout_bus_pll", mout_bus_pll_p,
@@ -1095,7 +1095,7 @@ struct samsung_mux_clock mif_mux_clks[] __initdata = {
1095 MUX_SEL_MIF, 24, 1), 1095 MUX_SEL_MIF, 24, 1),
1096}; 1096};
1097 1097
1098struct samsung_div_clock mif_div_clks[] __initdata = { 1098static struct samsung_div_clock mif_div_clks[] __initdata = {
1099 DIV(MIF_DOUT_MEDIA_PLL, "dout_media_pll", "mout_media_pll", 1099 DIV(MIF_DOUT_MEDIA_PLL, "dout_media_pll", "mout_media_pll",
1100 DIV_MIF, 0, 3), 1100 DIV_MIF, 0, 3),
1101 DIV(MIF_DOUT_MEM_PLL, "dout_mem_pll", "mout_mem_pll", 1101 DIV(MIF_DOUT_MEM_PLL, "dout_mem_pll", "mout_mem_pll",
@@ -1114,7 +1114,7 @@ struct samsung_div_clock mif_div_clks[] __initdata = {
1114 DIV_MIF, 28, 4), 1114 DIV_MIF, 28, 4),
1115}; 1115};
1116 1116
1117struct samsung_gate_clock mif_gate_clks[] __initdata = { 1117static struct samsung_gate_clock mif_gate_clks[] __initdata = {
1118 GATE(MIF_CLK_LPDDR3PHY_WRAP0, "clk_lpddr3phy_wrap0", "dout_clk2x_phy", 1118 GATE(MIF_CLK_LPDDR3PHY_WRAP0, "clk_lpddr3phy_wrap0", "dout_clk2x_phy",
1119 EN_IP_MIF, 12, CLK_IGNORE_UNUSED, 0), 1119 EN_IP_MIF, 12, CLK_IGNORE_UNUSED, 0),
1120 GATE(MIF_CLK_LPDDR3PHY_WRAP1, "clk_lpddr3phy_wrap1", "dout_clk2x_phy", 1120 GATE(MIF_CLK_LPDDR3PHY_WRAP1, "clk_lpddr3phy_wrap1", "dout_clk2x_phy",
@@ -1162,7 +1162,7 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = {
1162 1162
1163static void __init exynos5260_clk_mif_init(struct device_node *np) 1163static void __init exynos5260_clk_mif_init(struct device_node *np)
1164{ 1164{
1165 struct samsung_cmu_info cmu = {0}; 1165 struct samsung_cmu_info cmu = { NULL };
1166 1166
1167 cmu.pll_clks = mif_pll_clks; 1167 cmu.pll_clks = mif_pll_clks;
1168 cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks); 1168 cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks);
@@ -1221,7 +1221,7 @@ PNAME(mout_sclk_i2scod_p) = {"ioclk_i2s_cdclk", "fin_pll", "dout_aclk_peri_aud",
1221PNAME(mout_sclk_spdif_p) = {"ioclk_spdif_extclk", "fin_pll", 1221PNAME(mout_sclk_spdif_p) = {"ioclk_spdif_extclk", "fin_pll",
1222 "dout_aclk_peri_aud", "phyclk_hdmi_phy_ref_cko"}; 1222 "dout_aclk_peri_aud", "phyclk_hdmi_phy_ref_cko"};
1223 1223
1224struct samsung_mux_clock peri_mux_clks[] __initdata = { 1224static struct samsung_mux_clock peri_mux_clks[] __initdata = {
1225 MUX(PERI_MOUT_SCLK_PCM, "mout_sclk_pcm", mout_sclk_pcm_p, 1225 MUX(PERI_MOUT_SCLK_PCM, "mout_sclk_pcm", mout_sclk_pcm_p,
1226 MUX_SEL_PERI1, 4, 2), 1226 MUX_SEL_PERI1, 4, 2),
1227 MUX(PERI_MOUT_SCLK_I2SCOD, "mout_sclk_i2scod", mout_sclk_i2scod_p, 1227 MUX(PERI_MOUT_SCLK_I2SCOD, "mout_sclk_i2scod", mout_sclk_i2scod_p,
@@ -1230,12 +1230,12 @@ struct samsung_mux_clock peri_mux_clks[] __initdata = {
1230 MUX_SEL_PERI1, 20, 2), 1230 MUX_SEL_PERI1, 20, 2),
1231}; 1231};
1232 1232
1233struct samsung_div_clock peri_div_clks[] __initdata = { 1233static struct samsung_div_clock peri_div_clks[] __initdata = {
1234 DIV(PERI_DOUT_PCM, "dout_pcm", "mout_sclk_pcm", DIV_PERI, 0, 8), 1234 DIV(PERI_DOUT_PCM, "dout_pcm", "mout_sclk_pcm", DIV_PERI, 0, 8),
1235 DIV(PERI_DOUT_I2S, "dout_i2s", "mout_sclk_i2scod", DIV_PERI, 8, 6), 1235 DIV(PERI_DOUT_I2S, "dout_i2s", "mout_sclk_i2scod", DIV_PERI, 8, 6),
1236}; 1236};
1237 1237
1238struct samsung_gate_clock peri_gate_clks[] __initdata = { 1238static struct samsung_gate_clock peri_gate_clks[] __initdata = {
1239 GATE(PERI_SCLK_PCM1, "sclk_pcm1", "dout_pcm", EN_SCLK_PERI, 0, 1239 GATE(PERI_SCLK_PCM1, "sclk_pcm1", "dout_pcm", EN_SCLK_PERI, 0,
1240 CLK_SET_RATE_PARENT, 0), 1240 CLK_SET_RATE_PARENT, 0),
1241 GATE(PERI_SCLK_I2S, "sclk_i2s", "dout_i2s", EN_SCLK_PERI, 1, 1241 GATE(PERI_SCLK_I2S, "sclk_i2s", "dout_i2s", EN_SCLK_PERI, 1,
@@ -1370,7 +1370,7 @@ struct samsung_gate_clock peri_gate_clks[] __initdata = {
1370 1370
1371static void __init exynos5260_clk_peri_init(struct device_node *np) 1371static void __init exynos5260_clk_peri_init(struct device_node *np)
1372{ 1372{
1373 struct samsung_cmu_info cmu = {0}; 1373 struct samsung_cmu_info cmu = { NULL };
1374 1374
1375 cmu.mux_clks = peri_mux_clks; 1375 cmu.mux_clks = peri_mux_clks;
1376 cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks); 1376 cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks);
@@ -1432,7 +1432,7 @@ static unsigned long top_clk_regs[] __initdata = {
1432}; 1432};
1433 1433
1434/* fixed rate clocks generated inside the soc */ 1434/* fixed rate clocks generated inside the soc */
1435struct samsung_fixed_rate_clock fixed_rate_clks[] __initdata = { 1435static struct samsung_fixed_rate_clock fixed_rate_clks[] __initdata = {
1436 FRATE(PHYCLK_DPTX_PHY_CH3_TXD_CLK, "phyclk_dptx_phy_ch3_txd_clk", NULL, 1436 FRATE(PHYCLK_DPTX_PHY_CH3_TXD_CLK, "phyclk_dptx_phy_ch3_txd_clk", NULL,
1437 CLK_IS_ROOT, 270000000), 1437 CLK_IS_ROOT, 270000000),
1438 FRATE(PHYCLK_DPTX_PHY_CH2_TXD_CLK, "phyclk_dptx_phy_ch2_txd_clk", NULL, 1438 FRATE(PHYCLK_DPTX_PHY_CH2_TXD_CLK, "phyclk_dptx_phy_ch2_txd_clk", NULL,
@@ -1519,7 +1519,7 @@ PNAME(mout_sclk_fsys_mmc1_sdclkin_b_p) = {"mout_sclk_fsys_mmc1_sdclkin_a",
1519PNAME(mout_sclk_fsys_mmc2_sdclkin_b_p) = {"mout_sclk_fsys_mmc2_sdclkin_a", 1519PNAME(mout_sclk_fsys_mmc2_sdclkin_b_p) = {"mout_sclk_fsys_mmc2_sdclkin_a",
1520 "mout_mediatop_pll_user"}; 1520 "mout_mediatop_pll_user"};
1521 1521
1522struct samsung_mux_clock top_mux_clks[] __initdata = { 1522static struct samsung_mux_clock top_mux_clks[] __initdata = {
1523 MUX(TOP_MOUT_MEDIATOP_PLL_USER, "mout_mediatop_pll_user", 1523 MUX(TOP_MOUT_MEDIATOP_PLL_USER, "mout_mediatop_pll_user",
1524 mout_mediatop_pll_user_p, 1524 mout_mediatop_pll_user_p,
1525 MUX_SEL_TOP_PLL0, 0, 1), 1525 MUX_SEL_TOP_PLL0, 0, 1),
@@ -1679,7 +1679,7 @@ struct samsung_mux_clock top_mux_clks[] __initdata = {
1679 MUX_SEL_TOP_GSCL, 20, 1), 1679 MUX_SEL_TOP_GSCL, 20, 1),
1680}; 1680};
1681 1681
1682struct samsung_div_clock top_div_clks[] __initdata = { 1682static struct samsung_div_clock top_div_clks[] __initdata = {
1683 DIV(TOP_DOUT_ACLK_G2D_333, "dout_aclk_g2d_333", "mout_aclk_g2d_333", 1683 DIV(TOP_DOUT_ACLK_G2D_333, "dout_aclk_g2d_333", "mout_aclk_g2d_333",
1684 DIV_TOP_G2D_MFC, 0, 3), 1684 DIV_TOP_G2D_MFC, 0, 3),
1685 DIV(TOP_DOUT_ACLK_MFC_333, "dout_aclk_mfc_333", "mout_aclk_mfc_333", 1685 DIV(TOP_DOUT_ACLK_MFC_333, "dout_aclk_mfc_333", "mout_aclk_mfc_333",
@@ -1800,7 +1800,7 @@ struct samsung_div_clock top_div_clks[] __initdata = {
1800 1800
1801}; 1801};
1802 1802
1803struct samsung_gate_clock top_gate_clks[] __initdata = { 1803static struct samsung_gate_clock top_gate_clks[] __initdata = {
1804 GATE(TOP_SCLK_MMC0, "sclk_fsys_mmc0_sdclkin", 1804 GATE(TOP_SCLK_MMC0, "sclk_fsys_mmc0_sdclkin",
1805 "dout_sclk_fsys_mmc0_sdclkin_b", 1805 "dout_sclk_fsys_mmc0_sdclkin_b",
1806 EN_SCLK_TOP, 7, CLK_SET_RATE_PARENT, 0), 1806 EN_SCLK_TOP, 7, CLK_SET_RATE_PARENT, 0),
@@ -1826,7 +1826,7 @@ static struct samsung_pll_clock top_pll_clks[] __initdata = {
1826 1826
1827static void __init exynos5260_clk_top_init(struct device_node *np) 1827static void __init exynos5260_clk_top_init(struct device_node *np)
1828{ 1828{
1829 struct samsung_cmu_info cmu = {0}; 1829 struct samsung_cmu_info cmu = { NULL };
1830 1830
1831 cmu.pll_clks = top_pll_clks; 1831 cmu.pll_clks = top_pll_clks;
1832 cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks); 1832 cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks);
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index bea4a173eef5..a1d731ca8f48 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -504,7 +504,7 @@ static struct samsung_fixed_factor_clock
504 FFACTOR(0, "ff_dout_spll2", "mout_sclk_spll", 1, 2, 0), 504 FFACTOR(0, "ff_dout_spll2", "mout_sclk_spll", 1, 2, 0),
505}; 505};
506 506
507struct samsung_mux_clock exynos5800_mux_clks[] __initdata = { 507static struct samsung_mux_clock exynos5800_mux_clks[] __initdata = {
508 MUX(0, "mout_aclk400_isp", mout_group3_5800_p, SRC_TOP0, 0, 3), 508 MUX(0, "mout_aclk400_isp", mout_group3_5800_p, SRC_TOP0, 0, 3),
509 MUX(0, "mout_aclk400_mscl", mout_group3_5800_p, SRC_TOP0, 4, 3), 509 MUX(0, "mout_aclk400_mscl", mout_group3_5800_p, SRC_TOP0, 4, 3),
510 MUX(0, "mout_aclk400_wcore", mout_group2_5800_p, SRC_TOP0, 16, 3), 510 MUX(0, "mout_aclk400_wcore", mout_group2_5800_p, SRC_TOP0, 16, 3),
@@ -553,7 +553,7 @@ struct samsung_mux_clock exynos5800_mux_clks[] __initdata = {
553 MUX(0, "mout_fimd1", mout_group2_p, SRC_DISP10, 4, 3), 553 MUX(0, "mout_fimd1", mout_group2_p, SRC_DISP10, 4, 3),
554}; 554};
555 555
556struct samsung_div_clock exynos5800_div_clks[] __initdata = { 556static struct samsung_div_clock exynos5800_div_clks[] __initdata = {
557 DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore", DIV_TOP0, 16, 3), 557 DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore", DIV_TOP0, 16, 3),
558 558
559 DIV(0, "dout_aclk550_cam", "mout_aclk550_cam", 559 DIV(0, "dout_aclk550_cam", "mout_aclk550_cam",
@@ -569,14 +569,14 @@ struct samsung_div_clock exynos5800_div_clks[] __initdata = {
569 DIV(0, "dout_sclk_sw", "sclk_spll", DIV_TOP9, 24, 6), 569 DIV(0, "dout_sclk_sw", "sclk_spll", DIV_TOP9, 24, 6),
570}; 570};
571 571
572struct samsung_gate_clock exynos5800_gate_clks[] __initdata = { 572static struct samsung_gate_clock exynos5800_gate_clks[] __initdata = {
573 GATE(CLK_ACLK550_CAM, "aclk550_cam", "mout_user_aclk550_cam", 573 GATE(CLK_ACLK550_CAM, "aclk550_cam", "mout_user_aclk550_cam",
574 GATE_BUS_TOP, 24, 0, 0), 574 GATE_BUS_TOP, 24, 0, 0),
575 GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler", 575 GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler",
576 GATE_BUS_TOP, 27, 0, 0), 576 GATE_BUS_TOP, 27, 0, 0),
577}; 577};
578 578
579struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { 579static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
580 MUX(0, "sclk_bpll", mout_bpll_p, TOP_SPARE2, 0, 1), 580 MUX(0, "sclk_bpll", mout_bpll_p, TOP_SPARE2, 0, 1),
581 MUX(0, "mout_aclk400_wcore_bpll", mout_aclk400_wcore_bpll_p, 581 MUX(0, "mout_aclk400_wcore_bpll", mout_aclk400_wcore_bpll_p,
582 TOP_SPARE2, 4, 1), 582 TOP_SPARE2, 4, 1),
@@ -606,7 +606,7 @@ struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
606 MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1), 606 MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1),
607}; 607};
608 608
609struct samsung_div_clock exynos5420_div_clks[] __initdata = { 609static struct samsung_div_clock exynos5420_div_clks[] __initdata = {
610 DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore_bpll", 610 DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore_bpll",
611 DIV_TOP0, 16, 3), 611 DIV_TOP0, 16, 3),
612}; 612};
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index 9e04ae2bb4d7..39c95649d3d0 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -835,6 +835,7 @@ static unsigned long cpif_clk_regs[] __initdata = {
835 MPHY_PLL_CON1, 835 MPHY_PLL_CON1,
836 MPHY_PLL_FREQ_DET, 836 MPHY_PLL_FREQ_DET,
837 MUX_SEL_CPIF0, 837 MUX_SEL_CPIF0,
838 DIV_CPIF,
838 ENABLE_SCLK_CPIF, 839 ENABLE_SCLK_CPIF,
839}; 840};
840 841
@@ -1389,7 +1390,7 @@ static struct samsung_gate_clock mif_gate_clks[] __initdata = {
1389 1390
1390 /* ENABLE_ACLK_MIF2 */ 1391 /* ENABLE_ACLK_MIF2 */
1391 GATE(CLK_ACLK_MIFND_266, "aclk_mifnd_266", "div_aclk_mif_266", 1392 GATE(CLK_ACLK_MIFND_266, "aclk_mifnd_266", "div_aclk_mif_266",
1392 ENABLE_ACLK_MIF2, 20, 0, 0), 1393 ENABLE_ACLK_MIF2, 20, CLK_IGNORE_UNUSED, 0),
1393 GATE(CLK_ACLK_PPMU_DREX1S3, "aclk_ppmu_drex1s3", "div_aclk_drex1", 1394 GATE(CLK_ACLK_PPMU_DREX1S3, "aclk_ppmu_drex1s3", "div_aclk_drex1",
1394 ENABLE_ACLK_MIF2, 17, CLK_IGNORE_UNUSED, 0), 1395 ENABLE_ACLK_MIF2, 17, CLK_IGNORE_UNUSED, 0),
1395 GATE(CLK_ACLK_PPMU_DREX1S1, "aclk_ppmu_drex1s1", "div_aclk_drex1", 1396 GATE(CLK_ACLK_PPMU_DREX1S1, "aclk_ppmu_drex1s1", "div_aclk_drex1",
@@ -1832,39 +1833,39 @@ static struct samsung_gate_clock peris_gate_clks[] __initdata = {
1832 1833
1833 /* ENABLE_PCLK_PERIS_SECURE_TZPC */ 1834 /* ENABLE_PCLK_PERIS_SECURE_TZPC */
1834 GATE(CLK_PCLK_TZPC12, "pclk_tzpc12", "aclk_peris_66", 1835 GATE(CLK_PCLK_TZPC12, "pclk_tzpc12", "aclk_peris_66",
1835 ENABLE_PCLK_PERIS_SECURE_TZPC, 12, 0, 0), 1836 ENABLE_PCLK_PERIS_SECURE_TZPC, 12, CLK_IGNORE_UNUSED, 0),
1836 GATE(CLK_PCLK_TZPC11, "pclk_tzpc11", "aclk_peris_66", 1837 GATE(CLK_PCLK_TZPC11, "pclk_tzpc11", "aclk_peris_66",
1837 ENABLE_PCLK_PERIS_SECURE_TZPC, 11, 0, 0), 1838 ENABLE_PCLK_PERIS_SECURE_TZPC, 11, CLK_IGNORE_UNUSED, 0),
1838 GATE(CLK_PCLK_TZPC10, "pclk_tzpc10", "aclk_peris_66", 1839 GATE(CLK_PCLK_TZPC10, "pclk_tzpc10", "aclk_peris_66",
1839 ENABLE_PCLK_PERIS_SECURE_TZPC, 10, 0, 0), 1840 ENABLE_PCLK_PERIS_SECURE_TZPC, 10, CLK_IGNORE_UNUSED, 0),
1840 GATE(CLK_PCLK_TZPC9, "pclk_tzpc9", "aclk_peris_66", 1841 GATE(CLK_PCLK_TZPC9, "pclk_tzpc9", "aclk_peris_66",
1841 ENABLE_PCLK_PERIS_SECURE_TZPC, 9, 0, 0), 1842 ENABLE_PCLK_PERIS_SECURE_TZPC, 9, CLK_IGNORE_UNUSED, 0),
1842 GATE(CLK_PCLK_TZPC8, "pclk_tzpc8", "aclk_peris_66", 1843 GATE(CLK_PCLK_TZPC8, "pclk_tzpc8", "aclk_peris_66",
1843 ENABLE_PCLK_PERIS_SECURE_TZPC, 8, 0, 0), 1844 ENABLE_PCLK_PERIS_SECURE_TZPC, 8, CLK_IGNORE_UNUSED, 0),
1844 GATE(CLK_PCLK_TZPC7, "pclk_tzpc7", "aclk_peris_66", 1845 GATE(CLK_PCLK_TZPC7, "pclk_tzpc7", "aclk_peris_66",
1845 ENABLE_PCLK_PERIS_SECURE_TZPC, 7, 0, 0), 1846 ENABLE_PCLK_PERIS_SECURE_TZPC, 7, CLK_IGNORE_UNUSED, 0),
1846 GATE(CLK_PCLK_TZPC6, "pclk_tzpc6", "aclk_peris_66", 1847 GATE(CLK_PCLK_TZPC6, "pclk_tzpc6", "aclk_peris_66",
1847 ENABLE_PCLK_PERIS_SECURE_TZPC, 6, 0, 0), 1848 ENABLE_PCLK_PERIS_SECURE_TZPC, 6, CLK_IGNORE_UNUSED, 0),
1848 GATE(CLK_PCLK_TZPC5, "pclk_tzpc5", "aclk_peris_66", 1849 GATE(CLK_PCLK_TZPC5, "pclk_tzpc5", "aclk_peris_66",
1849 ENABLE_PCLK_PERIS_SECURE_TZPC, 5, 0, 0), 1850 ENABLE_PCLK_PERIS_SECURE_TZPC, 5, CLK_IGNORE_UNUSED, 0),
1850 GATE(CLK_PCLK_TZPC4, "pclk_tzpc4", "aclk_peris_66", 1851 GATE(CLK_PCLK_TZPC4, "pclk_tzpc4", "aclk_peris_66",
1851 ENABLE_PCLK_PERIS_SECURE_TZPC, 4, 0, 0), 1852 ENABLE_PCLK_PERIS_SECURE_TZPC, 4, CLK_IGNORE_UNUSED, 0),
1852 GATE(CLK_PCLK_TZPC3, "pclk_tzpc3", "aclk_peris_66", 1853 GATE(CLK_PCLK_TZPC3, "pclk_tzpc3", "aclk_peris_66",
1853 ENABLE_PCLK_PERIS_SECURE_TZPC, 3, 0, 0), 1854 ENABLE_PCLK_PERIS_SECURE_TZPC, 3, CLK_IGNORE_UNUSED, 0),
1854 GATE(CLK_PCLK_TZPC2, "pclk_tzpc2", "aclk_peris_66", 1855 GATE(CLK_PCLK_TZPC2, "pclk_tzpc2", "aclk_peris_66",
1855 ENABLE_PCLK_PERIS_SECURE_TZPC, 2, 0, 0), 1856 ENABLE_PCLK_PERIS_SECURE_TZPC, 2, CLK_IGNORE_UNUSED, 0),
1856 GATE(CLK_PCLK_TZPC1, "pclk_tzpc1", "aclk_peris_66", 1857 GATE(CLK_PCLK_TZPC1, "pclk_tzpc1", "aclk_peris_66",
1857 ENABLE_PCLK_PERIS_SECURE_TZPC, 1, 0, 0), 1858 ENABLE_PCLK_PERIS_SECURE_TZPC, 1, CLK_IGNORE_UNUSED, 0),
1858 GATE(CLK_PCLK_TZPC0, "pclk_tzpc0", "aclk_peris_66", 1859 GATE(CLK_PCLK_TZPC0, "pclk_tzpc0", "aclk_peris_66",
1859 ENABLE_PCLK_PERIS_SECURE_TZPC, 0, 0, 0), 1860 ENABLE_PCLK_PERIS_SECURE_TZPC, 0, CLK_IGNORE_UNUSED, 0),
1860 1861
1861 /* ENABLE_PCLK_PERIS_SECURE_SECKEY_APBIF */ 1862 /* ENABLE_PCLK_PERIS_SECURE_SECKEY_APBIF */
1862 GATE(CLK_PCLK_SECKEY_APBIF, "pclk_seckey_apbif", "aclk_peris_66", 1863 GATE(CLK_PCLK_SECKEY_APBIF, "pclk_seckey_apbif", "aclk_peris_66",
1863 ENABLE_PCLK_PERIS_SECURE_SECKEY_APBIF, 0, 0, 0), 1864 ENABLE_PCLK_PERIS_SECURE_SECKEY_APBIF, 0, CLK_IGNORE_UNUSED, 0),
1864 1865
1865 /* ENABLE_PCLK_PERIS_SECURE_CHIPID_APBIF */ 1866 /* ENABLE_PCLK_PERIS_SECURE_CHIPID_APBIF */
1866 GATE(CLK_PCLK_CHIPID_APBIF, "pclk_chipid_apbif", "aclk_peris_66", 1867 GATE(CLK_PCLK_CHIPID_APBIF, "pclk_chipid_apbif", "aclk_peris_66",
1867 ENABLE_PCLK_PERIS_SECURE_CHIPID_APBIF, 0, 0, 0), 1868 ENABLE_PCLK_PERIS_SECURE_CHIPID_APBIF, 0, CLK_IGNORE_UNUSED, 0),
1868 1869
1869 /* ENABLE_PCLK_PERIS_SECURE_TOPRTC */ 1870 /* ENABLE_PCLK_PERIS_SECURE_TOPRTC */
1870 GATE(CLK_PCLK_TOPRTC, "pclk_toprtc", "aclk_peris_66", 1871 GATE(CLK_PCLK_TOPRTC, "pclk_toprtc", "aclk_peris_66",
@@ -1895,11 +1896,11 @@ static struct samsung_gate_clock peris_gate_clks[] __initdata = {
1895 1896
1896 /* ENABLE_SCLK_PERIS_SECURE_SECKEY */ 1897 /* ENABLE_SCLK_PERIS_SECURE_SECKEY */
1897 GATE(CLK_SCLK_SECKEY, "sclk_seckey", "oscclk_efuse_common", 1898 GATE(CLK_SCLK_SECKEY, "sclk_seckey", "oscclk_efuse_common",
1898 ENABLE_SCLK_PERIS_SECURE_SECKEY, 0, 0, 0), 1899 ENABLE_SCLK_PERIS_SECURE_SECKEY, 0, CLK_IGNORE_UNUSED, 0),
1899 1900
1900 /* ENABLE_SCLK_PERIS_SECURE_CHIPID */ 1901 /* ENABLE_SCLK_PERIS_SECURE_CHIPID */
1901 GATE(CLK_SCLK_CHIPID, "sclk_chipid", "oscclk_efuse_common", 1902 GATE(CLK_SCLK_CHIPID, "sclk_chipid", "oscclk_efuse_common",
1902 ENABLE_SCLK_PERIS_SECURE_CHIPID, 0, 0, 0), 1903 ENABLE_SCLK_PERIS_SECURE_CHIPID, 0, CLK_IGNORE_UNUSED, 0),
1903 1904
1904 /* ENABLE_SCLK_PERIS_SECURE_TOPRTC */ 1905 /* ENABLE_SCLK_PERIS_SECURE_TOPRTC */
1905 GATE(CLK_SCLK_TOPRTC, "sclk_toprtc", "oscclk_efuse_common", 1906 GATE(CLK_SCLK_TOPRTC, "sclk_toprtc", "oscclk_efuse_common",
@@ -3286,10 +3287,10 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = {
3286 3287
3287static struct samsung_mux_clock g3d_mux_clks[] __initdata = { 3288static struct samsung_mux_clock g3d_mux_clks[] __initdata = {
3288 /* MUX_SEL_G3D */ 3289 /* MUX_SEL_G3D */
3289 MUX(CLK_MOUT_ACLK_G3D_400, "mout_aclk_g3d_400", mout_aclk_g3d_400_p, 3290 MUX_F(CLK_MOUT_ACLK_G3D_400, "mout_aclk_g3d_400", mout_aclk_g3d_400_p,
3290 MUX_SEL_G3D, 8, 1), 3291 MUX_SEL_G3D, 8, 1, CLK_SET_RATE_PARENT, 0),
3291 MUX(CLK_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p, 3292 MUX_F(CLK_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p,
3292 MUX_SEL_G3D, 0, 1), 3293 MUX_SEL_G3D, 0, 1, CLK_SET_RATE_PARENT, 0),
3293}; 3294};
3294 3295
3295static struct samsung_div_clock g3d_div_clks[] __initdata = { 3296static struct samsung_div_clock g3d_div_clks[] __initdata = {
@@ -3298,8 +3299,8 @@ static struct samsung_div_clock g3d_div_clks[] __initdata = {
3298 8, 2), 3299 8, 2),
3299 DIV(CLK_DIV_PCLK_G3D, "div_pclk_g3d", "div_aclk_g3d", DIV_G3D, 3300 DIV(CLK_DIV_PCLK_G3D, "div_pclk_g3d", "div_aclk_g3d", DIV_G3D,
3300 4, 3), 3301 4, 3),
3301 DIV(CLK_DIV_ACLK_G3D, "div_aclk_g3d", "mout_aclk_g3d_400", DIV_G3D, 3302 DIV_F(CLK_DIV_ACLK_G3D, "div_aclk_g3d", "mout_aclk_g3d_400", DIV_G3D,
3302 0, 3), 3303 0, 3, CLK_SET_RATE_PARENT, 0),
3303}; 3304};
3304 3305
3305static struct samsung_gate_clock g3d_gate_clks[] __initdata = { 3306static struct samsung_gate_clock g3d_gate_clks[] __initdata = {
@@ -3309,9 +3310,9 @@ static struct samsung_gate_clock g3d_gate_clks[] __initdata = {
3309 GATE(CLK_ACLK_BTS_G3D0, "aclk_bts_g3d0", "div_aclk_g3d", 3310 GATE(CLK_ACLK_BTS_G3D0, "aclk_bts_g3d0", "div_aclk_g3d",
3310 ENABLE_ACLK_G3D, 6, 0, 0), 3311 ENABLE_ACLK_G3D, 6, 0, 0),
3311 GATE(CLK_ACLK_ASYNCAPBS_G3D, "aclk_asyncapbs_g3d", "div_pclk_g3d", 3312 GATE(CLK_ACLK_ASYNCAPBS_G3D, "aclk_asyncapbs_g3d", "div_pclk_g3d",
3312 ENABLE_ACLK_G3D, 5, 0, 0), 3313 ENABLE_ACLK_G3D, 5, CLK_IGNORE_UNUSED, 0),
3313 GATE(CLK_ACLK_ASYNCAPBM_G3D, "aclk_asyncapbm_g3d", "div_aclk_g3d", 3314 GATE(CLK_ACLK_ASYNCAPBM_G3D, "aclk_asyncapbm_g3d", "div_aclk_g3d",
3314 ENABLE_ACLK_G3D, 4, 0, 0), 3315 ENABLE_ACLK_G3D, 4, CLK_IGNORE_UNUSED, 0),
3315 GATE(CLK_ACLK_AHB2APB_G3DP, "aclk_ahb2apb_g3dp", "div_pclk_g3d", 3316 GATE(CLK_ACLK_AHB2APB_G3DP, "aclk_ahb2apb_g3dp", "div_pclk_g3d",
3316 ENABLE_ACLK_G3D, 3, CLK_IGNORE_UNUSED, 0), 3317 ENABLE_ACLK_G3D, 3, CLK_IGNORE_UNUSED, 0),
3317 GATE(CLK_ACLK_G3DNP_150, "aclk_g3dnp_150", "div_pclk_g3d", 3318 GATE(CLK_ACLK_G3DNP_150, "aclk_g3dnp_150", "div_pclk_g3d",
@@ -3319,7 +3320,7 @@ static struct samsung_gate_clock g3d_gate_clks[] __initdata = {
3319 GATE(CLK_ACLK_G3DND_600, "aclk_g3dnd_600", "div_aclk_g3d", 3320 GATE(CLK_ACLK_G3DND_600, "aclk_g3dnd_600", "div_aclk_g3d",
3320 ENABLE_ACLK_G3D, 1, CLK_IGNORE_UNUSED, 0), 3321 ENABLE_ACLK_G3D, 1, CLK_IGNORE_UNUSED, 0),
3321 GATE(CLK_ACLK_G3D, "aclk_g3d", "div_aclk_g3d", 3322 GATE(CLK_ACLK_G3D, "aclk_g3d", "div_aclk_g3d",
3322 ENABLE_ACLK_G3D, 0, 0, 0), 3323 ENABLE_ACLK_G3D, 0, CLK_SET_RATE_PARENT, 0),
3323 3324
3324 /* ENABLE_PCLK_G3D */ 3325 /* ENABLE_PCLK_G3D */
3325 GATE(CLK_PCLK_BTS_G3D1, "pclk_bts_g3d1", "div_pclk_g3d", 3326 GATE(CLK_PCLK_BTS_G3D1, "pclk_bts_g3d1", "div_pclk_g3d",
@@ -3582,7 +3583,7 @@ static struct samsung_pll_clock apollo_pll_clks[] __initdata = {
3582static struct samsung_mux_clock apollo_mux_clks[] __initdata = { 3583static struct samsung_mux_clock apollo_mux_clks[] __initdata = {
3583 /* MUX_SEL_APOLLO0 */ 3584 /* MUX_SEL_APOLLO0 */
3584 MUX_F(CLK_MOUT_APOLLO_PLL, "mout_apollo_pll", mout_apollo_pll_p, 3585 MUX_F(CLK_MOUT_APOLLO_PLL, "mout_apollo_pll", mout_apollo_pll_p,
3585 MUX_SEL_APOLLO0, 0, 1, 0, CLK_MUX_READ_ONLY), 3586 MUX_SEL_APOLLO0, 0, 1, CLK_SET_RATE_PARENT, 0),
3586 3587
3587 /* MUX_SEL_APOLLO1 */ 3588 /* MUX_SEL_APOLLO1 */
3588 MUX(CLK_MOUT_BUS_PLL_APOLLO_USER, "mout_bus_pll_apollo_user", 3589 MUX(CLK_MOUT_BUS_PLL_APOLLO_USER, "mout_bus_pll_apollo_user",
@@ -3590,7 +3591,7 @@ static struct samsung_mux_clock apollo_mux_clks[] __initdata = {
3590 3591
3591 /* MUX_SEL_APOLLO2 */ 3592 /* MUX_SEL_APOLLO2 */
3592 MUX_F(CLK_MOUT_APOLLO, "mout_apollo", mout_apollo_p, MUX_SEL_APOLLO2, 3593 MUX_F(CLK_MOUT_APOLLO, "mout_apollo", mout_apollo_p, MUX_SEL_APOLLO2,
3593 0, 1, 0, CLK_MUX_READ_ONLY), 3594 0, 1, CLK_SET_RATE_PARENT, 0),
3594}; 3595};
3595 3596
3596static struct samsung_div_clock apollo_div_clks[] __initdata = { 3597static struct samsung_div_clock apollo_div_clks[] __initdata = {
@@ -3611,11 +3612,9 @@ static struct samsung_div_clock apollo_div_clks[] __initdata = {
3611 DIV_APOLLO0, 8, 3, CLK_GET_RATE_NOCACHE, 3612 DIV_APOLLO0, 8, 3, CLK_GET_RATE_NOCACHE,
3612 CLK_DIVIDER_READ_ONLY), 3613 CLK_DIVIDER_READ_ONLY),
3613 DIV_F(CLK_DIV_APOLLO2, "div_apollo2", "div_apollo1", 3614 DIV_F(CLK_DIV_APOLLO2, "div_apollo2", "div_apollo1",
3614 DIV_APOLLO0, 4, 3, CLK_GET_RATE_NOCACHE, 3615 DIV_APOLLO0, 4, 3, CLK_SET_RATE_PARENT, 0),
3615 CLK_DIVIDER_READ_ONLY),
3616 DIV_F(CLK_DIV_APOLLO1, "div_apollo1", "mout_apollo", 3616 DIV_F(CLK_DIV_APOLLO1, "div_apollo1", "mout_apollo",
3617 DIV_APOLLO0, 0, 3, CLK_GET_RATE_NOCACHE, 3617 DIV_APOLLO0, 0, 3, CLK_SET_RATE_PARENT, 0),
3618 CLK_DIVIDER_READ_ONLY),
3619 3618
3620 /* DIV_APOLLO1 */ 3619 /* DIV_APOLLO1 */
3621 DIV_F(CLK_DIV_SCLK_HPM_APOLLO, "div_sclk_hpm_apollo", "mout_apollo", 3620 DIV_F(CLK_DIV_SCLK_HPM_APOLLO, "div_sclk_hpm_apollo", "mout_apollo",
@@ -3666,7 +3665,8 @@ static struct samsung_gate_clock apollo_gate_clks[] __initdata = {
3666 GATE(CLK_SCLK_HPM_APOLLO, "sclk_hpm_apollo", "div_sclk_hpm_apollo", 3665 GATE(CLK_SCLK_HPM_APOLLO, "sclk_hpm_apollo", "div_sclk_hpm_apollo",
3667 ENABLE_SCLK_APOLLO, 1, CLK_IGNORE_UNUSED, 0), 3666 ENABLE_SCLK_APOLLO, 1, CLK_IGNORE_UNUSED, 0),
3668 GATE(CLK_SCLK_APOLLO, "sclk_apollo", "div_apollo2", 3667 GATE(CLK_SCLK_APOLLO, "sclk_apollo", "div_apollo2",
3669 ENABLE_SCLK_APOLLO, 0, CLK_IGNORE_UNUSED, 0), 3668 ENABLE_SCLK_APOLLO, 0,
3669 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0),
3670}; 3670};
3671 3671
3672static struct samsung_cmu_info apollo_cmu_info __initdata = { 3672static struct samsung_cmu_info apollo_cmu_info __initdata = {
@@ -3775,7 +3775,7 @@ static struct samsung_pll_clock atlas_pll_clks[] __initdata = {
3775static struct samsung_mux_clock atlas_mux_clks[] __initdata = { 3775static struct samsung_mux_clock atlas_mux_clks[] __initdata = {
3776 /* MUX_SEL_ATLAS0 */ 3776 /* MUX_SEL_ATLAS0 */
3777 MUX_F(CLK_MOUT_ATLAS_PLL, "mout_atlas_pll", mout_atlas_pll_p, 3777 MUX_F(CLK_MOUT_ATLAS_PLL, "mout_atlas_pll", mout_atlas_pll_p,
3778 MUX_SEL_ATLAS0, 0, 1, 0, CLK_MUX_READ_ONLY), 3778 MUX_SEL_ATLAS0, 0, 1, CLK_SET_RATE_PARENT, 0),
3779 3779
3780 /* MUX_SEL_ATLAS1 */ 3780 /* MUX_SEL_ATLAS1 */
3781 MUX(CLK_MOUT_BUS_PLL_ATLAS_USER, "mout_bus_pll_atlas_user", 3781 MUX(CLK_MOUT_BUS_PLL_ATLAS_USER, "mout_bus_pll_atlas_user",
@@ -3783,7 +3783,7 @@ static struct samsung_mux_clock atlas_mux_clks[] __initdata = {
3783 3783
3784 /* MUX_SEL_ATLAS2 */ 3784 /* MUX_SEL_ATLAS2 */
3785 MUX_F(CLK_MOUT_ATLAS, "mout_atlas", mout_atlas_p, MUX_SEL_ATLAS2, 3785 MUX_F(CLK_MOUT_ATLAS, "mout_atlas", mout_atlas_p, MUX_SEL_ATLAS2,
3786 0, 1, 0, CLK_MUX_READ_ONLY), 3786 0, 1, CLK_SET_RATE_PARENT, 0),
3787}; 3787};
3788 3788
3789static struct samsung_div_clock atlas_div_clks[] __initdata = { 3789static struct samsung_div_clock atlas_div_clks[] __initdata = {
@@ -3804,11 +3804,9 @@ static struct samsung_div_clock atlas_div_clks[] __initdata = {
3804 DIV_ATLAS0, 8, 3, CLK_GET_RATE_NOCACHE, 3804 DIV_ATLAS0, 8, 3, CLK_GET_RATE_NOCACHE,
3805 CLK_DIVIDER_READ_ONLY), 3805 CLK_DIVIDER_READ_ONLY),
3806 DIV_F(CLK_DIV_ATLAS2, "div_atlas2", "div_atlas1", 3806 DIV_F(CLK_DIV_ATLAS2, "div_atlas2", "div_atlas1",
3807 DIV_ATLAS0, 4, 3, CLK_GET_RATE_NOCACHE, 3807 DIV_ATLAS0, 4, 3, CLK_SET_RATE_PARENT, 0),
3808 CLK_DIVIDER_READ_ONLY),
3809 DIV_F(CLK_DIV_ATLAS1, "div_atlas1", "mout_atlas", 3808 DIV_F(CLK_DIV_ATLAS1, "div_atlas1", "mout_atlas",
3810 DIV_ATLAS0, 0, 3, CLK_GET_RATE_NOCACHE, 3809 DIV_ATLAS0, 0, 3, CLK_SET_RATE_PARENT, 0),
3811 CLK_DIVIDER_READ_ONLY),
3812 3810
3813 /* DIV_ATLAS1 */ 3811 /* DIV_ATLAS1 */
3814 DIV_F(CLK_DIV_SCLK_HPM_ATLAS, "div_sclk_hpm_atlas", "mout_atlas", 3812 DIV_F(CLK_DIV_SCLK_HPM_ATLAS, "div_sclk_hpm_atlas", "mout_atlas",
@@ -3885,7 +3883,8 @@ static struct samsung_gate_clock atlas_gate_clks[] __initdata = {
3885 GATE(CLK_ATCLK, "atclk", "div_atclk_atlas", 3883 GATE(CLK_ATCLK, "atclk", "div_atclk_atlas",
3886 ENABLE_SCLK_ATLAS, 1, CLK_IGNORE_UNUSED, 0), 3884 ENABLE_SCLK_ATLAS, 1, CLK_IGNORE_UNUSED, 0),
3887 GATE(CLK_SCLK_ATLAS, "sclk_atlas", "div_atlas2", 3885 GATE(CLK_SCLK_ATLAS, "sclk_atlas", "div_atlas2",
3888 ENABLE_SCLK_ATLAS, 0, CLK_IGNORE_UNUSED, 0), 3886 ENABLE_SCLK_ATLAS, 0,
3887 CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0),
3889}; 3888};
3890 3889
3891static struct samsung_cmu_info atlas_cmu_info __initdata = { 3890static struct samsung_cmu_info atlas_cmu_info __initdata = {
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 9d70e5c03804..bebc61b5fce1 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -1156,7 +1156,7 @@ static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
1156}; 1156};
1157 1157
1158static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, 1158static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1159 struct samsung_pll_clock *pll_clk, 1159 const struct samsung_pll_clock *pll_clk,
1160 void __iomem *base) 1160 void __iomem *base)
1161{ 1161{
1162 struct samsung_clk_pll *pll; 1162 struct samsung_clk_pll *pll;
@@ -1303,7 +1303,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1303} 1303}
1304 1304
1305void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, 1305void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
1306 struct samsung_pll_clock *pll_list, 1306 const struct samsung_pll_clock *pll_list,
1307 unsigned int nr_pll, void __iomem *base) 1307 unsigned int nr_pll, void __iomem *base)
1308{ 1308{
1309 int cnt; 1309 int cnt;
diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c
index f4f29ed6bd25..e56df5064889 100644
--- a/drivers/clk/samsung/clk-s3c2410-dclk.c
+++ b/drivers/clk/samsung/clk-s3c2410-dclk.c
@@ -81,13 +81,13 @@ static int s3c24xx_clkout_set_parent(struct clk_hw *hw, u8 index)
81 return ret; 81 return ret;
82} 82}
83 83
84const struct clk_ops s3c24xx_clkout_ops = { 84static const struct clk_ops s3c24xx_clkout_ops = {
85 .get_parent = s3c24xx_clkout_get_parent, 85 .get_parent = s3c24xx_clkout_get_parent,
86 .set_parent = s3c24xx_clkout_set_parent, 86 .set_parent = s3c24xx_clkout_set_parent,
87 .determine_rate = __clk_mux_determine_rate, 87 .determine_rate = __clk_mux_determine_rate,
88}; 88};
89 89
90struct clk *s3c24xx_register_clkout(struct device *dev, const char *name, 90static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name,
91 const char **parent_names, u8 num_parents, 91 const char **parent_names, u8 num_parents,
92 u8 shift, u32 mask) 92 u8 shift, u32 mask)
93{ 93{
@@ -404,7 +404,7 @@ static struct s3c24xx_dclk_drv_data dclk_variants[] = {
404 }, 404 },
405}; 405};
406 406
407static struct platform_device_id s3c24xx_dclk_driver_ids[] = { 407static const struct platform_device_id s3c24xx_dclk_driver_ids[] = {
408 { 408 {
409 .name = "s3c2410-dclk", 409 .name = "s3c2410-dclk",
410 .driver_data = (kernel_ulong_t)&dclk_variants[S3C2410], 410 .driver_data = (kernel_ulong_t)&dclk_variants[S3C2410],
diff --git a/drivers/clk/samsung/clk-s5pv210.c b/drivers/clk/samsung/clk-s5pv210.c
index e668e479a697..cf7e8fa7b624 100644
--- a/drivers/clk/samsung/clk-s5pv210.c
+++ b/drivers/clk/samsung/clk-s5pv210.c
@@ -169,44 +169,44 @@ static inline void s5pv210_clk_sleep_init(void) { }
169#endif 169#endif
170 170
171/* Mux parent lists. */ 171/* Mux parent lists. */
172static const char *fin_pll_p[] __initdata = { 172static const char *const fin_pll_p[] __initconst = {
173 "xxti", 173 "xxti",
174 "xusbxti" 174 "xusbxti"
175}; 175};
176 176
177static const char *mout_apll_p[] __initdata = { 177static const char *const mout_apll_p[] __initconst = {
178 "fin_pll", 178 "fin_pll",
179 "fout_apll" 179 "fout_apll"
180}; 180};
181 181
182static const char *mout_mpll_p[] __initdata = { 182static const char *const mout_mpll_p[] __initconst = {
183 "fin_pll", 183 "fin_pll",
184 "fout_mpll" 184 "fout_mpll"
185}; 185};
186 186
187static const char *mout_epll_p[] __initdata = { 187static const char *const mout_epll_p[] __initconst = {
188 "fin_pll", 188 "fin_pll",
189 "fout_epll" 189 "fout_epll"
190}; 190};
191 191
192static const char *mout_vpllsrc_p[] __initdata = { 192static const char *const mout_vpllsrc_p[] __initconst = {
193 "fin_pll", 193 "fin_pll",
194 "sclk_hdmi27m" 194 "sclk_hdmi27m"
195}; 195};
196 196
197static const char *mout_vpll_p[] __initdata = { 197static const char *const mout_vpll_p[] __initconst = {
198 "mout_vpllsrc", 198 "mout_vpllsrc",
199 "fout_vpll" 199 "fout_vpll"
200}; 200};
201 201
202static const char *mout_group1_p[] __initdata = { 202static const char *const mout_group1_p[] __initconst = {
203 "dout_a2m", 203 "dout_a2m",
204 "mout_mpll", 204 "mout_mpll",
205 "mout_epll", 205 "mout_epll",
206 "mout_vpll" 206 "mout_vpll"
207}; 207};
208 208
209static const char *mout_group2_p[] __initdata = { 209static const char *const mout_group2_p[] __initconst = {
210 "xxti", 210 "xxti",
211 "xusbxti", 211 "xusbxti",
212 "sclk_hdmi27m", 212 "sclk_hdmi27m",
@@ -218,7 +218,7 @@ static const char *mout_group2_p[] __initdata = {
218 "mout_vpll", 218 "mout_vpll",
219}; 219};
220 220
221static const char *mout_audio0_p[] __initdata = { 221static const char *const mout_audio0_p[] __initconst = {
222 "xxti", 222 "xxti",
223 "pcmcdclk0", 223 "pcmcdclk0",
224 "sclk_hdmi27m", 224 "sclk_hdmi27m",
@@ -230,7 +230,7 @@ static const char *mout_audio0_p[] __initdata = {
230 "mout_vpll", 230 "mout_vpll",
231}; 231};
232 232
233static const char *mout_audio1_p[] __initdata = { 233static const char *const mout_audio1_p[] __initconst = {
234 "i2scdclk1", 234 "i2scdclk1",
235 "pcmcdclk1", 235 "pcmcdclk1",
236 "sclk_hdmi27m", 236 "sclk_hdmi27m",
@@ -242,7 +242,7 @@ static const char *mout_audio1_p[] __initdata = {
242 "mout_vpll", 242 "mout_vpll",
243}; 243};
244 244
245static const char *mout_audio2_p[] __initdata = { 245static const char *const mout_audio2_p[] __initconst = {
246 "i2scdclk2", 246 "i2scdclk2",
247 "pcmcdclk2", 247 "pcmcdclk2",
248 "sclk_hdmi27m", 248 "sclk_hdmi27m",
@@ -254,63 +254,63 @@ static const char *mout_audio2_p[] __initdata = {
254 "mout_vpll", 254 "mout_vpll",
255}; 255};
256 256
257static const char *mout_spdif_p[] __initdata = { 257static const char *const mout_spdif_p[] __initconst = {
258 "dout_audio0", 258 "dout_audio0",
259 "dout_audio1", 259 "dout_audio1",
260 "dout_audio3", 260 "dout_audio3",
261}; 261};
262 262
263static const char *mout_group3_p[] __initdata = { 263static const char *const mout_group3_p[] __initconst = {
264 "mout_apll", 264 "mout_apll",
265 "mout_mpll" 265 "mout_mpll"
266}; 266};
267 267
268static const char *mout_group4_p[] __initdata = { 268static const char *const mout_group4_p[] __initconst = {
269 "mout_mpll", 269 "mout_mpll",
270 "dout_a2m" 270 "dout_a2m"
271}; 271};
272 272
273static const char *mout_flash_p[] __initdata = { 273static const char *const mout_flash_p[] __initconst = {
274 "dout_hclkd", 274 "dout_hclkd",
275 "dout_hclkp" 275 "dout_hclkp"
276}; 276};
277 277
278static const char *mout_dac_p[] __initdata = { 278static const char *const mout_dac_p[] __initconst = {
279 "mout_vpll", 279 "mout_vpll",
280 "sclk_hdmiphy" 280 "sclk_hdmiphy"
281}; 281};
282 282
283static const char *mout_hdmi_p[] __initdata = { 283static const char *const mout_hdmi_p[] __initconst = {
284 "sclk_hdmiphy", 284 "sclk_hdmiphy",
285 "dout_tblk" 285 "dout_tblk"
286}; 286};
287 287
288static const char *mout_mixer_p[] __initdata = { 288static const char *const mout_mixer_p[] __initconst = {
289 "mout_dac", 289 "mout_dac",
290 "mout_hdmi" 290 "mout_hdmi"
291}; 291};
292 292
293static const char *mout_vpll_6442_p[] __initdata = { 293static const char *const mout_vpll_6442_p[] __initconst = {
294 "fin_pll", 294 "fin_pll",
295 "fout_vpll" 295 "fout_vpll"
296}; 296};
297 297
298static const char *mout_mixer_6442_p[] __initdata = { 298static const char *const mout_mixer_6442_p[] __initconst = {
299 "mout_vpll", 299 "mout_vpll",
300 "dout_mixer" 300 "dout_mixer"
301}; 301};
302 302
303static const char *mout_d0sync_6442_p[] __initdata = { 303static const char *const mout_d0sync_6442_p[] __initconst = {
304 "mout_dsys", 304 "mout_dsys",
305 "div_apll" 305 "div_apll"
306}; 306};
307 307
308static const char *mout_d1sync_6442_p[] __initdata = { 308static const char *const mout_d1sync_6442_p[] __initconst = {
309 "mout_psys", 309 "mout_psys",
310 "div_apll" 310 "div_apll"
311}; 311};
312 312
313static const char *mout_group2_6442_p[] __initdata = { 313static const char *const mout_group2_6442_p[] __initconst = {
314 "fin_pll", 314 "fin_pll",
315 "none", 315 "none",
316 "none", 316 "none",
@@ -322,7 +322,7 @@ static const char *mout_group2_6442_p[] __initdata = {
322 "mout_vpll", 322 "mout_vpll",
323}; 323};
324 324
325static const char *mout_audio0_6442_p[] __initdata = { 325static const char *const mout_audio0_6442_p[] __initconst = {
326 "fin_pll", 326 "fin_pll",
327 "pcmcdclk0", 327 "pcmcdclk0",
328 "none", 328 "none",
@@ -334,7 +334,7 @@ static const char *mout_audio0_6442_p[] __initdata = {
334 "mout_vpll", 334 "mout_vpll",
335}; 335};
336 336
337static const char *mout_audio1_6442_p[] __initdata = { 337static const char *const mout_audio1_6442_p[] __initconst = {
338 "i2scdclk1", 338 "i2scdclk1",
339 "pcmcdclk1", 339 "pcmcdclk1",
340 "none", 340 "none",
@@ -347,7 +347,7 @@ static const char *mout_audio1_6442_p[] __initdata = {
347 "fin_pll", 347 "fin_pll",
348}; 348};
349 349
350static const char *mout_clksel_p[] __initdata = { 350static const char *const mout_clksel_p[] __initconst = {
351 "fout_apll_clkout", 351 "fout_apll_clkout",
352 "fout_mpll_clkout", 352 "fout_mpll_clkout",
353 "fout_epll", 353 "fout_epll",
@@ -370,7 +370,7 @@ static const char *mout_clksel_p[] __initdata = {
370 "div_dclk" 370 "div_dclk"
371}; 371};
372 372
373static const char *mout_clksel_6442_p[] __initdata = { 373static const char *const mout_clksel_6442_p[] __initconst = {
374 "fout_apll_clkout", 374 "fout_apll_clkout",
375 "fout_mpll_clkout", 375 "fout_mpll_clkout",
376 "fout_epll", 376 "fout_epll",
@@ -393,7 +393,7 @@ static const char *mout_clksel_6442_p[] __initdata = {
393 "div_dclk" 393 "div_dclk"
394}; 394};
395 395
396static const char *mout_clkout_p[] __initdata = { 396static const char *const mout_clkout_p[] __initconst = {
397 "dout_clkout", 397 "dout_clkout",
398 "none", 398 "none",
399 "xxti", 399 "xxti",
@@ -401,20 +401,20 @@ static const char *mout_clkout_p[] __initdata = {
401}; 401};
402 402
403/* Common fixed factor clocks. */ 403/* Common fixed factor clocks. */
404static struct samsung_fixed_factor_clock ffactor_clks[] __initdata = { 404static const struct samsung_fixed_factor_clock ffactor_clks[] __initconst = {
405 FFACTOR(FOUT_APLL_CLKOUT, "fout_apll_clkout", "fout_apll", 1, 4, 0), 405 FFACTOR(FOUT_APLL_CLKOUT, "fout_apll_clkout", "fout_apll", 1, 4, 0),
406 FFACTOR(FOUT_MPLL_CLKOUT, "fout_mpll_clkout", "fout_mpll", 1, 2, 0), 406 FFACTOR(FOUT_MPLL_CLKOUT, "fout_mpll_clkout", "fout_mpll", 1, 2, 0),
407 FFACTOR(DOUT_APLL_CLKOUT, "dout_apll_clkout", "dout_apll", 1, 4, 0), 407 FFACTOR(DOUT_APLL_CLKOUT, "dout_apll_clkout", "dout_apll", 1, 4, 0),
408}; 408};
409 409
410/* PLL input mux (fin_pll), which needs to be registered before PLLs. */ 410/* PLL input mux (fin_pll), which needs to be registered before PLLs. */
411static struct samsung_mux_clock early_mux_clks[] __initdata = { 411static const struct samsung_mux_clock early_mux_clks[] __initconst = {
412 MUX_F(FIN_PLL, "fin_pll", fin_pll_p, OM_STAT, 0, 1, 412 MUX_F(FIN_PLL, "fin_pll", fin_pll_p, OM_STAT, 0, 1,
413 CLK_MUX_READ_ONLY, 0), 413 CLK_MUX_READ_ONLY, 0),
414}; 414};
415 415
416/* Common clock muxes. */ 416/* Common clock muxes. */
417static struct samsung_mux_clock mux_clks[] __initdata = { 417static const struct samsung_mux_clock mux_clks[] __initconst = {
418 MUX(MOUT_FLASH, "mout_flash", mout_flash_p, CLK_SRC0, 28, 1), 418 MUX(MOUT_FLASH, "mout_flash", mout_flash_p, CLK_SRC0, 28, 1),
419 MUX(MOUT_PSYS, "mout_psys", mout_group4_p, CLK_SRC0, 24, 1), 419 MUX(MOUT_PSYS, "mout_psys", mout_group4_p, CLK_SRC0, 24, 1),
420 MUX(MOUT_DSYS, "mout_dsys", mout_group4_p, CLK_SRC0, 20, 1), 420 MUX(MOUT_DSYS, "mout_dsys", mout_group4_p, CLK_SRC0, 20, 1),
@@ -427,7 +427,7 @@ static struct samsung_mux_clock mux_clks[] __initdata = {
427}; 427};
428 428
429/* S5PV210-specific clock muxes. */ 429/* S5PV210-specific clock muxes. */
430static struct samsung_mux_clock s5pv210_mux_clks[] __initdata = { 430static const struct samsung_mux_clock s5pv210_mux_clks[] __initconst = {
431 MUX(MOUT_VPLL, "mout_vpll", mout_vpll_p, CLK_SRC0, 12, 1), 431 MUX(MOUT_VPLL, "mout_vpll", mout_vpll_p, CLK_SRC0, 12, 1),
432 432
433 MUX(MOUT_VPLLSRC, "mout_vpllsrc", mout_vpllsrc_p, CLK_SRC1, 28, 1), 433 MUX(MOUT_VPLLSRC, "mout_vpllsrc", mout_vpllsrc_p, CLK_SRC1, 28, 1),
@@ -472,7 +472,7 @@ static struct samsung_mux_clock s5pv210_mux_clks[] __initdata = {
472}; 472};
473 473
474/* S5P6442-specific clock muxes. */ 474/* S5P6442-specific clock muxes. */
475static struct samsung_mux_clock s5p6442_mux_clks[] __initdata = { 475static const struct samsung_mux_clock s5p6442_mux_clks[] __initconst = {
476 MUX(MOUT_VPLL, "mout_vpll", mout_vpll_6442_p, CLK_SRC0, 12, 1), 476 MUX(MOUT_VPLL, "mout_vpll", mout_vpll_6442_p, CLK_SRC0, 12, 1),
477 477
478 MUX(MOUT_FIMD, "mout_fimd", mout_group2_6442_p, CLK_SRC1, 20, 4), 478 MUX(MOUT_FIMD, "mout_fimd", mout_group2_6442_p, CLK_SRC1, 20, 4),
@@ -504,7 +504,7 @@ static struct samsung_mux_clock s5p6442_mux_clks[] __initdata = {
504}; 504};
505 505
506/* S5PV210-specific fixed rate clocks generated inside the SoC. */ 506/* S5PV210-specific fixed rate clocks generated inside the SoC. */
507static struct samsung_fixed_rate_clock s5pv210_frate_clks[] __initdata = { 507static const struct samsung_fixed_rate_clock s5pv210_frate_clks[] __initconst = {
508 FRATE(SCLK_HDMI27M, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000), 508 FRATE(SCLK_HDMI27M, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000),
509 FRATE(SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), 509 FRATE(SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
510 FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), 510 FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
@@ -512,12 +512,12 @@ static struct samsung_fixed_rate_clock s5pv210_frate_clks[] __initdata = {
512}; 512};
513 513
514/* S5P6442-specific fixed rate clocks generated inside the SoC. */ 514/* S5P6442-specific fixed rate clocks generated inside the SoC. */
515static struct samsung_fixed_rate_clock s5p6442_frate_clks[] __initdata = { 515static const struct samsung_fixed_rate_clock s5p6442_frate_clks[] __initconst = {
516 FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 30000000), 516 FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 30000000),
517}; 517};
518 518
519/* Common clock dividers. */ 519/* Common clock dividers. */
520static struct samsung_div_clock div_clks[] __initdata = { 520static const struct samsung_div_clock div_clks[] __initconst = {
521 DIV(DOUT_PCLKP, "dout_pclkp", "dout_hclkp", CLK_DIV0, 28, 3), 521 DIV(DOUT_PCLKP, "dout_pclkp", "dout_hclkp", CLK_DIV0, 28, 3),
522 DIV(DOUT_PCLKD, "dout_pclkd", "dout_hclkd", CLK_DIV0, 20, 3), 522 DIV(DOUT_PCLKD, "dout_pclkd", "dout_hclkd", CLK_DIV0, 20, 3),
523 DIV(DOUT_A2M, "dout_a2m", "mout_apll", CLK_DIV0, 4, 3), 523 DIV(DOUT_A2M, "dout_a2m", "mout_apll", CLK_DIV0, 4, 3),
@@ -549,7 +549,7 @@ static struct samsung_div_clock div_clks[] __initdata = {
549}; 549};
550 550
551/* S5PV210-specific clock dividers. */ 551/* S5PV210-specific clock dividers. */
552static struct samsung_div_clock s5pv210_div_clks[] __initdata = { 552static const struct samsung_div_clock s5pv210_div_clks[] __initconst = {
553 DIV(DOUT_HCLKP, "dout_hclkp", "mout_psys", CLK_DIV0, 24, 4), 553 DIV(DOUT_HCLKP, "dout_hclkp", "mout_psys", CLK_DIV0, 24, 4),
554 DIV(DOUT_HCLKD, "dout_hclkd", "mout_dsys", CLK_DIV0, 16, 4), 554 DIV(DOUT_HCLKD, "dout_hclkd", "mout_dsys", CLK_DIV0, 16, 4),
555 DIV(DOUT_PCLKM, "dout_pclkm", "dout_hclkm", CLK_DIV0, 12, 3), 555 DIV(DOUT_PCLKM, "dout_pclkm", "dout_hclkm", CLK_DIV0, 12, 3),
@@ -578,7 +578,7 @@ static struct samsung_div_clock s5pv210_div_clks[] __initdata = {
578}; 578};
579 579
580/* S5P6442-specific clock dividers. */ 580/* S5P6442-specific clock dividers. */
581static struct samsung_div_clock s5p6442_div_clks[] __initdata = { 581static const struct samsung_div_clock s5p6442_div_clks[] __initconst = {
582 DIV(DOUT_HCLKP, "dout_hclkp", "mout_d1sync", CLK_DIV0, 24, 4), 582 DIV(DOUT_HCLKP, "dout_hclkp", "mout_d1sync", CLK_DIV0, 24, 4),
583 DIV(DOUT_HCLKD, "dout_hclkd", "mout_d0sync", CLK_DIV0, 16, 4), 583 DIV(DOUT_HCLKD, "dout_hclkd", "mout_d0sync", CLK_DIV0, 16, 4),
584 584
@@ -586,7 +586,7 @@ static struct samsung_div_clock s5p6442_div_clks[] __initdata = {
586}; 586};
587 587
588/* Common clock gates. */ 588/* Common clock gates. */
589static struct samsung_gate_clock gate_clks[] __initdata = { 589static const struct samsung_gate_clock gate_clks[] __initconst = {
590 GATE(CLK_ROTATOR, "rotator", "dout_hclkd", CLK_GATE_IP0, 29, 0, 0), 590 GATE(CLK_ROTATOR, "rotator", "dout_hclkd", CLK_GATE_IP0, 29, 0, 0),
591 GATE(CLK_FIMC2, "fimc2", "dout_hclkd", CLK_GATE_IP0, 26, 0, 0), 591 GATE(CLK_FIMC2, "fimc2", "dout_hclkd", CLK_GATE_IP0, 26, 0, 0),
592 GATE(CLK_FIMC1, "fimc1", "dout_hclkd", CLK_GATE_IP0, 25, 0, 0), 592 GATE(CLK_FIMC1, "fimc1", "dout_hclkd", CLK_GATE_IP0, 25, 0, 0),
@@ -666,7 +666,7 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
666}; 666};
667 667
668/* S5PV210-specific clock gates. */ 668/* S5PV210-specific clock gates. */
669static struct samsung_gate_clock s5pv210_gate_clks[] __initdata = { 669static const struct samsung_gate_clock s5pv210_gate_clks[] __initconst = {
670 GATE(CLK_CSIS, "clk_csis", "dout_hclkd", CLK_GATE_IP0, 31, 0, 0), 670 GATE(CLK_CSIS, "clk_csis", "dout_hclkd", CLK_GATE_IP0, 31, 0, 0),
671 GATE(CLK_MFC, "mfc", "dout_hclkm", CLK_GATE_IP0, 16, 0, 0), 671 GATE(CLK_MFC, "mfc", "dout_hclkm", CLK_GATE_IP0, 16, 0, 0),
672 GATE(CLK_G2D, "g2d", "dout_hclkd", CLK_GATE_IP0, 12, 0, 0), 672 GATE(CLK_G2D, "g2d", "dout_hclkd", CLK_GATE_IP0, 12, 0, 0),
@@ -728,7 +728,7 @@ static struct samsung_gate_clock s5pv210_gate_clks[] __initdata = {
728}; 728};
729 729
730/* S5P6442-specific clock gates. */ 730/* S5P6442-specific clock gates. */
731static struct samsung_gate_clock s5p6442_gate_clks[] __initdata = { 731static const struct samsung_gate_clock s5p6442_gate_clks[] __initconst = {
732 GATE(CLK_JPEG, "jpeg", "dout_hclkd", CLK_GATE_IP0, 28, 0, 0), 732 GATE(CLK_JPEG, "jpeg", "dout_hclkd", CLK_GATE_IP0, 28, 0, 0),
733 GATE(CLK_MFC, "mfc", "dout_hclkd", CLK_GATE_IP0, 16, 0, 0), 733 GATE(CLK_MFC, "mfc", "dout_hclkd", CLK_GATE_IP0, 16, 0, 0),
734 GATE(CLK_G2D, "g2d", "dout_hclkd", CLK_GATE_IP0, 12, 0, 0), 734 GATE(CLK_G2D, "g2d", "dout_hclkd", CLK_GATE_IP0, 12, 0, 0),
@@ -748,14 +748,14 @@ static struct samsung_gate_clock s5p6442_gate_clks[] __initdata = {
748 * Clock aliases for legacy clkdev look-up. 748 * Clock aliases for legacy clkdev look-up.
749 * NOTE: Needed only to support legacy board files. 749 * NOTE: Needed only to support legacy board files.
750 */ 750 */
751static struct samsung_clock_alias s5pv210_aliases[] = { 751static const struct samsung_clock_alias s5pv210_aliases[] __initconst = {
752 ALIAS(DOUT_APLL, NULL, "armclk"), 752 ALIAS(DOUT_APLL, NULL, "armclk"),
753 ALIAS(DOUT_HCLKM, NULL, "hclk_msys"), 753 ALIAS(DOUT_HCLKM, NULL, "hclk_msys"),
754 ALIAS(MOUT_DMC0, NULL, "sclk_dmc0"), 754 ALIAS(MOUT_DMC0, NULL, "sclk_dmc0"),
755}; 755};
756 756
757/* S5PV210-specific PLLs. */ 757/* S5PV210-specific PLLs. */
758static struct samsung_pll_clock s5pv210_pll_clks[] __initdata = { 758static const struct samsung_pll_clock s5pv210_pll_clks[] __initconst = {
759 [apll] = PLL(pll_4508, FOUT_APLL, "fout_apll", "fin_pll", 759 [apll] = PLL(pll_4508, FOUT_APLL, "fout_apll", "fin_pll",
760 APLL_LOCK, APLL_CON0, NULL), 760 APLL_LOCK, APLL_CON0, NULL),
761 [mpll] = PLL(pll_4502, FOUT_MPLL, "fout_mpll", "fin_pll", 761 [mpll] = PLL(pll_4502, FOUT_MPLL, "fout_mpll", "fin_pll",
@@ -767,7 +767,7 @@ static struct samsung_pll_clock s5pv210_pll_clks[] __initdata = {
767}; 767};
768 768
769/* S5P6442-specific PLLs. */ 769/* S5P6442-specific PLLs. */
770static struct samsung_pll_clock s5p6442_pll_clks[] __initdata = { 770static const struct samsung_pll_clock s5p6442_pll_clks[] __initconst = {
771 [apll] = PLL(pll_4502, FOUT_APLL, "fout_apll", "fin_pll", 771 [apll] = PLL(pll_4502, FOUT_APLL, "fout_apll", "fin_pll",
772 APLL_LOCK, APLL_CON0, NULL), 772 APLL_LOCK, APLL_CON0, NULL),
773 [mpll] = PLL(pll_4502, FOUT_MPLL, "fout_mpll", "fin_pll", 773 [mpll] = PLL(pll_4502, FOUT_MPLL, "fout_mpll", "fin_pll",
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index 9e1f88c04fd4..0117238391d6 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -98,7 +98,7 @@ void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, struct clk *clk,
98 98
99/* register a list of aliases */ 99/* register a list of aliases */
100void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, 100void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
101 struct samsung_clock_alias *list, 101 const struct samsung_clock_alias *list,
102 unsigned int nr_clk) 102 unsigned int nr_clk)
103{ 103{
104 struct clk *clk; 104 struct clk *clk;
@@ -132,7 +132,8 @@ void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
132 132
133/* register a list of fixed clocks */ 133/* register a list of fixed clocks */
134void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx, 134void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx,
135 struct samsung_fixed_rate_clock *list, unsigned int nr_clk) 135 const struct samsung_fixed_rate_clock *list,
136 unsigned int nr_clk)
136{ 137{
137 struct clk *clk; 138 struct clk *clk;
138 unsigned int idx, ret; 139 unsigned int idx, ret;
@@ -161,7 +162,7 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx,
161 162
162/* register a list of fixed factor clocks */ 163/* register a list of fixed factor clocks */
163void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx, 164void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx,
164 struct samsung_fixed_factor_clock *list, unsigned int nr_clk) 165 const struct samsung_fixed_factor_clock *list, unsigned int nr_clk)
165{ 166{
166 struct clk *clk; 167 struct clk *clk;
167 unsigned int idx; 168 unsigned int idx;
@@ -181,7 +182,7 @@ void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx,
181 182
182/* register a list of mux clocks */ 183/* register a list of mux clocks */
183void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, 184void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
184 struct samsung_mux_clock *list, 185 const struct samsung_mux_clock *list,
185 unsigned int nr_clk) 186 unsigned int nr_clk)
186{ 187{
187 struct clk *clk; 188 struct clk *clk;
@@ -213,7 +214,7 @@ void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
213 214
214/* register a list of div clocks */ 215/* register a list of div clocks */
215void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, 216void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
216 struct samsung_div_clock *list, 217 const struct samsung_div_clock *list,
217 unsigned int nr_clk) 218 unsigned int nr_clk)
218{ 219{
219 struct clk *clk; 220 struct clk *clk;
@@ -252,7 +253,7 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
252 253
253/* register a list of gate clocks */ 254/* register a list of gate clocks */
254void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, 255void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
255 struct samsung_gate_clock *list, 256 const struct samsung_gate_clock *list,
256 unsigned int nr_clk) 257 unsigned int nr_clk)
257{ 258{
258 struct clk *clk; 259 struct clk *clk;
@@ -389,7 +390,7 @@ struct samsung_clk_provider * __init samsung_cmu_register_one(
389 390
390 ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); 391 ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
391 if (!ctx) { 392 if (!ctx) {
392 panic("%s: unable to alllocate ctx\n", __func__); 393 panic("%s: unable to allocate ctx\n", __func__);
393 return ctx; 394 return ctx;
394 } 395 }
395 396
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index e4c75383cea7..b775fc29caa5 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -121,7 +121,7 @@ struct samsung_mux_clock {
121 unsigned int id; 121 unsigned int id;
122 const char *dev_name; 122 const char *dev_name;
123 const char *name; 123 const char *name;
124 const char **parent_names; 124 const char *const *parent_names;
125 u8 num_parents; 125 u8 num_parents;
126 unsigned long flags; 126 unsigned long flags;
127 unsigned long offset; 127 unsigned long offset;
@@ -368,28 +368,28 @@ extern void __init samsung_clk_of_register_fixed_ext(
368extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, 368extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
369 struct clk *clk, unsigned int id); 369 struct clk *clk, unsigned int id);
370 370
371extern void samsung_clk_register_alias(struct samsung_clk_provider *ctx, 371extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
372 struct samsung_clock_alias *list, 372 const struct samsung_clock_alias *list,
373 unsigned int nr_clk); 373 unsigned int nr_clk);
374extern void __init samsung_clk_register_fixed_rate( 374extern void __init samsung_clk_register_fixed_rate(
375 struct samsung_clk_provider *ctx, 375 struct samsung_clk_provider *ctx,
376 struct samsung_fixed_rate_clock *clk_list, 376 const struct samsung_fixed_rate_clock *clk_list,
377 unsigned int nr_clk); 377 unsigned int nr_clk);
378extern void __init samsung_clk_register_fixed_factor( 378extern void __init samsung_clk_register_fixed_factor(
379 struct samsung_clk_provider *ctx, 379 struct samsung_clk_provider *ctx,
380 struct samsung_fixed_factor_clock *list, 380 const struct samsung_fixed_factor_clock *list,
381 unsigned int nr_clk); 381 unsigned int nr_clk);
382extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, 382extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
383 struct samsung_mux_clock *clk_list, 383 const struct samsung_mux_clock *clk_list,
384 unsigned int nr_clk); 384 unsigned int nr_clk);
385extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, 385extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
386 struct samsung_div_clock *clk_list, 386 const struct samsung_div_clock *clk_list,
387 unsigned int nr_clk); 387 unsigned int nr_clk);
388extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, 388extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
389 struct samsung_gate_clock *clk_list, 389 const struct samsung_gate_clock *clk_list,
390 unsigned int nr_clk); 390 unsigned int nr_clk);
391extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, 391extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
392 struct samsung_pll_clock *pll_list, 392 const struct samsung_pll_clock *pll_list,
393 unsigned int nr_clk, void __iomem *base); 393 unsigned int nr_clk, void __iomem *base);
394 394
395extern struct samsung_clk_provider __init *samsung_cmu_register_one( 395extern struct samsung_clk_provider __init *samsung_cmu_register_one(
diff --git a/drivers/clk/shmobile/clk-emev2.c b/drivers/clk/shmobile/clk-emev2.c
index 6c7c929c7765..5b60beb7d0eb 100644
--- a/drivers/clk/shmobile/clk-emev2.c
+++ b/drivers/clk/shmobile/clk-emev2.c
@@ -34,7 +34,7 @@
34static DEFINE_SPINLOCK(lock); 34static DEFINE_SPINLOCK(lock);
35 35
36/* not pretty, but hey */ 36/* not pretty, but hey */
37void __iomem *smu_base; 37static void __iomem *smu_base;
38 38
39static void __init emev2_smu_write(unsigned long value, int offs) 39static void __init emev2_smu_write(unsigned long value, int offs)
40{ 40{
diff --git a/drivers/clk/sirf/Makefile b/drivers/clk/sirf/Makefile
index 36b8e203f6e7..09b4210d9124 100644
--- a/drivers/clk/sirf/Makefile
+++ b/drivers/clk/sirf/Makefile
@@ -2,4 +2,4 @@
2# Makefile for sirf specific clk 2# Makefile for sirf specific clk
3# 3#
4 4
5obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o clk-atlas6.o 5obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o clk-atlas6.o clk-atlas7.o
diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
new file mode 100644
index 000000000000..db8ab691dbf6
--- /dev/null
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -0,0 +1,1632 @@
1/*
2 * Clock tree for CSR SiRFAtlas7
3 *
4 * Copyright (c) 2014 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/bitops.h>
10#include <linux/io.h>
11#include <linux/clk-provider.h>
12#include <linux/delay.h>
13#include <linux/of_address.h>
14#include <linux/reset-controller.h>
15#include <linux/slab.h>
16
17#define SIRFSOC_CLKC_MEMPLL_AB_FREQ 0x0000
18#define SIRFSOC_CLKC_MEMPLL_AB_SSC 0x0004
19#define SIRFSOC_CLKC_MEMPLL_AB_CTRL0 0x0008
20#define SIRFSOC_CLKC_MEMPLL_AB_CTRL1 0x000c
21#define SIRFSOC_CLKC_MEMPLL_AB_STATUS 0x0010
22#define SIRFSOC_CLKC_MEMPLL_AB_SSRAM_ADDR 0x0014
23#define SIRFSOC_CLKC_MEMPLL_AB_SSRAM_DATA 0x0018
24
25#define SIRFSOC_CLKC_CPUPLL_AB_FREQ 0x001c
26#define SIRFSOC_CLKC_CPUPLL_AB_SSC 0x0020
27#define SIRFSOC_CLKC_CPUPLL_AB_CTRL0 0x0024
28#define SIRFSOC_CLKC_CPUPLL_AB_CTRL1 0x0028
29#define SIRFSOC_CLKC_CPUPLL_AB_STATUS 0x002c
30
31#define SIRFSOC_CLKC_SYS0PLL_AB_FREQ 0x0030
32#define SIRFSOC_CLKC_SYS0PLL_AB_SSC 0x0034
33#define SIRFSOC_CLKC_SYS0PLL_AB_CTRL0 0x0038
34#define SIRFSOC_CLKC_SYS0PLL_AB_CTRL1 0x003c
35#define SIRFSOC_CLKC_SYS0PLL_AB_STATUS 0x0040
36
37#define SIRFSOC_CLKC_SYS1PLL_AB_FREQ 0x0044
38#define SIRFSOC_CLKC_SYS1PLL_AB_SSC 0x0048
39#define SIRFSOC_CLKC_SYS1PLL_AB_CTRL0 0x004c
40#define SIRFSOC_CLKC_SYS1PLL_AB_CTRL1 0x0050
41#define SIRFSOC_CLKC_SYS1PLL_AB_STATUS 0x0054
42
43#define SIRFSOC_CLKC_SYS2PLL_AB_FREQ 0x0058
44#define SIRFSOC_CLKC_SYS2PLL_AB_SSC 0x005c
45#define SIRFSOC_CLKC_SYS2PLL_AB_CTRL0 0x0060
46#define SIRFSOC_CLKC_SYS2PLL_AB_CTRL1 0x0064
47#define SIRFSOC_CLKC_SYS2PLL_AB_STATUS 0x0068
48
49#define SIRFSOC_CLKC_SYS3PLL_AB_FREQ 0x006c
50#define SIRFSOC_CLKC_SYS3PLL_AB_SSC 0x0070
51#define SIRFSOC_CLKC_SYS3PLL_AB_CTRL0 0x0074
52#define SIRFSOC_CLKC_SYS3PLL_AB_CTRL1 0x0078
53#define SIRFSOC_CLKC_SYS3PLL_AB_STATUS 0x007c
54
55#define SIRFSOC_ABPLL_CTRL0_SSEN 0x00001000
56#define SIRFSOC_ABPLL_CTRL0_BYPASS 0x00000010
57#define SIRFSOC_ABPLL_CTRL0_RESET 0x00000001
58
59#define SIRFSOC_CLKC_AUDIO_DTO_INC 0x0088
60#define SIRFSOC_CLKC_DISP0_DTO_INC 0x008c
61#define SIRFSOC_CLKC_DISP1_DTO_INC 0x0090
62
63#define SIRFSOC_CLKC_AUDIO_DTO_SRC 0x0094
64#define SIRFSOC_CLKC_AUDIO_DTO_ENA 0x0098
65#define SIRFSOC_CLKC_AUDIO_DTO_DROFF 0x009c
66
67#define SIRFSOC_CLKC_DISP0_DTO_SRC 0x00a0
68#define SIRFSOC_CLKC_DISP0_DTO_ENA 0x00a4
69#define SIRFSOC_CLKC_DISP0_DTO_DROFF 0x00a8
70
71#define SIRFSOC_CLKC_DISP1_DTO_SRC 0x00ac
72#define SIRFSOC_CLKC_DISP1_DTO_ENA 0x00b0
73#define SIRFSOC_CLKC_DISP1_DTO_DROFF 0x00b4
74
75#define SIRFSOC_CLKC_I2S_CLK_SEL 0x00b8
76#define SIRFSOC_CLKC_I2S_SEL_STAT 0x00bc
77
78#define SIRFSOC_CLKC_USBPHY_CLKDIV_CFG 0x00c0
79#define SIRFSOC_CLKC_USBPHY_CLKDIV_ENA 0x00c4
80#define SIRFSOC_CLKC_USBPHY_CLK_SEL 0x00c8
81#define SIRFSOC_CLKC_USBPHY_CLK_SEL_STAT 0x00cc
82
83#define SIRFSOC_CLKC_BTSS_CLKDIV_CFG 0x00d0
84#define SIRFSOC_CLKC_BTSS_CLKDIV_ENA 0x00d4
85#define SIRFSOC_CLKC_BTSS_CLK_SEL 0x00d8
86#define SIRFSOC_CLKC_BTSS_CLK_SEL_STAT 0x00dc
87
88#define SIRFSOC_CLKC_RGMII_CLKDIV_CFG 0x00e0
89#define SIRFSOC_CLKC_RGMII_CLKDIV_ENA 0x00e4
90#define SIRFSOC_CLKC_RGMII_CLK_SEL 0x00e8
91#define SIRFSOC_CLKC_RGMII_CLK_SEL_STAT 0x00ec
92
93#define SIRFSOC_CLKC_CPU_CLKDIV_CFG 0x00f0
94#define SIRFSOC_CLKC_CPU_CLKDIV_ENA 0x00f4
95#define SIRFSOC_CLKC_CPU_CLK_SEL 0x00f8
96#define SIRFSOC_CLKC_CPU_CLK_SEL_STAT 0x00fc
97
98#define SIRFSOC_CLKC_SDPHY01_CLKDIV_CFG 0x0100
99#define SIRFSOC_CLKC_SDPHY01_CLKDIV_ENA 0x0104
100#define SIRFSOC_CLKC_SDPHY01_CLK_SEL 0x0108
101#define SIRFSOC_CLKC_SDPHY01_CLK_SEL_STAT 0x010c
102
103#define SIRFSOC_CLKC_SDPHY23_CLKDIV_CFG 0x0110
104#define SIRFSOC_CLKC_SDPHY23_CLKDIV_ENA 0x0114
105#define SIRFSOC_CLKC_SDPHY23_CLK_SEL 0x0118
106#define SIRFSOC_CLKC_SDPHY23_CLK_SEL_STAT 0x011c
107
108#define SIRFSOC_CLKC_SDPHY45_CLKDIV_CFG 0x0120
109#define SIRFSOC_CLKC_SDPHY45_CLKDIV_ENA 0x0124
110#define SIRFSOC_CLKC_SDPHY45_CLK_SEL 0x0128
111#define SIRFSOC_CLKC_SDPHY45_CLK_SEL_STAT 0x012c
112
113#define SIRFSOC_CLKC_SDPHY67_CLKDIV_CFG 0x0130
114#define SIRFSOC_CLKC_SDPHY67_CLKDIV_ENA 0x0134
115#define SIRFSOC_CLKC_SDPHY67_CLK_SEL 0x0138
116#define SIRFSOC_CLKC_SDPHY67_CLK_SEL_STAT 0x013c
117
118#define SIRFSOC_CLKC_CAN_CLKDIV_CFG 0x0140
119#define SIRFSOC_CLKC_CAN_CLKDIV_ENA 0x0144
120#define SIRFSOC_CLKC_CAN_CLK_SEL 0x0148
121#define SIRFSOC_CLKC_CAN_CLK_SEL_STAT 0x014c
122
123#define SIRFSOC_CLKC_DEINT_CLKDIV_CFG 0x0150
124#define SIRFSOC_CLKC_DEINT_CLKDIV_ENA 0x0154
125#define SIRFSOC_CLKC_DEINT_CLK_SEL 0x0158
126#define SIRFSOC_CLKC_DEINT_CLK_SEL_STAT 0x015c
127
128#define SIRFSOC_CLKC_NAND_CLKDIV_CFG 0x0160
129#define SIRFSOC_CLKC_NAND_CLKDIV_ENA 0x0164
130#define SIRFSOC_CLKC_NAND_CLK_SEL 0x0168
131#define SIRFSOC_CLKC_NAND_CLK_SEL_STAT 0x016c
132
133#define SIRFSOC_CLKC_DISP0_CLKDIV_CFG 0x0170
134#define SIRFSOC_CLKC_DISP0_CLKDIV_ENA 0x0174
135#define SIRFSOC_CLKC_DISP0_CLK_SEL 0x0178
136#define SIRFSOC_CLKC_DISP0_CLK_SEL_STAT 0x017c
137
138#define SIRFSOC_CLKC_DISP1_CLKDIV_CFG 0x0180
139#define SIRFSOC_CLKC_DISP1_CLKDIV_ENA 0x0184
140#define SIRFSOC_CLKC_DISP1_CLK_SEL 0x0188
141#define SIRFSOC_CLKC_DISP1_CLK_SEL_STAT 0x018c
142
143#define SIRFSOC_CLKC_GPU_CLKDIV_CFG 0x0190
144#define SIRFSOC_CLKC_GPU_CLKDIV_ENA 0x0194
145#define SIRFSOC_CLKC_GPU_CLK_SEL 0x0198
146#define SIRFSOC_CLKC_GPU_CLK_SEL_STAT 0x019c
147
148#define SIRFSOC_CLKC_GNSS_CLKDIV_CFG 0x01a0
149#define SIRFSOC_CLKC_GNSS_CLKDIV_ENA 0x01a4
150#define SIRFSOC_CLKC_GNSS_CLK_SEL 0x01a8
151#define SIRFSOC_CLKC_GNSS_CLK_SEL_STAT 0x01ac
152
153#define SIRFSOC_CLKC_SHARED_DIVIDER_CFG0 0x01b0
154#define SIRFSOC_CLKC_SHARED_DIVIDER_CFG1 0x01b4
155#define SIRFSOC_CLKC_SHARED_DIVIDER_ENA 0x01b8
156
157#define SIRFSOC_CLKC_SYS_CLK_SEL 0x01bc
158#define SIRFSOC_CLKC_SYS_CLK_SEL_STAT 0x01c0
159#define SIRFSOC_CLKC_IO_CLK_SEL 0x01c4
160#define SIRFSOC_CLKC_IO_CLK_SEL_STAT 0x01c8
161#define SIRFSOC_CLKC_G2D_CLK_SEL 0x01cc
162#define SIRFSOC_CLKC_G2D_CLK_SEL_STAT 0x01d0
163#define SIRFSOC_CLKC_JPENC_CLK_SEL 0x01d4
164#define SIRFSOC_CLKC_JPENC_CLK_SEL_STAT 0x01d8
165#define SIRFSOC_CLKC_VDEC_CLK_SEL 0x01dc
166#define SIRFSOC_CLKC_VDEC_CLK_SEL_STAT 0x01e0
167#define SIRFSOC_CLKC_GMAC_CLK_SEL 0x01e4
168#define SIRFSOC_CLKC_GMAC_CLK_SEL_STAT 0x01e8
169#define SIRFSOC_CLKC_USB_CLK_SEL 0x01ec
170#define SIRFSOC_CLKC_USB_CLK_SEL_STAT 0x01f0
171#define SIRFSOC_CLKC_KAS_CLK_SEL 0x01f4
172#define SIRFSOC_CLKC_KAS_CLK_SEL_STAT 0x01f8
173#define SIRFSOC_CLKC_SEC_CLK_SEL 0x01fc
174#define SIRFSOC_CLKC_SEC_CLK_SEL_STAT 0x0200
175#define SIRFSOC_CLKC_SDR_CLK_SEL 0x0204
176#define SIRFSOC_CLKC_SDR_CLK_SEL_STAT 0x0208
177#define SIRFSOC_CLKC_VIP_CLK_SEL 0x020c
178#define SIRFSOC_CLKC_VIP_CLK_SEL_STAT 0x0210
179#define SIRFSOC_CLKC_NOCD_CLK_SEL 0x0214
180#define SIRFSOC_CLKC_NOCD_CLK_SEL_STAT 0x0218
181#define SIRFSOC_CLKC_NOCR_CLK_SEL 0x021c
182#define SIRFSOC_CLKC_NOCR_CLK_SEL_STAT 0x0220
183#define SIRFSOC_CLKC_TPIU_CLK_SEL 0x0224
184#define SIRFSOC_CLKC_TPIU_CLK_SEL_STAT 0x0228
185
186#define SIRFSOC_CLKC_ROOT_CLK_EN0_SET 0x022c
187#define SIRFSOC_CLKC_ROOT_CLK_EN0_CLR 0x0230
188#define SIRFSOC_CLKC_ROOT_CLK_EN0_STAT 0x0234
189#define SIRFSOC_CLKC_ROOT_CLK_EN1_SET 0x0238
190#define SIRFSOC_CLKC_ROOT_CLK_EN1_CLR 0x023c
191#define SIRFSOC_CLKC_ROOT_CLK_EN1_STAT 0x0240
192
193#define SIRFSOC_CLKC_LEAF_CLK_EN0_SET 0x0244
194#define SIRFSOC_CLKC_LEAF_CLK_EN0_CLR 0x0248
195#define SIRFSOC_CLKC_LEAF_CLK_EN0_STAT 0x024c
196
197#define SIRFSOC_CLKC_RSTC_A7_SW_RST 0x0308
198
199#define SIRFSOC_CLKC_LEAF_CLK_EN1_SET 0x04a0
200#define SIRFSOC_CLKC_LEAF_CLK_EN2_SET 0x04b8
201#define SIRFSOC_CLKC_LEAF_CLK_EN3_SET 0x04d0
202#define SIRFSOC_CLKC_LEAF_CLK_EN4_SET 0x04e8
203#define SIRFSOC_CLKC_LEAF_CLK_EN5_SET 0x0500
204#define SIRFSOC_CLKC_LEAF_CLK_EN6_SET 0x0518
205#define SIRFSOC_CLKC_LEAF_CLK_EN7_SET 0x0530
206#define SIRFSOC_CLKC_LEAF_CLK_EN8_SET 0x0548
207
208
209static void __iomem *sirfsoc_clk_vbase;
210static struct clk_onecell_data clk_data;
211
212static const struct clk_div_table pll_div_table[] = {
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
221struct clk_pll {
222 struct clk_hw hw;
223 u16 regofs; /* register offset */
224};
225#define to_pllclk(_hw) container_of(_hw, struct clk_pll, hw)
226
227struct clk_dto {
228 struct clk_hw hw;
229 u16 inc_offset; /* dto increment offset */
230 u16 src_offset; /* dto src offset */
231};
232#define to_dtoclk(_hw) container_of(_hw, struct clk_dto, hw)
233
234struct clk_unit {
235 struct clk_hw hw;
236 u16 regofs;
237 u16 bit;
238 spinlock_t *lock;
239};
240#define to_unitclk(_hw) container_of(_hw, struct clk_unit, hw)
241
242struct atlas7_div_init_data {
243 const char *div_name;
244 const char *parent_name;
245 const char *gate_name;
246 unsigned long flags;
247 u8 divider_flags;
248 u8 gate_flags;
249 u32 div_offset;
250 u8 shift;
251 u8 width;
252 u32 gate_offset;
253 u8 gate_bit;
254 spinlock_t *lock;
255};
256
257struct atlas7_mux_init_data {
258 const char *mux_name;
259 const char * const *parent_names;
260 u8 parent_num;
261 unsigned long flags;
262 u8 mux_flags;
263 u32 mux_offset;
264 u8 shift;
265 u8 width;
266};
267
268struct atlas7_unit_init_data {
269 u32 index;
270 const char *unit_name;
271 const char *parent_name;
272 unsigned long flags;
273 u32 regofs;
274 u8 bit;
275 spinlock_t *lock;
276};
277
278struct atlas7_reset_desc {
279 const char *name;
280 u32 clk_ofs;
281 u8 clk_bit;
282 u32 rst_ofs;
283 u8 rst_bit;
284 spinlock_t *lock;
285};
286
287static DEFINE_SPINLOCK(cpupll_ctrl1_lock);
288static DEFINE_SPINLOCK(mempll_ctrl1_lock);
289static DEFINE_SPINLOCK(sys0pll_ctrl1_lock);
290static DEFINE_SPINLOCK(sys1pll_ctrl1_lock);
291static DEFINE_SPINLOCK(sys2pll_ctrl1_lock);
292static DEFINE_SPINLOCK(sys3pll_ctrl1_lock);
293static DEFINE_SPINLOCK(usbphy_div_lock);
294static DEFINE_SPINLOCK(btss_div_lock);
295static DEFINE_SPINLOCK(rgmii_div_lock);
296static DEFINE_SPINLOCK(cpu_div_lock);
297static DEFINE_SPINLOCK(sdphy01_div_lock);
298static DEFINE_SPINLOCK(sdphy23_div_lock);
299static DEFINE_SPINLOCK(sdphy45_div_lock);
300static DEFINE_SPINLOCK(sdphy67_div_lock);
301static DEFINE_SPINLOCK(can_div_lock);
302static DEFINE_SPINLOCK(deint_div_lock);
303static DEFINE_SPINLOCK(nand_div_lock);
304static DEFINE_SPINLOCK(disp0_div_lock);
305static DEFINE_SPINLOCK(disp1_div_lock);
306static DEFINE_SPINLOCK(gpu_div_lock);
307static DEFINE_SPINLOCK(gnss_div_lock);
308/* gate register shared */
309static DEFINE_SPINLOCK(share_div_lock);
310static DEFINE_SPINLOCK(root0_gate_lock);
311static DEFINE_SPINLOCK(root1_gate_lock);
312static DEFINE_SPINLOCK(leaf0_gate_lock);
313static DEFINE_SPINLOCK(leaf1_gate_lock);
314static DEFINE_SPINLOCK(leaf2_gate_lock);
315static DEFINE_SPINLOCK(leaf3_gate_lock);
316static DEFINE_SPINLOCK(leaf4_gate_lock);
317static DEFINE_SPINLOCK(leaf5_gate_lock);
318static DEFINE_SPINLOCK(leaf6_gate_lock);
319static DEFINE_SPINLOCK(leaf7_gate_lock);
320static DEFINE_SPINLOCK(leaf8_gate_lock);
321
322static inline unsigned long clkc_readl(unsigned reg)
323{
324 return readl(sirfsoc_clk_vbase + reg);
325}
326
327static inline void clkc_writel(u32 val, unsigned reg)
328{
329 writel(val, sirfsoc_clk_vbase + reg);
330}
331
332/*
333* ABPLL
334* integer mode: Fvco = Fin * 2 * NF / NR
335* Spread Spectrum mode: Fvco = Fin * SSN / NR
336* SSN = 2^24 / (256 * ((ssdiv >> ssdepth) << ssdepth) + (ssmod << ssdepth))
337*/
338static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
339 unsigned long parent_rate)
340{
341 unsigned long fin = parent_rate;
342 struct clk_pll *clk = to_pllclk(hw);
343 u64 rate;
344 u32 regctrl0 = clkc_readl(clk->regofs + SIRFSOC_CLKC_MEMPLL_AB_CTRL0 -
345 SIRFSOC_CLKC_MEMPLL_AB_FREQ);
346 u32 regfreq = clkc_readl(clk->regofs);
347 u32 regssc = clkc_readl(clk->regofs + SIRFSOC_CLKC_MEMPLL_AB_SSC -
348 SIRFSOC_CLKC_MEMPLL_AB_FREQ);
349 u32 nr = (regfreq >> 16 & (BIT(3) - 1)) + 1;
350 u32 nf = (regfreq & (BIT(9) - 1)) + 1;
351 u32 ssdiv = regssc >> 8 & (BIT(12) - 1);
352 u32 ssdepth = regssc >> 20 & (BIT(2) - 1);
353 u32 ssmod = regssc & (BIT(8) - 1);
354
355 if (regctrl0 & SIRFSOC_ABPLL_CTRL0_BYPASS)
356 return fin;
357
358 if (regctrl0 & SIRFSOC_ABPLL_CTRL0_SSEN) {
359 rate = fin;
360 rate *= 1 << 24;
361 do_div(rate, (256 * ((ssdiv >> ssdepth) << ssdepth)
362 + (ssmod << ssdepth)));
363 } else {
364 rate = 2 * fin;
365 rate *= nf;
366 do_div(rate, nr);
367 }
368 return rate;
369}
370
371static const struct clk_ops ab_pll_ops = {
372 .recalc_rate = pll_clk_recalc_rate,
373};
374
375static const char * const pll_clk_parents[] = {
376 "xin",
377};
378
379static struct clk_init_data clk_cpupll_init = {
380 .name = "cpupll_vco",
381 .ops = &ab_pll_ops,
382 .parent_names = pll_clk_parents,
383 .num_parents = ARRAY_SIZE(pll_clk_parents),
384};
385
386static struct clk_pll clk_cpupll = {
387 .regofs = SIRFSOC_CLKC_CPUPLL_AB_FREQ,
388 .hw = {
389 .init = &clk_cpupll_init,
390 },
391};
392
393static struct clk_init_data clk_mempll_init = {
394 .name = "mempll_vco",
395 .ops = &ab_pll_ops,
396 .parent_names = pll_clk_parents,
397 .num_parents = ARRAY_SIZE(pll_clk_parents),
398};
399
400static struct clk_pll clk_mempll = {
401 .regofs = SIRFSOC_CLKC_MEMPLL_AB_FREQ,
402 .hw = {
403 .init = &clk_mempll_init,
404 },
405};
406
407static struct clk_init_data clk_sys0pll_init = {
408 .name = "sys0pll_vco",
409 .ops = &ab_pll_ops,
410 .parent_names = pll_clk_parents,
411 .num_parents = ARRAY_SIZE(pll_clk_parents),
412};
413
414static struct clk_pll clk_sys0pll = {
415 .regofs = SIRFSOC_CLKC_SYS0PLL_AB_FREQ,
416 .hw = {
417 .init = &clk_sys0pll_init,
418 },
419};
420
421static struct clk_init_data clk_sys1pll_init = {
422 .name = "sys1pll_vco",
423 .ops = &ab_pll_ops,
424 .parent_names = pll_clk_parents,
425 .num_parents = ARRAY_SIZE(pll_clk_parents),
426};
427
428static struct clk_pll clk_sys1pll = {
429 .regofs = SIRFSOC_CLKC_SYS1PLL_AB_FREQ,
430 .hw = {
431 .init = &clk_sys1pll_init,
432 },
433};
434
435static struct clk_init_data clk_sys2pll_init = {
436 .name = "sys2pll_vco",
437 .ops = &ab_pll_ops,
438 .parent_names = pll_clk_parents,
439 .num_parents = ARRAY_SIZE(pll_clk_parents),
440};
441
442static struct clk_pll clk_sys2pll = {
443 .regofs = SIRFSOC_CLKC_SYS2PLL_AB_FREQ,
444 .hw = {
445 .init = &clk_sys2pll_init,
446 },
447};
448
449static struct clk_init_data clk_sys3pll_init = {
450 .name = "sys3pll_vco",
451 .ops = &ab_pll_ops,
452 .parent_names = pll_clk_parents,
453 .num_parents = ARRAY_SIZE(pll_clk_parents),
454};
455
456static struct clk_pll clk_sys3pll = {
457 .regofs = SIRFSOC_CLKC_SYS3PLL_AB_FREQ,
458 .hw = {
459 .init = &clk_sys3pll_init,
460 },
461};
462
463/*
464 * DTO in clkc, default enable double resolution mode
465 * double resolution mode:fout = fin * finc / 2^29
466 * normal mode:fout = fin * finc / 2^28
467 */
468static int dto_clk_is_enabled(struct clk_hw *hw)
469{
470 struct clk_dto *clk = to_dtoclk(hw);
471 int reg;
472
473 reg = clk->src_offset + SIRFSOC_CLKC_AUDIO_DTO_ENA - SIRFSOC_CLKC_AUDIO_DTO_SRC;
474
475 return !!(clkc_readl(reg) & BIT(0));
476}
477
478static int dto_clk_enable(struct clk_hw *hw)
479{
480 u32 val, reg;
481 struct clk_dto *clk = to_dtoclk(hw);
482
483 reg = clk->src_offset + SIRFSOC_CLKC_AUDIO_DTO_ENA - SIRFSOC_CLKC_AUDIO_DTO_SRC;
484
485 val = clkc_readl(reg) | BIT(0);
486 clkc_writel(val, reg);
487 return 0;
488}
489
490static void dto_clk_disable(struct clk_hw *hw)
491{
492 u32 val, reg;
493 struct clk_dto *clk = to_dtoclk(hw);
494
495 reg = clk->src_offset + SIRFSOC_CLKC_AUDIO_DTO_ENA - SIRFSOC_CLKC_AUDIO_DTO_SRC;
496
497 val = clkc_readl(reg) & ~BIT(0);
498 clkc_writel(val, reg);
499}
500
501static unsigned long dto_clk_recalc_rate(struct clk_hw *hw,
502 unsigned long parent_rate)
503{
504 u64 rate = parent_rate;
505 struct clk_dto *clk = to_dtoclk(hw);
506 u32 finc = clkc_readl(clk->inc_offset);
507 u32 droff = clkc_readl(clk->src_offset + SIRFSOC_CLKC_AUDIO_DTO_DROFF - SIRFSOC_CLKC_AUDIO_DTO_SRC);
508
509 rate *= finc;
510 if (droff & BIT(0))
511 /* Double resolution off */
512 do_div(rate, 1 << 28);
513 else
514 do_div(rate, 1 << 29);
515
516 return rate;
517}
518
519static long dto_clk_round_rate(struct clk_hw *hw, unsigned long rate,
520 unsigned long *parent_rate)
521{
522 u64 dividend = rate * (1 << 29);
523
524 do_div(dividend, *parent_rate);
525 dividend *= *parent_rate;
526 do_div(dividend, 1 << 29);
527
528 return dividend;
529}
530
531static int dto_clk_set_rate(struct clk_hw *hw, unsigned long rate,
532 unsigned long parent_rate)
533{
534 u64 dividend = rate * (1 << 29);
535 struct clk_dto *clk = to_dtoclk(hw);
536
537 do_div(dividend, parent_rate);
538 clkc_writel(0, clk->src_offset + SIRFSOC_CLKC_AUDIO_DTO_DROFF - SIRFSOC_CLKC_AUDIO_DTO_SRC);
539 clkc_writel(dividend, clk->inc_offset);
540
541 return 0;
542}
543
544static u8 dto_clk_get_parent(struct clk_hw *hw)
545{
546 struct clk_dto *clk = to_dtoclk(hw);
547
548 return clkc_readl(clk->src_offset);
549}
550
551/*
552 * dto need CLK_SET_PARENT_GATE
553 */
554static int dto_clk_set_parent(struct clk_hw *hw, u8 index)
555{
556 struct clk_dto *clk = to_dtoclk(hw);
557
558 clkc_writel(index, clk->src_offset);
559 return 0;
560}
561
562static const struct clk_ops dto_ops = {
563 .is_enabled = dto_clk_is_enabled,
564 .enable = dto_clk_enable,
565 .disable = dto_clk_disable,
566 .recalc_rate = dto_clk_recalc_rate,
567 .round_rate = dto_clk_round_rate,
568 .set_rate = dto_clk_set_rate,
569 .get_parent = dto_clk_get_parent,
570 .set_parent = dto_clk_set_parent,
571};
572
573/* dto parent clock as syspllvco/clk1 */
574static const char * const audiodto_clk_parents[] = {
575 "sys0pll_clk1",
576 "sys1pll_clk1",
577 "sys3pll_clk1",
578};
579
580static struct clk_init_data clk_audiodto_init = {
581 .name = "audio_dto",
582 .ops = &dto_ops,
583 .parent_names = audiodto_clk_parents,
584 .num_parents = ARRAY_SIZE(audiodto_clk_parents),
585};
586
587static struct clk_dto clk_audio_dto = {
588 .inc_offset = SIRFSOC_CLKC_AUDIO_DTO_INC,
589 .src_offset = SIRFSOC_CLKC_AUDIO_DTO_SRC,
590 .hw = {
591 .init = &clk_audiodto_init,
592 },
593};
594
595static const char * const disp0dto_clk_parents[] = {
596 "sys0pll_clk1",
597 "sys1pll_clk1",
598 "sys3pll_clk1",
599};
600
601static struct clk_init_data clk_disp0dto_init = {
602 .name = "disp0_dto",
603 .ops = &dto_ops,
604 .parent_names = disp0dto_clk_parents,
605 .num_parents = ARRAY_SIZE(disp0dto_clk_parents),
606};
607
608static struct clk_dto clk_disp0_dto = {
609 .inc_offset = SIRFSOC_CLKC_DISP0_DTO_INC,
610 .src_offset = SIRFSOC_CLKC_DISP0_DTO_SRC,
611 .hw = {
612 .init = &clk_disp0dto_init,
613 },
614};
615
616static const char * const disp1dto_clk_parents[] = {
617 "sys0pll_clk1",
618 "sys1pll_clk1",
619 "sys3pll_clk1",
620};
621
622static struct clk_init_data clk_disp1dto_init = {
623 .name = "disp1_dto",
624 .ops = &dto_ops,
625 .parent_names = disp1dto_clk_parents,
626 .num_parents = ARRAY_SIZE(disp1dto_clk_parents),
627};
628
629static struct clk_dto clk_disp1_dto = {
630 .inc_offset = SIRFSOC_CLKC_DISP1_DTO_INC,
631 .src_offset = SIRFSOC_CLKC_DISP1_DTO_SRC,
632 .hw = {
633 .init = &clk_disp1dto_init,
634 },
635};
636
637static struct atlas7_div_init_data divider_list[] __initdata = {
638 /* div_name, parent_name, gate_name, clk_flag, divider_flag, gate_flag, div_offset, shift, wdith, gate_offset, bit_enable, lock */
639 { "sys0pll_qa1", "sys0pll_fixdiv", "sys0pll_a1", 0, 0, 0, SIRFSOC_CLKC_USBPHY_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_USBPHY_CLKDIV_ENA, 0, &usbphy_div_lock },
640 { "sys1pll_qa1", "sys1pll_fixdiv", "sys1pll_a1", 0, 0, 0, SIRFSOC_CLKC_USBPHY_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_USBPHY_CLKDIV_ENA, 4, &usbphy_div_lock },
641 { "sys2pll_qa1", "sys2pll_fixdiv", "sys2pll_a1", 0, 0, 0, SIRFSOC_CLKC_USBPHY_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_USBPHY_CLKDIV_ENA, 8, &usbphy_div_lock },
642 { "sys3pll_qa1", "sys3pll_fixdiv", "sys3pll_a1", 0, 0, 0, SIRFSOC_CLKC_USBPHY_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_USBPHY_CLKDIV_ENA, 12, &usbphy_div_lock },
643 { "sys0pll_qa2", "sys0pll_fixdiv", "sys0pll_a2", 0, 0, 0, SIRFSOC_CLKC_BTSS_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_BTSS_CLKDIV_ENA, 0, &btss_div_lock },
644 { "sys1pll_qa2", "sys1pll_fixdiv", "sys1pll_a2", 0, 0, 0, SIRFSOC_CLKC_BTSS_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_BTSS_CLKDIV_ENA, 4, &btss_div_lock },
645 { "sys2pll_qa2", "sys2pll_fixdiv", "sys2pll_a2", 0, 0, 0, SIRFSOC_CLKC_BTSS_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_BTSS_CLKDIV_ENA, 8, &btss_div_lock },
646 { "sys3pll_qa2", "sys3pll_fixdiv", "sys3pll_a2", 0, 0, 0, SIRFSOC_CLKC_BTSS_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_BTSS_CLKDIV_ENA, 12, &btss_div_lock },
647 { "sys0pll_qa3", "sys0pll_fixdiv", "sys0pll_a3", 0, 0, 0, SIRFSOC_CLKC_RGMII_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_RGMII_CLKDIV_ENA, 0, &rgmii_div_lock },
648 { "sys1pll_qa3", "sys1pll_fixdiv", "sys1pll_a3", 0, 0, 0, SIRFSOC_CLKC_RGMII_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_RGMII_CLKDIV_ENA, 4, &rgmii_div_lock },
649 { "sys2pll_qa3", "sys2pll_fixdiv", "sys2pll_a3", 0, 0, 0, SIRFSOC_CLKC_RGMII_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_RGMII_CLKDIV_ENA, 8, &rgmii_div_lock },
650 { "sys3pll_qa3", "sys3pll_fixdiv", "sys3pll_a3", 0, 0, 0, SIRFSOC_CLKC_RGMII_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_RGMII_CLKDIV_ENA, 12, &rgmii_div_lock },
651 { "sys0pll_qa4", "sys0pll_fixdiv", "sys0pll_a4", 0, 0, 0, SIRFSOC_CLKC_CPU_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_CPU_CLKDIV_ENA, 0, &cpu_div_lock },
652 { "sys1pll_qa4", "sys1pll_fixdiv", "sys1pll_a4", 0, 0, CLK_IGNORE_UNUSED, SIRFSOC_CLKC_CPU_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_CPU_CLKDIV_ENA, 4, &cpu_div_lock },
653 { "sys0pll_qa5", "sys0pll_fixdiv", "sys0pll_a5", 0, 0, 0, SIRFSOC_CLKC_SDPHY01_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_SDPHY01_CLKDIV_ENA, 0, &sdphy01_div_lock },
654 { "sys1pll_qa5", "sys1pll_fixdiv", "sys1pll_a5", 0, 0, 0, SIRFSOC_CLKC_SDPHY01_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_SDPHY01_CLKDIV_ENA, 4, &sdphy01_div_lock },
655 { "sys2pll_qa5", "sys2pll_fixdiv", "sys2pll_a5", 0, 0, 0, SIRFSOC_CLKC_SDPHY01_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_SDPHY01_CLKDIV_ENA, 8, &sdphy01_div_lock },
656 { "sys3pll_qa5", "sys3pll_fixdiv", "sys3pll_a5", 0, 0, 0, SIRFSOC_CLKC_SDPHY01_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_SDPHY01_CLKDIV_ENA, 12, &sdphy01_div_lock },
657 { "sys0pll_qa6", "sys0pll_fixdiv", "sys0pll_a6", 0, 0, 0, SIRFSOC_CLKC_SDPHY23_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_SDPHY23_CLKDIV_ENA, 0, &sdphy23_div_lock },
658 { "sys1pll_qa6", "sys1pll_fixdiv", "sys1pll_a6", 0, 0, 0, SIRFSOC_CLKC_SDPHY23_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_SDPHY23_CLKDIV_ENA, 4, &sdphy23_div_lock },
659 { "sys2pll_qa6", "sys2pll_fixdiv", "sys2pll_a6", 0, 0, 0, SIRFSOC_CLKC_SDPHY23_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_SDPHY23_CLKDIV_ENA, 8, &sdphy23_div_lock },
660 { "sys3pll_qa6", "sys3pll_fixdiv", "sys3pll_a6", 0, 0, 0, SIRFSOC_CLKC_SDPHY23_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_SDPHY23_CLKDIV_ENA, 12, &sdphy23_div_lock },
661 { "sys0pll_qa7", "sys0pll_fixdiv", "sys0pll_a7", 0, 0, 0, SIRFSOC_CLKC_SDPHY45_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_SDPHY45_CLKDIV_ENA, 0, &sdphy45_div_lock },
662 { "sys1pll_qa7", "sys1pll_fixdiv", "sys1pll_a7", 0, 0, 0, SIRFSOC_CLKC_SDPHY45_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_SDPHY45_CLKDIV_ENA, 4, &sdphy45_div_lock },
663 { "sys2pll_qa7", "sys2pll_fixdiv", "sys2pll_a7", 0, 0, 0, SIRFSOC_CLKC_SDPHY45_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_SDPHY45_CLKDIV_ENA, 8, &sdphy45_div_lock },
664 { "sys3pll_qa7", "sys3pll_fixdiv", "sys3pll_a7", 0, 0, 0, SIRFSOC_CLKC_SDPHY45_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_SDPHY45_CLKDIV_ENA, 12, &sdphy45_div_lock },
665 { "sys0pll_qa8", "sys0pll_fixdiv", "sys0pll_a8", 0, 0, 0, SIRFSOC_CLKC_SDPHY67_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_SDPHY67_CLKDIV_ENA, 0, &sdphy67_div_lock },
666 { "sys1pll_qa8", "sys1pll_fixdiv", "sys1pll_a8", 0, 0, 0, SIRFSOC_CLKC_SDPHY67_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_SDPHY67_CLKDIV_ENA, 4, &sdphy67_div_lock },
667 { "sys2pll_qa8", "sys2pll_fixdiv", "sys2pll_a8", 0, 0, 0, SIRFSOC_CLKC_SDPHY67_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_SDPHY67_CLKDIV_ENA, 8, &sdphy67_div_lock },
668 { "sys3pll_qa8", "sys3pll_fixdiv", "sys3pll_a8", 0, 0, 0, SIRFSOC_CLKC_SDPHY67_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_SDPHY67_CLKDIV_ENA, 12, &sdphy67_div_lock },
669 { "sys0pll_qa9", "sys0pll_fixdiv", "sys0pll_a9", 0, 0, 0, SIRFSOC_CLKC_CAN_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_CAN_CLKDIV_ENA, 0, &can_div_lock },
670 { "sys1pll_qa9", "sys1pll_fixdiv", "sys1pll_a9", 0, 0, 0, SIRFSOC_CLKC_CAN_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_CAN_CLKDIV_ENA, 4, &can_div_lock },
671 { "sys2pll_qa9", "sys2pll_fixdiv", "sys2pll_a9", 0, 0, 0, SIRFSOC_CLKC_CAN_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_CAN_CLKDIV_ENA, 8, &can_div_lock },
672 { "sys3pll_qa9", "sys3pll_fixdiv", "sys3pll_a9", 0, 0, 0, SIRFSOC_CLKC_CAN_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_CAN_CLKDIV_ENA, 12, &can_div_lock },
673 { "sys0pll_qa10", "sys0pll_fixdiv", "sys0pll_a10", 0, 0, 0, SIRFSOC_CLKC_DEINT_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_DEINT_CLKDIV_ENA, 0, &deint_div_lock },
674 { "sys1pll_qa10", "sys1pll_fixdiv", "sys1pll_a10", 0, 0, 0, SIRFSOC_CLKC_DEINT_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_DEINT_CLKDIV_ENA, 4, &deint_div_lock },
675 { "sys2pll_qa10", "sys2pll_fixdiv", "sys2pll_a10", 0, 0, 0, SIRFSOC_CLKC_DEINT_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_DEINT_CLKDIV_ENA, 8, &deint_div_lock },
676 { "sys3pll_qa10", "sys3pll_fixdiv", "sys3pll_a10", 0, 0, 0, SIRFSOC_CLKC_DEINT_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_DEINT_CLKDIV_ENA, 12, &deint_div_lock },
677 { "sys0pll_qa11", "sys0pll_fixdiv", "sys0pll_a11", 0, 0, 0, SIRFSOC_CLKC_NAND_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_NAND_CLKDIV_ENA, 0, &nand_div_lock },
678 { "sys1pll_qa11", "sys1pll_fixdiv", "sys1pll_a11", 0, 0, 0, SIRFSOC_CLKC_NAND_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_NAND_CLKDIV_ENA, 4, &nand_div_lock },
679 { "sys2pll_qa11", "sys2pll_fixdiv", "sys2pll_a11", 0, 0, 0, SIRFSOC_CLKC_NAND_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_NAND_CLKDIV_ENA, 8, &nand_div_lock },
680 { "sys3pll_qa11", "sys3pll_fixdiv", "sys3pll_a11", 0, 0, 0, SIRFSOC_CLKC_NAND_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_NAND_CLKDIV_ENA, 12, &nand_div_lock },
681 { "sys0pll_qa12", "sys0pll_fixdiv", "sys0pll_a12", 0, 0, 0, SIRFSOC_CLKC_DISP0_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_DISP0_CLKDIV_ENA, 0, &disp0_div_lock },
682 { "sys1pll_qa12", "sys1pll_fixdiv", "sys1pll_a12", 0, 0, 0, SIRFSOC_CLKC_DISP0_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_DISP0_CLKDIV_ENA, 4, &disp0_div_lock },
683 { "sys2pll_qa12", "sys2pll_fixdiv", "sys2pll_a12", 0, 0, 0, SIRFSOC_CLKC_DISP0_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_DISP0_CLKDIV_ENA, 8, &disp0_div_lock },
684 { "sys3pll_qa12", "sys3pll_fixdiv", "sys3pll_a12", 0, 0, 0, SIRFSOC_CLKC_DISP0_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_DISP0_CLKDIV_ENA, 12, &disp0_div_lock },
685 { "sys0pll_qa13", "sys0pll_fixdiv", "sys0pll_a13", 0, 0, 0, SIRFSOC_CLKC_DISP1_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_DISP1_CLKDIV_ENA, 0, &disp1_div_lock },
686 { "sys1pll_qa13", "sys1pll_fixdiv", "sys1pll_a13", 0, 0, 0, SIRFSOC_CLKC_DISP1_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_DISP1_CLKDIV_ENA, 4, &disp1_div_lock },
687 { "sys2pll_qa13", "sys2pll_fixdiv", "sys2pll_a13", 0, 0, 0, SIRFSOC_CLKC_DISP1_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_DISP1_CLKDIV_ENA, 8, &disp1_div_lock },
688 { "sys3pll_qa13", "sys3pll_fixdiv", "sys3pll_a13", 0, 0, 0, SIRFSOC_CLKC_DISP1_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_DISP1_CLKDIV_ENA, 12, &disp1_div_lock },
689 { "sys0pll_qa14", "sys0pll_fixdiv", "sys0pll_a14", 0, 0, 0, SIRFSOC_CLKC_GPU_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_GPU_CLKDIV_ENA, 0, &gpu_div_lock },
690 { "sys1pll_qa14", "sys1pll_fixdiv", "sys1pll_a14", 0, 0, 0, SIRFSOC_CLKC_GPU_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_GPU_CLKDIV_ENA, 4, &gpu_div_lock },
691 { "sys2pll_qa14", "sys2pll_fixdiv", "sys2pll_a14", 0, 0, 0, SIRFSOC_CLKC_GPU_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_GPU_CLKDIV_ENA, 8, &gpu_div_lock },
692 { "sys3pll_qa14", "sys3pll_fixdiv", "sys3pll_a14", 0, 0, 0, SIRFSOC_CLKC_GPU_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_GPU_CLKDIV_ENA, 12, &gpu_div_lock },
693 { "sys0pll_qa15", "sys0pll_fixdiv", "sys0pll_a15", 0, 0, 0, SIRFSOC_CLKC_GNSS_CLKDIV_CFG, 0, 6, SIRFSOC_CLKC_GNSS_CLKDIV_ENA, 0, &gnss_div_lock },
694 { "sys1pll_qa15", "sys1pll_fixdiv", "sys1pll_a15", 0, 0, 0, SIRFSOC_CLKC_GNSS_CLKDIV_CFG, 8, 6, SIRFSOC_CLKC_GNSS_CLKDIV_ENA, 4, &gnss_div_lock },
695 { "sys2pll_qa15", "sys2pll_fixdiv", "sys2pll_a15", 0, 0, 0, SIRFSOC_CLKC_GNSS_CLKDIV_CFG, 16, 6, SIRFSOC_CLKC_GNSS_CLKDIV_ENA, 8, &gnss_div_lock },
696 { "sys3pll_qa15", "sys3pll_fixdiv", "sys3pll_a15", 0, 0, 0, SIRFSOC_CLKC_GNSS_CLKDIV_CFG, 24, 6, SIRFSOC_CLKC_GNSS_CLKDIV_ENA, 12, &gnss_div_lock },
697 { "sys1pll_qa18", "sys1pll_fixdiv", "sys1pll_a18", 0, 0, 0, SIRFSOC_CLKC_SHARED_DIVIDER_CFG0, 24, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 12, &share_div_lock },
698 { "sys1pll_qa19", "sys1pll_fixdiv", "sys1pll_a19", 0, 0, CLK_IGNORE_UNUSED, SIRFSOC_CLKC_SHARED_DIVIDER_CFG0, 16, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 8, &share_div_lock },
699 { "sys1pll_qa20", "sys1pll_fixdiv", "sys1pll_a20", 0, 0, 0, SIRFSOC_CLKC_SHARED_DIVIDER_CFG0, 8, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 4, &share_div_lock },
700 { "sys2pll_qa20", "sys2pll_fixdiv", "sys2pll_a20", 0, 0, 0, SIRFSOC_CLKC_SHARED_DIVIDER_CFG0, 0, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 0, &share_div_lock },
701 { "sys1pll_qa17", "sys1pll_fixdiv", "sys1pll_a17", 0, 0, CLK_IGNORE_UNUSED, SIRFSOC_CLKC_SHARED_DIVIDER_CFG1, 8, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 20, &share_div_lock },
702 { "sys0pll_qa20", "sys0pll_fixdiv", "sys0pll_a20", 0, 0, 0, SIRFSOC_CLKC_SHARED_DIVIDER_CFG1, 0, 6, SIRFSOC_CLKC_SHARED_DIVIDER_ENA, 16, &share_div_lock },
703};
704
705static const char * const i2s_clk_parents[] = {
706 "xin",
707 "xinw",
708 "audio_dto",
709 /* "pwm_i2s01" */
710};
711
712static const char * const usbphy_clk_parents[] = {
713 "xin",
714 "xinw",
715 "sys0pll_a1",
716 "sys1pll_a1",
717 "sys2pll_a1",
718 "sys3pll_a1",
719};
720
721static const char * const btss_clk_parents[] = {
722 "xin",
723 "xinw",
724 "sys0pll_a2",
725 "sys1pll_a2",
726 "sys2pll_a2",
727 "sys3pll_a2",
728};
729
730static const char * const rgmii_clk_parents[] = {
731 "xin",
732 "xinw",
733 "sys0pll_a3",
734 "sys1pll_a3",
735 "sys2pll_a3",
736 "sys3pll_a3",
737};
738
739static const char * const cpu_clk_parents[] = {
740 "xin",
741 "xinw",
742 "sys0pll_a4",
743 "sys1pll_a4",
744 "cpupll_clk1",
745};
746
747static const char * const sdphy01_clk_parents[] = {
748 "xin",
749 "xinw",
750 "sys0pll_a5",
751 "sys1pll_a5",
752 "sys2pll_a5",
753 "sys3pll_a5",
754};
755
756static const char * const sdphy23_clk_parents[] = {
757 "xin",
758 "xinw",
759 "sys0pll_a6",
760 "sys1pll_a6",
761 "sys2pll_a6",
762 "sys3pll_a6",
763};
764
765static const char * const sdphy45_clk_parents[] = {
766 "xin",
767 "xinw",
768 "sys0pll_a7",
769 "sys1pll_a7",
770 "sys2pll_a7",
771 "sys3pll_a7",
772};
773
774static const char * const sdphy67_clk_parents[] = {
775 "xin",
776 "xinw",
777 "sys0pll_a8",
778 "sys1pll_a8",
779 "sys2pll_a8",
780 "sys3pll_a8",
781};
782
783static const char * const can_clk_parents[] = {
784 "xin",
785 "xinw",
786 "sys0pll_a9",
787 "sys1pll_a9",
788 "sys2pll_a9",
789 "sys3pll_a9",
790};
791
792static const char * const deint_clk_parents[] = {
793 "xin",
794 "xinw",
795 "sys0pll_a10",
796 "sys1pll_a10",
797 "sys2pll_a10",
798 "sys3pll_a10",
799};
800
801static const char * const nand_clk_parents[] = {
802 "xin",
803 "xinw",
804 "sys0pll_a11",
805 "sys1pll_a11",
806 "sys2pll_a11",
807 "sys3pll_a11",
808};
809
810static const char * const disp0_clk_parents[] = {
811 "xin",
812 "xinw",
813 "sys0pll_a12",
814 "sys1pll_a12",
815 "sys2pll_a12",
816 "sys3pll_a12",
817 "disp0_dto",
818};
819
820static const char * const disp1_clk_parents[] = {
821 "xin",
822 "xinw",
823 "sys0pll_a13",
824 "sys1pll_a13",
825 "sys2pll_a13",
826 "sys3pll_a13",
827 "disp1_dto",
828};
829
830static const char * const gpu_clk_parents[] = {
831 "xin",
832 "xinw",
833 "sys0pll_a14",
834 "sys1pll_a14",
835 "sys2pll_a14",
836 "sys3pll_a14",
837};
838
839static const char * const gnss_clk_parents[] = {
840 "xin",
841 "xinw",
842 "sys0pll_a15",
843 "sys1pll_a15",
844 "sys2pll_a15",
845 "sys3pll_a15",
846};
847
848static const char * const sys_clk_parents[] = {
849 "xin",
850 "xinw",
851 "sys2pll_a20",
852 "sys1pll_a20",
853 "sys1pll_a19",
854 "sys1pll_a18",
855 "sys0pll_a20",
856 "sys1pll_a17",
857};
858
859static const char * const io_clk_parents[] = {
860 "xin",
861 "xinw",
862 "sys2pll_a20",
863 "sys1pll_a20",
864 "sys1pll_a19",
865 "sys1pll_a18",
866 "sys0pll_a20",
867 "sys1pll_a17",
868};
869
870static const char * const g2d_clk_parents[] = {
871 "xin",
872 "xinw",
873 "sys2pll_a20",
874 "sys1pll_a20",
875 "sys1pll_a19",
876 "sys1pll_a18",
877 "sys0pll_a20",
878 "sys1pll_a17",
879};
880
881static const char * const jpenc_clk_parents[] = {
882 "xin",
883 "xinw",
884 "sys2pll_a20",
885 "sys1pll_a20",
886 "sys1pll_a19",
887 "sys1pll_a18",
888 "sys0pll_a20",
889 "sys1pll_a17",
890};
891
892static const char * const vdec_clk_parents[] = {
893 "xin",
894 "xinw",
895 "sys2pll_a20",
896 "sys1pll_a20",
897 "sys1pll_a19",
898 "sys1pll_a18",
899 "sys0pll_a20",
900 "sys1pll_a17",
901};
902
903static const char * const gmac_clk_parents[] = {
904 "xin",
905 "xinw",
906 "sys2pll_a20",
907 "sys1pll_a20",
908 "sys1pll_a19",
909 "sys1pll_a18",
910 "sys0pll_a20",
911 "sys1pll_a17",
912};
913
914static const char * const usb_clk_parents[] = {
915 "xin",
916 "xinw",
917 "sys2pll_a20",
918 "sys1pll_a20",
919 "sys1pll_a19",
920 "sys1pll_a18",
921 "sys0pll_a20",
922 "sys1pll_a17",
923};
924
925static const char * const kas_clk_parents[] = {
926 "xin",
927 "xinw",
928 "sys2pll_a20",
929 "sys1pll_a20",
930 "sys1pll_a19",
931 "sys1pll_a18",
932 "sys0pll_a20",
933 "sys1pll_a17",
934};
935
936static const char * const sec_clk_parents[] = {
937 "xin",
938 "xinw",
939 "sys2pll_a20",
940 "sys1pll_a20",
941 "sys1pll_a19",
942 "sys1pll_a18",
943 "sys0pll_a20",
944 "sys1pll_a17",
945};
946
947static const char * const sdr_clk_parents[] = {
948 "xin",
949 "xinw",
950 "sys2pll_a20",
951 "sys1pll_a20",
952 "sys1pll_a19",
953 "sys1pll_a18",
954 "sys0pll_a20",
955 "sys1pll_a17",
956};
957
958static const char * const vip_clk_parents[] = {
959 "xin",
960 "xinw",
961 "sys2pll_a20",
962 "sys1pll_a20",
963 "sys1pll_a19",
964 "sys1pll_a18",
965 "sys0pll_a20",
966 "sys1pll_a17",
967};
968
969static const char * const nocd_clk_parents[] = {
970 "xin",
971 "xinw",
972 "sys2pll_a20",
973 "sys1pll_a20",
974 "sys1pll_a19",
975 "sys1pll_a18",
976 "sys0pll_a20",
977 "sys1pll_a17",
978};
979
980static const char * const nocr_clk_parents[] = {
981 "xin",
982 "xinw",
983 "sys2pll_a20",
984 "sys1pll_a20",
985 "sys1pll_a19",
986 "sys1pll_a18",
987 "sys0pll_a20",
988 "sys1pll_a17",
989};
990
991static const char * const tpiu_clk_parents[] = {
992 "xin",
993 "xinw",
994 "sys2pll_a20",
995 "sys1pll_a20",
996 "sys1pll_a19",
997 "sys1pll_a18",
998 "sys0pll_a20",
999 "sys1pll_a17",
1000};
1001
1002static struct atlas7_mux_init_data mux_list[] __initdata = {
1003 /* mux_name, parent_names, parent_num, flags, mux_flags, mux_offset, shift, width */
1004 { "i2s_mux", i2s_clk_parents, ARRAY_SIZE(i2s_clk_parents), 0, 0, SIRFSOC_CLKC_I2S_CLK_SEL, 0, 2 },
1005 { "usbphy_mux", usbphy_clk_parents, ARRAY_SIZE(usbphy_clk_parents), 0, 0, SIRFSOC_CLKC_I2S_CLK_SEL, 0, 3 },
1006 { "btss_mux", btss_clk_parents, ARRAY_SIZE(btss_clk_parents), 0, 0, SIRFSOC_CLKC_BTSS_CLK_SEL, 0, 3 },
1007 { "rgmii_mux", rgmii_clk_parents, ARRAY_SIZE(rgmii_clk_parents), 0, 0, SIRFSOC_CLKC_RGMII_CLK_SEL, 0, 3 },
1008 { "cpu_mux", cpu_clk_parents, ARRAY_SIZE(cpu_clk_parents), 0, 0, SIRFSOC_CLKC_CPU_CLK_SEL, 0, 3 },
1009 { "sdphy01_mux", sdphy01_clk_parents, ARRAY_SIZE(sdphy01_clk_parents), 0, 0, SIRFSOC_CLKC_SDPHY01_CLK_SEL, 0, 3 },
1010 { "sdphy23_mux", sdphy23_clk_parents, ARRAY_SIZE(sdphy23_clk_parents), 0, 0, SIRFSOC_CLKC_SDPHY23_CLK_SEL, 0, 3 },
1011 { "sdphy45_mux", sdphy45_clk_parents, ARRAY_SIZE(sdphy45_clk_parents), 0, 0, SIRFSOC_CLKC_SDPHY45_CLK_SEL, 0, 3 },
1012 { "sdphy67_mux", sdphy67_clk_parents, ARRAY_SIZE(sdphy67_clk_parents), 0, 0, SIRFSOC_CLKC_SDPHY67_CLK_SEL, 0, 3 },
1013 { "can_mux", can_clk_parents, ARRAY_SIZE(can_clk_parents), 0, 0, SIRFSOC_CLKC_CAN_CLK_SEL, 0, 3 },
1014 { "deint_mux", deint_clk_parents, ARRAY_SIZE(deint_clk_parents), 0, 0, SIRFSOC_CLKC_DEINT_CLK_SEL, 0, 3 },
1015 { "nand_mux", nand_clk_parents, ARRAY_SIZE(nand_clk_parents), 0, 0, SIRFSOC_CLKC_NAND_CLK_SEL, 0, 3 },
1016 { "disp0_mux", disp0_clk_parents, ARRAY_SIZE(disp0_clk_parents), 0, 0, SIRFSOC_CLKC_DISP0_CLK_SEL, 0, 3 },
1017 { "disp1_mux", disp1_clk_parents, ARRAY_SIZE(disp1_clk_parents), 0, 0, SIRFSOC_CLKC_DISP1_CLK_SEL, 0, 3 },
1018 { "gpu_mux", gpu_clk_parents, ARRAY_SIZE(gpu_clk_parents), 0, 0, SIRFSOC_CLKC_GPU_CLK_SEL, 0, 3 },
1019 { "gnss_mux", gnss_clk_parents, ARRAY_SIZE(gnss_clk_parents), 0, 0, SIRFSOC_CLKC_GNSS_CLK_SEL, 0, 3 },
1020 { "sys_mux", sys_clk_parents, ARRAY_SIZE(sys_clk_parents), 0, 0, SIRFSOC_CLKC_SYS_CLK_SEL, 0, 3 },
1021 { "io_mux", io_clk_parents, ARRAY_SIZE(io_clk_parents), 0, 0, SIRFSOC_CLKC_IO_CLK_SEL, 0, 3 },
1022 { "g2d_mux", g2d_clk_parents, ARRAY_SIZE(g2d_clk_parents), 0, 0, SIRFSOC_CLKC_G2D_CLK_SEL, 0, 3 },
1023 { "jpenc_mux", jpenc_clk_parents, ARRAY_SIZE(jpenc_clk_parents), 0, 0, SIRFSOC_CLKC_JPENC_CLK_SEL, 0, 3 },
1024 { "vdec_mux", vdec_clk_parents, ARRAY_SIZE(vdec_clk_parents), 0, 0, SIRFSOC_CLKC_VDEC_CLK_SEL, 0, 3 },
1025 { "gmac_mux", gmac_clk_parents, ARRAY_SIZE(gmac_clk_parents), 0, 0, SIRFSOC_CLKC_GMAC_CLK_SEL, 0, 3 },
1026 { "usb_mux", usb_clk_parents, ARRAY_SIZE(usb_clk_parents), 0, 0, SIRFSOC_CLKC_USB_CLK_SEL, 0, 3 },
1027 { "kas_mux", kas_clk_parents, ARRAY_SIZE(kas_clk_parents), 0, 0, SIRFSOC_CLKC_KAS_CLK_SEL, 0, 3 },
1028 { "sec_mux", sec_clk_parents, ARRAY_SIZE(sec_clk_parents), 0, 0, SIRFSOC_CLKC_SEC_CLK_SEL, 0, 3 },
1029 { "sdr_mux", sdr_clk_parents, ARRAY_SIZE(sdr_clk_parents), 0, 0, SIRFSOC_CLKC_SDR_CLK_SEL, 0, 3 },
1030 { "vip_mux", vip_clk_parents, ARRAY_SIZE(vip_clk_parents), 0, 0, SIRFSOC_CLKC_VIP_CLK_SEL, 0, 3 },
1031 { "nocd_mux", nocd_clk_parents, ARRAY_SIZE(nocd_clk_parents), 0, 0, SIRFSOC_CLKC_NOCD_CLK_SEL, 0, 3 },
1032 { "nocr_mux", nocr_clk_parents, ARRAY_SIZE(nocr_clk_parents), 0, 0, SIRFSOC_CLKC_NOCR_CLK_SEL, 0, 3 },
1033 { "tpiu_mux", tpiu_clk_parents, ARRAY_SIZE(tpiu_clk_parents), 0, 0, SIRFSOC_CLKC_TPIU_CLK_SEL, 0, 3 },
1034};
1035
1036 /* new unit should add start from the tail of list */
1037static struct atlas7_unit_init_data unit_list[] __initdata = {
1038 /* unit_name, parent_name, flags, regofs, bit, lock */
1039 { 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, &root0_gate_lock },
1040 { 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, &root0_gate_lock },
1041 { 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, &root0_gate_lock },
1042 { 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, &root0_gate_lock },
1043 { 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, &root0_gate_lock },
1044 { 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, &root0_gate_lock },
1045 { 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, &root0_gate_lock },
1046 { 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, &root0_gate_lock },
1047 { 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, &root0_gate_lock },
1048 { 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, &root0_gate_lock },
1049 { 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, &root0_gate_lock },
1050 { 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, &root0_gate_lock },
1051 { 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, &root0_gate_lock },
1052 { 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, &root0_gate_lock },
1053 { 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, &root0_gate_lock },
1054 { 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, &root0_gate_lock },
1055 { 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, &root0_gate_lock },
1056 { 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, &root0_gate_lock },
1057 { 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, &root0_gate_lock },
1058 { 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, &root0_gate_lock },
1059 { 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, &root0_gate_lock },
1060 { 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, &root0_gate_lock },
1061 { 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, &root0_gate_lock },
1062 { 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, &root1_gate_lock },
1063 { 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, &root1_gate_lock },
1064 { 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, &root1_gate_lock },
1065 { 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, &root1_gate_lock },
1066 { 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, &root1_gate_lock },
1067 { 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, &root1_gate_lock },
1068 { 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, &root1_gate_lock },
1069 { 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, &root1_gate_lock },
1070 { 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, &root1_gate_lock },
1071 { 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, &root1_gate_lock },
1072 { 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, &root1_gate_lock },
1073 { 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, &root1_gate_lock },
1074 { 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, &root1_gate_lock },
1075 { 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, &root1_gate_lock },
1076 { 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, &root1_gate_lock },
1077 { 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, &root1_gate_lock },
1078 { 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, &root1_gate_lock },
1079 { 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, &root1_gate_lock },
1080 { 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, &root1_gate_lock },
1081 { 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, &root1_gate_lock },
1082 { 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, &root1_gate_lock },
1083 { 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, &root1_gate_lock },
1084 { 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, &root1_gate_lock },
1085 { 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, &leaf1_gate_lock },
1086 { 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, &leaf1_gate_lock },
1087 { 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, &leaf1_gate_lock },
1088 { 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, &leaf1_gate_lock },
1089 { 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, &leaf1_gate_lock },
1090 { 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, &leaf1_gate_lock },
1091 { 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, &leaf1_gate_lock },
1092 { 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, &leaf1_gate_lock },
1093 { 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, &leaf1_gate_lock },
1094 { 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, &leaf1_gate_lock },
1095 { 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, &leaf1_gate_lock },
1096 { 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, &leaf1_gate_lock },
1097 { 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, &leaf1_gate_lock },
1098 { 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, &leaf1_gate_lock },
1099 { 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, &leaf1_gate_lock },
1100 { 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, &leaf1_gate_lock },
1101 { 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, &leaf1_gate_lock },
1102 { 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, &leaf1_gate_lock },
1103 { 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, &leaf1_gate_lock },
1104 { 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, &leaf1_gate_lock },
1105 { 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, &leaf2_gate_lock },
1106 { 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, &leaf2_gate_lock },
1107 { 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, &leaf2_gate_lock },
1108 { 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, &leaf2_gate_lock },
1109 { 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, &leaf2_gate_lock },
1110 { 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, &leaf2_gate_lock },
1111 { 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, &leaf2_gate_lock },
1112 { 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, &leaf2_gate_lock },
1113 { 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, &leaf2_gate_lock },
1114 { 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, &leaf2_gate_lock },
1115 { 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, &leaf2_gate_lock },
1116 { 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, &leaf2_gate_lock },
1117 { 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, &leaf2_gate_lock },
1118 { 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, &leaf2_gate_lock },
1119 { 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, &leaf2_gate_lock },
1120 { 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, &leaf2_gate_lock },
1121 { 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15, &leaf2_gate_lock },
1122 { 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, &leaf2_gate_lock },
1123 { 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, &leaf2_gate_lock },
1124 { 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, &leaf2_gate_lock },
1125 { 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, &leaf3_gate_lock },
1126 { 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, &leaf3_gate_lock },
1127 { 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, &leaf3_gate_lock },
1128 { 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, &leaf3_gate_lock },
1129 { 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, &leaf3_gate_lock },
1130 { 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, &leaf3_gate_lock },
1131 { 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, &leaf3_gate_lock },
1132 { 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, &leaf3_gate_lock },
1133 { 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, &leaf3_gate_lock },
1134 { 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, &leaf3_gate_lock },
1135 { 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, &leaf3_gate_lock },
1136 { 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, &leaf3_gate_lock },
1137 { 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, &leaf3_gate_lock },
1138 { 99, "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, &leaf3_gate_lock },
1139 { 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, &leaf3_gate_lock },
1140 { 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, &leaf3_gate_lock },
1141 { 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, &leaf4_gate_lock },
1142 { 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, &leaf4_gate_lock },
1143 { 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, &leaf4_gate_lock },
1144 { 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, &leaf4_gate_lock },
1145 { 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, &leaf4_gate_lock },
1146 { 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, &leaf4_gate_lock },
1147 { 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, &leaf4_gate_lock },
1148 { 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, &leaf4_gate_lock },
1149 { 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, &leaf4_gate_lock },
1150 { 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, &leaf4_gate_lock },
1151 { 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, &leaf4_gate_lock },
1152 { 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, &leaf4_gate_lock },
1153 { 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12, &leaf4_gate_lock },
1154 { 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, &leaf4_gate_lock },
1155 { 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, &leaf4_gate_lock },
1156 { 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, &leaf4_gate_lock },
1157 { 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, &leaf5_gate_lock },
1158 { 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, &leaf5_gate_lock },
1159 { 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, &leaf5_gate_lock },
1160 { 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, &leaf5_gate_lock },
1161 { 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, &leaf6_gate_lock },
1162 { 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, &leaf6_gate_lock },
1163 { 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, &leaf6_gate_lock },
1164 { 125, "thcpum_cpudiv4", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, &leaf6_gate_lock },
1165 { 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, &leaf7_gate_lock },
1166 { 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, &leaf7_gate_lock },
1167 { 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, &leaf7_gate_lock },
1168 { 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, &leaf8_gate_lock },
1169 { 130, "dmac4_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, &leaf8_gate_lock },
1170 { 131, "uart6_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, &leaf8_gate_lock },
1171 { 132, "usp3_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, &leaf8_gate_lock },
1172 { 133, "a7ca_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, &leaf8_gate_lock },
1173 { 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, &leaf8_gate_lock },
1174 { 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, &leaf8_gate_lock },
1175 { 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, &root1_gate_lock },
1176 { 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, &leaf8_gate_lock },
1177};
1178
1179static struct clk *atlas7_clks[ARRAY_SIZE(unit_list)];
1180
1181static int unit_clk_is_enabled(struct clk_hw *hw)
1182{
1183 struct clk_unit *clk = to_unitclk(hw);
1184 u32 reg;
1185
1186 reg = clk->regofs + SIRFSOC_CLKC_ROOT_CLK_EN0_STAT - SIRFSOC_CLKC_ROOT_CLK_EN0_SET;
1187
1188 return !!(clkc_readl(reg) & BIT(clk->bit));
1189}
1190
1191static int unit_clk_enable(struct clk_hw *hw)
1192{
1193 u32 reg;
1194 struct clk_unit *clk = to_unitclk(hw);
1195 unsigned long flags;
1196
1197 reg = clk->regofs;
1198
1199 spin_lock_irqsave(clk->lock, flags);
1200 clkc_writel(BIT(clk->bit), reg);
1201 spin_unlock_irqrestore(clk->lock, flags);
1202 return 0;
1203}
1204
1205static void unit_clk_disable(struct clk_hw *hw)
1206{
1207 u32 reg;
1208 struct clk_unit *clk = to_unitclk(hw);
1209 unsigned long flags;
1210
1211 reg = clk->regofs + SIRFSOC_CLKC_ROOT_CLK_EN0_CLR - SIRFSOC_CLKC_ROOT_CLK_EN0_SET;
1212
1213 spin_lock_irqsave(clk->lock, flags);
1214 clkc_writel(BIT(clk->bit), reg);
1215 spin_unlock_irqrestore(clk->lock, flags);
1216}
1217
1218static const struct clk_ops unit_clk_ops = {
1219 .is_enabled = unit_clk_is_enabled,
1220 .enable = unit_clk_enable,
1221 .disable = unit_clk_disable,
1222};
1223
1224static struct clk * __init
1225atlas7_unit_clk_register(struct device *dev, const char *name,
1226 const char * const parent_name, unsigned long flags,
1227 u32 regofs, u8 bit, spinlock_t *lock)
1228{
1229 struct clk *clk;
1230 struct clk_unit *unit;
1231 struct clk_init_data init;
1232
1233 unit = kzalloc(sizeof(*unit), GFP_KERNEL);
1234 if (!unit)
1235 return ERR_PTR(-ENOMEM);
1236
1237 init.name = name;
1238 init.parent_names = &parent_name;
1239 init.num_parents = 1;
1240 init.ops = &unit_clk_ops;
1241 init.flags = flags;
1242
1243 unit->hw.init = &init;
1244 unit->regofs = regofs;
1245 unit->bit = bit;
1246 unit->lock = lock;
1247
1248 clk = clk_register(dev, &unit->hw);
1249 if (IS_ERR(clk))
1250 kfree(unit);
1251
1252 return clk;
1253}
1254
1255static struct atlas7_reset_desc atlas7_reset_unit[] = {
1256 { "PWM", 0x0244, 0, 0x0320, 0, &leaf0_gate_lock }, /* 0-5 */
1257 { "THCGUM", 0x0244, 3, 0x0320, 1, &leaf0_gate_lock },
1258 { "CVD", 0x04A0, 0, 0x032C, 0, &leaf1_gate_lock },
1259 { "TIMER", 0x04A0, 1, 0x032C, 1, &leaf1_gate_lock },
1260 { "PULSEC", 0x04A0, 2, 0x032C, 2, &leaf1_gate_lock },
1261 { "TSC", 0x04A0, 3, 0x032C, 3, &leaf1_gate_lock },
1262 { "IOCTOP", 0x04A0, 4, 0x032C, 4, &leaf1_gate_lock }, /* 6-10 */
1263 { "RSC", 0x04A0, 5, 0x032C, 5, &leaf1_gate_lock },
1264 { "DVM", 0x04A0, 6, 0x032C, 6, &leaf1_gate_lock },
1265 { "LVDS", 0x04A0, 7, 0x032C, 7, &leaf1_gate_lock },
1266 { "KAS", 0x04A0, 8, 0x032C, 8, &leaf1_gate_lock },
1267 { "AC97", 0x04A0, 9, 0x032C, 9, &leaf1_gate_lock }, /* 11-15 */
1268 { "USP0", 0x04A0, 10, 0x032C, 10, &leaf1_gate_lock },
1269 { "USP1", 0x04A0, 11, 0x032C, 11, &leaf1_gate_lock },
1270 { "USP2", 0x04A0, 12, 0x032C, 12, &leaf1_gate_lock },
1271 { "DMAC2", 0x04A0, 13, 0x032C, 13, &leaf1_gate_lock },
1272 { "DMAC3", 0x04A0, 14, 0x032C, 14, &leaf1_gate_lock }, /* 16-20 */
1273 { "AUDIO", 0x04A0, 15, 0x032C, 15, &leaf1_gate_lock },
1274 { "I2S1", 0x04A0, 17, 0x032C, 16, &leaf1_gate_lock },
1275 { "PMU_AUDIO", 0x04A0, 22, 0x032C, 17, &leaf1_gate_lock },
1276 { "THAUDMSCM", 0x04A0, 23, 0x032C, 18, &leaf1_gate_lock },
1277 { "SYS2PCI", 0x04B8, 0, 0x0338, 0, &leaf2_gate_lock }, /* 21-25 */
1278 { "PCIARB", 0x04B8, 1, 0x0338, 1, &leaf2_gate_lock },
1279 { "PCICOPY", 0x04B8, 2, 0x0338, 2, &leaf2_gate_lock },
1280 { "ROM", 0x04B8, 3, 0x0338, 3, &leaf2_gate_lock },
1281 { "SDIO23", 0x04B8, 4, 0x0338, 4, &leaf2_gate_lock },
1282 { "SDIO45", 0x04B8, 5, 0x0338, 5, &leaf2_gate_lock }, /* 26-30 */
1283 { "SDIO67", 0x04B8, 6, 0x0338, 6, &leaf2_gate_lock },
1284 { "VIP1", 0x04B8, 7, 0x0338, 7, &leaf2_gate_lock },
1285 { "VPP0", 0x04B8, 11, 0x0338, 8, &leaf2_gate_lock },
1286 { "LCD0", 0x04B8, 12, 0x0338, 9, &leaf2_gate_lock },
1287 { "VPP1", 0x04B8, 13, 0x0338, 10, &leaf2_gate_lock }, /* 31-35 */
1288 { "LCD1", 0x04B8, 14, 0x0338, 11, &leaf2_gate_lock },
1289 { "DCU", 0x04B8, 15, 0x0338, 12, &leaf2_gate_lock },
1290 { "GPIO", 0x04B8, 18, 0x0338, 13, &leaf2_gate_lock },
1291 { "DAPA_VDIFM", 0x04B8, 17, 0x0338, 15, &leaf2_gate_lock },
1292 { "THVDIFM", 0x04B8, 19, 0x0338, 16, &leaf2_gate_lock }, /* 36-40 */
1293 { "RGMII", 0x04D0, 0, 0x0344, 0, &leaf3_gate_lock },
1294 { "GMAC", 0x04D0, 1, 0x0344, 1, &leaf3_gate_lock },
1295 { "UART1", 0x04D0, 2, 0x0344, 2, &leaf3_gate_lock },
1296 { "DMAC0", 0x04D0, 3, 0x0344, 3, &leaf3_gate_lock },
1297 { "UART0", 0x04D0, 4, 0x0344, 4, &leaf3_gate_lock }, /* 41-45 */
1298 { "UART2", 0x04D0, 5, 0x0344, 5, &leaf3_gate_lock },
1299 { "UART3", 0x04D0, 6, 0x0344, 6, &leaf3_gate_lock },
1300 { "UART4", 0x04D0, 7, 0x0344, 7, &leaf3_gate_lock },
1301 { "UART5", 0x04D0, 8, 0x0344, 8, &leaf3_gate_lock },
1302 { "SPI1", 0x04D0, 9, 0x0344, 9, &leaf3_gate_lock }, /* 46-50 */
1303 { "GNSS_SYS_M0", 0x04D0, 10, 0x0344, 10, &leaf3_gate_lock },
1304 { "CANBUS1", 0x04D0, 12, 0x0344, 11, &leaf3_gate_lock },
1305 { "CCSEC", 0x04D0, 15, 0x0344, 12, &leaf3_gate_lock },
1306 { "CCPUB", 0x04D0, 16, 0x0344, 13, &leaf3_gate_lock },
1307 { "DAPA_GNSSM", 0x04D0, 13, 0x0344, 14, &leaf3_gate_lock }, /* 51-55 */
1308 { "THGNSSM", 0x04D0, 14, 0x0344, 15, &leaf3_gate_lock },
1309 { "VDEC", 0x04E8, 0, 0x0350, 0, &leaf4_gate_lock },
1310 { "JPENC", 0x04E8, 1, 0x0350, 1, &leaf4_gate_lock },
1311 { "G2D", 0x04E8, 2, 0x0350, 2, &leaf4_gate_lock },
1312 { "I2C0", 0x04E8, 3, 0x0350, 3, &leaf4_gate_lock }, /* 56-60 */
1313 { "I2C1", 0x04E8, 4, 0x0350, 4, &leaf4_gate_lock },
1314 { "GPIO0", 0x04E8, 5, 0x0350, 5, &leaf4_gate_lock },
1315 { "NAND", 0x04E8, 6, 0x0350, 6, &leaf4_gate_lock },
1316 { "SDIO01", 0x04E8, 7, 0x0350, 7, &leaf4_gate_lock },
1317 { "SYS2PCI2", 0x04E8, 8, 0x0350, 8, &leaf4_gate_lock }, /* 61-65 */
1318 { "USB0", 0x04E8, 11, 0x0350, 9, &leaf4_gate_lock },
1319 { "USB1", 0x04E8, 12, 0x0350, 10, &leaf4_gate_lock },
1320 { "THMEDIAM", 0x04E8, 15, 0x0350, 11, &leaf4_gate_lock },
1321 { "MEMC_DDRPHY", 0x0500, 0, 0x035C, 0, &leaf5_gate_lock },
1322 { "MEMC_UPCTL", 0x0500, 0, 0x035C, 1, &leaf5_gate_lock }, /* 66-70 */
1323 { "DAPA_MEM", 0x0500, 1, 0x035C, 2, &leaf5_gate_lock },
1324 { "MEMC_MEMDIV", 0x0500, 0, 0x035C, 3, &leaf5_gate_lock },
1325 { "THDDRM", 0x0500, 3, 0x035C, 4, &leaf5_gate_lock },
1326 { "CORESIGHT", 0x0518, 3, 0x0368, 13, &leaf6_gate_lock },
1327 { "THCPUM", 0x0518, 4, 0x0368, 17, &leaf6_gate_lock }, /* 71-75 */
1328 { "GRAPHIC", 0x0530, 0, 0x0374, 0, &leaf7_gate_lock },
1329 { "VSS_SDR", 0x0530, 1, 0x0374, 1, &leaf7_gate_lock },
1330 { "THGPUM", 0x0530, 2, 0x0374, 2, &leaf7_gate_lock },
1331 { "DMAC4", 0x0548, 2, 0x0380, 1, &leaf8_gate_lock },
1332 { "UART6", 0x0548, 3, 0x0380, 2, &leaf8_gate_lock }, /* 76- */
1333 { "USP3", 0x0548, 4, 0x0380, 3, &leaf8_gate_lock },
1334 { "THBTM", 0x0548, 5, 0x0380, 5, &leaf8_gate_lock },
1335 { "A7CA", 0x0548, 1, 0x0380, 0, &leaf8_gate_lock },
1336 { "A7CA_APB", 0x0548, 5, 0x0380, 4, &leaf8_gate_lock },
1337};
1338
1339static int atlas7_reset_module(struct reset_controller_dev *rcdev,
1340 unsigned long reset_idx)
1341{
1342 struct atlas7_reset_desc *reset = &atlas7_reset_unit[reset_idx];
1343 unsigned long flags;
1344
1345 /*
1346 * HW suggest unit reset sequence:
1347 * assert sw reset (0)
1348 * setting sw clk_en to if the clock was disabled before reset
1349 * delay 16 clocks
1350 * disable clock (sw clk_en = 0)
1351 * de-assert reset (1)
1352 * after this sequence, restore clock or not is decided by SW
1353 */
1354
1355 spin_lock_irqsave(reset->lock, flags);
1356 /* clock enable or not */
1357 if (clkc_readl(reset->clk_ofs + 8) & (1 << reset->clk_bit)) {
1358 clkc_writel(1 << reset->rst_bit, reset->rst_ofs + 4);
1359 udelay(2);
1360 clkc_writel(1 << reset->clk_bit, reset->clk_ofs + 4);
1361 clkc_writel(1 << reset->rst_bit, reset->rst_ofs);
1362 /* restore clock enable */
1363 clkc_writel(1 << reset->clk_bit, reset->clk_ofs);
1364 } else {
1365 clkc_writel(1 << reset->rst_bit, reset->rst_ofs + 4);
1366 clkc_writel(1 << reset->clk_bit, reset->clk_ofs);
1367 udelay(2);
1368 clkc_writel(1 << reset->clk_bit, reset->clk_ofs + 4);
1369 clkc_writel(1 << reset->rst_bit, reset->rst_ofs);
1370 }
1371 spin_unlock_irqrestore(reset->lock, flags);
1372
1373 return 0;
1374}
1375
1376static struct reset_control_ops atlas7_rst_ops = {
1377 .reset = atlas7_reset_module,
1378};
1379
1380static struct reset_controller_dev atlas7_rst_ctlr = {
1381 .ops = &atlas7_rst_ops,
1382 .owner = THIS_MODULE,
1383 .of_reset_n_cells = 1,
1384};
1385
1386static void __init atlas7_clk_init(struct device_node *np)
1387{
1388 struct clk *clk;
1389 struct atlas7_div_init_data *div;
1390 struct atlas7_mux_init_data *mux;
1391 struct atlas7_unit_init_data *unit;
1392 int i;
1393 int ret;
1394
1395 sirfsoc_clk_vbase = of_iomap(np, 0);
1396 if (!sirfsoc_clk_vbase)
1397 panic("unable to map clkc registers\n");
1398
1399 of_node_put(np);
1400
1401 clk = clk_register(NULL, &clk_cpupll.hw);
1402 BUG_ON(!clk);
1403 clk = clk_register(NULL, &clk_mempll.hw);
1404 BUG_ON(!clk);
1405 clk = clk_register(NULL, &clk_sys0pll.hw);
1406 BUG_ON(!clk);
1407 clk = clk_register(NULL, &clk_sys1pll.hw);
1408 BUG_ON(!clk);
1409 clk = clk_register(NULL, &clk_sys2pll.hw);
1410 BUG_ON(!clk);
1411 clk = clk_register(NULL, &clk_sys3pll.hw);
1412 BUG_ON(!clk);
1413
1414 clk = clk_register_divider_table(NULL, "cpupll_div1", "cpupll_vco", 0,
1415 sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1, 0, 3, 0,
1416 pll_div_table, &cpupll_ctrl1_lock);
1417 BUG_ON(!clk);
1418 clk = clk_register_divider_table(NULL, "cpupll_div2", "cpupll_vco", 0,
1419 sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1, 4, 3, 0,
1420 pll_div_table, &cpupll_ctrl1_lock);
1421 BUG_ON(!clk);
1422 clk = clk_register_divider_table(NULL, "cpupll_div3", "cpupll_vco", 0,
1423 sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1, 8, 3, 0,
1424 pll_div_table, &cpupll_ctrl1_lock);
1425 BUG_ON(!clk);
1426
1427 clk = clk_register_divider_table(NULL, "mempll_div1", "mempll_vco", 0,
1428 sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1, 0, 3, 0,
1429 pll_div_table, &mempll_ctrl1_lock);
1430 BUG_ON(!clk);
1431 clk = clk_register_divider_table(NULL, "mempll_div2", "mempll_vco", 0,
1432 sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1, 4, 3, 0,
1433 pll_div_table, &mempll_ctrl1_lock);
1434 BUG_ON(!clk);
1435 clk = clk_register_divider_table(NULL, "mempll_div3", "mempll_vco", 0,
1436 sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1, 8, 3, 0,
1437 pll_div_table, &mempll_ctrl1_lock);
1438 BUG_ON(!clk);
1439
1440 clk = clk_register_divider_table(NULL, "sys0pll_div1", "sys0pll_vco", 0,
1441 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1, 0, 3, 0,
1442 pll_div_table, &sys0pll_ctrl1_lock);
1443 BUG_ON(!clk);
1444 clk = clk_register_divider_table(NULL, "sys0pll_div2", "sys0pll_vco", 0,
1445 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1, 4, 3, 0,
1446 pll_div_table, &sys0pll_ctrl1_lock);
1447 BUG_ON(!clk);
1448 clk = clk_register_divider_table(NULL, "sys0pll_div3", "sys0pll_vco", 0,
1449 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1, 8, 3, 0,
1450 pll_div_table, &sys0pll_ctrl1_lock);
1451 BUG_ON(!clk);
1452 clk = clk_register_fixed_factor(NULL, "sys0pll_fixdiv", "sys0pll_vco",
1453 CLK_SET_RATE_PARENT, 1, 2);
1454
1455 clk = clk_register_divider_table(NULL, "sys1pll_div1", "sys1pll_vco", 0,
1456 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1, 0, 3, 0,
1457 pll_div_table, &sys1pll_ctrl1_lock);
1458 BUG_ON(!clk);
1459 clk = clk_register_divider_table(NULL, "sys1pll_div2", "sys1pll_vco", 0,
1460 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1, 4, 3, 0,
1461 pll_div_table, &sys1pll_ctrl1_lock);
1462 BUG_ON(!clk);
1463 clk = clk_register_divider_table(NULL, "sys1pll_div3", "sys1pll_vco", 0,
1464 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1, 8, 3, 0,
1465 pll_div_table, &sys1pll_ctrl1_lock);
1466 BUG_ON(!clk);
1467 clk = clk_register_fixed_factor(NULL, "sys1pll_fixdiv", "sys1pll_vco",
1468 CLK_SET_RATE_PARENT, 1, 2);
1469
1470 clk = clk_register_divider_table(NULL, "sys2pll_div1", "sys2pll_vco", 0,
1471 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1, 0, 3, 0,
1472 pll_div_table, &sys2pll_ctrl1_lock);
1473 BUG_ON(!clk);
1474 clk = clk_register_divider_table(NULL, "sys2pll_div2", "sys2pll_vco", 0,
1475 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1, 4, 3, 0,
1476 pll_div_table, &sys2pll_ctrl1_lock);
1477 BUG_ON(!clk);
1478 clk = clk_register_divider_table(NULL, "sys2pll_div3", "sys2pll_vco", 0,
1479 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1, 8, 3, 0,
1480 pll_div_table, &sys2pll_ctrl1_lock);
1481 BUG_ON(!clk);
1482 clk = clk_register_fixed_factor(NULL, "sys2pll_fixdiv", "sys2pll_vco",
1483 CLK_SET_RATE_PARENT, 1, 2);
1484
1485 clk = clk_register_divider_table(NULL, "sys3pll_div1", "sys3pll_vco", 0,
1486 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1, 0, 3, 0,
1487 pll_div_table, &sys3pll_ctrl1_lock);
1488 BUG_ON(!clk);
1489 clk = clk_register_divider_table(NULL, "sys3pll_div2", "sys3pll_vco", 0,
1490 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1, 4, 3, 0,
1491 pll_div_table, &sys3pll_ctrl1_lock);
1492 BUG_ON(!clk);
1493 clk = clk_register_divider_table(NULL, "sys3pll_div3", "sys3pll_vco", 0,
1494 sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1, 8, 3, 0,
1495 pll_div_table, &sys3pll_ctrl1_lock);
1496 BUG_ON(!clk);
1497 clk = clk_register_fixed_factor(NULL, "sys3pll_fixdiv", "sys3pll_vco",
1498 CLK_SET_RATE_PARENT, 1, 2);
1499
1500 BUG_ON(!clk);
1501 clk = clk_register_fixed_factor(NULL, "xinw_fixdiv_btslow", "xinw",
1502 CLK_SET_RATE_PARENT, 1, 4);
1503
1504 BUG_ON(!clk);
1505 clk = clk_register_gate(NULL, "cpupll_clk1", "cpupll_div1",
1506 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1,
1507 12, 0, &cpupll_ctrl1_lock);
1508 BUG_ON(!clk);
1509 clk = clk_register_gate(NULL, "cpupll_clk2", "cpupll_div2",
1510 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1,
1511 13, 0, &cpupll_ctrl1_lock);
1512 BUG_ON(!clk);
1513 clk = clk_register_gate(NULL, "cpupll_clk3", "cpupll_div3",
1514 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_CPUPLL_AB_CTRL1,
1515 14, 0, &cpupll_ctrl1_lock);
1516 BUG_ON(!clk);
1517
1518 clk = clk_register_gate(NULL, "mempll_clk1", "mempll_div1",
1519 CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
1520 sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1,
1521 12, 0, &mempll_ctrl1_lock);
1522 BUG_ON(!clk);
1523 clk = clk_register_gate(NULL, "mempll_clk2", "mempll_div2",
1524 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1,
1525 13, 0, &mempll_ctrl1_lock);
1526 BUG_ON(!clk);
1527 clk = clk_register_gate(NULL, "mempll_clk3", "mempll_div3",
1528 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_MEMPLL_AB_CTRL1,
1529 14, 0, &mempll_ctrl1_lock);
1530 BUG_ON(!clk);
1531
1532 clk = clk_register_gate(NULL, "sys0pll_clk1", "sys0pll_div1",
1533 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1,
1534 12, 0, &sys0pll_ctrl1_lock);
1535 BUG_ON(!clk);
1536 clk = clk_register_gate(NULL, "sys0pll_clk2", "sys0pll_div2",
1537 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1,
1538 13, 0, &sys0pll_ctrl1_lock);
1539 BUG_ON(!clk);
1540 clk = clk_register_gate(NULL, "sys0pll_clk3", "sys0pll_div3",
1541 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS0PLL_AB_CTRL1,
1542 14, 0, &sys0pll_ctrl1_lock);
1543 BUG_ON(!clk);
1544
1545 clk = clk_register_gate(NULL, "sys1pll_clk1", "sys1pll_div1",
1546 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1,
1547 12, 0, &sys1pll_ctrl1_lock);
1548 BUG_ON(!clk);
1549 clk = clk_register_gate(NULL, "sys1pll_clk2", "sys1pll_div2",
1550 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1,
1551 13, 0, &sys1pll_ctrl1_lock);
1552 BUG_ON(!clk);
1553 clk = clk_register_gate(NULL, "sys1pll_clk3", "sys1pll_div3",
1554 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS1PLL_AB_CTRL1,
1555 14, 0, &sys1pll_ctrl1_lock);
1556 BUG_ON(!clk);
1557
1558 clk = clk_register_gate(NULL, "sys2pll_clk1", "sys2pll_div1",
1559 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1,
1560 12, 0, &sys2pll_ctrl1_lock);
1561 BUG_ON(!clk);
1562 clk = clk_register_gate(NULL, "sys2pll_clk2", "sys2pll_div2",
1563 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1,
1564 13, 0, &sys2pll_ctrl1_lock);
1565 BUG_ON(!clk);
1566 clk = clk_register_gate(NULL, "sys2pll_clk3", "sys2pll_div3",
1567 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS2PLL_AB_CTRL1,
1568 14, 0, &sys2pll_ctrl1_lock);
1569 BUG_ON(!clk);
1570
1571 clk = clk_register_gate(NULL, "sys3pll_clk1", "sys3pll_div1",
1572 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1,
1573 12, 0, &sys3pll_ctrl1_lock);
1574 BUG_ON(!clk);
1575 clk = clk_register_gate(NULL, "sys3pll_clk2", "sys3pll_div2",
1576 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1,
1577 13, 0, &sys3pll_ctrl1_lock);
1578 BUG_ON(!clk);
1579 clk = clk_register_gate(NULL, "sys3pll_clk3", "sys3pll_div3",
1580 CLK_SET_RATE_PARENT, sirfsoc_clk_vbase + SIRFSOC_CLKC_SYS3PLL_AB_CTRL1,
1581 14, 0, &sys3pll_ctrl1_lock);
1582 BUG_ON(!clk);
1583
1584 clk = clk_register(NULL, &clk_audio_dto.hw);
1585 BUG_ON(!clk);
1586
1587 clk = clk_register(NULL, &clk_disp0_dto.hw);
1588 BUG_ON(!clk);
1589
1590 clk = clk_register(NULL, &clk_disp1_dto.hw);
1591 BUG_ON(!clk);
1592
1593 for (i = 0; i < ARRAY_SIZE(divider_list); i++) {
1594 div = &divider_list[i];
1595 clk = clk_register_divider(NULL, div->div_name,
1596 div->parent_name, div->divider_flags, sirfsoc_clk_vbase + div->div_offset,
1597 div->shift, div->width, 0, div->lock);
1598 BUG_ON(!clk);
1599 clk = clk_register_gate(NULL, div->gate_name, div->div_name,
1600 div->gate_flags, sirfsoc_clk_vbase + div->gate_offset,
1601 div->gate_bit, 0, div->lock);
1602 BUG_ON(!clk);
1603 }
1604 /* ignore selector status register check */
1605 for (i = 0; i < ARRAY_SIZE(mux_list); i++) {
1606 mux = &mux_list[i];
1607 clk = clk_register_mux(NULL, mux->mux_name, mux->parent_names,
1608 mux->parent_num, mux->flags,
1609 sirfsoc_clk_vbase + mux->mux_offset,
1610 mux->shift, mux->width,
1611 mux->mux_flags, NULL);
1612 BUG_ON(!clk);
1613 }
1614
1615 for (i = 0; i < ARRAY_SIZE(unit_list); i++) {
1616 unit = &unit_list[i];
1617 atlas7_clks[i] = atlas7_unit_clk_register(NULL, unit->unit_name, unit->parent_name,
1618 unit->flags, unit->regofs, unit->bit, unit->lock);
1619 BUG_ON(!atlas7_clks[i]);
1620 }
1621
1622 clk_data.clks = atlas7_clks;
1623 clk_data.clk_num = ARRAY_SIZE(unit_list);
1624
1625 ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1626 BUG_ON(ret);
1627
1628 atlas7_rst_ctlr.of_node = np;
1629 atlas7_rst_ctlr.nr_resets = ARRAY_SIZE(atlas7_reset_unit);
1630 reset_controller_register(&atlas7_rst_ctlr);
1631}
1632CLK_OF_DECLARE(atlas7_clk, "sirf,atlas7-car", atlas7_clk_init);
diff --git a/drivers/clk/sirf/clk-common.c b/drivers/clk/sirf/clk-common.c
index 37af51c5f213..9fc285d784d3 100644
--- a/drivers/clk/sirf/clk-common.c
+++ b/drivers/clk/sirf/clk-common.c
@@ -10,8 +10,8 @@
10#define KHZ 1000 10#define KHZ 1000
11#define MHZ (KHZ * KHZ) 11#define MHZ (KHZ * KHZ)
12 12
13static void *sirfsoc_clk_vbase; 13static void __iomem *sirfsoc_clk_vbase;
14static void *sirfsoc_rsc_vbase; 14static void __iomem *sirfsoc_rsc_vbase;
15static struct clk_onecell_data clk_data; 15static struct clk_onecell_data clk_data;
16 16
17/* 17/*
@@ -188,7 +188,7 @@ static struct clk_ops std_pll_ops = {
188 .set_rate = pll_clk_set_rate, 188 .set_rate = pll_clk_set_rate,
189}; 189};
190 190
191static const char *pll_clk_parents[] = { 191static const char * const pll_clk_parents[] = {
192 "osc", 192 "osc",
193}; 193};
194 194
@@ -284,7 +284,7 @@ static struct clk_hw usb_pll_clk_hw = {
284 * clock domains - cpu, mem, sys/io, dsp, gfx 284 * clock domains - cpu, mem, sys/io, dsp, gfx
285 */ 285 */
286 286
287static const char *dmn_clk_parents[] = { 287static const char * const dmn_clk_parents[] = {
288 "rtc", 288 "rtc",
289 "osc", 289 "osc",
290 "pll1", 290 "pll1",
@@ -673,7 +673,7 @@ static void std_clk_disable(struct clk_hw *hw)
673 clkc_writel(val, reg); 673 clkc_writel(val, reg);
674} 674}
675 675
676static const char *std_clk_io_parents[] = { 676static const char * const std_clk_io_parents[] = {
677 "io", 677 "io",
678}; 678};
679 679
@@ -949,7 +949,7 @@ static struct clk_std clk_pulse = {
949 }, 949 },
950}; 950};
951 951
952static const char *std_clk_dsp_parents[] = { 952static const char * const std_clk_dsp_parents[] = {
953 "dsp", 953 "dsp",
954}; 954};
955 955
@@ -981,7 +981,7 @@ static struct clk_std clk_mf = {
981 }, 981 },
982}; 982};
983 983
984static const char *std_clk_sys_parents[] = { 984static const char * const std_clk_sys_parents[] = {
985 "sys", 985 "sys",
986}; 986};
987 987
@@ -999,7 +999,7 @@ static struct clk_std clk_security = {
999 }, 999 },
1000}; 1000};
1001 1001
1002static const char *std_clk_usb_parents[] = { 1002static const char * const std_clk_usb_parents[] = {
1003 "usb_pll", 1003 "usb_pll",
1004}; 1004};
1005 1005
diff --git a/drivers/clk/socfpga/Makefile b/drivers/clk/socfpga/Makefile
index 7e2d15a0c7b8..d8bb239753a4 100644
--- a/drivers/clk/socfpga/Makefile
+++ b/drivers/clk/socfpga/Makefile
@@ -2,3 +2,4 @@ obj-y += clk.o
2obj-y += clk-gate.o 2obj-y += clk-gate.o
3obj-y += clk-pll.o 3obj-y += clk-pll.o
4obj-y += clk-periph.o 4obj-y += clk-periph.o
5obj-y += clk-pll-a10.o clk-periph-a10.o clk-gate-a10.o
diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c
new file mode 100644
index 000000000000..83c6780ff4b2
--- /dev/null
+++ b/drivers/clk/socfpga/clk-gate-a10.c
@@ -0,0 +1,190 @@
1/*
2 * Copyright (C) 2015 Altera Corporation. All rights reserved
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <linux/clk-provider.h>
17#include <linux/io.h>
18#include <linux/mfd/syscon.h>
19#include <linux/of.h>
20#include <linux/regmap.h>
21
22#include "clk.h"
23
24#define streq(a, b) (strcmp((a), (b)) == 0)
25
26#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw)
27
28/* SDMMC Group for System Manager defines */
29#define SYSMGR_SDMMCGRP_CTRL_OFFSET 0x28
30
31static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hwclk,
32 unsigned long parent_rate)
33{
34 struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
35 u32 div = 1, val;
36
37 if (socfpgaclk->fixed_div)
38 div = socfpgaclk->fixed_div;
39 else if (socfpgaclk->div_reg) {
40 val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
41 val &= div_mask(socfpgaclk->width);
42 div = (1 << val);
43 }
44
45 return parent_rate / div;
46}
47
48static int socfpga_clk_prepare(struct clk_hw *hwclk)
49{
50 struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
51 int i;
52 u32 hs_timing;
53 u32 clk_phase[2];
54
55 if (socfpgaclk->clk_phase[0] || socfpgaclk->clk_phase[1]) {
56 for (i = 0; i < ARRAY_SIZE(clk_phase); i++) {
57 switch (socfpgaclk->clk_phase[i]) {
58 case 0:
59 clk_phase[i] = 0;
60 break;
61 case 45:
62 clk_phase[i] = 1;
63 break;
64 case 90:
65 clk_phase[i] = 2;
66 break;
67 case 135:
68 clk_phase[i] = 3;
69 break;
70 case 180:
71 clk_phase[i] = 4;
72 break;
73 case 225:
74 clk_phase[i] = 5;
75 break;
76 case 270:
77 clk_phase[i] = 6;
78 break;
79 case 315:
80 clk_phase[i] = 7;
81 break;
82 default:
83 clk_phase[i] = 0;
84 break;
85 }
86 }
87
88 hs_timing = SYSMGR_SDMMC_CTRL_SET(clk_phase[0], clk_phase[1]);
89 if (!IS_ERR(socfpgaclk->sys_mgr_base_addr))
90 regmap_write(socfpgaclk->sys_mgr_base_addr,
91 SYSMGR_SDMMCGRP_CTRL_OFFSET, hs_timing);
92 else
93 pr_err("%s: cannot set clk_phase because sys_mgr_base_addr is not available!\n",
94 __func__);
95 }
96 return 0;
97}
98
99static struct clk_ops gateclk_ops = {
100 .prepare = socfpga_clk_prepare,
101 .recalc_rate = socfpga_gate_clk_recalc_rate,
102};
103
104static void __init __socfpga_gate_init(struct device_node *node,
105 const struct clk_ops *ops)
106{
107 u32 clk_gate[2];
108 u32 div_reg[3];
109 u32 clk_phase[2];
110 u32 fixed_div;
111 struct clk *clk;
112 struct socfpga_gate_clk *socfpga_clk;
113 const char *clk_name = node->name;
114 const char *parent_name[SOCFPGA_MAX_PARENTS];
115 struct clk_init_data init;
116 int rc;
117 int i = 0;
118
119 socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
120 if (WARN_ON(!socfpga_clk))
121 return;
122
123 rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
124 if (rc)
125 clk_gate[0] = 0;
126
127 if (clk_gate[0]) {
128 socfpga_clk->hw.reg = clk_mgr_a10_base_addr + clk_gate[0];
129 socfpga_clk->hw.bit_idx = clk_gate[1];
130
131 gateclk_ops.enable = clk_gate_ops.enable;
132 gateclk_ops.disable = clk_gate_ops.disable;
133 }
134
135 rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
136 if (rc)
137 socfpga_clk->fixed_div = 0;
138 else
139 socfpga_clk->fixed_div = fixed_div;
140
141 rc = of_property_read_u32_array(node, "div-reg", div_reg, 3);
142 if (!rc) {
143 socfpga_clk->div_reg = clk_mgr_a10_base_addr + div_reg[0];
144 socfpga_clk->shift = div_reg[1];
145 socfpga_clk->width = div_reg[2];
146 } else {
147 socfpga_clk->div_reg = NULL;
148 }
149
150 rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2);
151 if (!rc) {
152 socfpga_clk->clk_phase[0] = clk_phase[0];
153 socfpga_clk->clk_phase[1] = clk_phase[1];
154
155 socfpga_clk->sys_mgr_base_addr =
156 syscon_regmap_lookup_by_compatible("altr,sys-mgr");
157 if (IS_ERR(socfpga_clk->sys_mgr_base_addr)) {
158 pr_err("%s: failed to find altr,sys-mgr regmap!\n",
159 __func__);
160 return;
161 }
162 }
163
164 of_property_read_string(node, "clock-output-names", &clk_name);
165
166 init.name = clk_name;
167 init.ops = ops;
168 init.flags = 0;
169 while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] =
170 of_clk_get_parent_name(node, i)) != NULL)
171 i++;
172
173 init.parent_names = parent_name;
174 init.num_parents = i;
175 socfpga_clk->hw.hw.init = &init;
176
177 clk = clk_register(NULL, &socfpga_clk->hw.hw);
178 if (WARN_ON(IS_ERR(clk))) {
179 kfree(socfpga_clk);
180 return;
181 }
182 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
183 if (WARN_ON(rc))
184 return;
185}
186
187void __init socfpga_a10_gate_init(struct device_node *node)
188{
189 __socfpga_gate_init(node, &gateclk_ops);
190}
diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
index dd3a78c64795..82449cd76fd7 100644
--- a/drivers/clk/socfpga/clk-gate.c
+++ b/drivers/clk/socfpga/clk-gate.c
@@ -32,14 +32,10 @@
32#define SOCFPGA_MMC_CLK "sdmmc_clk" 32#define SOCFPGA_MMC_CLK "sdmmc_clk"
33#define SOCFPGA_GPIO_DB_CLK_OFFSET 0xA8 33#define SOCFPGA_GPIO_DB_CLK_OFFSET 0xA8
34 34
35#define streq(a, b) (strcmp((a), (b)) == 0)
36
37#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw) 35#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw)
38 36
39/* SDMMC Group for System Manager defines */ 37/* SDMMC Group for System Manager defines */
40#define SYSMGR_SDMMCGRP_CTRL_OFFSET 0x108 38#define SYSMGR_SDMMCGRP_CTRL_OFFSET 0x108
41#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \
42 ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))
43 39
44static u8 socfpga_clk_get_parent(struct clk_hw *hwclk) 40static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
45{ 41{
@@ -194,7 +190,6 @@ static void __init __socfpga_gate_init(struct device_node *node,
194 const char *parent_name[SOCFPGA_MAX_PARENTS]; 190 const char *parent_name[SOCFPGA_MAX_PARENTS];
195 struct clk_init_data init; 191 struct clk_init_data init;
196 int rc; 192 int rc;
197 int i = 0;
198 193
199 socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); 194 socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
200 if (WARN_ON(!socfpga_clk)) 195 if (WARN_ON(!socfpga_clk))
@@ -224,7 +219,7 @@ static void __init __socfpga_gate_init(struct device_node *node,
224 socfpga_clk->shift = div_reg[1]; 219 socfpga_clk->shift = div_reg[1];
225 socfpga_clk->width = div_reg[2]; 220 socfpga_clk->width = div_reg[2];
226 } else { 221 } else {
227 socfpga_clk->div_reg = 0; 222 socfpga_clk->div_reg = NULL;
228 } 223 }
229 224
230 rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2); 225 rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2);
@@ -238,12 +233,9 @@ static void __init __socfpga_gate_init(struct device_node *node,
238 init.name = clk_name; 233 init.name = clk_name;
239 init.ops = ops; 234 init.ops = ops;
240 init.flags = 0; 235 init.flags = 0;
241 while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] =
242 of_clk_get_parent_name(node, i)) != NULL)
243 i++;
244 236
237 init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS);
245 init.parent_names = parent_name; 238 init.parent_names = parent_name;
246 init.num_parents = i;
247 socfpga_clk->hw.hw.init = &init; 239 socfpga_clk->hw.hw.init = &init;
248 240
249 clk = clk_register(NULL, &socfpga_clk->hw.hw); 241 clk = clk_register(NULL, &socfpga_clk->hw.hw);
diff --git a/drivers/clk/socfpga/clk-periph-a10.c b/drivers/clk/socfpga/clk-periph-a10.c
new file mode 100644
index 000000000000..9d0181b5a6a4
--- /dev/null
+++ b/drivers/clk/socfpga/clk-periph-a10.c
@@ -0,0 +1,138 @@
1/*
2 * Copyright (C) 2015 Altera Corporation. All rights reserved
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <linux/clk-provider.h>
17#include <linux/io.h>
18#include <linux/of.h>
19
20#include "clk.h"
21
22#define CLK_MGR_FREE_SHIFT 16
23#define CLK_MGR_FREE_MASK 0x7
24
25#define SOCFPGA_MPU_FREE_CLK "mpu_free_clk"
26#define SOCFPGA_NOC_FREE_CLK "noc_free_clk"
27#define SOCFPGA_SDMMC_FREE_CLK "sdmmc_free_clk"
28#define to_socfpga_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw.hw)
29
30static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk,
31 unsigned long parent_rate)
32{
33 struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk);
34 u32 div;
35
36 if (socfpgaclk->fixed_div) {
37 div = socfpgaclk->fixed_div;
38 } else if (socfpgaclk->div_reg) {
39 div = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
40 div &= div_mask(socfpgaclk->width);
41 div += 1;
42 } else {
43 div = ((readl(socfpgaclk->hw.reg) & 0x7ff) + 1);
44 }
45
46 return parent_rate / div;
47}
48
49static u8 clk_periclk_get_parent(struct clk_hw *hwclk)
50{
51 struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk);
52 u32 clk_src;
53
54 clk_src = readl(socfpgaclk->hw.reg);
55 if (streq(hwclk->init->name, SOCFPGA_MPU_FREE_CLK) ||
56 streq(hwclk->init->name, SOCFPGA_NOC_FREE_CLK) ||
57 streq(hwclk->init->name, SOCFPGA_SDMMC_FREE_CLK))
58 return (clk_src >> CLK_MGR_FREE_SHIFT) &
59 CLK_MGR_FREE_MASK;
60 else
61 return 0;
62}
63
64static const struct clk_ops periclk_ops = {
65 .recalc_rate = clk_periclk_recalc_rate,
66 .get_parent = clk_periclk_get_parent,
67};
68
69static __init void __socfpga_periph_init(struct device_node *node,
70 const struct clk_ops *ops)
71{
72 u32 reg;
73 struct clk *clk;
74 struct socfpga_periph_clk *periph_clk;
75 const char *clk_name = node->name;
76 const char *parent_name;
77 struct clk_init_data init;
78 int rc;
79 u32 fixed_div;
80 u32 div_reg[3];
81
82 of_property_read_u32(node, "reg", &reg);
83
84 periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
85 if (WARN_ON(!periph_clk))
86 return;
87
88 periph_clk->hw.reg = clk_mgr_a10_base_addr + reg;
89
90 rc = of_property_read_u32_array(node, "div-reg", div_reg, 3);
91 if (!rc) {
92 periph_clk->div_reg = clk_mgr_a10_base_addr + div_reg[0];
93 periph_clk->shift = div_reg[1];
94 periph_clk->width = div_reg[2];
95 } else {
96 periph_clk->div_reg = NULL;
97 }
98
99 rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
100 if (rc)
101 periph_clk->fixed_div = 0;
102 else
103 periph_clk->fixed_div = fixed_div;
104
105 of_property_read_string(node, "clock-output-names", &clk_name);
106
107 init.name = clk_name;
108 init.ops = ops;
109 init.flags = 0;
110
111 parent_name = of_clk_get_parent_name(node, 0);
112 init.num_parents = 1;
113 init.parent_names = &parent_name;
114
115 periph_clk->hw.hw.init = &init;
116
117 clk = clk_register(NULL, &periph_clk->hw.hw);
118 if (WARN_ON(IS_ERR(clk))) {
119 kfree(periph_clk);
120 return;
121 }
122 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
123 if (rc < 0) {
124 pr_err("Could not register clock provider for node:%s\n",
125 clk_name);
126 goto err_clk;
127 }
128
129 return;
130
131err_clk:
132 clk_unregister(clk);
133}
134
135void __init socfpga_a10_periph_init(struct device_node *node)
136{
137 __socfpga_periph_init(node, &periclk_ops);
138}
diff --git a/drivers/clk/socfpga/clk-periph.c b/drivers/clk/socfpga/clk-periph.c
index 46531c34ec9b..83aeaa219d14 100644
--- a/drivers/clk/socfpga/clk-periph.c
+++ b/drivers/clk/socfpga/clk-periph.c
@@ -76,7 +76,7 @@ static __init void __socfpga_periph_init(struct device_node *node,
76 periph_clk->shift = div_reg[1]; 76 periph_clk->shift = div_reg[1];
77 periph_clk->width = div_reg[2]; 77 periph_clk->width = div_reg[2];
78 } else { 78 } else {
79 periph_clk->div_reg = 0; 79 periph_clk->div_reg = NULL;
80 } 80 }
81 81
82 rc = of_property_read_u32(node, "fixed-divider", &fixed_div); 82 rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c
new file mode 100644
index 000000000000..1178b11babca
--- /dev/null
+++ b/drivers/clk/socfpga/clk-pll-a10.c
@@ -0,0 +1,129 @@
1/*
2 * Copyright (C) 2015 Altera Corporation. All rights reserved
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
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 "clk.h"
22
23/* Clock Manager offsets */
24#define CLK_MGR_PLL_CLK_SRC_SHIFT 8
25#define CLK_MGR_PLL_CLK_SRC_MASK 0x3
26
27/* Clock bypass bits */
28#define SOCFPGA_PLL_BG_PWRDWN 0
29#define SOCFPGA_PLL_PWR_DOWN 1
30#define SOCFPGA_PLL_EXT_ENA 2
31#define SOCFPGA_PLL_DIVF_MASK 0x00001FFF
32#define SOCFPGA_PLL_DIVF_SHIFT 0
33#define SOCFPGA_PLL_DIVQ_MASK 0x003F0000
34#define SOCFPGA_PLL_DIVQ_SHIFT 16
35#define SOCFGPA_MAX_PARENTS 5
36
37#define SOCFPGA_MAIN_PLL_CLK "main_pll"
38#define SOCFPGA_PERIP_PLL_CLK "periph_pll"
39
40#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw)
41
42void __iomem *clk_mgr_a10_base_addr;
43
44static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
45 unsigned long parent_rate)
46{
47 struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
48 unsigned long divf, divq, reg;
49 unsigned long long vco_freq;
50
51 /* read VCO1 reg for numerator and denominator */
52 reg = readl(socfpgaclk->hw.reg + 0x4);
53 divf = (reg & SOCFPGA_PLL_DIVF_MASK) >> SOCFPGA_PLL_DIVF_SHIFT;
54 divq = (reg & SOCFPGA_PLL_DIVQ_MASK) >> SOCFPGA_PLL_DIVQ_SHIFT;
55 vco_freq = (unsigned long long)parent_rate * (divf + 1);
56 do_div(vco_freq, (1 + divq));
57 return (unsigned long)vco_freq;
58}
59
60static u8 clk_pll_get_parent(struct clk_hw *hwclk)
61{
62 struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
63 u32 pll_src;
64
65 pll_src = readl(socfpgaclk->hw.reg);
66
67 return (pll_src >> CLK_MGR_PLL_CLK_SRC_SHIFT) &
68 CLK_MGR_PLL_CLK_SRC_MASK;
69}
70
71static struct clk_ops clk_pll_ops = {
72 .recalc_rate = clk_pll_recalc_rate,
73 .get_parent = clk_pll_get_parent,
74};
75
76static struct __init clk * __socfpga_pll_init(struct device_node *node,
77 const struct clk_ops *ops)
78{
79 u32 reg;
80 struct clk *clk;
81 struct socfpga_pll *pll_clk;
82 const char *clk_name = node->name;
83 const char *parent_name[SOCFGPA_MAX_PARENTS];
84 struct clk_init_data init;
85 struct device_node *clkmgr_np;
86 int rc;
87 int i = 0;
88
89 of_property_read_u32(node, "reg", &reg);
90
91 pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
92 if (WARN_ON(!pll_clk))
93 return NULL;
94
95 clkmgr_np = of_find_compatible_node(NULL, NULL, "altr,clk-mgr");
96 clk_mgr_a10_base_addr = of_iomap(clkmgr_np, 0);
97 BUG_ON(!clk_mgr_a10_base_addr);
98 pll_clk->hw.reg = clk_mgr_a10_base_addr + reg;
99
100 of_property_read_string(node, "clock-output-names", &clk_name);
101
102 init.name = clk_name;
103 init.ops = ops;
104 init.flags = 0;
105
106 while (i < SOCFGPA_MAX_PARENTS && (parent_name[i] =
107 of_clk_get_parent_name(node, i)) != NULL)
108 i++;
109 init.num_parents = i;
110 init.parent_names = parent_name;
111 pll_clk->hw.hw.init = &init;
112
113 pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
114 clk_pll_ops.enable = clk_gate_ops.enable;
115 clk_pll_ops.disable = clk_gate_ops.disable;
116
117 clk = clk_register(NULL, &pll_clk->hw.hw);
118 if (WARN_ON(IS_ERR(clk))) {
119 kfree(pll_clk);
120 return NULL;
121 }
122 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
123 return clk;
124}
125
126void __init socfpga_a10_pll_init(struct device_node *node)
127{
128 __socfpga_pll_init(node, &clk_pll_ops);
129}
diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c
index de6da957a09d..8f26b5234947 100644
--- a/drivers/clk/socfpga/clk-pll.c
+++ b/drivers/clk/socfpga/clk-pll.c
@@ -92,7 +92,6 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node,
92 struct clk_init_data init; 92 struct clk_init_data init;
93 struct device_node *clkmgr_np; 93 struct device_node *clkmgr_np;
94 int rc; 94 int rc;
95 int i = 0;
96 95
97 of_property_read_u32(node, "reg", &reg); 96 of_property_read_u32(node, "reg", &reg);
98 97
@@ -111,11 +110,7 @@ static __init struct clk *__socfpga_pll_init(struct device_node *node,
111 init.ops = ops; 110 init.ops = ops;
112 init.flags = 0; 111 init.flags = 0;
113 112
114 while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] = 113 init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS);
115 of_clk_get_parent_name(node, i)) != NULL)
116 i++;
117
118 init.num_parents = i;
119 init.parent_names = parent_name; 114 init.parent_names = parent_name;
120 pll_clk->hw.hw.init = &init; 115 pll_clk->hw.hw.init = &init;
121 116
diff --git a/drivers/clk/socfpga/clk.c b/drivers/clk/socfpga/clk.c
index 43db947e5f0e..7564d2e35f32 100644
--- a/drivers/clk/socfpga/clk.c
+++ b/drivers/clk/socfpga/clk.c
@@ -24,4 +24,9 @@
24CLK_OF_DECLARE(socfpga_pll_clk, "altr,socfpga-pll-clock", socfpga_pll_init); 24CLK_OF_DECLARE(socfpga_pll_clk, "altr,socfpga-pll-clock", socfpga_pll_init);
25CLK_OF_DECLARE(socfpga_perip_clk, "altr,socfpga-perip-clk", socfpga_periph_init); 25CLK_OF_DECLARE(socfpga_perip_clk, "altr,socfpga-perip-clk", socfpga_periph_init);
26CLK_OF_DECLARE(socfpga_gate_clk, "altr,socfpga-gate-clk", socfpga_gate_init); 26CLK_OF_DECLARE(socfpga_gate_clk, "altr,socfpga-gate-clk", socfpga_gate_init);
27 27CLK_OF_DECLARE(socfpga_a10_pll_clk, "altr,socfpga-a10-pll-clock",
28 socfpga_a10_pll_init);
29CLK_OF_DECLARE(socfpga_a10_perip_clk, "altr,socfpga-a10-perip-clk",
30 socfpga_a10_periph_init);
31CLK_OF_DECLARE(socfpga_a10_gate_clk, "altr,socfpga-a10-gate-clk",
32 socfpga_a10_gate_init);
diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h
index d291f60c46e1..603973ab7e29 100644
--- a/drivers/clk/socfpga/clk.h
+++ b/drivers/clk/socfpga/clk.h
@@ -26,14 +26,22 @@
26#define CLKMGR_L4SRC 0x70 26#define CLKMGR_L4SRC 0x70
27#define CLKMGR_PERPLL_SRC 0xAC 27#define CLKMGR_PERPLL_SRC 0xAC
28 28
29#define SOCFPGA_MAX_PARENTS 3 29#define SOCFPGA_MAX_PARENTS 5
30#define div_mask(width) ((1 << (width)) - 1) 30#define div_mask(width) ((1 << (width)) - 1)
31 31
32#define streq(a, b) (strcmp((a), (b)) == 0)
33#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \
34 ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))
35
32extern void __iomem *clk_mgr_base_addr; 36extern void __iomem *clk_mgr_base_addr;
37extern void __iomem *clk_mgr_a10_base_addr;
33 38
34void __init socfpga_pll_init(struct device_node *node); 39void __init socfpga_pll_init(struct device_node *node);
35void __init socfpga_periph_init(struct device_node *node); 40void __init socfpga_periph_init(struct device_node *node);
36void __init socfpga_gate_init(struct device_node *node); 41void __init socfpga_gate_init(struct device_node *node);
42void socfpga_a10_pll_init(struct device_node *node);
43void socfpga_a10_periph_init(struct device_node *node);
44void socfpga_a10_gate_init(struct device_node *node);
37 45
38struct socfpga_pll { 46struct socfpga_pll {
39 struct clk_gate hw; 47 struct clk_gate hw;
@@ -44,6 +52,7 @@ struct socfpga_gate_clk {
44 char *parent_name; 52 char *parent_name;
45 u32 fixed_div; 53 u32 fixed_div;
46 void __iomem *div_reg; 54 void __iomem *div_reg;
55 struct regmap *sys_mgr_base_addr;
47 u32 width; /* only valid if div_reg != 0 */ 56 u32 width; /* only valid if div_reg != 0 */
48 u32 shift; /* only valid if div_reg != 0 */ 57 u32 shift; /* only valid if div_reg != 0 */
49 u32 clk_phase[2]; 58 u32 clk_phase[2];
diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c
index bf12a25eb3a2..657ca14ba709 100644
--- a/drivers/clk/st/clk-flexgen.c
+++ b/drivers/clk/st/clk-flexgen.c
@@ -116,7 +116,7 @@ static long flexgen_round_rate(struct clk_hw *hw, unsigned long rate,
116 return *prate / div; 116 return *prate / div;
117} 117}
118 118
119unsigned long flexgen_recalc_rate(struct clk_hw *hw, 119static unsigned long flexgen_recalc_rate(struct clk_hw *hw,
120 unsigned long parent_rate) 120 unsigned long parent_rate)
121{ 121{
122 struct flexgen *flexgen = to_flexgen(hw); 122 struct flexgen *flexgen = to_flexgen(hw);
@@ -174,7 +174,7 @@ static const struct clk_ops flexgen_ops = {
174 .set_rate = flexgen_set_rate, 174 .set_rate = flexgen_set_rate,
175}; 175};
176 176
177struct clk *clk_register_flexgen(const char *name, 177static struct clk *clk_register_flexgen(const char *name,
178 const char **parent_names, u8 num_parents, 178 const char **parent_names, u8 num_parents,
179 void __iomem *reg, spinlock_t *lock, u32 idx, 179 void __iomem *reg, spinlock_t *lock, u32 idx,
180 unsigned long flexgen_flags) { 180 unsigned long flexgen_flags) {
@@ -245,7 +245,7 @@ static const char ** __init flexgen_get_parents(struct device_node *np,
245 const char **parents; 245 const char **parents;
246 int nparents, i; 246 int nparents, i;
247 247
248 nparents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 248 nparents = of_clk_get_parent_count(np);
249 if (WARN_ON(nparents <= 0)) 249 if (WARN_ON(nparents <= 0))
250 return NULL; 250 return NULL;
251 251
@@ -260,7 +260,7 @@ static const char ** __init flexgen_get_parents(struct device_node *np,
260 return parents; 260 return parents;
261} 261}
262 262
263void __init st_of_flexgen_setup(struct device_node *np) 263static void __init st_of_flexgen_setup(struct device_node *np)
264{ 264{
265 struct device_node *pnode; 265 struct device_node *pnode;
266 void __iomem *reg; 266 void __iomem *reg;
diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
index a917c4c7eaa9..e94197f04b0b 100644
--- a/drivers/clk/st/clkgen-fsyn.c
+++ b/drivers/clk/st/clkgen-fsyn.c
@@ -492,7 +492,7 @@ static int quadfs_pll_is_enabled(struct clk_hw *hw)
492 return !!npda; 492 return !!npda;
493} 493}
494 494
495int clk_fs660c32_vco_get_rate(unsigned long input, struct stm_fs *fs, 495static int clk_fs660c32_vco_get_rate(unsigned long input, struct stm_fs *fs,
496 unsigned long *rate) 496 unsigned long *rate)
497{ 497{
498 unsigned long nd = fs->ndiv + 16; /* ndiv value */ 498 unsigned long nd = fs->ndiv + 16; /* ndiv value */
@@ -519,7 +519,7 @@ static unsigned long quadfs_pll_fs660c32_recalc_rate(struct clk_hw *hw,
519 return rate; 519 return rate;
520} 520}
521 521
522int clk_fs660c32_vco_get_params(unsigned long input, 522static int clk_fs660c32_vco_get_params(unsigned long input,
523 unsigned long output, struct stm_fs *fs) 523 unsigned long output, struct stm_fs *fs)
524{ 524{
525/* Formula 525/* Formula
diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c
index fdcff10f6d30..4fbe6e099587 100644
--- a/drivers/clk/st/clkgen-mux.c
+++ b/drivers/clk/st/clkgen-mux.c
@@ -26,7 +26,7 @@ static const char ** __init clkgen_mux_get_parents(struct device_node *np,
26 const char **parents; 26 const char **parents;
27 int nparents, i; 27 int nparents, i;
28 28
29 nparents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 29 nparents = of_clk_get_parent_count(np);
30 if (WARN_ON(nparents <= 0)) 30 if (WARN_ON(nparents <= 0))
31 return ERR_PTR(-EINVAL); 31 return ERR_PTR(-EINVAL);
32 32
@@ -131,7 +131,7 @@ static int clkgena_divmux_is_enabled(struct clk_hw *hw)
131 return (s8)clk_mux_ops.get_parent(mux_hw) > 0; 131 return (s8)clk_mux_ops.get_parent(mux_hw) > 0;
132} 132}
133 133
134u8 clkgena_divmux_get_parent(struct clk_hw *hw) 134static u8 clkgena_divmux_get_parent(struct clk_hw *hw)
135{ 135{
136 struct clkgena_divmux *genamux = to_clkgena_divmux(hw); 136 struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
137 struct clk_hw *mux_hw = &genamux->mux.hw; 137 struct clk_hw *mux_hw = &genamux->mux.hw;
@@ -168,7 +168,7 @@ static int clkgena_divmux_set_parent(struct clk_hw *hw, u8 index)
168 return 0; 168 return 0;
169} 169}
170 170
171unsigned long clkgena_divmux_recalc_rate(struct clk_hw *hw, 171static unsigned long clkgena_divmux_recalc_rate(struct clk_hw *hw,
172 unsigned long parent_rate) 172 unsigned long parent_rate)
173{ 173{
174 struct clkgena_divmux *genamux = to_clkgena_divmux(hw); 174 struct clkgena_divmux *genamux = to_clkgena_divmux(hw);
@@ -215,7 +215,7 @@ static const struct clk_ops clkgena_divmux_ops = {
215/** 215/**
216 * clk_register_genamux - register a genamux clock with the clock framework 216 * clk_register_genamux - register a genamux clock with the clock framework
217 */ 217 */
218struct clk *clk_register_genamux(const char *name, 218static struct clk *clk_register_genamux(const char *name,
219 const char **parent_names, u8 num_parents, 219 const char **parent_names, u8 num_parents,
220 void __iomem *reg, 220 void __iomem *reg,
221 const struct clkgena_divmux_data *muxdata, 221 const struct clkgena_divmux_data *muxdata,
@@ -385,7 +385,7 @@ static void __iomem * __init clkgen_get_register_base(
385 return reg; 385 return reg;
386} 386}
387 387
388void __init st_of_clkgena_divmux_setup(struct device_node *np) 388static void __init st_of_clkgena_divmux_setup(struct device_node *np)
389{ 389{
390 const struct of_device_id *match; 390 const struct of_device_id *match;
391 const struct clkgena_divmux_data *data; 391 const struct clkgena_divmux_data *data;
@@ -485,7 +485,7 @@ static const struct of_device_id clkgena_prediv_of_match[] = {
485 {} 485 {}
486}; 486};
487 487
488void __init st_of_clkgena_prediv_setup(struct device_node *np) 488static void __init st_of_clkgena_prediv_setup(struct device_node *np)
489{ 489{
490 const struct of_device_id *match; 490 const struct of_device_id *match;
491 void __iomem *reg; 491 void __iomem *reg;
@@ -622,7 +622,7 @@ static const struct of_device_id mux_of_match[] = {
622 {} 622 {}
623}; 623};
624 624
625void __init st_of_clkgen_mux_setup(struct device_node *np) 625static void __init st_of_clkgen_mux_setup(struct device_node *np)
626{ 626{
627 const struct of_device_id *match; 627 const struct of_device_id *match;
628 struct clk *clk; 628 struct clk *clk;
@@ -699,7 +699,7 @@ static const struct of_device_id vcc_of_match[] = {
699 {} 699 {}
700}; 700};
701 701
702void __init st_of_clkgen_vcc_setup(struct device_node *np) 702static void __init st_of_clkgen_vcc_setup(struct device_node *np)
703{ 703{
704 const struct of_device_id *match; 704 const struct of_device_id *match;
705 void __iomem *reg; 705 void __iomem *reg;
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c
index d204ba85db3a..106532207213 100644
--- a/drivers/clk/st/clkgen-pll.c
+++ b/drivers/clk/st/clkgen-pll.c
@@ -270,7 +270,7 @@ static int clkgen_pll_is_enabled(struct clk_hw *hw)
270 return !poweroff; 270 return !poweroff;
271} 271}
272 272
273unsigned long recalc_stm_pll800c65(struct clk_hw *hw, 273static unsigned long recalc_stm_pll800c65(struct clk_hw *hw,
274 unsigned long parent_rate) 274 unsigned long parent_rate)
275{ 275{
276 struct clkgen_pll *pll = to_clkgen_pll(hw); 276 struct clkgen_pll *pll = to_clkgen_pll(hw);
@@ -297,7 +297,7 @@ unsigned long recalc_stm_pll800c65(struct clk_hw *hw,
297 297
298} 298}
299 299
300unsigned long recalc_stm_pll1600c65(struct clk_hw *hw, 300static unsigned long recalc_stm_pll1600c65(struct clk_hw *hw,
301 unsigned long parent_rate) 301 unsigned long parent_rate)
302{ 302{
303 struct clkgen_pll *pll = to_clkgen_pll(hw); 303 struct clkgen_pll *pll = to_clkgen_pll(hw);
@@ -321,7 +321,7 @@ unsigned long recalc_stm_pll1600c65(struct clk_hw *hw,
321 return rate; 321 return rate;
322} 322}
323 323
324unsigned long recalc_stm_pll3200c32(struct clk_hw *hw, 324static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
325 unsigned long parent_rate) 325 unsigned long parent_rate)
326{ 326{
327 struct clkgen_pll *pll = to_clkgen_pll(hw); 327 struct clkgen_pll *pll = to_clkgen_pll(hw);
@@ -343,7 +343,7 @@ unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
343 return rate; 343 return rate;
344} 344}
345 345
346unsigned long recalc_stm_pll1200c32(struct clk_hw *hw, 346static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
347 unsigned long parent_rate) 347 unsigned long parent_rate)
348{ 348{
349 struct clkgen_pll *pll = to_clkgen_pll(hw); 349 struct clkgen_pll *pll = to_clkgen_pll(hw);
@@ -544,7 +544,7 @@ CLK_OF_DECLARE(clkgena_c65_plls,
544 "st,clkgena-plls-c65", clkgena_c65_pll_setup); 544 "st,clkgena-plls-c65", clkgena_c65_pll_setup);
545 545
546static struct clk * __init clkgen_odf_register(const char *parent_name, 546static struct clk * __init clkgen_odf_register(const char *parent_name,
547 void * __iomem reg, 547 void __iomem *reg,
548 struct clkgen_pll_data *pll_data, 548 struct clkgen_pll_data *pll_data,
549 int odf, 549 int odf,
550 spinlock_t *odf_lock, 550 spinlock_t *odf_lock,
diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
index d86bc46b93bd..19e543a32e2b 100644
--- a/drivers/clk/ti/clk-dra7-atl.c
+++ b/drivers/clk/ti/clk-dra7-atl.c
@@ -155,7 +155,7 @@ static int atl_clk_set_rate(struct clk_hw *hw, unsigned long rate,
155 return 0; 155 return 0;
156} 156}
157 157
158const struct clk_ops atl_clk_ops = { 158static const struct clk_ops atl_clk_ops = {
159 .enable = atl_clk_enable, 159 .enable = atl_clk_enable,
160 .disable = atl_clk_disable, 160 .disable = atl_clk_disable,
161 .is_enabled = atl_clk_is_enabled, 161 .is_enabled = atl_clk_is_enabled,
@@ -167,7 +167,7 @@ const struct clk_ops atl_clk_ops = {
167static void __init of_dra7_atl_clock_setup(struct device_node *node) 167static void __init of_dra7_atl_clock_setup(struct device_node *node)
168{ 168{
169 struct dra7_atl_desc *clk_hw = NULL; 169 struct dra7_atl_desc *clk_hw = NULL;
170 struct clk_init_data init = { 0 }; 170 struct clk_init_data init = { NULL };
171 const char **parent_names = NULL; 171 const char **parent_names = NULL;
172 struct clk *clk; 172 struct clk *clk;
173 173
@@ -252,6 +252,11 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
252 } 252 }
253 253
254 clk = of_clk_get_from_provider(&clkspec); 254 clk = of_clk_get_from_provider(&clkspec);
255 if (IS_ERR(clk)) {
256 pr_err("%s: failed to get atl clock %d from provider\n",
257 __func__, i);
258 return PTR_ERR(clk);
259 }
255 260
256 cdesc = to_atl_desc(__clk_get_hw(clk)); 261 cdesc = to_atl_desc(__clk_get_hw(clk));
257 cdesc->cinfo = cinfo; 262 cdesc->cinfo = cinfo;
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
index 0ebe5c51062b..64bb5e8a3b8c 100644
--- a/drivers/clk/ti/clk.c
+++ b/drivers/clk/ti/clk.c
@@ -122,14 +122,14 @@ void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
122 122
123 if (i == CLK_MAX_MEMMAPS) { 123 if (i == CLK_MAX_MEMMAPS) {
124 pr_err("clk-provider not found for %s!\n", node->name); 124 pr_err("clk-provider not found for %s!\n", node->name);
125 return ERR_PTR(-ENOENT); 125 return IOMEM_ERR_PTR(-ENOENT);
126 } 126 }
127 127
128 reg->index = i; 128 reg->index = i;
129 129
130 if (of_property_read_u32_index(node, "reg", index, &val)) { 130 if (of_property_read_u32_index(node, "reg", index, &val)) {
131 pr_err("%s must have reg[%d]!\n", node->name, index); 131 pr_err("%s must have reg[%d]!\n", node->name, index);
132 return ERR_PTR(-EINVAL); 132 return IOMEM_ERR_PTR(-EINVAL);
133 } 133 }
134 134
135 reg->offset = val; 135 reg->offset = val;
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 35fe1085480c..b82ef07f3403 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -32,7 +32,7 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
32 int i; 32 int i;
33 int num_clks; 33 int num_clks;
34 34
35 num_clks = of_count_phandle_with_args(node, "clocks", "#clock-cells"); 35 num_clks = of_clk_get_parent_count(node);
36 36
37 for (i = 0; i < num_clks; i++) { 37 for (i = 0; i < num_clks; i++) {
38 clk = of_clk_get(node, i); 38 clk = of_clk_get(node, i);
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 11478a501c30..2aacf7a3bcae 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -177,7 +177,7 @@ cleanup:
177} 177}
178 178
179#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_ATAGS) 179#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_ATAGS)
180void __iomem *_get_reg(u8 module, u16 offset) 180static void __iomem *_get_reg(u8 module, u16 offset)
181{ 181{
182 u32 reg; 182 u32 reg;
183 struct clk_omap_reg *reg_setup; 183 struct clk_omap_reg *reg_setup;
diff --git a/drivers/clk/ti/fapll.c b/drivers/clk/ti/fapll.c
index ffcd8e09e85b..730aa62454a2 100644
--- a/drivers/clk/ti/fapll.c
+++ b/drivers/clk/ti/fapll.c
@@ -621,13 +621,13 @@ static void __init ti_fapll_setup(struct device_node *node)
621 621
622 /* Check for hardwired audio_pll_clk1 */ 622 /* Check for hardwired audio_pll_clk1 */
623 if (is_audio_pll_clk1(freq)) { 623 if (is_audio_pll_clk1(freq)) {
624 freq = 0; 624 freq = NULL;
625 div = 0; 625 div = NULL;
626 } else { 626 } else {
627 /* Does the synthesizer have a FREQ register? */ 627 /* Does the synthesizer have a FREQ register? */
628 v = readl_relaxed(freq); 628 v = readl_relaxed(freq);
629 if (!v) 629 if (!v)
630 freq = 0; 630 freq = NULL;
631 } 631 }
632 synth_clk = ti_fapll_synth_setup(fd, freq, div, output_instance, 632 synth_clk = ti_fapll_synth_setup(fd, freq, div, output_instance,
633 output_name, node->name, 633 output_name, node->name,
diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c
index 80069c370a47..4626b97b7d83 100644
--- a/drivers/clk/ux500/u8500_clk.c
+++ b/drivers/clk/ux500/u8500_clk.c
@@ -116,11 +116,12 @@ void u8500_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base,
116 clk_register_clkdev(clk, NULL, "hdmi"); 116 clk_register_clkdev(clk, NULL, "hdmi");
117 clk_register_clkdev(clk, "hdmi", "mcde"); 117 clk_register_clkdev(clk, "hdmi", "mcde");
118 118
119 clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT); 119 clk = clk_reg_prcmu_scalable("apeatclk", NULL, PRCMU_APEATCLK, 0,
120 CLK_IS_ROOT|CLK_SET_RATE_GATE);
120 clk_register_clkdev(clk, NULL, "apeat"); 121 clk_register_clkdev(clk, NULL, "apeat");
121 122
122 clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK, 123 clk = clk_reg_prcmu_scalable("apetraceclk", NULL, PRCMU_APETRACECLK, 0,
123 CLK_IS_ROOT); 124 CLK_IS_ROOT|CLK_SET_RATE_GATE);
124 clk_register_clkdev(clk, NULL, "apetrace"); 125 clk_register_clkdev(clk, NULL, "apetrace");
125 126
126 clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT); 127 clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT);
diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c
index 7b55ef89baa5..e319ef912dc6 100644
--- a/drivers/clk/ux500/u8500_of_clk.c
+++ b/drivers/clk/ux500/u8500_of_clk.c
@@ -166,8 +166,8 @@ void u8500_of_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base,
166 clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT); 166 clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT);
167 prcmu_clk[PRCMU_APEATCLK] = clk; 167 prcmu_clk[PRCMU_APEATCLK] = clk;
168 168
169 clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK, 169 clk = clk_reg_prcmu_scalable("apetraceclk", NULL, PRCMU_APETRACECLK, 0,
170 CLK_IS_ROOT); 170 CLK_IS_ROOT|CLK_SET_RATE_GATE);
171 prcmu_clk[PRCMU_APETRACECLK] = clk; 171 prcmu_clk[PRCMU_APETRACECLK] = clk;
172 172
173 clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT); 173 clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT);
diff --git a/drivers/clk/versatile/clk-sp810.c b/drivers/clk/versatile/clk-sp810.c
index c6e86a9a2aa3..a96dd8e53fdb 100644
--- a/drivers/clk/versatile/clk-sp810.c
+++ b/drivers/clk/versatile/clk-sp810.c
@@ -135,7 +135,7 @@ static struct clk *clk_sp810_timerclken_of_get(struct of_phandle_args *clkspec,
135 return sp810->timerclken[clkspec->args[0]].clk; 135 return sp810->timerclken[clkspec->args[0]].clk;
136} 136}
137 137
138void __init clk_sp810_of_setup(struct device_node *node) 138static void __init clk_sp810_of_setup(struct device_node *node)
139{ 139{
140 struct clk_sp810 *sp810 = kzalloc(sizeof(*sp810), GFP_KERNEL); 140 struct clk_sp810 *sp810 = kzalloc(sizeof(*sp810), GFP_KERNEL);
141 const char *parent_names[2]; 141 const char *parent_names[2];
@@ -156,7 +156,7 @@ void __init clk_sp810_of_setup(struct device_node *node)
156 "timclk"); 156 "timclk");
157 parent_names[1] = of_clk_get_parent_name(node, sp810->timclk_index); 157 parent_names[1] = of_clk_get_parent_name(node, sp810->timclk_index);
158 158
159 if (parent_names[0] <= 0 || parent_names[1] <= 0) { 159 if (!parent_names[0] || !parent_names[1]) {
160 pr_warn("Failed to obtain parent clocks for SP810!\n"); 160 pr_warn("Failed to obtain parent clocks for SP810!\n");
161 return; 161 return;
162 } 162 }
diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c
index 40cb113be6af..de614384bb44 100644
--- a/drivers/clk/zynq/clkc.c
+++ b/drivers/clk/zynq/clkc.c
@@ -85,22 +85,29 @@ static DEFINE_SPINLOCK(canmioclk_lock);
85static DEFINE_SPINLOCK(dbgclk_lock); 85static DEFINE_SPINLOCK(dbgclk_lock);
86static DEFINE_SPINLOCK(aperclk_lock); 86static DEFINE_SPINLOCK(aperclk_lock);
87 87
88static const char *armpll_parents[] __initdata = {"armpll_int", "ps_clk"}; 88static const char *const armpll_parents[] __initconst = {"armpll_int",
89static const char *ddrpll_parents[] __initdata = {"ddrpll_int", "ps_clk"}; 89 "ps_clk"};
90static const char *iopll_parents[] __initdata = {"iopll_int", "ps_clk"}; 90static const char *const ddrpll_parents[] __initconst = {"ddrpll_int",
91 "ps_clk"};
92static const char *const iopll_parents[] __initconst = {"iopll_int",
93 "ps_clk"};
91static const char *gem0_mux_parents[] __initdata = {"gem0_div1", "dummy_name"}; 94static const char *gem0_mux_parents[] __initdata = {"gem0_div1", "dummy_name"};
92static const char *gem1_mux_parents[] __initdata = {"gem1_div1", "dummy_name"}; 95static const char *gem1_mux_parents[] __initdata = {"gem1_div1", "dummy_name"};
93static const char *can0_mio_mux2_parents[] __initdata = {"can0_gate", 96static const char *const can0_mio_mux2_parents[] __initconst = {"can0_gate",
94 "can0_mio_mux"}; 97 "can0_mio_mux"};
95static const char *can1_mio_mux2_parents[] __initdata = {"can1_gate", 98static const char *const can1_mio_mux2_parents[] __initconst = {"can1_gate",
96 "can1_mio_mux"}; 99 "can1_mio_mux"};
97static const char *dbg_emio_mux_parents[] __initdata = {"dbg_div", 100static const char *dbg_emio_mux_parents[] __initdata = {"dbg_div",
98 "dummy_name"}; 101 "dummy_name"};
99 102
100static const char *dbgtrc_emio_input_names[] __initdata = {"trace_emio_clk"}; 103static const char *const dbgtrc_emio_input_names[] __initconst = {
101static const char *gem0_emio_input_names[] __initdata = {"gem0_emio_clk"}; 104 "trace_emio_clk"};
102static const char *gem1_emio_input_names[] __initdata = {"gem1_emio_clk"}; 105static const char *const gem0_emio_input_names[] __initconst = {
103static const char *swdt_ext_clk_input_names[] __initdata = {"swdt_ext_clk"}; 106 "gem0_emio_clk"};
107static const char *const gem1_emio_input_names[] __initconst = {
108 "gem1_emio_clk"};
109static const char *const swdt_ext_clk_input_names[] __initconst = {
110 "swdt_ext_clk"};
104 111
105static void __init zynq_clk_register_fclk(enum zynq_clk fclk, 112static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
106 const char *clk_name, void __iomem *fclk_ctrl_reg, 113 const char *clk_name, void __iomem *fclk_ctrl_reg,
diff --git a/include/dt-bindings/clock/hi6220-clock.h b/include/dt-bindings/clock/hi6220-clock.h
new file mode 100644
index 000000000000..70ee3833a7a0
--- /dev/null
+++ b/include/dt-bindings/clock/hi6220-clock.h
@@ -0,0 +1,173 @@
1/*
2 * Copyright (c) 2015 Hisilicon Limited.
3 *
4 * Author: Bintian Wang <bintian.wang@huawei.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __DT_BINDINGS_CLOCK_HI6220_H
12#define __DT_BINDINGS_CLOCK_HI6220_H
13
14/* clk in Hi6220 AO (always on) controller */
15#define HI6220_NONE_CLOCK 0
16
17/* fixed rate clocks */
18#define HI6220_REF32K 1
19#define HI6220_CLK_TCXO 2
20#define HI6220_MMC1_PAD 3
21#define HI6220_MMC2_PAD 4
22#define HI6220_MMC0_PAD 5
23#define HI6220_PLL_BBP 6
24#define HI6220_PLL_GPU 7
25#define HI6220_PLL1_DDR 8
26#define HI6220_PLL_SYS 9
27#define HI6220_PLL_SYS_MEDIA 10
28#define HI6220_DDR_SRC 11
29#define HI6220_PLL_MEDIA 12
30#define HI6220_PLL_DDR 13
31
32/* fixed factor clocks */
33#define HI6220_300M 14
34#define HI6220_150M 15
35#define HI6220_PICOPHY_SRC 16
36#define HI6220_MMC0_SRC_SEL 17
37#define HI6220_MMC1_SRC_SEL 18
38#define HI6220_MMC2_SRC_SEL 19
39#define HI6220_VPU_CODEC 20
40#define HI6220_MMC0_SMP 21
41#define HI6220_MMC1_SMP 22
42#define HI6220_MMC2_SMP 23
43
44/* gate clocks */
45#define HI6220_WDT0_PCLK 24
46#define HI6220_WDT1_PCLK 25
47#define HI6220_WDT2_PCLK 26
48#define HI6220_TIMER0_PCLK 27
49#define HI6220_TIMER1_PCLK 28
50#define HI6220_TIMER2_PCLK 29
51#define HI6220_TIMER3_PCLK 30
52#define HI6220_TIMER4_PCLK 31
53#define HI6220_TIMER5_PCLK 32
54#define HI6220_TIMER6_PCLK 33
55#define HI6220_TIMER7_PCLK 34
56#define HI6220_TIMER8_PCLK 35
57#define HI6220_UART0_PCLK 36
58
59#define HI6220_AO_NR_CLKS 37
60
61/* clk in Hi6220 systrl */
62/* gate clock */
63#define HI6220_MMC0_CLK 1
64#define HI6220_MMC0_CIUCLK 2
65#define HI6220_MMC1_CLK 3
66#define HI6220_MMC1_CIUCLK 4
67#define HI6220_MMC2_CLK 5
68#define HI6220_MMC2_CIUCLK 6
69#define HI6220_USBOTG_HCLK 7
70#define HI6220_CLK_PICOPHY 8
71#define HI6220_HIFI 9
72#define HI6220_DACODEC_PCLK 10
73#define HI6220_EDMAC_ACLK 11
74#define HI6220_CS_ATB 12
75#define HI6220_I2C0_CLK 13
76#define HI6220_I2C1_CLK 14
77#define HI6220_I2C2_CLK 15
78#define HI6220_I2C3_CLK 16
79#define HI6220_UART1_PCLK 17
80#define HI6220_UART2_PCLK 18
81#define HI6220_UART3_PCLK 19
82#define HI6220_UART4_PCLK 20
83#define HI6220_SPI_CLK 21
84#define HI6220_TSENSOR_CLK 22
85#define HI6220_MMU_CLK 23
86#define HI6220_HIFI_SEL 24
87#define HI6220_MMC0_SYSPLL 25
88#define HI6220_MMC1_SYSPLL 26
89#define HI6220_MMC2_SYSPLL 27
90#define HI6220_MMC0_SEL 28
91#define HI6220_MMC1_SEL 29
92#define HI6220_BBPPLL_SEL 30
93#define HI6220_MEDIA_PLL_SRC 31
94#define HI6220_MMC2_SEL 32
95#define HI6220_CS_ATB_SYSPLL 33
96
97/* mux clocks */
98#define HI6220_MMC0_SRC 34
99#define HI6220_MMC0_SMP_IN 35
100#define HI6220_MMC1_SRC 36
101#define HI6220_MMC1_SMP_IN 37
102#define HI6220_MMC2_SRC 38
103#define HI6220_MMC2_SMP_IN 39
104#define HI6220_HIFI_SRC 40
105#define HI6220_UART1_SRC 41
106#define HI6220_UART2_SRC 42
107#define HI6220_UART3_SRC 43
108#define HI6220_UART4_SRC 44
109#define HI6220_MMC0_MUX0 45
110#define HI6220_MMC1_MUX0 46
111#define HI6220_MMC2_MUX0 47
112#define HI6220_MMC0_MUX1 48
113#define HI6220_MMC1_MUX1 49
114#define HI6220_MMC2_MUX1 50
115
116/* divider clocks */
117#define HI6220_CLK_BUS 51
118#define HI6220_MMC0_DIV 52
119#define HI6220_MMC1_DIV 53
120#define HI6220_MMC2_DIV 54
121#define HI6220_HIFI_DIV 55
122#define HI6220_BBPPLL0_DIV 56
123#define HI6220_CS_DAPB 57
124#define HI6220_CS_ATB_DIV 58
125
126#define HI6220_SYS_NR_CLKS 59
127
128/* clk in Hi6220 media controller */
129/* gate clocks */
130#define HI6220_DSI_PCLK 1
131#define HI6220_G3D_PCLK 2
132#define HI6220_ACLK_CODEC_VPU 3
133#define HI6220_ISP_SCLK 4
134#define HI6220_ADE_CORE 5
135#define HI6220_MED_MMU 6
136#define HI6220_CFG_CSI4PHY 7
137#define HI6220_CFG_CSI2PHY 8
138#define HI6220_ISP_SCLK_GATE 9
139#define HI6220_ISP_SCLK_GATE1 10
140#define HI6220_ADE_CORE_GATE 11
141#define HI6220_CODEC_VPU_GATE 12
142#define HI6220_MED_SYSPLL 13
143
144/* mux clocks */
145#define HI6220_1440_1200 14
146#define HI6220_1000_1200 15
147#define HI6220_1000_1440 16
148
149/* divider clocks */
150#define HI6220_CODEC_JPEG 17
151#define HI6220_ISP_SCLK_SRC 18
152#define HI6220_ISP_SCLK1 19
153#define HI6220_ADE_CORE_SRC 20
154#define HI6220_ADE_PIX_SRC 21
155#define HI6220_G3D_CLK 22
156#define HI6220_CODEC_VPU_SRC 23
157
158#define HI6220_MEDIA_NR_CLKS 24
159
160/* clk in Hi6220 power controller */
161/* gate clocks */
162#define HI6220_PLL_GPU_GATE 1
163#define HI6220_PLL1_DDR_GATE 2
164#define HI6220_PLL_DDR_GATE 3
165#define HI6220_PLL_MEDIA_GATE 4
166#define HI6220_PLL0_BBP_GATE 5
167
168/* divider clocks */
169#define HI6220_DDRC_SRC 6
170#define HI6220_DDRC_AXI1 7
171
172#define HI6220_POWER_NR_CLKS 8
173#endif
diff --git a/include/dt-bindings/clock/marvell,mmp2.h b/include/dt-bindings/clock/marvell,mmp2.h
index 591f7fba89e2..7a510384a82a 100644
--- a/include/dt-bindings/clock/marvell,mmp2.h
+++ b/include/dt-bindings/clock/marvell,mmp2.h
@@ -48,6 +48,7 @@
48#define MMP2_CLK_SSP1 78 48#define MMP2_CLK_SSP1 78
49#define MMP2_CLK_SSP2 79 49#define MMP2_CLK_SSP2 79
50#define MMP2_CLK_SSP3 80 50#define MMP2_CLK_SSP3 80
51#define MMP2_CLK_TIMER 81
51 52
52/* axi periphrals */ 53/* axi periphrals */
53#define MMP2_CLK_SDH0 101 54#define MMP2_CLK_SDH0 101
diff --git a/include/dt-bindings/clock/marvell,pxa168.h b/include/dt-bindings/clock/marvell,pxa168.h
index 79630b9d74b8..3e45bdfe1aa4 100644
--- a/include/dt-bindings/clock/marvell,pxa168.h
+++ b/include/dt-bindings/clock/marvell,pxa168.h
@@ -18,7 +18,9 @@
18#define PXA168_CLK_PLL1_13_1_5 18 18#define PXA168_CLK_PLL1_13_1_5 18
19#define PXA168_CLK_PLL1_2_1_5 19 19#define PXA168_CLK_PLL1_2_1_5 19
20#define PXA168_CLK_PLL1_3_16 20 20#define PXA168_CLK_PLL1_3_16 20
21#define PXA168_CLK_PLL1_192 21
21#define PXA168_CLK_UART_PLL 27 22#define PXA168_CLK_UART_PLL 27
23#define PXA168_CLK_USB_PLL 28
22 24
23/* apb periphrals */ 25/* apb periphrals */
24#define PXA168_CLK_TWSI0 60 26#define PXA168_CLK_TWSI0 60
@@ -40,6 +42,7 @@
40#define PXA168_CLK_SSP2 76 42#define PXA168_CLK_SSP2 76
41#define PXA168_CLK_SSP3 77 43#define PXA168_CLK_SSP3 77
42#define PXA168_CLK_SSP4 78 44#define PXA168_CLK_SSP4 78
45#define PXA168_CLK_TIMER 79
43 46
44/* axi periphrals */ 47/* axi periphrals */
45#define PXA168_CLK_DFC 100 48#define PXA168_CLK_DFC 100
diff --git a/include/dt-bindings/clock/marvell,pxa1928.h b/include/dt-bindings/clock/marvell,pxa1928.h
new file mode 100644
index 000000000000..d4f2e18919ff
--- /dev/null
+++ b/include/dt-bindings/clock/marvell,pxa1928.h
@@ -0,0 +1,57 @@
1#ifndef __DTS_MARVELL_PXA1928_CLOCK_H
2#define __DTS_MARVELL_PXA1928_CLOCK_H
3
4/*
5 * Clock ID values here correspond to the control register offset/4.
6 */
7
8/* apb peripherals */
9#define PXA1928_CLK_RTC 0x00
10#define PXA1928_CLK_TWSI0 0x01
11#define PXA1928_CLK_TWSI1 0x02
12#define PXA1928_CLK_TWSI2 0x03
13#define PXA1928_CLK_TWSI3 0x04
14#define PXA1928_CLK_OWIRE 0x05
15#define PXA1928_CLK_KPC 0x06
16#define PXA1928_CLK_TB_ROTARY 0x07
17#define PXA1928_CLK_SW_JTAG 0x08
18#define PXA1928_CLK_TIMER1 0x09
19#define PXA1928_CLK_UART0 0x0b
20#define PXA1928_CLK_UART1 0x0c
21#define PXA1928_CLK_UART2 0x0d
22#define PXA1928_CLK_GPIO 0x0e
23#define PXA1928_CLK_PWM0 0x0f
24#define PXA1928_CLK_PWM1 0x10
25#define PXA1928_CLK_PWM2 0x11
26#define PXA1928_CLK_PWM3 0x12
27#define PXA1928_CLK_SSP0 0x13
28#define PXA1928_CLK_SSP1 0x14
29#define PXA1928_CLK_SSP2 0x15
30
31#define PXA1928_CLK_TWSI4 0x1f
32#define PXA1928_CLK_TWSI5 0x20
33#define PXA1928_CLK_UART3 0x22
34#define PXA1928_CLK_THSENS_GLOB 0x24
35#define PXA1928_CLK_THSENS_CPU 0x26
36#define PXA1928_CLK_THSENS_VPU 0x27
37#define PXA1928_CLK_THSENS_GC 0x28
38#define PXA1928_APBC_NR_CLKS 0x30
39
40
41/* axi peripherals */
42#define PXA1928_CLK_SDH0 0x15
43#define PXA1928_CLK_SDH1 0x16
44#define PXA1928_CLK_USB 0x17
45#define PXA1928_CLK_NAND 0x18
46#define PXA1928_CLK_DMA 0x19
47
48#define PXA1928_CLK_SDH2 0x3a
49#define PXA1928_CLK_SDH3 0x3b
50#define PXA1928_CLK_HSIC 0x3e
51#define PXA1928_CLK_SDH4 0x57
52#define PXA1928_CLK_GC3D 0x5d
53#define PXA1928_CLK_GC2D 0x5f
54
55#define PXA1928_APMU_NR_CLKS 0x60
56
57#endif
diff --git a/include/dt-bindings/clock/marvell,pxa910.h b/include/dt-bindings/clock/marvell,pxa910.h
index 719cffb2bea2..135082a0b62f 100644
--- a/include/dt-bindings/clock/marvell,pxa910.h
+++ b/include/dt-bindings/clock/marvell,pxa910.h
@@ -18,7 +18,9 @@
18#define PXA910_CLK_PLL1_13_1_5 18 18#define PXA910_CLK_PLL1_13_1_5 18
19#define PXA910_CLK_PLL1_2_1_5 19 19#define PXA910_CLK_PLL1_2_1_5 19
20#define PXA910_CLK_PLL1_3_16 20 20#define PXA910_CLK_PLL1_3_16 20
21#define PXA910_CLK_PLL1_192 21
21#define PXA910_CLK_UART_PLL 27 22#define PXA910_CLK_UART_PLL 27
23#define PXA910_CLK_USB_PLL 28
22 24
23/* apb periphrals */ 25/* apb periphrals */
24#define PXA910_CLK_TWSI0 60 26#define PXA910_CLK_TWSI0 60
@@ -37,6 +39,8 @@
37#define PXA910_CLK_UART2 73 39#define PXA910_CLK_UART2 73
38#define PXA910_CLK_SSP0 74 40#define PXA910_CLK_SSP0 74
39#define PXA910_CLK_SSP1 75 41#define PXA910_CLK_SSP1 75
42#define PXA910_CLK_TIMER0 76
43#define PXA910_CLK_TIMER1 77
40 44
41/* axi periphrals */ 45/* axi periphrals */
42#define PXA910_CLK_DFC 100 46#define PXA910_CLK_DFC 100
diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h
new file mode 100644
index 000000000000..bd2720d58e0c
--- /dev/null
+++ b/include/dt-bindings/clock/meson8b-clkc.h
@@ -0,0 +1,25 @@
1/*
2 * Meson8b clock tree IDs
3 */
4
5#ifndef __MESON8B_CLKC_H
6#define __MESON8B_CLKC_H
7
8#define CLKID_UNUSED 0
9#define CLKID_XTAL 1
10#define CLKID_PLL_FIXED 2
11#define CLKID_PLL_VID 3
12#define CLKID_PLL_SYS 4
13#define CLKID_FCLK_DIV2 5
14#define CLKID_FCLK_DIV3 6
15#define CLKID_FCLK_DIV4 7
16#define CLKID_FCLK_DIV5 8
17#define CLKID_FCLK_DIV7 9
18#define CLKID_CLK81 10
19#define CLKID_MALI 11
20#define CLKID_CPUCLK 12
21#define CLKID_ZERO 13
22
23#define CLK_NR_CLKS (CLKID_ZERO + 1)
24
25#endif /* __MESON8B_CLKC_H */
diff --git a/include/dt-bindings/clock/mt8135-clk.h b/include/dt-bindings/clock/mt8135-clk.h
new file mode 100644
index 000000000000..6dac6c091dd2
--- /dev/null
+++ b/include/dt-bindings/clock/mt8135-clk.h
@@ -0,0 +1,194 @@
1/*
2 * Copyright (c) 2014 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#ifndef _DT_BINDINGS_CLK_MT8135_H
16#define _DT_BINDINGS_CLK_MT8135_H
17
18/* TOPCKGEN */
19
20#define CLK_TOP_DSI0_LNTC_DSICLK 1
21#define CLK_TOP_HDMITX_CLKDIG_CTS 2
22#define CLK_TOP_CLKPH_MCK 3
23#define CLK_TOP_CPUM_TCK_IN 4
24#define CLK_TOP_MAINPLL_806M 5
25#define CLK_TOP_MAINPLL_537P3M 6
26#define CLK_TOP_MAINPLL_322P4M 7
27#define CLK_TOP_MAINPLL_230P3M 8
28#define CLK_TOP_UNIVPLL_624M 9
29#define CLK_TOP_UNIVPLL_416M 10
30#define CLK_TOP_UNIVPLL_249P6M 11
31#define CLK_TOP_UNIVPLL_178P3M 12
32#define CLK_TOP_UNIVPLL_48M 13
33#define CLK_TOP_MMPLL_D2 14
34#define CLK_TOP_MMPLL_D3 15
35#define CLK_TOP_MMPLL_D5 16
36#define CLK_TOP_MMPLL_D7 17
37#define CLK_TOP_MMPLL_D4 18
38#define CLK_TOP_MMPLL_D6 19
39#define CLK_TOP_SYSPLL_D2 20
40#define CLK_TOP_SYSPLL_D4 21
41#define CLK_TOP_SYSPLL_D6 22
42#define CLK_TOP_SYSPLL_D8 23
43#define CLK_TOP_SYSPLL_D10 24
44#define CLK_TOP_SYSPLL_D12 25
45#define CLK_TOP_SYSPLL_D16 26
46#define CLK_TOP_SYSPLL_D24 27
47#define CLK_TOP_SYSPLL_D3 28
48#define CLK_TOP_SYSPLL_D2P5 29
49#define CLK_TOP_SYSPLL_D5 30
50#define CLK_TOP_SYSPLL_D3P5 31
51#define CLK_TOP_UNIVPLL1_D2 32
52#define CLK_TOP_UNIVPLL1_D4 33
53#define CLK_TOP_UNIVPLL1_D6 34
54#define CLK_TOP_UNIVPLL1_D8 35
55#define CLK_TOP_UNIVPLL1_D10 36
56#define CLK_TOP_UNIVPLL2_D2 37
57#define CLK_TOP_UNIVPLL2_D4 38
58#define CLK_TOP_UNIVPLL2_D6 39
59#define CLK_TOP_UNIVPLL2_D8 40
60#define CLK_TOP_UNIVPLL_D3 41
61#define CLK_TOP_UNIVPLL_D5 42
62#define CLK_TOP_UNIVPLL_D7 43
63#define CLK_TOP_UNIVPLL_D10 44
64#define CLK_TOP_UNIVPLL_D26 45
65#define CLK_TOP_APLL 46
66#define CLK_TOP_APLL_D4 47
67#define CLK_TOP_APLL_D8 48
68#define CLK_TOP_APLL_D16 49
69#define CLK_TOP_APLL_D24 50
70#define CLK_TOP_LVDSPLL_D2 51
71#define CLK_TOP_LVDSPLL_D4 52
72#define CLK_TOP_LVDSPLL_D8 53
73#define CLK_TOP_LVDSTX_CLKDIG_CT 54
74#define CLK_TOP_VPLL_DPIX 55
75#define CLK_TOP_TVHDMI_H 56
76#define CLK_TOP_HDMITX_CLKDIG_D2 57
77#define CLK_TOP_HDMITX_CLKDIG_D3 58
78#define CLK_TOP_TVHDMI_D2 59
79#define CLK_TOP_TVHDMI_D4 60
80#define CLK_TOP_MEMPLL_MCK_D4 61
81#define CLK_TOP_AXI_SEL 62
82#define CLK_TOP_SMI_SEL 63
83#define CLK_TOP_MFG_SEL 64
84#define CLK_TOP_IRDA_SEL 65
85#define CLK_TOP_CAM_SEL 66
86#define CLK_TOP_AUD_INTBUS_SEL 67
87#define CLK_TOP_JPG_SEL 68
88#define CLK_TOP_DISP_SEL 69
89#define CLK_TOP_MSDC30_1_SEL 70
90#define CLK_TOP_MSDC30_2_SEL 71
91#define CLK_TOP_MSDC30_3_SEL 72
92#define CLK_TOP_MSDC30_4_SEL 73
93#define CLK_TOP_USB20_SEL 74
94#define CLK_TOP_VENC_SEL 75
95#define CLK_TOP_SPI_SEL 76
96#define CLK_TOP_UART_SEL 77
97#define CLK_TOP_MEM_SEL 78
98#define CLK_TOP_CAMTG_SEL 79
99#define CLK_TOP_AUDIO_SEL 80
100#define CLK_TOP_FIX_SEL 81
101#define CLK_TOP_VDEC_SEL 82
102#define CLK_TOP_DDRPHYCFG_SEL 83
103#define CLK_TOP_DPILVDS_SEL 84
104#define CLK_TOP_PMICSPI_SEL 85
105#define CLK_TOP_MSDC30_0_SEL 86
106#define CLK_TOP_SMI_MFG_AS_SEL 87
107#define CLK_TOP_GCPU_SEL 88
108#define CLK_TOP_DPI1_SEL 89
109#define CLK_TOP_CCI_SEL 90
110#define CLK_TOP_APLL_SEL 91
111#define CLK_TOP_HDMIPLL_SEL 92
112#define CLK_TOP_NR_CLK 93
113
114/* APMIXED_SYS */
115
116#define CLK_APMIXED_ARMPLL1 1
117#define CLK_APMIXED_ARMPLL2 2
118#define CLK_APMIXED_MAINPLL 3
119#define CLK_APMIXED_UNIVPLL 4
120#define CLK_APMIXED_MMPLL 5
121#define CLK_APMIXED_MSDCPLL 6
122#define CLK_APMIXED_TVDPLL 7
123#define CLK_APMIXED_LVDSPLL 8
124#define CLK_APMIXED_AUDPLL 9
125#define CLK_APMIXED_VDECPLL 10
126#define CLK_APMIXED_NR_CLK 11
127
128/* INFRA_SYS */
129
130#define CLK_INFRA_PMIC_WRAP 1
131#define CLK_INFRA_PMICSPI 2
132#define CLK_INFRA_CCIF1_AP_CTRL 3
133#define CLK_INFRA_CCIF0_AP_CTRL 4
134#define CLK_INFRA_KP 5
135#define CLK_INFRA_CPUM 6
136#define CLK_INFRA_M4U 7
137#define CLK_INFRA_MFGAXI 8
138#define CLK_INFRA_DEVAPC 9
139#define CLK_INFRA_AUDIO 10
140#define CLK_INFRA_MFG_BUS 11
141#define CLK_INFRA_SMI 12
142#define CLK_INFRA_DBGCLK 13
143#define CLK_INFRA_NR_CLK 14
144
145/* PERI_SYS */
146
147#define CLK_PERI_I2C5 1
148#define CLK_PERI_I2C4 2
149#define CLK_PERI_I2C3 3
150#define CLK_PERI_I2C2 4
151#define CLK_PERI_I2C1 5
152#define CLK_PERI_I2C0 6
153#define CLK_PERI_UART3 7
154#define CLK_PERI_UART2 8
155#define CLK_PERI_UART1 9
156#define CLK_PERI_UART0 10
157#define CLK_PERI_IRDA 11
158#define CLK_PERI_NLI 12
159#define CLK_PERI_MD_HIF 13
160#define CLK_PERI_AP_HIF 14
161#define CLK_PERI_MSDC30_3 15
162#define CLK_PERI_MSDC30_2 16
163#define CLK_PERI_MSDC30_1 17
164#define CLK_PERI_MSDC20_2 18
165#define CLK_PERI_MSDC20_1 19
166#define CLK_PERI_AP_DMA 20
167#define CLK_PERI_USB1 21
168#define CLK_PERI_USB0 22
169#define CLK_PERI_PWM 23
170#define CLK_PERI_PWM7 24
171#define CLK_PERI_PWM6 25
172#define CLK_PERI_PWM5 26
173#define CLK_PERI_PWM4 27
174#define CLK_PERI_PWM3 28
175#define CLK_PERI_PWM2 29
176#define CLK_PERI_PWM1 30
177#define CLK_PERI_THERM 31
178#define CLK_PERI_NFI 32
179#define CLK_PERI_USBSLV 33
180#define CLK_PERI_USB1_MCU 34
181#define CLK_PERI_USB0_MCU 35
182#define CLK_PERI_GCPU 36
183#define CLK_PERI_FHCTL 37
184#define CLK_PERI_SPI1 38
185#define CLK_PERI_AUXADC 39
186#define CLK_PERI_PERI_PWRAP 40
187#define CLK_PERI_I2C6 41
188#define CLK_PERI_UART0_SEL 42
189#define CLK_PERI_UART1_SEL 43
190#define CLK_PERI_UART2_SEL 44
191#define CLK_PERI_UART3_SEL 45
192#define CLK_PERI_NR_CLK 46
193
194#endif /* _DT_BINDINGS_CLK_MT8135_H */
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
new file mode 100644
index 000000000000..4ad76ed882ad
--- /dev/null
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -0,0 +1,235 @@
1/*
2 * Copyright (c) 2014 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#ifndef _DT_BINDINGS_CLK_MT8173_H
16#define _DT_BINDINGS_CLK_MT8173_H
17
18/* TOPCKGEN */
19
20#define CLK_TOP_CLKPH_MCK_O 1
21#define CLK_TOP_DPI 2
22#define CLK_TOP_USB_SYSPLL_125M 3
23#define CLK_TOP_HDMITX_DIG_CTS 4
24#define CLK_TOP_ARMCA7PLL_754M 5
25#define CLK_TOP_ARMCA7PLL_502M 6
26#define CLK_TOP_MAIN_H546M 7
27#define CLK_TOP_MAIN_H364M 8
28#define CLK_TOP_MAIN_H218P4M 9
29#define CLK_TOP_MAIN_H156M 10
30#define CLK_TOP_TVDPLL_445P5M 11
31#define CLK_TOP_TVDPLL_594M 12
32#define CLK_TOP_UNIV_624M 13
33#define CLK_TOP_UNIV_416M 14
34#define CLK_TOP_UNIV_249P6M 15
35#define CLK_TOP_UNIV_178P3M 16
36#define CLK_TOP_UNIV_48M 17
37#define CLK_TOP_CLKRTC_EXT 18
38#define CLK_TOP_CLKRTC_INT 19
39#define CLK_TOP_FPC 20
40#define CLK_TOP_HDMITXPLL_D2 21
41#define CLK_TOP_HDMITXPLL_D3 22
42#define CLK_TOP_ARMCA7PLL_D2 23
43#define CLK_TOP_ARMCA7PLL_D3 24
44#define CLK_TOP_APLL1 25
45#define CLK_TOP_APLL2 26
46#define CLK_TOP_DMPLL 27
47#define CLK_TOP_DMPLL_D2 28
48#define CLK_TOP_DMPLL_D4 29
49#define CLK_TOP_DMPLL_D8 30
50#define CLK_TOP_DMPLL_D16 31
51#define CLK_TOP_LVDSPLL_D2 32
52#define CLK_TOP_LVDSPLL_D4 33
53#define CLK_TOP_LVDSPLL_D8 34
54#define CLK_TOP_MMPLL 35
55#define CLK_TOP_MMPLL_D2 36
56#define CLK_TOP_MSDCPLL 37
57#define CLK_TOP_MSDCPLL_D2 38
58#define CLK_TOP_MSDCPLL_D4 39
59#define CLK_TOP_MSDCPLL2 40
60#define CLK_TOP_MSDCPLL2_D2 41
61#define CLK_TOP_MSDCPLL2_D4 42
62#define CLK_TOP_SYSPLL_D2 43
63#define CLK_TOP_SYSPLL1_D2 44
64#define CLK_TOP_SYSPLL1_D4 45
65#define CLK_TOP_SYSPLL1_D8 46
66#define CLK_TOP_SYSPLL1_D16 47
67#define CLK_TOP_SYSPLL_D3 48
68#define CLK_TOP_SYSPLL2_D2 49
69#define CLK_TOP_SYSPLL2_D4 50
70#define CLK_TOP_SYSPLL_D5 51
71#define CLK_TOP_SYSPLL3_D2 52
72#define CLK_TOP_SYSPLL3_D4 53
73#define CLK_TOP_SYSPLL_D7 54
74#define CLK_TOP_SYSPLL4_D2 55
75#define CLK_TOP_SYSPLL4_D4 56
76#define CLK_TOP_TVDPLL 57
77#define CLK_TOP_TVDPLL_D2 58
78#define CLK_TOP_TVDPLL_D4 59
79#define CLK_TOP_TVDPLL_D8 60
80#define CLK_TOP_TVDPLL_D16 61
81#define CLK_TOP_UNIVPLL_D2 62
82#define CLK_TOP_UNIVPLL1_D2 63
83#define CLK_TOP_UNIVPLL1_D4 64
84#define CLK_TOP_UNIVPLL1_D8 65
85#define CLK_TOP_UNIVPLL_D3 66
86#define CLK_TOP_UNIVPLL2_D2 67
87#define CLK_TOP_UNIVPLL2_D4 68
88#define CLK_TOP_UNIVPLL2_D8 69
89#define CLK_TOP_UNIVPLL_D5 70
90#define CLK_TOP_UNIVPLL3_D2 71
91#define CLK_TOP_UNIVPLL3_D4 72
92#define CLK_TOP_UNIVPLL3_D8 73
93#define CLK_TOP_UNIVPLL_D7 74
94#define CLK_TOP_UNIVPLL_D26 75
95#define CLK_TOP_UNIVPLL_D52 76
96#define CLK_TOP_VCODECPLL 77
97#define CLK_TOP_VCODECPLL_370P5 78
98#define CLK_TOP_VENCPLL 79
99#define CLK_TOP_VENCPLL_D2 80
100#define CLK_TOP_VENCPLL_D4 81
101#define CLK_TOP_AXI_SEL 82
102#define CLK_TOP_MEM_SEL 83
103#define CLK_TOP_DDRPHYCFG_SEL 84
104#define CLK_TOP_MM_SEL 85
105#define CLK_TOP_PWM_SEL 86
106#define CLK_TOP_VDEC_SEL 87
107#define CLK_TOP_VENC_SEL 88
108#define CLK_TOP_MFG_SEL 89
109#define CLK_TOP_CAMTG_SEL 90
110#define CLK_TOP_UART_SEL 91
111#define CLK_TOP_SPI_SEL 92
112#define CLK_TOP_USB20_SEL 93
113#define CLK_TOP_USB30_SEL 94
114#define CLK_TOP_MSDC50_0_H_SEL 95
115#define CLK_TOP_MSDC50_0_SEL 96
116#define CLK_TOP_MSDC30_1_SEL 97
117#define CLK_TOP_MSDC30_2_SEL 98
118#define CLK_TOP_MSDC30_3_SEL 99
119#define CLK_TOP_AUDIO_SEL 100
120#define CLK_TOP_AUD_INTBUS_SEL 101
121#define CLK_TOP_PMICSPI_SEL 102
122#define CLK_TOP_SCP_SEL 103
123#define CLK_TOP_ATB_SEL 104
124#define CLK_TOP_VENC_LT_SEL 105
125#define CLK_TOP_DPI0_SEL 106
126#define CLK_TOP_IRDA_SEL 107
127#define CLK_TOP_CCI400_SEL 108
128#define CLK_TOP_AUD_1_SEL 109
129#define CLK_TOP_AUD_2_SEL 110
130#define CLK_TOP_MEM_MFG_IN_SEL 111
131#define CLK_TOP_AXI_MFG_IN_SEL 112
132#define CLK_TOP_SCAM_SEL 113
133#define CLK_TOP_SPINFI_IFR_SEL 114
134#define CLK_TOP_HDMI_SEL 115
135#define CLK_TOP_DPILVDS_SEL 116
136#define CLK_TOP_MSDC50_2_H_SEL 117
137#define CLK_TOP_HDCP_SEL 118
138#define CLK_TOP_HDCP_24M_SEL 119
139#define CLK_TOP_RTC_SEL 120
140#define CLK_TOP_APLL1_DIV0 121
141#define CLK_TOP_APLL1_DIV1 122
142#define CLK_TOP_APLL1_DIV2 123
143#define CLK_TOP_APLL1_DIV3 124
144#define CLK_TOP_APLL1_DIV4 125
145#define CLK_TOP_APLL1_DIV5 126
146#define CLK_TOP_APLL2_DIV0 127
147#define CLK_TOP_APLL2_DIV1 128
148#define CLK_TOP_APLL2_DIV2 129
149#define CLK_TOP_APLL2_DIV3 130
150#define CLK_TOP_APLL2_DIV4 131
151#define CLK_TOP_APLL2_DIV5 132
152#define CLK_TOP_I2S0_M_SEL 133
153#define CLK_TOP_I2S1_M_SEL 134
154#define CLK_TOP_I2S2_M_SEL 135
155#define CLK_TOP_I2S3_M_SEL 136
156#define CLK_TOP_I2S3_B_SEL 137
157#define CLK_TOP_NR_CLK 138
158
159/* APMIXED_SYS */
160
161#define CLK_APMIXED_ARMCA15PLL 1
162#define CLK_APMIXED_ARMCA7PLL 2
163#define CLK_APMIXED_MAINPLL 3
164#define CLK_APMIXED_UNIVPLL 4
165#define CLK_APMIXED_MMPLL 5
166#define CLK_APMIXED_MSDCPLL 6
167#define CLK_APMIXED_VENCPLL 7
168#define CLK_APMIXED_TVDPLL 8
169#define CLK_APMIXED_MPLL 9
170#define CLK_APMIXED_VCODECPLL 10
171#define CLK_APMIXED_APLL1 11
172#define CLK_APMIXED_APLL2 12
173#define CLK_APMIXED_LVDSPLL 13
174#define CLK_APMIXED_MSDCPLL2 14
175#define CLK_APMIXED_NR_CLK 15
176
177/* INFRA_SYS */
178
179#define CLK_INFRA_DBGCLK 1
180#define CLK_INFRA_SMI 2
181#define CLK_INFRA_AUDIO 3
182#define CLK_INFRA_GCE 4
183#define CLK_INFRA_L2C_SRAM 5
184#define CLK_INFRA_M4U 6
185#define CLK_INFRA_CPUM 7
186#define CLK_INFRA_KP 8
187#define CLK_INFRA_CEC 9
188#define CLK_INFRA_PMICSPI 10
189#define CLK_INFRA_PMICWRAP 11
190#define CLK_INFRA_NR_CLK 12
191
192/* PERI_SYS */
193
194#define CLK_PERI_NFI 1
195#define CLK_PERI_THERM 2
196#define CLK_PERI_PWM1 3
197#define CLK_PERI_PWM2 4
198#define CLK_PERI_PWM3 5
199#define CLK_PERI_PWM4 6
200#define CLK_PERI_PWM5 7
201#define CLK_PERI_PWM6 8
202#define CLK_PERI_PWM7 9
203#define CLK_PERI_PWM 10
204#define CLK_PERI_USB0 11
205#define CLK_PERI_USB1 12
206#define CLK_PERI_AP_DMA 13
207#define CLK_PERI_MSDC30_0 14
208#define CLK_PERI_MSDC30_1 15
209#define CLK_PERI_MSDC30_2 16
210#define CLK_PERI_MSDC30_3 17
211#define CLK_PERI_NLI_ARB 18
212#define CLK_PERI_IRDA 19
213#define CLK_PERI_UART0 20
214#define CLK_PERI_UART1 21
215#define CLK_PERI_UART2 22
216#define CLK_PERI_UART3 23
217#define CLK_PERI_I2C0 24
218#define CLK_PERI_I2C1 25
219#define CLK_PERI_I2C2 26
220#define CLK_PERI_I2C3 27
221#define CLK_PERI_I2C4 28
222#define CLK_PERI_AUXADC 29
223#define CLK_PERI_SPI0 30
224#define CLK_PERI_I2C5 31
225#define CLK_PERI_NFIECC 32
226#define CLK_PERI_SPI 33
227#define CLK_PERI_IRRX 34
228#define CLK_PERI_I2C6 35
229#define CLK_PERI_UART0_SEL 36
230#define CLK_PERI_UART1_SEL 37
231#define CLK_PERI_UART2_SEL 38
232#define CLK_PERI_UART3_SEL 39
233#define CLK_PERI_NR_CLK 40
234
235#endif /* _DT_BINDINGS_CLK_MT8173_H */
diff --git a/include/dt-bindings/reset-controller/mt8135-resets.h b/include/dt-bindings/reset-controller/mt8135-resets.h
new file mode 100644
index 000000000000..1fb629508db2
--- /dev/null
+++ b/include/dt-bindings/reset-controller/mt8135-resets.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright (c) 2014 MediaTek Inc.
3 * Author: Flora Fu, MediaTek
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#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8135
16#define _DT_BINDINGS_RESET_CONTROLLER_MT8135
17
18/* INFRACFG resets */
19#define MT8135_INFRA_EMI_REG_RST 0
20#define MT8135_INFRA_DRAMC0_A0_RST 1
21#define MT8135_INFRA_CCIF0_RST 2
22#define MT8135_INFRA_APCIRQ_EINT_RST 3
23#define MT8135_INFRA_APXGPT_RST 4
24#define MT8135_INFRA_SCPSYS_RST 5
25#define MT8135_INFRA_CCIF1_RST 6
26#define MT8135_INFRA_PMIC_WRAP_RST 7
27#define MT8135_INFRA_KP_RST 8
28#define MT8135_INFRA_EMI_RST 32
29#define MT8135_INFRA_DRAMC0_RST 34
30#define MT8135_INFRA_SMI_RST 35
31#define MT8135_INFRA_M4U_RST 36
32
33/* PERICFG resets */
34#define MT8135_PERI_UART0_SW_RST 0
35#define MT8135_PERI_UART1_SW_RST 1
36#define MT8135_PERI_UART2_SW_RST 2
37#define MT8135_PERI_UART3_SW_RST 3
38#define MT8135_PERI_IRDA_SW_RST 4
39#define MT8135_PERI_PTP_SW_RST 5
40#define MT8135_PERI_AP_HIF_SW_RST 6
41#define MT8135_PERI_GPCU_SW_RST 7
42#define MT8135_PERI_MD_HIF_SW_RST 8
43#define MT8135_PERI_NLI_SW_RST 9
44#define MT8135_PERI_AUXADC_SW_RST 10
45#define MT8135_PERI_DMA_SW_RST 11
46#define MT8135_PERI_NFI_SW_RST 14
47#define MT8135_PERI_PWM_SW_RST 15
48#define MT8135_PERI_THERM_SW_RST 16
49#define MT8135_PERI_MSDC0_SW_RST 17
50#define MT8135_PERI_MSDC1_SW_RST 18
51#define MT8135_PERI_MSDC2_SW_RST 19
52#define MT8135_PERI_MSDC3_SW_RST 20
53#define MT8135_PERI_I2C0_SW_RST 22
54#define MT8135_PERI_I2C1_SW_RST 23
55#define MT8135_PERI_I2C2_SW_RST 24
56#define MT8135_PERI_I2C3_SW_RST 25
57#define MT8135_PERI_I2C4_SW_RST 26
58#define MT8135_PERI_I2C5_SW_RST 27
59#define MT8135_PERI_I2C6_SW_RST 28
60#define MT8135_PERI_USB_SW_RST 29
61#define MT8135_PERI_SPI1_SW_RST 33
62#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34
63
64#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */
diff --git a/include/dt-bindings/reset-controller/mt8173-resets.h b/include/dt-bindings/reset-controller/mt8173-resets.h
new file mode 100644
index 000000000000..9464b37cf68c
--- /dev/null
+++ b/include/dt-bindings/reset-controller/mt8173-resets.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) 2014 MediaTek Inc.
3 * Author: Flora Fu, MediaTek
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#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8173
16#define _DT_BINDINGS_RESET_CONTROLLER_MT8173
17
18/* INFRACFG resets */
19#define MT8173_INFRA_EMI_REG_RST 0
20#define MT8173_INFRA_DRAMC0_A0_RST 1
21#define MT8173_INFRA_APCIRQ_EINT_RST 3
22#define MT8173_INFRA_APXGPT_RST 4
23#define MT8173_INFRA_SCPSYS_RST 5
24#define MT8173_INFRA_KP_RST 6
25#define MT8173_INFRA_PMIC_WRAP_RST 7
26#define MT8173_INFRA_MPIP_RST 8
27#define MT8173_INFRA_CEC_RST 9
28#define MT8173_INFRA_EMI_RST 32
29#define MT8173_INFRA_DRAMC0_RST 34
30#define MT8173_INFRA_APMIXEDSYS_RST 35
31#define MT8173_INFRA_MIPI_DSI_RST 36
32#define MT8173_INFRA_TRNG_RST 37
33#define MT8173_INFRA_SYSIRQ_RST 38
34#define MT8173_INFRA_MIPI_CSI_RST 39
35#define MT8173_INFRA_GCE_FAXI_RST 40
36#define MT8173_INFRA_MMIOMMURST 47
37
38
39/* PERICFG resets */
40#define MT8173_PERI_UART0_SW_RST 0
41#define MT8173_PERI_UART1_SW_RST 1
42#define MT8173_PERI_UART2_SW_RST 2
43#define MT8173_PERI_UART3_SW_RST 3
44#define MT8173_PERI_IRRX_SW_RST 4
45#define MT8173_PERI_PWM_SW_RST 8
46#define MT8173_PERI_AUXADC_SW_RST 10
47#define MT8173_PERI_DMA_SW_RST 11
48#define MT8173_PERI_I2C6_SW_RST 13
49#define MT8173_PERI_NFI_SW_RST 14
50#define MT8173_PERI_THERM_SW_RST 16
51#define MT8173_PERI_MSDC2_SW_RST 17
52#define MT8173_PERI_MSDC3_SW_RST 18
53#define MT8173_PERI_MSDC0_SW_RST 19
54#define MT8173_PERI_MSDC1_SW_RST 20
55#define MT8173_PERI_I2C0_SW_RST 22
56#define MT8173_PERI_I2C1_SW_RST 23
57#define MT8173_PERI_I2C2_SW_RST 24
58#define MT8173_PERI_I2C3_SW_RST 25
59#define MT8173_PERI_I2C4_SW_RST 26
60#define MT8173_PERI_HDMI_SW_RST 29
61#define MT8173_PERI_SPI0_SW_RST 33
62
63#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8173 */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index df695313f975..4a943d13625b 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -209,7 +209,7 @@ struct clk_ops {
209struct clk_init_data { 209struct clk_init_data {
210 const char *name; 210 const char *name;
211 const struct clk_ops *ops; 211 const struct clk_ops *ops;
212 const char **parent_names; 212 const char * const *parent_names;
213 u8 num_parents; 213 u8 num_parents;
214 unsigned long flags; 214 unsigned long flags;
215}; 215};
@@ -426,12 +426,14 @@ extern const struct clk_ops clk_mux_ops;
426extern const struct clk_ops clk_mux_ro_ops; 426extern const struct clk_ops clk_mux_ro_ops;
427 427
428struct clk *clk_register_mux(struct device *dev, const char *name, 428struct clk *clk_register_mux(struct device *dev, const char *name,
429 const char **parent_names, u8 num_parents, unsigned long flags, 429 const char * const *parent_names, u8 num_parents,
430 unsigned long flags,
430 void __iomem *reg, u8 shift, u8 width, 431 void __iomem *reg, u8 shift, u8 width,
431 u8 clk_mux_flags, spinlock_t *lock); 432 u8 clk_mux_flags, spinlock_t *lock);
432 433
433struct clk *clk_register_mux_table(struct device *dev, const char *name, 434struct clk *clk_register_mux_table(struct device *dev, const char *name,
434 const char **parent_names, u8 num_parents, unsigned long flags, 435 const char * const *parent_names, u8 num_parents,
436 unsigned long flags,
435 void __iomem *reg, u8 shift, u32 mask, 437 void __iomem *reg, u8 shift, u32 mask,
436 u8 clk_mux_flags, u32 *table, spinlock_t *lock); 438 u8 clk_mux_flags, u32 *table, spinlock_t *lock);
437 439
@@ -457,7 +459,7 @@ struct clk_fixed_factor {
457 unsigned int div; 459 unsigned int div;
458}; 460};
459 461
460extern struct clk_ops clk_fixed_factor_ops; 462extern const struct clk_ops clk_fixed_factor_ops;
461struct clk *clk_register_fixed_factor(struct device *dev, const char *name, 463struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
462 const char *parent_name, unsigned long flags, 464 const char *parent_name, unsigned long flags,
463 unsigned int mult, unsigned int div); 465 unsigned int mult, unsigned int div);
@@ -518,7 +520,7 @@ struct clk_composite {
518}; 520};
519 521
520struct clk *clk_register_composite(struct device *dev, const char *name, 522struct clk *clk_register_composite(struct device *dev, const char *name,
521 const char **parent_names, int num_parents, 523 const char * const *parent_names, int num_parents,
522 struct clk_hw *mux_hw, const struct clk_ops *mux_ops, 524 struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
523 struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 525 struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
524 struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 526 struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
@@ -624,6 +626,8 @@ struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
624 void *data); 626 void *data);
625struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data); 627struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data);
626int of_clk_get_parent_count(struct device_node *np); 628int of_clk_get_parent_count(struct device_node *np);
629int of_clk_parent_fill(struct device_node *np, const char **parents,
630 unsigned int size);
627const char *of_clk_get_parent_name(struct device_node *np, int index); 631const char *of_clk_get_parent_name(struct device_node *np, int index);
628 632
629void of_clk_init(const struct of_device_id *matches); 633void of_clk_init(const struct of_device_id *matches);