diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2016-09-14 14:10:15 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@codeaurora.org> | 2016-09-14 14:10:15 -0400 |
commit | de64f5c87d7422fbdc502aa5934fafecb4e2da32 (patch) | |
tree | c69675457f8f629835ed1866624aba9287f3f7bf | |
parent | 3db385ea144daea9c6e1a15f98eacafaec9ad9f1 (diff) | |
parent | d63a5e7c713a68bd368016f2022326a1a91310d8 (diff) |
Merge tag 'sunxi-clk-for-4.9' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux into clk-next
Pull Allwinner clock driver changes from Maxime Ripard:
Four more SoCs converted to the new clock framework (A31, A31s, A23 and
A33).
* tag 'sunxi-clk-for-4.9' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux:
clk: sunxi-ng: Add hardware dependency
clk: sunxi-ng: Add A23 CCU
clk: sunxi-ng: Add A33 CCU support
clk: sunxi-ng: Add N-class clocks support
clk: sunxi-ng: mux: Add mux table macro
clk: sunxi-ng: div: Allow to set a maximum
clk: sunxi-ng: div: Add kerneldoc for the _ccu_div structure
clk: sunxi-ng: div: Add mux table macros
clk: sunxi-ng: Add A31/A31s clocks
clk: sunxi-ng: mux: Add clk notifier functions
clk: sunxi-ng: mux: support fixed pre-dividers on multiple parents
clk: sunxi-ng: mux: Add support for mux tables
clk: sunxi-ng: mux: Rename mux macro to be consistent
clk: sunxi-ng: nkm: Add mux to support multiple parents
clk: sunxi-ng: mux: Increase fixed pre-divider div size
24 files changed, 3860 insertions, 79 deletions
diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt index cb91507ffb1e..3868458a5feb 100644 --- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt +++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt | |||
@@ -2,7 +2,10 @@ Allwinner Clock Control Unit Binding | |||
2 | ------------------------------------ | 2 | ------------------------------------ |
3 | 3 | ||
4 | Required properties : | 4 | Required properties : |
5 | - compatible: must contain one of the following compatible: | 5 | - compatible: must contain one of the following compatibles: |
6 | - "allwinner,sun6i-a31-ccu" | ||
7 | - "allwinner,sun8i-a23-ccu" | ||
8 | - "allwinner,sun8i-a33-ccu" | ||
6 | - "allwinner,sun8i-h3-ccu" | 9 | - "allwinner,sun8i-h3-ccu" |
7 | 10 | ||
8 | - reg: Must contain the registers base address and length | 11 | - reg: Must contain the registers base address and length |
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 2afcbd39e41e..254d9526c018 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config SUNXI_CCU | 1 | config SUNXI_CCU |
2 | bool "Clock support for Allwinner SoCs" | 2 | bool "Clock support for Allwinner SoCs" |
3 | depends on ARCH_SUNXI || COMPILE_TEST | ||
3 | default ARCH_SUNXI | 4 | default ARCH_SUNXI |
4 | 5 | ||
5 | if SUNXI_CCU | 6 | if SUNXI_CCU |
@@ -19,6 +20,10 @@ config SUNXI_CCU_GATE | |||
19 | config SUNXI_CCU_MUX | 20 | config SUNXI_CCU_MUX |
20 | bool | 21 | bool |
21 | 22 | ||
23 | config SUNXI_CCU_MULT | ||
24 | bool | ||
25 | select SUNXI_CCU_MUX | ||
26 | |||
22 | config SUNXI_CCU_PHASE | 27 | config SUNXI_CCU_PHASE |
23 | bool | 28 | bool |
24 | 29 | ||
@@ -51,6 +56,40 @@ config SUNXI_CCU_MP | |||
51 | 56 | ||
52 | # SoC Drivers | 57 | # SoC Drivers |
53 | 58 | ||
59 | config SUN6I_A31_CCU | ||
60 | bool "Support for the Allwinner A31/A31s CCU" | ||
61 | select SUNXI_CCU_DIV | ||
62 | select SUNXI_CCU_NK | ||
63 | select SUNXI_CCU_NKM | ||
64 | select SUNXI_CCU_NM | ||
65 | select SUNXI_CCU_MP | ||
66 | select SUNXI_CCU_PHASE | ||
67 | default MACH_SUN6I | ||
68 | |||
69 | config SUN8I_A23_CCU | ||
70 | bool "Support for the Allwinner A23 CCU" | ||
71 | select SUNXI_CCU_DIV | ||
72 | select SUNXI_CCU_MULT | ||
73 | select SUNXI_CCU_NK | ||
74 | select SUNXI_CCU_NKM | ||
75 | select SUNXI_CCU_NKMP | ||
76 | select SUNXI_CCU_NM | ||
77 | select SUNXI_CCU_MP | ||
78 | select SUNXI_CCU_PHASE | ||
79 | default MACH_SUN8I | ||
80 | |||
81 | config SUN8I_A33_CCU | ||
82 | bool "Support for the Allwinner A33 CCU" | ||
83 | select SUNXI_CCU_DIV | ||
84 | select SUNXI_CCU_MULT | ||
85 | select SUNXI_CCU_NK | ||
86 | select SUNXI_CCU_NKM | ||
87 | select SUNXI_CCU_NKMP | ||
88 | select SUNXI_CCU_NM | ||
89 | select SUNXI_CCU_MP | ||
90 | select SUNXI_CCU_PHASE | ||
91 | default MACH_SUN8I | ||
92 | |||
54 | config SUN8I_H3_CCU | 93 | config SUN8I_H3_CCU |
55 | bool "Support for the Allwinner H3 CCU" | 94 | bool "Support for the Allwinner H3 CCU" |
56 | select SUNXI_CCU_DIV | 95 | select SUNXI_CCU_DIV |
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 633ce642ffae..106cba27c331 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile | |||
@@ -7,6 +7,7 @@ obj-$(CONFIG_SUNXI_CCU_DIV) += ccu_div.o | |||
7 | obj-$(CONFIG_SUNXI_CCU_FRAC) += ccu_frac.o | 7 | obj-$(CONFIG_SUNXI_CCU_FRAC) += ccu_frac.o |
8 | obj-$(CONFIG_SUNXI_CCU_GATE) += ccu_gate.o | 8 | obj-$(CONFIG_SUNXI_CCU_GATE) += ccu_gate.o |
9 | obj-$(CONFIG_SUNXI_CCU_MUX) += ccu_mux.o | 9 | obj-$(CONFIG_SUNXI_CCU_MUX) += ccu_mux.o |
10 | obj-$(CONFIG_SUNXI_CCU_MULT) += ccu_mult.o | ||
10 | obj-$(CONFIG_SUNXI_CCU_PHASE) += ccu_phase.o | 11 | obj-$(CONFIG_SUNXI_CCU_PHASE) += ccu_phase.o |
11 | 12 | ||
12 | # Multi-factor clocks | 13 | # Multi-factor clocks |
@@ -17,4 +18,7 @@ obj-$(CONFIG_SUNXI_CCU_NM) += ccu_nm.o | |||
17 | obj-$(CONFIG_SUNXI_CCU_MP) += ccu_mp.o | 18 | obj-$(CONFIG_SUNXI_CCU_MP) += ccu_mp.o |
18 | 19 | ||
19 | # SoC support | 20 | # SoC support |
21 | obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o | ||
22 | obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o | ||
23 | obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o | ||
20 | obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o | 24 | obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o |
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c new file mode 100644 index 000000000000..f1d61faa5bd9 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c | |||
@@ -0,0 +1,1235 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016 Chen-Yu Tsai | ||
3 | * | ||
4 | * Chen-Yu Tsai <wens@csie.org> | ||
5 | * | ||
6 | * Based on ccu-sun8i-h3.c by Maxime Ripard. | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/clk-provider.h> | ||
19 | #include <linux/of_address.h> | ||
20 | |||
21 | #include "ccu_common.h" | ||
22 | #include "ccu_reset.h" | ||
23 | |||
24 | #include "ccu_div.h" | ||
25 | #include "ccu_gate.h" | ||
26 | #include "ccu_mp.h" | ||
27 | #include "ccu_mult.h" | ||
28 | #include "ccu_mux.h" | ||
29 | #include "ccu_nk.h" | ||
30 | #include "ccu_nkm.h" | ||
31 | #include "ccu_nkmp.h" | ||
32 | #include "ccu_nm.h" | ||
33 | #include "ccu_phase.h" | ||
34 | |||
35 | #include "ccu-sun6i-a31.h" | ||
36 | |||
37 | static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu", | ||
38 | "osc24M", 0x000, | ||
39 | 8, 5, /* N */ | ||
40 | 4, 2, /* K */ | ||
41 | 0, 2, /* M */ | ||
42 | BIT(31), /* gate */ | ||
43 | BIT(28), /* lock */ | ||
44 | 0); | ||
45 | |||
46 | /* | ||
47 | * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from | ||
48 | * the base (2x, 4x and 8x), and one variable divider (the one true | ||
49 | * pll audio). | ||
50 | * | ||
51 | * We don't have any need for the variable divider for now, so we just | ||
52 | * hardcode it to match with the clock names | ||
53 | */ | ||
54 | #define SUN6I_A31_PLL_AUDIO_REG 0x008 | ||
55 | |||
56 | static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", | ||
57 | "osc24M", 0x008, | ||
58 | 8, 7, /* N */ | ||
59 | 0, 5, /* M */ | ||
60 | BIT(31), /* gate */ | ||
61 | BIT(28), /* lock */ | ||
62 | 0); | ||
63 | |||
64 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0", | ||
65 | "osc24M", 0x010, | ||
66 | 8, 7, /* N */ | ||
67 | 0, 4, /* M */ | ||
68 | BIT(24), /* frac enable */ | ||
69 | BIT(25), /* frac select */ | ||
70 | 270000000, /* frac rate 0 */ | ||
71 | 297000000, /* frac rate 1 */ | ||
72 | BIT(31), /* gate */ | ||
73 | BIT(28), /* lock */ | ||
74 | 0); | ||
75 | |||
76 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", | ||
77 | "osc24M", 0x018, | ||
78 | 8, 7, /* N */ | ||
79 | 0, 4, /* M */ | ||
80 | BIT(24), /* frac enable */ | ||
81 | BIT(25), /* frac select */ | ||
82 | 270000000, /* frac rate 0 */ | ||
83 | 297000000, /* frac rate 1 */ | ||
84 | BIT(31), /* gate */ | ||
85 | BIT(28), /* lock */ | ||
86 | 0); | ||
87 | |||
88 | static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr", | ||
89 | "osc24M", 0x020, | ||
90 | 8, 5, /* N */ | ||
91 | 4, 2, /* K */ | ||
92 | 0, 2, /* M */ | ||
93 | BIT(31), /* gate */ | ||
94 | BIT(28), /* lock */ | ||
95 | 0); | ||
96 | |||
97 | static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph", | ||
98 | "osc24M", 0x028, | ||
99 | 8, 5, /* N */ | ||
100 | 4, 2, /* K */ | ||
101 | BIT(31), /* gate */ | ||
102 | BIT(28), /* lock */ | ||
103 | 2, /* post-div */ | ||
104 | 0); | ||
105 | |||
106 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1", | ||
107 | "osc24M", 0x030, | ||
108 | 8, 7, /* N */ | ||
109 | 0, 4, /* M */ | ||
110 | BIT(24), /* frac enable */ | ||
111 | BIT(25), /* frac select */ | ||
112 | 270000000, /* frac rate 0 */ | ||
113 | 297000000, /* frac rate 1 */ | ||
114 | BIT(31), /* gate */ | ||
115 | BIT(28), /* lock */ | ||
116 | 0); | ||
117 | |||
118 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", | ||
119 | "osc24M", 0x038, | ||
120 | 8, 7, /* N */ | ||
121 | 0, 4, /* M */ | ||
122 | BIT(24), /* frac enable */ | ||
123 | BIT(25), /* frac select */ | ||
124 | 270000000, /* frac rate 0 */ | ||
125 | 297000000, /* frac rate 1 */ | ||
126 | BIT(31), /* gate */ | ||
127 | BIT(28), /* lock */ | ||
128 | 0); | ||
129 | |||
130 | /* | ||
131 | * The MIPI PLL has 2 modes: "MIPI" and "HDMI". | ||
132 | * | ||
133 | * The MIPI mode is a standard NKM-style clock. The HDMI mode is an | ||
134 | * integer / fractional clock with switchable multipliers and dividers. | ||
135 | * This is not supported here. We hardcode the PLL to MIPI mode. | ||
136 | */ | ||
137 | #define SUN6I_A31_PLL_MIPI_REG 0x040 | ||
138 | |||
139 | static const char * const pll_mipi_parents[] = { "pll-video0", "pll-video1" }; | ||
140 | static SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(pll_mipi_clk, "pll-mipi", | ||
141 | pll_mipi_parents, 0x040, | ||
142 | 8, 4, /* N */ | ||
143 | 4, 2, /* K */ | ||
144 | 0, 4, /* M */ | ||
145 | 21, 0, /* mux */ | ||
146 | BIT(31), /* gate */ | ||
147 | BIT(28), /* lock */ | ||
148 | 0); | ||
149 | |||
150 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll9_clk, "pll9", | ||
151 | "osc24M", 0x044, | ||
152 | 8, 7, /* N */ | ||
153 | 0, 4, /* M */ | ||
154 | BIT(24), /* frac enable */ | ||
155 | BIT(25), /* frac select */ | ||
156 | 270000000, /* frac rate 0 */ | ||
157 | 297000000, /* frac rate 1 */ | ||
158 | BIT(31), /* gate */ | ||
159 | BIT(28), /* lock */ | ||
160 | 0); | ||
161 | |||
162 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll10_clk, "pll10", | ||
163 | "osc24M", 0x048, | ||
164 | 8, 7, /* N */ | ||
165 | 0, 4, /* M */ | ||
166 | BIT(24), /* frac enable */ | ||
167 | BIT(25), /* frac select */ | ||
168 | 270000000, /* frac rate 0 */ | ||
169 | 297000000, /* frac rate 1 */ | ||
170 | BIT(31), /* gate */ | ||
171 | BIT(28), /* lock */ | ||
172 | 0); | ||
173 | |||
174 | static const char * const cpux_parents[] = { "osc32k", "osc24M", | ||
175 | "pll-cpu", "pll-cpu" }; | ||
176 | static SUNXI_CCU_MUX(cpu_clk, "cpu", cpux_parents, | ||
177 | 0x050, 16, 2, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); | ||
178 | |||
179 | static struct clk_div_table axi_div_table[] = { | ||
180 | { .val = 0, .div = 1 }, | ||
181 | { .val = 1, .div = 2 }, | ||
182 | { .val = 2, .div = 3 }, | ||
183 | { .val = 3, .div = 4 }, | ||
184 | { .val = 4, .div = 4 }, | ||
185 | { .val = 5, .div = 4 }, | ||
186 | { .val = 6, .div = 4 }, | ||
187 | { .val = 7, .div = 4 }, | ||
188 | { /* Sentinel */ }, | ||
189 | }; | ||
190 | |||
191 | static SUNXI_CCU_DIV_TABLE(axi_clk, "axi", "cpu", | ||
192 | 0x050, 0, 3, axi_div_table, 0); | ||
193 | |||
194 | static const char * const ahb1_parents[] = { "osc32k", "osc24M", | ||
195 | "axi", "pll-periph" }; | ||
196 | |||
197 | static struct ccu_div ahb1_clk = { | ||
198 | .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), | ||
199 | |||
200 | .mux = { | ||
201 | .shift = 12, | ||
202 | .width = 2, | ||
203 | |||
204 | .variable_prediv = { | ||
205 | .index = 3, | ||
206 | .shift = 6, | ||
207 | .width = 2, | ||
208 | }, | ||
209 | }, | ||
210 | |||
211 | .common = { | ||
212 | .reg = 0x054, | ||
213 | .features = CCU_FEATURE_VARIABLE_PREDIV, | ||
214 | .hw.init = CLK_HW_INIT_PARENTS("ahb1", | ||
215 | ahb1_parents, | ||
216 | &ccu_div_ops, | ||
217 | 0), | ||
218 | }, | ||
219 | }; | ||
220 | |||
221 | static struct clk_div_table apb1_div_table[] = { | ||
222 | { .val = 0, .div = 2 }, | ||
223 | { .val = 1, .div = 2 }, | ||
224 | { .val = 2, .div = 4 }, | ||
225 | { .val = 3, .div = 8 }, | ||
226 | { /* Sentinel */ }, | ||
227 | }; | ||
228 | |||
229 | static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1", | ||
230 | 0x054, 8, 2, apb1_div_table, 0); | ||
231 | |||
232 | static const char * const apb2_parents[] = { "osc32k", "osc24M", | ||
233 | "pll-periph", "pll-periph" }; | ||
234 | static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058, | ||
235 | 0, 5, /* M */ | ||
236 | 16, 2, /* P */ | ||
237 | 24, 2, /* mux */ | ||
238 | 0); | ||
239 | |||
240 | static SUNXI_CCU_GATE(ahb1_mipidsi_clk, "ahb1-mipidsi", "ahb1", | ||
241 | 0x060, BIT(1), 0); | ||
242 | static SUNXI_CCU_GATE(ahb1_ss_clk, "ahb1-ss", "ahb1", | ||
243 | 0x060, BIT(5), 0); | ||
244 | static SUNXI_CCU_GATE(ahb1_dma_clk, "ahb1-dma", "ahb1", | ||
245 | 0x060, BIT(6), 0); | ||
246 | static SUNXI_CCU_GATE(ahb1_mmc0_clk, "ahb1-mmc0", "ahb1", | ||
247 | 0x060, BIT(8), 0); | ||
248 | static SUNXI_CCU_GATE(ahb1_mmc1_clk, "ahb1-mmc1", "ahb1", | ||
249 | 0x060, BIT(9), 0); | ||
250 | static SUNXI_CCU_GATE(ahb1_mmc2_clk, "ahb1-mmc2", "ahb1", | ||
251 | 0x060, BIT(10), 0); | ||
252 | static SUNXI_CCU_GATE(ahb1_mmc3_clk, "ahb1-mmc3", "ahb1", | ||
253 | 0x060, BIT(12), 0); | ||
254 | static SUNXI_CCU_GATE(ahb1_nand1_clk, "ahb1-nand1", "ahb1", | ||
255 | 0x060, BIT(13), 0); | ||
256 | static SUNXI_CCU_GATE(ahb1_nand0_clk, "ahb1-nand0", "ahb1", | ||
257 | 0x060, BIT(13), 0); | ||
258 | static SUNXI_CCU_GATE(ahb1_sdram_clk, "ahb1-sdram", "ahb1", | ||
259 | 0x060, BIT(14), 0); | ||
260 | static SUNXI_CCU_GATE(ahb1_emac_clk, "ahb1-emac", "ahb1", | ||
261 | 0x060, BIT(17), 0); | ||
262 | static SUNXI_CCU_GATE(ahb1_ts_clk, "ahb1-ts", "ahb1", | ||
263 | 0x060, BIT(18), 0); | ||
264 | static SUNXI_CCU_GATE(ahb1_hstimer_clk, "ahb1-hstimer", "ahb1", | ||
265 | 0x060, BIT(19), 0); | ||
266 | static SUNXI_CCU_GATE(ahb1_spi0_clk, "ahb1-spi0", "ahb1", | ||
267 | 0x060, BIT(20), 0); | ||
268 | static SUNXI_CCU_GATE(ahb1_spi1_clk, "ahb1-spi1", "ahb1", | ||
269 | 0x060, BIT(21), 0); | ||
270 | static SUNXI_CCU_GATE(ahb1_spi2_clk, "ahb1-spi2", "ahb1", | ||
271 | 0x060, BIT(22), 0); | ||
272 | static SUNXI_CCU_GATE(ahb1_spi3_clk, "ahb1-spi3", "ahb1", | ||
273 | 0x060, BIT(23), 0); | ||
274 | static SUNXI_CCU_GATE(ahb1_otg_clk, "ahb1-otg", "ahb1", | ||
275 | 0x060, BIT(24), 0); | ||
276 | static SUNXI_CCU_GATE(ahb1_ehci0_clk, "ahb1-ehci0", "ahb1", | ||
277 | 0x060, BIT(26), 0); | ||
278 | static SUNXI_CCU_GATE(ahb1_ehci1_clk, "ahb1-ehci1", "ahb1", | ||
279 | 0x060, BIT(27), 0); | ||
280 | static SUNXI_CCU_GATE(ahb1_ohci0_clk, "ahb1-ohci0", "ahb1", | ||
281 | 0x060, BIT(29), 0); | ||
282 | static SUNXI_CCU_GATE(ahb1_ohci1_clk, "ahb1-ohci1", "ahb1", | ||
283 | 0x060, BIT(30), 0); | ||
284 | static SUNXI_CCU_GATE(ahb1_ohci2_clk, "ahb1-ohci2", "ahb1", | ||
285 | 0x060, BIT(31), 0); | ||
286 | |||
287 | static SUNXI_CCU_GATE(ahb1_ve_clk, "ahb1-ve", "ahb1", | ||
288 | 0x064, BIT(0), 0); | ||
289 | static SUNXI_CCU_GATE(ahb1_lcd0_clk, "ahb1-lcd0", "ahb1", | ||
290 | 0x064, BIT(4), 0); | ||
291 | static SUNXI_CCU_GATE(ahb1_lcd1_clk, "ahb1-lcd1", "ahb1", | ||
292 | 0x064, BIT(5), 0); | ||
293 | static SUNXI_CCU_GATE(ahb1_csi_clk, "ahb1-csi", "ahb1", | ||
294 | 0x064, BIT(8), 0); | ||
295 | static SUNXI_CCU_GATE(ahb1_hdmi_clk, "ahb1-hdmi", "ahb1", | ||
296 | 0x064, BIT(11), 0); | ||
297 | static SUNXI_CCU_GATE(ahb1_be0_clk, "ahb1-be0", "ahb1", | ||
298 | 0x064, BIT(12), 0); | ||
299 | static SUNXI_CCU_GATE(ahb1_be1_clk, "ahb1-be1", "ahb1", | ||
300 | 0x064, BIT(13), 0); | ||
301 | static SUNXI_CCU_GATE(ahb1_fe0_clk, "ahb1-fe0", "ahb1", | ||
302 | 0x064, BIT(14), 0); | ||
303 | static SUNXI_CCU_GATE(ahb1_fe1_clk, "ahb1-fe1", "ahb1", | ||
304 | 0x064, BIT(15), 0); | ||
305 | static SUNXI_CCU_GATE(ahb1_mp_clk, "ahb1-mp", "ahb1", | ||
306 | 0x064, BIT(18), 0); | ||
307 | static SUNXI_CCU_GATE(ahb1_gpu_clk, "ahb1-gpu", "ahb1", | ||
308 | 0x064, BIT(20), 0); | ||
309 | static SUNXI_CCU_GATE(ahb1_deu0_clk, "ahb1-deu0", "ahb1", | ||
310 | 0x064, BIT(23), 0); | ||
311 | static SUNXI_CCU_GATE(ahb1_deu1_clk, "ahb1-deu1", "ahb1", | ||
312 | 0x064, BIT(24), 0); | ||
313 | static SUNXI_CCU_GATE(ahb1_drc0_clk, "ahb1-drc0", "ahb1", | ||
314 | 0x064, BIT(25), 0); | ||
315 | static SUNXI_CCU_GATE(ahb1_drc1_clk, "ahb1-drc1", "ahb1", | ||
316 | 0x064, BIT(26), 0); | ||
317 | |||
318 | static SUNXI_CCU_GATE(apb1_codec_clk, "apb1-codec", "apb1", | ||
319 | 0x068, BIT(0), 0); | ||
320 | static SUNXI_CCU_GATE(apb1_spdif_clk, "apb1-spdif", "apb1", | ||
321 | 0x068, BIT(1), 0); | ||
322 | static SUNXI_CCU_GATE(apb1_digital_mic_clk, "apb1-digital-mic", "apb1", | ||
323 | 0x068, BIT(4), 0); | ||
324 | static SUNXI_CCU_GATE(apb1_pio_clk, "apb1-pio", "apb1", | ||
325 | 0x068, BIT(5), 0); | ||
326 | static SUNXI_CCU_GATE(apb1_daudio0_clk, "apb1-daudio0", "apb1", | ||
327 | 0x068, BIT(12), 0); | ||
328 | static SUNXI_CCU_GATE(apb1_daudio1_clk, "apb1-daudio1", "apb1", | ||
329 | 0x068, BIT(13), 0); | ||
330 | |||
331 | static SUNXI_CCU_GATE(apb2_i2c0_clk, "apb2-i2c0", "apb2", | ||
332 | 0x06c, BIT(0), 0); | ||
333 | static SUNXI_CCU_GATE(apb2_i2c1_clk, "apb2-i2c1", "apb2", | ||
334 | 0x06c, BIT(1), 0); | ||
335 | static SUNXI_CCU_GATE(apb2_i2c2_clk, "apb2-i2c2", "apb2", | ||
336 | 0x06c, BIT(2), 0); | ||
337 | static SUNXI_CCU_GATE(apb2_i2c3_clk, "apb2-i2c3", "apb2", | ||
338 | 0x06c, BIT(3), 0); | ||
339 | static SUNXI_CCU_GATE(apb2_uart0_clk, "apb2-uart0", "apb2", | ||
340 | 0x06c, BIT(16), 0); | ||
341 | static SUNXI_CCU_GATE(apb2_uart1_clk, "apb2-uart1", "apb2", | ||
342 | 0x06c, BIT(17), 0); | ||
343 | static SUNXI_CCU_GATE(apb2_uart2_clk, "apb2-uart2", "apb2", | ||
344 | 0x06c, BIT(18), 0); | ||
345 | static SUNXI_CCU_GATE(apb2_uart3_clk, "apb2-uart3", "apb2", | ||
346 | 0x06c, BIT(19), 0); | ||
347 | static SUNXI_CCU_GATE(apb2_uart4_clk, "apb2-uart4", "apb2", | ||
348 | 0x06c, BIT(20), 0); | ||
349 | static SUNXI_CCU_GATE(apb2_uart5_clk, "apb2-uart5", "apb2", | ||
350 | 0x06c, BIT(21), 0); | ||
351 | |||
352 | static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" }; | ||
353 | static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", mod0_default_parents, | ||
354 | 0x080, | ||
355 | 0, 4, /* M */ | ||
356 | 16, 2, /* P */ | ||
357 | 24, 2, /* mux */ | ||
358 | BIT(31), /* gate */ | ||
359 | 0); | ||
360 | |||
361 | static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", mod0_default_parents, | ||
362 | 0x084, | ||
363 | 0, 4, /* M */ | ||
364 | 16, 2, /* P */ | ||
365 | 24, 2, /* mux */ | ||
366 | BIT(31), /* gate */ | ||
367 | 0); | ||
368 | |||
369 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, | ||
370 | 0x088, | ||
371 | 0, 4, /* M */ | ||
372 | 16, 2, /* P */ | ||
373 | 24, 2, /* mux */ | ||
374 | BIT(31), /* gate */ | ||
375 | 0); | ||
376 | |||
377 | static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0", | ||
378 | 0x088, 20, 3, 0); | ||
379 | static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0", | ||
380 | 0x088, 8, 3, 0); | ||
381 | |||
382 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, | ||
383 | 0x08c, | ||
384 | 0, 4, /* M */ | ||
385 | 16, 2, /* P */ | ||
386 | 24, 2, /* mux */ | ||
387 | BIT(31), /* gate */ | ||
388 | 0); | ||
389 | |||
390 | static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1", | ||
391 | 0x08c, 20, 3, 0); | ||
392 | static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1", | ||
393 | 0x08c, 8, 3, 0); | ||
394 | |||
395 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, | ||
396 | 0x090, | ||
397 | 0, 4, /* M */ | ||
398 | 16, 2, /* P */ | ||
399 | 24, 2, /* mux */ | ||
400 | BIT(31), /* gate */ | ||
401 | 0); | ||
402 | |||
403 | static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2", | ||
404 | 0x090, 20, 3, 0); | ||
405 | static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2", | ||
406 | 0x090, 8, 3, 0); | ||
407 | |||
408 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents, | ||
409 | 0x094, | ||
410 | 0, 4, /* M */ | ||
411 | 16, 2, /* P */ | ||
412 | 24, 2, /* mux */ | ||
413 | BIT(31), /* gate */ | ||
414 | 0); | ||
415 | |||
416 | static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3_sample", "mmc3", | ||
417 | 0x094, 20, 3, 0); | ||
418 | static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3_output", "mmc3", | ||
419 | 0x094, 8, 3, 0); | ||
420 | |||
421 | static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098, | ||
422 | 0, 4, /* M */ | ||
423 | 16, 2, /* P */ | ||
424 | 24, 2, /* mux */ | ||
425 | BIT(31), /* gate */ | ||
426 | 0); | ||
427 | |||
428 | static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c, | ||
429 | 0, 4, /* M */ | ||
430 | 16, 2, /* P */ | ||
431 | 24, 2, /* mux */ | ||
432 | BIT(31), /* gate */ | ||
433 | 0); | ||
434 | |||
435 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0, | ||
436 | 0, 4, /* M */ | ||
437 | 16, 2, /* P */ | ||
438 | 24, 2, /* mux */ | ||
439 | BIT(31), /* gate */ | ||
440 | 0); | ||
441 | |||
442 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4, | ||
443 | 0, 4, /* M */ | ||
444 | 16, 2, /* P */ | ||
445 | 24, 2, /* mux */ | ||
446 | BIT(31), /* gate */ | ||
447 | 0); | ||
448 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8, | ||
449 | 0, 4, /* M */ | ||
450 | 16, 2, /* P */ | ||
451 | 24, 2, /* mux */ | ||
452 | BIT(31), /* gate */ | ||
453 | 0); | ||
454 | |||
455 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0ac, | ||
456 | 0, 4, /* M */ | ||
457 | 16, 2, /* P */ | ||
458 | 24, 2, /* mux */ | ||
459 | BIT(31), /* gate */ | ||
460 | 0); | ||
461 | |||
462 | static const char * const daudio_parents[] = { "pll-audio-8x", "pll-audio-4x", | ||
463 | "pll-audio-2x", "pll-audio" }; | ||
464 | static SUNXI_CCU_MUX_WITH_GATE(daudio0_clk, "daudio0", daudio_parents, | ||
465 | 0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
466 | static SUNXI_CCU_MUX_WITH_GATE(daudio1_clk, "daudio1", daudio_parents, | ||
467 | 0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
468 | |||
469 | static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio", | ||
470 | 0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT); | ||
471 | |||
472 | static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", | ||
473 | 0x0cc, BIT(8), 0); | ||
474 | static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", | ||
475 | 0x0cc, BIT(9), 0); | ||
476 | static SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M", | ||
477 | 0x0cc, BIT(10), 0); | ||
478 | static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M", | ||
479 | 0x0cc, BIT(16), 0); | ||
480 | static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc24M", | ||
481 | 0x0cc, BIT(17), 0); | ||
482 | static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc24M", | ||
483 | 0x0cc, BIT(18), 0); | ||
484 | |||
485 | /* TODO emac clk not supported yet */ | ||
486 | |||
487 | static const char * const dram_parents[] = { "pll-ddr", "pll-periph" }; | ||
488 | static SUNXI_CCU_MP_WITH_MUX_GATE(mdfs_clk, "mdfs", dram_parents, 0x0f0, | ||
489 | 0, 4, /* M */ | ||
490 | 16, 2, /* P */ | ||
491 | 24, 2, /* mux */ | ||
492 | BIT(31), /* gate */ | ||
493 | CLK_IS_CRITICAL); | ||
494 | |||
495 | static SUNXI_CCU_M_WITH_MUX(sdram0_clk, "sdram0", dram_parents, | ||
496 | 0x0f4, 0, 4, 4, 1, CLK_IS_CRITICAL); | ||
497 | static SUNXI_CCU_M_WITH_MUX(sdram1_clk, "sdram1", dram_parents, | ||
498 | 0x0f4, 8, 4, 12, 1, CLK_IS_CRITICAL); | ||
499 | |||
500 | static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "mdfs", | ||
501 | 0x100, BIT(0), 0); | ||
502 | static SUNXI_CCU_GATE(dram_csi_isp_clk, "dram-csi-isp", "mdfs", | ||
503 | 0x100, BIT(1), 0); | ||
504 | static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "mdfs", | ||
505 | 0x100, BIT(3), 0); | ||
506 | static SUNXI_CCU_GATE(dram_drc0_clk, "dram-drc0", "mdfs", | ||
507 | 0x100, BIT(16), 0); | ||
508 | static SUNXI_CCU_GATE(dram_drc1_clk, "dram-drc1", "mdfs", | ||
509 | 0x100, BIT(17), 0); | ||
510 | static SUNXI_CCU_GATE(dram_deu0_clk, "dram-deu0", "mdfs", | ||
511 | 0x100, BIT(18), 0); | ||
512 | static SUNXI_CCU_GATE(dram_deu1_clk, "dram-deu1", "mdfs", | ||
513 | 0x100, BIT(19), 0); | ||
514 | static SUNXI_CCU_GATE(dram_fe0_clk, "dram-fe0", "mdfs", | ||
515 | 0x100, BIT(24), 0); | ||
516 | static SUNXI_CCU_GATE(dram_fe1_clk, "dram-fe1", "mdfs", | ||
517 | 0x100, BIT(25), 0); | ||
518 | static SUNXI_CCU_GATE(dram_be0_clk, "dram-be0", "mdfs", | ||
519 | 0x100, BIT(26), 0); | ||
520 | static SUNXI_CCU_GATE(dram_be1_clk, "dram-be1", "mdfs", | ||
521 | 0x100, BIT(27), 0); | ||
522 | static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "mdfs", | ||
523 | 0x100, BIT(28), 0); | ||
524 | |||
525 | static const char * const de_parents[] = { "pll-video0", "pll-video1", | ||
526 | "pll-periph-2x", "pll-gpu", | ||
527 | "pll9", "pll10" }; | ||
528 | static SUNXI_CCU_M_WITH_MUX_GATE(be0_clk, "be0", de_parents, | ||
529 | 0x104, 0, 4, 24, 3, BIT(31), 0); | ||
530 | static SUNXI_CCU_M_WITH_MUX_GATE(be1_clk, "be1", de_parents, | ||
531 | 0x108, 0, 4, 24, 3, BIT(31), 0); | ||
532 | static SUNXI_CCU_M_WITH_MUX_GATE(fe0_clk, "fe0", de_parents, | ||
533 | 0x10c, 0, 4, 24, 3, BIT(31), 0); | ||
534 | static SUNXI_CCU_M_WITH_MUX_GATE(fe1_clk, "fe1", de_parents, | ||
535 | 0x110, 0, 4, 24, 3, BIT(31), 0); | ||
536 | |||
537 | static const char * const mp_parents[] = { "pll-video0", "pll-video1", | ||
538 | "pll9", "pll10" }; | ||
539 | static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", mp_parents, | ||
540 | 0x114, 0, 4, 24, 3, BIT(31), 0); | ||
541 | |||
542 | static const char * const lcd_ch0_parents[] = { "pll-video0", "pll-video1", | ||
543 | "pll-video0-2x", | ||
544 | "pll-video1-2x", "pll-mipi" }; | ||
545 | static SUNXI_CCU_MUX_WITH_GATE(lcd0_ch0_clk, "lcd0-ch0", lcd_ch0_parents, | ||
546 | 0x118, 24, 2, BIT(31), 0); | ||
547 | static SUNXI_CCU_MUX_WITH_GATE(lcd1_ch0_clk, "lcd1-ch0", lcd_ch0_parents, | ||
548 | 0x11c, 24, 2, BIT(31), 0); | ||
549 | |||
550 | static const char * const lcd_ch1_parents[] = { "pll-video0", "pll-video1", | ||
551 | "pll-video0-2x", | ||
552 | "pll-video1-2x" }; | ||
553 | static SUNXI_CCU_M_WITH_MUX_GATE(lcd0_ch1_clk, "lcd0-ch1", lcd_ch1_parents, | ||
554 | 0x12c, 0, 4, 24, 3, BIT(31), 0); | ||
555 | static SUNXI_CCU_M_WITH_MUX_GATE(lcd1_ch1_clk, "lcd1-ch1", lcd_ch1_parents, | ||
556 | 0x12c, 0, 4, 24, 3, BIT(31), 0); | ||
557 | |||
558 | static const char * const csi_sclk_parents[] = { "pll-video0", "pll-video1", | ||
559 | "pll9", "pll10", "pll-mipi", | ||
560 | "pll-ve" }; | ||
561 | static SUNXI_CCU_M_WITH_MUX_GATE(csi0_sclk_clk, "csi0-sclk", csi_sclk_parents, | ||
562 | 0x134, 16, 4, 24, 3, BIT(31), 0); | ||
563 | |||
564 | static const char * const csi_mclk_parents[] = { "pll-video0", "pll-video1", | ||
565 | "osc24M" }; | ||
566 | static const u8 csi_mclk_table[] = { 0, 1, 5 }; | ||
567 | static struct ccu_div csi0_mclk_clk = { | ||
568 | .enable = BIT(15), | ||
569 | .div = _SUNXI_CCU_DIV(0, 4), | ||
570 | .mux = _SUNXI_CCU_MUX_TABLE(8, 3, csi_mclk_table), | ||
571 | .common = { | ||
572 | .reg = 0x134, | ||
573 | .hw.init = CLK_HW_INIT_PARENTS("csi0-mclk", | ||
574 | csi_mclk_parents, | ||
575 | &ccu_div_ops, | ||
576 | 0), | ||
577 | }, | ||
578 | }; | ||
579 | |||
580 | static struct ccu_div csi1_mclk_clk = { | ||
581 | .enable = BIT(15), | ||
582 | .div = _SUNXI_CCU_DIV(0, 4), | ||
583 | .mux = _SUNXI_CCU_MUX_TABLE(8, 3, csi_mclk_table), | ||
584 | .common = { | ||
585 | .reg = 0x138, | ||
586 | .hw.init = CLK_HW_INIT_PARENTS("csi1-mclk", | ||
587 | csi_mclk_parents, | ||
588 | &ccu_div_ops, | ||
589 | 0), | ||
590 | }, | ||
591 | }; | ||
592 | |||
593 | static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", | ||
594 | 0x13c, 16, 3, BIT(31), 0); | ||
595 | |||
596 | static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio", | ||
597 | 0x140, BIT(31), CLK_SET_RATE_PARENT); | ||
598 | static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", | ||
599 | 0x144, BIT(31), 0); | ||
600 | static SUNXI_CCU_GATE(digital_mic_clk, "digital-mic", "pll-audio", | ||
601 | 0x148, BIT(31), CLK_SET_RATE_PARENT); | ||
602 | |||
603 | static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents, | ||
604 | 0x150, 0, 4, 24, 2, BIT(31), 0); | ||
605 | |||
606 | static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(31), 0); | ||
607 | |||
608 | static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0); | ||
609 | |||
610 | static const char * const mbus_parents[] = { "osc24M", "pll-periph", | ||
611 | "pll-ddr" }; | ||
612 | static SUNXI_CCU_MP_WITH_MUX_GATE(mbus0_clk, "mbus0", mbus_parents, 0x15c, | ||
613 | 0, 3, /* M */ | ||
614 | 16, 2, /* P */ | ||
615 | 24, 2, /* mux */ | ||
616 | BIT(31), /* gate */ | ||
617 | CLK_IS_CRITICAL); | ||
618 | |||
619 | static SUNXI_CCU_MP_WITH_MUX_GATE(mbus1_clk, "mbus1", mbus_parents, 0x160, | ||
620 | 0, 3, /* M */ | ||
621 | 16, 2, /* P */ | ||
622 | 24, 2, /* mux */ | ||
623 | BIT(31), /* gate */ | ||
624 | CLK_IS_CRITICAL); | ||
625 | |||
626 | static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_clk, "mipi-dsi", lcd_ch1_parents, | ||
627 | 0x168, 16, 3, 24, 2, BIT(31), 0); | ||
628 | static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_dphy_clk, "mipi-dsi-dphy", | ||
629 | lcd_ch1_parents, 0x168, 0, 3, 8, 2, | ||
630 | BIT(15), 0); | ||
631 | static SUNXI_CCU_M_WITH_MUX_GATE(mipi_csi_dphy_clk, "mipi-csi-dphy", | ||
632 | lcd_ch1_parents, 0x168, 0, 3, 8, 2, | ||
633 | BIT(15), 0); | ||
634 | |||
635 | static SUNXI_CCU_M_WITH_MUX_GATE(iep_drc0_clk, "iep-drc0", de_parents, | ||
636 | 0x180, 0, 3, 24, 2, BIT(31), 0); | ||
637 | static SUNXI_CCU_M_WITH_MUX_GATE(iep_drc1_clk, "iep-drc1", de_parents, | ||
638 | 0x184, 0, 3, 24, 2, BIT(31), 0); | ||
639 | static SUNXI_CCU_M_WITH_MUX_GATE(iep_deu0_clk, "iep-deu0", de_parents, | ||
640 | 0x188, 0, 3, 24, 2, BIT(31), 0); | ||
641 | static SUNXI_CCU_M_WITH_MUX_GATE(iep_deu1_clk, "iep-deu1", de_parents, | ||
642 | 0x18c, 0, 3, 24, 2, BIT(31), 0); | ||
643 | |||
644 | static const char * const gpu_parents[] = { "pll-gpu", "pll-periph-2x", | ||
645 | "pll-video0", "pll-video1", | ||
646 | "pll9", "pll10" }; | ||
647 | static const struct ccu_mux_fixed_prediv gpu_predivs[] = { | ||
648 | { .index = 1, .div = 3, }, | ||
649 | }; | ||
650 | |||
651 | static struct ccu_div gpu_core_clk = { | ||
652 | .enable = BIT(31), | ||
653 | .div = _SUNXI_CCU_DIV(0, 3), | ||
654 | .mux = { | ||
655 | .shift = 24, | ||
656 | .width = 3, | ||
657 | .fixed_predivs = gpu_predivs, | ||
658 | .n_predivs = ARRAY_SIZE(gpu_predivs), | ||
659 | }, | ||
660 | .common = { | ||
661 | .reg = 0x1a0, | ||
662 | .features = CCU_FEATURE_FIXED_PREDIV, | ||
663 | .hw.init = CLK_HW_INIT_PARENTS("gpu-core", | ||
664 | gpu_parents, | ||
665 | &ccu_div_ops, | ||
666 | 0), | ||
667 | }, | ||
668 | }; | ||
669 | |||
670 | static struct ccu_div gpu_memory_clk = { | ||
671 | .enable = BIT(31), | ||
672 | .div = _SUNXI_CCU_DIV(0, 3), | ||
673 | .mux = { | ||
674 | .shift = 24, | ||
675 | .width = 3, | ||
676 | .fixed_predivs = gpu_predivs, | ||
677 | .n_predivs = ARRAY_SIZE(gpu_predivs), | ||
678 | }, | ||
679 | .common = { | ||
680 | .reg = 0x1a4, | ||
681 | .features = CCU_FEATURE_FIXED_PREDIV, | ||
682 | .hw.init = CLK_HW_INIT_PARENTS("gpu-memory", | ||
683 | gpu_parents, | ||
684 | &ccu_div_ops, | ||
685 | 0), | ||
686 | }, | ||
687 | }; | ||
688 | |||
689 | static struct ccu_div gpu_hyd_clk = { | ||
690 | .enable = BIT(31), | ||
691 | .div = _SUNXI_CCU_DIV(0, 3), | ||
692 | .mux = { | ||
693 | .shift = 24, | ||
694 | .width = 3, | ||
695 | .fixed_predivs = gpu_predivs, | ||
696 | .n_predivs = ARRAY_SIZE(gpu_predivs), | ||
697 | }, | ||
698 | .common = { | ||
699 | .reg = 0x1a8, | ||
700 | .features = CCU_FEATURE_FIXED_PREDIV, | ||
701 | .hw.init = CLK_HW_INIT_PARENTS("gpu-hyd", | ||
702 | gpu_parents, | ||
703 | &ccu_div_ops, | ||
704 | 0), | ||
705 | }, | ||
706 | }; | ||
707 | |||
708 | static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", mod0_default_parents, 0x1b0, | ||
709 | 0, 3, /* M */ | ||
710 | 24, 2, /* mux */ | ||
711 | BIT(31), /* gate */ | ||
712 | 0); | ||
713 | |||
714 | static SUNXI_CCU_M_WITH_MUX_GATE(trace_clk, "trace", mod0_default_parents, | ||
715 | 0x1b0, | ||
716 | 0, 3, /* M */ | ||
717 | 24, 2, /* mux */ | ||
718 | BIT(31), /* gate */ | ||
719 | 0); | ||
720 | |||
721 | static const char * const clk_out_parents[] = { "osc24M", "osc32k", "osc24M", | ||
722 | "axi", "ahb1" }; | ||
723 | static const u8 clk_out_table[] = { 0, 1, 2, 11, 13 }; | ||
724 | |||
725 | static const struct ccu_mux_fixed_prediv clk_out_predivs[] = { | ||
726 | { .index = 0, .div = 750, }, | ||
727 | { .index = 3, .div = 4, }, | ||
728 | { .index = 4, .div = 4, }, | ||
729 | }; | ||
730 | |||
731 | static struct ccu_mp out_a_clk = { | ||
732 | .enable = BIT(31), | ||
733 | .m = _SUNXI_CCU_DIV(8, 5), | ||
734 | .p = _SUNXI_CCU_DIV(20, 2), | ||
735 | .mux = { | ||
736 | .shift = 24, | ||
737 | .width = 4, | ||
738 | .table = clk_out_table, | ||
739 | .fixed_predivs = clk_out_predivs, | ||
740 | .n_predivs = ARRAY_SIZE(clk_out_predivs), | ||
741 | }, | ||
742 | .common = { | ||
743 | .reg = 0x300, | ||
744 | .features = CCU_FEATURE_FIXED_PREDIV, | ||
745 | .hw.init = CLK_HW_INIT_PARENTS("out-a", | ||
746 | clk_out_parents, | ||
747 | &ccu_div_ops, | ||
748 | 0), | ||
749 | }, | ||
750 | }; | ||
751 | |||
752 | static struct ccu_mp out_b_clk = { | ||
753 | .enable = BIT(31), | ||
754 | .m = _SUNXI_CCU_DIV(8, 5), | ||
755 | .p = _SUNXI_CCU_DIV(20, 2), | ||
756 | .mux = { | ||
757 | .shift = 24, | ||
758 | .width = 4, | ||
759 | .table = clk_out_table, | ||
760 | .fixed_predivs = clk_out_predivs, | ||
761 | .n_predivs = ARRAY_SIZE(clk_out_predivs), | ||
762 | }, | ||
763 | .common = { | ||
764 | .reg = 0x304, | ||
765 | .features = CCU_FEATURE_FIXED_PREDIV, | ||
766 | .hw.init = CLK_HW_INIT_PARENTS("out-b", | ||
767 | clk_out_parents, | ||
768 | &ccu_div_ops, | ||
769 | 0), | ||
770 | }, | ||
771 | }; | ||
772 | |||
773 | static struct ccu_mp out_c_clk = { | ||
774 | .enable = BIT(31), | ||
775 | .m = _SUNXI_CCU_DIV(8, 5), | ||
776 | .p = _SUNXI_CCU_DIV(20, 2), | ||
777 | .mux = { | ||
778 | .shift = 24, | ||
779 | .width = 4, | ||
780 | .table = clk_out_table, | ||
781 | .fixed_predivs = clk_out_predivs, | ||
782 | .n_predivs = ARRAY_SIZE(clk_out_predivs), | ||
783 | }, | ||
784 | .common = { | ||
785 | .reg = 0x308, | ||
786 | .features = CCU_FEATURE_FIXED_PREDIV, | ||
787 | .hw.init = CLK_HW_INIT_PARENTS("out-c", | ||
788 | clk_out_parents, | ||
789 | &ccu_div_ops, | ||
790 | 0), | ||
791 | }, | ||
792 | }; | ||
793 | |||
794 | static struct ccu_common *sun6i_a31_ccu_clks[] = { | ||
795 | &pll_cpu_clk.common, | ||
796 | &pll_audio_base_clk.common, | ||
797 | &pll_video0_clk.common, | ||
798 | &pll_ve_clk.common, | ||
799 | &pll_ddr_clk.common, | ||
800 | &pll_periph_clk.common, | ||
801 | &pll_video1_clk.common, | ||
802 | &pll_gpu_clk.common, | ||
803 | &pll_mipi_clk.common, | ||
804 | &pll9_clk.common, | ||
805 | &pll10_clk.common, | ||
806 | &cpu_clk.common, | ||
807 | &axi_clk.common, | ||
808 | &ahb1_clk.common, | ||
809 | &apb1_clk.common, | ||
810 | &apb2_clk.common, | ||
811 | &ahb1_mipidsi_clk.common, | ||
812 | &ahb1_ss_clk.common, | ||
813 | &ahb1_dma_clk.common, | ||
814 | &ahb1_mmc0_clk.common, | ||
815 | &ahb1_mmc1_clk.common, | ||
816 | &ahb1_mmc2_clk.common, | ||
817 | &ahb1_mmc3_clk.common, | ||
818 | &ahb1_nand1_clk.common, | ||
819 | &ahb1_nand0_clk.common, | ||
820 | &ahb1_sdram_clk.common, | ||
821 | &ahb1_emac_clk.common, | ||
822 | &ahb1_ts_clk.common, | ||
823 | &ahb1_hstimer_clk.common, | ||
824 | &ahb1_spi0_clk.common, | ||
825 | &ahb1_spi1_clk.common, | ||
826 | &ahb1_spi2_clk.common, | ||
827 | &ahb1_spi3_clk.common, | ||
828 | &ahb1_otg_clk.common, | ||
829 | &ahb1_ehci0_clk.common, | ||
830 | &ahb1_ehci1_clk.common, | ||
831 | &ahb1_ohci0_clk.common, | ||
832 | &ahb1_ohci1_clk.common, | ||
833 | &ahb1_ohci2_clk.common, | ||
834 | &ahb1_ve_clk.common, | ||
835 | &ahb1_lcd0_clk.common, | ||
836 | &ahb1_lcd1_clk.common, | ||
837 | &ahb1_csi_clk.common, | ||
838 | &ahb1_hdmi_clk.common, | ||
839 | &ahb1_be0_clk.common, | ||
840 | &ahb1_be1_clk.common, | ||
841 | &ahb1_fe0_clk.common, | ||
842 | &ahb1_fe1_clk.common, | ||
843 | &ahb1_mp_clk.common, | ||
844 | &ahb1_gpu_clk.common, | ||
845 | &ahb1_deu0_clk.common, | ||
846 | &ahb1_deu1_clk.common, | ||
847 | &ahb1_drc0_clk.common, | ||
848 | &ahb1_drc1_clk.common, | ||
849 | &apb1_codec_clk.common, | ||
850 | &apb1_spdif_clk.common, | ||
851 | &apb1_digital_mic_clk.common, | ||
852 | &apb1_pio_clk.common, | ||
853 | &apb1_daudio0_clk.common, | ||
854 | &apb1_daudio1_clk.common, | ||
855 | &apb2_i2c0_clk.common, | ||
856 | &apb2_i2c1_clk.common, | ||
857 | &apb2_i2c2_clk.common, | ||
858 | &apb2_i2c3_clk.common, | ||
859 | &apb2_uart0_clk.common, | ||
860 | &apb2_uart1_clk.common, | ||
861 | &apb2_uart2_clk.common, | ||
862 | &apb2_uart3_clk.common, | ||
863 | &apb2_uart4_clk.common, | ||
864 | &apb2_uart5_clk.common, | ||
865 | &nand0_clk.common, | ||
866 | &nand1_clk.common, | ||
867 | &mmc0_clk.common, | ||
868 | &mmc0_sample_clk.common, | ||
869 | &mmc0_output_clk.common, | ||
870 | &mmc1_clk.common, | ||
871 | &mmc1_sample_clk.common, | ||
872 | &mmc1_output_clk.common, | ||
873 | &mmc2_clk.common, | ||
874 | &mmc2_sample_clk.common, | ||
875 | &mmc2_output_clk.common, | ||
876 | &mmc3_clk.common, | ||
877 | &mmc3_sample_clk.common, | ||
878 | &mmc3_output_clk.common, | ||
879 | &ts_clk.common, | ||
880 | &ss_clk.common, | ||
881 | &spi0_clk.common, | ||
882 | &spi1_clk.common, | ||
883 | &spi2_clk.common, | ||
884 | &spi3_clk.common, | ||
885 | &daudio0_clk.common, | ||
886 | &daudio1_clk.common, | ||
887 | &spdif_clk.common, | ||
888 | &usb_phy0_clk.common, | ||
889 | &usb_phy1_clk.common, | ||
890 | &usb_phy2_clk.common, | ||
891 | &usb_ohci0_clk.common, | ||
892 | &usb_ohci1_clk.common, | ||
893 | &usb_ohci2_clk.common, | ||
894 | &mdfs_clk.common, | ||
895 | &sdram0_clk.common, | ||
896 | &sdram1_clk.common, | ||
897 | &dram_ve_clk.common, | ||
898 | &dram_csi_isp_clk.common, | ||
899 | &dram_ts_clk.common, | ||
900 | &dram_drc0_clk.common, | ||
901 | &dram_drc1_clk.common, | ||
902 | &dram_deu0_clk.common, | ||
903 | &dram_deu1_clk.common, | ||
904 | &dram_fe0_clk.common, | ||
905 | &dram_fe1_clk.common, | ||
906 | &dram_be0_clk.common, | ||
907 | &dram_be1_clk.common, | ||
908 | &dram_mp_clk.common, | ||
909 | &be0_clk.common, | ||
910 | &be1_clk.common, | ||
911 | &fe0_clk.common, | ||
912 | &fe1_clk.common, | ||
913 | &mp_clk.common, | ||
914 | &lcd0_ch0_clk.common, | ||
915 | &lcd1_ch0_clk.common, | ||
916 | &lcd0_ch1_clk.common, | ||
917 | &lcd1_ch1_clk.common, | ||
918 | &csi0_sclk_clk.common, | ||
919 | &csi0_mclk_clk.common, | ||
920 | &csi1_mclk_clk.common, | ||
921 | &ve_clk.common, | ||
922 | &codec_clk.common, | ||
923 | &avs_clk.common, | ||
924 | &digital_mic_clk.common, | ||
925 | &hdmi_clk.common, | ||
926 | &hdmi_ddc_clk.common, | ||
927 | &ps_clk.common, | ||
928 | &mbus0_clk.common, | ||
929 | &mbus1_clk.common, | ||
930 | &mipi_dsi_clk.common, | ||
931 | &mipi_dsi_dphy_clk.common, | ||
932 | &mipi_csi_dphy_clk.common, | ||
933 | &iep_drc0_clk.common, | ||
934 | &iep_drc1_clk.common, | ||
935 | &iep_deu0_clk.common, | ||
936 | &iep_deu1_clk.common, | ||
937 | &gpu_core_clk.common, | ||
938 | &gpu_memory_clk.common, | ||
939 | &gpu_hyd_clk.common, | ||
940 | &ats_clk.common, | ||
941 | &trace_clk.common, | ||
942 | &out_a_clk.common, | ||
943 | &out_b_clk.common, | ||
944 | &out_c_clk.common, | ||
945 | }; | ||
946 | |||
947 | /* We hardcode the divider to 4 for now */ | ||
948 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | ||
949 | "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); | ||
950 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | ||
951 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | ||
952 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | ||
953 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | ||
954 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | ||
955 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | ||
956 | static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", | ||
957 | "pll-periph", 1, 2, 0); | ||
958 | static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", | ||
959 | "pll-video0", 1, 2, 0); | ||
960 | static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", | ||
961 | "pll-video1", 1, 2, 0); | ||
962 | |||
963 | static struct clk_hw_onecell_data sun6i_a31_hw_clks = { | ||
964 | .hws = { | ||
965 | [CLK_PLL_CPU] = &pll_cpu_clk.common.hw, | ||
966 | [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, | ||
967 | [CLK_PLL_AUDIO] = &pll_audio_clk.hw, | ||
968 | [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, | ||
969 | [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, | ||
970 | [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, | ||
971 | [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, | ||
972 | [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw, | ||
973 | [CLK_PLL_VE] = &pll_ve_clk.common.hw, | ||
974 | [CLK_PLL_DDR] = &pll_ddr_clk.common.hw, | ||
975 | [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw, | ||
976 | [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw, | ||
977 | [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, | ||
978 | [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw, | ||
979 | [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, | ||
980 | [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw, | ||
981 | [CLK_PLL9] = &pll9_clk.common.hw, | ||
982 | [CLK_PLL10] = &pll10_clk.common.hw, | ||
983 | [CLK_CPU] = &cpu_clk.common.hw, | ||
984 | [CLK_AXI] = &axi_clk.common.hw, | ||
985 | [CLK_AHB1] = &ahb1_clk.common.hw, | ||
986 | [CLK_APB1] = &apb1_clk.common.hw, | ||
987 | [CLK_APB2] = &apb2_clk.common.hw, | ||
988 | [CLK_AHB1_MIPIDSI] = &ahb1_mipidsi_clk.common.hw, | ||
989 | [CLK_AHB1_SS] = &ahb1_ss_clk.common.hw, | ||
990 | [CLK_AHB1_DMA] = &ahb1_dma_clk.common.hw, | ||
991 | [CLK_AHB1_MMC0] = &ahb1_mmc0_clk.common.hw, | ||
992 | [CLK_AHB1_MMC1] = &ahb1_mmc1_clk.common.hw, | ||
993 | [CLK_AHB1_MMC2] = &ahb1_mmc2_clk.common.hw, | ||
994 | [CLK_AHB1_MMC3] = &ahb1_mmc3_clk.common.hw, | ||
995 | [CLK_AHB1_NAND1] = &ahb1_nand1_clk.common.hw, | ||
996 | [CLK_AHB1_NAND0] = &ahb1_nand0_clk.common.hw, | ||
997 | [CLK_AHB1_SDRAM] = &ahb1_sdram_clk.common.hw, | ||
998 | [CLK_AHB1_EMAC] = &ahb1_emac_clk.common.hw, | ||
999 | [CLK_AHB1_TS] = &ahb1_ts_clk.common.hw, | ||
1000 | [CLK_AHB1_HSTIMER] = &ahb1_hstimer_clk.common.hw, | ||
1001 | [CLK_AHB1_SPI0] = &ahb1_spi0_clk.common.hw, | ||
1002 | [CLK_AHB1_SPI1] = &ahb1_spi1_clk.common.hw, | ||
1003 | [CLK_AHB1_SPI2] = &ahb1_spi2_clk.common.hw, | ||
1004 | [CLK_AHB1_SPI3] = &ahb1_spi3_clk.common.hw, | ||
1005 | [CLK_AHB1_OTG] = &ahb1_otg_clk.common.hw, | ||
1006 | [CLK_AHB1_EHCI0] = &ahb1_ehci0_clk.common.hw, | ||
1007 | [CLK_AHB1_EHCI1] = &ahb1_ehci1_clk.common.hw, | ||
1008 | [CLK_AHB1_OHCI0] = &ahb1_ohci0_clk.common.hw, | ||
1009 | [CLK_AHB1_OHCI1] = &ahb1_ohci1_clk.common.hw, | ||
1010 | [CLK_AHB1_OHCI2] = &ahb1_ohci2_clk.common.hw, | ||
1011 | [CLK_AHB1_VE] = &ahb1_ve_clk.common.hw, | ||
1012 | [CLK_AHB1_LCD0] = &ahb1_lcd0_clk.common.hw, | ||
1013 | [CLK_AHB1_LCD1] = &ahb1_lcd1_clk.common.hw, | ||
1014 | [CLK_AHB1_CSI] = &ahb1_csi_clk.common.hw, | ||
1015 | [CLK_AHB1_HDMI] = &ahb1_hdmi_clk.common.hw, | ||
1016 | [CLK_AHB1_BE0] = &ahb1_be0_clk.common.hw, | ||
1017 | [CLK_AHB1_BE1] = &ahb1_be1_clk.common.hw, | ||
1018 | [CLK_AHB1_FE0] = &ahb1_fe0_clk.common.hw, | ||
1019 | [CLK_AHB1_FE1] = &ahb1_fe1_clk.common.hw, | ||
1020 | [CLK_AHB1_MP] = &ahb1_mp_clk.common.hw, | ||
1021 | [CLK_AHB1_GPU] = &ahb1_gpu_clk.common.hw, | ||
1022 | [CLK_AHB1_DEU0] = &ahb1_deu0_clk.common.hw, | ||
1023 | [CLK_AHB1_DEU1] = &ahb1_deu1_clk.common.hw, | ||
1024 | [CLK_AHB1_DRC0] = &ahb1_drc0_clk.common.hw, | ||
1025 | [CLK_AHB1_DRC1] = &ahb1_drc1_clk.common.hw, | ||
1026 | [CLK_APB1_CODEC] = &apb1_codec_clk.common.hw, | ||
1027 | [CLK_APB1_SPDIF] = &apb1_spdif_clk.common.hw, | ||
1028 | [CLK_APB1_DIGITAL_MIC] = &apb1_digital_mic_clk.common.hw, | ||
1029 | [CLK_APB1_PIO] = &apb1_pio_clk.common.hw, | ||
1030 | [CLK_APB1_DAUDIO0] = &apb1_daudio0_clk.common.hw, | ||
1031 | [CLK_APB1_DAUDIO1] = &apb1_daudio1_clk.common.hw, | ||
1032 | [CLK_APB2_I2C0] = &apb2_i2c0_clk.common.hw, | ||
1033 | [CLK_APB2_I2C1] = &apb2_i2c1_clk.common.hw, | ||
1034 | [CLK_APB2_I2C2] = &apb2_i2c2_clk.common.hw, | ||
1035 | [CLK_APB2_I2C3] = &apb2_i2c3_clk.common.hw, | ||
1036 | [CLK_APB2_UART0] = &apb2_uart0_clk.common.hw, | ||
1037 | [CLK_APB2_UART1] = &apb2_uart1_clk.common.hw, | ||
1038 | [CLK_APB2_UART2] = &apb2_uart2_clk.common.hw, | ||
1039 | [CLK_APB2_UART3] = &apb2_uart3_clk.common.hw, | ||
1040 | [CLK_APB2_UART4] = &apb2_uart4_clk.common.hw, | ||
1041 | [CLK_APB2_UART5] = &apb2_uart5_clk.common.hw, | ||
1042 | [CLK_NAND0] = &nand0_clk.common.hw, | ||
1043 | [CLK_NAND1] = &nand1_clk.common.hw, | ||
1044 | [CLK_MMC0] = &mmc0_clk.common.hw, | ||
1045 | [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw, | ||
1046 | [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw, | ||
1047 | [CLK_MMC1] = &mmc1_clk.common.hw, | ||
1048 | [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw, | ||
1049 | [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw, | ||
1050 | [CLK_MMC2] = &mmc2_clk.common.hw, | ||
1051 | [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw, | ||
1052 | [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw, | ||
1053 | [CLK_MMC3] = &mmc3_clk.common.hw, | ||
1054 | [CLK_MMC3_SAMPLE] = &mmc3_sample_clk.common.hw, | ||
1055 | [CLK_MMC3_OUTPUT] = &mmc3_output_clk.common.hw, | ||
1056 | [CLK_TS] = &ts_clk.common.hw, | ||
1057 | [CLK_SS] = &ss_clk.common.hw, | ||
1058 | [CLK_SPI0] = &spi0_clk.common.hw, | ||
1059 | [CLK_SPI1] = &spi1_clk.common.hw, | ||
1060 | [CLK_SPI2] = &spi2_clk.common.hw, | ||
1061 | [CLK_SPI3] = &spi3_clk.common.hw, | ||
1062 | [CLK_DAUDIO0] = &daudio0_clk.common.hw, | ||
1063 | [CLK_DAUDIO1] = &daudio1_clk.common.hw, | ||
1064 | [CLK_SPDIF] = &spdif_clk.common.hw, | ||
1065 | [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, | ||
1066 | [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, | ||
1067 | [CLK_USB_PHY2] = &usb_phy2_clk.common.hw, | ||
1068 | [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, | ||
1069 | [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, | ||
1070 | [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw, | ||
1071 | [CLK_MDFS] = &mdfs_clk.common.hw, | ||
1072 | [CLK_SDRAM0] = &sdram0_clk.common.hw, | ||
1073 | [CLK_SDRAM1] = &sdram1_clk.common.hw, | ||
1074 | [CLK_DRAM_VE] = &dram_ve_clk.common.hw, | ||
1075 | [CLK_DRAM_CSI_ISP] = &dram_csi_isp_clk.common.hw, | ||
1076 | [CLK_DRAM_TS] = &dram_ts_clk.common.hw, | ||
1077 | [CLK_DRAM_DRC0] = &dram_drc0_clk.common.hw, | ||
1078 | [CLK_DRAM_DRC1] = &dram_drc1_clk.common.hw, | ||
1079 | [CLK_DRAM_DEU0] = &dram_deu0_clk.common.hw, | ||
1080 | [CLK_DRAM_DEU1] = &dram_deu1_clk.common.hw, | ||
1081 | [CLK_DRAM_FE0] = &dram_fe0_clk.common.hw, | ||
1082 | [CLK_DRAM_FE1] = &dram_fe1_clk.common.hw, | ||
1083 | [CLK_DRAM_BE0] = &dram_be0_clk.common.hw, | ||
1084 | [CLK_DRAM_BE1] = &dram_be1_clk.common.hw, | ||
1085 | [CLK_DRAM_MP] = &dram_mp_clk.common.hw, | ||
1086 | [CLK_BE0] = &be0_clk.common.hw, | ||
1087 | [CLK_BE1] = &be1_clk.common.hw, | ||
1088 | [CLK_FE0] = &fe0_clk.common.hw, | ||
1089 | [CLK_FE1] = &fe1_clk.common.hw, | ||
1090 | [CLK_MP] = &mp_clk.common.hw, | ||
1091 | [CLK_LCD0_CH0] = &lcd0_ch0_clk.common.hw, | ||
1092 | [CLK_LCD1_CH0] = &lcd1_ch0_clk.common.hw, | ||
1093 | [CLK_LCD0_CH1] = &lcd0_ch1_clk.common.hw, | ||
1094 | [CLK_LCD1_CH1] = &lcd1_ch1_clk.common.hw, | ||
1095 | [CLK_CSI0_SCLK] = &csi0_sclk_clk.common.hw, | ||
1096 | [CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw, | ||
1097 | [CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw, | ||
1098 | [CLK_VE] = &ve_clk.common.hw, | ||
1099 | [CLK_CODEC] = &codec_clk.common.hw, | ||
1100 | [CLK_AVS] = &avs_clk.common.hw, | ||
1101 | [CLK_DIGITAL_MIC] = &digital_mic_clk.common.hw, | ||
1102 | [CLK_HDMI] = &hdmi_clk.common.hw, | ||
1103 | [CLK_HDMI_DDC] = &hdmi_ddc_clk.common.hw, | ||
1104 | [CLK_PS] = &ps_clk.common.hw, | ||
1105 | [CLK_MBUS0] = &mbus0_clk.common.hw, | ||
1106 | [CLK_MBUS1] = &mbus1_clk.common.hw, | ||
1107 | [CLK_MIPI_DSI] = &mipi_dsi_clk.common.hw, | ||
1108 | [CLK_MIPI_DSI_DPHY] = &mipi_dsi_dphy_clk.common.hw, | ||
1109 | [CLK_MIPI_CSI_DPHY] = &mipi_csi_dphy_clk.common.hw, | ||
1110 | [CLK_IEP_DRC0] = &iep_drc0_clk.common.hw, | ||
1111 | [CLK_IEP_DRC1] = &iep_drc1_clk.common.hw, | ||
1112 | [CLK_IEP_DEU0] = &iep_deu0_clk.common.hw, | ||
1113 | [CLK_IEP_DEU1] = &iep_deu1_clk.common.hw, | ||
1114 | [CLK_GPU_CORE] = &gpu_core_clk.common.hw, | ||
1115 | [CLK_GPU_MEMORY] = &gpu_memory_clk.common.hw, | ||
1116 | [CLK_GPU_HYD] = &gpu_hyd_clk.common.hw, | ||
1117 | [CLK_ATS] = &ats_clk.common.hw, | ||
1118 | [CLK_TRACE] = &trace_clk.common.hw, | ||
1119 | [CLK_OUT_A] = &out_a_clk.common.hw, | ||
1120 | [CLK_OUT_B] = &out_b_clk.common.hw, | ||
1121 | [CLK_OUT_C] = &out_c_clk.common.hw, | ||
1122 | }, | ||
1123 | .num = CLK_NUMBER, | ||
1124 | }; | ||
1125 | |||
1126 | static struct ccu_reset_map sun6i_a31_ccu_resets[] = { | ||
1127 | [RST_USB_PHY0] = { 0x0cc, BIT(0) }, | ||
1128 | [RST_USB_PHY1] = { 0x0cc, BIT(1) }, | ||
1129 | [RST_USB_PHY2] = { 0x0cc, BIT(2) }, | ||
1130 | |||
1131 | [RST_AHB1_MIPI_DSI] = { 0x2c0, BIT(1) }, | ||
1132 | [RST_AHB1_SS] = { 0x2c0, BIT(5) }, | ||
1133 | [RST_AHB1_DMA] = { 0x2c0, BIT(6) }, | ||
1134 | [RST_AHB1_MMC0] = { 0x2c0, BIT(8) }, | ||
1135 | [RST_AHB1_MMC1] = { 0x2c0, BIT(9) }, | ||
1136 | [RST_AHB1_MMC2] = { 0x2c0, BIT(10) }, | ||
1137 | [RST_AHB1_MMC3] = { 0x2c0, BIT(11) }, | ||
1138 | [RST_AHB1_NAND1] = { 0x2c0, BIT(12) }, | ||
1139 | [RST_AHB1_NAND0] = { 0x2c0, BIT(13) }, | ||
1140 | [RST_AHB1_SDRAM] = { 0x2c0, BIT(14) }, | ||
1141 | [RST_AHB1_EMAC] = { 0x2c0, BIT(17) }, | ||
1142 | [RST_AHB1_TS] = { 0x2c0, BIT(18) }, | ||
1143 | [RST_AHB1_HSTIMER] = { 0x2c0, BIT(19) }, | ||
1144 | [RST_AHB1_SPI0] = { 0x2c0, BIT(20) }, | ||
1145 | [RST_AHB1_SPI1] = { 0x2c0, BIT(21) }, | ||
1146 | [RST_AHB1_SPI2] = { 0x2c0, BIT(22) }, | ||
1147 | [RST_AHB1_SPI3] = { 0x2c0, BIT(23) }, | ||
1148 | [RST_AHB1_OTG] = { 0x2c0, BIT(24) }, | ||
1149 | [RST_AHB1_EHCI0] = { 0x2c0, BIT(26) }, | ||
1150 | [RST_AHB1_EHCI1] = { 0x2c0, BIT(27) }, | ||
1151 | [RST_AHB1_OHCI0] = { 0x2c0, BIT(29) }, | ||
1152 | [RST_AHB1_OHCI1] = { 0x2c0, BIT(30) }, | ||
1153 | [RST_AHB1_OHCI2] = { 0x2c0, BIT(31) }, | ||
1154 | |||
1155 | [RST_AHB1_VE] = { 0x2c4, BIT(0) }, | ||
1156 | [RST_AHB1_LCD0] = { 0x2c4, BIT(4) }, | ||
1157 | [RST_AHB1_LCD1] = { 0x2c4, BIT(5) }, | ||
1158 | [RST_AHB1_CSI] = { 0x2c4, BIT(8) }, | ||
1159 | [RST_AHB1_HDMI] = { 0x2c4, BIT(11) }, | ||
1160 | [RST_AHB1_BE0] = { 0x2c4, BIT(12) }, | ||
1161 | [RST_AHB1_BE1] = { 0x2c4, BIT(13) }, | ||
1162 | [RST_AHB1_FE0] = { 0x2c4, BIT(14) }, | ||
1163 | [RST_AHB1_FE1] = { 0x2c4, BIT(15) }, | ||
1164 | [RST_AHB1_MP] = { 0x2c4, BIT(18) }, | ||
1165 | [RST_AHB1_GPU] = { 0x2c4, BIT(20) }, | ||
1166 | [RST_AHB1_DEU0] = { 0x2c4, BIT(23) }, | ||
1167 | [RST_AHB1_DEU1] = { 0x2c4, BIT(24) }, | ||
1168 | [RST_AHB1_DRC0] = { 0x2c4, BIT(25) }, | ||
1169 | [RST_AHB1_DRC1] = { 0x2c4, BIT(26) }, | ||
1170 | [RST_AHB1_LVDS] = { 0x2c8, BIT(0) }, | ||
1171 | |||
1172 | [RST_APB1_CODEC] = { 0x2d0, BIT(0) }, | ||
1173 | [RST_APB1_SPDIF] = { 0x2d0, BIT(1) }, | ||
1174 | [RST_APB1_DIGITAL_MIC] = { 0x2d0, BIT(4) }, | ||
1175 | [RST_APB1_DAUDIO0] = { 0x2d0, BIT(12) }, | ||
1176 | [RST_APB1_DAUDIO1] = { 0x2d0, BIT(13) }, | ||
1177 | |||
1178 | [RST_APB2_I2C0] = { 0x2d8, BIT(0) }, | ||
1179 | [RST_APB2_I2C1] = { 0x2d8, BIT(1) }, | ||
1180 | [RST_APB2_I2C2] = { 0x2d8, BIT(2) }, | ||
1181 | [RST_APB2_I2C3] = { 0x2d8, BIT(3) }, | ||
1182 | [RST_APB2_UART0] = { 0x2d8, BIT(16) }, | ||
1183 | [RST_APB2_UART1] = { 0x2d8, BIT(17) }, | ||
1184 | [RST_APB2_UART2] = { 0x2d8, BIT(18) }, | ||
1185 | [RST_APB2_UART3] = { 0x2d8, BIT(19) }, | ||
1186 | [RST_APB2_UART4] = { 0x2d8, BIT(20) }, | ||
1187 | [RST_APB2_UART5] = { 0x2d8, BIT(21) }, | ||
1188 | }; | ||
1189 | |||
1190 | static const struct sunxi_ccu_desc sun6i_a31_ccu_desc = { | ||
1191 | .ccu_clks = sun6i_a31_ccu_clks, | ||
1192 | .num_ccu_clks = ARRAY_SIZE(sun6i_a31_ccu_clks), | ||
1193 | |||
1194 | .hw_clks = &sun6i_a31_hw_clks, | ||
1195 | |||
1196 | .resets = sun6i_a31_ccu_resets, | ||
1197 | .num_resets = ARRAY_SIZE(sun6i_a31_ccu_resets), | ||
1198 | }; | ||
1199 | |||
1200 | static struct ccu_mux_nb sun6i_a31_cpu_nb = { | ||
1201 | .common = &cpu_clk.common, | ||
1202 | .cm = &cpu_clk.mux, | ||
1203 | .delay_us = 1, /* > 8 clock cycles at 24 MHz */ | ||
1204 | .bypass_index = 1, /* index of 24 MHz oscillator */ | ||
1205 | }; | ||
1206 | |||
1207 | static void __init sun6i_a31_ccu_setup(struct device_node *node) | ||
1208 | { | ||
1209 | void __iomem *reg; | ||
1210 | u32 val; | ||
1211 | |||
1212 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | ||
1213 | if (IS_ERR(reg)) { | ||
1214 | pr_err("%s: Could not map the clock registers\n", | ||
1215 | of_node_full_name(node)); | ||
1216 | return; | ||
1217 | } | ||
1218 | |||
1219 | /* Force the PLL-Audio-1x divider to 4 */ | ||
1220 | val = readl(reg + SUN6I_A31_PLL_AUDIO_REG); | ||
1221 | val &= ~GENMASK(19, 16); | ||
1222 | writel(val | (3 << 16), reg + SUN6I_A31_PLL_AUDIO_REG); | ||
1223 | |||
1224 | /* Force PLL-MIPI to MIPI mode */ | ||
1225 | val = readl(reg + SUN6I_A31_PLL_MIPI_REG); | ||
1226 | val &= BIT(16); | ||
1227 | writel(val, reg + SUN6I_A31_PLL_MIPI_REG); | ||
1228 | |||
1229 | sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc); | ||
1230 | |||
1231 | ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk, | ||
1232 | &sun6i_a31_cpu_nb); | ||
1233 | } | ||
1234 | CLK_OF_DECLARE(sun6i_a31_ccu, "allwinner,sun6i-a31-ccu", | ||
1235 | sun6i_a31_ccu_setup); | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.h b/drivers/clk/sunxi-ng/ccu-sun6i-a31.h new file mode 100644 index 000000000000..4e434011e9e7 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * Copyright 2016 Chen-Yu Tsai | ||
3 | * | ||
4 | * Chen-Yu Tsai <wens@csie.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #ifndef _CCU_SUN6I_A31_H_ | ||
18 | #define _CCU_SUN6I_A31_H_ | ||
19 | |||
20 | #include <dt-bindings/clock/sun6i-a31-ccu.h> | ||
21 | #include <dt-bindings/reset/sun6i-a31-ccu.h> | ||
22 | |||
23 | #define CLK_PLL_CPU 0 | ||
24 | #define CLK_PLL_AUDIO_BASE 1 | ||
25 | #define CLK_PLL_AUDIO 2 | ||
26 | #define CLK_PLL_AUDIO_2X 3 | ||
27 | #define CLK_PLL_AUDIO_4X 4 | ||
28 | #define CLK_PLL_AUDIO_8X 5 | ||
29 | #define CLK_PLL_VIDEO0 6 | ||
30 | #define CLK_PLL_VIDEO0_2X 7 | ||
31 | #define CLK_PLL_VE 8 | ||
32 | #define CLK_PLL_DDR 9 | ||
33 | |||
34 | /* The PLL_PERIPH clock is exported */ | ||
35 | |||
36 | #define CLK_PLL_PERIPH_2X 11 | ||
37 | #define CLK_PLL_VIDEO1 12 | ||
38 | #define CLK_PLL_VIDEO1_2X 13 | ||
39 | #define CLK_PLL_GPU 14 | ||
40 | #define CLK_PLL_MIPI 15 | ||
41 | #define CLK_PLL9 16 | ||
42 | #define CLK_PLL10 17 | ||
43 | |||
44 | /* The CPUX clock is exported */ | ||
45 | |||
46 | #define CLK_AXI 19 | ||
47 | #define CLK_AHB1 20 | ||
48 | #define CLK_APB1 21 | ||
49 | #define CLK_APB2 22 | ||
50 | |||
51 | /* All the bus gates are exported */ | ||
52 | |||
53 | /* The first bunch of module clocks are exported */ | ||
54 | |||
55 | /* EMAC clock is not implemented */ | ||
56 | |||
57 | #define CLK_MDFS 107 | ||
58 | #define CLK_SDRAM0 108 | ||
59 | #define CLK_SDRAM1 109 | ||
60 | |||
61 | /* All the DRAM gates are exported */ | ||
62 | |||
63 | /* Some more module clocks are exported */ | ||
64 | |||
65 | #define CLK_MBUS0 141 | ||
66 | #define CLK_MBUS1 142 | ||
67 | |||
68 | /* Some more module clocks and external clock outputs are exported */ | ||
69 | |||
70 | #define CLK_NUMBER (CLK_OUT_C + 1) | ||
71 | |||
72 | #endif /* _CCU_SUN6I_A31_H_ */ | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h b/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h new file mode 100644 index 000000000000..62c0f8d49ef8 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Copyright 2016 Maxime Ripard | ||
3 | * | ||
4 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #ifndef _CCU_SUN8I_A23_A33_H_ | ||
18 | #define _CCU_SUN8I_A23_A33_H_ | ||
19 | |||
20 | #include <dt-bindings/clock/sun8i-a23-a33-ccu.h> | ||
21 | #include <dt-bindings/reset/sun8i-a23-a33-ccu.h> | ||
22 | |||
23 | #define CLK_PLL_CPUX 0 | ||
24 | #define CLK_PLL_AUDIO_BASE 1 | ||
25 | #define CLK_PLL_AUDIO 2 | ||
26 | #define CLK_PLL_AUDIO_2X 3 | ||
27 | #define CLK_PLL_AUDIO_4X 4 | ||
28 | #define CLK_PLL_AUDIO_8X 5 | ||
29 | #define CLK_PLL_VIDEO 6 | ||
30 | #define CLK_PLL_VIDEO_2X 7 | ||
31 | #define CLK_PLL_VE 8 | ||
32 | #define CLK_PLL_DDR0 9 | ||
33 | #define CLK_PLL_PERIPH 10 | ||
34 | #define CLK_PLL_PERIPH_2X 11 | ||
35 | #define CLK_PLL_GPU 12 | ||
36 | #define CLK_PLL_MIPI 13 | ||
37 | #define CLK_PLL_HSIC 14 | ||
38 | #define CLK_PLL_DE 15 | ||
39 | #define CLK_PLL_DDR1 16 | ||
40 | #define CLK_PLL_DDR 17 | ||
41 | |||
42 | /* The CPUX clock is exported */ | ||
43 | |||
44 | #define CLK_AXI 19 | ||
45 | #define CLK_AHB1 20 | ||
46 | #define CLK_APB1 21 | ||
47 | #define CLK_APB2 22 | ||
48 | |||
49 | /* All the bus gates are exported */ | ||
50 | |||
51 | /* The first part of the mod clocks is exported */ | ||
52 | |||
53 | #define CLK_DRAM 79 | ||
54 | |||
55 | /* Some more module clocks are exported */ | ||
56 | |||
57 | #define CLK_MBUS 95 | ||
58 | |||
59 | /* And the last module clocks are exported */ | ||
60 | |||
61 | #define CLK_NUMBER (CLK_ATS + 1) | ||
62 | |||
63 | #endif /* _CCU_SUN8I_A23_A33_H_ */ | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c new file mode 100644 index 000000000000..11e624ab28b1 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c | |||
@@ -0,0 +1,737 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016 Maxime Ripard. All rights reserved. | ||
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/clk-provider.h> | ||
15 | #include <linux/of_address.h> | ||
16 | |||
17 | #include "ccu_common.h" | ||
18 | #include "ccu_reset.h" | ||
19 | |||
20 | #include "ccu_div.h" | ||
21 | #include "ccu_gate.h" | ||
22 | #include "ccu_mp.h" | ||
23 | #include "ccu_mult.h" | ||
24 | #include "ccu_nk.h" | ||
25 | #include "ccu_nkm.h" | ||
26 | #include "ccu_nkmp.h" | ||
27 | #include "ccu_nm.h" | ||
28 | #include "ccu_phase.h" | ||
29 | |||
30 | #include "ccu-sun8i-a23-a33.h" | ||
31 | |||
32 | |||
33 | static struct ccu_nkmp pll_cpux_clk = { | ||
34 | .enable = BIT(31), | ||
35 | .lock = BIT(28), | ||
36 | |||
37 | .n = _SUNXI_CCU_MULT(8, 5), | ||
38 | .k = _SUNXI_CCU_MULT(4, 2), | ||
39 | .m = _SUNXI_CCU_DIV(0, 2), | ||
40 | .p = _SUNXI_CCU_DIV_MAX(16, 2, 4), | ||
41 | |||
42 | .common = { | ||
43 | .reg = 0x000, | ||
44 | .hw.init = CLK_HW_INIT("pll-cpux", "osc24M", | ||
45 | &ccu_nkmp_ops, | ||
46 | 0), | ||
47 | }, | ||
48 | }; | ||
49 | |||
50 | /* | ||
51 | * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from | ||
52 | * the base (2x, 4x and 8x), and one variable divider (the one true | ||
53 | * pll audio). | ||
54 | * | ||
55 | * We don't have any need for the variable divider for now, so we just | ||
56 | * hardcode it to match with the clock names | ||
57 | */ | ||
58 | #define SUN8I_A23_PLL_AUDIO_REG 0x008 | ||
59 | |||
60 | static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", | ||
61 | "osc24M", 0x008, | ||
62 | 8, 7, /* N */ | ||
63 | 0, 5, /* M */ | ||
64 | BIT(31), /* gate */ | ||
65 | BIT(28), /* lock */ | ||
66 | CLK_SET_RATE_UNGATE); | ||
67 | |||
68 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video", | ||
69 | "osc24M", 0x010, | ||
70 | 8, 7, /* N */ | ||
71 | 0, 4, /* M */ | ||
72 | BIT(24), /* frac enable */ | ||
73 | BIT(25), /* frac select */ | ||
74 | 270000000, /* frac rate 0 */ | ||
75 | 297000000, /* frac rate 1 */ | ||
76 | BIT(31), /* gate */ | ||
77 | BIT(28), /* lock */ | ||
78 | CLK_SET_RATE_UNGATE); | ||
79 | |||
80 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", | ||
81 | "osc24M", 0x018, | ||
82 | 8, 7, /* N */ | ||
83 | 0, 4, /* M */ | ||
84 | BIT(24), /* frac enable */ | ||
85 | BIT(25), /* frac select */ | ||
86 | 270000000, /* frac rate 0 */ | ||
87 | 297000000, /* frac rate 1 */ | ||
88 | BIT(31), /* gate */ | ||
89 | BIT(28), /* lock */ | ||
90 | CLK_SET_RATE_UNGATE); | ||
91 | |||
92 | static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr", | ||
93 | "osc24M", 0x020, | ||
94 | 8, 5, /* N */ | ||
95 | 4, 2, /* K */ | ||
96 | 0, 2, /* M */ | ||
97 | BIT(31), /* gate */ | ||
98 | BIT(28), /* lock */ | ||
99 | 0); | ||
100 | |||
101 | static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph", | ||
102 | "osc24M", 0x028, | ||
103 | 8, 5, /* N */ | ||
104 | 4, 2, /* K */ | ||
105 | BIT(31), /* gate */ | ||
106 | BIT(28), /* lock */ | ||
107 | 2, /* post-div */ | ||
108 | CLK_SET_RATE_UNGATE); | ||
109 | |||
110 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", | ||
111 | "osc24M", 0x038, | ||
112 | 8, 7, /* N */ | ||
113 | 0, 4, /* M */ | ||
114 | BIT(24), /* frac enable */ | ||
115 | BIT(25), /* frac select */ | ||
116 | 270000000, /* frac rate 0 */ | ||
117 | 297000000, /* frac rate 1 */ | ||
118 | BIT(31), /* gate */ | ||
119 | BIT(28), /* lock */ | ||
120 | CLK_SET_RATE_UNGATE); | ||
121 | |||
122 | /* | ||
123 | * The MIPI PLL has 2 modes: "MIPI" and "HDMI". | ||
124 | * | ||
125 | * The MIPI mode is a standard NKM-style clock. The HDMI mode is an | ||
126 | * integer / fractional clock with switchable multipliers and dividers. | ||
127 | * This is not supported here. We hardcode the PLL to MIPI mode. | ||
128 | */ | ||
129 | #define SUN8I_A23_PLL_MIPI_REG 0x040 | ||
130 | static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_mipi_clk, "pll-mipi", | ||
131 | "pll-video", 0x040, | ||
132 | 8, 4, /* N */ | ||
133 | 4, 2, /* K */ | ||
134 | 0, 4, /* M */ | ||
135 | BIT(31), /* gate */ | ||
136 | BIT(28), /* lock */ | ||
137 | CLK_SET_RATE_UNGATE); | ||
138 | |||
139 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_hsic_clk, "pll-hsic", | ||
140 | "osc24M", 0x044, | ||
141 | 8, 7, /* N */ | ||
142 | 0, 4, /* M */ | ||
143 | BIT(24), /* frac enable */ | ||
144 | BIT(25), /* frac select */ | ||
145 | 270000000, /* frac rate 0 */ | ||
146 | 297000000, /* frac rate 1 */ | ||
147 | BIT(31), /* gate */ | ||
148 | BIT(28), /* lock */ | ||
149 | CLK_SET_RATE_UNGATE); | ||
150 | |||
151 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de", | ||
152 | "osc24M", 0x048, | ||
153 | 8, 7, /* N */ | ||
154 | 0, 4, /* M */ | ||
155 | BIT(24), /* frac enable */ | ||
156 | BIT(25), /* frac select */ | ||
157 | 270000000, /* frac rate 0 */ | ||
158 | 297000000, /* frac rate 1 */ | ||
159 | BIT(31), /* gate */ | ||
160 | BIT(28), /* lock */ | ||
161 | CLK_SET_RATE_UNGATE); | ||
162 | |||
163 | static const char * const cpux_parents[] = { "osc32k", "osc24M", | ||
164 | "pll-cpux" , "pll-cpux" }; | ||
165 | static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents, | ||
166 | 0x050, 16, 2, CLK_IS_CRITICAL); | ||
167 | |||
168 | static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); | ||
169 | |||
170 | static const char * const ahb1_parents[] = { "osc32k", "osc24M", | ||
171 | "axi" , "pll-periph" }; | ||
172 | static struct ccu_div ahb1_clk = { | ||
173 | .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), | ||
174 | |||
175 | .mux = { | ||
176 | .shift = 12, | ||
177 | .width = 2, | ||
178 | |||
179 | .variable_prediv = { | ||
180 | .index = 3, | ||
181 | .shift = 6, | ||
182 | .width = 2, | ||
183 | }, | ||
184 | }, | ||
185 | |||
186 | .common = { | ||
187 | .reg = 0x054, | ||
188 | .features = CCU_FEATURE_VARIABLE_PREDIV, | ||
189 | .hw.init = CLK_HW_INIT_PARENTS("ahb1", | ||
190 | ahb1_parents, | ||
191 | &ccu_div_ops, | ||
192 | 0), | ||
193 | }, | ||
194 | }; | ||
195 | |||
196 | static struct clk_div_table apb1_div_table[] = { | ||
197 | { .val = 0, .div = 2 }, | ||
198 | { .val = 1, .div = 2 }, | ||
199 | { .val = 2, .div = 4 }, | ||
200 | { .val = 3, .div = 8 }, | ||
201 | { /* Sentinel */ }, | ||
202 | }; | ||
203 | static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1", | ||
204 | 0x054, 8, 2, apb1_div_table, 0); | ||
205 | |||
206 | static const char * const apb2_parents[] = { "osc32k", "osc24M", | ||
207 | "pll-periph" , "pll-periph" }; | ||
208 | static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058, | ||
209 | 0, 5, /* M */ | ||
210 | 16, 2, /* P */ | ||
211 | 24, 2, /* mux */ | ||
212 | 0); | ||
213 | |||
214 | static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1", | ||
215 | 0x060, BIT(1), 0); | ||
216 | static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1", | ||
217 | 0x060, BIT(6), 0); | ||
218 | static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1", | ||
219 | 0x060, BIT(8), 0); | ||
220 | static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1", | ||
221 | 0x060, BIT(9), 0); | ||
222 | static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1", | ||
223 | 0x060, BIT(10), 0); | ||
224 | static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1", | ||
225 | 0x060, BIT(13), 0); | ||
226 | static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1", | ||
227 | 0x060, BIT(14), 0); | ||
228 | static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1", | ||
229 | 0x060, BIT(19), 0); | ||
230 | static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1", | ||
231 | 0x060, BIT(20), 0); | ||
232 | static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1", | ||
233 | 0x060, BIT(21), 0); | ||
234 | static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1", | ||
235 | 0x060, BIT(24), 0); | ||
236 | static SUNXI_CCU_GATE(bus_ehci_clk, "bus-ehci", "ahb1", | ||
237 | 0x060, BIT(26), 0); | ||
238 | static SUNXI_CCU_GATE(bus_ohci_clk, "bus-ohci", "ahb1", | ||
239 | 0x060, BIT(29), 0); | ||
240 | |||
241 | static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1", | ||
242 | 0x064, BIT(0), 0); | ||
243 | static SUNXI_CCU_GATE(bus_lcd_clk, "bus-lcd", "ahb1", | ||
244 | 0x064, BIT(4), 0); | ||
245 | static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1", | ||
246 | 0x064, BIT(8), 0); | ||
247 | static SUNXI_CCU_GATE(bus_de_be_clk, "bus-de-be", "ahb1", | ||
248 | 0x064, BIT(12), 0); | ||
249 | static SUNXI_CCU_GATE(bus_de_fe_clk, "bus-de-fe", "ahb1", | ||
250 | 0x064, BIT(14), 0); | ||
251 | static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1", | ||
252 | 0x064, BIT(20), 0); | ||
253 | static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1", | ||
254 | 0x064, BIT(21), 0); | ||
255 | static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1", | ||
256 | 0x064, BIT(22), 0); | ||
257 | static SUNXI_CCU_GATE(bus_drc_clk, "bus-drc", "ahb1", | ||
258 | 0x064, BIT(25), 0); | ||
259 | |||
260 | static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1", | ||
261 | 0x068, BIT(0), 0); | ||
262 | static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1", | ||
263 | 0x068, BIT(5), 0); | ||
264 | static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", | ||
265 | 0x068, BIT(12), 0); | ||
266 | static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", | ||
267 | 0x068, BIT(13), 0); | ||
268 | |||
269 | static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", | ||
270 | 0x06c, BIT(0), 0); | ||
271 | static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", | ||
272 | 0x06c, BIT(1), 0); | ||
273 | static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", | ||
274 | 0x06c, BIT(2), 0); | ||
275 | static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", | ||
276 | 0x06c, BIT(16), 0); | ||
277 | static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", | ||
278 | 0x06c, BIT(17), 0); | ||
279 | static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", | ||
280 | 0x06c, BIT(18), 0); | ||
281 | static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", | ||
282 | 0x06c, BIT(19), 0); | ||
283 | static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2", | ||
284 | 0x06c, BIT(20), 0); | ||
285 | |||
286 | static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" }; | ||
287 | static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080, | ||
288 | 0, 4, /* M */ | ||
289 | 16, 2, /* P */ | ||
290 | 24, 2, /* mux */ | ||
291 | BIT(31), /* gate */ | ||
292 | 0); | ||
293 | |||
294 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088, | ||
295 | 0, 4, /* M */ | ||
296 | 16, 2, /* P */ | ||
297 | 24, 2, /* mux */ | ||
298 | BIT(31), /* gate */ | ||
299 | 0); | ||
300 | |||
301 | static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0", | ||
302 | 0x088, 20, 3, 0); | ||
303 | static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0", | ||
304 | 0x088, 8, 3, 0); | ||
305 | |||
306 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c, | ||
307 | 0, 4, /* M */ | ||
308 | 16, 2, /* P */ | ||
309 | 24, 2, /* mux */ | ||
310 | BIT(31), /* gate */ | ||
311 | 0); | ||
312 | |||
313 | static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1", | ||
314 | 0x08c, 20, 3, 0); | ||
315 | static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1", | ||
316 | 0x08c, 8, 3, 0); | ||
317 | |||
318 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090, | ||
319 | 0, 4, /* M */ | ||
320 | 16, 2, /* P */ | ||
321 | 24, 2, /* mux */ | ||
322 | BIT(31), /* gate */ | ||
323 | 0); | ||
324 | |||
325 | static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2", | ||
326 | 0x090, 20, 3, 0); | ||
327 | static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2", | ||
328 | 0x090, 8, 3, 0); | ||
329 | |||
330 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0, | ||
331 | 0, 4, /* M */ | ||
332 | 16, 2, /* P */ | ||
333 | 24, 2, /* mux */ | ||
334 | BIT(31), /* gate */ | ||
335 | 0); | ||
336 | |||
337 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4, | ||
338 | 0, 4, /* M */ | ||
339 | 16, 2, /* P */ | ||
340 | 24, 2, /* mux */ | ||
341 | BIT(31), /* gate */ | ||
342 | 0); | ||
343 | |||
344 | static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x", | ||
345 | "pll-audio-2x", "pll-audio" }; | ||
346 | static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents, | ||
347 | 0x0b0, 16, 2, BIT(31), 0); | ||
348 | |||
349 | static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents, | ||
350 | 0x0b4, 16, 2, BIT(31), 0); | ||
351 | |||
352 | /* TODO: the parent for most of the USB clocks is not known */ | ||
353 | static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", | ||
354 | 0x0cc, BIT(8), 0); | ||
355 | static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", | ||
356 | 0x0cc, BIT(9), 0); | ||
357 | static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic", | ||
358 | 0x0cc, BIT(10), 0); | ||
359 | static SUNXI_CCU_GATE(usb_hsic_12M_clk, "usb-hsic-12M", "osc24M", | ||
360 | 0x0cc, BIT(11), 0); | ||
361 | static SUNXI_CCU_GATE(usb_ohci_clk, "usb-ohci", "osc24M", | ||
362 | 0x0cc, BIT(16), 0); | ||
363 | |||
364 | static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr", | ||
365 | 0x100, BIT(0), 0); | ||
366 | static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "pll-ddr", | ||
367 | 0x100, BIT(1), 0); | ||
368 | static SUNXI_CCU_GATE(dram_drc_clk, "dram-drc", "pll-ddr", | ||
369 | 0x100, BIT(16), 0); | ||
370 | static SUNXI_CCU_GATE(dram_de_fe_clk, "dram-de-fe", "pll-ddr", | ||
371 | 0x100, BIT(24), 0); | ||
372 | static SUNXI_CCU_GATE(dram_de_be_clk, "dram-de-be", "pll-ddr", | ||
373 | 0x100, BIT(26), 0); | ||
374 | |||
375 | static const char * const de_parents[] = { "pll-video", "pll-periph-2x", | ||
376 | "pll-gpu", "pll-de" }; | ||
377 | static const u8 de_table[] = { 0, 2, 3, 5 }; | ||
378 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_be_clk, "de-be", | ||
379 | de_parents, de_table, | ||
380 | 0x104, 0, 4, 24, 3, BIT(31), 0); | ||
381 | |||
382 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_fe_clk, "de-fe", | ||
383 | de_parents, de_table, | ||
384 | 0x10c, 0, 4, 24, 3, BIT(31), 0); | ||
385 | |||
386 | static const char * const lcd_ch0_parents[] = { "pll-video", "pll-video-2x", | ||
387 | "pll-mipi" }; | ||
388 | static const u8 lcd_ch0_table[] = { 0, 2, 4 }; | ||
389 | static SUNXI_CCU_MUX_TABLE_WITH_GATE(lcd_ch0_clk, "lcd-ch0", | ||
390 | lcd_ch0_parents, lcd_ch0_table, | ||
391 | 0x118, 24, 3, BIT(31), | ||
392 | CLK_SET_RATE_PARENT); | ||
393 | |||
394 | static const char * const lcd_ch1_parents[] = { "pll-video", "pll-video-2x" }; | ||
395 | static const u8 lcd_ch1_table[] = { 0, 2 }; | ||
396 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd_ch1_clk, "lcd-ch1", | ||
397 | lcd_ch1_parents, lcd_ch1_table, | ||
398 | 0x12c, 0, 4, 24, 2, BIT(31), 0); | ||
399 | |||
400 | static const char * const csi_sclk_parents[] = { "pll-video", "pll-de", | ||
401 | "pll-mipi", "pll-ve" }; | ||
402 | static const u8 csi_sclk_table[] = { 0, 3, 4, 5 }; | ||
403 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk", | ||
404 | csi_sclk_parents, csi_sclk_table, | ||
405 | 0x134, 16, 4, 24, 3, BIT(31), 0); | ||
406 | |||
407 | static const char * const csi_mclk_parents[] = { "pll-video", "pll-de", | ||
408 | "osc24M" }; | ||
409 | static const u8 csi_mclk_table[] = { 0, 3, 5 }; | ||
410 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk", | ||
411 | csi_mclk_parents, csi_mclk_table, | ||
412 | 0x134, 0, 5, 8, 3, BIT(15), 0); | ||
413 | |||
414 | static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", | ||
415 | 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT); | ||
416 | |||
417 | static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio", | ||
418 | 0x140, BIT(31), 0); | ||
419 | static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", | ||
420 | 0x144, BIT(31), 0); | ||
421 | |||
422 | static const char * const mbus_parents[] = { "osc24M", "pll-periph-2x", | ||
423 | "pll-ddr" }; | ||
424 | static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, | ||
425 | 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL); | ||
426 | |||
427 | static const char * const dsi_sclk_parents[] = { "pll-video", "pll-video-2x" }; | ||
428 | static const u8 dsi_sclk_table[] = { 0, 2 }; | ||
429 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_sclk_clk, "dsi-sclk", | ||
430 | dsi_sclk_parents, dsi_sclk_table, | ||
431 | 0x168, 16, 4, 24, 2, BIT(31), 0); | ||
432 | |||
433 | static const char * const dsi_dphy_parents[] = { "pll-video", "pll-periph" }; | ||
434 | static const u8 dsi_dphy_table[] = { 0, 2 }; | ||
435 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy", | ||
436 | dsi_dphy_parents, dsi_dphy_table, | ||
437 | 0x168, 0, 4, 8, 2, BIT(15), 0); | ||
438 | |||
439 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(drc_clk, "drc", | ||
440 | de_parents, de_table, | ||
441 | 0x180, 0, 4, 24, 3, BIT(31), 0); | ||
442 | |||
443 | static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu", | ||
444 | 0x1a0, 0, 3, BIT(31), 0); | ||
445 | |||
446 | static const char * const ats_parents[] = { "osc24M", "pll-periph" }; | ||
447 | static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", ats_parents, | ||
448 | 0x1b0, 0, 3, 24, 2, BIT(31), 0); | ||
449 | |||
450 | static struct ccu_common *sun8i_a23_ccu_clks[] = { | ||
451 | &pll_cpux_clk.common, | ||
452 | &pll_audio_base_clk.common, | ||
453 | &pll_video_clk.common, | ||
454 | &pll_ve_clk.common, | ||
455 | &pll_ddr_clk.common, | ||
456 | &pll_periph_clk.common, | ||
457 | &pll_gpu_clk.common, | ||
458 | &pll_mipi_clk.common, | ||
459 | &pll_hsic_clk.common, | ||
460 | &pll_de_clk.common, | ||
461 | &cpux_clk.common, | ||
462 | &axi_clk.common, | ||
463 | &ahb1_clk.common, | ||
464 | &apb1_clk.common, | ||
465 | &apb2_clk.common, | ||
466 | &bus_mipi_dsi_clk.common, | ||
467 | &bus_dma_clk.common, | ||
468 | &bus_mmc0_clk.common, | ||
469 | &bus_mmc1_clk.common, | ||
470 | &bus_mmc2_clk.common, | ||
471 | &bus_nand_clk.common, | ||
472 | &bus_dram_clk.common, | ||
473 | &bus_hstimer_clk.common, | ||
474 | &bus_spi0_clk.common, | ||
475 | &bus_spi1_clk.common, | ||
476 | &bus_otg_clk.common, | ||
477 | &bus_ehci_clk.common, | ||
478 | &bus_ohci_clk.common, | ||
479 | &bus_ve_clk.common, | ||
480 | &bus_lcd_clk.common, | ||
481 | &bus_csi_clk.common, | ||
482 | &bus_de_fe_clk.common, | ||
483 | &bus_de_be_clk.common, | ||
484 | &bus_gpu_clk.common, | ||
485 | &bus_msgbox_clk.common, | ||
486 | &bus_spinlock_clk.common, | ||
487 | &bus_drc_clk.common, | ||
488 | &bus_codec_clk.common, | ||
489 | &bus_pio_clk.common, | ||
490 | &bus_i2s0_clk.common, | ||
491 | &bus_i2s1_clk.common, | ||
492 | &bus_i2c0_clk.common, | ||
493 | &bus_i2c1_clk.common, | ||
494 | &bus_i2c2_clk.common, | ||
495 | &bus_uart0_clk.common, | ||
496 | &bus_uart1_clk.common, | ||
497 | &bus_uart2_clk.common, | ||
498 | &bus_uart3_clk.common, | ||
499 | &bus_uart4_clk.common, | ||
500 | &nand_clk.common, | ||
501 | &mmc0_clk.common, | ||
502 | &mmc0_sample_clk.common, | ||
503 | &mmc0_output_clk.common, | ||
504 | &mmc1_clk.common, | ||
505 | &mmc1_sample_clk.common, | ||
506 | &mmc1_output_clk.common, | ||
507 | &mmc2_clk.common, | ||
508 | &mmc2_sample_clk.common, | ||
509 | &mmc2_output_clk.common, | ||
510 | &spi0_clk.common, | ||
511 | &spi1_clk.common, | ||
512 | &i2s0_clk.common, | ||
513 | &i2s1_clk.common, | ||
514 | &usb_phy0_clk.common, | ||
515 | &usb_phy1_clk.common, | ||
516 | &usb_hsic_clk.common, | ||
517 | &usb_hsic_12M_clk.common, | ||
518 | &usb_ohci_clk.common, | ||
519 | &dram_ve_clk.common, | ||
520 | &dram_csi_clk.common, | ||
521 | &dram_drc_clk.common, | ||
522 | &dram_de_fe_clk.common, | ||
523 | &dram_de_be_clk.common, | ||
524 | &de_be_clk.common, | ||
525 | &de_fe_clk.common, | ||
526 | &lcd_ch0_clk.common, | ||
527 | &lcd_ch1_clk.common, | ||
528 | &csi_sclk_clk.common, | ||
529 | &csi_mclk_clk.common, | ||
530 | &ve_clk.common, | ||
531 | &ac_dig_clk.common, | ||
532 | &avs_clk.common, | ||
533 | &mbus_clk.common, | ||
534 | &dsi_sclk_clk.common, | ||
535 | &dsi_dphy_clk.common, | ||
536 | &drc_clk.common, | ||
537 | &gpu_clk.common, | ||
538 | &ats_clk.common, | ||
539 | }; | ||
540 | |||
541 | /* We hardcode the divider to 4 for now */ | ||
542 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | ||
543 | "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); | ||
544 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | ||
545 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | ||
546 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | ||
547 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | ||
548 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | ||
549 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | ||
550 | static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", | ||
551 | "pll-periph", 1, 2, 0); | ||
552 | static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x", | ||
553 | "pll-video", 1, 2, 0); | ||
554 | |||
555 | static struct clk_hw_onecell_data sun8i_a23_hw_clks = { | ||
556 | .hws = { | ||
557 | [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw, | ||
558 | [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, | ||
559 | [CLK_PLL_AUDIO] = &pll_audio_clk.hw, | ||
560 | [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, | ||
561 | [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, | ||
562 | [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, | ||
563 | [CLK_PLL_VIDEO] = &pll_video_clk.common.hw, | ||
564 | [CLK_PLL_VIDEO_2X] = &pll_video_2x_clk.hw, | ||
565 | [CLK_PLL_VE] = &pll_ve_clk.common.hw, | ||
566 | [CLK_PLL_DDR0] = &pll_ddr_clk.common.hw, | ||
567 | [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw, | ||
568 | [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw, | ||
569 | [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, | ||
570 | [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw, | ||
571 | [CLK_PLL_HSIC] = &pll_hsic_clk.common.hw, | ||
572 | [CLK_PLL_DE] = &pll_de_clk.common.hw, | ||
573 | [CLK_CPUX] = &cpux_clk.common.hw, | ||
574 | [CLK_AXI] = &axi_clk.common.hw, | ||
575 | [CLK_AHB1] = &ahb1_clk.common.hw, | ||
576 | [CLK_APB1] = &apb1_clk.common.hw, | ||
577 | [CLK_APB2] = &apb2_clk.common.hw, | ||
578 | [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw, | ||
579 | [CLK_BUS_DMA] = &bus_dma_clk.common.hw, | ||
580 | [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, | ||
581 | [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, | ||
582 | [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, | ||
583 | [CLK_BUS_NAND] = &bus_nand_clk.common.hw, | ||
584 | [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, | ||
585 | [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, | ||
586 | [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, | ||
587 | [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, | ||
588 | [CLK_BUS_OTG] = &bus_otg_clk.common.hw, | ||
589 | [CLK_BUS_EHCI] = &bus_ehci_clk.common.hw, | ||
590 | [CLK_BUS_OHCI] = &bus_ohci_clk.common.hw, | ||
591 | [CLK_BUS_VE] = &bus_ve_clk.common.hw, | ||
592 | [CLK_BUS_LCD] = &bus_lcd_clk.common.hw, | ||
593 | [CLK_BUS_CSI] = &bus_csi_clk.common.hw, | ||
594 | [CLK_BUS_DE_BE] = &bus_de_be_clk.common.hw, | ||
595 | [CLK_BUS_DE_FE] = &bus_de_fe_clk.common.hw, | ||
596 | [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, | ||
597 | [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw, | ||
598 | [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw, | ||
599 | [CLK_BUS_DRC] = &bus_drc_clk.common.hw, | ||
600 | [CLK_BUS_CODEC] = &bus_codec_clk.common.hw, | ||
601 | [CLK_BUS_PIO] = &bus_pio_clk.common.hw, | ||
602 | [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw, | ||
603 | [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw, | ||
604 | [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, | ||
605 | [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, | ||
606 | [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, | ||
607 | [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, | ||
608 | [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, | ||
609 | [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, | ||
610 | [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, | ||
611 | [CLK_BUS_UART4] = &bus_uart4_clk.common.hw, | ||
612 | [CLK_NAND] = &nand_clk.common.hw, | ||
613 | [CLK_MMC0] = &mmc0_clk.common.hw, | ||
614 | [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw, | ||
615 | [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw, | ||
616 | [CLK_MMC1] = &mmc1_clk.common.hw, | ||
617 | [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw, | ||
618 | [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw, | ||
619 | [CLK_MMC2] = &mmc2_clk.common.hw, | ||
620 | [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw, | ||
621 | [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw, | ||
622 | [CLK_SPI0] = &spi0_clk.common.hw, | ||
623 | [CLK_SPI1] = &spi1_clk.common.hw, | ||
624 | [CLK_I2S0] = &i2s0_clk.common.hw, | ||
625 | [CLK_I2S1] = &i2s1_clk.common.hw, | ||
626 | [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, | ||
627 | [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, | ||
628 | [CLK_USB_HSIC] = &usb_hsic_clk.common.hw, | ||
629 | [CLK_USB_HSIC_12M] = &usb_hsic_12M_clk.common.hw, | ||
630 | [CLK_USB_OHCI] = &usb_ohci_clk.common.hw, | ||
631 | [CLK_DRAM_VE] = &dram_ve_clk.common.hw, | ||
632 | [CLK_DRAM_CSI] = &dram_csi_clk.common.hw, | ||
633 | [CLK_DRAM_DRC] = &dram_drc_clk.common.hw, | ||
634 | [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw, | ||
635 | [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw, | ||
636 | [CLK_DE_BE] = &de_be_clk.common.hw, | ||
637 | [CLK_DE_FE] = &de_fe_clk.common.hw, | ||
638 | [CLK_LCD_CH0] = &lcd_ch0_clk.common.hw, | ||
639 | [CLK_LCD_CH1] = &lcd_ch1_clk.common.hw, | ||
640 | [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, | ||
641 | [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw, | ||
642 | [CLK_VE] = &ve_clk.common.hw, | ||
643 | [CLK_AC_DIG] = &ac_dig_clk.common.hw, | ||
644 | [CLK_AVS] = &avs_clk.common.hw, | ||
645 | [CLK_MBUS] = &mbus_clk.common.hw, | ||
646 | [CLK_DSI_SCLK] = &dsi_sclk_clk.common.hw, | ||
647 | [CLK_DSI_DPHY] = &dsi_dphy_clk.common.hw, | ||
648 | [CLK_DRC] = &drc_clk.common.hw, | ||
649 | [CLK_GPU] = &gpu_clk.common.hw, | ||
650 | [CLK_ATS] = &ats_clk.common.hw, | ||
651 | }, | ||
652 | .num = CLK_NUMBER, | ||
653 | }; | ||
654 | |||
655 | static struct ccu_reset_map sun8i_a23_ccu_resets[] = { | ||
656 | [RST_USB_PHY0] = { 0x0cc, BIT(0) }, | ||
657 | [RST_USB_PHY1] = { 0x0cc, BIT(1) }, | ||
658 | [RST_USB_HSIC] = { 0x0cc, BIT(2) }, | ||
659 | |||
660 | [RST_MBUS] = { 0x0fc, BIT(31) }, | ||
661 | |||
662 | [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) }, | ||
663 | [RST_BUS_DMA] = { 0x2c0, BIT(6) }, | ||
664 | [RST_BUS_MMC0] = { 0x2c0, BIT(8) }, | ||
665 | [RST_BUS_MMC1] = { 0x2c0, BIT(9) }, | ||
666 | [RST_BUS_MMC2] = { 0x2c0, BIT(10) }, | ||
667 | [RST_BUS_NAND] = { 0x2c0, BIT(13) }, | ||
668 | [RST_BUS_DRAM] = { 0x2c0, BIT(14) }, | ||
669 | [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) }, | ||
670 | [RST_BUS_SPI0] = { 0x2c0, BIT(20) }, | ||
671 | [RST_BUS_SPI1] = { 0x2c0, BIT(21) }, | ||
672 | [RST_BUS_OTG] = { 0x2c0, BIT(24) }, | ||
673 | [RST_BUS_EHCI] = { 0x2c0, BIT(26) }, | ||
674 | [RST_BUS_OHCI] = { 0x2c0, BIT(29) }, | ||
675 | |||
676 | [RST_BUS_VE] = { 0x2c4, BIT(0) }, | ||
677 | [RST_BUS_LCD] = { 0x2c4, BIT(4) }, | ||
678 | [RST_BUS_CSI] = { 0x2c4, BIT(8) }, | ||
679 | [RST_BUS_DE_BE] = { 0x2c4, BIT(12) }, | ||
680 | [RST_BUS_DE_FE] = { 0x2c4, BIT(14) }, | ||
681 | [RST_BUS_GPU] = { 0x2c4, BIT(20) }, | ||
682 | [RST_BUS_MSGBOX] = { 0x2c4, BIT(21) }, | ||
683 | [RST_BUS_SPINLOCK] = { 0x2c4, BIT(22) }, | ||
684 | [RST_BUS_DRC] = { 0x2c4, BIT(25) }, | ||
685 | |||
686 | [RST_BUS_LVDS] = { 0x2c8, BIT(0) }, | ||
687 | |||
688 | [RST_BUS_CODEC] = { 0x2d0, BIT(0) }, | ||
689 | [RST_BUS_I2S0] = { 0x2d0, BIT(12) }, | ||
690 | [RST_BUS_I2S1] = { 0x2d0, BIT(13) }, | ||
691 | |||
692 | [RST_BUS_I2C0] = { 0x2d4, BIT(0) }, | ||
693 | [RST_BUS_I2C1] = { 0x2d4, BIT(1) }, | ||
694 | [RST_BUS_I2C2] = { 0x2d4, BIT(2) }, | ||
695 | [RST_BUS_UART0] = { 0x2d4, BIT(16) }, | ||
696 | [RST_BUS_UART1] = { 0x2d4, BIT(17) }, | ||
697 | [RST_BUS_UART2] = { 0x2d4, BIT(18) }, | ||
698 | [RST_BUS_UART3] = { 0x2d4, BIT(19) }, | ||
699 | [RST_BUS_UART4] = { 0x2d4, BIT(20) }, | ||
700 | }; | ||
701 | |||
702 | static const struct sunxi_ccu_desc sun8i_a23_ccu_desc = { | ||
703 | .ccu_clks = sun8i_a23_ccu_clks, | ||
704 | .num_ccu_clks = ARRAY_SIZE(sun8i_a23_ccu_clks), | ||
705 | |||
706 | .hw_clks = &sun8i_a23_hw_clks, | ||
707 | |||
708 | .resets = sun8i_a23_ccu_resets, | ||
709 | .num_resets = ARRAY_SIZE(sun8i_a23_ccu_resets), | ||
710 | }; | ||
711 | |||
712 | static void __init sun8i_a23_ccu_setup(struct device_node *node) | ||
713 | { | ||
714 | void __iomem *reg; | ||
715 | u32 val; | ||
716 | |||
717 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | ||
718 | if (IS_ERR(reg)) { | ||
719 | pr_err("%s: Could not map the clock registers\n", | ||
720 | of_node_full_name(node)); | ||
721 | return; | ||
722 | } | ||
723 | |||
724 | /* Force the PLL-Audio-1x divider to 4 */ | ||
725 | val = readl(reg + SUN8I_A23_PLL_AUDIO_REG); | ||
726 | val &= ~GENMASK(19, 16); | ||
727 | writel(val | (3 << 16), reg + SUN8I_A23_PLL_AUDIO_REG); | ||
728 | |||
729 | /* Force PLL-MIPI to MIPI mode */ | ||
730 | val = readl(reg + SUN8I_A23_PLL_MIPI_REG); | ||
731 | val &= ~BIT(16); | ||
732 | writel(val, reg + SUN8I_A23_PLL_MIPI_REG); | ||
733 | |||
734 | sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc); | ||
735 | } | ||
736 | CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu", | ||
737 | sun8i_a23_ccu_setup); | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c new file mode 100644 index 000000000000..fc00892906d8 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c | |||
@@ -0,0 +1,780 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016 Maxime Ripard. All rights reserved. | ||
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/clk-provider.h> | ||
15 | #include <linux/of_address.h> | ||
16 | |||
17 | #include "ccu_common.h" | ||
18 | #include "ccu_reset.h" | ||
19 | |||
20 | #include "ccu_div.h" | ||
21 | #include "ccu_gate.h" | ||
22 | #include "ccu_mp.h" | ||
23 | #include "ccu_mult.h" | ||
24 | #include "ccu_nk.h" | ||
25 | #include "ccu_nkm.h" | ||
26 | #include "ccu_nkmp.h" | ||
27 | #include "ccu_nm.h" | ||
28 | #include "ccu_phase.h" | ||
29 | |||
30 | #include "ccu-sun8i-a23-a33.h" | ||
31 | |||
32 | static struct ccu_nkmp pll_cpux_clk = { | ||
33 | .enable = BIT(31), | ||
34 | .lock = BIT(28), | ||
35 | |||
36 | .n = _SUNXI_CCU_MULT(8, 5), | ||
37 | .k = _SUNXI_CCU_MULT(4, 2), | ||
38 | .m = _SUNXI_CCU_DIV(0, 2), | ||
39 | .p = _SUNXI_CCU_DIV_MAX(16, 2, 4), | ||
40 | |||
41 | .common = { | ||
42 | .reg = 0x000, | ||
43 | .hw.init = CLK_HW_INIT("pll-cpux", "osc24M", | ||
44 | &ccu_nkmp_ops, | ||
45 | 0), | ||
46 | }, | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from | ||
51 | * the base (2x, 4x and 8x), and one variable divider (the one true | ||
52 | * pll audio). | ||
53 | * | ||
54 | * We don't have any need for the variable divider for now, so we just | ||
55 | * hardcode it to match with the clock names | ||
56 | */ | ||
57 | #define SUN8I_A33_PLL_AUDIO_REG 0x008 | ||
58 | |||
59 | static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", | ||
60 | "osc24M", 0x008, | ||
61 | 8, 7, /* N */ | ||
62 | 0, 5, /* M */ | ||
63 | BIT(31), /* gate */ | ||
64 | BIT(28), /* lock */ | ||
65 | CLK_SET_RATE_UNGATE); | ||
66 | |||
67 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video", | ||
68 | "osc24M", 0x010, | ||
69 | 8, 7, /* N */ | ||
70 | 0, 4, /* M */ | ||
71 | BIT(24), /* frac enable */ | ||
72 | BIT(25), /* frac select */ | ||
73 | 270000000, /* frac rate 0 */ | ||
74 | 297000000, /* frac rate 1 */ | ||
75 | BIT(31), /* gate */ | ||
76 | BIT(28), /* lock */ | ||
77 | CLK_SET_RATE_UNGATE); | ||
78 | |||
79 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", | ||
80 | "osc24M", 0x018, | ||
81 | 8, 7, /* N */ | ||
82 | 0, 4, /* M */ | ||
83 | BIT(24), /* frac enable */ | ||
84 | BIT(25), /* frac select */ | ||
85 | 270000000, /* frac rate 0 */ | ||
86 | 297000000, /* frac rate 1 */ | ||
87 | BIT(31), /* gate */ | ||
88 | BIT(28), /* lock */ | ||
89 | CLK_SET_RATE_UNGATE); | ||
90 | |||
91 | static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr0_clk, "pll-ddr0", | ||
92 | "osc24M", 0x020, | ||
93 | 8, 5, /* N */ | ||
94 | 4, 2, /* K */ | ||
95 | 0, 2, /* M */ | ||
96 | BIT(31), /* gate */ | ||
97 | BIT(28), /* lock */ | ||
98 | 0); | ||
99 | |||
100 | static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph", | ||
101 | "osc24M", 0x028, | ||
102 | 8, 5, /* N */ | ||
103 | 4, 2, /* K */ | ||
104 | BIT(31), /* gate */ | ||
105 | BIT(28), /* lock */ | ||
106 | 2, /* post-div */ | ||
107 | CLK_SET_RATE_UNGATE); | ||
108 | |||
109 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", | ||
110 | "osc24M", 0x038, | ||
111 | 8, 7, /* N */ | ||
112 | 0, 4, /* M */ | ||
113 | BIT(24), /* frac enable */ | ||
114 | BIT(25), /* frac select */ | ||
115 | 270000000, /* frac rate 0 */ | ||
116 | 297000000, /* frac rate 1 */ | ||
117 | BIT(31), /* gate */ | ||
118 | BIT(28), /* lock */ | ||
119 | CLK_SET_RATE_UNGATE); | ||
120 | |||
121 | /* | ||
122 | * The MIPI PLL has 2 modes: "MIPI" and "HDMI". | ||
123 | * | ||
124 | * The MIPI mode is a standard NKM-style clock. The HDMI mode is an | ||
125 | * integer / fractional clock with switchable multipliers and dividers. | ||
126 | * This is not supported here. We hardcode the PLL to MIPI mode. | ||
127 | */ | ||
128 | #define SUN8I_A33_PLL_MIPI_REG 0x040 | ||
129 | static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_mipi_clk, "pll-mipi", | ||
130 | "pll-video", 0x040, | ||
131 | 8, 4, /* N */ | ||
132 | 4, 2, /* K */ | ||
133 | 0, 4, /* M */ | ||
134 | BIT(31), /* gate */ | ||
135 | BIT(28), /* lock */ | ||
136 | CLK_SET_RATE_UNGATE); | ||
137 | |||
138 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_hsic_clk, "pll-hsic", | ||
139 | "osc24M", 0x044, | ||
140 | 8, 7, /* N */ | ||
141 | 0, 4, /* M */ | ||
142 | BIT(24), /* frac enable */ | ||
143 | BIT(25), /* frac select */ | ||
144 | 270000000, /* frac rate 0 */ | ||
145 | 297000000, /* frac rate 1 */ | ||
146 | BIT(31), /* gate */ | ||
147 | BIT(28), /* lock */ | ||
148 | CLK_SET_RATE_UNGATE); | ||
149 | |||
150 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de", | ||
151 | "osc24M", 0x048, | ||
152 | 8, 7, /* N */ | ||
153 | 0, 4, /* M */ | ||
154 | BIT(24), /* frac enable */ | ||
155 | BIT(25), /* frac select */ | ||
156 | 270000000, /* frac rate 0 */ | ||
157 | 297000000, /* frac rate 1 */ | ||
158 | BIT(31), /* gate */ | ||
159 | BIT(28), /* lock */ | ||
160 | CLK_SET_RATE_UNGATE); | ||
161 | |||
162 | /* TODO: Fix N */ | ||
163 | static SUNXI_CCU_N_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1", | ||
164 | "osc24M", 0x04c, | ||
165 | 8, 6, /* N */ | ||
166 | BIT(31), /* gate */ | ||
167 | BIT(28), /* lock */ | ||
168 | CLK_SET_RATE_UNGATE); | ||
169 | |||
170 | static const char * const cpux_parents[] = { "osc32k", "osc24M", | ||
171 | "pll-cpux" , "pll-cpux" }; | ||
172 | static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents, | ||
173 | 0x050, 16, 2, CLK_IS_CRITICAL); | ||
174 | |||
175 | static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); | ||
176 | |||
177 | static const char * const ahb1_parents[] = { "osc32k", "osc24M", | ||
178 | "axi" , "pll-periph" }; | ||
179 | static struct ccu_div ahb1_clk = { | ||
180 | .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), | ||
181 | |||
182 | .mux = { | ||
183 | .shift = 12, | ||
184 | .width = 2, | ||
185 | |||
186 | .variable_prediv = { | ||
187 | .index = 3, | ||
188 | .shift = 6, | ||
189 | .width = 2, | ||
190 | }, | ||
191 | }, | ||
192 | |||
193 | .common = { | ||
194 | .reg = 0x054, | ||
195 | .features = CCU_FEATURE_VARIABLE_PREDIV, | ||
196 | .hw.init = CLK_HW_INIT_PARENTS("ahb1", | ||
197 | ahb1_parents, | ||
198 | &ccu_div_ops, | ||
199 | 0), | ||
200 | }, | ||
201 | }; | ||
202 | |||
203 | static struct clk_div_table apb1_div_table[] = { | ||
204 | { .val = 0, .div = 2 }, | ||
205 | { .val = 1, .div = 2 }, | ||
206 | { .val = 2, .div = 4 }, | ||
207 | { .val = 3, .div = 8 }, | ||
208 | { /* Sentinel */ }, | ||
209 | }; | ||
210 | static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1", | ||
211 | 0x054, 8, 2, apb1_div_table, 0); | ||
212 | |||
213 | static const char * const apb2_parents[] = { "osc32k", "osc24M", | ||
214 | "pll-periph" , "pll-periph" }; | ||
215 | static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058, | ||
216 | 0, 5, /* M */ | ||
217 | 16, 2, /* P */ | ||
218 | 24, 2, /* mux */ | ||
219 | 0); | ||
220 | |||
221 | static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1", | ||
222 | 0x060, BIT(1), 0); | ||
223 | static SUNXI_CCU_GATE(bus_ss_clk, "bus-ss", "ahb1", | ||
224 | 0x060, BIT(5), 0); | ||
225 | static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1", | ||
226 | 0x060, BIT(6), 0); | ||
227 | static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1", | ||
228 | 0x060, BIT(8), 0); | ||
229 | static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1", | ||
230 | 0x060, BIT(9), 0); | ||
231 | static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1", | ||
232 | 0x060, BIT(10), 0); | ||
233 | static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1", | ||
234 | 0x060, BIT(13), 0); | ||
235 | static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1", | ||
236 | 0x060, BIT(14), 0); | ||
237 | static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1", | ||
238 | 0x060, BIT(19), 0); | ||
239 | static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1", | ||
240 | 0x060, BIT(20), 0); | ||
241 | static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1", | ||
242 | 0x060, BIT(21), 0); | ||
243 | static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1", | ||
244 | 0x060, BIT(24), 0); | ||
245 | static SUNXI_CCU_GATE(bus_ehci_clk, "bus-ehci", "ahb1", | ||
246 | 0x060, BIT(26), 0); | ||
247 | static SUNXI_CCU_GATE(bus_ohci_clk, "bus-ohci", "ahb1", | ||
248 | 0x060, BIT(29), 0); | ||
249 | |||
250 | static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1", | ||
251 | 0x064, BIT(0), 0); | ||
252 | static SUNXI_CCU_GATE(bus_lcd_clk, "bus-lcd", "ahb1", | ||
253 | 0x064, BIT(4), 0); | ||
254 | static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1", | ||
255 | 0x064, BIT(8), 0); | ||
256 | static SUNXI_CCU_GATE(bus_de_be_clk, "bus-de-be", "ahb1", | ||
257 | 0x064, BIT(12), 0); | ||
258 | static SUNXI_CCU_GATE(bus_de_fe_clk, "bus-de-fe", "ahb1", | ||
259 | 0x064, BIT(14), 0); | ||
260 | static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1", | ||
261 | 0x064, BIT(20), 0); | ||
262 | static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1", | ||
263 | 0x064, BIT(21), 0); | ||
264 | static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1", | ||
265 | 0x064, BIT(22), 0); | ||
266 | static SUNXI_CCU_GATE(bus_drc_clk, "bus-drc", "ahb1", | ||
267 | 0x064, BIT(25), 0); | ||
268 | static SUNXI_CCU_GATE(bus_sat_clk, "bus-sat", "ahb1", | ||
269 | 0x064, BIT(26), 0); | ||
270 | |||
271 | static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1", | ||
272 | 0x068, BIT(0), 0); | ||
273 | static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1", | ||
274 | 0x068, BIT(5), 0); | ||
275 | static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", | ||
276 | 0x068, BIT(12), 0); | ||
277 | static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", | ||
278 | 0x068, BIT(13), 0); | ||
279 | |||
280 | static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", | ||
281 | 0x06c, BIT(0), 0); | ||
282 | static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", | ||
283 | 0x06c, BIT(1), 0); | ||
284 | static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", | ||
285 | 0x06c, BIT(2), 0); | ||
286 | static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", | ||
287 | 0x06c, BIT(16), 0); | ||
288 | static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", | ||
289 | 0x06c, BIT(17), 0); | ||
290 | static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", | ||
291 | 0x06c, BIT(18), 0); | ||
292 | static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", | ||
293 | 0x06c, BIT(19), 0); | ||
294 | static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2", | ||
295 | 0x06c, BIT(20), 0); | ||
296 | |||
297 | static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" }; | ||
298 | static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080, | ||
299 | 0, 4, /* M */ | ||
300 | 16, 2, /* P */ | ||
301 | 24, 2, /* mux */ | ||
302 | BIT(31), /* gate */ | ||
303 | 0); | ||
304 | |||
305 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088, | ||
306 | 0, 4, /* M */ | ||
307 | 16, 2, /* P */ | ||
308 | 24, 2, /* mux */ | ||
309 | BIT(31), /* gate */ | ||
310 | 0); | ||
311 | |||
312 | static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0", | ||
313 | 0x088, 20, 3, 0); | ||
314 | static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0", | ||
315 | 0x088, 8, 3, 0); | ||
316 | |||
317 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c, | ||
318 | 0, 4, /* M */ | ||
319 | 16, 2, /* P */ | ||
320 | 24, 2, /* mux */ | ||
321 | BIT(31), /* gate */ | ||
322 | 0); | ||
323 | |||
324 | static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1", | ||
325 | 0x08c, 20, 3, 0); | ||
326 | static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1", | ||
327 | 0x08c, 8, 3, 0); | ||
328 | |||
329 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090, | ||
330 | 0, 4, /* M */ | ||
331 | 16, 2, /* P */ | ||
332 | 24, 2, /* mux */ | ||
333 | BIT(31), /* gate */ | ||
334 | 0); | ||
335 | |||
336 | static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2", | ||
337 | 0x090, 20, 3, 0); | ||
338 | static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2", | ||
339 | 0x090, 8, 3, 0); | ||
340 | |||
341 | static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c, | ||
342 | 0, 4, /* M */ | ||
343 | 16, 2, /* P */ | ||
344 | 24, 2, /* mux */ | ||
345 | BIT(31), /* gate */ | ||
346 | 0); | ||
347 | |||
348 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0, | ||
349 | 0, 4, /* M */ | ||
350 | 16, 2, /* P */ | ||
351 | 24, 2, /* mux */ | ||
352 | BIT(31), /* gate */ | ||
353 | 0); | ||
354 | |||
355 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4, | ||
356 | 0, 4, /* M */ | ||
357 | 16, 2, /* P */ | ||
358 | 24, 2, /* mux */ | ||
359 | BIT(31), /* gate */ | ||
360 | 0); | ||
361 | |||
362 | static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x", | ||
363 | "pll-audio-2x", "pll-audio" }; | ||
364 | static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents, | ||
365 | 0x0b0, 16, 2, BIT(31), 0); | ||
366 | |||
367 | static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents, | ||
368 | 0x0b4, 16, 2, BIT(31), 0); | ||
369 | |||
370 | /* TODO: the parent for most of the USB clocks is not known */ | ||
371 | static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", | ||
372 | 0x0cc, BIT(8), 0); | ||
373 | static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", | ||
374 | 0x0cc, BIT(9), 0); | ||
375 | static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic", | ||
376 | 0x0cc, BIT(10), 0); | ||
377 | static SUNXI_CCU_GATE(usb_hsic_12M_clk, "usb-hsic-12M", "osc24M", | ||
378 | 0x0cc, BIT(11), 0); | ||
379 | static SUNXI_CCU_GATE(usb_ohci_clk, "usb-ohci", "osc24M", | ||
380 | 0x0cc, BIT(16), 0); | ||
381 | |||
382 | static SUNXI_CCU_M(dram_clk, "dram", "pll-ddr", | ||
383 | 0x0f4, 0, 4, CLK_IS_CRITICAL); | ||
384 | |||
385 | static const char * const pll_ddr_parents[] = { "pll-ddr0", "pll-ddr1" }; | ||
386 | static SUNXI_CCU_MUX(pll_ddr_clk, "pll-ddr", pll_ddr_parents, | ||
387 | 0x0f8, 16, 1, 0); | ||
388 | |||
389 | static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram", | ||
390 | 0x100, BIT(0), 0); | ||
391 | static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "dram", | ||
392 | 0x100, BIT(1), 0); | ||
393 | static SUNXI_CCU_GATE(dram_drc_clk, "dram-drc", "dram", | ||
394 | 0x100, BIT(16), 0); | ||
395 | static SUNXI_CCU_GATE(dram_de_fe_clk, "dram-de-fe", "dram", | ||
396 | 0x100, BIT(24), 0); | ||
397 | static SUNXI_CCU_GATE(dram_de_be_clk, "dram-de-be", "dram", | ||
398 | 0x100, BIT(26), 0); | ||
399 | |||
400 | static const char * const de_parents[] = { "pll-video", "pll-periph-2x", | ||
401 | "pll-gpu", "pll-de" }; | ||
402 | static const u8 de_table[] = { 0, 2, 3, 5 }; | ||
403 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_be_clk, "de-be", | ||
404 | de_parents, de_table, | ||
405 | 0x104, 0, 4, 24, 3, BIT(31), 0); | ||
406 | |||
407 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_fe_clk, "de-fe", | ||
408 | de_parents, de_table, | ||
409 | 0x10c, 0, 4, 24, 3, BIT(31), 0); | ||
410 | |||
411 | static const char * const lcd_ch0_parents[] = { "pll-video", "pll-video-2x", | ||
412 | "pll-mipi" }; | ||
413 | static const u8 lcd_ch0_table[] = { 0, 2, 4 }; | ||
414 | static SUNXI_CCU_MUX_TABLE_WITH_GATE(lcd_ch0_clk, "lcd-ch0", | ||
415 | lcd_ch0_parents, lcd_ch0_table, | ||
416 | 0x118, 24, 3, BIT(31), | ||
417 | CLK_SET_RATE_PARENT); | ||
418 | |||
419 | static const char * const lcd_ch1_parents[] = { "pll-video", "pll-video-2x" }; | ||
420 | static const u8 lcd_ch1_table[] = { 0, 2 }; | ||
421 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd_ch1_clk, "lcd-ch1", | ||
422 | lcd_ch1_parents, lcd_ch1_table, | ||
423 | 0x12c, 0, 4, 24, 2, BIT(31), 0); | ||
424 | |||
425 | static const char * const csi_sclk_parents[] = { "pll-video", "pll-de", | ||
426 | "pll-mipi", "pll-ve" }; | ||
427 | static const u8 csi_sclk_table[] = { 0, 3, 4, 5 }; | ||
428 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk", | ||
429 | csi_sclk_parents, csi_sclk_table, | ||
430 | 0x134, 16, 4, 24, 3, BIT(31), 0); | ||
431 | |||
432 | static const char * const csi_mclk_parents[] = { "pll-video", "pll-de", | ||
433 | "osc24M" }; | ||
434 | static const u8 csi_mclk_table[] = { 0, 3, 5 }; | ||
435 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk", | ||
436 | csi_mclk_parents, csi_mclk_table, | ||
437 | 0x134, 0, 5, 8, 3, BIT(15), 0); | ||
438 | |||
439 | static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", | ||
440 | 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT); | ||
441 | |||
442 | static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio", | ||
443 | 0x140, BIT(31), 0); | ||
444 | static SUNXI_CCU_GATE(ac_dig_4x_clk, "ac-dig-4x", "pll-audio-4x", | ||
445 | 0x140, BIT(30), 0); | ||
446 | static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", | ||
447 | 0x144, BIT(31), 0); | ||
448 | |||
449 | static const char * const mbus_parents[] = { "osc24M", "pll-periph-2x", | ||
450 | "pll-ddr0", "pll-ddr1" }; | ||
451 | static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, | ||
452 | 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL); | ||
453 | |||
454 | static const char * const dsi_sclk_parents[] = { "pll-video", "pll-video-2x" }; | ||
455 | static const u8 dsi_sclk_table[] = { 0, 2 }; | ||
456 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_sclk_clk, "dsi-sclk", | ||
457 | dsi_sclk_parents, dsi_sclk_table, | ||
458 | 0x168, 16, 4, 24, 2, BIT(31), 0); | ||
459 | |||
460 | static const char * const dsi_dphy_parents[] = { "pll-video", "pll-periph" }; | ||
461 | static const u8 dsi_dphy_table[] = { 0, 2 }; | ||
462 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy", | ||
463 | dsi_dphy_parents, dsi_dphy_table, | ||
464 | 0x168, 0, 4, 8, 2, BIT(15), 0); | ||
465 | |||
466 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(drc_clk, "drc", | ||
467 | de_parents, de_table, | ||
468 | 0x180, 0, 4, 24, 3, BIT(31), 0); | ||
469 | |||
470 | static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu", | ||
471 | 0x1a0, 0, 3, BIT(31), 0); | ||
472 | |||
473 | static const char * const ats_parents[] = { "osc24M", "pll-periph" }; | ||
474 | static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", ats_parents, | ||
475 | 0x1b0, 0, 3, 24, 2, BIT(31), 0); | ||
476 | |||
477 | static struct ccu_common *sun8i_a33_ccu_clks[] = { | ||
478 | &pll_cpux_clk.common, | ||
479 | &pll_audio_base_clk.common, | ||
480 | &pll_video_clk.common, | ||
481 | &pll_ve_clk.common, | ||
482 | &pll_ddr0_clk.common, | ||
483 | &pll_periph_clk.common, | ||
484 | &pll_gpu_clk.common, | ||
485 | &pll_mipi_clk.common, | ||
486 | &pll_hsic_clk.common, | ||
487 | &pll_de_clk.common, | ||
488 | &pll_ddr1_clk.common, | ||
489 | &pll_ddr_clk.common, | ||
490 | &cpux_clk.common, | ||
491 | &axi_clk.common, | ||
492 | &ahb1_clk.common, | ||
493 | &apb1_clk.common, | ||
494 | &apb2_clk.common, | ||
495 | &bus_mipi_dsi_clk.common, | ||
496 | &bus_ss_clk.common, | ||
497 | &bus_dma_clk.common, | ||
498 | &bus_mmc0_clk.common, | ||
499 | &bus_mmc1_clk.common, | ||
500 | &bus_mmc2_clk.common, | ||
501 | &bus_nand_clk.common, | ||
502 | &bus_dram_clk.common, | ||
503 | &bus_hstimer_clk.common, | ||
504 | &bus_spi0_clk.common, | ||
505 | &bus_spi1_clk.common, | ||
506 | &bus_otg_clk.common, | ||
507 | &bus_ehci_clk.common, | ||
508 | &bus_ohci_clk.common, | ||
509 | &bus_ve_clk.common, | ||
510 | &bus_lcd_clk.common, | ||
511 | &bus_csi_clk.common, | ||
512 | &bus_de_fe_clk.common, | ||
513 | &bus_de_be_clk.common, | ||
514 | &bus_gpu_clk.common, | ||
515 | &bus_msgbox_clk.common, | ||
516 | &bus_spinlock_clk.common, | ||
517 | &bus_drc_clk.common, | ||
518 | &bus_sat_clk.common, | ||
519 | &bus_codec_clk.common, | ||
520 | &bus_pio_clk.common, | ||
521 | &bus_i2s0_clk.common, | ||
522 | &bus_i2s1_clk.common, | ||
523 | &bus_i2c0_clk.common, | ||
524 | &bus_i2c1_clk.common, | ||
525 | &bus_i2c2_clk.common, | ||
526 | &bus_uart0_clk.common, | ||
527 | &bus_uart1_clk.common, | ||
528 | &bus_uart2_clk.common, | ||
529 | &bus_uart3_clk.common, | ||
530 | &bus_uart4_clk.common, | ||
531 | &nand_clk.common, | ||
532 | &mmc0_clk.common, | ||
533 | &mmc0_sample_clk.common, | ||
534 | &mmc0_output_clk.common, | ||
535 | &mmc1_clk.common, | ||
536 | &mmc1_sample_clk.common, | ||
537 | &mmc1_output_clk.common, | ||
538 | &mmc2_clk.common, | ||
539 | &mmc2_sample_clk.common, | ||
540 | &mmc2_output_clk.common, | ||
541 | &ss_clk.common, | ||
542 | &spi0_clk.common, | ||
543 | &spi1_clk.common, | ||
544 | &i2s0_clk.common, | ||
545 | &i2s1_clk.common, | ||
546 | &usb_phy0_clk.common, | ||
547 | &usb_phy1_clk.common, | ||
548 | &usb_hsic_clk.common, | ||
549 | &usb_hsic_12M_clk.common, | ||
550 | &usb_ohci_clk.common, | ||
551 | &dram_clk.common, | ||
552 | &dram_ve_clk.common, | ||
553 | &dram_csi_clk.common, | ||
554 | &dram_drc_clk.common, | ||
555 | &dram_de_fe_clk.common, | ||
556 | &dram_de_be_clk.common, | ||
557 | &de_be_clk.common, | ||
558 | &de_fe_clk.common, | ||
559 | &lcd_ch0_clk.common, | ||
560 | &lcd_ch1_clk.common, | ||
561 | &csi_sclk_clk.common, | ||
562 | &csi_mclk_clk.common, | ||
563 | &ve_clk.common, | ||
564 | &ac_dig_clk.common, | ||
565 | &ac_dig_4x_clk.common, | ||
566 | &avs_clk.common, | ||
567 | &mbus_clk.common, | ||
568 | &dsi_sclk_clk.common, | ||
569 | &dsi_dphy_clk.common, | ||
570 | &drc_clk.common, | ||
571 | &gpu_clk.common, | ||
572 | &ats_clk.common, | ||
573 | }; | ||
574 | |||
575 | /* We hardcode the divider to 4 for now */ | ||
576 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | ||
577 | "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); | ||
578 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | ||
579 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | ||
580 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | ||
581 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | ||
582 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | ||
583 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | ||
584 | static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", | ||
585 | "pll-periph", 1, 2, 0); | ||
586 | static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x", | ||
587 | "pll-video", 1, 2, 0); | ||
588 | |||
589 | static struct clk_hw_onecell_data sun8i_a33_hw_clks = { | ||
590 | .hws = { | ||
591 | [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw, | ||
592 | [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, | ||
593 | [CLK_PLL_AUDIO] = &pll_audio_clk.hw, | ||
594 | [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, | ||
595 | [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, | ||
596 | [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, | ||
597 | [CLK_PLL_VIDEO] = &pll_video_clk.common.hw, | ||
598 | [CLK_PLL_VIDEO_2X] = &pll_video_2x_clk.hw, | ||
599 | [CLK_PLL_VE] = &pll_ve_clk.common.hw, | ||
600 | [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw, | ||
601 | [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw, | ||
602 | [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw, | ||
603 | [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, | ||
604 | [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw, | ||
605 | [CLK_PLL_HSIC] = &pll_hsic_clk.common.hw, | ||
606 | [CLK_PLL_DE] = &pll_de_clk.common.hw, | ||
607 | [CLK_PLL_DDR1] = &pll_ddr1_clk.common.hw, | ||
608 | [CLK_PLL_DDR] = &pll_ddr_clk.common.hw, | ||
609 | [CLK_CPUX] = &cpux_clk.common.hw, | ||
610 | [CLK_AXI] = &axi_clk.common.hw, | ||
611 | [CLK_AHB1] = &ahb1_clk.common.hw, | ||
612 | [CLK_APB1] = &apb1_clk.common.hw, | ||
613 | [CLK_APB2] = &apb2_clk.common.hw, | ||
614 | [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw, | ||
615 | [CLK_BUS_SS] = &bus_ss_clk.common.hw, | ||
616 | [CLK_BUS_DMA] = &bus_dma_clk.common.hw, | ||
617 | [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, | ||
618 | [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, | ||
619 | [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, | ||
620 | [CLK_BUS_NAND] = &bus_nand_clk.common.hw, | ||
621 | [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, | ||
622 | [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, | ||
623 | [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, | ||
624 | [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, | ||
625 | [CLK_BUS_OTG] = &bus_otg_clk.common.hw, | ||
626 | [CLK_BUS_EHCI] = &bus_ehci_clk.common.hw, | ||
627 | [CLK_BUS_OHCI] = &bus_ohci_clk.common.hw, | ||
628 | [CLK_BUS_VE] = &bus_ve_clk.common.hw, | ||
629 | [CLK_BUS_LCD] = &bus_lcd_clk.common.hw, | ||
630 | [CLK_BUS_CSI] = &bus_csi_clk.common.hw, | ||
631 | [CLK_BUS_DE_BE] = &bus_de_be_clk.common.hw, | ||
632 | [CLK_BUS_DE_FE] = &bus_de_fe_clk.common.hw, | ||
633 | [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, | ||
634 | [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw, | ||
635 | [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw, | ||
636 | [CLK_BUS_DRC] = &bus_drc_clk.common.hw, | ||
637 | [CLK_BUS_SAT] = &bus_sat_clk.common.hw, | ||
638 | [CLK_BUS_CODEC] = &bus_codec_clk.common.hw, | ||
639 | [CLK_BUS_PIO] = &bus_pio_clk.common.hw, | ||
640 | [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw, | ||
641 | [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw, | ||
642 | [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, | ||
643 | [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, | ||
644 | [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, | ||
645 | [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, | ||
646 | [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, | ||
647 | [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, | ||
648 | [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, | ||
649 | [CLK_BUS_UART4] = &bus_uart4_clk.common.hw, | ||
650 | [CLK_NAND] = &nand_clk.common.hw, | ||
651 | [CLK_MMC0] = &mmc0_clk.common.hw, | ||
652 | [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw, | ||
653 | [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw, | ||
654 | [CLK_MMC1] = &mmc1_clk.common.hw, | ||
655 | [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw, | ||
656 | [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw, | ||
657 | [CLK_MMC2] = &mmc2_clk.common.hw, | ||
658 | [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw, | ||
659 | [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw, | ||
660 | [CLK_SS] = &ss_clk.common.hw, | ||
661 | [CLK_SPI0] = &spi0_clk.common.hw, | ||
662 | [CLK_SPI1] = &spi1_clk.common.hw, | ||
663 | [CLK_I2S0] = &i2s0_clk.common.hw, | ||
664 | [CLK_I2S1] = &i2s1_clk.common.hw, | ||
665 | [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, | ||
666 | [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, | ||
667 | [CLK_USB_HSIC] = &usb_hsic_clk.common.hw, | ||
668 | [CLK_USB_HSIC_12M] = &usb_hsic_12M_clk.common.hw, | ||
669 | [CLK_USB_OHCI] = &usb_ohci_clk.common.hw, | ||
670 | [CLK_DRAM] = &dram_clk.common.hw, | ||
671 | [CLK_DRAM_VE] = &dram_ve_clk.common.hw, | ||
672 | [CLK_DRAM_CSI] = &dram_csi_clk.common.hw, | ||
673 | [CLK_DRAM_DRC] = &dram_drc_clk.common.hw, | ||
674 | [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw, | ||
675 | [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw, | ||
676 | [CLK_DE_BE] = &de_be_clk.common.hw, | ||
677 | [CLK_DE_FE] = &de_fe_clk.common.hw, | ||
678 | [CLK_LCD_CH0] = &lcd_ch0_clk.common.hw, | ||
679 | [CLK_LCD_CH1] = &lcd_ch1_clk.common.hw, | ||
680 | [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, | ||
681 | [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw, | ||
682 | [CLK_VE] = &ve_clk.common.hw, | ||
683 | [CLK_AC_DIG] = &ac_dig_clk.common.hw, | ||
684 | [CLK_AC_DIG_4X] = &ac_dig_4x_clk.common.hw, | ||
685 | [CLK_AVS] = &avs_clk.common.hw, | ||
686 | [CLK_MBUS] = &mbus_clk.common.hw, | ||
687 | [CLK_DSI_SCLK] = &dsi_sclk_clk.common.hw, | ||
688 | [CLK_DSI_DPHY] = &dsi_dphy_clk.common.hw, | ||
689 | [CLK_DRC] = &drc_clk.common.hw, | ||
690 | [CLK_GPU] = &gpu_clk.common.hw, | ||
691 | [CLK_ATS] = &ats_clk.common.hw, | ||
692 | }, | ||
693 | .num = CLK_NUMBER, | ||
694 | }; | ||
695 | |||
696 | static struct ccu_reset_map sun8i_a33_ccu_resets[] = { | ||
697 | [RST_USB_PHY0] = { 0x0cc, BIT(0) }, | ||
698 | [RST_USB_PHY1] = { 0x0cc, BIT(1) }, | ||
699 | [RST_USB_HSIC] = { 0x0cc, BIT(2) }, | ||
700 | |||
701 | [RST_MBUS] = { 0x0fc, BIT(31) }, | ||
702 | |||
703 | [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) }, | ||
704 | [RST_BUS_SS] = { 0x2c0, BIT(5) }, | ||
705 | [RST_BUS_DMA] = { 0x2c0, BIT(6) }, | ||
706 | [RST_BUS_MMC0] = { 0x2c0, BIT(8) }, | ||
707 | [RST_BUS_MMC1] = { 0x2c0, BIT(9) }, | ||
708 | [RST_BUS_MMC2] = { 0x2c0, BIT(10) }, | ||
709 | [RST_BUS_NAND] = { 0x2c0, BIT(13) }, | ||
710 | [RST_BUS_DRAM] = { 0x2c0, BIT(14) }, | ||
711 | [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) }, | ||
712 | [RST_BUS_SPI0] = { 0x2c0, BIT(20) }, | ||
713 | [RST_BUS_SPI1] = { 0x2c0, BIT(21) }, | ||
714 | [RST_BUS_OTG] = { 0x2c0, BIT(24) }, | ||
715 | [RST_BUS_EHCI] = { 0x2c0, BIT(26) }, | ||
716 | [RST_BUS_OHCI] = { 0x2c0, BIT(29) }, | ||
717 | |||
718 | [RST_BUS_VE] = { 0x2c4, BIT(0) }, | ||
719 | [RST_BUS_LCD] = { 0x2c4, BIT(4) }, | ||
720 | [RST_BUS_CSI] = { 0x2c4, BIT(8) }, | ||
721 | [RST_BUS_DE_BE] = { 0x2c4, BIT(12) }, | ||
722 | [RST_BUS_DE_FE] = { 0x2c4, BIT(14) }, | ||
723 | [RST_BUS_GPU] = { 0x2c4, BIT(20) }, | ||
724 | [RST_BUS_MSGBOX] = { 0x2c4, BIT(21) }, | ||
725 | [RST_BUS_SPINLOCK] = { 0x2c4, BIT(22) }, | ||
726 | [RST_BUS_DRC] = { 0x2c4, BIT(25) }, | ||
727 | [RST_BUS_SAT] = { 0x2c4, BIT(26) }, | ||
728 | |||
729 | [RST_BUS_LVDS] = { 0x2c8, BIT(0) }, | ||
730 | |||
731 | [RST_BUS_CODEC] = { 0x2d0, BIT(0) }, | ||
732 | [RST_BUS_I2S0] = { 0x2d0, BIT(12) }, | ||
733 | [RST_BUS_I2S1] = { 0x2d0, BIT(13) }, | ||
734 | |||
735 | [RST_BUS_I2C0] = { 0x2d4, BIT(0) }, | ||
736 | [RST_BUS_I2C1] = { 0x2d4, BIT(1) }, | ||
737 | [RST_BUS_I2C2] = { 0x2d4, BIT(2) }, | ||
738 | [RST_BUS_UART0] = { 0x2d4, BIT(16) }, | ||
739 | [RST_BUS_UART1] = { 0x2d4, BIT(17) }, | ||
740 | [RST_BUS_UART2] = { 0x2d4, BIT(18) }, | ||
741 | [RST_BUS_UART3] = { 0x2d4, BIT(19) }, | ||
742 | [RST_BUS_UART4] = { 0x2d4, BIT(20) }, | ||
743 | }; | ||
744 | |||
745 | static const struct sunxi_ccu_desc sun8i_a33_ccu_desc = { | ||
746 | .ccu_clks = sun8i_a33_ccu_clks, | ||
747 | .num_ccu_clks = ARRAY_SIZE(sun8i_a33_ccu_clks), | ||
748 | |||
749 | .hw_clks = &sun8i_a33_hw_clks, | ||
750 | |||
751 | .resets = sun8i_a33_ccu_resets, | ||
752 | .num_resets = ARRAY_SIZE(sun8i_a33_ccu_resets), | ||
753 | }; | ||
754 | |||
755 | static void __init sun8i_a33_ccu_setup(struct device_node *node) | ||
756 | { | ||
757 | void __iomem *reg; | ||
758 | u32 val; | ||
759 | |||
760 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | ||
761 | if (IS_ERR(reg)) { | ||
762 | pr_err("%s: Could not map the clock registers\n", | ||
763 | of_node_full_name(node)); | ||
764 | return; | ||
765 | } | ||
766 | |||
767 | /* Force the PLL-Audio-1x divider to 4 */ | ||
768 | val = readl(reg + SUN8I_A33_PLL_AUDIO_REG); | ||
769 | val &= ~GENMASK(19, 16); | ||
770 | writel(val | (3 << 16), reg + SUN8I_A33_PLL_AUDIO_REG); | ||
771 | |||
772 | /* Force PLL-MIPI to MIPI mode */ | ||
773 | val = readl(reg + SUN8I_A33_PLL_MIPI_REG); | ||
774 | val &= ~BIT(16); | ||
775 | writel(val, reg + SUN8I_A33_PLL_MIPI_REG); | ||
776 | |||
777 | sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc); | ||
778 | } | ||
779 | CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu", | ||
780 | sun8i_a33_ccu_setup); | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 267f99523fbe..4d70590f05e3 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c | |||
@@ -184,15 +184,15 @@ static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058, | |||
184 | 0); | 184 | 0); |
185 | 185 | ||
186 | static const char * const ahb2_parents[] = { "ahb1" , "pll-periph0" }; | 186 | static const char * const ahb2_parents[] = { "ahb1" , "pll-periph0" }; |
187 | static const struct ccu_mux_fixed_prediv ahb2_fixed_predivs[] = { | ||
188 | { .index = 1, .div = 2 }, | ||
189 | }; | ||
187 | static struct ccu_mux ahb2_clk = { | 190 | static struct ccu_mux ahb2_clk = { |
188 | .mux = { | 191 | .mux = { |
189 | .shift = 0, | 192 | .shift = 0, |
190 | .width = 1, | 193 | .width = 1, |
191 | 194 | .fixed_predivs = ahb2_fixed_predivs, | |
192 | .fixed_prediv = { | 195 | .n_predivs = ARRAY_SIZE(ahb2_fixed_predivs), |
193 | .index = 1, | ||
194 | .div = 2, | ||
195 | }, | ||
196 | }, | 196 | }, |
197 | 197 | ||
198 | .common = { | 198 | .common = { |
diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h index 653ade5769b3..34c338832c0d 100644 --- a/drivers/clk/sunxi-ng/ccu_div.h +++ b/drivers/clk/sunxi-ng/ccu_div.h | |||
@@ -19,10 +19,29 @@ | |||
19 | #include "ccu_common.h" | 19 | #include "ccu_common.h" |
20 | #include "ccu_mux.h" | 20 | #include "ccu_mux.h" |
21 | 21 | ||
22 | /** | ||
23 | * struct _ccu_div - Internal divider description | ||
24 | * @shift: Bit offset of the divider in its register | ||
25 | * @width: Width of the divider field in its register | ||
26 | * @max: Maximum value allowed for that divider. This is the | ||
27 | * arithmetic value, not the maximum value to be set in the | ||
28 | * register. | ||
29 | * @flags: clk_divider flags to apply on this divider | ||
30 | * @table: Divider table pointer (if applicable) | ||
31 | * | ||
32 | * That structure represents a single divider, and is meant to be | ||
33 | * embedded in other structures representing the various clock | ||
34 | * classes. | ||
35 | * | ||
36 | * It is basically a wrapper around the clk_divider functions | ||
37 | * arguments. | ||
38 | */ | ||
22 | struct _ccu_div { | 39 | struct _ccu_div { |
23 | u8 shift; | 40 | u8 shift; |
24 | u8 width; | 41 | u8 width; |
25 | 42 | ||
43 | u32 max; | ||
44 | |||
26 | u32 flags; | 45 | u32 flags; |
27 | 46 | ||
28 | struct clk_div_table *table; | 47 | struct clk_div_table *table; |
@@ -36,14 +55,25 @@ struct _ccu_div { | |||
36 | .table = _table, \ | 55 | .table = _table, \ |
37 | } | 56 | } |
38 | 57 | ||
39 | #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \ | ||
40 | _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, _flags) | ||
41 | |||
42 | #define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \ | 58 | #define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \ |
43 | _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0) | 59 | _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0) |
44 | 60 | ||
61 | #define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \ | ||
62 | { \ | ||
63 | .shift = _shift, \ | ||
64 | .width = _width, \ | ||
65 | .flags = _flags, \ | ||
66 | .max = _max, \ | ||
67 | } | ||
68 | |||
69 | #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \ | ||
70 | _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags) | ||
71 | |||
72 | #define _SUNXI_CCU_DIV_MAX(_shift, _width, _max) \ | ||
73 | _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0) | ||
74 | |||
45 | #define _SUNXI_CCU_DIV(_shift, _width) \ | 75 | #define _SUNXI_CCU_DIV(_shift, _width) \ |
46 | _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, 0) | 76 | _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0) |
47 | 77 | ||
48 | struct ccu_div { | 78 | struct ccu_div { |
49 | u32 enable; | 79 | u32 enable; |
@@ -77,13 +107,16 @@ struct ccu_div { | |||
77 | _shift, _width, _table, 0, \ | 107 | _shift, _width, _table, 0, \ |
78 | _flags) | 108 | _flags) |
79 | 109 | ||
80 | #define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ | 110 | #define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \ |
81 | _mshift, _mwidth, _muxshift, _muxwidth, \ | 111 | _parents, _table, \ |
82 | _gate, _flags) \ | 112 | _reg, \ |
113 | _mshift, _mwidth, \ | ||
114 | _muxshift, _muxwidth, \ | ||
115 | _gate, _flags) \ | ||
83 | struct ccu_div _struct = { \ | 116 | struct ccu_div _struct = { \ |
84 | .enable = _gate, \ | 117 | .enable = _gate, \ |
85 | .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \ | 118 | .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \ |
86 | .mux = SUNXI_CLK_MUX(_muxshift, _muxwidth), \ | 119 | .mux = _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \ |
87 | .common = { \ | 120 | .common = { \ |
88 | .reg = _reg, \ | 121 | .reg = _reg, \ |
89 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ | 122 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ |
@@ -93,12 +126,23 @@ struct ccu_div { | |||
93 | }, \ | 126 | }, \ |
94 | } | 127 | } |
95 | 128 | ||
129 | #define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ | ||
130 | _mshift, _mwidth, _muxshift, _muxwidth, \ | ||
131 | _gate, _flags) \ | ||
132 | SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \ | ||
133 | _parents, NULL, \ | ||
134 | _reg, _mshift, _mwidth, \ | ||
135 | _muxshift, _muxwidth, \ | ||
136 | _gate, _flags) | ||
137 | |||
96 | #define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg, \ | 138 | #define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg, \ |
97 | _mshift, _mwidth, _muxshift, _muxwidth, \ | 139 | _mshift, _mwidth, _muxshift, _muxwidth, \ |
98 | _flags) \ | 140 | _flags) \ |
99 | SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ | 141 | SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \ |
100 | _mshift, _mwidth, _muxshift, _muxwidth, \ | 142 | _parents, NULL, \ |
101 | 0, _flags) | 143 | _reg, _mshift, _mwidth, \ |
144 | _muxshift, _muxwidth, \ | ||
145 | 0, _flags) | ||
102 | 146 | ||
103 | 147 | ||
104 | #define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \ | 148 | #define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \ |
diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index cbf33ef5faa9..ebb1b31568a5 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c | |||
@@ -21,9 +21,9 @@ static void ccu_mp_find_best(unsigned long parent, unsigned long rate, | |||
21 | unsigned int best_m = 0, best_p = 0; | 21 | unsigned int best_m = 0, best_p = 0; |
22 | unsigned int _m, _p; | 22 | unsigned int _m, _p; |
23 | 23 | ||
24 | for (_p = 0; _p <= max_p; _p++) { | 24 | for (_p = 1; _p <= max_p; _p <<= 1) { |
25 | for (_m = 1; _m <= max_m; _m++) { | 25 | for (_m = 1; _m <= max_m; _m++) { |
26 | unsigned long tmp_rate = (parent >> _p) / _m; | 26 | unsigned long tmp_rate = parent / _p / _m; |
27 | 27 | ||
28 | if (tmp_rate > rate) | 28 | if (tmp_rate > rate) |
29 | continue; | 29 | continue; |
@@ -46,13 +46,15 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, | |||
46 | void *data) | 46 | void *data) |
47 | { | 47 | { |
48 | struct ccu_mp *cmp = data; | 48 | struct ccu_mp *cmp = data; |
49 | unsigned int max_m, max_p; | ||
49 | unsigned int m, p; | 50 | unsigned int m, p; |
50 | 51 | ||
51 | ccu_mp_find_best(parent_rate, rate, | 52 | max_m = cmp->m.max ?: 1 << cmp->m.width; |
52 | 1 << cmp->m.width, (1 << cmp->p.width) - 1, | 53 | max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); |
53 | &m, &p); | ||
54 | 54 | ||
55 | return (parent_rate >> p) / m; | 55 | ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p); |
56 | |||
57 | return parent_rate / p / m; | ||
56 | } | 58 | } |
57 | 59 | ||
58 | static void ccu_mp_disable(struct clk_hw *hw) | 60 | static void ccu_mp_disable(struct clk_hw *hw) |
@@ -108,13 +110,14 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate, | |||
108 | { | 110 | { |
109 | struct ccu_mp *cmp = hw_to_ccu_mp(hw); | 111 | struct ccu_mp *cmp = hw_to_ccu_mp(hw); |
110 | unsigned long flags; | 112 | unsigned long flags; |
113 | unsigned int max_m, max_p; | ||
111 | unsigned int m, p; | 114 | unsigned int m, p; |
112 | u32 reg; | 115 | u32 reg; |
113 | 116 | ||
114 | ccu_mp_find_best(parent_rate, rate, | 117 | max_m = cmp->m.max ?: 1 << cmp->m.width; |
115 | 1 << cmp->m.width, (1 << cmp->p.width) - 1, | 118 | max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); |
116 | &m, &p); | ||
117 | 119 | ||
120 | ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p); | ||
118 | 121 | ||
119 | spin_lock_irqsave(cmp->common.lock, flags); | 122 | spin_lock_irqsave(cmp->common.lock, flags); |
120 | 123 | ||
@@ -122,7 +125,7 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate, | |||
122 | reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift); | 125 | reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift); |
123 | reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift); | 126 | reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift); |
124 | 127 | ||
125 | writel(reg | (p << cmp->p.shift) | ((m - 1) << cmp->m.shift), | 128 | writel(reg | (ilog2(p) << cmp->p.shift) | ((m - 1) << cmp->m.shift), |
126 | cmp->common.base + cmp->common.reg); | 129 | cmp->common.base + cmp->common.reg); |
127 | 130 | ||
128 | spin_unlock_irqrestore(cmp->common.lock, flags); | 131 | spin_unlock_irqrestore(cmp->common.lock, flags); |
diff --git a/drivers/clk/sunxi-ng/ccu_mp.h b/drivers/clk/sunxi-ng/ccu_mp.h index 3cf12bf95962..edf9215ea8cc 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.h +++ b/drivers/clk/sunxi-ng/ccu_mp.h | |||
@@ -44,7 +44,7 @@ struct ccu_mp { | |||
44 | .enable = _gate, \ | 44 | .enable = _gate, \ |
45 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ | 45 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ |
46 | .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ | 46 | .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ |
47 | .mux = SUNXI_CLK_MUX(_muxshift, _muxwidth), \ | 47 | .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ |
48 | .common = { \ | 48 | .common = { \ |
49 | .reg = _reg, \ | 49 | .reg = _reg, \ |
50 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ | 50 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ |
diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c new file mode 100644 index 000000000000..010e9424691d --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu_mult.c | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Maxime Ripard | ||
3 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation; either version 2 of | ||
8 | * the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | |||
13 | #include "ccu_gate.h" | ||
14 | #include "ccu_mult.h" | ||
15 | |||
16 | static void ccu_mult_find_best(unsigned long parent, unsigned long rate, | ||
17 | unsigned int max_n, unsigned int *n) | ||
18 | { | ||
19 | *n = rate / parent; | ||
20 | } | ||
21 | |||
22 | static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux, | ||
23 | unsigned long parent_rate, | ||
24 | unsigned long rate, | ||
25 | void *data) | ||
26 | { | ||
27 | struct ccu_mult *cm = data; | ||
28 | unsigned int n; | ||
29 | |||
30 | ccu_mult_find_best(parent_rate, rate, 1 << cm->mult.width, &n); | ||
31 | |||
32 | return parent_rate * n; | ||
33 | } | ||
34 | |||
35 | static void ccu_mult_disable(struct clk_hw *hw) | ||
36 | { | ||
37 | struct ccu_mult *cm = hw_to_ccu_mult(hw); | ||
38 | |||
39 | return ccu_gate_helper_disable(&cm->common, cm->enable); | ||
40 | } | ||
41 | |||
42 | static int ccu_mult_enable(struct clk_hw *hw) | ||
43 | { | ||
44 | struct ccu_mult *cm = hw_to_ccu_mult(hw); | ||
45 | |||
46 | return ccu_gate_helper_enable(&cm->common, cm->enable); | ||
47 | } | ||
48 | |||
49 | static int ccu_mult_is_enabled(struct clk_hw *hw) | ||
50 | { | ||
51 | struct ccu_mult *cm = hw_to_ccu_mult(hw); | ||
52 | |||
53 | return ccu_gate_helper_is_enabled(&cm->common, cm->enable); | ||
54 | } | ||
55 | |||
56 | static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw, | ||
57 | unsigned long parent_rate) | ||
58 | { | ||
59 | struct ccu_mult *cm = hw_to_ccu_mult(hw); | ||
60 | unsigned long val; | ||
61 | u32 reg; | ||
62 | |||
63 | reg = readl(cm->common.base + cm->common.reg); | ||
64 | val = reg >> cm->mult.shift; | ||
65 | val &= (1 << cm->mult.width) - 1; | ||
66 | |||
67 | ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1, | ||
68 | &parent_rate); | ||
69 | |||
70 | return parent_rate * (val + 1); | ||
71 | } | ||
72 | |||
73 | static int ccu_mult_determine_rate(struct clk_hw *hw, | ||
74 | struct clk_rate_request *req) | ||
75 | { | ||
76 | struct ccu_mult *cm = hw_to_ccu_mult(hw); | ||
77 | |||
78 | return ccu_mux_helper_determine_rate(&cm->common, &cm->mux, | ||
79 | req, ccu_mult_round_rate, cm); | ||
80 | } | ||
81 | |||
82 | static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate, | ||
83 | unsigned long parent_rate) | ||
84 | { | ||
85 | struct ccu_mult *cm = hw_to_ccu_mult(hw); | ||
86 | unsigned long flags; | ||
87 | unsigned int n; | ||
88 | u32 reg; | ||
89 | |||
90 | ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1, | ||
91 | &parent_rate); | ||
92 | |||
93 | ccu_mult_find_best(parent_rate, rate, 1 << cm->mult.width, &n); | ||
94 | |||
95 | spin_lock_irqsave(cm->common.lock, flags); | ||
96 | |||
97 | reg = readl(cm->common.base + cm->common.reg); | ||
98 | reg &= ~GENMASK(cm->mult.width + cm->mult.shift - 1, cm->mult.shift); | ||
99 | |||
100 | writel(reg | ((n - 1) << cm->mult.shift), | ||
101 | cm->common.base + cm->common.reg); | ||
102 | |||
103 | spin_unlock_irqrestore(cm->common.lock, flags); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static u8 ccu_mult_get_parent(struct clk_hw *hw) | ||
109 | { | ||
110 | struct ccu_mult *cm = hw_to_ccu_mult(hw); | ||
111 | |||
112 | return ccu_mux_helper_get_parent(&cm->common, &cm->mux); | ||
113 | } | ||
114 | |||
115 | static int ccu_mult_set_parent(struct clk_hw *hw, u8 index) | ||
116 | { | ||
117 | struct ccu_mult *cm = hw_to_ccu_mult(hw); | ||
118 | |||
119 | return ccu_mux_helper_set_parent(&cm->common, &cm->mux, index); | ||
120 | } | ||
121 | |||
122 | const struct clk_ops ccu_mult_ops = { | ||
123 | .disable = ccu_mult_disable, | ||
124 | .enable = ccu_mult_enable, | ||
125 | .is_enabled = ccu_mult_is_enabled, | ||
126 | |||
127 | .get_parent = ccu_mult_get_parent, | ||
128 | .set_parent = ccu_mult_set_parent, | ||
129 | |||
130 | .determine_rate = ccu_mult_determine_rate, | ||
131 | .recalc_rate = ccu_mult_recalc_rate, | ||
132 | .set_rate = ccu_mult_set_rate, | ||
133 | }; | ||
diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h index 609db6610880..5d2c8dc14073 100644 --- a/drivers/clk/sunxi-ng/ccu_mult.h +++ b/drivers/clk/sunxi-ng/ccu_mult.h | |||
@@ -1,6 +1,9 @@ | |||
1 | #ifndef _CCU_MULT_H_ | 1 | #ifndef _CCU_MULT_H_ |
2 | #define _CCU_MULT_H_ | 2 | #define _CCU_MULT_H_ |
3 | 3 | ||
4 | #include "ccu_common.h" | ||
5 | #include "ccu_mux.h" | ||
6 | |||
4 | struct _ccu_mult { | 7 | struct _ccu_mult { |
5 | u8 shift; | 8 | u8 shift; |
6 | u8 width; | 9 | u8 width; |
@@ -12,4 +15,36 @@ struct _ccu_mult { | |||
12 | .width = _width, \ | 15 | .width = _width, \ |
13 | } | 16 | } |
14 | 17 | ||
18 | struct ccu_mult { | ||
19 | u32 enable; | ||
20 | |||
21 | struct _ccu_mult mult; | ||
22 | struct ccu_mux_internal mux; | ||
23 | struct ccu_common common; | ||
24 | }; | ||
25 | |||
26 | #define SUNXI_CCU_N_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ | ||
27 | _mshift, _mwidth, _gate, _lock, \ | ||
28 | _flags) \ | ||
29 | struct ccu_mult _struct = { \ | ||
30 | .enable = _gate, \ | ||
31 | .mult = _SUNXI_CCU_MULT(_mshift, _mwidth), \ | ||
32 | .common = { \ | ||
33 | .reg = _reg, \ | ||
34 | .hw.init = CLK_HW_INIT(_name, \ | ||
35 | _parent, \ | ||
36 | &ccu_mult_ops, \ | ||
37 | _flags), \ | ||
38 | }, \ | ||
39 | } | ||
40 | |||
41 | static inline struct ccu_mult *hw_to_ccu_mult(struct clk_hw *hw) | ||
42 | { | ||
43 | struct ccu_common *common = hw_to_ccu_common(hw); | ||
44 | |||
45 | return container_of(common, struct ccu_mult, common); | ||
46 | } | ||
47 | |||
48 | extern const struct clk_ops ccu_mult_ops; | ||
49 | |||
15 | #endif /* _CCU_MULT_H_ */ | 50 | #endif /* _CCU_MULT_H_ */ |
diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c index 58fc36e7dcce..a43ad52a957d 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.c +++ b/drivers/clk/sunxi-ng/ccu_mux.c | |||
@@ -8,7 +8,9 @@ | |||
8 | * the License, or (at your option) any later version. | 8 | * the License, or (at your option) any later version. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/clk.h> | ||
11 | #include <linux/clk-provider.h> | 12 | #include <linux/clk-provider.h> |
13 | #include <linux/delay.h> | ||
12 | 14 | ||
13 | #include "ccu_gate.h" | 15 | #include "ccu_gate.h" |
14 | #include "ccu_mux.h" | 16 | #include "ccu_mux.h" |
@@ -18,8 +20,9 @@ void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common, | |||
18 | int parent_index, | 20 | int parent_index, |
19 | unsigned long *parent_rate) | 21 | unsigned long *parent_rate) |
20 | { | 22 | { |
21 | u8 prediv = 1; | 23 | u16 prediv = 1; |
22 | u32 reg; | 24 | u32 reg; |
25 | int i; | ||
23 | 26 | ||
24 | if (!((common->features & CCU_FEATURE_FIXED_PREDIV) || | 27 | if (!((common->features & CCU_FEATURE_FIXED_PREDIV) || |
25 | (common->features & CCU_FEATURE_VARIABLE_PREDIV))) | 28 | (common->features & CCU_FEATURE_VARIABLE_PREDIV))) |
@@ -32,8 +35,9 @@ void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common, | |||
32 | } | 35 | } |
33 | 36 | ||
34 | if (common->features & CCU_FEATURE_FIXED_PREDIV) | 37 | if (common->features & CCU_FEATURE_FIXED_PREDIV) |
35 | if (parent_index == cm->fixed_prediv.index) | 38 | for (i = 0; i < cm->n_predivs; i++) |
36 | prediv = cm->fixed_prediv.div; | 39 | if (parent_index == cm->fixed_predivs[i].index) |
40 | prediv = cm->fixed_predivs[i].div; | ||
37 | 41 | ||
38 | if (common->features & CCU_FEATURE_VARIABLE_PREDIV) | 42 | if (common->features & CCU_FEATURE_VARIABLE_PREDIV) |
39 | if (parent_index == cm->variable_prediv.index) { | 43 | if (parent_index == cm->variable_prediv.index) { |
@@ -107,6 +111,15 @@ u8 ccu_mux_helper_get_parent(struct ccu_common *common, | |||
107 | parent = reg >> cm->shift; | 111 | parent = reg >> cm->shift; |
108 | parent &= (1 << cm->width) - 1; | 112 | parent &= (1 << cm->width) - 1; |
109 | 113 | ||
114 | if (cm->table) { | ||
115 | int num_parents = clk_hw_get_num_parents(&common->hw); | ||
116 | int i; | ||
117 | |||
118 | for (i = 0; i < num_parents; i++) | ||
119 | if (cm->table[i] == parent) | ||
120 | return i; | ||
121 | } | ||
122 | |||
110 | return parent; | 123 | return parent; |
111 | } | 124 | } |
112 | 125 | ||
@@ -117,6 +130,9 @@ int ccu_mux_helper_set_parent(struct ccu_common *common, | |||
117 | unsigned long flags; | 130 | unsigned long flags; |
118 | u32 reg; | 131 | u32 reg; |
119 | 132 | ||
133 | if (cm->table) | ||
134 | index = cm->table[index]; | ||
135 | |||
120 | spin_lock_irqsave(common->lock, flags); | 136 | spin_lock_irqsave(common->lock, flags); |
121 | 137 | ||
122 | reg = readl(common->base + common->reg); | 138 | reg = readl(common->base + common->reg); |
@@ -185,3 +201,37 @@ const struct clk_ops ccu_mux_ops = { | |||
185 | .determine_rate = __clk_mux_determine_rate, | 201 | .determine_rate = __clk_mux_determine_rate, |
186 | .recalc_rate = ccu_mux_recalc_rate, | 202 | .recalc_rate = ccu_mux_recalc_rate, |
187 | }; | 203 | }; |
204 | |||
205 | /* | ||
206 | * This clock notifier is called when the frequency of the of the parent | ||
207 | * PLL clock is to be changed. The idea is to switch the parent to a | ||
208 | * stable clock, such as the main oscillator, while the PLL frequency | ||
209 | * stabilizes. | ||
210 | */ | ||
211 | static int ccu_mux_notifier_cb(struct notifier_block *nb, | ||
212 | unsigned long event, void *data) | ||
213 | { | ||
214 | struct ccu_mux_nb *mux = to_ccu_mux_nb(nb); | ||
215 | int ret = 0; | ||
216 | |||
217 | if (event == PRE_RATE_CHANGE) { | ||
218 | mux->original_index = ccu_mux_helper_get_parent(mux->common, | ||
219 | mux->cm); | ||
220 | ret = ccu_mux_helper_set_parent(mux->common, mux->cm, | ||
221 | mux->bypass_index); | ||
222 | } else if (event == POST_RATE_CHANGE) { | ||
223 | ret = ccu_mux_helper_set_parent(mux->common, mux->cm, | ||
224 | mux->original_index); | ||
225 | } | ||
226 | |||
227 | udelay(mux->delay_us); | ||
228 | |||
229 | return notifier_from_errno(ret); | ||
230 | } | ||
231 | |||
232 | int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb) | ||
233 | { | ||
234 | mux_nb->clk_nb.notifier_call = ccu_mux_notifier_cb; | ||
235 | |||
236 | return clk_notifier_register(clk, &mux_nb->clk_nb); | ||
237 | } | ||
diff --git a/drivers/clk/sunxi-ng/ccu_mux.h b/drivers/clk/sunxi-ng/ccu_mux.h index 945082631e7d..47aba3a48245 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.h +++ b/drivers/clk/sunxi-ng/ccu_mux.h | |||
@@ -5,14 +5,18 @@ | |||
5 | 5 | ||
6 | #include "ccu_common.h" | 6 | #include "ccu_common.h" |
7 | 7 | ||
8 | struct ccu_mux_fixed_prediv { | ||
9 | u8 index; | ||
10 | u16 div; | ||
11 | }; | ||
12 | |||
8 | struct ccu_mux_internal { | 13 | struct ccu_mux_internal { |
9 | u8 shift; | 14 | u8 shift; |
10 | u8 width; | 15 | u8 width; |
16 | const u8 *table; | ||
11 | 17 | ||
12 | struct { | 18 | const struct ccu_mux_fixed_prediv *fixed_predivs; |
13 | u8 index; | 19 | u8 n_predivs; |
14 | u8 div; | ||
15 | } fixed_prediv; | ||
16 | 20 | ||
17 | struct { | 21 | struct { |
18 | u8 index; | 22 | u8 index; |
@@ -21,12 +25,16 @@ struct ccu_mux_internal { | |||
21 | } variable_prediv; | 25 | } variable_prediv; |
22 | }; | 26 | }; |
23 | 27 | ||
24 | #define SUNXI_CLK_MUX(_shift, _width) \ | 28 | #define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table) \ |
25 | { \ | 29 | { \ |
26 | .shift = _shift, \ | 30 | .shift = _shift, \ |
27 | .width = _width, \ | 31 | .width = _width, \ |
32 | .table = _table, \ | ||
28 | } | 33 | } |
29 | 34 | ||
35 | #define _SUNXI_CCU_MUX(_shift, _width) \ | ||
36 | _SUNXI_CCU_MUX_TABLE(_shift, _width, NULL) | ||
37 | |||
30 | struct ccu_mux { | 38 | struct ccu_mux { |
31 | u16 reg; | 39 | u16 reg; |
32 | u32 enable; | 40 | u32 enable; |
@@ -35,9 +43,12 @@ struct ccu_mux { | |||
35 | struct ccu_common common; | 43 | struct ccu_common common; |
36 | }; | 44 | }; |
37 | 45 | ||
38 | #define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, _flags) \ | 46 | #define SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, _table, \ |
47 | _reg, _shift, _width, _gate, \ | ||
48 | _flags) \ | ||
39 | struct ccu_mux _struct = { \ | 49 | struct ccu_mux _struct = { \ |
40 | .mux = SUNXI_CLK_MUX(_shift, _width), \ | 50 | .enable = _gate, \ |
51 | .mux = _SUNXI_CCU_MUX_TABLE(_shift, _width, _table), \ | ||
41 | .common = { \ | 52 | .common = { \ |
42 | .reg = _reg, \ | 53 | .reg = _reg, \ |
43 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ | 54 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ |
@@ -49,17 +60,14 @@ struct ccu_mux { | |||
49 | 60 | ||
50 | #define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg, \ | 61 | #define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg, \ |
51 | _shift, _width, _gate, _flags) \ | 62 | _shift, _width, _gate, _flags) \ |
52 | struct ccu_mux _struct = { \ | 63 | SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \ |
53 | .enable = _gate, \ | 64 | _reg, _shift, _width, _gate, \ |
54 | .mux = SUNXI_CLK_MUX(_shift, _width), \ | 65 | _flags) |
55 | .common = { \ | 66 | |
56 | .reg = _reg, \ | 67 | #define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, \ |
57 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ | 68 | _flags) \ |
58 | _parents, \ | 69 | SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \ |
59 | &ccu_mux_ops, \ | 70 | _reg, _shift, _width, 0, _flags) |
60 | _flags), \ | ||
61 | } \ | ||
62 | } | ||
63 | 71 | ||
64 | static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw) | 72 | static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw) |
65 | { | 73 | { |
@@ -88,4 +96,18 @@ int ccu_mux_helper_set_parent(struct ccu_common *common, | |||
88 | struct ccu_mux_internal *cm, | 96 | struct ccu_mux_internal *cm, |
89 | u8 index); | 97 | u8 index); |
90 | 98 | ||
99 | struct ccu_mux_nb { | ||
100 | struct notifier_block clk_nb; | ||
101 | struct ccu_common *common; | ||
102 | struct ccu_mux_internal *cm; | ||
103 | |||
104 | u32 delay_us; /* How many us to wait after reparenting */ | ||
105 | u8 bypass_index; /* Which parent to temporarily use */ | ||
106 | u8 original_index; /* This is set by the notifier callback */ | ||
107 | }; | ||
108 | |||
109 | #define to_ccu_mux_nb(_nb) container_of(_nb, struct ccu_mux_nb, clk_nb) | ||
110 | |||
111 | int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb); | ||
112 | |||
91 | #endif /* _CCU_MUX_H_ */ | 113 | #endif /* _CCU_MUX_H_ */ |
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c index 2071822b1e9c..059fdc3b4f96 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.c +++ b/drivers/clk/sunxi-ng/ccu_nkm.c | |||
@@ -93,19 +93,30 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw, | |||
93 | return parent_rate * (n + 1) * (k + 1) / (m + 1); | 93 | return parent_rate * (n + 1) * (k + 1) / (m + 1); |
94 | } | 94 | } |
95 | 95 | ||
96 | static long ccu_nkm_round_rate(struct clk_hw *hw, unsigned long rate, | 96 | static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, |
97 | unsigned long *parent_rate) | 97 | unsigned long parent_rate, |
98 | unsigned long rate, | ||
99 | void *data) | ||
98 | { | 100 | { |
99 | struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); | 101 | struct ccu_nkm *nkm = data; |
100 | struct _ccu_nkm _nkm; | 102 | struct _ccu_nkm _nkm; |
101 | 103 | ||
102 | _nkm.max_n = 1 << nkm->n.width; | 104 | _nkm.max_n = 1 << nkm->n.width; |
103 | _nkm.max_k = 1 << nkm->k.width; | 105 | _nkm.max_k = 1 << nkm->k.width; |
104 | _nkm.max_m = 1 << nkm->m.width; | 106 | _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; |
105 | 107 | ||
106 | ccu_nkm_find_best(*parent_rate, rate, &_nkm); | 108 | ccu_nkm_find_best(parent_rate, rate, &_nkm); |
107 | 109 | ||
108 | return *parent_rate * _nkm.n * _nkm.k / _nkm.m; | 110 | return parent_rate * _nkm.n * _nkm.k / _nkm.m; |
111 | } | ||
112 | |||
113 | static int ccu_nkm_determine_rate(struct clk_hw *hw, | ||
114 | struct clk_rate_request *req) | ||
115 | { | ||
116 | struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); | ||
117 | |||
118 | return ccu_mux_helper_determine_rate(&nkm->common, &nkm->mux, | ||
119 | req, ccu_nkm_round_rate, nkm); | ||
109 | } | 120 | } |
110 | 121 | ||
111 | static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate, | 122 | static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate, |
@@ -118,7 +129,7 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate, | |||
118 | 129 | ||
119 | _nkm.max_n = 1 << nkm->n.width; | 130 | _nkm.max_n = 1 << nkm->n.width; |
120 | _nkm.max_k = 1 << nkm->k.width; | 131 | _nkm.max_k = 1 << nkm->k.width; |
121 | _nkm.max_m = 1 << nkm->m.width; | 132 | _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; |
122 | 133 | ||
123 | ccu_nkm_find_best(parent_rate, rate, &_nkm); | 134 | ccu_nkm_find_best(parent_rate, rate, &_nkm); |
124 | 135 | ||
@@ -142,12 +153,29 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate, | |||
142 | return 0; | 153 | return 0; |
143 | } | 154 | } |
144 | 155 | ||
156 | static u8 ccu_nkm_get_parent(struct clk_hw *hw) | ||
157 | { | ||
158 | struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); | ||
159 | |||
160 | return ccu_mux_helper_get_parent(&nkm->common, &nkm->mux); | ||
161 | } | ||
162 | |||
163 | static int ccu_nkm_set_parent(struct clk_hw *hw, u8 index) | ||
164 | { | ||
165 | struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); | ||
166 | |||
167 | return ccu_mux_helper_set_parent(&nkm->common, &nkm->mux, index); | ||
168 | } | ||
169 | |||
145 | const struct clk_ops ccu_nkm_ops = { | 170 | const struct clk_ops ccu_nkm_ops = { |
146 | .disable = ccu_nkm_disable, | 171 | .disable = ccu_nkm_disable, |
147 | .enable = ccu_nkm_enable, | 172 | .enable = ccu_nkm_enable, |
148 | .is_enabled = ccu_nkm_is_enabled, | 173 | .is_enabled = ccu_nkm_is_enabled, |
149 | 174 | ||
175 | .get_parent = ccu_nkm_get_parent, | ||
176 | .set_parent = ccu_nkm_set_parent, | ||
177 | |||
178 | .determine_rate = ccu_nkm_determine_rate, | ||
150 | .recalc_rate = ccu_nkm_recalc_rate, | 179 | .recalc_rate = ccu_nkm_recalc_rate, |
151 | .round_rate = ccu_nkm_round_rate, | ||
152 | .set_rate = ccu_nkm_set_rate, | 180 | .set_rate = ccu_nkm_set_rate, |
153 | }; | 181 | }; |
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h index 1936ac1c6b37..35493fddd8ab 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.h +++ b/drivers/clk/sunxi-ng/ccu_nkm.h | |||
@@ -32,10 +32,33 @@ struct ccu_nkm { | |||
32 | struct _ccu_mult n; | 32 | struct _ccu_mult n; |
33 | struct _ccu_mult k; | 33 | struct _ccu_mult k; |
34 | struct _ccu_div m; | 34 | struct _ccu_div m; |
35 | struct ccu_mux_internal mux; | ||
35 | 36 | ||
36 | struct ccu_common common; | 37 | struct ccu_common common; |
37 | }; | 38 | }; |
38 | 39 | ||
40 | #define SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(_struct, _name, _parents, _reg, \ | ||
41 | _nshift, _nwidth, \ | ||
42 | _kshift, _kwidth, \ | ||
43 | _mshift, _mwidth, \ | ||
44 | _muxshift, _muxwidth, \ | ||
45 | _gate, _lock, _flags) \ | ||
46 | struct ccu_nkm _struct = { \ | ||
47 | .enable = _gate, \ | ||
48 | .lock = _lock, \ | ||
49 | .k = _SUNXI_CCU_MULT(_kshift, _kwidth), \ | ||
50 | .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ | ||
51 | .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ | ||
52 | .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ | ||
53 | .common = { \ | ||
54 | .reg = _reg, \ | ||
55 | .hw.init = CLK_HW_INIT_PARENTS(_name, \ | ||
56 | _parents, \ | ||
57 | &ccu_nkm_ops, \ | ||
58 | _flags), \ | ||
59 | }, \ | ||
60 | } | ||
61 | |||
39 | #define SUNXI_CCU_NKM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ | 62 | #define SUNXI_CCU_NKM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ |
40 | _nshift, _nwidth, \ | 63 | _nshift, _nwidth, \ |
41 | _kshift, _kwidth, \ | 64 | _kshift, _kwidth, \ |
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index 9f2b98e19dc9..9769dee99511 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c | |||
@@ -29,14 +29,14 @@ static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate, | |||
29 | unsigned long _n, _k, _m, _p; | 29 | unsigned long _n, _k, _m, _p; |
30 | 30 | ||
31 | for (_k = 1; _k <= nkmp->max_k; _k++) { | 31 | for (_k = 1; _k <= nkmp->max_k; _k++) { |
32 | for (_p = 0; _p <= nkmp->max_p; _p++) { | 32 | for (_p = 1; _p <= nkmp->max_p; _p <<= 1) { |
33 | unsigned long tmp_rate; | 33 | unsigned long tmp_rate; |
34 | 34 | ||
35 | rational_best_approximation(rate / _k, parent >> _p, | 35 | rational_best_approximation(rate / _k, parent / _p, |
36 | nkmp->max_n, nkmp->max_m, | 36 | nkmp->max_n, nkmp->max_m, |
37 | &_n, &_m); | 37 | &_n, &_m); |
38 | 38 | ||
39 | tmp_rate = (parent * _n * _k >> _p) / _m; | 39 | tmp_rate = parent * _n * _k / (_m * _p); |
40 | 40 | ||
41 | if (tmp_rate > rate) | 41 | if (tmp_rate > rate) |
42 | continue; | 42 | continue; |
@@ -110,13 +110,12 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, | |||
110 | 110 | ||
111 | _nkmp.max_n = 1 << nkmp->n.width; | 111 | _nkmp.max_n = 1 << nkmp->n.width; |
112 | _nkmp.max_k = 1 << nkmp->k.width; | 112 | _nkmp.max_k = 1 << nkmp->k.width; |
113 | _nkmp.max_m = 1 << nkmp->m.width; | 113 | _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width; |
114 | _nkmp.max_p = (1 << nkmp->p.width) - 1; | 114 | _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); |
115 | 115 | ||
116 | ccu_nkmp_find_best(*parent_rate, rate, | 116 | ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); |
117 | &_nkmp); | ||
118 | 117 | ||
119 | return (*parent_rate * _nkmp.n * _nkmp.k >> _nkmp.p) / _nkmp.m; | 118 | return *parent_rate * _nkmp.n * _nkmp.k / (_nkmp.m * _nkmp.p); |
120 | } | 119 | } |
121 | 120 | ||
122 | static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, | 121 | static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, |
@@ -129,8 +128,8 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, | |||
129 | 128 | ||
130 | _nkmp.max_n = 1 << nkmp->n.width; | 129 | _nkmp.max_n = 1 << nkmp->n.width; |
131 | _nkmp.max_k = 1 << nkmp->k.width; | 130 | _nkmp.max_k = 1 << nkmp->k.width; |
132 | _nkmp.max_m = 1 << nkmp->m.width; | 131 | _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width; |
133 | _nkmp.max_p = (1 << nkmp->p.width) - 1; | 132 | _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); |
134 | 133 | ||
135 | ccu_nkmp_find_best(parent_rate, rate, &_nkmp); | 134 | ccu_nkmp_find_best(parent_rate, rate, &_nkmp); |
136 | 135 | ||
@@ -145,7 +144,7 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, | |||
145 | reg |= (_nkmp.n - 1) << nkmp->n.shift; | 144 | reg |= (_nkmp.n - 1) << nkmp->n.shift; |
146 | reg |= (_nkmp.k - 1) << nkmp->k.shift; | 145 | reg |= (_nkmp.k - 1) << nkmp->k.shift; |
147 | reg |= (_nkmp.m - 1) << nkmp->m.shift; | 146 | reg |= (_nkmp.m - 1) << nkmp->m.shift; |
148 | reg |= _nkmp.p << nkmp->p.shift; | 147 | reg |= ilog2(_nkmp.p) << nkmp->p.shift; |
149 | 148 | ||
150 | writel(reg, nkmp->common.base + nkmp->common.reg); | 149 | writel(reg, nkmp->common.base + nkmp->common.reg); |
151 | 150 | ||
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index e35ddd8eec8b..b61bdd8c7a7f 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c | |||
@@ -61,11 +61,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, | |||
61 | unsigned long *parent_rate) | 61 | unsigned long *parent_rate) |
62 | { | 62 | { |
63 | struct ccu_nm *nm = hw_to_ccu_nm(hw); | 63 | struct ccu_nm *nm = hw_to_ccu_nm(hw); |
64 | unsigned long max_n, max_m; | ||
64 | unsigned long n, m; | 65 | unsigned long n, m; |
65 | 66 | ||
66 | rational_best_approximation(rate, *parent_rate, | 67 | max_n = 1 << nm->n.width; |
67 | 1 << nm->n.width, 1 << nm->m.width, | 68 | max_m = nm->m.max ?: 1 << nm->m.width; |
68 | &n, &m); | 69 | |
70 | rational_best_approximation(rate, *parent_rate, max_n, max_m, &n, &m); | ||
69 | 71 | ||
70 | return *parent_rate * n / m; | 72 | return *parent_rate * n / m; |
71 | } | 73 | } |
@@ -75,6 +77,7 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate, | |||
75 | { | 77 | { |
76 | struct ccu_nm *nm = hw_to_ccu_nm(hw); | 78 | struct ccu_nm *nm = hw_to_ccu_nm(hw); |
77 | unsigned long flags; | 79 | unsigned long flags; |
80 | unsigned long max_n, max_m; | ||
78 | unsigned long n, m; | 81 | unsigned long n, m; |
79 | u32 reg; | 82 | u32 reg; |
80 | 83 | ||
@@ -83,9 +86,10 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate, | |||
83 | else | 86 | else |
84 | ccu_frac_helper_disable(&nm->common, &nm->frac); | 87 | ccu_frac_helper_disable(&nm->common, &nm->frac); |
85 | 88 | ||
86 | rational_best_approximation(rate, parent_rate, | 89 | max_n = 1 << nm->n.width; |
87 | 1 << nm->n.width, 1 << nm->m.width, | 90 | max_m = nm->m.max ?: 1 << nm->m.width; |
88 | &n, &m); | 91 | |
92 | rational_best_approximation(rate, parent_rate, max_n, max_m, &n, &m); | ||
89 | 93 | ||
90 | spin_lock_irqsave(nm->common.lock, flags); | 94 | spin_lock_irqsave(nm->common.lock, flags); |
91 | 95 | ||
diff --git a/include/dt-bindings/clock/sun6i-a31-ccu.h b/include/dt-bindings/clock/sun6i-a31-ccu.h new file mode 100644 index 000000000000..4482530fb6f5 --- /dev/null +++ b/include/dt-bindings/clock/sun6i-a31-ccu.h | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org> | ||
3 | * | ||
4 | * This file is dual-licensed: you can use it either under the terms | ||
5 | * of the GPL or the X11 license, at your option. Note that this dual | ||
6 | * licensing only applies to this file, and not this project as a | ||
7 | * whole. | ||
8 | * | ||
9 | * a) This file is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of the | ||
12 | * License, or (at your option) any later version. | ||
13 | * | ||
14 | * This file is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * Or, alternatively, | ||
20 | * | ||
21 | * b) Permission is hereby granted, free of charge, to any person | ||
22 | * obtaining a copy of this software and associated documentation | ||
23 | * files (the "Software"), to deal in the Software without | ||
24 | * restriction, including without limitation the rights to use, | ||
25 | * copy, modify, merge, publish, distribute, sublicense, and/or | ||
26 | * sell copies of the Software, and to permit persons to whom the | ||
27 | * Software is furnished to do so, subject to the following | ||
28 | * conditions: | ||
29 | * | ||
30 | * The above copyright notice and this permission notice shall be | ||
31 | * included in all copies or substantial portions of the Software. | ||
32 | * | ||
33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
34 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
35 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
36 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
37 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
38 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
39 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
40 | * OTHER DEALINGS IN THE SOFTWARE. | ||
41 | */ | ||
42 | |||
43 | #ifndef _DT_BINDINGS_CLK_SUN6I_A31_H_ | ||
44 | #define _DT_BINDINGS_CLK_SUN6I_A31_H_ | ||
45 | |||
46 | #define CLK_PLL_PERIPH 10 | ||
47 | |||
48 | #define CLK_CPU 18 | ||
49 | |||
50 | #define CLK_AHB1_MIPIDSI 23 | ||
51 | #define CLK_AHB1_SS 24 | ||
52 | #define CLK_AHB1_DMA 25 | ||
53 | #define CLK_AHB1_MMC0 26 | ||
54 | #define CLK_AHB1_MMC1 27 | ||
55 | #define CLK_AHB1_MMC2 28 | ||
56 | #define CLK_AHB1_MMC3 29 | ||
57 | #define CLK_AHB1_NAND1 30 | ||
58 | #define CLK_AHB1_NAND0 31 | ||
59 | #define CLK_AHB1_SDRAM 32 | ||
60 | #define CLK_AHB1_EMAC 33 | ||
61 | #define CLK_AHB1_TS 34 | ||
62 | #define CLK_AHB1_HSTIMER 35 | ||
63 | #define CLK_AHB1_SPI0 36 | ||
64 | #define CLK_AHB1_SPI1 37 | ||
65 | #define CLK_AHB1_SPI2 38 | ||
66 | #define CLK_AHB1_SPI3 39 | ||
67 | #define CLK_AHB1_OTG 40 | ||
68 | #define CLK_AHB1_EHCI0 41 | ||
69 | #define CLK_AHB1_EHCI1 42 | ||
70 | #define CLK_AHB1_OHCI0 43 | ||
71 | #define CLK_AHB1_OHCI1 44 | ||
72 | #define CLK_AHB1_OHCI2 45 | ||
73 | #define CLK_AHB1_VE 46 | ||
74 | #define CLK_AHB1_LCD0 47 | ||
75 | #define CLK_AHB1_LCD1 48 | ||
76 | #define CLK_AHB1_CSI 49 | ||
77 | #define CLK_AHB1_HDMI 50 | ||
78 | #define CLK_AHB1_BE0 51 | ||
79 | #define CLK_AHB1_BE1 52 | ||
80 | #define CLK_AHB1_FE0 53 | ||
81 | #define CLK_AHB1_FE1 54 | ||
82 | #define CLK_AHB1_MP 55 | ||
83 | #define CLK_AHB1_GPU 56 | ||
84 | #define CLK_AHB1_DEU0 57 | ||
85 | #define CLK_AHB1_DEU1 58 | ||
86 | #define CLK_AHB1_DRC0 59 | ||
87 | #define CLK_AHB1_DRC1 60 | ||
88 | |||
89 | #define CLK_APB1_CODEC 61 | ||
90 | #define CLK_APB1_SPDIF 62 | ||
91 | #define CLK_APB1_DIGITAL_MIC 63 | ||
92 | #define CLK_APB1_PIO 64 | ||
93 | #define CLK_APB1_DAUDIO0 65 | ||
94 | #define CLK_APB1_DAUDIO1 66 | ||
95 | |||
96 | #define CLK_APB2_I2C0 67 | ||
97 | #define CLK_APB2_I2C1 68 | ||
98 | #define CLK_APB2_I2C2 69 | ||
99 | #define CLK_APB2_I2C3 70 | ||
100 | #define CLK_APB2_UART0 71 | ||
101 | #define CLK_APB2_UART1 72 | ||
102 | #define CLK_APB2_UART2 73 | ||
103 | #define CLK_APB2_UART3 74 | ||
104 | #define CLK_APB2_UART4 75 | ||
105 | #define CLK_APB2_UART5 76 | ||
106 | |||
107 | #define CLK_NAND0 77 | ||
108 | #define CLK_NAND1 78 | ||
109 | #define CLK_MMC0 79 | ||
110 | #define CLK_MMC0_SAMPLE 80 | ||
111 | #define CLK_MMC0_OUTPUT 81 | ||
112 | #define CLK_MMC1 82 | ||
113 | #define CLK_MMC1_SAMPLE 83 | ||
114 | #define CLK_MMC1_OUTPUT 84 | ||
115 | #define CLK_MMC2 85 | ||
116 | #define CLK_MMC2_SAMPLE 86 | ||
117 | #define CLK_MMC2_OUTPUT 87 | ||
118 | #define CLK_MMC3 88 | ||
119 | #define CLK_MMC3_SAMPLE 89 | ||
120 | #define CLK_MMC3_OUTPUT 90 | ||
121 | #define CLK_TS 91 | ||
122 | #define CLK_SS 92 | ||
123 | #define CLK_SPI0 93 | ||
124 | #define CLK_SPI1 94 | ||
125 | #define CLK_SPI2 95 | ||
126 | #define CLK_SPI3 96 | ||
127 | #define CLK_DAUDIO0 97 | ||
128 | #define CLK_DAUDIO1 98 | ||
129 | #define CLK_SPDIF 99 | ||
130 | #define CLK_USB_PHY0 100 | ||
131 | #define CLK_USB_PHY1 101 | ||
132 | #define CLK_USB_PHY2 102 | ||
133 | #define CLK_USB_OHCI0 103 | ||
134 | #define CLK_USB_OHCI1 104 | ||
135 | #define CLK_USB_OHCI2 105 | ||
136 | |||
137 | #define CLK_DRAM_VE 110 | ||
138 | #define CLK_DRAM_CSI_ISP 111 | ||
139 | #define CLK_DRAM_TS 112 | ||
140 | #define CLK_DRAM_DRC0 113 | ||
141 | #define CLK_DRAM_DRC1 114 | ||
142 | #define CLK_DRAM_DEU0 115 | ||
143 | #define CLK_DRAM_DEU1 116 | ||
144 | #define CLK_DRAM_FE0 117 | ||
145 | #define CLK_DRAM_FE1 118 | ||
146 | #define CLK_DRAM_BE0 119 | ||
147 | #define CLK_DRAM_BE1 120 | ||
148 | #define CLK_DRAM_MP 121 | ||
149 | |||
150 | #define CLK_BE0 122 | ||
151 | #define CLK_BE1 123 | ||
152 | #define CLK_FE0 124 | ||
153 | #define CLK_FE1 125 | ||
154 | #define CLK_MP 126 | ||
155 | #define CLK_LCD0_CH0 127 | ||
156 | #define CLK_LCD1_CH0 128 | ||
157 | #define CLK_LCD0_CH1 129 | ||
158 | #define CLK_LCD1_CH1 130 | ||
159 | #define CLK_CSI0_SCLK 131 | ||
160 | #define CLK_CSI0_MCLK 132 | ||
161 | #define CLK_CSI1_MCLK 133 | ||
162 | #define CLK_VE 134 | ||
163 | #define CLK_CODEC 135 | ||
164 | #define CLK_AVS 136 | ||
165 | #define CLK_DIGITAL_MIC 137 | ||
166 | #define CLK_HDMI 138 | ||
167 | #define CLK_HDMI_DDC 139 | ||
168 | #define CLK_PS 140 | ||
169 | |||
170 | #define CLK_MIPI_DSI 143 | ||
171 | #define CLK_MIPI_DSI_DPHY 144 | ||
172 | #define CLK_MIPI_CSI_DPHY 145 | ||
173 | #define CLK_IEP_DRC0 146 | ||
174 | #define CLK_IEP_DRC1 147 | ||
175 | #define CLK_IEP_DEU0 148 | ||
176 | #define CLK_IEP_DEU1 149 | ||
177 | #define CLK_GPU_CORE 150 | ||
178 | #define CLK_GPU_MEMORY 151 | ||
179 | #define CLK_GPU_HYD 152 | ||
180 | #define CLK_ATS 153 | ||
181 | #define CLK_TRACE 154 | ||
182 | |||
183 | #define CLK_OUT_A 155 | ||
184 | #define CLK_OUT_B 156 | ||
185 | #define CLK_OUT_C 157 | ||
186 | |||
187 | #endif /* _DT_BINDINGS_CLK_SUN6I_A31_H_ */ | ||
diff --git a/include/dt-bindings/clock/sun8i-a23-a33-ccu.h b/include/dt-bindings/clock/sun8i-a23-a33-ccu.h new file mode 100644 index 000000000000..f8222b6b2cc3 --- /dev/null +++ b/include/dt-bindings/clock/sun8i-a23-a33-ccu.h | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com> | ||
3 | * | ||
4 | * This file is dual-licensed: you can use it either under the terms | ||
5 | * of the GPL or the X11 license, at your option. Note that this dual | ||
6 | * licensing only applies to this file, and not this project as a | ||
7 | * whole. | ||
8 | * | ||
9 | * a) This file is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of the | ||
12 | * License, or (at your option) any later version. | ||
13 | * | ||
14 | * This file is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * Or, alternatively, | ||
20 | * | ||
21 | * b) Permission is hereby granted, free of charge, to any person | ||
22 | * obtaining a copy of this software and associated documentation | ||
23 | * files (the "Software"), to deal in the Software without | ||
24 | * restriction, including without limitation the rights to use, | ||
25 | * copy, modify, merge, publish, distribute, sublicense, and/or | ||
26 | * sell copies of the Software, and to permit persons to whom the | ||
27 | * Software is furnished to do so, subject to the following | ||
28 | * conditions: | ||
29 | * | ||
30 | * The above copyright notice and this permission notice shall be | ||
31 | * included in all copies or substantial portions of the Software. | ||
32 | * | ||
33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
34 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
35 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
36 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
37 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
38 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
39 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
40 | * OTHER DEALINGS IN THE SOFTWARE. | ||
41 | */ | ||
42 | |||
43 | #ifndef _DT_BINDINGS_CLK_SUN8I_A23_A33_H_ | ||
44 | #define _DT_BINDINGS_CLK_SUN8I_A23_A33_H_ | ||
45 | |||
46 | #define CLK_CPUX 18 | ||
47 | |||
48 | #define CLK_BUS_MIPI_DSI 23 | ||
49 | #define CLK_BUS_SS 24 | ||
50 | #define CLK_BUS_DMA 25 | ||
51 | #define CLK_BUS_MMC0 26 | ||
52 | #define CLK_BUS_MMC1 27 | ||
53 | #define CLK_BUS_MMC2 28 | ||
54 | #define CLK_BUS_NAND 29 | ||
55 | #define CLK_BUS_DRAM 30 | ||
56 | #define CLK_BUS_HSTIMER 31 | ||
57 | #define CLK_BUS_SPI0 32 | ||
58 | #define CLK_BUS_SPI1 33 | ||
59 | #define CLK_BUS_OTG 34 | ||
60 | #define CLK_BUS_EHCI 35 | ||
61 | #define CLK_BUS_OHCI 36 | ||
62 | #define CLK_BUS_VE 37 | ||
63 | #define CLK_BUS_LCD 38 | ||
64 | #define CLK_BUS_CSI 39 | ||
65 | #define CLK_BUS_DE_BE 40 | ||
66 | #define CLK_BUS_DE_FE 41 | ||
67 | #define CLK_BUS_GPU 42 | ||
68 | #define CLK_BUS_MSGBOX 43 | ||
69 | #define CLK_BUS_SPINLOCK 44 | ||
70 | #define CLK_BUS_DRC 45 | ||
71 | #define CLK_BUS_SAT 46 | ||
72 | #define CLK_BUS_CODEC 47 | ||
73 | #define CLK_BUS_PIO 48 | ||
74 | #define CLK_BUS_I2S0 49 | ||
75 | #define CLK_BUS_I2S1 50 | ||
76 | #define CLK_BUS_I2C0 51 | ||
77 | #define CLK_BUS_I2C1 52 | ||
78 | #define CLK_BUS_I2C2 53 | ||
79 | #define CLK_BUS_UART0 54 | ||
80 | #define CLK_BUS_UART1 55 | ||
81 | #define CLK_BUS_UART2 56 | ||
82 | #define CLK_BUS_UART3 57 | ||
83 | #define CLK_BUS_UART4 58 | ||
84 | #define CLK_NAND 59 | ||
85 | #define CLK_MMC0 60 | ||
86 | #define CLK_MMC0_SAMPLE 61 | ||
87 | #define CLK_MMC0_OUTPUT 62 | ||
88 | #define CLK_MMC1 63 | ||
89 | #define CLK_MMC1_SAMPLE 64 | ||
90 | #define CLK_MMC1_OUTPUT 65 | ||
91 | #define CLK_MMC2 66 | ||
92 | #define CLK_MMC2_SAMPLE 67 | ||
93 | #define CLK_MMC2_OUTPUT 68 | ||
94 | #define CLK_SS 69 | ||
95 | #define CLK_SPI0 70 | ||
96 | #define CLK_SPI1 71 | ||
97 | #define CLK_I2S0 72 | ||
98 | #define CLK_I2S1 73 | ||
99 | #define CLK_USB_PHY0 74 | ||
100 | #define CLK_USB_PHY1 75 | ||
101 | #define CLK_USB_HSIC 76 | ||
102 | #define CLK_USB_HSIC_12M 77 | ||
103 | #define CLK_USB_OHCI 78 | ||
104 | |||
105 | #define CLK_DRAM_VE 80 | ||
106 | #define CLK_DRAM_CSI 81 | ||
107 | #define CLK_DRAM_DRC 82 | ||
108 | #define CLK_DRAM_DE_FE 83 | ||
109 | #define CLK_DRAM_DE_BE 84 | ||
110 | #define CLK_DE_BE 85 | ||
111 | #define CLK_DE_FE 86 | ||
112 | #define CLK_LCD_CH0 87 | ||
113 | #define CLK_LCD_CH1 88 | ||
114 | #define CLK_CSI_SCLK 89 | ||
115 | #define CLK_CSI_MCLK 90 | ||
116 | #define CLK_VE 91 | ||
117 | #define CLK_AC_DIG 92 | ||
118 | #define CLK_AC_DIG_4X 93 | ||
119 | #define CLK_AVS 94 | ||
120 | |||
121 | #define CLK_DSI_SCLK 96 | ||
122 | #define CLK_DSI_DPHY 97 | ||
123 | #define CLK_DRC 98 | ||
124 | #define CLK_GPU 99 | ||
125 | #define CLK_ATS 100 | ||
126 | |||
127 | #endif /* _DT_BINDINGS_CLK_SUN8I_A23_A33_H_ */ | ||
diff --git a/include/dt-bindings/reset/sun6i-a31-ccu.h b/include/dt-bindings/reset/sun6i-a31-ccu.h new file mode 100644 index 000000000000..fbff365ed6e1 --- /dev/null +++ b/include/dt-bindings/reset/sun6i-a31-ccu.h | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org> | ||
3 | * | ||
4 | * This file is dual-licensed: you can use it either under the terms | ||
5 | * of the GPL or the X11 license, at your option. Note that this dual | ||
6 | * licensing only applies to this file, and not this project as a | ||
7 | * whole. | ||
8 | * | ||
9 | * a) This file is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of the | ||
12 | * License, or (at your option) any later version. | ||
13 | * | ||
14 | * This file is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * Or, alternatively, | ||
20 | * | ||
21 | * b) Permission is hereby granted, free of charge, to any person | ||
22 | * obtaining a copy of this software and associated documentation | ||
23 | * files (the "Software"), to deal in the Software without | ||
24 | * restriction, including without limitation the rights to use, | ||
25 | * copy, modify, merge, publish, distribute, sublicense, and/or | ||
26 | * sell copies of the Software, and to permit persons to whom the | ||
27 | * Software is furnished to do so, subject to the following | ||
28 | * conditions: | ||
29 | * | ||
30 | * The above copyright notice and this permission notice shall be | ||
31 | * included in all copies or substantial portions of the Software. | ||
32 | * | ||
33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
34 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
35 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
36 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
37 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
38 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
39 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
40 | * OTHER DEALINGS IN THE SOFTWARE. | ||
41 | */ | ||
42 | |||
43 | #ifndef _DT_BINDINGS_RST_SUN6I_A31_H_ | ||
44 | #define _DT_BINDINGS_RST_SUN6I_A31_H_ | ||
45 | |||
46 | #define RST_USB_PHY0 0 | ||
47 | #define RST_USB_PHY1 1 | ||
48 | #define RST_USB_PHY2 2 | ||
49 | |||
50 | #define RST_AHB1_MIPI_DSI 3 | ||
51 | #define RST_AHB1_SS 4 | ||
52 | #define RST_AHB1_DMA 5 | ||
53 | #define RST_AHB1_MMC0 6 | ||
54 | #define RST_AHB1_MMC1 7 | ||
55 | #define RST_AHB1_MMC2 8 | ||
56 | #define RST_AHB1_MMC3 9 | ||
57 | #define RST_AHB1_NAND1 10 | ||
58 | #define RST_AHB1_NAND0 11 | ||
59 | #define RST_AHB1_SDRAM 12 | ||
60 | #define RST_AHB1_EMAC 13 | ||
61 | #define RST_AHB1_TS 14 | ||
62 | #define RST_AHB1_HSTIMER 15 | ||
63 | #define RST_AHB1_SPI0 16 | ||
64 | #define RST_AHB1_SPI1 17 | ||
65 | #define RST_AHB1_SPI2 18 | ||
66 | #define RST_AHB1_SPI3 19 | ||
67 | #define RST_AHB1_OTG 20 | ||
68 | #define RST_AHB1_EHCI0 21 | ||
69 | #define RST_AHB1_EHCI1 22 | ||
70 | #define RST_AHB1_OHCI0 23 | ||
71 | #define RST_AHB1_OHCI1 24 | ||
72 | #define RST_AHB1_OHCI2 25 | ||
73 | #define RST_AHB1_VE 26 | ||
74 | #define RST_AHB1_LCD0 27 | ||
75 | #define RST_AHB1_LCD1 28 | ||
76 | #define RST_AHB1_CSI 29 | ||
77 | #define RST_AHB1_HDMI 30 | ||
78 | #define RST_AHB1_BE0 31 | ||
79 | #define RST_AHB1_BE1 32 | ||
80 | #define RST_AHB1_FE0 33 | ||
81 | #define RST_AHB1_FE1 34 | ||
82 | #define RST_AHB1_MP 35 | ||
83 | #define RST_AHB1_GPU 36 | ||
84 | #define RST_AHB1_DEU0 37 | ||
85 | #define RST_AHB1_DEU1 38 | ||
86 | #define RST_AHB1_DRC0 39 | ||
87 | #define RST_AHB1_DRC1 40 | ||
88 | #define RST_AHB1_LVDS 41 | ||
89 | |||
90 | #define RST_APB1_CODEC 42 | ||
91 | #define RST_APB1_SPDIF 43 | ||
92 | #define RST_APB1_DIGITAL_MIC 44 | ||
93 | #define RST_APB1_DAUDIO0 45 | ||
94 | #define RST_APB1_DAUDIO1 46 | ||
95 | #define RST_APB2_I2C0 47 | ||
96 | #define RST_APB2_I2C1 48 | ||
97 | #define RST_APB2_I2C2 49 | ||
98 | #define RST_APB2_I2C3 50 | ||
99 | #define RST_APB2_UART0 51 | ||
100 | #define RST_APB2_UART1 52 | ||
101 | #define RST_APB2_UART2 53 | ||
102 | #define RST_APB2_UART3 54 | ||
103 | #define RST_APB2_UART4 55 | ||
104 | #define RST_APB2_UART5 56 | ||
105 | |||
106 | #endif /* _DT_BINDINGS_RST_SUN6I_A31_H_ */ | ||
diff --git a/include/dt-bindings/reset/sun8i-a23-a33-ccu.h b/include/dt-bindings/reset/sun8i-a23-a33-ccu.h new file mode 100644 index 000000000000..6121f2b0cd0a --- /dev/null +++ b/include/dt-bindings/reset/sun8i-a23-a33-ccu.h | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com> | ||
3 | * | ||
4 | * This file is dual-licensed: you can use it either under the terms | ||
5 | * of the GPL or the X11 license, at your option. Note that this dual | ||
6 | * licensing only applies to this file, and not this project as a | ||
7 | * whole. | ||
8 | * | ||
9 | * a) This file is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of the | ||
12 | * License, or (at your option) any later version. | ||
13 | * | ||
14 | * This file is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * Or, alternatively, | ||
20 | * | ||
21 | * b) Permission is hereby granted, free of charge, to any person | ||
22 | * obtaining a copy of this software and associated documentation | ||
23 | * files (the "Software"), to deal in the Software without | ||
24 | * restriction, including without limitation the rights to use, | ||
25 | * copy, modify, merge, publish, distribute, sublicense, and/or | ||
26 | * sell copies of the Software, and to permit persons to whom the | ||
27 | * Software is furnished to do so, subject to the following | ||
28 | * conditions: | ||
29 | * | ||
30 | * The above copyright notice and this permission notice shall be | ||
31 | * included in all copies or substantial portions of the Software. | ||
32 | * | ||
33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
34 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
35 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
36 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
37 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
38 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
39 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
40 | * OTHER DEALINGS IN THE SOFTWARE. | ||
41 | */ | ||
42 | |||
43 | #ifndef _DT_BINDINGS_RST_SUN8I_A23_A33_H_ | ||
44 | #define _DT_BINDINGS_RST_SUN8I_A23_A33_H_ | ||
45 | |||
46 | #define RST_USB_PHY0 0 | ||
47 | #define RST_USB_PHY1 1 | ||
48 | #define RST_USB_HSIC 2 | ||
49 | #define RST_MBUS 3 | ||
50 | #define RST_BUS_MIPI_DSI 4 | ||
51 | #define RST_BUS_SS 5 | ||
52 | #define RST_BUS_DMA 6 | ||
53 | #define RST_BUS_MMC0 7 | ||
54 | #define RST_BUS_MMC1 8 | ||
55 | #define RST_BUS_MMC2 9 | ||
56 | #define RST_BUS_NAND 10 | ||
57 | #define RST_BUS_DRAM 11 | ||
58 | #define RST_BUS_HSTIMER 12 | ||
59 | #define RST_BUS_SPI0 13 | ||
60 | #define RST_BUS_SPI1 14 | ||
61 | #define RST_BUS_OTG 15 | ||
62 | #define RST_BUS_EHCI 16 | ||
63 | #define RST_BUS_OHCI 17 | ||
64 | #define RST_BUS_VE 18 | ||
65 | #define RST_BUS_LCD 19 | ||
66 | #define RST_BUS_CSI 20 | ||
67 | #define RST_BUS_DE_BE 21 | ||
68 | #define RST_BUS_DE_FE 22 | ||
69 | #define RST_BUS_GPU 23 | ||
70 | #define RST_BUS_MSGBOX 24 | ||
71 | #define RST_BUS_SPINLOCK 25 | ||
72 | #define RST_BUS_DRC 26 | ||
73 | #define RST_BUS_SAT 27 | ||
74 | #define RST_BUS_LVDS 28 | ||
75 | #define RST_BUS_CODEC 29 | ||
76 | #define RST_BUS_I2S0 30 | ||
77 | #define RST_BUS_I2S1 31 | ||
78 | #define RST_BUS_I2C0 32 | ||
79 | #define RST_BUS_I2C1 33 | ||
80 | #define RST_BUS_I2C2 34 | ||
81 | #define RST_BUS_UART0 35 | ||
82 | #define RST_BUS_UART1 36 | ||
83 | #define RST_BUS_UART2 37 | ||
84 | #define RST_BUS_UART3 38 | ||
85 | #define RST_BUS_UART4 39 | ||
86 | |||
87 | #endif /* _DT_BINDINGS_RST_SUN8I_A23_A33_H_ */ | ||