diff options
author | Michael Turquette <mturquette@baylibre.com> | 2015-06-17 16:20:43 -0400 |
---|---|---|
committer | Michael Turquette <mturquette@baylibre.com> | 2015-06-17 16:20:43 -0400 |
commit | b2d8bc21ce68b65d7cbaa5c929aac1630acf69fc (patch) | |
tree | 682862a4cf6a3fa701d5c19a95303f10754c8ce7 | |
parent | d4a4f75cd8f29cd9464a5a32e9224a91571d6649 (diff) | |
parent | 46965688acd0f9599a3c3ecce82109b3b24153a9 (diff) |
Merge remote-tracking branch 'clk/clk-next' into clk-next
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 | ||
231 | See the basic clock types in drivers/clk/clk-*.c for examples. | 231 | See 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 | |||
235 | For platforms with many clocks (often numbering into the hundreds) it | ||
236 | may be desirable to statically initialize some clock data. This | ||
237 | presents a problem since the definition of struct clk should be hidden | ||
238 | from everyone except for the clock core in drivers/clk/clk.c. | ||
239 | |||
240 | To get around this problem struct clk's definition is exposed in | ||
241 | include/linux/clk-private.h along with some macros for more easily | ||
242 | initializing instances of the basic clock types. These clocks must | ||
243 | still be initialized with the common clock framework via a call to | ||
244 | __clk_init. | ||
245 | |||
246 | clk-private.h must NEVER be included by code which implements struct | ||
247 | clk_ops callbacks, nor must it be included by any logic which pokes | ||
248 | around inside of struct clk at run-time. To do so is a layering | ||
249 | violation. | ||
250 | |||
251 | To better enforce this policy, always follow this simple rule: any | ||
252 | statically initialized clock data MUST be defined in a separate file | ||
253 | from the logic that implements its ops. Basically separate the logic | ||
254 | from the data and all is well. | ||
255 | |||
256 | Part 6 - Disabling clock gating of unused clocks | ||
257 | 234 | ||
258 | Sometimes during development it can be useful to be able to bypass the | 235 | Sometimes during development it can be useful to be able to bypass the |
259 | default disabling of unused clocks. For example, if drivers aren't enabling | 236 | default disabling of unused clocks. For example, if drivers aren't enabling |
@@ -264,7 +241,7 @@ are sorted out. | |||
264 | To bypass this disabling, include "clk_ignore_unused" in the bootargs to the | 241 | To bypass this disabling, include "clk_ignore_unused" in the bootargs to the |
265 | kernel. | 242 | kernel. |
266 | 243 | ||
267 | Part 7 - Locking | 244 | Part 6 - Locking |
268 | 245 | ||
269 | The common clock framework uses two global locks, the prepare lock and the | 246 | The common clock framework uses two global locks, the prepare lock and the |
270 | enable lock. | 247 | enable 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 @@ | |||
1 | Mediatek apmixedsys controller | ||
2 | ============================== | ||
3 | |||
4 | The Mediatek apmixedsys controller provides the PLLs to the system. | ||
5 | |||
6 | Required Properties: | ||
7 | |||
8 | - compatible: Should be: | ||
9 | - "mediatek,mt8135-apmixedsys" | ||
10 | - "mediatek,mt8173-apmixedsys" | ||
11 | - #clock-cells: Must be 1 | ||
12 | |||
13 | The apmixedsys controller uses the common clk binding from | ||
14 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
15 | The available clocks are defined in dt-bindings/clock/mt*-clk.h. | ||
16 | |||
17 | Example: | ||
18 | |||
19 | apmixedsys: 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 @@ | |||
1 | Mediatek infracfg controller | ||
2 | ============================ | ||
3 | |||
4 | The Mediatek infracfg controller provides various clocks and reset | ||
5 | outputs to the system. | ||
6 | |||
7 | Required 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 | |||
15 | The infracfg controller uses the common clk binding from | ||
16 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
17 | The available clocks are defined in dt-bindings/clock/mt*-clk.h. | ||
18 | Also it uses the common reset controller binding from | ||
19 | Documentation/devicetree/bindings/reset/reset.txt. | ||
20 | The available reset outputs are defined in | ||
21 | dt-bindings/reset-controller/mt*-resets.h | ||
22 | |||
23 | Example: | ||
24 | |||
25 | infracfg: 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 @@ | |||
1 | Mediatek pericfg controller | ||
2 | =========================== | ||
3 | |||
4 | The Mediatek pericfg controller provides various clocks and reset | ||
5 | outputs to the system. | ||
6 | |||
7 | Required 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 | |||
15 | The pericfg controller uses the common clk binding from | ||
16 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
17 | The available clocks are defined in dt-bindings/clock/mt*-clk.h. | ||
18 | Also it uses the common reset controller binding from | ||
19 | Documentation/devicetree/bindings/reset/reset.txt. | ||
20 | The available reset outputs are defined in | ||
21 | dt-bindings/reset-controller/mt*-resets.h | ||
22 | |||
23 | Example: | ||
24 | |||
25 | pericfg: 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 @@ | |||
1 | Mediatek topckgen controller | ||
2 | ============================ | ||
3 | |||
4 | The Mediatek topckgen controller provides various clocks to the system. | ||
5 | |||
6 | Required Properties: | ||
7 | |||
8 | - compatible: Should be: | ||
9 | - "mediatek,mt8135-topckgen" | ||
10 | - "mediatek,mt8173-topckgen" | ||
11 | - #clock-cells: Must be 1 | ||
12 | |||
13 | The topckgen controller uses the common clk binding from | ||
14 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
15 | The available clocks are defined in dt-bindings/clock/mt*-clk.h. | ||
16 | |||
17 | Example: | ||
18 | |||
19 | topckgen: 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 | |||
3 | The Amlogic Meson8b clock controller generates and supplies clock to various | ||
4 | controllers within the SoC. | ||
5 | |||
6 | Required 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 | |||
17 | Each clock is assigned an identifier and client nodes can use this identifier | ||
18 | to specify the clock which they consume. All available clocks are defined as | ||
19 | preprocessor macros in the dt-bindings/clock/meson8b-clkc.h header and can be | ||
20 | used in device tree sources. | ||
21 | |||
22 | Example: 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 | |||
31 | Example: 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 | |||
138 | and clock frequencies. Such a configuration can be specified in a device tree | 138 | and clock frequencies. Such a configuration can be specified in a device tree |
139 | node through assigned-clocks, assigned-clock-parents and assigned-clock-rates | 139 | node through assigned-clocks, assigned-clock-parents and assigned-clock-rates |
140 | properties. The assigned-clock-parents property should contain a list of parent | 140 | properties. The assigned-clock-parents property should contain a list of parent |
141 | clocks in form of phandle and clock specifier pairs, the assigned-clock-parents | 141 | clocks in the form of a phandle and clock specifier pair and the |
142 | property the list of assigned clock frequency values - corresponding to clocks | 142 | assigned-clock-rates property should contain a list of frequencies in Hz. Both |
143 | listed in the assigned-clocks property. | 143 | these properties should correspond to the clocks listed in the assigned-clocks |
144 | property. | ||
144 | 145 | ||
145 | To skip setting parent or rate of a clock its corresponding entry should be | 146 | To skip setting parent or rate of a clock its corresponding entry should be |
146 | set to 0, or can be omitted if it is not followed by any non-zero entry. | 147 | set 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 | |||
3 | Required 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 | |||
9 | The clock consumer should specify the desired clock by having the clock | ||
10 | ID in its "clocks" phandle cell. | ||
11 | The ID list atlas7_clks defined in drivers/clk/sirf/clk-atlas7.c | ||
12 | |||
13 | The reset consumer should specify the desired reset by having the reset | ||
14 | ID in its "reset" phandle cell. | ||
15 | The ID list atlas7_reset_unit defined in drivers/clk/sirf/clk-atlas7.c | ||
16 | |||
17 | Examples: Clock and reset controller node: | ||
18 | |||
19 | car: clock-controller@18620000 { | ||
20 | compatible = "sirf,atlas7-car"; | ||
21 | reg = <0x18620000 0x1000>; | ||
22 | #clock-cells = <1>; | ||
23 | #reset-cells = <1>; | ||
24 | }; | ||
25 | |||
26 | Examples: Consumers using clock or reset: | ||
27 | |||
28 | timer@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 | |||
40 | uart1: 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 | |||
49 | vpp@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 | ||
53 | Example of consumer: | 53 | Example of consumer: |
54 | 54 | ||
55 | uart@e1020000 { | 55 | serial@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 | |||
3 | The PXA1928 clock subsystem generates and supplies clock to various | ||
4 | controllers within the PXA1928 SoC. The PXA1928 contains 3 clock controller | ||
5 | blocks called APMU, MPMU, and APBC roughly corresponding to internal buses. | ||
6 | |||
7 | Required 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 | |||
18 | Each clock is assigned an identifier and client nodes use the clock controller | ||
19 | phandle and this identifier to specify the clock which they consume. | ||
20 | |||
21 | All 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 | |||
19 | 9 pex1 PCIe Cntrl 1 | 19 | 9 pex1 PCIe Cntrl 1 |
20 | 15 sata0 SATA Host 0 | 20 | 15 sata0 SATA Host 0 |
21 | 17 sdio SDHCI Host | 21 | 17 sdio SDHCI Host |
22 | 23 crypto CESA (crypto engine) | ||
22 | 25 tdm Time Division Mplx | 23 | 25 tdm Time Division Mplx |
23 | 28 ddr DDR Cntrl | 24 | 28 ddr DDR Cntrl |
24 | 30 sata1 SATA Host 0 | 25 | 30 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 @@ | |||
1 | Binding for TO CDCE925 programmable I2C clock synthesizers. | ||
2 | |||
3 | Reference | ||
4 | This 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 | |||
9 | The driver provides clock sources for each output Y1 through Y5. | ||
10 | |||
11 | Required 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 | |||
17 | Optional properties: | ||
18 | - xtal-load-pf: Crystal load-capacitor value to fine-tune performance on a | ||
19 | board, or to compensate for external influences. | ||
20 | |||
21 | For both PLL1 and PLL2 an optional child node can be used to specify spread | ||
22 | spectrum 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 | |||
29 | Example: | ||
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 | ||
81 | config 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 | |||
81 | config COMMON_CLK_S2MPS11 | 98 | config 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 | ||
170 | source "drivers/clk/bcm/Kconfig" | ||
171 | source "drivers/clk/hisilicon/Kconfig" | ||
153 | source "drivers/clk/qcom/Kconfig" | 172 | source "drivers/clk/qcom/Kconfig" |
154 | 173 | ||
155 | endmenu | 174 | endmenu |
156 | 175 | ||
157 | source "drivers/clk/bcm/Kconfig" | ||
158 | source "drivers/clk/mvebu/Kconfig" | 176 | source "drivers/clk/mvebu/Kconfig" |
159 | 177 | ||
160 | source "drivers/clk/samsung/Kconfig" | 178 | source "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 | |||
38 | obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o | 38 | obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o |
39 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o | 39 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o |
40 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o | 40 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o |
41 | obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o | ||
41 | obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o | 42 | obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o |
42 | obj-$(CONFIG_ARCH_U300) += clk-u300.o | 43 | obj-$(CONFIG_ARCH_U300) += clk-u300.o |
43 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o | 44 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o |
@@ -47,14 +48,14 @@ obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o | |||
47 | obj-$(CONFIG_COMMON_CLK_AT91) += at91/ | 48 | obj-$(CONFIG_COMMON_CLK_AT91) += at91/ |
48 | obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm/ | 49 | obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm/ |
49 | obj-$(CONFIG_ARCH_BERLIN) += berlin/ | 50 | obj-$(CONFIG_ARCH_BERLIN) += berlin/ |
50 | obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/ | 51 | obj-$(CONFIG_ARCH_HISI) += hisilicon/ |
51 | obj-$(CONFIG_ARCH_HIP04) += hisilicon/ | ||
52 | obj-$(CONFIG_ARCH_HIX5HD2) += hisilicon/ | ||
53 | obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ | 52 | obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ |
53 | obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ | ||
54 | ifeq ($(CONFIG_COMMON_CLK), y) | 54 | ifeq ($(CONFIG_COMMON_CLK), y) |
55 | obj-$(CONFIG_ARCH_MMP) += mmp/ | 55 | obj-$(CONFIG_ARCH_MMP) += mmp/ |
56 | endif | 56 | endif |
57 | obj-$(CONFIG_PLAT_ORION) += mvebu/ | 57 | obj-$(CONFIG_PLAT_ORION) += mvebu/ |
58 | obj-$(CONFIG_ARCH_MESON) += meson/ | ||
58 | obj-$(CONFIG_ARCH_MXS) += mxs/ | 59 | obj-$(CONFIG_ARCH_MXS) += mxs/ |
59 | obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ | 60 | obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ |
60 | obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ | 61 | obj-$(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 | ||
156 | static struct irq_domain_ops pmc_irq_ops = { | 156 | static 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 | ||
24 | LIST_HEAD(ccu_list); /* The list of set up CCUs */ | ||
25 | |||
26 | /* Validity checking */ | 24 | /* Validity checking */ |
27 | 25 | ||
28 | static bool ccu_data_offsets_valid(struct ccu_data *ccu) | 26 | static 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" | |
29 | struct 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 | ||
37 | struct berlin2_pll { | 30 | struct 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 | ||
97 | static const char *cdce706_clkin_name[] = { | 97 | static 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 | ||
105 | static const char *cdce706_divider_parent_name[] = { | 105 | static 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 | ||
667 | static int cdce706_remove(struct i2c_client *client) | 667 | static 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 | ||
39 | struct clk_cdce925_chip; | ||
40 | |||
41 | struct 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 | |||
50 | struct 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 | |||
59 | struct 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 | |||
70 | static 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 | |||
78 | static 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 | |||
87 | static 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 | |||
124 | static 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 | |||
133 | static 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))) */ | ||
162 | static 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 */ | ||
178 | static 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 */ | ||
195 | static 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 | |||
249 | static 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 | |||
258 | static 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 | |||
267 | static 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 | |||
291 | static 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 | |||
309 | static 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 | |||
318 | static 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 | |||
326 | static 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 | |||
336 | static 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 | |||
353 | static 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 | |||
396 | static 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 | |||
413 | static 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 | |||
423 | static 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 | |||
432 | static 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 | |||
449 | static 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 | |||
460 | static 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 | |||
470 | static 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 | |||
479 | static 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 | |||
490 | static 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 | |||
517 | static 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. */ | ||
561 | static struct regmap_bus regmap_cdce925_bus = { | ||
562 | .write = cdce925_regmap_i2c_write, | ||
563 | .read = cdce925_regmap_i2c_read, | ||
564 | }; | ||
565 | |||
566 | static 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, ®map_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 | |||
717 | error: | ||
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 | |||
725 | static const struct i2c_device_id cdce925_id[] = { | ||
726 | { "cdce925", 0 }, | ||
727 | { } | ||
728 | }; | ||
729 | MODULE_DEVICE_TABLE(i2c, cdce925_id); | ||
730 | |||
731 | static const struct of_device_id clk_cdce925_of_match[] = { | ||
732 | { .compatible = "ti,cdce925" }, | ||
733 | { }, | ||
734 | }; | ||
735 | MODULE_DEVICE_TABLE(of, clk_cdce925_of_match); | ||
736 | |||
737 | static 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 | }; | ||
745 | module_i2c_driver(cdce925_driver); | ||
746 | |||
747 | MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>"); | ||
748 | MODULE_DESCRIPTION("cdce925 driver"); | ||
749 | MODULE_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 | ||
190 | struct clk *clk_register_composite(struct device *dev, const char *name, | 190 | struct 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 | */ |
130 | int of_clk_set_defaults(struct device_node *node, bool clk_supplier) | 131 | int 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, | |||
55 | static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate, | 55 | static 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 | ||
61 | struct clk_ops clk_fixed_factor_ops = { | 67 | const 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 | */ |
192 | void __init of_gpio_gate_clk_setup(struct device_node *node) | 192 | static 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 | } |
206 | EXPORT_SYMBOL_GPL(of_gpio_gate_clk_setup); | ||
207 | CLK_OF_DECLARE(gpio_gate_clk, "gpio-gate-clock", of_gpio_gate_clk_setup); | 206 | CLK_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 | ||
83 | static const char const *cpu_parents[] = { "cpu_clk_div", "osc_33m_clk", }; | 83 | static const char * const cpu_parents[] = { "cpu_clk_div", "osc_33m_clk", }; |
84 | static const char const *ahb_parents[] = { "ahb_clk_div", "osc_33m_clk", }; | 84 | static const char * const ahb_parents[] = { "ahb_clk_div", "osc_33m_clk", }; |
85 | static const char const *dc_parents[] = { "dc_clk_div", "osc_33m_clk", }; | 85 | static const char * const dc_parents[] = { "dc_clk_div", "osc_33m_clk", }; |
86 | 86 | ||
87 | void __init ls1x_clk_init(void) | 87 | void __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 | |||
34 | struct max_gen_clk { | 36 | struct 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 | ||
18 | void __init moxart_of_pll_clk_init(struct device_node *node) | 18 | static 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) | |||
53 | CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock", | 53 | CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock", |
54 | moxart_of_pll_clk_init); | 54 | moxart_of_pll_clk_init); |
55 | 55 | ||
56 | void __init moxart_of_apb_clk_init(struct device_node *node) | 56 | static 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 = { | |||
114 | EXPORT_SYMBOL_GPL(clk_mux_ro_ops); | 114 | EXPORT_SYMBOL_GPL(clk_mux_ro_ops); |
115 | 115 | ||
116 | struct clk *clk_register_mux_table(struct device *dev, const char *name, | 116 | struct 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, | |||
166 | EXPORT_SYMBOL_GPL(clk_register_mux_table); | 167 | EXPORT_SYMBOL_GPL(clk_register_mux_table); |
167 | 168 | ||
168 | struct clk *clk_register_mux(struct device *dev, const char *name, | 169 | struct 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 | ||
43 | static DEFINE_SPINLOCK(clk_lock); | 43 | static DEFINE_SPINLOCK(clk_lock); |
44 | 44 | ||
45 | static inline u32 xgene_clk_read(void *csr) | 45 | static inline u32 xgene_clk_read(void __iomem *csr) |
46 | { | 46 | { |
47 | return readl_relaxed(csr); | 47 | return readl_relaxed(csr); |
48 | } | 48 | } |
49 | 49 | ||
50 | static inline void xgene_clk_write(u32 data, void *csr) | 50 | static 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 | ||
122 | const struct clk_ops xgene_clk_pll_ops = { | 122 | static 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, ®, |
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, ®, |
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 | ||
389 | const struct clk_ops xgene_clk_ops = { | 391 | static 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); | |||
37 | static HLIST_HEAD(clk_orphan_list); | 38 | static HLIST_HEAD(clk_orphan_list); |
38 | static LIST_HEAD(clk_notifier_list); | 39 | static LIST_HEAD(clk_notifier_list); |
39 | 40 | ||
40 | static long clk_core_get_accuracy(struct clk_core *clk); | ||
41 | static unsigned long clk_core_get_rate(struct clk_core *clk); | ||
42 | static int clk_core_get_phase(struct clk_core *clk); | ||
43 | static bool clk_core_is_prepared(struct clk_core *clk); | ||
44 | static bool clk_core_is_enabled(struct clk_core *clk); | ||
45 | static struct clk_core *clk_core_lookup(const char *name); | ||
46 | |||
47 | /*** private data structures ***/ | 41 | /*** private data structures ***/ |
48 | 42 | ||
49 | struct clk_core { | 43 | struct 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 ***/ | 142 | static bool clk_core_is_prepared(struct clk_core *core) |
149 | |||
150 | #ifdef CONFIG_DEBUG_FS | ||
151 | #include <linux/debugfs.h> | ||
152 | |||
153 | static struct dentry *rootdir; | ||
154 | static int inited = 0; | ||
155 | static DEFINE_MUTEX(clk_debug_lock); | ||
156 | static HLIST_HEAD(clk_debug_list); | ||
157 | |||
158 | static struct hlist_head *all_lists[] = { | ||
159 | &clk_root_list, | ||
160 | &clk_orphan_list, | ||
161 | NULL, | ||
162 | }; | ||
163 | |||
164 | static struct hlist_head *orphan_list[] = { | ||
165 | &clk_orphan_list, | ||
166 | NULL, | ||
167 | }; | ||
168 | |||
169 | static 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 | |||
182 | static 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 | |||
196 | static 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 | |||
216 | static 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 | |
221 | static 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 | |||
228 | static 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 | |||
241 | static 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 | |||
258 | static 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 | |||
284 | static int clk_dump_open(struct inode *inode, struct file *file) | ||
285 | { | ||
286 | return single_open(file, clk_dump, inode->i_private); | ||
287 | } | ||
288 | |||
289 | static 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 | |||
296 | static 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 | |||
356 | err_out: | ||
357 | debugfs_remove_recursive(clk->dentry); | ||
358 | clk->dentry = NULL; | ||
359 | out: | ||
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 | */ | ||
371 | static 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); | ||
382 | unlock: | ||
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 | */ | ||
396 | static 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 | |||
405 | struct 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 | } |
416 | EXPORT_SYMBOL_GPL(clk_debugfs_add_file); | ||
417 | 153 | ||
418 | /** | 154 | static 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 | */ | ||
430 | static 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 | } |
469 | late_initcall(clk_debug_init); | ||
470 | #else | ||
471 | static inline int clk_debug_register(struct clk_core *clk) { return 0; } | ||
472 | static inline void clk_debug_reparent(struct clk_core *clk, | ||
473 | struct clk_core *new_parent) | ||
474 | { | ||
475 | } | ||
476 | static inline void clk_debug_unregister(struct clk_core *clk) | ||
477 | { | ||
478 | } | ||
479 | #endif | ||
480 | 165 | ||
481 | /* caller must hold prepare_lock */ | 166 | static void clk_unprepare_unused_subtree(struct clk_core *core) |
482 | static 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 */ | 191 | static void clk_disable_unused_subtree(struct clk_core *core) |
508 | static 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 | ||
540 | unlock_out: | 223 | unlock_out: |
@@ -551,7 +234,7 @@ __setup("clk_ignore_unused", clk_ignore_unused_setup); | |||
551 | 234 | ||
552 | static int clk_disable_unused(void) | 235 | static 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 | } |
609 | EXPORT_SYMBOL_GPL(__clk_get_parent); | 292 | EXPORT_SYMBOL_GPL(__clk_get_parent); |
610 | 293 | ||
611 | static struct clk_core *clk_core_get_parent_by_index(struct clk_core *clk, | 294 | static 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 | |||
312 | static 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 | |||
337 | static 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 | ||
625 | struct clk *clk_get_parent_by_index(struct clk *clk, u8 index) | 351 | struct 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 | ||
643 | static unsigned long clk_core_get_rate_nolock(struct clk_core *clk) | 369 | static 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 | ||
660 | out: | 386 | out: |
@@ -670,12 +396,12 @@ unsigned long __clk_get_rate(struct clk *clk) | |||
670 | } | 396 | } |
671 | EXPORT_SYMBOL_GPL(__clk_get_rate); | 397 | EXPORT_SYMBOL_GPL(__clk_get_rate); |
672 | 398 | ||
673 | static unsigned long __clk_get_accuracy(struct clk_core *clk) | 399 | static 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 | ||
681 | unsigned long __clk_get_flags(struct clk *clk) | 407 | unsigned long __clk_get_flags(struct clk *clk) |
@@ -684,27 +410,6 @@ unsigned long __clk_get_flags(struct clk *clk) | |||
684 | } | 410 | } |
685 | EXPORT_SYMBOL_GPL(__clk_get_flags); | 411 | EXPORT_SYMBOL_GPL(__clk_get_flags); |
686 | 412 | ||
687 | static 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); | ||
704 | out: | ||
705 | return !!ret; | ||
706 | } | ||
707 | |||
708 | bool __clk_is_prepared(struct clk *clk) | 413 | bool __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 | ||
716 | static 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); | ||
733 | out: | ||
734 | return !!ret; | ||
735 | } | ||
736 | |||
737 | bool __clk_is_enabled(struct clk *clk) | 421 | bool __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 | } |
744 | EXPORT_SYMBOL_GPL(__clk_is_enabled); | 428 | EXPORT_SYMBOL_GPL(__clk_is_enabled); |
745 | 429 | ||
746 | static 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 | |||
764 | static 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 | |||
789 | static bool mux_is_better_rate(unsigned long rate, unsigned long now, | 430 | static 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 | ||
856 | static void clk_core_get_boundaries(struct clk_core *clk, | 497 | static 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 | ||
904 | static void clk_core_unprepare(struct clk_core *clk) | 545 | static 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 | } |
946 | EXPORT_SYMBOL_GPL(clk_unprepare); | 589 | EXPORT_SYMBOL_GPL(clk_unprepare); |
947 | 590 | ||
948 | static int clk_core_prepare(struct clk_core *clk) | 591 | static 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 | } |
1003 | EXPORT_SYMBOL_GPL(clk_prepare); | 648 | EXPORT_SYMBOL_GPL(clk_prepare); |
1004 | 649 | ||
1005 | static void clk_core_disable(struct clk_core *clk) | 650 | static 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 | |||
1026 | static 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 | } |
1057 | EXPORT_SYMBOL_GPL(clk_disable); | 696 | EXPORT_SYMBOL_GPL(clk_disable); |
1058 | 697 | ||
1059 | static int clk_core_enable(struct clk_core *clk) | 698 | static 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 | ||
1092 | static 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 | } |
1124 | EXPORT_SYMBOL_GPL(clk_enable); | 760 | EXPORT_SYMBOL_GPL(clk_enable); |
1125 | 761 | ||
1126 | static unsigned long clk_core_round_rate_nolock(struct clk_core *clk, | 762 | static 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 | */ |
1168 | unsigned long __clk_determine_rate(struct clk_hw *hw, | 803 | unsigned 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 | */ |
1187 | unsigned long __clk_round_rate(struct clk *clk, unsigned long rate) | 822 | unsigned 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 | */ |
1239 | static int __clk_notify(struct clk_core *clk, unsigned long msg, | 874 | static 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 | */ |
1271 | static void __clk_recalc_accuracies(struct clk_core *clk) | 904 | static 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 | ||
1291 | static long clk_core_get_accuracy(struct clk_core *clk) | 924 | static 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 | } |
1321 | EXPORT_SYMBOL_GPL(clk_get_accuracy); | 954 | EXPORT_SYMBOL_GPL(clk_get_accuracy); |
1322 | 955 | ||
1323 | static unsigned long clk_recalc(struct clk_core *clk, | 956 | static 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 | */ |
1345 | static void __clk_recalc_rates(struct clk_core *clk, unsigned long msg) | 976 | static 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 | ||
1371 | static unsigned long clk_core_get_rate(struct clk_core *clk) | 1002 | static 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 | } |
1401 | EXPORT_SYMBOL_GPL(clk_get_rate); | 1032 | EXPORT_SYMBOL_GPL(clk_get_rate); |
1402 | 1033 | ||
1403 | static int clk_fetch_parent_index(struct clk_core *clk, | 1034 | static 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 | ||
1436 | static void clk_reparent(struct clk_core *clk, struct clk_core *new_parent) | 1067 | static 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 | ||
1453 | static struct clk_core *__clk_set_parent_before(struct clk_core *clk, | 1084 | static 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 | ||
1511 | static int __clk_set_parent(struct clk_core *clk, struct clk_core *parent, | 1142 | static 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 | */ |
1564 | static int __clk_speculate_rates(struct clk_core *clk, | 1193 | static 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 | ||
1595 | static void clk_calc_subtree(struct clk_core *clk, unsigned long new_rate, | 1224 | static 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 | */ |
1618 | static struct clk_core *clk_calc_new_rates(struct clk_core *clk, | 1247 | static 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 | ||
1697 | out: | 1326 | out: |
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 | */ |
1708 | static struct clk_core *clk_propagate_rate_change(struct clk_core *clk, | 1337 | static 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 | */ |
1746 | static void clk_change_rate(struct clk_core *clk) | 1375 | static 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 | ||
1807 | static int clk_core_set_rate_nolock(struct clk_core *clk, | 1436 | static 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 | */ |
1980 | static struct clk_core *__clk_init_parent(struct clk_core *clk) | 1609 | static 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 | ||
2019 | out: | 1648 | out: |
2020 | return ret; | 1649 | return ret; |
2021 | } | 1650 | } |
2022 | 1651 | ||
2023 | static void clk_core_reparent(struct clk_core *clk, | 1652 | static 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 | } |
2063 | EXPORT_SYMBOL_GPL(clk_has_parent); | 1692 | EXPORT_SYMBOL_GPL(clk_has_parent); |
2064 | 1693 | ||
2065 | static int clk_core_set_parent(struct clk_core *clk, struct clk_core *parent) | 1694 | static 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 | ||
2122 | out: | 1751 | out: |
@@ -2201,21 +1830,16 @@ int clk_set_phase(struct clk *clk, int degrees) | |||
2201 | } | 1830 | } |
2202 | EXPORT_SYMBOL_GPL(clk_set_phase); | 1831 | EXPORT_SYMBOL_GPL(clk_set_phase); |
2203 | 1832 | ||
2204 | static int clk_core_get_phase(struct clk_core *clk) | 1833 | static 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 | ||
2215 | out: | ||
2216 | return ret; | 1841 | return ret; |
2217 | } | 1842 | } |
2218 | EXPORT_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 | } |
1858 | EXPORT_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 | } |
2259 | EXPORT_SYMBOL_GPL(clk_is_match); | 1884 | EXPORT_SYMBOL_GPL(clk_is_match); |
2260 | 1885 | ||
1886 | /*** debugfs support ***/ | ||
1887 | |||
1888 | #ifdef CONFIG_DEBUG_FS | ||
1889 | #include <linux/debugfs.h> | ||
1890 | |||
1891 | static struct dentry *rootdir; | ||
1892 | static int inited = 0; | ||
1893 | static DEFINE_MUTEX(clk_debug_lock); | ||
1894 | static HLIST_HEAD(clk_debug_list); | ||
1895 | |||
1896 | static struct hlist_head *all_lists[] = { | ||
1897 | &clk_root_list, | ||
1898 | &clk_orphan_list, | ||
1899 | NULL, | ||
1900 | }; | ||
1901 | |||
1902 | static struct hlist_head *orphan_list[] = { | ||
1903 | &clk_orphan_list, | ||
1904 | NULL, | ||
1905 | }; | ||
1906 | |||
1907 | static 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 | |||
1920 | static 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 | |||
1934 | static 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 | |||
1954 | static int clk_summary_open(struct inode *inode, struct file *file) | ||
1955 | { | ||
1956 | return single_open(file, clk_summary_show, inode->i_private); | ||
1957 | } | ||
1958 | |||
1959 | static 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 | |||
1966 | static 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 | |||
1980 | static 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 | |||
1997 | static 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 | |||
2023 | static int clk_dump_open(struct inode *inode, struct file *file) | ||
2024 | { | ||
2025 | return single_open(file, clk_dump, inode->i_private); | ||
2026 | } | ||
2027 | |||
2028 | static 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 | |||
2035 | static 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 | |||
2095 | err_out: | ||
2096 | debugfs_remove_recursive(core->dentry); | ||
2097 | core->dentry = NULL; | ||
2098 | out: | ||
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 | */ | ||
2110 | static 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); | ||
2121 | unlock: | ||
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 | */ | ||
2135 | static 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 | |||
2144 | struct 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 | } | ||
2155 | EXPORT_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 | */ | ||
2166 | static 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 | } | ||
2205 | late_initcall(clk_debug_init); | ||
2206 | #else | ||
2207 | static inline int clk_debug_register(struct clk_core *core) { return 0; } | ||
2208 | static inline void clk_debug_reparent(struct clk_core *core, | ||
2209 | struct clk_core *new_parent) | ||
2210 | { | ||
2211 | } | ||
2212 | static 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); |
2439 | out: | 2395 | out: |
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 | */ |
2493 | struct clk *clk_register(struct device *dev, struct clk_hw *hw) | 2449 | struct 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 | ||
2557 | fail_parent_names_copy: | 2508 | fail_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); |
2561 | fail_parent_names: | 2512 | fail_parent_names: |
2562 | kfree_const(clk->name); | 2513 | kfree_const(core->name); |
2563 | fail_name: | 2514 | fail_name: |
2564 | kfree(clk); | 2515 | kfree(core); |
2565 | fail_out: | 2516 | fail_out: |
2566 | return ERR_PTR(ret); | 2517 | return ERR_PTR(ret); |
2567 | } | 2518 | } |
2568 | EXPORT_SYMBOL_GPL(clk_register); | 2519 | EXPORT_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 | */ | ||
2574 | static void __clk_release(struct kref *ref) | 2522 | static 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 | } |
3069 | EXPORT_SYMBOL_GPL(of_clk_get_parent_name); | 3017 | EXPORT_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 | */ | ||
3028 | int 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 | } | ||
3038 | EXPORT_SYMBOL_GPL(of_clk_parent_fill); | ||
3039 | |||
3071 | struct clock_provider { | 3040 | struct 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 @@ | |||
1 | config 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 | ||
5 | obj-y += clk.o clkgate-separated.o | 5 | obj-y += clk.o clkgate-separated.o clkdivider-hi6220.o |
6 | 6 | ||
7 | obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o | 7 | obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o |
8 | obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o | 8 | obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o |
9 | obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o | 9 | obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o |
10 | obj-$(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 */ |
41 | static const char *timer0_mux_p[] __initdata = { "osc32k", "timerclk01", }; | 41 | static const char *const timer0_mux_p[] __initconst = { "osc32k", "timerclk01", }; |
42 | static const char *timer1_mux_p[] __initdata = { "osc32k", "timerclk01", }; | 42 | static const char *const timer1_mux_p[] __initconst = { "osc32k", "timerclk01", }; |
43 | static const char *timer2_mux_p[] __initdata = { "osc32k", "timerclk23", }; | 43 | static const char *const timer2_mux_p[] __initconst = { "osc32k", "timerclk23", }; |
44 | static const char *timer3_mux_p[] __initdata = { "osc32k", "timerclk23", }; | 44 | static const char *const timer3_mux_p[] __initconst = { "osc32k", "timerclk23", }; |
45 | static const char *timer4_mux_p[] __initdata = { "osc32k", "timerclk45", }; | 45 | static const char *const timer4_mux_p[] __initconst = { "osc32k", "timerclk45", }; |
46 | static const char *timer5_mux_p[] __initdata = { "osc32k", "timerclk45", }; | 46 | static const char *const timer5_mux_p[] __initconst = { "osc32k", "timerclk45", }; |
47 | static const char *timer6_mux_p[] __initdata = { "osc32k", "timerclk67", }; | 47 | static const char *const timer6_mux_p[] __initconst = { "osc32k", "timerclk67", }; |
48 | static const char *timer7_mux_p[] __initdata = { "osc32k", "timerclk67", }; | 48 | static const char *const timer7_mux_p[] __initconst = { "osc32k", "timerclk67", }; |
49 | static const char *timer8_mux_p[] __initdata = { "osc32k", "timerclk89", }; | 49 | static const char *const timer8_mux_p[] __initconst = { "osc32k", "timerclk89", }; |
50 | static const char *timer9_mux_p[] __initdata = { "osc32k", "timerclk89", }; | 50 | static const char *const timer9_mux_p[] __initconst = { "osc32k", "timerclk89", }; |
51 | static const char *uart0_mux_p[] __initdata = { "osc26m", "pclk", }; | 51 | static const char *const uart0_mux_p[] __initconst = { "osc26m", "pclk", }; |
52 | static const char *uart1_mux_p[] __initdata = { "osc26m", "pclk", }; | 52 | static const char *const uart1_mux_p[] __initconst = { "osc26m", "pclk", }; |
53 | static const char *uart2_mux_p[] __initdata = { "osc26m", "pclk", }; | 53 | static const char *const uart2_mux_p[] __initconst = { "osc26m", "pclk", }; |
54 | static const char *uart3_mux_p[] __initdata = { "osc26m", "pclk", }; | 54 | static const char *const uart3_mux_p[] __initconst = { "osc26m", "pclk", }; |
55 | static const char *uart4_mux_p[] __initdata = { "osc26m", "pclk", }; | 55 | static const char *const uart4_mux_p[] __initconst = { "osc26m", "pclk", }; |
56 | static const char *spi0_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; | 56 | static const char *const spi0_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", }; |
57 | static const char *spi1_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; | 57 | static const char *const spi1_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", }; |
58 | static const char *spi2_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", }; | 58 | static const char *const spi2_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", }; |
59 | /* share axi parent */ | 59 | /* share axi parent */ |
60 | static const char *saxi_mux_p[] __initdata = { "armpll3", "armpll2", }; | 60 | static const char *const saxi_mux_p[] __initconst = { "armpll3", "armpll2", }; |
61 | static const char *pwm0_mux_p[] __initdata = { "osc32k", "osc26m", }; | 61 | static const char *const pwm0_mux_p[] __initconst = { "osc32k", "osc26m", }; |
62 | static const char *pwm1_mux_p[] __initdata = { "osc32k", "osc26m", }; | 62 | static const char *const pwm1_mux_p[] __initconst = { "osc32k", "osc26m", }; |
63 | static const char *sd_mux_p[] __initdata = { "armpll2", "armpll3", }; | 63 | static const char *const sd_mux_p[] __initconst = { "armpll2", "armpll3", }; |
64 | static const char *mmc1_mux_p[] __initdata = { "armpll2", "armpll3", }; | 64 | static const char *const mmc1_mux_p[] __initconst = { "armpll2", "armpll3", }; |
65 | static const char *mmc1_mux2_p[] __initdata = { "osc26m", "mmc1_div", }; | 65 | static const char *const mmc1_mux2_p[] __initconst = { "osc26m", "mmc1_div", }; |
66 | static const char *g2d_mux_p[] __initdata = { "armpll2", "armpll3", }; | 66 | static const char *const g2d_mux_p[] __initconst = { "armpll2", "armpll3", }; |
67 | static const char *venc_mux_p[] __initdata = { "armpll2", "armpll3", }; | 67 | static const char *const venc_mux_p[] __initconst = { "armpll2", "armpll3", }; |
68 | static const char *vdec_mux_p[] __initdata = { "armpll2", "armpll3", }; | 68 | static const char *const vdec_mux_p[] __initconst = { "armpll2", "armpll3", }; |
69 | static const char *vpp_mux_p[] __initdata = { "armpll2", "armpll3", }; | 69 | static const char *const vpp_mux_p[] __initconst = { "armpll2", "armpll3", }; |
70 | static const char *edc0_mux_p[] __initdata = { "armpll2", "armpll3", }; | 70 | static const char *const edc0_mux_p[] __initconst = { "armpll2", "armpll3", }; |
71 | static const char *ldi0_mux_p[] __initdata = { "armpll2", "armpll4", | 71 | static const char *const ldi0_mux_p[] __initconst = { "armpll2", "armpll4", |
72 | "armpll3", "armpll5", }; | 72 | "armpll3", "armpll5", }; |
73 | static const char *edc1_mux_p[] __initdata = { "armpll2", "armpll3", }; | 73 | static const char *const edc1_mux_p[] __initconst = { "armpll2", "armpll3", }; |
74 | static const char *ldi1_mux_p[] __initdata = { "armpll2", "armpll4", | 74 | static const char *const ldi1_mux_p[] __initconst = { "armpll2", "armpll4", |
75 | "armpll3", "armpll5", }; | 75 | "armpll3", "armpll5", }; |
76 | static const char *rclk_hsic_p[] __initdata = { "armpll3", "armpll2", }; | 76 | static const char *const rclk_hsic_p[] __initconst = { "armpll3", "armpll2", }; |
77 | static const char *mmc2_mux_p[] __initdata = { "armpll2", "armpll3", }; | 77 | static const char *const mmc2_mux_p[] __initconst = { "armpll2", "armpll3", }; |
78 | static const char *mmc3_mux_p[] __initdata = { "armpll2", "armpll3", }; | 78 | static 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 */ | ||
28 | static 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 | |||
44 | static 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 | |||
57 | static 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 | |||
73 | static 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 | } | ||
90 | CLK_OF_DECLARE(hi6220_clk_ao, "hisilicon,hi6220-aoctrl", hi6220_clk_ao_init); | ||
91 | |||
92 | |||
93 | /* clocks in sysctrl */ | ||
94 | static const char *mmc0_mux0_p[] __initdata = { "pll_ddr_gate", "syspll", }; | ||
95 | static const char *mmc0_mux1_p[] __initdata = { "mmc0_mux0", "pll_media_gate", }; | ||
96 | static const char *mmc0_src_p[] __initdata = { "mmc0srcsel", "mmc0_div", }; | ||
97 | static const char *mmc1_mux0_p[] __initdata = { "pll_ddr_gate", "syspll", }; | ||
98 | static const char *mmc1_mux1_p[] __initdata = { "mmc1_mux0", "pll_media_gate", }; | ||
99 | static const char *mmc1_src_p[] __initdata = { "mmc1srcsel", "mmc1_div", }; | ||
100 | static const char *mmc2_mux0_p[] __initdata = { "pll_ddr_gate", "syspll", }; | ||
101 | static const char *mmc2_mux1_p[] __initdata = { "mmc2_mux0", "pll_media_gate", }; | ||
102 | static const char *mmc2_src_p[] __initdata = { "mmc2srcsel", "mmc2_div", }; | ||
103 | static const char *mmc0_sample_in[] __initdata = { "mmc0_sample", "mmc0_pad", }; | ||
104 | static const char *mmc1_sample_in[] __initdata = { "mmc1_sample", "mmc1_pad", }; | ||
105 | static const char *mmc2_sample_in[] __initdata = { "mmc2_sample", "mmc2_pad", }; | ||
106 | static const char *uart1_src[] __initdata = { "clk_tcxo", "clk_150m", }; | ||
107 | static const char *uart2_src[] __initdata = { "clk_tcxo", "clk_150m", }; | ||
108 | static const char *uart3_src[] __initdata = { "clk_tcxo", "clk_150m", }; | ||
109 | static const char *uart4_src[] __initdata = { "clk_tcxo", "clk_150m", }; | ||
110 | static const char *hifi_src[] __initdata = { "syspll", "pll_media_gate", }; | ||
111 | |||
112 | static 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 | |||
148 | static 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 | |||
168 | static 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 | |||
179 | static 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 | } | ||
196 | CLK_OF_DECLARE(hi6220_clk_sys, "hisilicon,hi6220-sysctrl", hi6220_clk_sys_init); | ||
197 | |||
198 | |||
199 | /* clocks in media controller */ | ||
200 | static const char *clk_1000_1200_src[] __initdata = { "pll_gpu_gate", "media_syspll_src", }; | ||
201 | static const char *clk_1440_1200_src[] __initdata = { "media_syspll_src", "media_pll_src", }; | ||
202 | static const char *clk_1000_1440_src[] __initdata = { "pll_gpu_gate", "media_pll_src", }; | ||
203 | |||
204 | static 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 | |||
220 | static 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 | |||
226 | static 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 | |||
236 | static 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 | } | ||
253 | CLK_OF_DECLARE(hi6220_clk_media, "hisilicon,hi6220-mediactrl", hi6220_clk_media_init); | ||
254 | |||
255 | |||
256 | /* clocks in pmctrl */ | ||
257 | static 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 | |||
265 | static 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 | |||
270 | static 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 | } | ||
284 | CLK_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 | ||
49 | static const char *sfc_mux_p[] __initdata = { | 49 | static const char *const sfc_mux_p[] __initconst = { |
50 | "24m", "150m", "200m", "100m", "75m", }; | 50 | "24m", "150m", "200m", "100m", "75m", }; |
51 | static u32 sfc_mux_table[] = {0, 4, 5, 6, 7}; | 51 | static u32 sfc_mux_table[] = {0, 4, 5, 6, 7}; |
52 | 52 | ||
53 | static const char *sdio_mux_p[] __initdata = { | 53 | static const char *const sdio_mux_p[] __initconst = { |
54 | "75m", "100m", "50m", "15m", }; | 54 | "75m", "100m", "50m", "15m", }; |
55 | static u32 sdio_mux_table[] = {0, 1, 2, 3}; | 55 | static u32 sdio_mux_table[] = {0, 1, 2, 3}; |
56 | 56 | ||
57 | static const char *fephy_mux_p[] __initdata = { "25m", "125m"}; | 57 | static const char *const fephy_mux_p[] __initconst = { "25m", "125m"}; |
58 | static u32 fephy_mux_table[] = {0, 1}; | 58 | static 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 | ||
255 | void __init hix5hd2_clk_register_complex(struct hix5hd2_complex_clock *clks, | 255 | static void __init |
256 | int nums, struct hisi_clock_data *data) | 256 | hix5hd2_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 | |||
236 | void __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 { | |||
55 | struct hisi_mux_clock { | 55 | struct 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 | ||
82 | struct 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 | |||
82 | struct hisi_gate_clock { | 94 | struct 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 *); |
109 | struct 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 | ||
98 | struct hisi_clock_data __init *hisi_clk_init(struct device_node *, int); | 113 | struct hisi_clock_data *hisi_clk_init(struct device_node *, int); |
99 | void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *, | 114 | void hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *, |
100 | int, struct hisi_clock_data *); | 115 | int, struct hisi_clock_data *); |
101 | void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *, | 116 | void hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *, |
102 | int, struct hisi_clock_data *); | 117 | int, struct hisi_clock_data *); |
103 | void __init hisi_clk_register_mux(struct hisi_mux_clock *, int, | 118 | void hisi_clk_register_mux(struct hisi_mux_clock *, int, |
104 | struct hisi_clock_data *); | 119 | struct hisi_clock_data *); |
105 | void __init hisi_clk_register_divider(struct hisi_divider_clock *, | 120 | void hisi_clk_register_divider(struct hisi_divider_clock *, |
121 | int, struct hisi_clock_data *); | ||
122 | void hisi_clk_register_gate(struct hisi_gate_clock *, | ||
123 | int, struct hisi_clock_data *); | ||
124 | void hisi_clk_register_gate_sep(struct hisi_gate_clock *, | ||
125 | int, struct hisi_clock_data *); | ||
126 | void hi6220_clk_register_divider(struct hi6220_divider_clock *, | ||
106 | int, struct hisi_clock_data *); | 127 | int, struct hisi_clock_data *); |
107 | void __init hisi_clk_register_gate(struct hisi_gate_clock *, | ||
108 | int, struct hisi_clock_data *); | ||
109 | void __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 | */ | ||
34 | struct 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 | |||
47 | static 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 | |||
60 | static 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 | |||
69 | static 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 | |||
96 | static 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 | |||
102 | struct 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 @@ | |||
1 | obj-y += clk-mtk.o clk-pll.o clk-gate.o | ||
2 | obj-$(CONFIG_RESET_CONTROLLER) += reset.o | ||
3 | obj-y += clk-mt8135.o | ||
4 | obj-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 | |||
26 | static 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 | |||
38 | static 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 | |||
50 | static 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 | |||
57 | static 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 | |||
64 | static int mtk_cg_enable(struct clk_hw *hw) | ||
65 | { | ||
66 | mtk_cg_clr_bit(hw); | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static void mtk_cg_disable(struct clk_hw *hw) | ||
72 | { | ||
73 | mtk_cg_set_bit(hw); | ||
74 | } | ||
75 | |||
76 | static int mtk_cg_enable_inv(struct clk_hw *hw) | ||
77 | { | ||
78 | mtk_cg_set_bit(hw); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static void mtk_cg_disable_inv(struct clk_hw *hw) | ||
84 | { | ||
85 | mtk_cg_clr_bit(hw); | ||
86 | } | ||
87 | |||
88 | const 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 | |||
94 | const 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 | |||
100 | struct 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 | |||
22 | struct 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 | |||
31 | static 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 | |||
36 | extern const struct clk_ops mtk_clk_gate_ops_setclr; | ||
37 | extern const struct clk_ops mtk_clk_gate_ops_setclr_inv; | ||
38 | |||
39 | struct 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 | |||
24 | static DEFINE_SPINLOCK(mt8135_clk_lock); | ||
25 | |||
26 | static 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 | |||
33 | static 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 | |||
109 | static 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 | |||
119 | static 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 | |||
137 | static 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 | |||
153 | static const char * const irda_parents[] __initconst = { | ||
154 | "clk26m", | ||
155 | "univpll2_d8", | ||
156 | "univpll1_d6" | ||
157 | }; | ||
158 | |||
159 | static 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 | |||
170 | static const char * const aud_intbus_parents[] __initconst = { | ||
171 | "clk26m", | ||
172 | "syspll_d6", | ||
173 | "univpll_d10" | ||
174 | }; | ||
175 | |||
176 | static 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 | |||
186 | static 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 | |||
197 | static const char * const msdc30_parents[] __initconst = { | ||
198 | "clk26m", | ||
199 | "syspll_d6", | ||
200 | "syspll_d5", | ||
201 | "univpll1_d4", | ||
202 | "univpll2_d4", | ||
203 | "msdcpll" | ||
204 | }; | ||
205 | |||
206 | static const char * const usb20_parents[] __initconst = { | ||
207 | "clk26m", | ||
208 | "univpll2_d6", | ||
209 | "univpll1_d10" | ||
210 | }; | ||
211 | |||
212 | static 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 | |||
223 | static 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 | |||
232 | static const char * const uart_parents[] __initconst = { | ||
233 | "clk26m", | ||
234 | "univpll2_d8" | ||
235 | }; | ||
236 | |||
237 | static const char * const mem_parents[] __initconst = { | ||
238 | "clk26m", | ||
239 | "clkph_mck" | ||
240 | }; | ||
241 | |||
242 | static const char * const camtg_parents[] __initconst = { | ||
243 | "clk26m", | ||
244 | "univpll_d26", | ||
245 | "univpll1_d6", | ||
246 | "syspll_d16", | ||
247 | "syspll_d8" | ||
248 | }; | ||
249 | |||
250 | static const char * const audio_parents[] __initconst = { | ||
251 | "clk26m", | ||
252 | "syspll_d24" | ||
253 | }; | ||
254 | |||
255 | static 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 | |||
266 | static 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 | |||
285 | static const char * const ddrphycfg_parents[] __initconst = { | ||
286 | "clk26m", | ||
287 | "axi_sel", | ||
288 | "syspll_d12" | ||
289 | }; | ||
290 | |||
291 | static const char * const dpilvds_parents[] __initconst = { | ||
292 | "clk26m", | ||
293 | "lvdspll", | ||
294 | "lvdspll_d2", | ||
295 | "lvdspll_d4", | ||
296 | "lvdspll_d8" | ||
297 | }; | ||
298 | |||
299 | static 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 | |||
310 | static const char * const smi_mfg_as_parents[] __initconst = { | ||
311 | "clk26m", | ||
312 | "smi_sel", | ||
313 | "mfg_sel", | ||
314 | "mem_sel" | ||
315 | }; | ||
316 | |||
317 | static const char * const gcpu_parents[] __initconst = { | ||
318 | "clk26m", | ||
319 | "syspll_d4", | ||
320 | "univpll_d7", | ||
321 | "syspll_d5", | ||
322 | "syspll_d6" | ||
323 | }; | ||
324 | |||
325 | static const char * const dpi1_parents[] __initconst = { | ||
326 | "clk26m", | ||
327 | "tvhdmi_h_ck", | ||
328 | "tvhdmi_d2", | ||
329 | "tvhdmi_d4" | ||
330 | }; | ||
331 | |||
332 | static 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 | |||
341 | static 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 | |||
350 | static const char * const hdmipll_parents[] __initconst = { | ||
351 | "clk26m", | ||
352 | "hdmitx_clkdig_cts", | ||
353 | "hdmitx_clkdig_d2", | ||
354 | "hdmitx_clkdig_d3" | ||
355 | }; | ||
356 | |||
357 | static 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 | |||
404 | static 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 | |||
419 | static 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 | |||
435 | static const struct mtk_gate_regs peri0_cg_regs = { | ||
436 | .set_ofs = 0x0008, | ||
437 | .clr_ofs = 0x0010, | ||
438 | .sta_ofs = 0x0018, | ||
439 | }; | ||
440 | |||
441 | static 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 | |||
465 | static 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 | |||
511 | static const char * const uart_ck_sel_parents[] __initconst = { | ||
512 | "clk26m", | ||
513 | "uart_sel", | ||
514 | }; | ||
515 | |||
516 | static 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 | |||
523 | static 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 | } | ||
549 | CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8135-topckgen", mtk_topckgen_init); | ||
550 | |||
551 | static 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 | } | ||
570 | CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8135-infracfg", mtk_infrasys_init); | ||
571 | |||
572 | static 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 | } | ||
598 | CLK_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 | |||
620 | static 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 | |||
633 | static 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 | } | ||
643 | CLK_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 | |||
25 | static DEFINE_SPINLOCK(mt8173_clk_lock); | ||
26 | |||
27 | static 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 | |||
34 | static 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 | |||
130 | static 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 | |||
141 | static const char * const mem_parents[] __initconst = { | ||
142 | "clk26m", | ||
143 | "dmpll_ck" | ||
144 | }; | ||
145 | |||
146 | static const char * const ddrphycfg_parents[] __initconst = { | ||
147 | "clk26m", | ||
148 | "syspll1_d8" | ||
149 | }; | ||
150 | |||
151 | static 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 | |||
163 | static const char * const pwm_parents[] __initconst = { | ||
164 | "clk26m", | ||
165 | "univpll2_d4", | ||
166 | "univpll3_d2", | ||
167 | "univpll1_d4" | ||
168 | }; | ||
169 | |||
170 | static 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 | |||
183 | static 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 | |||
196 | static 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 | |||
215 | static 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 | |||
224 | static const char * const uart_parents[] __initconst = { | ||
225 | "clk26m", | ||
226 | "univpll2_d8" | ||
227 | }; | ||
228 | |||
229 | static 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 | |||
239 | static const char * const usb20_parents[] __initconst = { | ||
240 | "clk26m", | ||
241 | "univpll1_d8", | ||
242 | "univpll3_d4" | ||
243 | }; | ||
244 | |||
245 | static const char * const usb30_parents[] __initconst = { | ||
246 | "clk26m", | ||
247 | "univpll3_d2", | ||
248 | "usb_syspll_125m", | ||
249 | "univpll2_d4" | ||
250 | }; | ||
251 | |||
252 | static 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 | |||
261 | static 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 | |||
279 | static 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 | |||
290 | static 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 | |||
301 | static 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 | |||
318 | static const char * const audio_parents[] __initconst = { | ||
319 | "clk26m", | ||
320 | "syspll3_d4", | ||
321 | "syspll4_d4", | ||
322 | "syspll1_d16" | ||
323 | }; | ||
324 | |||
325 | static 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 | |||
335 | static 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 | |||
346 | static 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 | |||
355 | static const char * const atb_parents[] __initconst = { | ||
356 | "clk26m", | ||
357 | "syspll1_d2", | ||
358 | "univpll_d5", | ||
359 | "dmpll_d2" | ||
360 | }; | ||
361 | |||
362 | static 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 | |||
377 | static 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 | |||
387 | static const char * const irda_parents[] __initconst = { | ||
388 | "clk26m", | ||
389 | "univpll2_d4", | ||
390 | "syspll2_d4" | ||
391 | }; | ||
392 | |||
393 | static 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 | |||
404 | static const char * const aud_1_parents[] __initconst = { | ||
405 | "clk26m", | ||
406 | "apll1_ck", | ||
407 | "univpll2_d4", | ||
408 | "univpll2_d8" | ||
409 | }; | ||
410 | |||
411 | static const char * const aud_2_parents[] __initconst = { | ||
412 | "clk26m", | ||
413 | "apll2_ck", | ||
414 | "univpll2_d4", | ||
415 | "univpll2_d8" | ||
416 | }; | ||
417 | |||
418 | static const char * const mem_mfg_in_parents[] __initconst = { | ||
419 | "clk26m", | ||
420 | "mmpll_ck", | ||
421 | "dmpll_ck", | ||
422 | "clk26m" | ||
423 | }; | ||
424 | |||
425 | static const char * const axi_mfg_in_parents[] __initconst = { | ||
426 | "clk26m", | ||
427 | "axi_sel", | ||
428 | "dmpll_d2" | ||
429 | }; | ||
430 | |||
431 | static const char * const scam_parents[] __initconst = { | ||
432 | "clk26m", | ||
433 | "syspll3_d2", | ||
434 | "univpll2_d4", | ||
435 | "dmpll_d4" | ||
436 | }; | ||
437 | |||
438 | static 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 | |||
449 | static const char * const hdmi_parents[] __initconst = { | ||
450 | "clk26m", | ||
451 | "hdmitx_dig_cts", | ||
452 | "hdmitxpll_d2", | ||
453 | "hdmitxpll_d3" | ||
454 | }; | ||
455 | |||
456 | static const char * const dpilvds_parents[] __initconst = { | ||
457 | "clk26m", | ||
458 | "lvdspll", | ||
459 | "lvdspll_d2", | ||
460 | "lvdspll_d4", | ||
461 | "lvdspll_d8", | ||
462 | "fpc_ck" | ||
463 | }; | ||
464 | |||
465 | static 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 | |||
474 | static const char * const hdcp_parents[] __initconst = { | ||
475 | "clk26m", | ||
476 | "syspll4_d2", | ||
477 | "syspll3_d4", | ||
478 | "univpll2_d4" | ||
479 | }; | ||
480 | |||
481 | static const char * const hdcp_24m_parents[] __initconst = { | ||
482 | "clk26m", | ||
483 | "univpll_d26", | ||
484 | "univpll_d52", | ||
485 | "univpll2_d8" | ||
486 | }; | ||
487 | |||
488 | static const char * const rtc_parents[] __initconst = { | ||
489 | "clkrtc_int", | ||
490 | "clkrtc_ext", | ||
491 | "clk26m", | ||
492 | "univpll3_d8" | ||
493 | }; | ||
494 | |||
495 | static const char * const i2s0_m_ck_parents[] __initconst = { | ||
496 | "apll1_div1", | ||
497 | "apll2_div1" | ||
498 | }; | ||
499 | |||
500 | static const char * const i2s1_m_ck_parents[] __initconst = { | ||
501 | "apll1_div2", | ||
502 | "apll2_div2" | ||
503 | }; | ||
504 | |||
505 | static const char * const i2s2_m_ck_parents[] __initconst = { | ||
506 | "apll1_div3", | ||
507 | "apll2_div3" | ||
508 | }; | ||
509 | |||
510 | static const char * const i2s3_m_ck_parents[] __initconst = { | ||
511 | "apll1_div4", | ||
512 | "apll2_div4" | ||
513 | }; | ||
514 | |||
515 | static const char * const i2s3_b_ck_parents[] __initconst = { | ||
516 | "apll1_div5", | ||
517 | "apll2_div5" | ||
518 | }; | ||
519 | |||
520 | static 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 | |||
592 | static 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 | |||
607 | static 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 | |||
621 | static const struct mtk_gate_regs peri0_cg_regs = { | ||
622 | .set_ofs = 0x0008, | ||
623 | .clr_ofs = 0x0010, | ||
624 | .sta_ofs = 0x0018, | ||
625 | }; | ||
626 | |||
627 | static 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 | |||
651 | static 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 | |||
691 | static const char * const uart_ck_sel_parents[] __initconst = { | ||
692 | "clk26m", | ||
693 | "uart_sel", | ||
694 | }; | ||
695 | |||
696 | static 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 | |||
703 | static 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 | } | ||
729 | CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8173-topckgen", mtk_topckgen_init); | ||
730 | |||
731 | static 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 | } | ||
748 | CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8173-infracfg", mtk_infrasys_init); | ||
749 | |||
750 | static 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 | } | ||
776 | CLK_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 | |||
800 | static 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 | |||
817 | static 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 | } | ||
829 | CLK_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 | |||
27 | struct 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; | ||
46 | err_out: | ||
47 | kfree(clk_data); | ||
48 | |||
49 | return NULL; | ||
50 | } | ||
51 | |||
52 | void 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 | |||
75 | int 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 | |||
114 | struct 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; | ||
193 | err_out: | ||
194 | kfree(mux); | ||
195 | |||
196 | return ERR_PTR(ret); | ||
197 | } | ||
198 | |||
199 | void 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 | |||
28 | struct 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 | |||
44 | extern void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, | ||
45 | int num, struct clk_onecell_data *clk_data); | ||
46 | |||
47 | struct 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 | |||
108 | struct clk *mtk_clk_register_composite(const struct mtk_composite *mc, | ||
109 | void __iomem *base, spinlock_t *lock); | ||
110 | |||
111 | void 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 | |||
115 | struct mtk_gate_regs { | ||
116 | u32 sta_ofs; | ||
117 | u32 clr_ofs; | ||
118 | u32 set_ofs; | ||
119 | }; | ||
120 | |||
121 | struct 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 | |||
130 | int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks, | ||
131 | int num, struct clk_onecell_data *clk_data); | ||
132 | |||
133 | struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num); | ||
134 | |||
135 | #define HAVE_RST_BAR BIT(0) | ||
136 | |||
137 | struct 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 | |||
155 | void __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 | ||
160 | void mtk_register_reset_controller(struct device_node *np, | ||
161 | unsigned int num_regs, int regofs); | ||
162 | #else | ||
163 | static 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 | |||
44 | struct 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 | |||
54 | static 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 | |||
59 | static 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 | |||
66 | static 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 | |||
90 | static 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 | */ | ||
134 | static 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 | |||
157 | static 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 | |||
170 | static 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 | |||
186 | static 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 | |||
198 | static 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 | |||
231 | static 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 | |||
258 | static 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 | |||
267 | static 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 | |||
301 | void __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 | |||
24 | struct mtk_reset { | ||
25 | struct regmap *regmap; | ||
26 | int regofs; | ||
27 | struct reset_controller_dev rcdev; | ||
28 | }; | ||
29 | |||
30 | static 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 | |||
39 | static 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 | |||
48 | static 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 | |||
60 | static struct reset_control_ops mtk_reset_ops = { | ||
61 | .assert = mtk_reset_assert, | ||
62 | .deassert = mtk_reset_deassert, | ||
63 | .reset = mtk_reset, | ||
64 | }; | ||
65 | |||
66 | void 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 | |||
5 | obj-y += clkc.o clk-pll.o clk-cpu.o | ||
6 | obj-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 | |||
53 | struct 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 | |||
63 | static 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 | |||
72 | static 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 | |||
99 | static 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 | |||
121 | static 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 | |||
142 | static 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 | */ | ||
163 | static 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 | |||
178 | static 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 | |||
184 | struct 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 | |||
235 | unregister_clk_nb: | ||
236 | clk_notifier_unregister(pclk, &clk_cpu->clk_nb); | ||
237 | free_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 | |||
47 | struct 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 | |||
56 | static 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 | |||
83 | static 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 | |||
99 | static 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 | |||
112 | static 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 | |||
128 | static 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 | |||
176 | static 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 | |||
182 | static const struct clk_ops meson_clk_pll_ro_ops = { | ||
183 | .recalc_rate = meson_clk_pll_recalc_rate, | ||
184 | }; | ||
185 | |||
186 | struct 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 | |||
25 | static DEFINE_SPINLOCK(clk_lock); | ||
26 | |||
27 | static struct clk **clks; | ||
28 | static struct clk_onecell_data clk_data; | ||
29 | |||
30 | struct 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 | |||
44 | static void meson_clk_add_lookup(struct clk *clk, unsigned int id) | ||
45 | { | ||
46 | if (clks && id) | ||
47 | clks[id] = clk; | ||
48 | } | ||
49 | |||
50 | static struct clk * __init | ||
51 | meson_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 | |||
121 | error: | ||
122 | kfree(gate); | ||
123 | kfree(div); | ||
124 | kfree(mux); | ||
125 | |||
126 | return clk; | ||
127 | } | ||
128 | |||
129 | static struct clk * __init | ||
130 | meson_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 | |||
171 | static struct clk * __init | ||
172 | meson_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 | |||
201 | void __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 | |||
32 | struct 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 | |||
44 | struct 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 | |||
58 | struct pll_conf { | ||
59 | const struct pll_rate_table *rate_table; | ||
60 | struct parm m; | ||
61 | struct parm n; | ||
62 | struct parm od; | ||
63 | }; | ||
64 | |||
65 | struct fixed_fact_conf { | ||
66 | unsigned int div; | ||
67 | unsigned int mult; | ||
68 | struct parm div_parm; | ||
69 | struct parm mult_parm; | ||
70 | }; | ||
71 | |||
72 | struct fixed_rate_conf { | ||
73 | unsigned long rate; | ||
74 | struct parm rate_parm; | ||
75 | }; | ||
76 | |||
77 | struct 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 | |||
90 | enum clk_type { | ||
91 | CLK_FIXED_FACTOR, | ||
92 | CLK_FIXED_RATE, | ||
93 | CLK_COMPOSITE, | ||
94 | CLK_CPU, | ||
95 | CLK_PLL, | ||
96 | }; | ||
97 | |||
98 | struct 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 | |||
179 | struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks); | ||
180 | void meson_clk_register_clks(const struct clk_conf *clk_confs, | ||
181 | unsigned int nr_confs, void __iomem *clk_base); | ||
182 | struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, | ||
183 | void __iomem *reg_base, spinlock_t *lock); | ||
184 | struct 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 | |||
35 | static 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 | |||
91 | static 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 | |||
105 | PNAME(p_xtal) = { "xtal" }; | ||
106 | PNAME(p_fclk_div) = { "fixed_pll" }; | ||
107 | PNAME(p_cpu_clk) = { "sys_pll" }; | ||
108 | PNAME(p_clk81) = { "fclk_div3", "fclk_div4", "fclk_div5" }; | ||
109 | PNAME(p_mali) = { "fclk_div3", "fclk_div4", "fclk_div5", | ||
110 | "fclk_div7", "zero" }; | ||
111 | |||
112 | static u32 mux_table_clk81[] = { 6, 5, 7 }; | ||
113 | static u32 mux_table_mali[] = { 6, 5, 7, 4, 0 }; | ||
114 | |||
115 | static 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 | |||
121 | static 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 | |||
128 | static 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 | |||
136 | static 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 | |||
143 | static 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 | |||
147 | static 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 | |||
168 | static 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 | } | ||
196 | CLK_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 | |||
12 | obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o | 12 | obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o |
13 | obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o | 13 | obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o |
14 | obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o | 14 | obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o |
15 | |||
16 | obj-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 | ||
118 | struct clk_ops clk_apbc_ops = { | 118 | static 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 | ||
64 | struct clk_ops clk_apmu_ops = { | 64 | static 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 | ||
65 | static struct mmp_clk_factor_tbl uart_factor_tbl[] = { | 65 | static 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 | ||
72 | static const char *uart_parent[] = {"uart_pll", "vctcxo"}; | 70 | static 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 | ||
100 | static struct mmp_clk_factor_tbl uart_factor_tbl[] = { | 101 | static 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 | ||
107 | static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit) | 106 | static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit) |
@@ -134,6 +133,9 @@ static DEFINE_SPINLOCK(ssp2_lock); | |||
134 | static DEFINE_SPINLOCK(ssp3_lock); | 133 | static DEFINE_SPINLOCK(ssp3_lock); |
135 | static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"}; | 134 | static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"}; |
136 | 135 | ||
136 | static DEFINE_SPINLOCK(timer_lock); | ||
137 | static const char *timer_parent_names[] = {"clk32", "vctcxo_2", "vctcxo_4", "vctcxo"}; | ||
138 | |||
137 | static DEFINE_SPINLOCK(reset_lock); | 139 | static DEFINE_SPINLOCK(reset_lock); |
138 | 140 | ||
139 | static struct mmp_param_mux_clk apbc_mux_clks[] = { | 141 | static 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 | ||
150 | static struct mmp_param_gate_clk apbc_gate_clks[] = { | 153 | static 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 | ||
175 | static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit) | 179 | static 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 | ||
63 | static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { | 65 | static 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); | |||
119 | static DEFINE_SPINLOCK(ssp4_lock); | 122 | static DEFINE_SPINLOCK(ssp4_lock); |
120 | static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; | 123 | static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; |
121 | 124 | ||
125 | static DEFINE_SPINLOCK(timer_lock); | ||
126 | static const char *timer_parent_names[] = {"pll1_48", "clk32", "pll1_96", "pll1_192"}; | ||
127 | |||
122 | static DEFINE_SPINLOCK(reset_lock); | 128 | static DEFINE_SPINLOCK(reset_lock); |
123 | 129 | ||
124 | static struct mmp_param_mux_clk apbc_mux_clks[] = { | 130 | static 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 | ||
135 | static struct mmp_param_gate_clk apbc_gate_clks[] = { | 142 | static 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 | ||
156 | static void pxa168_apb_periph_clk_init(struct pxa168_clk_unit *pxa_unit) | 164 | static 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 | |||
28 | struct 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 | |||
36 | static 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 | |||
45 | static 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 | |||
56 | static 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 | |||
64 | static struct mmp_clk_factor_tbl uart_factor_tbl[] = { | ||
65 | {.num = 832, .den = 234}, /*58.5MHZ */ | ||
66 | {.num = 1, .den = 1}, /*26MHZ */ | ||
67 | }; | ||
68 | |||
69 | static 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 | |||
87 | static DEFINE_SPINLOCK(uart0_lock); | ||
88 | static DEFINE_SPINLOCK(uart1_lock); | ||
89 | static DEFINE_SPINLOCK(uart2_lock); | ||
90 | static DEFINE_SPINLOCK(uart3_lock); | ||
91 | static const char *uart_parent_names[] = {"uart_pll", "vctcxo"}; | ||
92 | |||
93 | static DEFINE_SPINLOCK(ssp0_lock); | ||
94 | static DEFINE_SPINLOCK(ssp1_lock); | ||
95 | static const char *ssp_parent_names[] = {"vctcxo_d4", "vctcxo_d2", "vctcxo", "pll1_d12"}; | ||
96 | |||
97 | static DEFINE_SPINLOCK(reset_lock); | ||
98 | |||
99 | static 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 | |||
108 | static 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 | |||
131 | static 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 | |||
142 | static DEFINE_SPINLOCK(sdh0_lock); | ||
143 | static DEFINE_SPINLOCK(sdh1_lock); | ||
144 | static DEFINE_SPINLOCK(sdh2_lock); | ||
145 | static DEFINE_SPINLOCK(sdh3_lock); | ||
146 | static DEFINE_SPINLOCK(sdh4_lock); | ||
147 | static const char *sdh_parent_names[] = {"pll1_624", "pll5p", "pll5", "pll1_416"}; | ||
148 | |||
149 | static DEFINE_SPINLOCK(usb_lock); | ||
150 | |||
151 | static 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 | |||
155 | static 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 | |||
159 | static 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 | |||
170 | static 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 | |||
184 | static 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 | |||
208 | static 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 | } | ||
224 | CLK_OF_DECLARE(pxa1928_mpmu_clk, "marvell,pxa1928-mpmu", pxa1928_mpmu_clk_init); | ||
225 | |||
226 | static 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 | } | ||
244 | CLK_OF_DECLARE(pxa1928_apmu_clk, "marvell,pxa1928-apmu", pxa1928_apmu_clk_init); | ||
245 | |||
246 | static 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 | } | ||
265 | CLK_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 | ||
62 | static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = { | 65 | static 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); | |||
115 | static DEFINE_SPINLOCK(ssp1_lock); | 119 | static DEFINE_SPINLOCK(ssp1_lock); |
116 | static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; | 120 | static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; |
117 | 121 | ||
122 | static DEFINE_SPINLOCK(timer0_lock); | ||
123 | static DEFINE_SPINLOCK(timer1_lock); | ||
124 | static const char *timer_parent_names[] = {"pll1_48", "clk32", "pll1_96"}; | ||
125 | |||
118 | static DEFINE_SPINLOCK(reset_lock); | 126 | static DEFINE_SPINLOCK(reset_lock); |
119 | 127 | ||
120 | static struct mmp_param_mux_clk apbc_mux_clks[] = { | 128 | static 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 | ||
127 | static struct mmp_param_mux_clk apbcp_mux_clks[] = { | 137 | static 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 | ||
147 | static struct mmp_param_gate_clk apbcp_gate_clks[] = { | 159 | static 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 | ||
80 | static const char *sel_pll[] __initdata = { "pll", "ref_xtal", }; | 80 | static const char *const sel_pll[] __initconst = { "pll", "ref_xtal", }; |
81 | static const char *sel_cpu[] __initdata = { "ref_cpu", "ref_xtal", }; | 81 | static const char *const sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", }; |
82 | static const char *sel_pix[] __initdata = { "ref_pix", "ref_xtal", }; | 82 | static const char *const sel_pix[] __initconst = { "ref_pix", "ref_xtal", }; |
83 | static const char *sel_io[] __initdata = { "ref_io", "ref_xtal", }; | 83 | static const char *const sel_io[] __initconst = { "ref_io", "ref_xtal", }; |
84 | static const char *cpu_sels[] __initdata = { "cpu_pll", "cpu_xtal", }; | 84 | static const char *const cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", }; |
85 | static const char *emi_sels[] __initdata = { "emi_pll", "emi_xtal", }; | 85 | static const char *const emi_sels[] __initconst = { "emi_pll", "emi_xtal", }; |
86 | 86 | ||
87 | enum imx23_clk { | 87 | enum 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 | ||
128 | static const char *sel_cpu[] __initdata = { "ref_cpu", "ref_xtal", }; | 128 | static const char *const sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", }; |
129 | static const char *sel_io0[] __initdata = { "ref_io0", "ref_xtal", }; | 129 | static const char *const sel_io0[] __initconst = { "ref_io0", "ref_xtal", }; |
130 | static const char *sel_io1[] __initdata = { "ref_io1", "ref_xtal", }; | 130 | static const char *const sel_io1[] __initconst = { "ref_io1", "ref_xtal", }; |
131 | static const char *sel_pix[] __initdata = { "ref_pix", "ref_xtal", }; | 131 | static const char *const sel_pix[] __initconst = { "ref_pix", "ref_xtal", }; |
132 | static const char *sel_gpmi[] __initdata = { "ref_gpmi", "ref_xtal", }; | 132 | static const char *const sel_gpmi[] __initconst = { "ref_gpmi", "ref_xtal", }; |
133 | static const char *sel_pll0[] __initdata = { "pll0", "ref_xtal", }; | 133 | static const char *const sel_pll0[] __initconst = { "pll0", "ref_xtal", }; |
134 | static const char *cpu_sels[] __initdata = { "cpu_pll", "cpu_xtal", }; | 134 | static const char *const cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", }; |
135 | static const char *emi_sels[] __initdata = { "emi_pll", "emi_xtal", }; | 135 | static const char *const emi_sels[] __initconst = { "emi_pll", "emi_xtal", }; |
136 | static const char *ptp_sels[] __initdata = { "ref_xtal", "pll0", }; | 136 | static const char *const ptp_sels[] __initconst = { "ref_xtal", "pll0", }; |
137 | 137 | ||
138 | enum imx28_clk { | 138 | enum 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 | ||
51 | static inline struct clk *mxs_clk_mux(const char *name, void __iomem *reg, | 51 | static 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 | |||
53 | struct pistachio_clk_pll { | 68 | struct 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 | ||
85 | static 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 | |||
70 | static inline u32 do_div_round_closest(u64 dividend, u32 divisor) | 91 | static 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 | ||
233 | struct clk *rockchip_clk_register_cpuclk(const char *name, | 233 | struct 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 | ||
122 | struct clk *rockchip_clk_register_mmc(const char *name, | 122 | struct 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 | ||
331 | struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, | 331 | struct 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 | ||
29 | struct rockchip_pll_rate_table rk3188_pll_rates[] = { | 29 | static 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 | ||
30 | struct rockchip_pll_rate_table rk3288_pll_rates[] = { | 30 | static 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 | */ |
41 | static struct clk *rockchip_clk_register_branch(const char *name, | 41 | static 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 | ||
105 | static struct clk *rockchip_clk_register_frac_branch(const char *name, | 105 | static 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 | ||
299 | void __init rockchip_clk_register_armclk(unsigned int lookup_id, | 299 | void __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 { | |||
108 | struct rockchip_pll_clock { | 108 | struct 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 | ||
142 | struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, | 142 | struct 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 | ||
149 | struct rockchip_cpuclk_clksel { | 149 | struct rockchip_cpuclk_clksel { |
@@ -173,16 +173,16 @@ struct rockchip_cpuclk_reg_data { | |||
173 | }; | 173 | }; |
174 | 174 | ||
175 | struct clk *rockchip_clk_register_cpuclk(const char *name, | 175 | struct 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 | ||
181 | struct clk *rockchip_clk_register_mmc(const char *name, | 181 | struct 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 | ||
187 | enum rockchip_clk_branch_type { | 187 | enum 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, | |||
403 | void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list, | 403 | void 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); |
405 | void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name, | 405 | void 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"}; | |||
94 | PNAME(mout_sclk_aud_i2s_p) = {"mout_aud_pll_user", "ioclk_i2s_cdclk"}; | 94 | PNAME(mout_sclk_aud_i2s_p) = {"mout_aud_pll_user", "ioclk_i2s_cdclk"}; |
95 | PNAME(mout_sclk_aud_pcm_p) = {"mout_aud_pll_user", "ioclk_pcm_extclk"}; | 95 | PNAME(mout_sclk_aud_pcm_p) = {"mout_aud_pll_user", "ioclk_pcm_extclk"}; |
96 | 96 | ||
97 | struct samsung_mux_clock aud_mux_clks[] __initdata = { | 97 | static 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 | ||
106 | struct samsung_div_clock aud_div_clks[] __initdata = { | 106 | static 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 | ||
118 | struct samsung_gate_clock aud_gate_clks[] __initdata = { | 118 | static 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 | ||
136 | static void __init exynos5260_clk_aud_init(struct device_node *np) | 136 | static 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", | |||
203 | PNAME(mout_sclk_hdmi_spdif_p) = {"fin_pll", "ioclk_spdif_extclk", | 203 | PNAME(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 | ||
206 | struct samsung_mux_clock disp_mux_clks[] __initdata = { | 206 | static 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 | ||
275 | struct samsung_div_clock disp_div_clks[] __initdata = { | 275 | static 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 | ||
288 | struct samsung_gate_clock disp_gate_clks[] __initdata = { | 288 | static 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 | ||
326 | static void __init exynos5260_clk_disp_init(struct device_node *np) | 326 | static 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 = { | |||
363 | PNAME(mout_egl_b_p) = {"mout_egl_pll", "dout_bus_pll"}; | 363 | PNAME(mout_egl_b_p) = {"mout_egl_pll", "dout_bus_pll"}; |
364 | PNAME(mout_egl_pll_p) = {"fin_pll", "fout_egl_pll"}; | 364 | PNAME(mout_egl_pll_p) = {"fin_pll", "fout_egl_pll"}; |
365 | 365 | ||
366 | struct samsung_mux_clock egl_mux_clks[] __initdata = { | 366 | static 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 | ||
372 | struct samsung_div_clock egl_div_clks[] __initdata = { | 372 | static 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 | ||
390 | static void __init exynos5260_clk_egl_init(struct device_node *np) | 390 | static 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", | |||
433 | PNAME(mout_phyclk_usbdrd30_phyclock_user_p) = {"fin_pll", | 433 | PNAME(mout_phyclk_usbdrd30_phyclock_user_p) = {"fin_pll", |
434 | "phyclk_usbdrd30_udrd30_phyclock"}; | 434 | "phyclk_usbdrd30_udrd30_phyclock"}; |
435 | 435 | ||
436 | struct samsung_mux_clock fsys_mux_clks[] __initdata = { | 436 | static 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 | ||
459 | struct samsung_gate_clock fsys_gate_clks[] __initdata = { | 459 | static 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 | ||
492 | static void __init exynos5260_clk_fsys_init(struct device_node *np) | 492 | static 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 | ||
538 | PNAME(mout_aclk_g2d_333_user_p) = {"fin_pll", "dout_aclk_g2d_333"}; | 538 | PNAME(mout_aclk_g2d_333_user_p) = {"fin_pll", "dout_aclk_g2d_333"}; |
539 | 539 | ||
540 | struct samsung_mux_clock g2d_mux_clks[] __initdata = { | 540 | static 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 | ||
546 | struct samsung_div_clock g2d_div_clks[] __initdata = { | 546 | static 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 | ||
551 | struct samsung_gate_clock g2d_gate_clks[] __initdata = { | 551 | static 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 | ||
581 | static void __init exynos5260_clk_g2d_init(struct device_node *np) | 581 | static 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 | ||
618 | PNAME(mout_g3d_pll_p) = {"fin_pll", "fout_g3d_pll"}; | 618 | PNAME(mout_g3d_pll_p) = {"fin_pll", "fout_g3d_pll"}; |
619 | 619 | ||
620 | struct samsung_mux_clock g3d_mux_clks[] __initdata = { | 620 | static 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 | ||
625 | struct samsung_div_clock g3d_div_clks[] __initdata = { | 625 | static 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 | ||
630 | struct samsung_gate_clock g3d_gate_clks[] __initdata = { | 630 | static 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 | ||
642 | static void __init exynos5260_clk_g3d_init(struct device_node *np) | 642 | static 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"}; | |||
694 | PNAME(mout_aclk_gscl_fimc_user_p) = {"fin_pll", "dout_aclk_gscl_400"}; | 694 | PNAME(mout_aclk_gscl_fimc_user_p) = {"fin_pll", "dout_aclk_gscl_400"}; |
695 | PNAME(mout_aclk_csis_p) = {"dout_aclk_csis_200", "mout_aclk_gscl_fimc_user"}; | 695 | PNAME(mout_aclk_csis_p) = {"dout_aclk_csis_200", "mout_aclk_gscl_fimc_user"}; |
696 | 696 | ||
697 | struct samsung_mux_clock gscl_mux_clks[] __initdata = { | 697 | static 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 | ||
711 | struct samsung_div_clock gscl_div_clks[] __initdata = { | 711 | static 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 | ||
720 | struct samsung_gate_clock gscl_gate_clks[] __initdata = { | 720 | static 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 | ||
777 | static void __init exynos5260_clk_gscl_init(struct device_node *np) | 777 | static 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 = { | |||
813 | PNAME(mout_isp_400_user_p) = {"fin_pll", "dout_aclk_isp1_400"}; | 813 | PNAME(mout_isp_400_user_p) = {"fin_pll", "dout_aclk_isp1_400"}; |
814 | PNAME(mout_isp_266_user_p) = {"fin_pll", "dout_aclk_isp1_266"}; | 814 | PNAME(mout_isp_266_user_p) = {"fin_pll", "dout_aclk_isp1_266"}; |
815 | 815 | ||
816 | struct samsung_mux_clock isp_mux_clks[] __initdata = { | 816 | static 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 | ||
823 | struct samsung_div_clock isp_div_clks[] __initdata = { | 823 | static 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 | ||
835 | struct samsung_gate_clock isp_gate_clks[] __initdata = { | 835 | static 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 | ||
896 | static void __init exynos5260_clk_isp_init(struct device_node *np) | 896 | static 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 = { | |||
934 | PNAME(mout_kfc_pll_p) = {"fin_pll", "fout_kfc_pll"}; | 934 | PNAME(mout_kfc_pll_p) = {"fin_pll", "fout_kfc_pll"}; |
935 | PNAME(mout_kfc_p) = {"mout_kfc_pll", "dout_media_pll"}; | 935 | PNAME(mout_kfc_p) = {"mout_kfc_pll", "dout_media_pll"}; |
936 | 936 | ||
937 | struct samsung_mux_clock kfc_mux_clks[] __initdata = { | 937 | static 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 | ||
943 | struct samsung_div_clock kfc_div_clks[] __initdata = { | 943 | static 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 | ||
960 | static void __init exynos5260_clk_kfc_init(struct device_node *np) | 960 | static 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 | ||
994 | PNAME(mout_aclk_mfc_333_user_p) = {"fin_pll", "dout_aclk_mfc_333"}; | 994 | PNAME(mout_aclk_mfc_333_user_p) = {"fin_pll", "dout_aclk_mfc_333"}; |
995 | 995 | ||
996 | struct samsung_mux_clock mfc_mux_clks[] __initdata = { | 996 | static 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 | ||
1002 | struct samsung_div_clock mfc_div_clks[] __initdata = { | 1002 | static 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 | ||
1007 | struct samsung_gate_clock mfc_gate_clks[] __initdata = { | 1007 | static 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 | ||
1016 | static void __init exynos5260_clk_mfc_init(struct device_node *np) | 1016 | static 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"}; | |||
1078 | PNAME(mout_clkm_phy_p) = {"mout_mif_drex", "dout_media_pll"}; | 1078 | PNAME(mout_clkm_phy_p) = {"mout_mif_drex", "dout_media_pll"}; |
1079 | PNAME(mout_clk2x_phy_p) = {"mout_mif_drex2x", "dout_media_pll"}; | 1079 | PNAME(mout_clk2x_phy_p) = {"mout_mif_drex2x", "dout_media_pll"}; |
1080 | 1080 | ||
1081 | struct samsung_mux_clock mif_mux_clks[] __initdata = { | 1081 | static 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 | ||
1098 | struct samsung_div_clock mif_div_clks[] __initdata = { | 1098 | static 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 | ||
1117 | struct samsung_gate_clock mif_gate_clks[] __initdata = { | 1117 | static 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 | ||
1163 | static void __init exynos5260_clk_mif_init(struct device_node *np) | 1163 | static 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", | |||
1221 | PNAME(mout_sclk_spdif_p) = {"ioclk_spdif_extclk", "fin_pll", | 1221 | PNAME(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 | ||
1224 | struct samsung_mux_clock peri_mux_clks[] __initdata = { | 1224 | static 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 | ||
1233 | struct samsung_div_clock peri_div_clks[] __initdata = { | 1233 | static 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 | ||
1238 | struct samsung_gate_clock peri_gate_clks[] __initdata = { | 1238 | static 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 | ||
1371 | static void __init exynos5260_clk_peri_init(struct device_node *np) | 1371 | static 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 */ |
1435 | struct samsung_fixed_rate_clock fixed_rate_clks[] __initdata = { | 1435 | static 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", | |||
1519 | PNAME(mout_sclk_fsys_mmc2_sdclkin_b_p) = {"mout_sclk_fsys_mmc2_sdclkin_a", | 1519 | PNAME(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 | ||
1522 | struct samsung_mux_clock top_mux_clks[] __initdata = { | 1522 | static 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 | ||
1682 | struct samsung_div_clock top_div_clks[] __initdata = { | 1682 | static 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 | ||
1803 | struct samsung_gate_clock top_gate_clks[] __initdata = { | 1803 | static 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 | ||
1827 | static void __init exynos5260_clk_top_init(struct device_node *np) | 1827 | static 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 | ||
507 | struct samsung_mux_clock exynos5800_mux_clks[] __initdata = { | 507 | static 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 | ||
556 | struct samsung_div_clock exynos5800_div_clks[] __initdata = { | 556 | static 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 | ||
572 | struct samsung_gate_clock exynos5800_gate_clks[] __initdata = { | 572 | static 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 | ||
579 | struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { | 579 | static 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 | ||
609 | struct samsung_div_clock exynos5420_div_clks[] __initdata = { | 609 | static 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 | ||
3287 | static struct samsung_mux_clock g3d_mux_clks[] __initdata = { | 3288 | static 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 | ||
3295 | static struct samsung_div_clock g3d_div_clks[] __initdata = { | 3296 | static 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 | ||
3305 | static struct samsung_gate_clock g3d_gate_clks[] __initdata = { | 3306 | static 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 = { | |||
3582 | static struct samsung_mux_clock apollo_mux_clks[] __initdata = { | 3583 | static 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 | ||
3596 | static struct samsung_div_clock apollo_div_clks[] __initdata = { | 3597 | static 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 | ||
3672 | static struct samsung_cmu_info apollo_cmu_info __initdata = { | 3672 | static struct samsung_cmu_info apollo_cmu_info __initdata = { |
@@ -3775,7 +3775,7 @@ static struct samsung_pll_clock atlas_pll_clks[] __initdata = { | |||
3775 | static struct samsung_mux_clock atlas_mux_clks[] __initdata = { | 3775 | static 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 | ||
3789 | static struct samsung_div_clock atlas_div_clks[] __initdata = { | 3789 | static 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 | ||
3891 | static struct samsung_cmu_info atlas_cmu_info __initdata = { | 3890 | static 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 | ||
1158 | static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, | 1158 | static 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 | ||
1305 | void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, | 1305 | void __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 | ||
84 | const struct clk_ops s3c24xx_clkout_ops = { | 84 | static 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 | ||
90 | struct clk *s3c24xx_register_clkout(struct device *dev, const char *name, | 90 | static 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 | ||
407 | static struct platform_device_id s3c24xx_dclk_driver_ids[] = { | 407 | static 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. */ |
172 | static const char *fin_pll_p[] __initdata = { | 172 | static const char *const fin_pll_p[] __initconst = { |
173 | "xxti", | 173 | "xxti", |
174 | "xusbxti" | 174 | "xusbxti" |
175 | }; | 175 | }; |
176 | 176 | ||
177 | static const char *mout_apll_p[] __initdata = { | 177 | static const char *const mout_apll_p[] __initconst = { |
178 | "fin_pll", | 178 | "fin_pll", |
179 | "fout_apll" | 179 | "fout_apll" |
180 | }; | 180 | }; |
181 | 181 | ||
182 | static const char *mout_mpll_p[] __initdata = { | 182 | static const char *const mout_mpll_p[] __initconst = { |
183 | "fin_pll", | 183 | "fin_pll", |
184 | "fout_mpll" | 184 | "fout_mpll" |
185 | }; | 185 | }; |
186 | 186 | ||
187 | static const char *mout_epll_p[] __initdata = { | 187 | static const char *const mout_epll_p[] __initconst = { |
188 | "fin_pll", | 188 | "fin_pll", |
189 | "fout_epll" | 189 | "fout_epll" |
190 | }; | 190 | }; |
191 | 191 | ||
192 | static const char *mout_vpllsrc_p[] __initdata = { | 192 | static const char *const mout_vpllsrc_p[] __initconst = { |
193 | "fin_pll", | 193 | "fin_pll", |
194 | "sclk_hdmi27m" | 194 | "sclk_hdmi27m" |
195 | }; | 195 | }; |
196 | 196 | ||
197 | static const char *mout_vpll_p[] __initdata = { | 197 | static const char *const mout_vpll_p[] __initconst = { |
198 | "mout_vpllsrc", | 198 | "mout_vpllsrc", |
199 | "fout_vpll" | 199 | "fout_vpll" |
200 | }; | 200 | }; |
201 | 201 | ||
202 | static const char *mout_group1_p[] __initdata = { | 202 | static 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 | ||
209 | static const char *mout_group2_p[] __initdata = { | 209 | static 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 | ||
221 | static const char *mout_audio0_p[] __initdata = { | 221 | static 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 | ||
233 | static const char *mout_audio1_p[] __initdata = { | 233 | static 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 | ||
245 | static const char *mout_audio2_p[] __initdata = { | 245 | static 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 | ||
257 | static const char *mout_spdif_p[] __initdata = { | 257 | static 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 | ||
263 | static const char *mout_group3_p[] __initdata = { | 263 | static const char *const mout_group3_p[] __initconst = { |
264 | "mout_apll", | 264 | "mout_apll", |
265 | "mout_mpll" | 265 | "mout_mpll" |
266 | }; | 266 | }; |
267 | 267 | ||
268 | static const char *mout_group4_p[] __initdata = { | 268 | static const char *const mout_group4_p[] __initconst = { |
269 | "mout_mpll", | 269 | "mout_mpll", |
270 | "dout_a2m" | 270 | "dout_a2m" |
271 | }; | 271 | }; |
272 | 272 | ||
273 | static const char *mout_flash_p[] __initdata = { | 273 | static const char *const mout_flash_p[] __initconst = { |
274 | "dout_hclkd", | 274 | "dout_hclkd", |
275 | "dout_hclkp" | 275 | "dout_hclkp" |
276 | }; | 276 | }; |
277 | 277 | ||
278 | static const char *mout_dac_p[] __initdata = { | 278 | static const char *const mout_dac_p[] __initconst = { |
279 | "mout_vpll", | 279 | "mout_vpll", |
280 | "sclk_hdmiphy" | 280 | "sclk_hdmiphy" |
281 | }; | 281 | }; |
282 | 282 | ||
283 | static const char *mout_hdmi_p[] __initdata = { | 283 | static const char *const mout_hdmi_p[] __initconst = { |
284 | "sclk_hdmiphy", | 284 | "sclk_hdmiphy", |
285 | "dout_tblk" | 285 | "dout_tblk" |
286 | }; | 286 | }; |
287 | 287 | ||
288 | static const char *mout_mixer_p[] __initdata = { | 288 | static const char *const mout_mixer_p[] __initconst = { |
289 | "mout_dac", | 289 | "mout_dac", |
290 | "mout_hdmi" | 290 | "mout_hdmi" |
291 | }; | 291 | }; |
292 | 292 | ||
293 | static const char *mout_vpll_6442_p[] __initdata = { | 293 | static const char *const mout_vpll_6442_p[] __initconst = { |
294 | "fin_pll", | 294 | "fin_pll", |
295 | "fout_vpll" | 295 | "fout_vpll" |
296 | }; | 296 | }; |
297 | 297 | ||
298 | static const char *mout_mixer_6442_p[] __initdata = { | 298 | static const char *const mout_mixer_6442_p[] __initconst = { |
299 | "mout_vpll", | 299 | "mout_vpll", |
300 | "dout_mixer" | 300 | "dout_mixer" |
301 | }; | 301 | }; |
302 | 302 | ||
303 | static const char *mout_d0sync_6442_p[] __initdata = { | 303 | static const char *const mout_d0sync_6442_p[] __initconst = { |
304 | "mout_dsys", | 304 | "mout_dsys", |
305 | "div_apll" | 305 | "div_apll" |
306 | }; | 306 | }; |
307 | 307 | ||
308 | static const char *mout_d1sync_6442_p[] __initdata = { | 308 | static const char *const mout_d1sync_6442_p[] __initconst = { |
309 | "mout_psys", | 309 | "mout_psys", |
310 | "div_apll" | 310 | "div_apll" |
311 | }; | 311 | }; |
312 | 312 | ||
313 | static const char *mout_group2_6442_p[] __initdata = { | 313 | static 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 | ||
325 | static const char *mout_audio0_6442_p[] __initdata = { | 325 | static 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 | ||
337 | static const char *mout_audio1_6442_p[] __initdata = { | 337 | static 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 | ||
350 | static const char *mout_clksel_p[] __initdata = { | 350 | static 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 | ||
373 | static const char *mout_clksel_6442_p[] __initdata = { | 373 | static 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 | ||
396 | static const char *mout_clkout_p[] __initdata = { | 396 | static 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. */ |
404 | static struct samsung_fixed_factor_clock ffactor_clks[] __initdata = { | 404 | static 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. */ |
411 | static struct samsung_mux_clock early_mux_clks[] __initdata = { | 411 | static 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. */ |
417 | static struct samsung_mux_clock mux_clks[] __initdata = { | 417 | static 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. */ |
430 | static struct samsung_mux_clock s5pv210_mux_clks[] __initdata = { | 430 | static 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. */ |
475 | static struct samsung_mux_clock s5p6442_mux_clks[] __initdata = { | 475 | static 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. */ |
507 | static struct samsung_fixed_rate_clock s5pv210_frate_clks[] __initdata = { | 507 | static 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. */ |
515 | static struct samsung_fixed_rate_clock s5p6442_frate_clks[] __initdata = { | 515 | static 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. */ |
520 | static struct samsung_div_clock div_clks[] __initdata = { | 520 | static 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. */ |
552 | static struct samsung_div_clock s5pv210_div_clks[] __initdata = { | 552 | static 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. */ |
581 | static struct samsung_div_clock s5p6442_div_clks[] __initdata = { | 581 | static 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. */ |
589 | static struct samsung_gate_clock gate_clks[] __initdata = { | 589 | static 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. */ |
669 | static struct samsung_gate_clock s5pv210_gate_clks[] __initdata = { | 669 | static 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. */ |
731 | static struct samsung_gate_clock s5p6442_gate_clks[] __initdata = { | 731 | static 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 | */ |
751 | static struct samsung_clock_alias s5pv210_aliases[] = { | 751 | static 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. */ |
758 | static struct samsung_pll_clock s5pv210_pll_clks[] __initdata = { | 758 | static 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. */ |
770 | static struct samsung_pll_clock s5p6442_pll_clks[] __initdata = { | 770 | static 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 */ |
100 | void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, | 100 | void __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 */ |
134 | void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx, | 134 | void __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 */ |
163 | void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx, | 164 | void __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 */ |
183 | void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, | 184 | void __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 */ |
215 | void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, | 216 | void __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 */ |
254 | void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, | 255 | void __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( | |||
368 | extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, | 368 | extern 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 | ||
371 | extern void samsung_clk_register_alias(struct samsung_clk_provider *ctx, | 371 | extern 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); |
374 | extern void __init samsung_clk_register_fixed_rate( | 374 | extern 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); |
378 | extern void __init samsung_clk_register_fixed_factor( | 378 | extern 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); |
382 | extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, | 382 | extern 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); |
385 | extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, | 385 | extern 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); |
388 | extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, | 388 | extern 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); |
391 | extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, | 391 | extern 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 | ||
395 | extern struct samsung_clk_provider __init *samsung_cmu_register_one( | 395 | extern 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 @@ | |||
34 | static DEFINE_SPINLOCK(lock); | 34 | static DEFINE_SPINLOCK(lock); |
35 | 35 | ||
36 | /* not pretty, but hey */ | 36 | /* not pretty, but hey */ |
37 | void __iomem *smu_base; | 37 | static void __iomem *smu_base; |
38 | 38 | ||
39 | static void __init emev2_smu_write(unsigned long value, int offs) | 39 | static 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 | ||
5 | obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o clk-atlas6.o | 5 | obj-$(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 | |||
209 | static void __iomem *sirfsoc_clk_vbase; | ||
210 | static struct clk_onecell_data clk_data; | ||
211 | |||
212 | static 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 | |||
221 | struct 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 | |||
227 | struct 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 | |||
234 | struct 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 | |||
242 | struct 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 | |||
257 | struct 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 | |||
268 | struct 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 | |||
278 | struct 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 | |||
287 | static DEFINE_SPINLOCK(cpupll_ctrl1_lock); | ||
288 | static DEFINE_SPINLOCK(mempll_ctrl1_lock); | ||
289 | static DEFINE_SPINLOCK(sys0pll_ctrl1_lock); | ||
290 | static DEFINE_SPINLOCK(sys1pll_ctrl1_lock); | ||
291 | static DEFINE_SPINLOCK(sys2pll_ctrl1_lock); | ||
292 | static DEFINE_SPINLOCK(sys3pll_ctrl1_lock); | ||
293 | static DEFINE_SPINLOCK(usbphy_div_lock); | ||
294 | static DEFINE_SPINLOCK(btss_div_lock); | ||
295 | static DEFINE_SPINLOCK(rgmii_div_lock); | ||
296 | static DEFINE_SPINLOCK(cpu_div_lock); | ||
297 | static DEFINE_SPINLOCK(sdphy01_div_lock); | ||
298 | static DEFINE_SPINLOCK(sdphy23_div_lock); | ||
299 | static DEFINE_SPINLOCK(sdphy45_div_lock); | ||
300 | static DEFINE_SPINLOCK(sdphy67_div_lock); | ||
301 | static DEFINE_SPINLOCK(can_div_lock); | ||
302 | static DEFINE_SPINLOCK(deint_div_lock); | ||
303 | static DEFINE_SPINLOCK(nand_div_lock); | ||
304 | static DEFINE_SPINLOCK(disp0_div_lock); | ||
305 | static DEFINE_SPINLOCK(disp1_div_lock); | ||
306 | static DEFINE_SPINLOCK(gpu_div_lock); | ||
307 | static DEFINE_SPINLOCK(gnss_div_lock); | ||
308 | /* gate register shared */ | ||
309 | static DEFINE_SPINLOCK(share_div_lock); | ||
310 | static DEFINE_SPINLOCK(root0_gate_lock); | ||
311 | static DEFINE_SPINLOCK(root1_gate_lock); | ||
312 | static DEFINE_SPINLOCK(leaf0_gate_lock); | ||
313 | static DEFINE_SPINLOCK(leaf1_gate_lock); | ||
314 | static DEFINE_SPINLOCK(leaf2_gate_lock); | ||
315 | static DEFINE_SPINLOCK(leaf3_gate_lock); | ||
316 | static DEFINE_SPINLOCK(leaf4_gate_lock); | ||
317 | static DEFINE_SPINLOCK(leaf5_gate_lock); | ||
318 | static DEFINE_SPINLOCK(leaf6_gate_lock); | ||
319 | static DEFINE_SPINLOCK(leaf7_gate_lock); | ||
320 | static DEFINE_SPINLOCK(leaf8_gate_lock); | ||
321 | |||
322 | static inline unsigned long clkc_readl(unsigned reg) | ||
323 | { | ||
324 | return readl(sirfsoc_clk_vbase + reg); | ||
325 | } | ||
326 | |||
327 | static 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 | */ | ||
338 | static 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 | |||
371 | static const struct clk_ops ab_pll_ops = { | ||
372 | .recalc_rate = pll_clk_recalc_rate, | ||
373 | }; | ||
374 | |||
375 | static const char * const pll_clk_parents[] = { | ||
376 | "xin", | ||
377 | }; | ||
378 | |||
379 | static 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 | |||
386 | static struct clk_pll clk_cpupll = { | ||
387 | .regofs = SIRFSOC_CLKC_CPUPLL_AB_FREQ, | ||
388 | .hw = { | ||
389 | .init = &clk_cpupll_init, | ||
390 | }, | ||
391 | }; | ||
392 | |||
393 | static 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 | |||
400 | static struct clk_pll clk_mempll = { | ||
401 | .regofs = SIRFSOC_CLKC_MEMPLL_AB_FREQ, | ||
402 | .hw = { | ||
403 | .init = &clk_mempll_init, | ||
404 | }, | ||
405 | }; | ||
406 | |||
407 | static 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 | |||
414 | static struct clk_pll clk_sys0pll = { | ||
415 | .regofs = SIRFSOC_CLKC_SYS0PLL_AB_FREQ, | ||
416 | .hw = { | ||
417 | .init = &clk_sys0pll_init, | ||
418 | }, | ||
419 | }; | ||
420 | |||
421 | static 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 | |||
428 | static struct clk_pll clk_sys1pll = { | ||
429 | .regofs = SIRFSOC_CLKC_SYS1PLL_AB_FREQ, | ||
430 | .hw = { | ||
431 | .init = &clk_sys1pll_init, | ||
432 | }, | ||
433 | }; | ||
434 | |||
435 | static 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 | |||
442 | static struct clk_pll clk_sys2pll = { | ||
443 | .regofs = SIRFSOC_CLKC_SYS2PLL_AB_FREQ, | ||
444 | .hw = { | ||
445 | .init = &clk_sys2pll_init, | ||
446 | }, | ||
447 | }; | ||
448 | |||
449 | static 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 | |||
456 | static 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 | */ | ||
468 | static 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 | |||
478 | static 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 | |||
490 | static 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 | |||
501 | static 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 | |||
519 | static 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 | |||
531 | static 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 | |||
544 | static 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 | */ | ||
554 | static 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 | |||
562 | static 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 */ | ||
574 | static const char * const audiodto_clk_parents[] = { | ||
575 | "sys0pll_clk1", | ||
576 | "sys1pll_clk1", | ||
577 | "sys3pll_clk1", | ||
578 | }; | ||
579 | |||
580 | static 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 | |||
587 | static 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 | |||
595 | static const char * const disp0dto_clk_parents[] = { | ||
596 | "sys0pll_clk1", | ||
597 | "sys1pll_clk1", | ||
598 | "sys3pll_clk1", | ||
599 | }; | ||
600 | |||
601 | static 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 | |||
608 | static 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 | |||
616 | static const char * const disp1dto_clk_parents[] = { | ||
617 | "sys0pll_clk1", | ||
618 | "sys1pll_clk1", | ||
619 | "sys3pll_clk1", | ||
620 | }; | ||
621 | |||
622 | static 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 | |||
629 | static 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 | |||
637 | static 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 | |||
705 | static const char * const i2s_clk_parents[] = { | ||
706 | "xin", | ||
707 | "xinw", | ||
708 | "audio_dto", | ||
709 | /* "pwm_i2s01" */ | ||
710 | }; | ||
711 | |||
712 | static const char * const usbphy_clk_parents[] = { | ||
713 | "xin", | ||
714 | "xinw", | ||
715 | "sys0pll_a1", | ||
716 | "sys1pll_a1", | ||
717 | "sys2pll_a1", | ||
718 | "sys3pll_a1", | ||
719 | }; | ||
720 | |||
721 | static const char * const btss_clk_parents[] = { | ||
722 | "xin", | ||
723 | "xinw", | ||
724 | "sys0pll_a2", | ||
725 | "sys1pll_a2", | ||
726 | "sys2pll_a2", | ||
727 | "sys3pll_a2", | ||
728 | }; | ||
729 | |||
730 | static const char * const rgmii_clk_parents[] = { | ||
731 | "xin", | ||
732 | "xinw", | ||
733 | "sys0pll_a3", | ||
734 | "sys1pll_a3", | ||
735 | "sys2pll_a3", | ||
736 | "sys3pll_a3", | ||
737 | }; | ||
738 | |||
739 | static const char * const cpu_clk_parents[] = { | ||
740 | "xin", | ||
741 | "xinw", | ||
742 | "sys0pll_a4", | ||
743 | "sys1pll_a4", | ||
744 | "cpupll_clk1", | ||
745 | }; | ||
746 | |||
747 | static const char * const sdphy01_clk_parents[] = { | ||
748 | "xin", | ||
749 | "xinw", | ||
750 | "sys0pll_a5", | ||
751 | "sys1pll_a5", | ||
752 | "sys2pll_a5", | ||
753 | "sys3pll_a5", | ||
754 | }; | ||
755 | |||
756 | static const char * const sdphy23_clk_parents[] = { | ||
757 | "xin", | ||
758 | "xinw", | ||
759 | "sys0pll_a6", | ||
760 | "sys1pll_a6", | ||
761 | "sys2pll_a6", | ||
762 | "sys3pll_a6", | ||
763 | }; | ||
764 | |||
765 | static const char * const sdphy45_clk_parents[] = { | ||
766 | "xin", | ||
767 | "xinw", | ||
768 | "sys0pll_a7", | ||
769 | "sys1pll_a7", | ||
770 | "sys2pll_a7", | ||
771 | "sys3pll_a7", | ||
772 | }; | ||
773 | |||
774 | static const char * const sdphy67_clk_parents[] = { | ||
775 | "xin", | ||
776 | "xinw", | ||
777 | "sys0pll_a8", | ||
778 | "sys1pll_a8", | ||
779 | "sys2pll_a8", | ||
780 | "sys3pll_a8", | ||
781 | }; | ||
782 | |||
783 | static const char * const can_clk_parents[] = { | ||
784 | "xin", | ||
785 | "xinw", | ||
786 | "sys0pll_a9", | ||
787 | "sys1pll_a9", | ||
788 | "sys2pll_a9", | ||
789 | "sys3pll_a9", | ||
790 | }; | ||
791 | |||
792 | static const char * const deint_clk_parents[] = { | ||
793 | "xin", | ||
794 | "xinw", | ||
795 | "sys0pll_a10", | ||
796 | "sys1pll_a10", | ||
797 | "sys2pll_a10", | ||
798 | "sys3pll_a10", | ||
799 | }; | ||
800 | |||
801 | static const char * const nand_clk_parents[] = { | ||
802 | "xin", | ||
803 | "xinw", | ||
804 | "sys0pll_a11", | ||
805 | "sys1pll_a11", | ||
806 | "sys2pll_a11", | ||
807 | "sys3pll_a11", | ||
808 | }; | ||
809 | |||
810 | static 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 | |||
820 | static 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 | |||
830 | static const char * const gpu_clk_parents[] = { | ||
831 | "xin", | ||
832 | "xinw", | ||
833 | "sys0pll_a14", | ||
834 | "sys1pll_a14", | ||
835 | "sys2pll_a14", | ||
836 | "sys3pll_a14", | ||
837 | }; | ||
838 | |||
839 | static const char * const gnss_clk_parents[] = { | ||
840 | "xin", | ||
841 | "xinw", | ||
842 | "sys0pll_a15", | ||
843 | "sys1pll_a15", | ||
844 | "sys2pll_a15", | ||
845 | "sys3pll_a15", | ||
846 | }; | ||
847 | |||
848 | static 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 | |||
859 | static 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 | |||
870 | static 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 | |||
881 | static 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 | |||
892 | static 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 | |||
903 | static 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 | |||
914 | static 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 | |||
925 | static 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 | |||
936 | static 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 | |||
947 | static 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 | |||
958 | static 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 | |||
969 | static 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 | |||
980 | static 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 | |||
991 | static 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 | |||
1002 | static 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 */ | ||
1037 | static 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 | |||
1179 | static struct clk *atlas7_clks[ARRAY_SIZE(unit_list)]; | ||
1180 | |||
1181 | static 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 | |||
1191 | static 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 | |||
1205 | static 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 | |||
1218 | static 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 | |||
1224 | static struct clk * __init | ||
1225 | atlas7_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 | |||
1255 | static 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 | |||
1339 | static 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 | |||
1376 | static struct reset_control_ops atlas7_rst_ops = { | ||
1377 | .reset = atlas7_reset_module, | ||
1378 | }; | ||
1379 | |||
1380 | static struct reset_controller_dev atlas7_rst_ctlr = { | ||
1381 | .ops = &atlas7_rst_ops, | ||
1382 | .owner = THIS_MODULE, | ||
1383 | .of_reset_n_cells = 1, | ||
1384 | }; | ||
1385 | |||
1386 | static 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 = ÷r_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 | } | ||
1632 | CLK_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 | ||
13 | static void *sirfsoc_clk_vbase; | 13 | static void __iomem *sirfsoc_clk_vbase; |
14 | static void *sirfsoc_rsc_vbase; | 14 | static void __iomem *sirfsoc_rsc_vbase; |
15 | static struct clk_onecell_data clk_data; | 15 | static 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 | ||
191 | static const char *pll_clk_parents[] = { | 191 | static 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 | ||
287 | static const char *dmn_clk_parents[] = { | 287 | static 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 | ||
676 | static const char *std_clk_io_parents[] = { | 676 | static 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 | ||
952 | static const char *std_clk_dsp_parents[] = { | 952 | static 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 | ||
984 | static const char *std_clk_sys_parents[] = { | 984 | static 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 | ||
1002 | static const char *std_clk_usb_parents[] = { | 1002 | static 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 | |||
2 | obj-y += clk-gate.o | 2 | obj-y += clk-gate.o |
3 | obj-y += clk-pll.o | 3 | obj-y += clk-pll.o |
4 | obj-y += clk-periph.o | 4 | obj-y += clk-periph.o |
5 | obj-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 | |||
31 | static 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 | |||
48 | static 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 | |||
99 | static struct clk_ops gateclk_ops = { | ||
100 | .prepare = socfpga_clk_prepare, | ||
101 | .recalc_rate = socfpga_gate_clk_recalc_rate, | ||
102 | }; | ||
103 | |||
104 | static 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 | |||
187 | void __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 | ||
44 | static u8 socfpga_clk_get_parent(struct clk_hw *hwclk) | 40 | static 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 | |||
30 | static 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 | |||
49 | static 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 | |||
64 | static const struct clk_ops periclk_ops = { | ||
65 | .recalc_rate = clk_periclk_recalc_rate, | ||
66 | .get_parent = clk_periclk_get_parent, | ||
67 | }; | ||
68 | |||
69 | static __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", ®); | ||
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 | |||
131 | err_clk: | ||
132 | clk_unregister(clk); | ||
133 | } | ||
134 | |||
135 | void __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 | |||
42 | void __iomem *clk_mgr_a10_base_addr; | ||
43 | |||
44 | static 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 | |||
60 | static 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 | |||
71 | static struct clk_ops clk_pll_ops = { | ||
72 | .recalc_rate = clk_pll_recalc_rate, | ||
73 | .get_parent = clk_pll_get_parent, | ||
74 | }; | ||
75 | |||
76 | static 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", ®); | ||
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 | |||
126 | void __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", ®); | 96 | of_property_read_u32(node, "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 @@ | |||
24 | CLK_OF_DECLARE(socfpga_pll_clk, "altr,socfpga-pll-clock", socfpga_pll_init); | 24 | CLK_OF_DECLARE(socfpga_pll_clk, "altr,socfpga-pll-clock", socfpga_pll_init); |
25 | CLK_OF_DECLARE(socfpga_perip_clk, "altr,socfpga-perip-clk", socfpga_periph_init); | 25 | CLK_OF_DECLARE(socfpga_perip_clk, "altr,socfpga-perip-clk", socfpga_periph_init); |
26 | CLK_OF_DECLARE(socfpga_gate_clk, "altr,socfpga-gate-clk", socfpga_gate_init); | 26 | CLK_OF_DECLARE(socfpga_gate_clk, "altr,socfpga-gate-clk", socfpga_gate_init); |
27 | 27 | CLK_OF_DECLARE(socfpga_a10_pll_clk, "altr,socfpga-a10-pll-clock", | |
28 | socfpga_a10_pll_init); | ||
29 | CLK_OF_DECLARE(socfpga_a10_perip_clk, "altr,socfpga-a10-perip-clk", | ||
30 | socfpga_a10_periph_init); | ||
31 | CLK_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 | |||
32 | extern void __iomem *clk_mgr_base_addr; | 36 | extern void __iomem *clk_mgr_base_addr; |
37 | extern void __iomem *clk_mgr_a10_base_addr; | ||
33 | 38 | ||
34 | void __init socfpga_pll_init(struct device_node *node); | 39 | void __init socfpga_pll_init(struct device_node *node); |
35 | void __init socfpga_periph_init(struct device_node *node); | 40 | void __init socfpga_periph_init(struct device_node *node); |
36 | void __init socfpga_gate_init(struct device_node *node); | 41 | void __init socfpga_gate_init(struct device_node *node); |
42 | void socfpga_a10_pll_init(struct device_node *node); | ||
43 | void socfpga_a10_periph_init(struct device_node *node); | ||
44 | void socfpga_a10_gate_init(struct device_node *node); | ||
37 | 45 | ||
38 | struct socfpga_pll { | 46 | struct 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 | ||
119 | unsigned long flexgen_recalc_rate(struct clk_hw *hw, | 119 | static 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 | ||
177 | struct clk *clk_register_flexgen(const char *name, | 177 | static 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 | ||
263 | void __init st_of_flexgen_setup(struct device_node *np) | 263 | static 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 | ||
495 | int clk_fs660c32_vco_get_rate(unsigned long input, struct stm_fs *fs, | 495 | static 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 | ||
522 | int clk_fs660c32_vco_get_params(unsigned long input, | 522 | static 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 | ||
134 | u8 clkgena_divmux_get_parent(struct clk_hw *hw) | 134 | static 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 | ||
171 | unsigned long clkgena_divmux_recalc_rate(struct clk_hw *hw, | 171 | static 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 | */ |
218 | struct clk *clk_register_genamux(const char *name, | 218 | static 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 | ||
388 | void __init st_of_clkgena_divmux_setup(struct device_node *np) | 388 | static 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 | ||
488 | void __init st_of_clkgena_prediv_setup(struct device_node *np) | 488 | static 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 | ||
625 | void __init st_of_clkgen_mux_setup(struct device_node *np) | 625 | static 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 | ||
702 | void __init st_of_clkgen_vcc_setup(struct device_node *np) | 702 | static 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 | ||
273 | unsigned long recalc_stm_pll800c65(struct clk_hw *hw, | 273 | static 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 | ||
300 | unsigned long recalc_stm_pll1600c65(struct clk_hw *hw, | 300 | static 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 | ||
324 | unsigned long recalc_stm_pll3200c32(struct clk_hw *hw, | 324 | static 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 | ||
346 | unsigned long recalc_stm_pll1200c32(struct clk_hw *hw, | 346 | static 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 | ||
546 | static struct clk * __init clkgen_odf_register(const char *parent_name, | 546 | static 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 | ||
158 | const struct clk_ops atl_clk_ops = { | 158 | static 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 = { | |||
167 | static void __init of_dra7_atl_clock_setup(struct device_node *node) | 167 | static 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) |
180 | void __iomem *_get_reg(u8 module, u16 offset) | 180 | static 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 | ||
138 | void __init clk_sp810_of_setup(struct device_node *node) | 138 | static 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); | |||
85 | static DEFINE_SPINLOCK(dbgclk_lock); | 85 | static DEFINE_SPINLOCK(dbgclk_lock); |
86 | static DEFINE_SPINLOCK(aperclk_lock); | 86 | static DEFINE_SPINLOCK(aperclk_lock); |
87 | 87 | ||
88 | static const char *armpll_parents[] __initdata = {"armpll_int", "ps_clk"}; | 88 | static const char *const armpll_parents[] __initconst = {"armpll_int", |
89 | static const char *ddrpll_parents[] __initdata = {"ddrpll_int", "ps_clk"}; | 89 | "ps_clk"}; |
90 | static const char *iopll_parents[] __initdata = {"iopll_int", "ps_clk"}; | 90 | static const char *const ddrpll_parents[] __initconst = {"ddrpll_int", |
91 | "ps_clk"}; | ||
92 | static const char *const iopll_parents[] __initconst = {"iopll_int", | ||
93 | "ps_clk"}; | ||
91 | static const char *gem0_mux_parents[] __initdata = {"gem0_div1", "dummy_name"}; | 94 | static const char *gem0_mux_parents[] __initdata = {"gem0_div1", "dummy_name"}; |
92 | static const char *gem1_mux_parents[] __initdata = {"gem1_div1", "dummy_name"}; | 95 | static const char *gem1_mux_parents[] __initdata = {"gem1_div1", "dummy_name"}; |
93 | static const char *can0_mio_mux2_parents[] __initdata = {"can0_gate", | 96 | static const char *const can0_mio_mux2_parents[] __initconst = {"can0_gate", |
94 | "can0_mio_mux"}; | 97 | "can0_mio_mux"}; |
95 | static const char *can1_mio_mux2_parents[] __initdata = {"can1_gate", | 98 | static const char *const can1_mio_mux2_parents[] __initconst = {"can1_gate", |
96 | "can1_mio_mux"}; | 99 | "can1_mio_mux"}; |
97 | static const char *dbg_emio_mux_parents[] __initdata = {"dbg_div", | 100 | static const char *dbg_emio_mux_parents[] __initdata = {"dbg_div", |
98 | "dummy_name"}; | 101 | "dummy_name"}; |
99 | 102 | ||
100 | static const char *dbgtrc_emio_input_names[] __initdata = {"trace_emio_clk"}; | 103 | static const char *const dbgtrc_emio_input_names[] __initconst = { |
101 | static const char *gem0_emio_input_names[] __initdata = {"gem0_emio_clk"}; | 104 | "trace_emio_clk"}; |
102 | static const char *gem1_emio_input_names[] __initdata = {"gem1_emio_clk"}; | 105 | static const char *const gem0_emio_input_names[] __initconst = { |
103 | static const char *swdt_ext_clk_input_names[] __initdata = {"swdt_ext_clk"}; | 106 | "gem0_emio_clk"}; |
107 | static const char *const gem1_emio_input_names[] __initconst = { | ||
108 | "gem1_emio_clk"}; | ||
109 | static const char *const swdt_ext_clk_input_names[] __initconst = { | ||
110 | "swdt_ext_clk"}; | ||
104 | 111 | ||
105 | static void __init zynq_clk_register_fclk(enum zynq_clk fclk, | 112 | static 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 { | |||
209 | struct clk_init_data { | 209 | struct 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; | |||
426 | extern const struct clk_ops clk_mux_ro_ops; | 426 | extern const struct clk_ops clk_mux_ro_ops; |
427 | 427 | ||
428 | struct clk *clk_register_mux(struct device *dev, const char *name, | 428 | struct 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 | ||
433 | struct clk *clk_register_mux_table(struct device *dev, const char *name, | 434 | struct 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 | ||
460 | extern struct clk_ops clk_fixed_factor_ops; | 462 | extern const struct clk_ops clk_fixed_factor_ops; |
461 | struct clk *clk_register_fixed_factor(struct device *dev, const char *name, | 463 | struct 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 | ||
520 | struct clk *clk_register_composite(struct device *dev, const char *name, | 522 | struct 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); |
625 | struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data); | 627 | struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data); |
626 | int of_clk_get_parent_count(struct device_node *np); | 628 | int of_clk_get_parent_count(struct device_node *np); |
629 | int of_clk_parent_fill(struct device_node *np, const char **parents, | ||
630 | unsigned int size); | ||
627 | const char *of_clk_get_parent_name(struct device_node *np, int index); | 631 | const char *of_clk_get_parent_name(struct device_node *np, int index); |
628 | 632 | ||
629 | void of_clk_init(const struct of_device_id *matches); | 633 | void of_clk_init(const struct of_device_id *matches); |