1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Marvell PXA3xxx family clocks |
4 | * |
5 | * Copyright (C) 2014 Robert Jarzmik |
6 | * |
7 | * Heavily inspired from former arch/arm/mach-pxa/pxa3xx.c |
8 | * |
9 | * For non-devicetree platforms. Once pxa is fully converted to devicetree, this |
10 | * should go away. |
11 | */ |
12 | #include <linux/io.h> |
13 | #include <linux/clk.h> |
14 | #include <linux/clk-provider.h> |
15 | #include <linux/clkdev.h> |
16 | #include <linux/of.h> |
17 | #include <linux/soc/pxa/cpu.h> |
18 | #include <linux/soc/pxa/smemc.h> |
19 | #include <linux/clk/pxa.h> |
20 | |
21 | #include <dt-bindings/clock/pxa-clock.h> |
22 | #include "clk-pxa.h" |
23 | |
24 | #define KHz 1000 |
25 | #define MHz (1000 * 1000) |
26 | |
27 | #define ACCR (0x0000) /* Application Subsystem Clock Configuration Register */ |
28 | #define ACSR (0x0004) /* Application Subsystem Clock Status Register */ |
29 | #define AICSR (0x0008) /* Application Subsystem Interrupt Control/Status Register */ |
30 | #define CKENA (0x000C) /* A Clock Enable Register */ |
31 | #define CKENB (0x0010) /* B Clock Enable Register */ |
32 | #define CKENC (0x0024) /* C Clock Enable Register */ |
33 | #define AC97_DIV (0x0014) /* AC97 clock divisor value register */ |
34 | |
35 | #define ACCR_XPDIS (1 << 31) /* Core PLL Output Disable */ |
36 | #define ACCR_SPDIS (1 << 30) /* System PLL Output Disable */ |
37 | #define ACCR_D0CS (1 << 26) /* D0 Mode Clock Select */ |
38 | #define ACCR_PCCE (1 << 11) /* Power Mode Change Clock Enable */ |
39 | #define ACCR_DDR_D0CS (1 << 7) /* DDR SDRAM clock frequency in D0CS (PXA31x only) */ |
40 | |
41 | #define ACCR_SMCFS_MASK (0x7 << 23) /* Static Memory Controller Frequency Select */ |
42 | #define ACCR_SFLFS_MASK (0x3 << 18) /* Frequency Select for Internal Memory Controller */ |
43 | #define ACCR_XSPCLK_MASK (0x3 << 16) /* Core Frequency during Frequency Change */ |
44 | #define ACCR_HSS_MASK (0x3 << 14) /* System Bus-Clock Frequency Select */ |
45 | #define ACCR_DMCFS_MASK (0x3 << 12) /* Dynamic Memory Controller Clock Frequency Select */ |
46 | #define ACCR_XN_MASK (0x7 << 8) /* Core PLL Turbo-Mode-to-Run-Mode Ratio */ |
47 | #define ACCR_XL_MASK (0x1f) /* Core PLL Run-Mode-to-Oscillator Ratio */ |
48 | |
49 | #define ACCR_SMCFS(x) (((x) & 0x7) << 23) |
50 | #define ACCR_SFLFS(x) (((x) & 0x3) << 18) |
51 | #define ACCR_XSPCLK(x) (((x) & 0x3) << 16) |
52 | #define ACCR_HSS(x) (((x) & 0x3) << 14) |
53 | #define ACCR_DMCFS(x) (((x) & 0x3) << 12) |
54 | #define ACCR_XN(x) (((x) & 0x7) << 8) |
55 | #define ACCR_XL(x) ((x) & 0x1f) |
56 | |
57 | /* |
58 | * Clock Enable Bit |
59 | */ |
60 | #define CKEN_LCD 1 /* < LCD Clock Enable */ |
61 | #define CKEN_USBH 2 /* < USB host clock enable */ |
62 | #define CKEN_CAMERA 3 /* < Camera interface clock enable */ |
63 | #define CKEN_NAND 4 /* < NAND Flash Controller Clock Enable */ |
64 | #define CKEN_USB2 6 /* < USB 2.0 client clock enable. */ |
65 | #define CKEN_DMC 8 /* < Dynamic Memory Controller clock enable */ |
66 | #define CKEN_SMC 9 /* < Static Memory Controller clock enable */ |
67 | #define CKEN_ISC 10 /* < Internal SRAM Controller clock enable */ |
68 | #define CKEN_BOOT 11 /* < Boot rom clock enable */ |
69 | #define CKEN_MMC1 12 /* < MMC1 Clock enable */ |
70 | #define CKEN_MMC2 13 /* < MMC2 clock enable */ |
71 | #define CKEN_KEYPAD 14 /* < Keypand Controller Clock Enable */ |
72 | #define CKEN_CIR 15 /* < Consumer IR Clock Enable */ |
73 | #define CKEN_USIM0 17 /* < USIM[0] Clock Enable */ |
74 | #define CKEN_USIM1 18 /* < USIM[1] Clock Enable */ |
75 | #define CKEN_TPM 19 /* < TPM clock enable */ |
76 | #define CKEN_UDC 20 /* < UDC clock enable */ |
77 | #define CKEN_BTUART 21 /* < BTUART clock enable */ |
78 | #define CKEN_FFUART 22 /* < FFUART clock enable */ |
79 | #define CKEN_STUART 23 /* < STUART clock enable */ |
80 | #define CKEN_AC97 24 /* < AC97 clock enable */ |
81 | #define CKEN_TOUCH 25 /* < Touch screen Interface Clock Enable */ |
82 | #define CKEN_SSP1 26 /* < SSP1 clock enable */ |
83 | #define CKEN_SSP2 27 /* < SSP2 clock enable */ |
84 | #define CKEN_SSP3 28 /* < SSP3 clock enable */ |
85 | #define CKEN_SSP4 29 /* < SSP4 clock enable */ |
86 | #define CKEN_MSL0 30 /* < MSL0 clock enable */ |
87 | #define CKEN_PWM0 32 /* < PWM[0] clock enable */ |
88 | #define CKEN_PWM1 33 /* < PWM[1] clock enable */ |
89 | #define CKEN_I2C 36 /* < I2C clock enable */ |
90 | #define CKEN_INTC 38 /* < Interrupt controller clock enable */ |
91 | #define CKEN_GPIO 39 /* < GPIO clock enable */ |
92 | #define CKEN_1WIRE 40 /* < 1-wire clock enable */ |
93 | #define CKEN_HSIO2 41 /* < HSIO2 clock enable */ |
94 | #define CKEN_MINI_IM 48 /* < Mini-IM */ |
95 | #define CKEN_MINI_LCD 49 /* < Mini LCD */ |
96 | |
97 | #define CKEN_MMC3 5 /* < MMC3 Clock Enable */ |
98 | #define CKEN_MVED 43 /* < MVED clock enable */ |
99 | |
100 | /* Note: GCU clock enable bit differs on PXA300/PXA310 and PXA320 */ |
101 | #define CKEN_PXA300_GCU 42 /* Graphics controller clock enable */ |
102 | #define CKEN_PXA320_GCU 7 /* Graphics controller clock enable */ |
103 | |
104 | |
105 | enum { |
106 | PXA_CORE_60Mhz = 0, |
107 | PXA_CORE_RUN, |
108 | PXA_CORE_TURBO, |
109 | }; |
110 | |
111 | enum { |
112 | PXA_BUS_60Mhz = 0, |
113 | PXA_BUS_HSS, |
114 | }; |
115 | |
116 | /* crystal frequency to HSIO bus frequency multiplier (HSS) */ |
117 | static unsigned char hss_mult[4] = { 8, 12, 16, 24 }; |
118 | |
119 | /* crystal frequency to static memory controller multiplier (SMCFS) */ |
120 | static unsigned int smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; |
121 | static const char * const get_freq_khz[] = { |
122 | "core" , "ring_osc_60mhz" , "run" , "cpll" , "system_bus" |
123 | }; |
124 | |
125 | static void __iomem *clk_regs; |
126 | |
127 | /* |
128 | * Get the clock frequency as reflected by ACSR and the turbo flag. |
129 | * We assume these values have been applied via a fcs. |
130 | * If info is not 0 we also display the current settings. |
131 | */ |
132 | unsigned int pxa3xx_get_clk_frequency_khz(int info) |
133 | { |
134 | struct clk *clk; |
135 | unsigned long clks[5]; |
136 | int i; |
137 | |
138 | for (i = 0; i < 5; i++) { |
139 | clk = clk_get(NULL, get_freq_khz[i]); |
140 | if (IS_ERR(clk)) { |
141 | clks[i] = 0; |
142 | } else { |
143 | clks[i] = clk_get_rate(clk); |
144 | clk_put(clk); |
145 | } |
146 | } |
147 | if (info) { |
148 | pr_info("RO Mode clock: %ld.%02ldMHz\n" , |
149 | clks[1] / 1000000, (clks[0] % 1000000) / 10000); |
150 | pr_info("Run Mode clock: %ld.%02ldMHz\n" , |
151 | clks[2] / 1000000, (clks[1] % 1000000) / 10000); |
152 | pr_info("Turbo Mode clock: %ld.%02ldMHz\n" , |
153 | clks[3] / 1000000, (clks[2] % 1000000) / 10000); |
154 | pr_info("System bus clock: %ld.%02ldMHz\n" , |
155 | clks[4] / 1000000, (clks[4] % 1000000) / 10000); |
156 | } |
157 | return (unsigned int)clks[0] / KHz; |
158 | } |
159 | |
160 | void pxa3xx_clk_update_accr(u32 disable, u32 enable, u32 xclkcfg, u32 mask) |
161 | { |
162 | u32 accr = readl(clk_regs + ACCR); |
163 | |
164 | accr &= ~disable; |
165 | accr |= enable; |
166 | |
167 | writel(accr, clk_regs + ACCR); |
168 | if (xclkcfg) |
169 | __asm__("mcr p14, 0, %0, c6, c0, 0\n" : : "r" (xclkcfg)); |
170 | |
171 | while ((readl(clk_regs + ACSR) & mask) != (accr & mask)) |
172 | cpu_relax(); |
173 | } |
174 | |
175 | static unsigned long clk_pxa3xx_ac97_get_rate(struct clk_hw *hw, |
176 | unsigned long parent_rate) |
177 | { |
178 | unsigned long ac97_div, rate; |
179 | |
180 | ac97_div = readl(addr: clk_regs + AC97_DIV); |
181 | |
182 | /* This may loose precision for some rates but won't for the |
183 | * standard 24.576MHz. |
184 | */ |
185 | rate = parent_rate / 2; |
186 | rate /= ((ac97_div >> 12) & 0x7fff); |
187 | rate *= (ac97_div & 0xfff); |
188 | |
189 | return rate; |
190 | } |
191 | PARENTS(clk_pxa3xx_ac97) = { "spll_624mhz" }; |
192 | RATE_RO_OPS(clk_pxa3xx_ac97, "ac97" ); |
193 | |
194 | static unsigned long clk_pxa3xx_smemc_get_rate(struct clk_hw *hw, |
195 | unsigned long parent_rate) |
196 | { |
197 | unsigned long acsr = readl(addr: clk_regs + ACSR); |
198 | |
199 | return (parent_rate / 48) * smcfs_mult[(acsr >> 23) & 0x7] / |
200 | pxa3xx_smemc_get_memclkdiv(); |
201 | |
202 | } |
203 | PARENTS(clk_pxa3xx_smemc) = { "spll_624mhz" }; |
204 | RATE_RO_OPS(clk_pxa3xx_smemc, "smemc" ); |
205 | |
206 | static bool pxa3xx_is_ring_osc_forced(void) |
207 | { |
208 | unsigned long acsr = readl(addr: clk_regs + ACSR); |
209 | |
210 | return acsr & ACCR_D0CS; |
211 | } |
212 | |
213 | PARENTS(pxa3xx_pbus) = { "ring_osc_60mhz" , "spll_624mhz" }; |
214 | PARENTS(pxa3xx_32Khz_bus) = { "osc_32_768khz" , "osc_32_768khz" }; |
215 | PARENTS(pxa3xx_13MHz_bus) = { "osc_13mhz" , "osc_13mhz" }; |
216 | PARENTS(pxa3xx_ac97_bus) = { "ring_osc_60mhz" , "ac97" }; |
217 | PARENTS(pxa3xx_sbus) = { "ring_osc_60mhz" , "system_bus" }; |
218 | PARENTS(pxa3xx_smemcbus) = { "ring_osc_60mhz" , "smemc" }; |
219 | |
220 | #define CKEN_AB(bit) ((CKEN_ ## bit > 31) ? CKENB : CKENA) |
221 | #define PXA3XX_CKEN(dev_id, con_id, parents, mult_lp, div_lp, mult_hp, \ |
222 | div_hp, bit, is_lp, flags) \ |
223 | PXA_CKEN(dev_id, con_id, bit, parents, mult_lp, div_lp, \ |
224 | mult_hp, div_hp, is_lp, CKEN_AB(bit), \ |
225 | (CKEN_ ## bit % 32), flags) |
226 | #define PXA3XX_PBUS_CKEN(dev_id, con_id, bit, mult_lp, div_lp, \ |
227 | mult_hp, div_hp, delay) \ |
228 | PXA3XX_CKEN(dev_id, con_id, pxa3xx_pbus_parents, mult_lp, \ |
229 | div_lp, mult_hp, div_hp, bit, pxa3xx_is_ring_osc_forced, 0) |
230 | #define PXA3XX_CKEN_1RATE(dev_id, con_id, bit, parents) \ |
231 | PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ |
232 | CKEN_AB(bit), (CKEN_ ## bit % 32), 0) |
233 | |
234 | static struct desc_clk_cken pxa3xx_clocks[] __initdata = { |
235 | PXA3XX_PBUS_CKEN("pxa2xx-uart.0" , NULL, FFUART, 1, 4, 1, 42, 1), |
236 | PXA3XX_PBUS_CKEN("pxa2xx-uart.1" , NULL, BTUART, 1, 4, 1, 42, 1), |
237 | PXA3XX_PBUS_CKEN("pxa2xx-uart.2" , NULL, STUART, 1, 4, 1, 42, 1), |
238 | PXA3XX_PBUS_CKEN("pxa2xx-i2c.0" , NULL, I2C, 2, 5, 1, 19, 0), |
239 | PXA3XX_PBUS_CKEN("pxa27x-udc" , NULL, UDC, 1, 4, 1, 13, 5), |
240 | PXA3XX_PBUS_CKEN("pxa27x-ohci" , NULL, USBH, 1, 4, 1, 13, 0), |
241 | PXA3XX_PBUS_CKEN("pxa3xx-u2d" , NULL, USB2, 1, 4, 1, 13, 0), |
242 | PXA3XX_PBUS_CKEN("pxa27x-pwm.0" , NULL, PWM0, 1, 6, 1, 48, 0), |
243 | PXA3XX_PBUS_CKEN("pxa27x-pwm.1" , NULL, PWM1, 1, 6, 1, 48, 0), |
244 | PXA3XX_PBUS_CKEN("pxa2xx-mci.0" , NULL, MMC1, 1, 4, 1, 24, 0), |
245 | PXA3XX_PBUS_CKEN("pxa2xx-mci.1" , NULL, MMC2, 1, 4, 1, 24, 0), |
246 | PXA3XX_PBUS_CKEN("pxa2xx-mci.2" , NULL, MMC3, 1, 4, 1, 24, 0), |
247 | |
248 | PXA3XX_CKEN_1RATE("pxa27x-keypad" , NULL, KEYPAD, |
249 | pxa3xx_32Khz_bus_parents), |
250 | PXA3XX_CKEN_1RATE("pxa3xx-ssp.0" , NULL, SSP1, pxa3xx_13MHz_bus_parents), |
251 | PXA3XX_CKEN_1RATE("pxa3xx-ssp.1" , NULL, SSP2, pxa3xx_13MHz_bus_parents), |
252 | PXA3XX_CKEN_1RATE("pxa3xx-ssp.2" , NULL, SSP3, pxa3xx_13MHz_bus_parents), |
253 | PXA3XX_CKEN_1RATE("pxa3xx-ssp.3" , NULL, SSP4, pxa3xx_13MHz_bus_parents), |
254 | |
255 | PXA3XX_CKEN(NULL, "AC97CLK" , pxa3xx_ac97_bus_parents, 1, 4, 1, 1, AC97, |
256 | pxa3xx_is_ring_osc_forced, 0), |
257 | PXA3XX_CKEN(NULL, "CAMCLK" , pxa3xx_sbus_parents, 1, 2, 1, 1, CAMERA, |
258 | pxa3xx_is_ring_osc_forced, 0), |
259 | PXA3XX_CKEN("pxa2xx-fb" , NULL, pxa3xx_sbus_parents, 1, 1, 1, 1, LCD, |
260 | pxa3xx_is_ring_osc_forced, 0), |
261 | PXA3XX_CKEN("pxa2xx-pcmcia" , NULL, pxa3xx_smemcbus_parents, 1, 4, |
262 | 1, 1, SMC, pxa3xx_is_ring_osc_forced, CLK_IGNORE_UNUSED), |
263 | }; |
264 | |
265 | static struct desc_clk_cken pxa300_310_clocks[] __initdata = { |
266 | |
267 | PXA3XX_PBUS_CKEN("pxa3xx-gcu" , NULL, PXA300_GCU, 1, 1, 1, 1, 0), |
268 | PXA3XX_PBUS_CKEN("pxa3xx-nand" , NULL, NAND, 1, 2, 1, 4, 0), |
269 | PXA3XX_CKEN_1RATE("pxa3xx-gpio" , NULL, GPIO, pxa3xx_13MHz_bus_parents), |
270 | }; |
271 | |
272 | static struct desc_clk_cken pxa320_clocks[] __initdata = { |
273 | PXA3XX_PBUS_CKEN("pxa3xx-nand" , NULL, NAND, 1, 2, 1, 6, 0), |
274 | PXA3XX_PBUS_CKEN("pxa3xx-gcu" , NULL, PXA320_GCU, 1, 1, 1, 1, 0), |
275 | PXA3XX_CKEN_1RATE("pxa3xx-gpio" , NULL, GPIO, pxa3xx_13MHz_bus_parents), |
276 | }; |
277 | |
278 | static struct desc_clk_cken pxa93x_clocks[] __initdata = { |
279 | |
280 | PXA3XX_PBUS_CKEN("pxa3xx-gcu" , NULL, PXA300_GCU, 1, 1, 1, 1, 0), |
281 | PXA3XX_PBUS_CKEN("pxa3xx-nand" , NULL, NAND, 1, 2, 1, 4, 0), |
282 | PXA3XX_CKEN_1RATE("pxa93x-gpio" , NULL, GPIO, pxa3xx_13MHz_bus_parents), |
283 | }; |
284 | |
285 | static unsigned long clk_pxa3xx_system_bus_get_rate(struct clk_hw *hw, |
286 | unsigned long parent_rate) |
287 | { |
288 | unsigned long acsr = readl(addr: clk_regs + ACSR); |
289 | unsigned int hss = (acsr >> 14) & 0x3; |
290 | |
291 | if (pxa3xx_is_ring_osc_forced()) |
292 | return parent_rate; |
293 | return parent_rate / 48 * hss_mult[hss]; |
294 | } |
295 | |
296 | static u8 clk_pxa3xx_system_bus_get_parent(struct clk_hw *hw) |
297 | { |
298 | if (pxa3xx_is_ring_osc_forced()) |
299 | return PXA_BUS_60Mhz; |
300 | else |
301 | return PXA_BUS_HSS; |
302 | } |
303 | |
304 | PARENTS(clk_pxa3xx_system_bus) = { "ring_osc_60mhz" , "spll_624mhz" }; |
305 | MUX_RO_RATE_RO_OPS(clk_pxa3xx_system_bus, "system_bus" ); |
306 | |
307 | static unsigned long clk_pxa3xx_core_get_rate(struct clk_hw *hw, |
308 | unsigned long parent_rate) |
309 | { |
310 | return parent_rate; |
311 | } |
312 | |
313 | static u8 clk_pxa3xx_core_get_parent(struct clk_hw *hw) |
314 | { |
315 | unsigned long xclkcfg; |
316 | unsigned int t; |
317 | |
318 | if (pxa3xx_is_ring_osc_forced()) |
319 | return PXA_CORE_60Mhz; |
320 | |
321 | /* Read XCLKCFG register turbo bit */ |
322 | __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (xclkcfg)); |
323 | t = xclkcfg & 0x1; |
324 | |
325 | if (t) |
326 | return PXA_CORE_TURBO; |
327 | return PXA_CORE_RUN; |
328 | } |
329 | PARENTS(clk_pxa3xx_core) = { "ring_osc_60mhz" , "run" , "cpll" }; |
330 | MUX_RO_RATE_RO_OPS(clk_pxa3xx_core, "core" ); |
331 | |
332 | static unsigned long clk_pxa3xx_run_get_rate(struct clk_hw *hw, |
333 | unsigned long parent_rate) |
334 | { |
335 | unsigned long acsr = readl(addr: clk_regs + ACSR); |
336 | unsigned int xn = (acsr & ACCR_XN_MASK) >> 8; |
337 | unsigned int t, xclkcfg; |
338 | |
339 | /* Read XCLKCFG register turbo bit */ |
340 | __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (xclkcfg)); |
341 | t = xclkcfg & 0x1; |
342 | |
343 | return t ? (parent_rate / xn) * 2 : parent_rate; |
344 | } |
345 | PARENTS(clk_pxa3xx_run) = { "cpll" }; |
346 | RATE_RO_OPS(clk_pxa3xx_run, "run" ); |
347 | |
348 | static unsigned long clk_pxa3xx_cpll_get_rate(struct clk_hw *hw, |
349 | unsigned long parent_rate) |
350 | { |
351 | unsigned long acsr = readl(addr: clk_regs + ACSR); |
352 | unsigned int xn = (acsr & ACCR_XN_MASK) >> 8; |
353 | unsigned int xl = acsr & ACCR_XL_MASK; |
354 | unsigned int t, xclkcfg; |
355 | |
356 | /* Read XCLKCFG register turbo bit */ |
357 | __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (xclkcfg)); |
358 | t = xclkcfg & 0x1; |
359 | |
360 | pr_info("RJK: parent_rate=%lu, xl=%u, xn=%u\n" , parent_rate, xl, xn); |
361 | return t ? parent_rate * xl * xn : parent_rate * xl; |
362 | } |
363 | PARENTS(clk_pxa3xx_cpll) = { "osc_13mhz" }; |
364 | RATE_RO_OPS(clk_pxa3xx_cpll, "cpll" ); |
365 | |
366 | static void __init pxa3xx_register_core(void) |
367 | { |
368 | clk_register_clk_pxa3xx_cpll(); |
369 | clk_register_clk_pxa3xx_run(); |
370 | |
371 | clkdev_pxa_register(CLK_CORE, con_id: "core" , NULL, |
372 | clk: clk_register_clk_pxa3xx_core()); |
373 | } |
374 | |
375 | static void __init pxa3xx_register_plls(void) |
376 | { |
377 | clk_register_fixed_rate(NULL, name: "osc_13mhz" , NULL, |
378 | CLK_GET_RATE_NOCACHE, |
379 | fixed_rate: 13 * MHz); |
380 | clkdev_pxa_register(CLK_OSC32k768, con_id: "osc_32_768khz" , NULL, |
381 | clk: clk_register_fixed_rate(NULL, name: "osc_32_768khz" , NULL, |
382 | CLK_GET_RATE_NOCACHE, |
383 | fixed_rate: 32768)); |
384 | clk_register_fixed_rate(NULL, name: "ring_osc_120mhz" , NULL, |
385 | CLK_GET_RATE_NOCACHE, |
386 | fixed_rate: 120 * MHz); |
387 | clk_register_fixed_rate(NULL, name: "clk_dummy" , NULL, flags: 0, fixed_rate: 0); |
388 | clk_register_fixed_factor(NULL, name: "spll_624mhz" , parent_name: "osc_13mhz" , flags: 0, mult: 48, div: 1); |
389 | clk_register_fixed_factor(NULL, name: "ring_osc_60mhz" , parent_name: "ring_osc_120mhz" , |
390 | flags: 0, mult: 1, div: 2); |
391 | } |
392 | |
393 | #define DUMMY_CLK(_con_id, _dev_id, _parent) \ |
394 | { .con_id = _con_id, .dev_id = _dev_id, .parent = _parent } |
395 | struct dummy_clk { |
396 | const char *con_id; |
397 | const char *dev_id; |
398 | const char *parent; |
399 | }; |
400 | static struct dummy_clk dummy_clks[] __initdata = { |
401 | DUMMY_CLK(NULL, "pxa93x-gpio" , "osc_13mhz" ), |
402 | DUMMY_CLK(NULL, "sa1100-rtc" , "osc_32_768khz" ), |
403 | DUMMY_CLK("UARTCLK" , "pxa2xx-ir" , "STUART" ), |
404 | DUMMY_CLK(NULL, "pxa3xx-pwri2c.1" , "osc_13mhz" ), |
405 | }; |
406 | |
407 | static void __init pxa3xx_dummy_clocks_init(void) |
408 | { |
409 | struct clk *clk; |
410 | struct dummy_clk *d; |
411 | const char *name; |
412 | int i; |
413 | |
414 | for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) { |
415 | d = &dummy_clks[i]; |
416 | name = d->dev_id ? d->dev_id : d->con_id; |
417 | clk = clk_register_fixed_factor(NULL, name, parent_name: d->parent, flags: 0, mult: 1, div: 1); |
418 | clk_register_clkdev(clk, d->con_id, d->dev_id); |
419 | } |
420 | } |
421 | |
422 | static void __init pxa3xx_base_clocks_init(void __iomem *oscc_reg) |
423 | { |
424 | struct clk *clk; |
425 | |
426 | pxa3xx_register_plls(); |
427 | pxa3xx_register_core(); |
428 | clk_register_clk_pxa3xx_system_bus(); |
429 | clk_register_clk_pxa3xx_ac97(); |
430 | clk_register_clk_pxa3xx_smemc(); |
431 | clk = clk_register_gate(NULL, name: "CLK_POUT" , |
432 | parent_name: "osc_13mhz" , flags: 0, reg: oscc_reg, bit_idx: 11, clk_gate_flags: 0, NULL); |
433 | clk_register_clkdev(clk, "CLK_POUT" , NULL); |
434 | clkdev_pxa_register(CLK_OSTIMER, con_id: "OSTIMER0" , NULL, |
435 | clk: clk_register_fixed_factor(NULL, name: "os-timer0" , |
436 | parent_name: "osc_13mhz" , flags: 0, mult: 1, div: 4)); |
437 | } |
438 | |
439 | int __init pxa3xx_clocks_init(void __iomem *regs, void __iomem *oscc_reg) |
440 | { |
441 | int ret; |
442 | |
443 | clk_regs = regs; |
444 | pxa3xx_base_clocks_init(oscc_reg); |
445 | pxa3xx_dummy_clocks_init(); |
446 | ret = clk_pxa_cken_init(clks: pxa3xx_clocks, ARRAY_SIZE(pxa3xx_clocks), clk_regs: regs); |
447 | if (ret) |
448 | return ret; |
449 | if (cpu_is_pxa320()) |
450 | return clk_pxa_cken_init(clks: pxa320_clocks, |
451 | ARRAY_SIZE(pxa320_clocks), clk_regs: regs); |
452 | if (cpu_is_pxa300() || cpu_is_pxa310()) |
453 | return clk_pxa_cken_init(clks: pxa300_310_clocks, |
454 | ARRAY_SIZE(pxa300_310_clocks), clk_regs: regs); |
455 | return clk_pxa_cken_init(clks: pxa93x_clocks, ARRAY_SIZE(pxa93x_clocks), clk_regs: regs); |
456 | } |
457 | |
458 | static void __init pxa3xx_dt_clocks_init(struct device_node *np) |
459 | { |
460 | pxa3xx_clocks_init(ioremap(offset: 0x41340000, size: 0x10), ioremap(offset: 0x41350000, size: 4)); |
461 | clk_pxa_dt_common_init(np); |
462 | } |
463 | CLK_OF_DECLARE(pxa_clks, "marvell,pxa300-clocks" , pxa3xx_dt_clocks_init); |
464 | |