1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Clock definitions for u8500 platform. |
4 | * |
5 | * Copyright (C) 2012 ST-Ericsson SA |
6 | * Author: Ulf Hansson <ulf.hansson@linaro.org> |
7 | */ |
8 | |
9 | #include <linux/of.h> |
10 | #include <linux/of_address.h> |
11 | #include <linux/clk-provider.h> |
12 | #include <linux/mfd/dbx500-prcmu.h> |
13 | |
14 | #include "clk.h" |
15 | #include "prcc.h" |
16 | #include "reset-prcc.h" |
17 | |
18 | static struct clk *prcc_pclk[(PRCC_NUM_PERIPH_CLUSTERS + 1) * PRCC_PERIPHS_PER_CLUSTER]; |
19 | static struct clk *prcc_kclk[(PRCC_NUM_PERIPH_CLUSTERS + 1) * PRCC_PERIPHS_PER_CLUSTER]; |
20 | static struct clk_hw *clkout_clk[2]; |
21 | |
22 | #define PRCC_SHOW(clk, base, bit) \ |
23 | clk[(base * PRCC_PERIPHS_PER_CLUSTER) + bit] |
24 | #define PRCC_PCLK_STORE(clk, base, bit) \ |
25 | prcc_pclk[(base * PRCC_PERIPHS_PER_CLUSTER) + bit] = clk |
26 | #define PRCC_KCLK_STORE(clk, base, bit) \ |
27 | prcc_kclk[(base * PRCC_PERIPHS_PER_CLUSTER) + bit] = clk |
28 | |
29 | static struct clk *ux500_twocell_get(struct of_phandle_args *clkspec, |
30 | void *data) |
31 | { |
32 | struct clk **clk_data = data; |
33 | unsigned int base, bit; |
34 | |
35 | if (clkspec->args_count != 2) |
36 | return ERR_PTR(error: -EINVAL); |
37 | |
38 | base = clkspec->args[0]; |
39 | bit = clkspec->args[1]; |
40 | |
41 | if (base != 1 && base != 2 && base != 3 && base != 5 && base != 6) { |
42 | pr_err("%s: invalid PRCC base %d\n" , __func__, base); |
43 | return ERR_PTR(error: -EINVAL); |
44 | } |
45 | |
46 | return PRCC_SHOW(clk_data, base, bit); |
47 | } |
48 | |
49 | static struct clk_hw_onecell_data u8500_prcmu_hw_clks = { |
50 | .hws = { |
51 | /* |
52 | * This assignment makes sure the dynamic array |
53 | * gets the right size. |
54 | */ |
55 | [PRCMU_NUM_CLKS] = NULL, |
56 | }, |
57 | .num = PRCMU_NUM_CLKS, |
58 | }; |
59 | |
60 | /* Essentially names for the first PRCMU_CLKSRC_* defines */ |
61 | static const char * const u8500_clkout_parents[] = { |
62 | "clk38m_to_clkgen" , |
63 | "aclk" , |
64 | /* Just called "sysclk" in documentation */ |
65 | "ab8500_sysclk" , |
66 | "lcdclk" , |
67 | "sdmmcclk" , |
68 | "tvclk" , |
69 | "timclk" , |
70 | /* CLK009 is not implemented, add it if you need it */ |
71 | "clk009" , |
72 | }; |
73 | |
74 | static struct clk_hw *ux500_clkout_get(struct of_phandle_args *clkspec, |
75 | void *data) |
76 | { |
77 | u32 id, source, divider; |
78 | struct clk_hw *clkout; |
79 | |
80 | if (clkspec->args_count != 3) |
81 | return ERR_PTR(error: -EINVAL); |
82 | |
83 | id = clkspec->args[0]; |
84 | source = clkspec->args[1]; |
85 | divider = clkspec->args[2]; |
86 | |
87 | if (id > 1) { |
88 | pr_err("%s: invalid clkout ID %d\n" , __func__, id); |
89 | return ERR_PTR(error: -EINVAL); |
90 | } |
91 | |
92 | if (clkout_clk[id]) { |
93 | pr_info("%s: clkout%d already registered, not reconfiguring\n" , |
94 | __func__, id + 1); |
95 | return clkout_clk[id]; |
96 | } |
97 | |
98 | if (source > 7) { |
99 | pr_err("%s: invalid source ID %d\n" , __func__, source); |
100 | return ERR_PTR(error: -EINVAL); |
101 | } |
102 | |
103 | if (divider == 0 || divider > 63) { |
104 | pr_err("%s: invalid divider %d\n" , __func__, divider); |
105 | return ERR_PTR(error: -EINVAL); |
106 | } |
107 | |
108 | pr_debug("registering clkout%d with source %d and divider %d\n" , |
109 | id + 1, source, divider); |
110 | |
111 | clkout = clk_reg_prcmu_clkout(name: id ? "clkout2" : "clkout1" , |
112 | parent_names: u8500_clkout_parents, |
113 | ARRAY_SIZE(u8500_clkout_parents), |
114 | source, divider); |
115 | if (IS_ERR(ptr: clkout)) { |
116 | pr_err("failed to register clkout%d\n" , id + 1); |
117 | return ERR_CAST(ptr: clkout); |
118 | } |
119 | |
120 | clkout_clk[id] = clkout; |
121 | |
122 | return clkout; |
123 | } |
124 | |
125 | static void u8500_clk_init(struct device_node *np) |
126 | { |
127 | struct prcmu_fw_version *fw_version; |
128 | struct device_node *child = NULL; |
129 | const char *sgaclk_parent = NULL; |
130 | struct clk *clk, *rtc_clk, *twd_clk; |
131 | u32 bases[CLKRST_MAX]; |
132 | struct u8500_prcc_reset *rstc; |
133 | int i; |
134 | |
135 | /* |
136 | * We allocate the reset controller here so that we can fill in the |
137 | * base addresses properly and pass to the reset controller init |
138 | * function later on. |
139 | */ |
140 | rstc = kzalloc(size: sizeof(*rstc), GFP_KERNEL); |
141 | if (!rstc) |
142 | return; |
143 | |
144 | for (i = 0; i < ARRAY_SIZE(bases); i++) { |
145 | struct resource r; |
146 | |
147 | if (of_address_to_resource(dev: np, index: i, r: &r)) |
148 | /* Not much choice but to continue */ |
149 | pr_err("failed to get CLKRST %d base address\n" , |
150 | i + 1); |
151 | bases[i] = r.start; |
152 | rstc->phy_base[i] = r.start; |
153 | } |
154 | |
155 | /* Clock sources */ |
156 | u8500_prcmu_hw_clks.hws[PRCMU_PLLSOC0] = |
157 | clk_reg_prcmu_gate(name: "soc0_pll" , NULL, PRCMU_PLLSOC0, |
158 | CLK_IGNORE_UNUSED); |
159 | |
160 | u8500_prcmu_hw_clks.hws[PRCMU_PLLSOC1] = |
161 | clk_reg_prcmu_gate(name: "soc1_pll" , NULL, PRCMU_PLLSOC1, |
162 | CLK_IGNORE_UNUSED); |
163 | |
164 | u8500_prcmu_hw_clks.hws[PRCMU_PLLDDR] = |
165 | clk_reg_prcmu_gate(name: "ddr_pll" , NULL, PRCMU_PLLDDR, |
166 | CLK_IGNORE_UNUSED); |
167 | |
168 | /* |
169 | * Read-only clocks that only return their current rate, only used |
170 | * as parents to other clocks and not visible in the device tree. |
171 | * clk38m_to_clkgen is the same as the SYSCLK, i.e. the root clock. |
172 | */ |
173 | clk_reg_prcmu_rate(name: "clk38m_to_clkgen" , NULL, PRCMU_SYSCLK, |
174 | CLK_IGNORE_UNUSED); |
175 | clk_reg_prcmu_rate(name: "aclk" , NULL, PRCMU_ACLK, |
176 | CLK_IGNORE_UNUSED); |
177 | |
178 | /* TODO: add CLK009 if needed */ |
179 | |
180 | rtc_clk = clk_register_fixed_rate(NULL, name: "rtc32k" , parent_name: "NULL" , |
181 | CLK_IGNORE_UNUSED, |
182 | fixed_rate: 32768); |
183 | |
184 | /* PRCMU clocks */ |
185 | fw_version = prcmu_get_fw_version(); |
186 | if (fw_version != NULL) { |
187 | switch (fw_version->project) { |
188 | case PRCMU_FW_PROJECT_U8500_C2: |
189 | case PRCMU_FW_PROJECT_U8500_SSG1: |
190 | case PRCMU_FW_PROJECT_U8520: |
191 | case PRCMU_FW_PROJECT_U8420: |
192 | case PRCMU_FW_PROJECT_U8420_SYSCLK: |
193 | case PRCMU_FW_PROJECT_U8500_SSG2: |
194 | sgaclk_parent = "soc0_pll" ; |
195 | break; |
196 | default: |
197 | break; |
198 | } |
199 | } |
200 | |
201 | if (sgaclk_parent) |
202 | u8500_prcmu_hw_clks.hws[PRCMU_SGACLK] = |
203 | clk_reg_prcmu_gate(name: "sgclk" , parent_name: sgaclk_parent, |
204 | PRCMU_SGACLK, flags: 0); |
205 | else |
206 | u8500_prcmu_hw_clks.hws[PRCMU_SGACLK] = |
207 | clk_reg_prcmu_gate(name: "sgclk" , NULL, PRCMU_SGACLK, flags: 0); |
208 | |
209 | u8500_prcmu_hw_clks.hws[PRCMU_UARTCLK] = |
210 | clk_reg_prcmu_gate(name: "uartclk" , NULL, PRCMU_UARTCLK, flags: 0); |
211 | u8500_prcmu_hw_clks.hws[PRCMU_MSP02CLK] = |
212 | clk_reg_prcmu_gate(name: "msp02clk" , NULL, PRCMU_MSP02CLK, flags: 0); |
213 | u8500_prcmu_hw_clks.hws[PRCMU_MSP1CLK] = |
214 | clk_reg_prcmu_gate(name: "msp1clk" , NULL, PRCMU_MSP1CLK, flags: 0); |
215 | u8500_prcmu_hw_clks.hws[PRCMU_I2CCLK] = |
216 | clk_reg_prcmu_gate(name: "i2cclk" , NULL, PRCMU_I2CCLK, flags: 0); |
217 | u8500_prcmu_hw_clks.hws[PRCMU_SLIMCLK] = |
218 | clk_reg_prcmu_gate(name: "slimclk" , NULL, PRCMU_SLIMCLK, flags: 0); |
219 | u8500_prcmu_hw_clks.hws[PRCMU_PER1CLK] = |
220 | clk_reg_prcmu_gate(name: "per1clk" , NULL, PRCMU_PER1CLK, flags: 0); |
221 | u8500_prcmu_hw_clks.hws[PRCMU_PER2CLK] = |
222 | clk_reg_prcmu_gate(name: "per2clk" , NULL, PRCMU_PER2CLK, flags: 0); |
223 | u8500_prcmu_hw_clks.hws[PRCMU_PER3CLK] = |
224 | clk_reg_prcmu_gate(name: "per3clk" , NULL, PRCMU_PER3CLK, flags: 0); |
225 | u8500_prcmu_hw_clks.hws[PRCMU_PER5CLK] = |
226 | clk_reg_prcmu_gate(name: "per5clk" , NULL, PRCMU_PER5CLK, flags: 0); |
227 | u8500_prcmu_hw_clks.hws[PRCMU_PER6CLK] = |
228 | clk_reg_prcmu_gate(name: "per6clk" , NULL, PRCMU_PER6CLK, flags: 0); |
229 | u8500_prcmu_hw_clks.hws[PRCMU_PER7CLK] = |
230 | clk_reg_prcmu_gate(name: "per7clk" , NULL, PRCMU_PER7CLK, flags: 0); |
231 | u8500_prcmu_hw_clks.hws[PRCMU_LCDCLK] = |
232 | clk_reg_prcmu_scalable(name: "lcdclk" , NULL, PRCMU_LCDCLK, rate: 0, |
233 | CLK_SET_RATE_GATE); |
234 | u8500_prcmu_hw_clks.hws[PRCMU_BMLCLK] = |
235 | clk_reg_prcmu_opp_gate(name: "bmlclk" , NULL, PRCMU_BMLCLK, flags: 0); |
236 | u8500_prcmu_hw_clks.hws[PRCMU_HSITXCLK] = |
237 | clk_reg_prcmu_scalable(name: "hsitxclk" , NULL, PRCMU_HSITXCLK, rate: 0, |
238 | CLK_SET_RATE_GATE); |
239 | u8500_prcmu_hw_clks.hws[PRCMU_HSIRXCLK] = |
240 | clk_reg_prcmu_scalable(name: "hsirxclk" , NULL, PRCMU_HSIRXCLK, rate: 0, |
241 | CLK_SET_RATE_GATE); |
242 | u8500_prcmu_hw_clks.hws[PRCMU_HDMICLK] = |
243 | clk_reg_prcmu_scalable(name: "hdmiclk" , NULL, PRCMU_HDMICLK, rate: 0, |
244 | CLK_SET_RATE_GATE); |
245 | u8500_prcmu_hw_clks.hws[PRCMU_APEATCLK] = |
246 | clk_reg_prcmu_gate(name: "apeatclk" , NULL, PRCMU_APEATCLK, flags: 0); |
247 | u8500_prcmu_hw_clks.hws[PRCMU_APETRACECLK] = |
248 | clk_reg_prcmu_scalable(name: "apetraceclk" , NULL, PRCMU_APETRACECLK, rate: 0, |
249 | CLK_SET_RATE_GATE); |
250 | u8500_prcmu_hw_clks.hws[PRCMU_MCDECLK] = |
251 | clk_reg_prcmu_gate(name: "mcdeclk" , NULL, PRCMU_MCDECLK, flags: 0); |
252 | u8500_prcmu_hw_clks.hws[PRCMU_IPI2CCLK] = |
253 | clk_reg_prcmu_opp_gate(name: "ipi2cclk" , NULL, PRCMU_IPI2CCLK, flags: 0); |
254 | u8500_prcmu_hw_clks.hws[PRCMU_DSIALTCLK] = |
255 | clk_reg_prcmu_gate(name: "dsialtclk" , NULL, PRCMU_DSIALTCLK, flags: 0); |
256 | u8500_prcmu_hw_clks.hws[PRCMU_DMACLK] = |
257 | clk_reg_prcmu_gate(name: "dmaclk" , NULL, PRCMU_DMACLK, flags: 0); |
258 | u8500_prcmu_hw_clks.hws[PRCMU_B2R2CLK] = |
259 | clk_reg_prcmu_gate(name: "b2r2clk" , NULL, PRCMU_B2R2CLK, flags: 0); |
260 | u8500_prcmu_hw_clks.hws[PRCMU_TVCLK] = |
261 | clk_reg_prcmu_scalable(name: "tvclk" , NULL, PRCMU_TVCLK, rate: 0, |
262 | CLK_SET_RATE_GATE); |
263 | u8500_prcmu_hw_clks.hws[PRCMU_SSPCLK] = |
264 | clk_reg_prcmu_gate(name: "sspclk" , NULL, PRCMU_SSPCLK, flags: 0); |
265 | u8500_prcmu_hw_clks.hws[PRCMU_RNGCLK] = |
266 | clk_reg_prcmu_gate(name: "rngclk" , NULL, PRCMU_RNGCLK, flags: 0); |
267 | u8500_prcmu_hw_clks.hws[PRCMU_UICCCLK] = |
268 | clk_reg_prcmu_gate(name: "uiccclk" , NULL, PRCMU_UICCCLK, flags: 0); |
269 | u8500_prcmu_hw_clks.hws[PRCMU_TIMCLK] = |
270 | clk_reg_prcmu_gate(name: "timclk" , NULL, PRCMU_TIMCLK, flags: 0); |
271 | u8500_prcmu_hw_clks.hws[PRCMU_SYSCLK] = |
272 | clk_reg_prcmu_gate(name: "ab8500_sysclk" , NULL, PRCMU_SYSCLK, flags: 0); |
273 | u8500_prcmu_hw_clks.hws[PRCMU_SDMMCCLK] = |
274 | clk_reg_prcmu_opp_volt_scalable(name: "sdmmcclk" , NULL, |
275 | PRCMU_SDMMCCLK, rate: 100000000, |
276 | CLK_SET_RATE_GATE); |
277 | u8500_prcmu_hw_clks.hws[PRCMU_PLLDSI] = |
278 | clk_reg_prcmu_scalable(name: "dsi_pll" , parent_name: "hdmiclk" , |
279 | PRCMU_PLLDSI, rate: 0, CLK_SET_RATE_GATE); |
280 | u8500_prcmu_hw_clks.hws[PRCMU_DSI0CLK] = |
281 | clk_reg_prcmu_scalable(name: "dsi0clk" , parent_name: "dsi_pll" , |
282 | PRCMU_DSI0CLK, rate: 0, CLK_SET_RATE_GATE); |
283 | u8500_prcmu_hw_clks.hws[PRCMU_DSI1CLK] = |
284 | clk_reg_prcmu_scalable(name: "dsi1clk" , parent_name: "dsi_pll" , |
285 | PRCMU_DSI1CLK, rate: 0, CLK_SET_RATE_GATE); |
286 | u8500_prcmu_hw_clks.hws[PRCMU_DSI0ESCCLK] = |
287 | clk_reg_prcmu_scalable(name: "dsi0escclk" , parent_name: "tvclk" , |
288 | PRCMU_DSI0ESCCLK, rate: 0, CLK_SET_RATE_GATE); |
289 | u8500_prcmu_hw_clks.hws[PRCMU_DSI1ESCCLK] = |
290 | clk_reg_prcmu_scalable(name: "dsi1escclk" , parent_name: "tvclk" , |
291 | PRCMU_DSI1ESCCLK, rate: 0, CLK_SET_RATE_GATE); |
292 | u8500_prcmu_hw_clks.hws[PRCMU_DSI2ESCCLK] = |
293 | clk_reg_prcmu_scalable(name: "dsi2escclk" , parent_name: "tvclk" , |
294 | PRCMU_DSI2ESCCLK, rate: 0, CLK_SET_RATE_GATE); |
295 | u8500_prcmu_hw_clks.hws[PRCMU_ARMSS] = |
296 | clk_reg_prcmu_scalable_rate(name: "armss" , NULL, |
297 | PRCMU_ARMSS, rate: 0, CLK_IGNORE_UNUSED); |
298 | |
299 | twd_clk = clk_register_fixed_factor(NULL, name: "smp_twd" , parent_name: "armss" , |
300 | CLK_IGNORE_UNUSED, mult: 1, div: 2); |
301 | |
302 | /* PRCC P-clocks */ |
303 | clk = clk_reg_prcc_pclk(name: "p1_pclk0" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
304 | BIT(0), flags: 0); |
305 | PRCC_PCLK_STORE(clk, 1, 0); |
306 | |
307 | clk = clk_reg_prcc_pclk(name: "p1_pclk1" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
308 | BIT(1), flags: 0); |
309 | PRCC_PCLK_STORE(clk, 1, 1); |
310 | |
311 | clk = clk_reg_prcc_pclk(name: "p1_pclk2" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
312 | BIT(2), flags: 0); |
313 | PRCC_PCLK_STORE(clk, 1, 2); |
314 | |
315 | clk = clk_reg_prcc_pclk(name: "p1_pclk3" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
316 | BIT(3), flags: 0); |
317 | PRCC_PCLK_STORE(clk, 1, 3); |
318 | |
319 | clk = clk_reg_prcc_pclk(name: "p1_pclk4" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
320 | BIT(4), flags: 0); |
321 | PRCC_PCLK_STORE(clk, 1, 4); |
322 | |
323 | clk = clk_reg_prcc_pclk(name: "p1_pclk5" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
324 | BIT(5), flags: 0); |
325 | PRCC_PCLK_STORE(clk, 1, 5); |
326 | |
327 | clk = clk_reg_prcc_pclk(name: "p1_pclk6" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
328 | BIT(6), flags: 0); |
329 | PRCC_PCLK_STORE(clk, 1, 6); |
330 | |
331 | clk = clk_reg_prcc_pclk(name: "p1_pclk7" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
332 | BIT(7), flags: 0); |
333 | PRCC_PCLK_STORE(clk, 1, 7); |
334 | |
335 | clk = clk_reg_prcc_pclk(name: "p1_pclk8" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
336 | BIT(8), flags: 0); |
337 | PRCC_PCLK_STORE(clk, 1, 8); |
338 | |
339 | clk = clk_reg_prcc_pclk(name: "p1_pclk9" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
340 | BIT(9), flags: 0); |
341 | PRCC_PCLK_STORE(clk, 1, 9); |
342 | |
343 | clk = clk_reg_prcc_pclk(name: "p1_pclk10" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
344 | BIT(10), flags: 0); |
345 | PRCC_PCLK_STORE(clk, 1, 10); |
346 | |
347 | clk = clk_reg_prcc_pclk(name: "p1_pclk11" , parent_name: "per1clk" , phy_base: bases[CLKRST1_INDEX], |
348 | BIT(11), flags: 0); |
349 | PRCC_PCLK_STORE(clk, 1, 11); |
350 | |
351 | clk = clk_reg_prcc_pclk(name: "p2_pclk0" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
352 | BIT(0), flags: 0); |
353 | PRCC_PCLK_STORE(clk, 2, 0); |
354 | |
355 | clk = clk_reg_prcc_pclk(name: "p2_pclk1" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
356 | BIT(1), flags: 0); |
357 | PRCC_PCLK_STORE(clk, 2, 1); |
358 | |
359 | clk = clk_reg_prcc_pclk(name: "p2_pclk2" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
360 | BIT(2), flags: 0); |
361 | PRCC_PCLK_STORE(clk, 2, 2); |
362 | |
363 | clk = clk_reg_prcc_pclk(name: "p2_pclk3" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
364 | BIT(3), flags: 0); |
365 | PRCC_PCLK_STORE(clk, 2, 3); |
366 | |
367 | clk = clk_reg_prcc_pclk(name: "p2_pclk4" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
368 | BIT(4), flags: 0); |
369 | PRCC_PCLK_STORE(clk, 2, 4); |
370 | |
371 | clk = clk_reg_prcc_pclk(name: "p2_pclk5" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
372 | BIT(5), flags: 0); |
373 | PRCC_PCLK_STORE(clk, 2, 5); |
374 | |
375 | clk = clk_reg_prcc_pclk(name: "p2_pclk6" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
376 | BIT(6), flags: 0); |
377 | PRCC_PCLK_STORE(clk, 2, 6); |
378 | |
379 | clk = clk_reg_prcc_pclk(name: "p2_pclk7" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
380 | BIT(7), flags: 0); |
381 | PRCC_PCLK_STORE(clk, 2, 7); |
382 | |
383 | clk = clk_reg_prcc_pclk(name: "p2_pclk8" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
384 | BIT(8), flags: 0); |
385 | PRCC_PCLK_STORE(clk, 2, 8); |
386 | |
387 | clk = clk_reg_prcc_pclk(name: "p2_pclk9" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
388 | BIT(9), flags: 0); |
389 | PRCC_PCLK_STORE(clk, 2, 9); |
390 | |
391 | clk = clk_reg_prcc_pclk(name: "p2_pclk10" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
392 | BIT(10), flags: 0); |
393 | PRCC_PCLK_STORE(clk, 2, 10); |
394 | |
395 | clk = clk_reg_prcc_pclk(name: "p2_pclk11" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
396 | BIT(11), flags: 0); |
397 | PRCC_PCLK_STORE(clk, 2, 11); |
398 | |
399 | clk = clk_reg_prcc_pclk(name: "p2_pclk12" , parent_name: "per2clk" , phy_base: bases[CLKRST2_INDEX], |
400 | BIT(12), flags: 0); |
401 | PRCC_PCLK_STORE(clk, 2, 12); |
402 | |
403 | clk = clk_reg_prcc_pclk(name: "p3_pclk0" , parent_name: "per3clk" , phy_base: bases[CLKRST3_INDEX], |
404 | BIT(0), flags: 0); |
405 | PRCC_PCLK_STORE(clk, 3, 0); |
406 | |
407 | clk = clk_reg_prcc_pclk(name: "p3_pclk1" , parent_name: "per3clk" , phy_base: bases[CLKRST3_INDEX], |
408 | BIT(1), flags: 0); |
409 | PRCC_PCLK_STORE(clk, 3, 1); |
410 | |
411 | clk = clk_reg_prcc_pclk(name: "p3_pclk2" , parent_name: "per3clk" , phy_base: bases[CLKRST3_INDEX], |
412 | BIT(2), flags: 0); |
413 | PRCC_PCLK_STORE(clk, 3, 2); |
414 | |
415 | clk = clk_reg_prcc_pclk(name: "p3_pclk3" , parent_name: "per3clk" , phy_base: bases[CLKRST3_INDEX], |
416 | BIT(3), flags: 0); |
417 | PRCC_PCLK_STORE(clk, 3, 3); |
418 | |
419 | clk = clk_reg_prcc_pclk(name: "p3_pclk4" , parent_name: "per3clk" , phy_base: bases[CLKRST3_INDEX], |
420 | BIT(4), flags: 0); |
421 | PRCC_PCLK_STORE(clk, 3, 4); |
422 | |
423 | clk = clk_reg_prcc_pclk(name: "p3_pclk5" , parent_name: "per3clk" , phy_base: bases[CLKRST3_INDEX], |
424 | BIT(5), flags: 0); |
425 | PRCC_PCLK_STORE(clk, 3, 5); |
426 | |
427 | clk = clk_reg_prcc_pclk(name: "p3_pclk6" , parent_name: "per3clk" , phy_base: bases[CLKRST3_INDEX], |
428 | BIT(6), flags: 0); |
429 | PRCC_PCLK_STORE(clk, 3, 6); |
430 | |
431 | clk = clk_reg_prcc_pclk(name: "p3_pclk7" , parent_name: "per3clk" , phy_base: bases[CLKRST3_INDEX], |
432 | BIT(7), flags: 0); |
433 | PRCC_PCLK_STORE(clk, 3, 7); |
434 | |
435 | clk = clk_reg_prcc_pclk(name: "p3_pclk8" , parent_name: "per3clk" , phy_base: bases[CLKRST3_INDEX], |
436 | BIT(8), flags: 0); |
437 | PRCC_PCLK_STORE(clk, 3, 8); |
438 | |
439 | clk = clk_reg_prcc_pclk(name: "p5_pclk0" , parent_name: "per5clk" , phy_base: bases[CLKRST5_INDEX], |
440 | BIT(0), flags: 0); |
441 | PRCC_PCLK_STORE(clk, 5, 0); |
442 | |
443 | clk = clk_reg_prcc_pclk(name: "p5_pclk1" , parent_name: "per5clk" , phy_base: bases[CLKRST5_INDEX], |
444 | BIT(1), flags: 0); |
445 | PRCC_PCLK_STORE(clk, 5, 1); |
446 | |
447 | clk = clk_reg_prcc_pclk(name: "p6_pclk0" , parent_name: "per6clk" , phy_base: bases[CLKRST6_INDEX], |
448 | BIT(0), flags: 0); |
449 | PRCC_PCLK_STORE(clk, 6, 0); |
450 | |
451 | clk = clk_reg_prcc_pclk(name: "p6_pclk1" , parent_name: "per6clk" , phy_base: bases[CLKRST6_INDEX], |
452 | BIT(1), flags: 0); |
453 | PRCC_PCLK_STORE(clk, 6, 1); |
454 | |
455 | clk = clk_reg_prcc_pclk(name: "p6_pclk2" , parent_name: "per6clk" , phy_base: bases[CLKRST6_INDEX], |
456 | BIT(2), flags: 0); |
457 | PRCC_PCLK_STORE(clk, 6, 2); |
458 | |
459 | clk = clk_reg_prcc_pclk(name: "p6_pclk3" , parent_name: "per6clk" , phy_base: bases[CLKRST6_INDEX], |
460 | BIT(3), flags: 0); |
461 | PRCC_PCLK_STORE(clk, 6, 3); |
462 | |
463 | clk = clk_reg_prcc_pclk(name: "p6_pclk4" , parent_name: "per6clk" , phy_base: bases[CLKRST6_INDEX], |
464 | BIT(4), flags: 0); |
465 | PRCC_PCLK_STORE(clk, 6, 4); |
466 | |
467 | clk = clk_reg_prcc_pclk(name: "p6_pclk5" , parent_name: "per6clk" , phy_base: bases[CLKRST6_INDEX], |
468 | BIT(5), flags: 0); |
469 | PRCC_PCLK_STORE(clk, 6, 5); |
470 | |
471 | clk = clk_reg_prcc_pclk(name: "p6_pclk6" , parent_name: "per6clk" , phy_base: bases[CLKRST6_INDEX], |
472 | BIT(6), flags: 0); |
473 | PRCC_PCLK_STORE(clk, 6, 6); |
474 | |
475 | clk = clk_reg_prcc_pclk(name: "p6_pclk7" , parent_name: "per6clk" , phy_base: bases[CLKRST6_INDEX], |
476 | BIT(7), flags: 0); |
477 | PRCC_PCLK_STORE(clk, 6, 7); |
478 | |
479 | /* PRCC K-clocks |
480 | * |
481 | * FIXME: Some drivers requires PERPIH[n| to be automatically enabled |
482 | * by enabling just the K-clock, even if it is not a valid parent to |
483 | * the K-clock. Until drivers get fixed we might need some kind of |
484 | * "parent muxed join". |
485 | */ |
486 | |
487 | /* Periph1 */ |
488 | clk = clk_reg_prcc_kclk(name: "p1_uart0_kclk" , parent_name: "uartclk" , |
489 | phy_base: bases[CLKRST1_INDEX], BIT(0), CLK_SET_RATE_GATE); |
490 | PRCC_KCLK_STORE(clk, 1, 0); |
491 | |
492 | clk = clk_reg_prcc_kclk(name: "p1_uart1_kclk" , parent_name: "uartclk" , |
493 | phy_base: bases[CLKRST1_INDEX], BIT(1), CLK_SET_RATE_GATE); |
494 | PRCC_KCLK_STORE(clk, 1, 1); |
495 | |
496 | clk = clk_reg_prcc_kclk(name: "p1_i2c1_kclk" , parent_name: "i2cclk" , |
497 | phy_base: bases[CLKRST1_INDEX], BIT(2), CLK_SET_RATE_GATE); |
498 | PRCC_KCLK_STORE(clk, 1, 2); |
499 | |
500 | clk = clk_reg_prcc_kclk(name: "p1_msp0_kclk" , parent_name: "msp02clk" , |
501 | phy_base: bases[CLKRST1_INDEX], BIT(3), CLK_SET_RATE_GATE); |
502 | PRCC_KCLK_STORE(clk, 1, 3); |
503 | |
504 | clk = clk_reg_prcc_kclk(name: "p1_msp1_kclk" , parent_name: "msp1clk" , |
505 | phy_base: bases[CLKRST1_INDEX], BIT(4), CLK_SET_RATE_GATE); |
506 | PRCC_KCLK_STORE(clk, 1, 4); |
507 | |
508 | clk = clk_reg_prcc_kclk(name: "p1_sdi0_kclk" , parent_name: "sdmmcclk" , |
509 | phy_base: bases[CLKRST1_INDEX], BIT(5), CLK_SET_RATE_GATE); |
510 | PRCC_KCLK_STORE(clk, 1, 5); |
511 | |
512 | clk = clk_reg_prcc_kclk(name: "p1_i2c2_kclk" , parent_name: "i2cclk" , |
513 | phy_base: bases[CLKRST1_INDEX], BIT(6), CLK_SET_RATE_GATE); |
514 | PRCC_KCLK_STORE(clk, 1, 6); |
515 | |
516 | clk = clk_reg_prcc_kclk(name: "p1_slimbus0_kclk" , parent_name: "slimclk" , |
517 | phy_base: bases[CLKRST1_INDEX], BIT(8), CLK_SET_RATE_GATE); |
518 | PRCC_KCLK_STORE(clk, 1, 8); |
519 | |
520 | clk = clk_reg_prcc_kclk(name: "p1_i2c4_kclk" , parent_name: "i2cclk" , |
521 | phy_base: bases[CLKRST1_INDEX], BIT(9), CLK_SET_RATE_GATE); |
522 | PRCC_KCLK_STORE(clk, 1, 9); |
523 | |
524 | clk = clk_reg_prcc_kclk(name: "p1_msp3_kclk" , parent_name: "msp1clk" , |
525 | phy_base: bases[CLKRST1_INDEX], BIT(10), CLK_SET_RATE_GATE); |
526 | PRCC_KCLK_STORE(clk, 1, 10); |
527 | |
528 | /* Periph2 */ |
529 | clk = clk_reg_prcc_kclk(name: "p2_i2c3_kclk" , parent_name: "i2cclk" , |
530 | phy_base: bases[CLKRST2_INDEX], BIT(0), CLK_SET_RATE_GATE); |
531 | PRCC_KCLK_STORE(clk, 2, 0); |
532 | |
533 | clk = clk_reg_prcc_kclk(name: "p2_sdi4_kclk" , parent_name: "sdmmcclk" , |
534 | phy_base: bases[CLKRST2_INDEX], BIT(2), CLK_SET_RATE_GATE); |
535 | PRCC_KCLK_STORE(clk, 2, 2); |
536 | |
537 | clk = clk_reg_prcc_kclk(name: "p2_msp2_kclk" , parent_name: "msp02clk" , |
538 | phy_base: bases[CLKRST2_INDEX], BIT(3), CLK_SET_RATE_GATE); |
539 | PRCC_KCLK_STORE(clk, 2, 3); |
540 | |
541 | clk = clk_reg_prcc_kclk(name: "p2_sdi1_kclk" , parent_name: "sdmmcclk" , |
542 | phy_base: bases[CLKRST2_INDEX], BIT(4), CLK_SET_RATE_GATE); |
543 | PRCC_KCLK_STORE(clk, 2, 4); |
544 | |
545 | clk = clk_reg_prcc_kclk(name: "p2_sdi3_kclk" , parent_name: "sdmmcclk" , |
546 | phy_base: bases[CLKRST2_INDEX], BIT(5), CLK_SET_RATE_GATE); |
547 | PRCC_KCLK_STORE(clk, 2, 5); |
548 | |
549 | /* Note that rate is received from parent. */ |
550 | clk = clk_reg_prcc_kclk(name: "p2_ssirx_kclk" , parent_name: "hsirxclk" , |
551 | phy_base: bases[CLKRST2_INDEX], BIT(6), |
552 | CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT); |
553 | PRCC_KCLK_STORE(clk, 2, 6); |
554 | |
555 | clk = clk_reg_prcc_kclk(name: "p2_ssitx_kclk" , parent_name: "hsitxclk" , |
556 | phy_base: bases[CLKRST2_INDEX], BIT(7), |
557 | CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT); |
558 | PRCC_KCLK_STORE(clk, 2, 7); |
559 | |
560 | /* Periph3 */ |
561 | clk = clk_reg_prcc_kclk(name: "p3_ssp0_kclk" , parent_name: "sspclk" , |
562 | phy_base: bases[CLKRST3_INDEX], BIT(1), CLK_SET_RATE_GATE); |
563 | PRCC_KCLK_STORE(clk, 3, 1); |
564 | |
565 | clk = clk_reg_prcc_kclk(name: "p3_ssp1_kclk" , parent_name: "sspclk" , |
566 | phy_base: bases[CLKRST3_INDEX], BIT(2), CLK_SET_RATE_GATE); |
567 | PRCC_KCLK_STORE(clk, 3, 2); |
568 | |
569 | clk = clk_reg_prcc_kclk(name: "p3_i2c0_kclk" , parent_name: "i2cclk" , |
570 | phy_base: bases[CLKRST3_INDEX], BIT(3), CLK_SET_RATE_GATE); |
571 | PRCC_KCLK_STORE(clk, 3, 3); |
572 | |
573 | clk = clk_reg_prcc_kclk(name: "p3_sdi2_kclk" , parent_name: "sdmmcclk" , |
574 | phy_base: bases[CLKRST3_INDEX], BIT(4), CLK_SET_RATE_GATE); |
575 | PRCC_KCLK_STORE(clk, 3, 4); |
576 | |
577 | clk = clk_reg_prcc_kclk(name: "p3_ske_kclk" , parent_name: "rtc32k" , |
578 | phy_base: bases[CLKRST3_INDEX], BIT(5), CLK_SET_RATE_GATE); |
579 | PRCC_KCLK_STORE(clk, 3, 5); |
580 | |
581 | clk = clk_reg_prcc_kclk(name: "p3_uart2_kclk" , parent_name: "uartclk" , |
582 | phy_base: bases[CLKRST3_INDEX], BIT(6), CLK_SET_RATE_GATE); |
583 | PRCC_KCLK_STORE(clk, 3, 6); |
584 | |
585 | clk = clk_reg_prcc_kclk(name: "p3_sdi5_kclk" , parent_name: "sdmmcclk" , |
586 | phy_base: bases[CLKRST3_INDEX], BIT(7), CLK_SET_RATE_GATE); |
587 | PRCC_KCLK_STORE(clk, 3, 7); |
588 | |
589 | /* Periph6 */ |
590 | clk = clk_reg_prcc_kclk(name: "p3_rng_kclk" , parent_name: "rngclk" , |
591 | phy_base: bases[CLKRST6_INDEX], BIT(0), CLK_SET_RATE_GATE); |
592 | PRCC_KCLK_STORE(clk, 6, 0); |
593 | |
594 | for_each_child_of_node(np, child) { |
595 | if (of_node_name_eq(np: child, name: "prcmu-clock" )) |
596 | of_clk_add_hw_provider(np: child, get: of_clk_hw_onecell_get, |
597 | data: &u8500_prcmu_hw_clks); |
598 | |
599 | if (of_node_name_eq(np: child, name: "clkout-clock" )) |
600 | of_clk_add_hw_provider(np: child, get: ux500_clkout_get, NULL); |
601 | |
602 | if (of_node_name_eq(np: child, name: "prcc-periph-clock" )) |
603 | of_clk_add_provider(np: child, clk_src_get: ux500_twocell_get, data: prcc_pclk); |
604 | |
605 | if (of_node_name_eq(np: child, name: "prcc-kernel-clock" )) |
606 | of_clk_add_provider(np: child, clk_src_get: ux500_twocell_get, data: prcc_kclk); |
607 | |
608 | if (of_node_name_eq(np: child, name: "rtc32k-clock" )) |
609 | of_clk_add_provider(np: child, clk_src_get: of_clk_src_simple_get, data: rtc_clk); |
610 | |
611 | if (of_node_name_eq(np: child, name: "smp-twd-clock" )) |
612 | of_clk_add_provider(np: child, clk_src_get: of_clk_src_simple_get, data: twd_clk); |
613 | |
614 | if (of_node_name_eq(np: child, name: "prcc-reset-controller" )) |
615 | u8500_prcc_reset_init(np: child, ur: rstc); |
616 | } |
617 | } |
618 | CLK_OF_DECLARE(u8500_clks, "stericsson,u8500-clks" , u8500_clk_init); |
619 | |