diff options
author | Michael Turquette <mturquette@linaro.org> | 2014-11-24 21:08:53 -0500 |
---|---|---|
committer | Michael Turquette <mturquette@linaro.org> | 2014-11-24 21:08:53 -0500 |
commit | b082915c9d4b15590558766979aed78424690057 (patch) | |
tree | 22ea44f38cefc5954b5bebf63c845b409eac13a6 | |
parent | da57b46010dd8d93aabc4c3e8d11751ac617d914 (diff) | |
parent | c1ec51603053260b138fc98e2ed18a5a9bea4515 (diff) |
Merge tag 'sunxi-clocks-for-3.19' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux into clk-next
Allwinner Clocks additions for 3.19
A few patches that should go through the clock tree, mostly fixes, cleanups,
and new clocks additions to start to support the A80.
-rw-r--r-- | Documentation/devicetree/bindings/clock/sunxi.txt | 31 | ||||
-rw-r--r-- | arch/arm/boot/dts/sun4i-a10.dtsi | 12 | ||||
-rw-r--r-- | arch/arm/boot/dts/sun5i-a10s.dtsi | 12 | ||||
-rw-r--r-- | arch/arm/boot/dts/sun5i-a13.dtsi | 12 | ||||
-rw-r--r-- | arch/arm/boot/dts/sun6i-a31.dtsi | 12 | ||||
-rw-r--r-- | arch/arm/boot/dts/sun7i-a20.dtsi | 12 | ||||
-rw-r--r-- | arch/arm/boot/dts/sun8i-a23.dtsi | 12 | ||||
-rw-r--r-- | drivers/clk/sunxi/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/sunxi/clk-a20-gmac.c | 7 | ||||
-rw-r--r-- | drivers/clk/sunxi/clk-factors.c | 2 | ||||
-rw-r--r-- | drivers/clk/sunxi/clk-factors.h | 3 | ||||
-rw-r--r-- | drivers/clk/sunxi/clk-mod0.c | 1 | ||||
-rw-r--r-- | drivers/clk/sunxi/clk-sun8i-mbus.c | 1 | ||||
-rw-r--r-- | drivers/clk/sunxi/clk-sun9i-core.c | 271 | ||||
-rw-r--r-- | drivers/clk/sunxi/clk-sunxi.c | 85 |
15 files changed, 380 insertions, 94 deletions
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index ed116df9c3e7..67b2b99f2b33 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt | |||
@@ -10,14 +10,17 @@ Required properties: | |||
10 | "allwinner,sun4i-a10-pll1-clk" - for the main PLL clock and PLL4 | 10 | "allwinner,sun4i-a10-pll1-clk" - for the main PLL clock and PLL4 |
11 | "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31 | 11 | "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31 |
12 | "allwinner,sun8i-a23-pll1-clk" - for the main PLL clock on A23 | 12 | "allwinner,sun8i-a23-pll1-clk" - for the main PLL clock on A23 |
13 | "allwinner,sun9i-a80-pll4-clk" - for the peripheral PLLs on A80 | ||
13 | "allwinner,sun4i-a10-pll5-clk" - for the PLL5 clock | 14 | "allwinner,sun4i-a10-pll5-clk" - for the PLL5 clock |
14 | "allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock | 15 | "allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock |
15 | "allwinner,sun6i-a31-pll6-clk" - for the PLL6 clock on A31 | 16 | "allwinner,sun6i-a31-pll6-clk" - for the PLL6 clock on A31 |
17 | "allwinner,sun9i-a80-gt-clk" - for the GT bus clock on A80 | ||
16 | "allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock | 18 | "allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock |
17 | "allwinner,sun4i-a10-axi-clk" - for the AXI clock | 19 | "allwinner,sun4i-a10-axi-clk" - for the AXI clock |
18 | "allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23 | 20 | "allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23 |
19 | "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates | 21 | "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates |
20 | "allwinner,sun4i-a10-ahb-clk" - for the AHB clock | 22 | "allwinner,sun4i-a10-ahb-clk" - for the AHB clock |
23 | "allwinner,sun9i-a80-ahb-clk" - for the AHB bus clocks on A80 | ||
21 | "allwinner,sun4i-a10-ahb-gates-clk" - for the AHB gates on A10 | 24 | "allwinner,sun4i-a10-ahb-gates-clk" - for the AHB gates on A10 |
22 | "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13 | 25 | "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13 |
23 | "allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s | 26 | "allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s |
@@ -26,24 +29,29 @@ Required properties: | |||
26 | "allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31 | 29 | "allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31 |
27 | "allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31 | 30 | "allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31 |
28 | "allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23 | 31 | "allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23 |
32 | "allwinner,sun9i-a80-ahb0-gates-clk" - for the AHB0 gates on A80 | ||
33 | "allwinner,sun9i-a80-ahb1-gates-clk" - for the AHB1 gates on A80 | ||
34 | "allwinner,sun9i-a80-ahb2-gates-clk" - for the AHB2 gates on A80 | ||
29 | "allwinner,sun4i-a10-apb0-clk" - for the APB0 clock | 35 | "allwinner,sun4i-a10-apb0-clk" - for the APB0 clock |
30 | "allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31 | 36 | "allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31 |
31 | "allwinner,sun8i-a23-apb0-clk" - for the APB0 clock on A23 | 37 | "allwinner,sun8i-a23-apb0-clk" - for the APB0 clock on A23 |
38 | "allwinner,sun9i-a80-apb0-clk" - for the APB0 bus clock on A80 | ||
32 | "allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10 | 39 | "allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10 |
33 | "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13 | 40 | "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13 |
34 | "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s | 41 | "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s |
35 | "allwinner,sun6i-a31-apb0-gates-clk" - for the APB0 gates on A31 | 42 | "allwinner,sun6i-a31-apb0-gates-clk" - for the APB0 gates on A31 |
36 | "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20 | 43 | "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20 |
37 | "allwinner,sun8i-a23-apb0-gates-clk" - for the APB0 gates on A23 | 44 | "allwinner,sun8i-a23-apb0-gates-clk" - for the APB0 gates on A23 |
45 | "allwinner,sun9i-a80-apb0-gates-clk" - for the APB0 gates on A80 | ||
38 | "allwinner,sun4i-a10-apb1-clk" - for the APB1 clock | 46 | "allwinner,sun4i-a10-apb1-clk" - for the APB1 clock |
39 | "allwinner,sun4i-a10-apb1-mux-clk" - for the APB1 clock muxing | 47 | "allwinner,sun9i-a80-apb1-clk" - for the APB1 bus clock on A80 |
40 | "allwinner,sun4i-a10-apb1-gates-clk" - for the APB1 gates on A10 | 48 | "allwinner,sun4i-a10-apb1-gates-clk" - for the APB1 gates on A10 |
41 | "allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13 | 49 | "allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13 |
42 | "allwinner,sun5i-a10s-apb1-gates-clk" - for the APB1 gates on A10s | 50 | "allwinner,sun5i-a10s-apb1-gates-clk" - for the APB1 gates on A10s |
43 | "allwinner,sun6i-a31-apb1-gates-clk" - for the APB1 gates on A31 | 51 | "allwinner,sun6i-a31-apb1-gates-clk" - for the APB1 gates on A31 |
44 | "allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20 | 52 | "allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20 |
45 | "allwinner,sun8i-a23-apb1-gates-clk" - for the APB1 gates on A23 | 53 | "allwinner,sun8i-a23-apb1-gates-clk" - for the APB1 gates on A23 |
46 | "allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31 | 54 | "allwinner,sun9i-a80-apb1-gates-clk" - for the APB1 gates on A80 |
47 | "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 | 55 | "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 |
48 | "allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23 | 56 | "allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23 |
49 | "allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13 | 57 | "allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13 |
@@ -63,8 +71,9 @@ Required properties for all clocks: | |||
63 | multiplexed clocks, the list order must match the hardware | 71 | multiplexed clocks, the list order must match the hardware |
64 | programming order. | 72 | programming order. |
65 | - #clock-cells : from common clock binding; shall be set to 0 except for | 73 | - #clock-cells : from common clock binding; shall be set to 0 except for |
66 | "allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk" and | 74 | the following compatibles where it shall be set to 1: |
67 | "allwinner,sun4i-pll6-clk" where it shall be set to 1 | 75 | "allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk", |
76 | "allwinner,sun4i-pll6-clk", "allwinner,sun6i-a31-pll6-clk" | ||
68 | - clock-output-names : shall be the corresponding names of the outputs. | 77 | - clock-output-names : shall be the corresponding names of the outputs. |
69 | If the clock module only has one output, the name shall be the | 78 | If the clock module only has one output, the name shall be the |
70 | module name. | 79 | module name. |
@@ -79,6 +88,12 @@ Clock consumers should specify the desired clocks they use with a | |||
79 | "clocks" phandle cell. Consumers that are using a gated clock should | 88 | "clocks" phandle cell. Consumers that are using a gated clock should |
80 | provide an additional ID in their clock property. This ID is the | 89 | provide an additional ID in their clock property. This ID is the |
81 | offset of the bit controlling this particular gate in the register. | 90 | offset of the bit controlling this particular gate in the register. |
91 | For the other clocks with "#clock-cells" = 1, the additional ID shall | ||
92 | refer to the index of the output. | ||
93 | |||
94 | For "allwinner,sun6i-a31-pll6-clk", there are 2 outputs. The first output | ||
95 | is the normal PLL6 output, or "pll6". The second output is rate doubled | ||
96 | PLL6, or "pll6x2". | ||
82 | 97 | ||
83 | For example: | 98 | For example: |
84 | 99 | ||
@@ -106,6 +121,14 @@ pll5: clk@01c20020 { | |||
106 | clock-output-names = "pll5_ddr", "pll5_other"; | 121 | clock-output-names = "pll5_ddr", "pll5_other"; |
107 | }; | 122 | }; |
108 | 123 | ||
124 | pll6: clk@01c20028 { | ||
125 | #clock-cells = <1>; | ||
126 | compatible = "allwinner,sun6i-a31-pll6-clk"; | ||
127 | reg = <0x01c20028 0x4>; | ||
128 | clocks = <&osc24M>; | ||
129 | clock-output-names = "pll6", "pll6x2"; | ||
130 | }; | ||
131 | |||
109 | cpu: cpu@01c20054 { | 132 | cpu: cpu@01c20054 { |
110 | #clock-cells = <0>; | 133 | #clock-cells = <0>; |
111 | compatible = "allwinner,sun4i-a10-cpu-clk"; | 134 | compatible = "allwinner,sun4i-a10-cpu-clk"; |
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 380f914b226d..5e2ec2dd8333 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi | |||
@@ -174,19 +174,11 @@ | |||
174 | "apb0_ir1", "apb0_keypad"; | 174 | "apb0_ir1", "apb0_keypad"; |
175 | }; | 175 | }; |
176 | 176 | ||
177 | apb1_mux: apb1_mux@01c20058 { | 177 | apb1: clk@01c20058 { |
178 | #clock-cells = <0>; | ||
179 | compatible = "allwinner,sun4i-a10-apb1-mux-clk"; | ||
180 | reg = <0x01c20058 0x4>; | ||
181 | clocks = <&osc24M>, <&pll6 1>, <&osc32k>; | ||
182 | clock-output-names = "apb1_mux"; | ||
183 | }; | ||
184 | |||
185 | apb1: apb1@01c20058 { | ||
186 | #clock-cells = <0>; | 178 | #clock-cells = <0>; |
187 | compatible = "allwinner,sun4i-a10-apb1-clk"; | 179 | compatible = "allwinner,sun4i-a10-apb1-clk"; |
188 | reg = <0x01c20058 0x4>; | 180 | reg = <0x01c20058 0x4>; |
189 | clocks = <&apb1_mux>; | 181 | clocks = <&osc24M>, <&pll6 1>, <&osc32k>; |
190 | clock-output-names = "apb1"; | 182 | clock-output-names = "apb1"; |
191 | }; | 183 | }; |
192 | 184 | ||
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index 531272c0e526..d2a85144d2d9 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi | |||
@@ -162,19 +162,11 @@ | |||
162 | "apb0_ir", "apb0_keypad"; | 162 | "apb0_ir", "apb0_keypad"; |
163 | }; | 163 | }; |
164 | 164 | ||
165 | apb1_mux: apb1_mux@01c20058 { | 165 | apb1: clk@01c20058 { |
166 | #clock-cells = <0>; | ||
167 | compatible = "allwinner,sun4i-a10-apb1-mux-clk"; | ||
168 | reg = <0x01c20058 0x4>; | ||
169 | clocks = <&osc24M>, <&pll6 1>, <&osc32k>; | ||
170 | clock-output-names = "apb1_mux"; | ||
171 | }; | ||
172 | |||
173 | apb1: apb1@01c20058 { | ||
174 | #clock-cells = <0>; | 166 | #clock-cells = <0>; |
175 | compatible = "allwinner,sun4i-a10-apb1-clk"; | 167 | compatible = "allwinner,sun4i-a10-apb1-clk"; |
176 | reg = <0x01c20058 0x4>; | 168 | reg = <0x01c20058 0x4>; |
177 | clocks = <&apb1_mux>; | 169 | clocks = <&osc24M>, <&pll6 1>, <&osc32k>; |
178 | clock-output-names = "apb1"; | 170 | clock-output-names = "apb1"; |
179 | }; | 171 | }; |
180 | 172 | ||
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index b131068f4f35..c35217ea1f64 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi | |||
@@ -161,19 +161,11 @@ | |||
161 | clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir"; | 161 | clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir"; |
162 | }; | 162 | }; |
163 | 163 | ||
164 | apb1_mux: apb1_mux@01c20058 { | 164 | apb1: clk@01c20058 { |
165 | #clock-cells = <0>; | ||
166 | compatible = "allwinner,sun4i-a10-apb1-mux-clk"; | ||
167 | reg = <0x01c20058 0x4>; | ||
168 | clocks = <&osc24M>, <&pll6 1>, <&osc32k>; | ||
169 | clock-output-names = "apb1_mux"; | ||
170 | }; | ||
171 | |||
172 | apb1: apb1@01c20058 { | ||
173 | #clock-cells = <0>; | 165 | #clock-cells = <0>; |
174 | compatible = "allwinner,sun4i-a10-apb1-clk"; | 166 | compatible = "allwinner,sun4i-a10-apb1-clk"; |
175 | reg = <0x01c20058 0x4>; | 167 | reg = <0x01c20058 0x4>; |
176 | clocks = <&apb1_mux>; | 168 | clocks = <&osc24M>, <&pll6 1>, <&osc32k>; |
177 | clock-output-names = "apb1"; | 169 | clock-output-names = "apb1"; |
178 | }; | 170 | }; |
179 | 171 | ||
diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index 543f895d18d3..4083201e93c8 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi | |||
@@ -217,19 +217,11 @@ | |||
217 | "apb1_daudio1"; | 217 | "apb1_daudio1"; |
218 | }; | 218 | }; |
219 | 219 | ||
220 | apb2_mux: apb2_mux@01c20058 { | 220 | apb2: clk@01c20058 { |
221 | #clock-cells = <0>; | 221 | #clock-cells = <0>; |
222 | compatible = "allwinner,sun4i-a10-apb1-mux-clk"; | 222 | compatible = "allwinner,sun4i-a10-apb1-clk"; |
223 | reg = <0x01c20058 0x4>; | 223 | reg = <0x01c20058 0x4>; |
224 | clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>; | 224 | clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>; |
225 | clock-output-names = "apb2_mux"; | ||
226 | }; | ||
227 | |||
228 | apb2: apb2@01c20058 { | ||
229 | #clock-cells = <0>; | ||
230 | compatible = "allwinner,sun6i-a31-apb2-div-clk"; | ||
231 | reg = <0x01c20058 0x4>; | ||
232 | clocks = <&apb2_mux>; | ||
233 | clock-output-names = "apb2"; | 225 | clock-output-names = "apb2"; |
234 | }; | 226 | }; |
235 | 227 | ||
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 82097c905c48..6d996c9e282a 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi | |||
@@ -222,19 +222,11 @@ | |||
222 | "apb0_iis2", "apb0_keypad"; | 222 | "apb0_iis2", "apb0_keypad"; |
223 | }; | 223 | }; |
224 | 224 | ||
225 | apb1_mux: apb1_mux@01c20058 { | 225 | apb1: clk@01c20058 { |
226 | #clock-cells = <0>; | ||
227 | compatible = "allwinner,sun4i-a10-apb1-mux-clk"; | ||
228 | reg = <0x01c20058 0x4>; | ||
229 | clocks = <&osc24M>, <&pll6 1>, <&osc32k>; | ||
230 | clock-output-names = "apb1_mux"; | ||
231 | }; | ||
232 | |||
233 | apb1: apb1@01c20058 { | ||
234 | #clock-cells = <0>; | 226 | #clock-cells = <0>; |
235 | compatible = "allwinner,sun4i-a10-apb1-clk"; | 227 | compatible = "allwinner,sun4i-a10-apb1-clk"; |
236 | reg = <0x01c20058 0x4>; | 228 | reg = <0x01c20058 0x4>; |
237 | clocks = <&apb1_mux>; | 229 | clocks = <&osc24M>, <&pll6 1>, <&osc32k>; |
238 | clock-output-names = "apb1"; | 230 | clock-output-names = "apb1"; |
239 | }; | 231 | }; |
240 | 232 | ||
diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index 6146ef15efbe..701960e9d033 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi | |||
@@ -189,19 +189,11 @@ | |||
189 | "apb1_daudio0", "apb1_daudio1"; | 189 | "apb1_daudio0", "apb1_daudio1"; |
190 | }; | 190 | }; |
191 | 191 | ||
192 | apb2_mux: apb2_mux_clk@01c20058 { | 192 | apb2: clk@01c20058 { |
193 | #clock-cells = <0>; | 193 | #clock-cells = <0>; |
194 | compatible = "allwinner,sun4i-a10-apb1-mux-clk"; | 194 | compatible = "allwinner,sun4i-a10-apb1-clk"; |
195 | reg = <0x01c20058 0x4>; | 195 | reg = <0x01c20058 0x4>; |
196 | clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>; | 196 | clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>; |
197 | clock-output-names = "apb2_mux"; | ||
198 | }; | ||
199 | |||
200 | apb2: apb2_clk@01c20058 { | ||
201 | #clock-cells = <0>; | ||
202 | compatible = "allwinner,sun6i-a31-apb2-div-clk"; | ||
203 | reg = <0x01c20058 0x4>; | ||
204 | clocks = <&apb2_mux>; | ||
205 | clock-output-names = "apb2"; | 197 | clock-output-names = "apb2"; |
206 | }; | 198 | }; |
207 | 199 | ||
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index 7ddc2b553846..a66953c0f430 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile | |||
@@ -7,6 +7,7 @@ obj-y += clk-a10-hosc.o | |||
7 | obj-y += clk-a20-gmac.o | 7 | obj-y += clk-a20-gmac.o |
8 | obj-y += clk-mod0.o | 8 | obj-y += clk-mod0.o |
9 | obj-y += clk-sun8i-mbus.o | 9 | obj-y += clk-sun8i-mbus.o |
10 | obj-y += clk-sun9i-core.o | ||
10 | 11 | ||
11 | obj-$(CONFIG_MFD_SUN6I_PRCM) += \ | 12 | obj-$(CONFIG_MFD_SUN6I_PRCM) += \ |
12 | clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \ | 13 | clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \ |
diff --git a/drivers/clk/sunxi/clk-a20-gmac.c b/drivers/clk/sunxi/clk-a20-gmac.c index 5296fd6dd7b3..0dcf4f205fb8 100644 --- a/drivers/clk/sunxi/clk-a20-gmac.c +++ b/drivers/clk/sunxi/clk-a20-gmac.c | |||
@@ -53,6 +53,11 @@ static DEFINE_SPINLOCK(gmac_lock); | |||
53 | #define SUN7I_A20_GMAC_MASK 0x3 | 53 | #define SUN7I_A20_GMAC_MASK 0x3 |
54 | #define SUN7I_A20_GMAC_PARENTS 2 | 54 | #define SUN7I_A20_GMAC_PARENTS 2 |
55 | 55 | ||
56 | static u32 sun7i_a20_gmac_mux_table[SUN7I_A20_GMAC_PARENTS] = { | ||
57 | 0x00, /* Select mii_phy_tx_clk */ | ||
58 | 0x02, /* Select gmac_int_tx_clk */ | ||
59 | }; | ||
60 | |||
56 | static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) | 61 | static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) |
57 | { | 62 | { |
58 | struct clk *clk; | 63 | struct clk *clk; |
@@ -90,7 +95,7 @@ static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) | |||
90 | gate->lock = &gmac_lock; | 95 | gate->lock = &gmac_lock; |
91 | mux->reg = reg; | 96 | mux->reg = reg; |
92 | mux->mask = SUN7I_A20_GMAC_MASK; | 97 | mux->mask = SUN7I_A20_GMAC_MASK; |
93 | mux->flags = CLK_MUX_INDEX_BIT; | 98 | mux->table = sun7i_a20_gmac_mux_table; |
94 | mux->lock = &gmac_lock; | 99 | mux->lock = &gmac_lock; |
95 | 100 | ||
96 | clk = clk_register_composite(NULL, clk_name, | 101 | clk = clk_register_composite(NULL, clk_name, |
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index f83ba097126c..5521e866fa5e 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c | |||
@@ -224,7 +224,7 @@ struct clk * __init sunxi_factors_register(struct device_node *node, | |||
224 | /* set up gate properties */ | 224 | /* set up gate properties */ |
225 | mux->reg = reg; | 225 | mux->reg = reg; |
226 | mux->shift = data->mux; | 226 | mux->shift = data->mux; |
227 | mux->mask = SUNXI_FACTORS_MUX_MASK; | 227 | mux->mask = data->muxmask; |
228 | mux->lock = factors->lock; | 228 | mux->lock = factors->lock; |
229 | mux_hw = &mux->hw; | 229 | mux_hw = &mux->hw; |
230 | } | 230 | } |
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index 9913840018d3..912238fde132 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h | |||
@@ -7,8 +7,6 @@ | |||
7 | 7 | ||
8 | #define SUNXI_FACTORS_NOT_APPLICABLE (0) | 8 | #define SUNXI_FACTORS_NOT_APPLICABLE (0) |
9 | 9 | ||
10 | #define SUNXI_FACTORS_MUX_MASK 0x3 | ||
11 | |||
12 | struct clk_factors_config { | 10 | struct clk_factors_config { |
13 | u8 nshift; | 11 | u8 nshift; |
14 | u8 nwidth; | 12 | u8 nwidth; |
@@ -24,6 +22,7 @@ struct clk_factors_config { | |||
24 | struct factors_data { | 22 | struct factors_data { |
25 | int enable; | 23 | int enable; |
26 | int mux; | 24 | int mux; |
25 | int muxmask; | ||
27 | struct clk_factors_config *table; | 26 | struct clk_factors_config *table; |
28 | void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); | 27 | void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); |
29 | const char *name; | 28 | const char *name; |
diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index 4a563850ee6e..da0524eaee94 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c | |||
@@ -70,6 +70,7 @@ static struct clk_factors_config sun4i_a10_mod0_config = { | |||
70 | static const struct factors_data sun4i_a10_mod0_data __initconst = { | 70 | static const struct factors_data sun4i_a10_mod0_data __initconst = { |
71 | .enable = 31, | 71 | .enable = 31, |
72 | .mux = 24, | 72 | .mux = 24, |
73 | .muxmask = BIT(1) | BIT(0), | ||
73 | .table = &sun4i_a10_mod0_config, | 74 | .table = &sun4i_a10_mod0_config, |
74 | .getter = sun4i_a10_get_mod0_factors, | 75 | .getter = sun4i_a10_get_mod0_factors, |
75 | }; | 76 | }; |
diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index 8e49b44cee41..ef49786eefd3 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c | |||
@@ -60,6 +60,7 @@ static struct clk_factors_config sun8i_a23_mbus_config = { | |||
60 | static const struct factors_data sun8i_a23_mbus_data __initconst = { | 60 | static const struct factors_data sun8i_a23_mbus_data __initconst = { |
61 | .enable = 31, | 61 | .enable = 31, |
62 | .mux = 24, | 62 | .mux = 24, |
63 | .muxmask = BIT(1) | BIT(0), | ||
63 | .table = &sun8i_a23_mbus_config, | 64 | .table = &sun8i_a23_mbus_config, |
64 | .getter = sun8i_a23_get_mbus_factors, | 65 | .getter = sun8i_a23_get_mbus_factors, |
65 | }; | 66 | }; |
diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c new file mode 100644 index 000000000000..3cb9036d91bb --- /dev/null +++ b/drivers/clk/sunxi/clk-sun9i-core.c | |||
@@ -0,0 +1,271 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Chen-Yu Tsai | ||
3 | * | ||
4 | * Chen-Yu Tsai <wens@csie.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk-provider.h> | ||
18 | #include <linux/clkdev.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/of_address.h> | ||
21 | #include <linux/log2.h> | ||
22 | |||
23 | #include "clk-factors.h" | ||
24 | |||
25 | |||
26 | /** | ||
27 | * sun9i_a80_get_pll4_factors() - calculates n, p, m factors for PLL1 | ||
28 | * PLL4 rate is calculated as follows | ||
29 | * rate = (parent_rate * n >> p) / (m + 1); | ||
30 | * parent_rate is always 24Mhz | ||
31 | * | ||
32 | * p and m are named div1 and div2 in Allwinner's SDK | ||
33 | */ | ||
34 | |||
35 | static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, | ||
36 | u8 *n, u8 *k, u8 *m, u8 *p) | ||
37 | { | ||
38 | int div; | ||
39 | |||
40 | /* Normalize value to a 6M multiple */ | ||
41 | div = DIV_ROUND_UP(*freq, 6000000); | ||
42 | |||
43 | /* divs above 256 cannot be odd */ | ||
44 | if (div > 256) | ||
45 | div = round_up(div, 2); | ||
46 | |||
47 | /* divs above 512 must be a multiple of 4 */ | ||
48 | if (div > 512) | ||
49 | div = round_up(div, 4); | ||
50 | |||
51 | *freq = 6000000 * div; | ||
52 | |||
53 | /* we were called to round the frequency, we can now return */ | ||
54 | if (n == NULL) | ||
55 | return; | ||
56 | |||
57 | /* p will be 1 for divs under 512 */ | ||
58 | if (div < 512) | ||
59 | *p = 1; | ||
60 | else | ||
61 | *p = 0; | ||
62 | |||
63 | /* m will be 1 if div is odd */ | ||
64 | if (div & 1) | ||
65 | *m = 1; | ||
66 | else | ||
67 | *m = 0; | ||
68 | |||
69 | /* calculate a suitable n based on m and p */ | ||
70 | *n = div / (*p + 1) / (*m + 1); | ||
71 | } | ||
72 | |||
73 | static struct clk_factors_config sun9i_a80_pll4_config = { | ||
74 | .mshift = 18, | ||
75 | .mwidth = 1, | ||
76 | .nshift = 8, | ||
77 | .nwidth = 8, | ||
78 | .pshift = 16, | ||
79 | .pwidth = 1, | ||
80 | }; | ||
81 | |||
82 | static const struct factors_data sun9i_a80_pll4_data __initconst = { | ||
83 | .enable = 31, | ||
84 | .table = &sun9i_a80_pll4_config, | ||
85 | .getter = sun9i_a80_get_pll4_factors, | ||
86 | }; | ||
87 | |||
88 | static DEFINE_SPINLOCK(sun9i_a80_pll4_lock); | ||
89 | |||
90 | static void __init sun9i_a80_pll4_setup(struct device_node *node) | ||
91 | { | ||
92 | sunxi_factors_register(node, &sun9i_a80_pll4_data, &sun9i_a80_pll4_lock); | ||
93 | } | ||
94 | CLK_OF_DECLARE(sun9i_a80_pll4, "allwinner,sun9i-a80-pll4-clk", sun9i_a80_pll4_setup); | ||
95 | |||
96 | |||
97 | /** | ||
98 | * sun9i_a80_get_gt_factors() - calculates m factor for GT | ||
99 | * GT rate is calculated as follows | ||
100 | * rate = parent_rate / (m + 1); | ||
101 | */ | ||
102 | |||
103 | static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate, | ||
104 | u8 *n, u8 *k, u8 *m, u8 *p) | ||
105 | { | ||
106 | u32 div; | ||
107 | |||
108 | if (parent_rate < *freq) | ||
109 | *freq = parent_rate; | ||
110 | |||
111 | div = DIV_ROUND_UP(parent_rate, *freq); | ||
112 | |||
113 | /* maximum divider is 4 */ | ||
114 | if (div > 4) | ||
115 | div = 4; | ||
116 | |||
117 | *freq = parent_rate / div; | ||
118 | |||
119 | /* we were called to round the frequency, we can now return */ | ||
120 | if (!m) | ||
121 | return; | ||
122 | |||
123 | *m = div; | ||
124 | } | ||
125 | |||
126 | static struct clk_factors_config sun9i_a80_gt_config = { | ||
127 | .mshift = 0, | ||
128 | .mwidth = 2, | ||
129 | }; | ||
130 | |||
131 | static const struct factors_data sun9i_a80_gt_data __initconst = { | ||
132 | .mux = 24, | ||
133 | .muxmask = BIT(1) | BIT(0), | ||
134 | .table = &sun9i_a80_gt_config, | ||
135 | .getter = sun9i_a80_get_gt_factors, | ||
136 | }; | ||
137 | |||
138 | static DEFINE_SPINLOCK(sun9i_a80_gt_lock); | ||
139 | |||
140 | static void __init sun9i_a80_gt_setup(struct device_node *node) | ||
141 | { | ||
142 | struct clk *gt = sunxi_factors_register(node, &sun9i_a80_gt_data, | ||
143 | &sun9i_a80_gt_lock); | ||
144 | |||
145 | /* The GT bus clock needs to be always enabled */ | ||
146 | __clk_get(gt); | ||
147 | clk_prepare_enable(gt); | ||
148 | } | ||
149 | CLK_OF_DECLARE(sun9i_a80_gt, "allwinner,sun9i-a80-gt-clk", sun9i_a80_gt_setup); | ||
150 | |||
151 | |||
152 | /** | ||
153 | * sun9i_a80_get_ahb_factors() - calculates p factor for AHB0/1/2 | ||
154 | * AHB rate is calculated as follows | ||
155 | * rate = parent_rate >> p; | ||
156 | */ | ||
157 | |||
158 | static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate, | ||
159 | u8 *n, u8 *k, u8 *m, u8 *p) | ||
160 | { | ||
161 | u32 _p; | ||
162 | |||
163 | if (parent_rate < *freq) | ||
164 | *freq = parent_rate; | ||
165 | |||
166 | _p = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); | ||
167 | |||
168 | /* maximum p is 3 */ | ||
169 | if (_p > 3) | ||
170 | _p = 3; | ||
171 | |||
172 | *freq = parent_rate >> _p; | ||
173 | |||
174 | /* we were called to round the frequency, we can now return */ | ||
175 | if (!p) | ||
176 | return; | ||
177 | |||
178 | *p = _p; | ||
179 | } | ||
180 | |||
181 | static struct clk_factors_config sun9i_a80_ahb_config = { | ||
182 | .pshift = 0, | ||
183 | .pwidth = 2, | ||
184 | }; | ||
185 | |||
186 | static const struct factors_data sun9i_a80_ahb_data __initconst = { | ||
187 | .mux = 24, | ||
188 | .muxmask = BIT(1) | BIT(0), | ||
189 | .table = &sun9i_a80_ahb_config, | ||
190 | .getter = sun9i_a80_get_ahb_factors, | ||
191 | }; | ||
192 | |||
193 | static DEFINE_SPINLOCK(sun9i_a80_ahb_lock); | ||
194 | |||
195 | static void __init sun9i_a80_ahb_setup(struct device_node *node) | ||
196 | { | ||
197 | sunxi_factors_register(node, &sun9i_a80_ahb_data, &sun9i_a80_ahb_lock); | ||
198 | } | ||
199 | CLK_OF_DECLARE(sun9i_a80_ahb, "allwinner,sun9i-a80-ahb-clk", sun9i_a80_ahb_setup); | ||
200 | |||
201 | |||
202 | static const struct factors_data sun9i_a80_apb0_data __initconst = { | ||
203 | .mux = 24, | ||
204 | .muxmask = BIT(0), | ||
205 | .table = &sun9i_a80_ahb_config, | ||
206 | .getter = sun9i_a80_get_ahb_factors, | ||
207 | }; | ||
208 | |||
209 | static DEFINE_SPINLOCK(sun9i_a80_apb0_lock); | ||
210 | |||
211 | static void __init sun9i_a80_apb0_setup(struct device_node *node) | ||
212 | { | ||
213 | sunxi_factors_register(node, &sun9i_a80_apb0_data, &sun9i_a80_apb0_lock); | ||
214 | } | ||
215 | CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-clk", sun9i_a80_apb0_setup); | ||
216 | |||
217 | |||
218 | /** | ||
219 | * sun9i_a80_get_apb1_factors() - calculates m, p factors for APB1 | ||
220 | * APB1 rate is calculated as follows | ||
221 | * rate = (parent_rate >> p) / (m + 1); | ||
222 | */ | ||
223 | |||
224 | static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate, | ||
225 | u8 *n, u8 *k, u8 *m, u8 *p) | ||
226 | { | ||
227 | u32 div; | ||
228 | u8 calcm, calcp; | ||
229 | |||
230 | if (parent_rate < *freq) | ||
231 | *freq = parent_rate; | ||
232 | |||
233 | div = DIV_ROUND_UP(parent_rate, *freq); | ||
234 | |||
235 | /* Highest possible divider is 256 (p = 3, m = 31) */ | ||
236 | if (div > 256) | ||
237 | div = 256; | ||
238 | |||
239 | calcp = order_base_2(div); | ||
240 | calcm = (parent_rate >> calcp) - 1; | ||
241 | *freq = (parent_rate >> calcp) / (calcm + 1); | ||
242 | |||
243 | /* we were called to round the frequency, we can now return */ | ||
244 | if (n == NULL) | ||
245 | return; | ||
246 | |||
247 | *m = calcm; | ||
248 | *p = calcp; | ||
249 | } | ||
250 | |||
251 | static struct clk_factors_config sun9i_a80_apb1_config = { | ||
252 | .mshift = 0, | ||
253 | .mwidth = 5, | ||
254 | .pshift = 16, | ||
255 | .pwidth = 2, | ||
256 | }; | ||
257 | |||
258 | static const struct factors_data sun9i_a80_apb1_data __initconst = { | ||
259 | .mux = 24, | ||
260 | .muxmask = BIT(0), | ||
261 | .table = &sun9i_a80_apb1_config, | ||
262 | .getter = sun9i_a80_get_apb1_factors, | ||
263 | }; | ||
264 | |||
265 | static DEFINE_SPINLOCK(sun9i_a80_apb1_lock); | ||
266 | |||
267 | static void __init sun9i_a80_apb1_setup(struct device_node *node) | ||
268 | { | ||
269 | sunxi_factors_register(node, &sun9i_a80_apb1_data, &sun9i_a80_apb1_lock); | ||
270 | } | ||
271 | CLK_OF_DECLARE(sun9i_a80_apb1, "allwinner,sun9i-a80-apb1-clk", sun9i_a80_apb1_setup); | ||
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index d5dc951264ca..570202582dcf 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c | |||
@@ -245,9 +245,9 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, | |||
245 | } | 245 | } |
246 | 246 | ||
247 | /** | 247 | /** |
248 | * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6 | 248 | * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6x2 |
249 | * PLL6 rate is calculated as follows | 249 | * PLL6x2 rate is calculated as follows |
250 | * rate = parent_rate * n * (k + 1) / 2 | 250 | * rate = parent_rate * (n + 1) * (k + 1) |
251 | * parent_rate is always 24Mhz | 251 | * parent_rate is always 24Mhz |
252 | */ | 252 | */ |
253 | 253 | ||
@@ -256,13 +256,7 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, | |||
256 | { | 256 | { |
257 | u8 div; | 257 | u8 div; |
258 | 258 | ||
259 | /* | 259 | /* Normalize value to a parent_rate multiple (24M) */ |
260 | * We always have 24MHz / 2, so we can just say that our | ||
261 | * parent clock is 12MHz. | ||
262 | */ | ||
263 | parent_rate = parent_rate / 2; | ||
264 | |||
265 | /* Normalize value to a parent_rate multiple (24M / 2) */ | ||
266 | div = *freq / parent_rate; | 260 | div = *freq / parent_rate; |
267 | *freq = parent_rate * div; | 261 | *freq = parent_rate * div; |
268 | 262 | ||
@@ -274,7 +268,7 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, | |||
274 | if (*k > 3) | 268 | if (*k > 3) |
275 | *k = 3; | 269 | *k = 3; |
276 | 270 | ||
277 | *n = DIV_ROUND_UP(div, (*k+1)); | 271 | *n = DIV_ROUND_UP(div, (*k+1)) - 1; |
278 | } | 272 | } |
279 | 273 | ||
280 | /** | 274 | /** |
@@ -445,6 +439,7 @@ static struct clk_factors_config sun6i_a31_pll6_config = { | |||
445 | .nwidth = 5, | 439 | .nwidth = 5, |
446 | .kshift = 4, | 440 | .kshift = 4, |
447 | .kwidth = 2, | 441 | .kwidth = 2, |
442 | .n_start = 1, | ||
448 | }; | 443 | }; |
449 | 444 | ||
450 | static struct clk_factors_config sun4i_apb1_config = { | 445 | static struct clk_factors_config sun4i_apb1_config = { |
@@ -504,9 +499,12 @@ static const struct factors_data sun6i_a31_pll6_data __initconst = { | |||
504 | .enable = 31, | 499 | .enable = 31, |
505 | .table = &sun6i_a31_pll6_config, | 500 | .table = &sun6i_a31_pll6_config, |
506 | .getter = sun6i_a31_get_pll6_factors, | 501 | .getter = sun6i_a31_get_pll6_factors, |
502 | .name = "pll6x2", | ||
507 | }; | 503 | }; |
508 | 504 | ||
509 | static const struct factors_data sun4i_apb1_data __initconst = { | 505 | static const struct factors_data sun4i_apb1_data __initconst = { |
506 | .mux = 24, | ||
507 | .muxmask = BIT(1) | BIT(0), | ||
510 | .table = &sun4i_apb1_config, | 508 | .table = &sun4i_apb1_config, |
511 | .getter = sun4i_get_apb1_factors, | 509 | .getter = sun4i_get_apb1_factors, |
512 | }; | 510 | }; |
@@ -514,6 +512,7 @@ static const struct factors_data sun4i_apb1_data __initconst = { | |||
514 | static const struct factors_data sun7i_a20_out_data __initconst = { | 512 | static const struct factors_data sun7i_a20_out_data __initconst = { |
515 | .enable = 31, | 513 | .enable = 31, |
516 | .mux = 24, | 514 | .mux = 24, |
515 | .muxmask = BIT(1) | BIT(0), | ||
517 | .table = &sun7i_a20_out_config, | 516 | .table = &sun7i_a20_out_config, |
518 | .getter = sun7i_a20_get_out_factors, | 517 | .getter = sun7i_a20_get_out_factors, |
519 | }; | 518 | }; |
@@ -544,10 +543,6 @@ static const struct mux_data sun6i_a31_ahb1_mux_data __initconst = { | |||
544 | .shift = 12, | 543 | .shift = 12, |
545 | }; | 544 | }; |
546 | 545 | ||
547 | static const struct mux_data sun4i_apb1_mux_data __initconst = { | ||
548 | .shift = 24, | ||
549 | }; | ||
550 | |||
551 | static void __init sunxi_mux_clk_setup(struct device_node *node, | 546 | static void __init sunxi_mux_clk_setup(struct device_node *node, |
552 | struct mux_data *data) | 547 | struct mux_data *data) |
553 | { | 548 | { |
@@ -633,12 +628,6 @@ static const struct div_data sun4i_apb0_data __initconst = { | |||
633 | .table = sun4i_apb0_table, | 628 | .table = sun4i_apb0_table, |
634 | }; | 629 | }; |
635 | 630 | ||
636 | static const struct div_data sun6i_a31_apb2_div_data __initconst = { | ||
637 | .shift = 0, | ||
638 | .pow = 0, | ||
639 | .width = 4, | ||
640 | }; | ||
641 | |||
642 | static void __init sunxi_divider_clk_setup(struct device_node *node, | 631 | static void __init sunxi_divider_clk_setup(struct device_node *node, |
643 | struct div_data *data) | 632 | struct div_data *data) |
644 | { | 633 | { |
@@ -757,6 +746,18 @@ static const struct gates_data sun8i_a23_ahb1_gates_data __initconst = { | |||
757 | .mask = {0x25386742, 0x2505111}, | 746 | .mask = {0x25386742, 0x2505111}, |
758 | }; | 747 | }; |
759 | 748 | ||
749 | static const struct gates_data sun9i_a80_ahb0_gates_data __initconst = { | ||
750 | .mask = {0xF5F12B}, | ||
751 | }; | ||
752 | |||
753 | static const struct gates_data sun9i_a80_ahb1_gates_data __initconst = { | ||
754 | .mask = {0x1E20003}, | ||
755 | }; | ||
756 | |||
757 | static const struct gates_data sun9i_a80_ahb2_gates_data __initconst = { | ||
758 | .mask = {0x9B7}, | ||
759 | }; | ||
760 | |||
760 | static const struct gates_data sun4i_apb0_gates_data __initconst = { | 761 | static const struct gates_data sun4i_apb0_gates_data __initconst = { |
761 | .mask = {0x4EF}, | 762 | .mask = {0x4EF}, |
762 | }; | 763 | }; |
@@ -773,6 +774,10 @@ static const struct gates_data sun7i_a20_apb0_gates_data __initconst = { | |||
773 | .mask = { 0x4ff }, | 774 | .mask = { 0x4ff }, |
774 | }; | 775 | }; |
775 | 776 | ||
777 | static const struct gates_data sun9i_a80_apb0_gates_data __initconst = { | ||
778 | .mask = {0xEB822}, | ||
779 | }; | ||
780 | |||
776 | static const struct gates_data sun4i_apb1_gates_data __initconst = { | 781 | static const struct gates_data sun4i_apb1_gates_data __initconst = { |
777 | .mask = {0xFF00F7}, | 782 | .mask = {0xFF00F7}, |
778 | }; | 783 | }; |
@@ -801,6 +806,10 @@ static const struct gates_data sun7i_a20_apb1_gates_data __initconst = { | |||
801 | .mask = { 0xff80ff }, | 806 | .mask = { 0xff80ff }, |
802 | }; | 807 | }; |
803 | 808 | ||
809 | static const struct gates_data sun9i_a80_apb1_gates_data __initconst = { | ||
810 | .mask = {0x3F001F}, | ||
811 | }; | ||
812 | |||
804 | static const struct gates_data sun8i_a23_apb2_gates_data __initconst = { | 813 | static const struct gates_data sun8i_a23_apb2_gates_data __initconst = { |
805 | .mask = {0x1F0007}, | 814 | .mask = {0x1F0007}, |
806 | }; | 815 | }; |
@@ -893,6 +902,7 @@ static void __init sunxi_gates_clk_setup(struct device_node *node, | |||
893 | 902 | ||
894 | struct divs_data { | 903 | struct divs_data { |
895 | const struct factors_data *factors; /* data for the factor clock */ | 904 | const struct factors_data *factors; /* data for the factor clock */ |
905 | int ndivs; /* number of children */ | ||
896 | struct { | 906 | struct { |
897 | u8 fixed; /* is it a fixed divisor? if not... */ | 907 | u8 fixed; /* is it a fixed divisor? if not... */ |
898 | struct clk_div_table *table; /* is it a table based divisor? */ | 908 | struct clk_div_table *table; /* is it a table based divisor? */ |
@@ -912,6 +922,7 @@ static struct clk_div_table pll6_sata_tbl[] = { | |||
912 | 922 | ||
913 | static const struct divs_data pll5_divs_data __initconst = { | 923 | static const struct divs_data pll5_divs_data __initconst = { |
914 | .factors = &sun4i_pll5_data, | 924 | .factors = &sun4i_pll5_data, |
925 | .ndivs = 2, | ||
915 | .div = { | 926 | .div = { |
916 | { .shift = 0, .pow = 0, }, /* M, DDR */ | 927 | { .shift = 0, .pow = 0, }, /* M, DDR */ |
917 | { .shift = 16, .pow = 1, }, /* P, other */ | 928 | { .shift = 16, .pow = 1, }, /* P, other */ |
@@ -920,12 +931,21 @@ static const struct divs_data pll5_divs_data __initconst = { | |||
920 | 931 | ||
921 | static const struct divs_data pll6_divs_data __initconst = { | 932 | static const struct divs_data pll6_divs_data __initconst = { |
922 | .factors = &sun4i_pll6_data, | 933 | .factors = &sun4i_pll6_data, |
934 | .ndivs = 2, | ||
923 | .div = { | 935 | .div = { |
924 | { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ | 936 | { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ |
925 | { .fixed = 2 }, /* P, other */ | 937 | { .fixed = 2 }, /* P, other */ |
926 | } | 938 | } |
927 | }; | 939 | }; |
928 | 940 | ||
941 | static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { | ||
942 | .factors = &sun6i_a31_pll6_data, | ||
943 | .ndivs = 1, | ||
944 | .div = { | ||
945 | { .fixed = 2 }, /* normal output */ | ||
946 | } | ||
947 | }; | ||
948 | |||
929 | /** | 949 | /** |
930 | * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks | 950 | * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks |
931 | * | 951 | * |
@@ -950,7 +970,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, | |||
950 | struct clk_fixed_factor *fix_factor; | 970 | struct clk_fixed_factor *fix_factor; |
951 | struct clk_divider *divider; | 971 | struct clk_divider *divider; |
952 | void __iomem *reg; | 972 | void __iomem *reg; |
953 | int i = 0; | 973 | int ndivs = SUNXI_DIVS_MAX_QTY, i = 0; |
954 | int flags, clkflags; | 974 | int flags, clkflags; |
955 | 975 | ||
956 | /* Set up factor clock that we will be dividing */ | 976 | /* Set up factor clock that we will be dividing */ |
@@ -973,7 +993,11 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, | |||
973 | * our RAM clock! */ | 993 | * our RAM clock! */ |
974 | clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT; | 994 | clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT; |
975 | 995 | ||
976 | for (i = 0; i < SUNXI_DIVS_MAX_QTY; i++) { | 996 | /* if number of children known, use it */ |
997 | if (data->ndivs) | ||
998 | ndivs = data->ndivs; | ||
999 | |||
1000 | for (i = 0; i < ndivs; i++) { | ||
977 | if (of_property_read_string_index(node, "clock-output-names", | 1001 | if (of_property_read_string_index(node, "clock-output-names", |
978 | i, &clk_name) != 0) | 1002 | i, &clk_name) != 0) |
979 | break; | 1003 | break; |
@@ -1062,7 +1086,6 @@ static const struct of_device_id clk_factors_match[] __initconst = { | |||
1062 | {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, | 1086 | {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, |
1063 | {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, | 1087 | {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, |
1064 | {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, | 1088 | {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, |
1065 | {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,}, | ||
1066 | {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, | 1089 | {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, |
1067 | {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, | 1090 | {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, |
1068 | {} | 1091 | {} |
@@ -1074,7 +1097,6 @@ static const struct of_device_id clk_div_match[] __initconst = { | |||
1074 | {.compatible = "allwinner,sun8i-a23-axi-clk", .data = &sun8i_a23_axi_data,}, | 1097 | {.compatible = "allwinner,sun8i-a23-axi-clk", .data = &sun8i_a23_axi_data,}, |
1075 | {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,}, | 1098 | {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,}, |
1076 | {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,}, | 1099 | {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,}, |
1077 | {.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,}, | ||
1078 | {} | 1100 | {} |
1079 | }; | 1101 | }; |
1080 | 1102 | ||
@@ -1082,13 +1104,13 @@ static const struct of_device_id clk_div_match[] __initconst = { | |||
1082 | static const struct of_device_id clk_divs_match[] __initconst = { | 1104 | static const struct of_device_id clk_divs_match[] __initconst = { |
1083 | {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,}, | 1105 | {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,}, |
1084 | {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,}, | 1106 | {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,}, |
1107 | {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_divs_data,}, | ||
1085 | {} | 1108 | {} |
1086 | }; | 1109 | }; |
1087 | 1110 | ||
1088 | /* Matches for mux clocks */ | 1111 | /* Matches for mux clocks */ |
1089 | static const struct of_device_id clk_mux_match[] __initconst = { | 1112 | static const struct of_device_id clk_mux_match[] __initconst = { |
1090 | {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,}, | 1113 | {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,}, |
1091 | {.compatible = "allwinner,sun4i-a10-apb1-mux-clk", .data = &sun4i_apb1_mux_data,}, | ||
1092 | {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, | 1114 | {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, |
1093 | {} | 1115 | {} |
1094 | }; | 1116 | }; |
@@ -1102,16 +1124,21 @@ static const struct of_device_id clk_gates_match[] __initconst = { | |||
1102 | {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,}, | 1124 | {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,}, |
1103 | {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,}, | 1125 | {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,}, |
1104 | {.compatible = "allwinner,sun8i-a23-ahb1-gates-clk", .data = &sun8i_a23_ahb1_gates_data,}, | 1126 | {.compatible = "allwinner,sun8i-a23-ahb1-gates-clk", .data = &sun8i_a23_ahb1_gates_data,}, |
1127 | {.compatible = "allwinner,sun9i-a80-ahb0-gates-clk", .data = &sun9i_a80_ahb0_gates_data,}, | ||
1128 | {.compatible = "allwinner,sun9i-a80-ahb1-gates-clk", .data = &sun9i_a80_ahb1_gates_data,}, | ||
1129 | {.compatible = "allwinner,sun9i-a80-ahb2-gates-clk", .data = &sun9i_a80_ahb2_gates_data,}, | ||
1105 | {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, | 1130 | {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, |
1106 | {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,}, | 1131 | {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,}, |
1107 | {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, | 1132 | {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, |
1108 | {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,}, | 1133 | {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,}, |
1134 | {.compatible = "allwinner,sun9i-a80-apb0-gates-clk", .data = &sun9i_a80_apb0_gates_data,}, | ||
1109 | {.compatible = "allwinner,sun4i-a10-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, | 1135 | {.compatible = "allwinner,sun4i-a10-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, |
1110 | {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,}, | 1136 | {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,}, |
1111 | {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, | 1137 | {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, |
1112 | {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,}, | 1138 | {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,}, |
1113 | {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,}, | 1139 | {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,}, |
1114 | {.compatible = "allwinner,sun8i-a23-apb1-gates-clk", .data = &sun8i_a23_apb1_gates_data,}, | 1140 | {.compatible = "allwinner,sun8i-a23-apb1-gates-clk", .data = &sun8i_a23_apb1_gates_data,}, |
1141 | {.compatible = "allwinner,sun9i-a80-apb1-gates-clk", .data = &sun9i_a80_apb1_gates_data,}, | ||
1115 | {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, | 1142 | {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, |
1116 | {.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,}, | 1143 | {.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,}, |
1117 | {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,}, | 1144 | {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,}, |
@@ -1200,3 +1227,9 @@ static void __init sun6i_init_clocks(struct device_node *node) | |||
1200 | } | 1227 | } |
1201 | CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks); | 1228 | CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks); |
1202 | CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks); | 1229 | CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks); |
1230 | |||
1231 | static void __init sun9i_init_clocks(struct device_node *node) | ||
1232 | { | ||
1233 | sunxi_init_clocks(NULL, 0); | ||
1234 | } | ||
1235 | CLK_OF_DECLARE(sun9i_a80_clk_init, "allwinner,sun9i-a80", sun9i_init_clocks); | ||