1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * arch/arm/mach-ep93xx/clock.c |
4 | * Clock control for Cirrus EP93xx chips. |
5 | * |
6 | * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> |
7 | */ |
8 | |
9 | #define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt |
10 | |
11 | #include <linux/kernel.h> |
12 | #include <linux/clk.h> |
13 | #include <linux/err.h> |
14 | #include <linux/module.h> |
15 | #include <linux/string.h> |
16 | #include <linux/io.h> |
17 | #include <linux/spinlock.h> |
18 | #include <linux/clkdev.h> |
19 | #include <linux/clk-provider.h> |
20 | #include <linux/soc/cirrus/ep93xx.h> |
21 | |
22 | #include "hardware.h" |
23 | |
24 | #include <asm/div64.h> |
25 | |
26 | #include "soc.h" |
27 | |
28 | static DEFINE_SPINLOCK(clk_lock); |
29 | |
30 | static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; |
31 | static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; |
32 | static char pclk_divisors[] = { 1, 2, 4, 8 }; |
33 | |
34 | static char adc_divisors[] = { 16, 4 }; |
35 | static char sclk_divisors[] = { 2, 4 }; |
36 | static char lrclk_divisors[] = { 32, 64, 128 }; |
37 | |
38 | static const char * const mux_parents[] = { |
39 | "xtali" , |
40 | "pll1" , |
41 | "pll2" |
42 | }; |
43 | |
44 | /* |
45 | * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS |
46 | */ |
47 | static unsigned long calc_pll_rate(unsigned long long rate, u32 config_word) |
48 | { |
49 | int i; |
50 | |
51 | rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */ |
52 | rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */ |
53 | do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */ |
54 | for (i = 0; i < ((config_word >> 16) & 3); i++) /* PS */ |
55 | rate >>= 1; |
56 | |
57 | return (unsigned long)rate; |
58 | } |
59 | |
60 | struct clk_psc { |
61 | struct clk_hw hw; |
62 | void __iomem *reg; |
63 | u8 bit_idx; |
64 | u32 mask; |
65 | u8 shift; |
66 | u8 width; |
67 | char *div; |
68 | u8 num_div; |
69 | spinlock_t *lock; |
70 | }; |
71 | |
72 | #define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw) |
73 | |
74 | static int ep93xx_clk_is_enabled(struct clk_hw *hw) |
75 | { |
76 | struct clk_psc *psc = to_clk_psc(hw); |
77 | u32 val = readl(addr: psc->reg); |
78 | |
79 | return (val & BIT(psc->bit_idx)) ? 1 : 0; |
80 | } |
81 | |
82 | static int ep93xx_clk_enable(struct clk_hw *hw) |
83 | { |
84 | struct clk_psc *psc = to_clk_psc(hw); |
85 | unsigned long flags = 0; |
86 | u32 val; |
87 | |
88 | if (psc->lock) |
89 | spin_lock_irqsave(psc->lock, flags); |
90 | |
91 | val = __raw_readl(addr: psc->reg); |
92 | val |= BIT(psc->bit_idx); |
93 | |
94 | ep93xx_syscon_swlocked_write(val, reg: psc->reg); |
95 | |
96 | if (psc->lock) |
97 | spin_unlock_irqrestore(lock: psc->lock, flags); |
98 | |
99 | return 0; |
100 | } |
101 | |
102 | static void ep93xx_clk_disable(struct clk_hw *hw) |
103 | { |
104 | struct clk_psc *psc = to_clk_psc(hw); |
105 | unsigned long flags = 0; |
106 | u32 val; |
107 | |
108 | if (psc->lock) |
109 | spin_lock_irqsave(psc->lock, flags); |
110 | |
111 | val = __raw_readl(addr: psc->reg); |
112 | val &= ~BIT(psc->bit_idx); |
113 | |
114 | ep93xx_syscon_swlocked_write(val, reg: psc->reg); |
115 | |
116 | if (psc->lock) |
117 | spin_unlock_irqrestore(lock: psc->lock, flags); |
118 | } |
119 | |
120 | static const struct clk_ops clk_ep93xx_gate_ops = { |
121 | .enable = ep93xx_clk_enable, |
122 | .disable = ep93xx_clk_disable, |
123 | .is_enabled = ep93xx_clk_is_enabled, |
124 | }; |
125 | |
126 | static struct clk_hw *ep93xx_clk_register_gate(const char *name, |
127 | const char *parent_name, |
128 | void __iomem *reg, |
129 | u8 bit_idx) |
130 | { |
131 | struct clk_init_data init; |
132 | struct clk_psc *psc; |
133 | struct clk *clk; |
134 | |
135 | psc = kzalloc(size: sizeof(*psc), GFP_KERNEL); |
136 | if (!psc) |
137 | return ERR_PTR(error: -ENOMEM); |
138 | |
139 | init.name = name; |
140 | init.ops = &clk_ep93xx_gate_ops; |
141 | init.flags = CLK_SET_RATE_PARENT; |
142 | init.parent_names = (parent_name ? &parent_name : NULL); |
143 | init.num_parents = (parent_name ? 1 : 0); |
144 | |
145 | psc->reg = reg; |
146 | psc->bit_idx = bit_idx; |
147 | psc->hw.init = &init; |
148 | psc->lock = &clk_lock; |
149 | |
150 | clk = clk_register(NULL, hw: &psc->hw); |
151 | if (IS_ERR(ptr: clk)) { |
152 | kfree(objp: psc); |
153 | return ERR_CAST(ptr: clk); |
154 | } |
155 | |
156 | return &psc->hw; |
157 | } |
158 | |
159 | static u8 ep93xx_mux_get_parent(struct clk_hw *hw) |
160 | { |
161 | struct clk_psc *psc = to_clk_psc(hw); |
162 | u32 val = __raw_readl(addr: psc->reg); |
163 | |
164 | if (!(val & EP93XX_SYSCON_CLKDIV_ESEL)) |
165 | return 0; |
166 | |
167 | if (!(val & EP93XX_SYSCON_CLKDIV_PSEL)) |
168 | return 1; |
169 | |
170 | return 2; |
171 | } |
172 | |
173 | static int ep93xx_mux_set_parent_lock(struct clk_hw *hw, u8 index) |
174 | { |
175 | struct clk_psc *psc = to_clk_psc(hw); |
176 | unsigned long flags = 0; |
177 | u32 val; |
178 | |
179 | if (index >= ARRAY_SIZE(mux_parents)) |
180 | return -EINVAL; |
181 | |
182 | if (psc->lock) |
183 | spin_lock_irqsave(psc->lock, flags); |
184 | |
185 | val = __raw_readl(addr: psc->reg); |
186 | val &= ~(EP93XX_SYSCON_CLKDIV_ESEL | EP93XX_SYSCON_CLKDIV_PSEL); |
187 | |
188 | |
189 | if (index != 0) { |
190 | val |= EP93XX_SYSCON_CLKDIV_ESEL; |
191 | val |= (index - 1) ? EP93XX_SYSCON_CLKDIV_PSEL : 0; |
192 | } |
193 | |
194 | ep93xx_syscon_swlocked_write(val, reg: psc->reg); |
195 | |
196 | if (psc->lock) |
197 | spin_unlock_irqrestore(lock: psc->lock, flags); |
198 | |
199 | return 0; |
200 | } |
201 | |
202 | static bool is_best(unsigned long rate, unsigned long now, |
203 | unsigned long best) |
204 | { |
205 | return abs(rate - now) < abs(rate - best); |
206 | } |
207 | |
208 | static int ep93xx_mux_determine_rate(struct clk_hw *hw, |
209 | struct clk_rate_request *req) |
210 | { |
211 | unsigned long rate = req->rate; |
212 | struct clk *best_parent = NULL; |
213 | unsigned long __parent_rate; |
214 | unsigned long best_rate = 0, actual_rate, mclk_rate; |
215 | unsigned long best_parent_rate; |
216 | int __div = 0, __pdiv = 0; |
217 | int i; |
218 | |
219 | /* |
220 | * Try the two pll's and the external clock |
221 | * Because the valid predividers are 2, 2.5 and 3, we multiply |
222 | * all the clocks by 2 to avoid floating point math. |
223 | * |
224 | * This is based on the algorithm in the ep93xx raster guide: |
225 | * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf |
226 | * |
227 | */ |
228 | for (i = 0; i < ARRAY_SIZE(mux_parents); i++) { |
229 | struct clk *parent = clk_get_sys(dev_id: mux_parents[i], NULL); |
230 | |
231 | __parent_rate = clk_get_rate(clk: parent); |
232 | mclk_rate = __parent_rate * 2; |
233 | |
234 | /* Try each predivider value */ |
235 | for (__pdiv = 4; __pdiv <= 6; __pdiv++) { |
236 | __div = mclk_rate / (rate * __pdiv); |
237 | if (__div < 2 || __div > 127) |
238 | continue; |
239 | |
240 | actual_rate = mclk_rate / (__pdiv * __div); |
241 | if (is_best(rate, now: actual_rate, best: best_rate)) { |
242 | best_rate = actual_rate; |
243 | best_parent_rate = __parent_rate; |
244 | best_parent = parent; |
245 | } |
246 | } |
247 | } |
248 | |
249 | if (!best_parent) |
250 | return -EINVAL; |
251 | |
252 | req->best_parent_rate = best_parent_rate; |
253 | req->best_parent_hw = __clk_get_hw(clk: best_parent); |
254 | req->rate = best_rate; |
255 | |
256 | return 0; |
257 | } |
258 | |
259 | static unsigned long ep93xx_ddiv_recalc_rate(struct clk_hw *hw, |
260 | unsigned long parent_rate) |
261 | { |
262 | struct clk_psc *psc = to_clk_psc(hw); |
263 | unsigned long rate = 0; |
264 | u32 val = __raw_readl(addr: psc->reg); |
265 | int __pdiv = ((val >> EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) & 0x03); |
266 | int __div = val & 0x7f; |
267 | |
268 | if (__div > 0) |
269 | rate = (parent_rate * 2) / ((__pdiv + 3) * __div); |
270 | |
271 | return rate; |
272 | } |
273 | |
274 | static int ep93xx_ddiv_set_rate(struct clk_hw *hw, unsigned long rate, |
275 | unsigned long parent_rate) |
276 | { |
277 | struct clk_psc *psc = to_clk_psc(hw); |
278 | int pdiv = 0, div = 0; |
279 | unsigned long best_rate = 0, actual_rate, mclk_rate; |
280 | int __div = 0, __pdiv = 0; |
281 | u32 val; |
282 | |
283 | mclk_rate = parent_rate * 2; |
284 | |
285 | for (__pdiv = 4; __pdiv <= 6; __pdiv++) { |
286 | __div = mclk_rate / (rate * __pdiv); |
287 | if (__div < 2 || __div > 127) |
288 | continue; |
289 | |
290 | actual_rate = mclk_rate / (__pdiv * __div); |
291 | if (is_best(rate, now: actual_rate, best: best_rate)) { |
292 | pdiv = __pdiv - 3; |
293 | div = __div; |
294 | best_rate = actual_rate; |
295 | } |
296 | } |
297 | |
298 | if (!best_rate) |
299 | return -EINVAL; |
300 | |
301 | val = __raw_readl(addr: psc->reg); |
302 | |
303 | /* Clear old dividers */ |
304 | val &= ~0x37f; |
305 | |
306 | /* Set the new pdiv and div bits for the new clock rate */ |
307 | val |= (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div; |
308 | ep93xx_syscon_swlocked_write(val, reg: psc->reg); |
309 | |
310 | return 0; |
311 | } |
312 | |
313 | static const struct clk_ops clk_ddiv_ops = { |
314 | .enable = ep93xx_clk_enable, |
315 | .disable = ep93xx_clk_disable, |
316 | .is_enabled = ep93xx_clk_is_enabled, |
317 | .get_parent = ep93xx_mux_get_parent, |
318 | .set_parent = ep93xx_mux_set_parent_lock, |
319 | .determine_rate = ep93xx_mux_determine_rate, |
320 | .recalc_rate = ep93xx_ddiv_recalc_rate, |
321 | .set_rate = ep93xx_ddiv_set_rate, |
322 | }; |
323 | |
324 | static struct clk_hw *clk_hw_register_ddiv(const char *name, |
325 | void __iomem *reg, |
326 | u8 bit_idx) |
327 | { |
328 | struct clk_init_data init; |
329 | struct clk_psc *psc; |
330 | struct clk *clk; |
331 | |
332 | psc = kzalloc(size: sizeof(*psc), GFP_KERNEL); |
333 | if (!psc) |
334 | return ERR_PTR(error: -ENOMEM); |
335 | |
336 | init.name = name; |
337 | init.ops = &clk_ddiv_ops; |
338 | init.flags = 0; |
339 | init.parent_names = mux_parents; |
340 | init.num_parents = ARRAY_SIZE(mux_parents); |
341 | |
342 | psc->reg = reg; |
343 | psc->bit_idx = bit_idx; |
344 | psc->lock = &clk_lock; |
345 | psc->hw.init = &init; |
346 | |
347 | clk = clk_register(NULL, hw: &psc->hw); |
348 | if (IS_ERR(ptr: clk)) { |
349 | kfree(objp: psc); |
350 | return ERR_CAST(ptr: clk); |
351 | } |
352 | return &psc->hw; |
353 | } |
354 | |
355 | static unsigned long ep93xx_div_recalc_rate(struct clk_hw *hw, |
356 | unsigned long parent_rate) |
357 | { |
358 | struct clk_psc *psc = to_clk_psc(hw); |
359 | u32 val = __raw_readl(addr: psc->reg); |
360 | u8 index = (val & psc->mask) >> psc->shift; |
361 | |
362 | if (index > psc->num_div) |
363 | return 0; |
364 | |
365 | return DIV_ROUND_UP_ULL(parent_rate, psc->div[index]); |
366 | } |
367 | |
368 | static long ep93xx_div_round_rate(struct clk_hw *hw, unsigned long rate, |
369 | unsigned long *parent_rate) |
370 | { |
371 | struct clk_psc *psc = to_clk_psc(hw); |
372 | unsigned long best = 0, now, maxdiv; |
373 | int i; |
374 | |
375 | maxdiv = psc->div[psc->num_div - 1]; |
376 | |
377 | for (i = 0; i < psc->num_div; i++) { |
378 | if ((rate * psc->div[i]) == *parent_rate) |
379 | return DIV_ROUND_UP_ULL((u64)*parent_rate, psc->div[i]); |
380 | |
381 | now = DIV_ROUND_UP_ULL((u64)*parent_rate, psc->div[i]); |
382 | |
383 | if (is_best(rate, now, best)) |
384 | best = now; |
385 | } |
386 | |
387 | if (!best) |
388 | best = DIV_ROUND_UP_ULL(*parent_rate, maxdiv); |
389 | |
390 | return best; |
391 | } |
392 | |
393 | static int ep93xx_div_set_rate(struct clk_hw *hw, unsigned long rate, |
394 | unsigned long parent_rate) |
395 | { |
396 | struct clk_psc *psc = to_clk_psc(hw); |
397 | u32 val = __raw_readl(addr: psc->reg) & ~psc->mask; |
398 | int i; |
399 | |
400 | for (i = 0; i < psc->num_div; i++) |
401 | if (rate == parent_rate / psc->div[i]) { |
402 | val |= i << psc->shift; |
403 | break; |
404 | } |
405 | |
406 | if (i == psc->num_div) |
407 | return -EINVAL; |
408 | |
409 | ep93xx_syscon_swlocked_write(val, reg: psc->reg); |
410 | |
411 | return 0; |
412 | } |
413 | |
414 | static const struct clk_ops ep93xx_div_ops = { |
415 | .enable = ep93xx_clk_enable, |
416 | .disable = ep93xx_clk_disable, |
417 | .is_enabled = ep93xx_clk_is_enabled, |
418 | .recalc_rate = ep93xx_div_recalc_rate, |
419 | .round_rate = ep93xx_div_round_rate, |
420 | .set_rate = ep93xx_div_set_rate, |
421 | }; |
422 | |
423 | static struct clk_hw *clk_hw_register_div(const char *name, |
424 | const char *parent_name, |
425 | void __iomem *reg, |
426 | u8 enable_bit, |
427 | u8 shift, |
428 | u8 width, |
429 | char *clk_divisors, |
430 | u8 num_div) |
431 | { |
432 | struct clk_init_data init; |
433 | struct clk_psc *psc; |
434 | struct clk *clk; |
435 | |
436 | psc = kzalloc(size: sizeof(*psc), GFP_KERNEL); |
437 | if (!psc) |
438 | return ERR_PTR(error: -ENOMEM); |
439 | |
440 | init.name = name; |
441 | init.ops = &ep93xx_div_ops; |
442 | init.flags = 0; |
443 | init.parent_names = (parent_name ? &parent_name : NULL); |
444 | init.num_parents = 1; |
445 | |
446 | psc->reg = reg; |
447 | psc->bit_idx = enable_bit; |
448 | psc->mask = GENMASK(shift + width - 1, shift); |
449 | psc->shift = shift; |
450 | psc->div = clk_divisors; |
451 | psc->num_div = num_div; |
452 | psc->lock = &clk_lock; |
453 | psc->hw.init = &init; |
454 | |
455 | clk = clk_register(NULL, hw: &psc->hw); |
456 | if (IS_ERR(ptr: clk)) { |
457 | kfree(objp: psc); |
458 | return ERR_CAST(ptr: clk); |
459 | } |
460 | return &psc->hw; |
461 | } |
462 | |
463 | struct ep93xx_gate { |
464 | unsigned int bit; |
465 | const char *dev_id; |
466 | const char *con_id; |
467 | }; |
468 | |
469 | static struct ep93xx_gate ep93xx_uarts[] = { |
470 | {EP93XX_SYSCON_DEVCFG_U1EN, "apb:uart1" , NULL}, |
471 | {EP93XX_SYSCON_DEVCFG_U2EN, "apb:uart2" , NULL}, |
472 | {EP93XX_SYSCON_DEVCFG_U3EN, "apb:uart3" , NULL}, |
473 | }; |
474 | |
475 | static void __init ep93xx_uart_clock_init(void) |
476 | { |
477 | unsigned int i; |
478 | struct clk_hw *hw; |
479 | u32 value; |
480 | unsigned int clk_uart_div; |
481 | |
482 | value = __raw_readl(EP93XX_SYSCON_PWRCNT); |
483 | if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD) |
484 | clk_uart_div = 1; |
485 | else |
486 | clk_uart_div = 2; |
487 | |
488 | hw = clk_hw_register_fixed_factor(NULL, name: "uart" , parent_name: "xtali" , flags: 0, mult: 1, div: clk_uart_div); |
489 | |
490 | /* parenting uart gate clocks to uart clock */ |
491 | for (i = 0; i < ARRAY_SIZE(ep93xx_uarts); i++) { |
492 | hw = ep93xx_clk_register_gate(name: ep93xx_uarts[i].dev_id, |
493 | parent_name: "uart" , |
494 | EP93XX_SYSCON_DEVCFG, |
495 | bit_idx: ep93xx_uarts[i].bit); |
496 | |
497 | clk_hw_register_clkdev(hw, NULL, ep93xx_uarts[i].dev_id); |
498 | } |
499 | } |
500 | |
501 | static struct ep93xx_gate ep93xx_dmas[] = { |
502 | {EP93XX_SYSCON_PWRCNT_DMA_M2P0, NULL, "m2p0" }, |
503 | {EP93XX_SYSCON_PWRCNT_DMA_M2P1, NULL, "m2p1" }, |
504 | {EP93XX_SYSCON_PWRCNT_DMA_M2P2, NULL, "m2p2" }, |
505 | {EP93XX_SYSCON_PWRCNT_DMA_M2P3, NULL, "m2p3" }, |
506 | {EP93XX_SYSCON_PWRCNT_DMA_M2P4, NULL, "m2p4" }, |
507 | {EP93XX_SYSCON_PWRCNT_DMA_M2P5, NULL, "m2p5" }, |
508 | {EP93XX_SYSCON_PWRCNT_DMA_M2P6, NULL, "m2p6" }, |
509 | {EP93XX_SYSCON_PWRCNT_DMA_M2P7, NULL, "m2p7" }, |
510 | {EP93XX_SYSCON_PWRCNT_DMA_M2P8, NULL, "m2p8" }, |
511 | {EP93XX_SYSCON_PWRCNT_DMA_M2P9, NULL, "m2p9" }, |
512 | {EP93XX_SYSCON_PWRCNT_DMA_M2M0, NULL, "m2m0" }, |
513 | {EP93XX_SYSCON_PWRCNT_DMA_M2M1, NULL, "m2m1" }, |
514 | }; |
515 | |
516 | static void __init ep93xx_dma_clock_init(void) |
517 | { |
518 | unsigned int i; |
519 | struct clk_hw *hw; |
520 | int ret; |
521 | |
522 | for (i = 0; i < ARRAY_SIZE(ep93xx_dmas); i++) { |
523 | hw = clk_hw_register_gate(NULL, ep93xx_dmas[i].con_id, |
524 | "hclk" , 0, |
525 | EP93XX_SYSCON_PWRCNT, |
526 | ep93xx_dmas[i].bit, |
527 | 0, |
528 | &clk_lock); |
529 | |
530 | ret = clk_hw_register_clkdev(hw, ep93xx_dmas[i].con_id, NULL); |
531 | if (ret) |
532 | pr_err("%s: failed to register lookup %s\n" , |
533 | __func__, ep93xx_dmas[i].con_id); |
534 | } |
535 | } |
536 | |
537 | static int __init ep93xx_clock_init(void) |
538 | { |
539 | u32 value; |
540 | struct clk_hw *hw; |
541 | unsigned long clk_pll1_rate; |
542 | unsigned long clk_f_rate; |
543 | unsigned long clk_h_rate; |
544 | unsigned long clk_p_rate; |
545 | unsigned long clk_pll2_rate; |
546 | unsigned int clk_f_div; |
547 | unsigned int clk_h_div; |
548 | unsigned int clk_p_div; |
549 | unsigned int clk_usb_div; |
550 | unsigned long clk_spi_div; |
551 | |
552 | hw = clk_hw_register_fixed_rate(NULL, "xtali" , NULL, 0, EP93XX_EXT_CLK_RATE); |
553 | clk_hw_register_clkdev(hw, NULL, "xtali" ); |
554 | |
555 | /* Determine the bootloader configured pll1 rate */ |
556 | value = __raw_readl(EP93XX_SYSCON_CLKSET1); |
557 | if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1)) |
558 | clk_pll1_rate = EP93XX_EXT_CLK_RATE; |
559 | else |
560 | clk_pll1_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, config_word: value); |
561 | |
562 | hw = clk_hw_register_fixed_rate(NULL, "pll1" , "xtali" , 0, clk_pll1_rate); |
563 | clk_hw_register_clkdev(hw, NULL, "pll1" ); |
564 | |
565 | /* Initialize the pll1 derived clocks */ |
566 | clk_f_div = fclk_divisors[(value >> 25) & 0x7]; |
567 | clk_h_div = hclk_divisors[(value >> 20) & 0x7]; |
568 | clk_p_div = pclk_divisors[(value >> 18) & 0x3]; |
569 | |
570 | hw = clk_hw_register_fixed_factor(NULL, name: "fclk" , parent_name: "pll1" , flags: 0, mult: 1, div: clk_f_div); |
571 | clk_f_rate = clk_get_rate(clk: hw->clk); |
572 | hw = clk_hw_register_fixed_factor(NULL, name: "hclk" , parent_name: "pll1" , flags: 0, mult: 1, div: clk_h_div); |
573 | clk_h_rate = clk_get_rate(clk: hw->clk); |
574 | hw = clk_hw_register_fixed_factor(NULL, name: "pclk" , parent_name: "hclk" , flags: 0, mult: 1, div: clk_p_div); |
575 | clk_p_rate = clk_get_rate(clk: hw->clk); |
576 | |
577 | clk_hw_register_clkdev(hw, "apb_pclk" , NULL); |
578 | |
579 | ep93xx_dma_clock_init(); |
580 | |
581 | /* Determine the bootloader configured pll2 rate */ |
582 | value = __raw_readl(EP93XX_SYSCON_CLKSET2); |
583 | if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2)) |
584 | clk_pll2_rate = EP93XX_EXT_CLK_RATE; |
585 | else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN) |
586 | clk_pll2_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, config_word: value); |
587 | else |
588 | clk_pll2_rate = 0; |
589 | |
590 | hw = clk_hw_register_fixed_rate(NULL, "pll2" , "xtali" , 0, clk_pll2_rate); |
591 | clk_hw_register_clkdev(hw, NULL, "pll2" ); |
592 | |
593 | /* Initialize the pll2 derived clocks */ |
594 | /* |
595 | * These four bits set the divide ratio between the PLL2 |
596 | * output and the USB clock. |
597 | * 0000 - Divide by 1 |
598 | * 0001 - Divide by 2 |
599 | * 0010 - Divide by 3 |
600 | * 0011 - Divide by 4 |
601 | * 0100 - Divide by 5 |
602 | * 0101 - Divide by 6 |
603 | * 0110 - Divide by 7 |
604 | * 0111 - Divide by 8 |
605 | * 1000 - Divide by 9 |
606 | * 1001 - Divide by 10 |
607 | * 1010 - Divide by 11 |
608 | * 1011 - Divide by 12 |
609 | * 1100 - Divide by 13 |
610 | * 1101 - Divide by 14 |
611 | * 1110 - Divide by 15 |
612 | * 1111 - Divide by 1 |
613 | * On power-on-reset these bits are reset to 0000b. |
614 | */ |
615 | clk_usb_div = (((value >> 28) & 0xf) + 1); |
616 | hw = clk_hw_register_fixed_factor(NULL, name: "usb_clk" , parent_name: "pll2" , flags: 0, mult: 1, div: clk_usb_div); |
617 | hw = clk_hw_register_gate(NULL, "ohci-platform" , |
618 | "usb_clk" , 0, |
619 | EP93XX_SYSCON_PWRCNT, |
620 | EP93XX_SYSCON_PWRCNT_USH_EN, |
621 | 0, |
622 | &clk_lock); |
623 | clk_hw_register_clkdev(hw, NULL, "ohci-platform" ); |
624 | |
625 | /* |
626 | * EP93xx SSP clock rate was doubled in version E2. For more information |
627 | * see: |
628 | * http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf |
629 | */ |
630 | clk_spi_div = 1; |
631 | if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2) |
632 | clk_spi_div = 2; |
633 | hw = clk_hw_register_fixed_factor(NULL, name: "ep93xx-spi.0" , parent_name: "xtali" , flags: 0, mult: 1, div: clk_spi_div); |
634 | clk_hw_register_clkdev(hw, NULL, "ep93xx-spi.0" ); |
635 | |
636 | /* pwm clock */ |
637 | hw = clk_hw_register_fixed_factor(NULL, name: "pwm_clk" , parent_name: "xtali" , flags: 0, mult: 1, div: 1); |
638 | clk_hw_register_clkdev(hw, "pwm_clk" , NULL); |
639 | |
640 | pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n" , |
641 | clk_pll1_rate / 1000000, clk_pll2_rate / 1000000); |
642 | pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n" , |
643 | clk_f_rate / 1000000, clk_h_rate / 1000000, |
644 | clk_p_rate / 1000000); |
645 | |
646 | ep93xx_uart_clock_init(); |
647 | |
648 | /* touchscreen/adc clock */ |
649 | hw = clk_hw_register_div(name: "ep93xx-adc" , |
650 | parent_name: "xtali" , |
651 | EP93XX_SYSCON_KEYTCHCLKDIV, |
652 | EP93XX_SYSCON_KEYTCHCLKDIV_TSEN, |
653 | EP93XX_SYSCON_KEYTCHCLKDIV_ADIV, |
654 | width: 1, |
655 | clk_divisors: adc_divisors, |
656 | ARRAY_SIZE(adc_divisors)); |
657 | |
658 | clk_hw_register_clkdev(hw, NULL, "ep93xx-adc" ); |
659 | |
660 | /* keypad clock */ |
661 | hw = clk_hw_register_div(name: "ep93xx-keypad" , |
662 | parent_name: "xtali" , |
663 | EP93XX_SYSCON_KEYTCHCLKDIV, |
664 | EP93XX_SYSCON_KEYTCHCLKDIV_KEN, |
665 | EP93XX_SYSCON_KEYTCHCLKDIV_KDIV, |
666 | width: 1, |
667 | clk_divisors: adc_divisors, |
668 | ARRAY_SIZE(adc_divisors)); |
669 | |
670 | clk_hw_register_clkdev(hw, NULL, "ep93xx-keypad" ); |
671 | |
672 | /* On reset PDIV and VDIV is set to zero, while PDIV zero |
673 | * means clock disable, VDIV shouldn't be zero. |
674 | * So i set both dividers to minimum. |
675 | */ |
676 | /* ENA - Enable CLK divider. */ |
677 | /* PDIV - 00 - Disable clock */ |
678 | /* VDIV - at least 2 */ |
679 | /* Check and enable video clk registers */ |
680 | value = __raw_readl(EP93XX_SYSCON_VIDCLKDIV); |
681 | value |= (1 << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2; |
682 | ep93xx_syscon_swlocked_write(val: value, EP93XX_SYSCON_VIDCLKDIV); |
683 | |
684 | /* check and enable i2s clk registers */ |
685 | value = __raw_readl(EP93XX_SYSCON_I2SCLKDIV); |
686 | value |= (1 << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2; |
687 | ep93xx_syscon_swlocked_write(val: value, EP93XX_SYSCON_I2SCLKDIV); |
688 | |
689 | /* video clk */ |
690 | hw = clk_hw_register_ddiv(name: "ep93xx-fb" , |
691 | EP93XX_SYSCON_VIDCLKDIV, |
692 | EP93XX_SYSCON_CLKDIV_ENABLE); |
693 | |
694 | clk_hw_register_clkdev(hw, NULL, "ep93xx-fb" ); |
695 | |
696 | /* i2s clk */ |
697 | hw = clk_hw_register_ddiv(name: "mclk" , |
698 | EP93XX_SYSCON_I2SCLKDIV, |
699 | EP93XX_SYSCON_CLKDIV_ENABLE); |
700 | |
701 | clk_hw_register_clkdev(hw, "mclk" , "ep93xx-i2s" ); |
702 | |
703 | /* i2s sclk */ |
704 | #define EP93XX_I2SCLKDIV_SDIV_SHIFT 16 |
705 | #define EP93XX_I2SCLKDIV_SDIV_WIDTH 1 |
706 | hw = clk_hw_register_div(name: "sclk" , |
707 | parent_name: "mclk" , |
708 | EP93XX_SYSCON_I2SCLKDIV, |
709 | EP93XX_SYSCON_I2SCLKDIV_SENA, |
710 | EP93XX_I2SCLKDIV_SDIV_SHIFT, |
711 | EP93XX_I2SCLKDIV_SDIV_WIDTH, |
712 | clk_divisors: sclk_divisors, |
713 | ARRAY_SIZE(sclk_divisors)); |
714 | |
715 | clk_hw_register_clkdev(hw, "sclk" , "ep93xx-i2s" ); |
716 | |
717 | /* i2s lrclk */ |
718 | #define EP93XX_I2SCLKDIV_LRDIV32_SHIFT 17 |
719 | #define EP93XX_I2SCLKDIV_LRDIV32_WIDTH 3 |
720 | hw = clk_hw_register_div(name: "lrclk" , |
721 | parent_name: "sclk" , |
722 | EP93XX_SYSCON_I2SCLKDIV, |
723 | EP93XX_SYSCON_I2SCLKDIV_SENA, |
724 | EP93XX_I2SCLKDIV_LRDIV32_SHIFT, |
725 | EP93XX_I2SCLKDIV_LRDIV32_WIDTH, |
726 | clk_divisors: lrclk_divisors, |
727 | ARRAY_SIZE(lrclk_divisors)); |
728 | |
729 | clk_hw_register_clkdev(hw, "lrclk" , "ep93xx-i2s" ); |
730 | |
731 | return 0; |
732 | } |
733 | postcore_initcall(ep93xx_clock_init); |
734 | |