Root/
1 | /* |
2 | * U300 clock implementation |
3 | * Copyright (C) 2007-2012 ST-Ericsson AB |
4 | * License terms: GNU General Public License (GPL) version 2 |
5 | * Author: Linus Walleij <linus.walleij@stericsson.com> |
6 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> |
7 | */ |
8 | #include <linux/clk.h> |
9 | #include <linux/clkdev.h> |
10 | #include <linux/err.h> |
11 | #include <linux/io.h> |
12 | #include <linux/clk-provider.h> |
13 | #include <linux/spinlock.h> |
14 | #include <mach/syscon.h> |
15 | |
16 | /* |
17 | * The clocking hierarchy currently looks like this. |
18 | * NOTE: the idea is NOT to show how the clocks are routed on the chip! |
19 | * The ideas is to show dependencies, so a clock higher up in the |
20 | * hierarchy has to be on in order for another clock to be on. Now, |
21 | * both CPU and DMA can actually be on top of the hierarchy, and that |
22 | * is not modeled currently. Instead we have the backbone AMBA bus on |
23 | * top. This bus cannot be programmed in any way but conceptually it |
24 | * needs to be active for the bridges and devices to transport data. |
25 | * |
26 | * Please be aware that a few clocks are hw controlled, which mean that |
27 | * the hw itself can turn on/off or change the rate of the clock when |
28 | * needed! |
29 | * |
30 | * AMBA bus |
31 | * | |
32 | * +- CPU |
33 | * +- FSMC NANDIF NAND Flash interface |
34 | * +- SEMI Shared Memory interface |
35 | * +- ISP Image Signal Processor (U335 only) |
36 | * +- CDS (U335 only) |
37 | * +- DMA Direct Memory Access Controller |
38 | * +- AAIF APP/ACC Inteface (Mobile Scalable Link, MSL) |
39 | * +- APEX |
40 | * +- VIDEO_ENC AVE2/3 Video Encoder |
41 | * +- XGAM Graphics Accelerator Controller |
42 | * +- AHB |
43 | * | |
44 | * +- ahb:0 AHB Bridge |
45 | * | | |
46 | * | +- ahb:1 INTCON Interrupt controller |
47 | * | +- ahb:3 MSPRO Memory Stick Pro controller |
48 | * | +- ahb:4 EMIF External Memory interface |
49 | * | |
50 | * +- fast:0 FAST bridge |
51 | * | | |
52 | * | +- fast:1 MMCSD MMC/SD card reader controller |
53 | * | +- fast:2 I2S0 PCM I2S channel 0 controller |
54 | * | +- fast:3 I2S1 PCM I2S channel 1 controller |
55 | * | +- fast:4 I2C0 I2C channel 0 controller |
56 | * | +- fast:5 I2C1 I2C channel 1 controller |
57 | * | +- fast:6 SPI SPI controller |
58 | * | +- fast:7 UART1 Secondary UART (U335 only) |
59 | * | |
60 | * +- slow:0 SLOW bridge |
61 | * | |
62 | * +- slow:1 SYSCON (not possible to control) |
63 | * +- slow:2 WDOG Watchdog |
64 | * +- slow:3 UART0 primary UART |
65 | * +- slow:4 TIMER_APP Application timer - used in Linux |
66 | * +- slow:5 KEYPAD controller |
67 | * +- slow:6 GPIO controller |
68 | * +- slow:7 RTC controller |
69 | * +- slow:8 BT Bus Tracer (not used currently) |
70 | * +- slow:9 EH Event Handler (not used currently) |
71 | * +- slow:a TIMER_ACC Access style timer (not used currently) |
72 | * +- slow:b PPM (U335 only, what is that?) |
73 | */ |
74 | |
75 | /* Global syscon virtual base */ |
76 | static void __iomem *syscon_vbase; |
77 | |
78 | /** |
79 | * struct clk_syscon - U300 syscon clock |
80 | * @hw: corresponding clock hardware entry |
81 | * @hw_ctrld: whether this clock is hardware controlled (for refcount etc) |
82 | * and does not need any magic pokes to be enabled/disabled |
83 | * @reset: state holder, whether this block's reset line is asserted or not |
84 | * @res_reg: reset line enable/disable flag register |
85 | * @res_bit: bit for resetting or taking this consumer out of reset |
86 | * @en_reg: clock line enable/disable flag register |
87 | * @en_bit: bit for enabling/disabling this consumer clock line |
88 | * @clk_val: magic value to poke in the register to enable/disable |
89 | * this one clock |
90 | */ |
91 | struct clk_syscon { |
92 | struct clk_hw hw; |
93 | bool hw_ctrld; |
94 | bool reset; |
95 | void __iomem *res_reg; |
96 | u8 res_bit; |
97 | void __iomem *en_reg; |
98 | u8 en_bit; |
99 | u16 clk_val; |
100 | }; |
101 | |
102 | #define to_syscon(_hw) container_of(_hw, struct clk_syscon, hw) |
103 | |
104 | static DEFINE_SPINLOCK(syscon_resetreg_lock); |
105 | |
106 | /* |
107 | * Reset control functions. We remember if a block has been |
108 | * taken out of reset and don't remove the reset assertion again |
109 | * and vice versa. Currently we only remove resets so the |
110 | * enablement function is defined out. |
111 | */ |
112 | static void syscon_block_reset_enable(struct clk_syscon *sclk) |
113 | { |
114 | unsigned long iflags; |
115 | u16 val; |
116 | |
117 | /* Not all blocks support resetting */ |
118 | if (!sclk->res_reg) |
119 | return; |
120 | spin_lock_irqsave(&syscon_resetreg_lock, iflags); |
121 | val = readw(sclk->res_reg); |
122 | val |= BIT(sclk->res_bit); |
123 | writew(val, sclk->res_reg); |
124 | spin_unlock_irqrestore(&syscon_resetreg_lock, iflags); |
125 | sclk->reset = true; |
126 | } |
127 | |
128 | static void syscon_block_reset_disable(struct clk_syscon *sclk) |
129 | { |
130 | unsigned long iflags; |
131 | u16 val; |
132 | |
133 | /* Not all blocks support resetting */ |
134 | if (!sclk->res_reg) |
135 | return; |
136 | spin_lock_irqsave(&syscon_resetreg_lock, iflags); |
137 | val = readw(sclk->res_reg); |
138 | val &= ~BIT(sclk->res_bit); |
139 | writew(val, sclk->res_reg); |
140 | spin_unlock_irqrestore(&syscon_resetreg_lock, iflags); |
141 | sclk->reset = false; |
142 | } |
143 | |
144 | static int syscon_clk_prepare(struct clk_hw *hw) |
145 | { |
146 | struct clk_syscon *sclk = to_syscon(hw); |
147 | |
148 | /* If the block is in reset, bring it out */ |
149 | if (sclk->reset) |
150 | syscon_block_reset_disable(sclk); |
151 | return 0; |
152 | } |
153 | |
154 | static void syscon_clk_unprepare(struct clk_hw *hw) |
155 | { |
156 | struct clk_syscon *sclk = to_syscon(hw); |
157 | |
158 | /* Please don't force the console into reset */ |
159 | if (sclk->clk_val == U300_SYSCON_SBCER_UART_CLK_EN) |
160 | return; |
161 | /* When unpreparing, force block into reset */ |
162 | if (!sclk->reset) |
163 | syscon_block_reset_enable(sclk); |
164 | } |
165 | |
166 | static int syscon_clk_enable(struct clk_hw *hw) |
167 | { |
168 | struct clk_syscon *sclk = to_syscon(hw); |
169 | |
170 | /* Don't touch the hardware controlled clocks */ |
171 | if (sclk->hw_ctrld) |
172 | return 0; |
173 | /* These cannot be controlled */ |
174 | if (sclk->clk_val == 0xFFFFU) |
175 | return 0; |
176 | |
177 | writew(sclk->clk_val, syscon_vbase + U300_SYSCON_SBCER); |
178 | return 0; |
179 | } |
180 | |
181 | static void syscon_clk_disable(struct clk_hw *hw) |
182 | { |
183 | struct clk_syscon *sclk = to_syscon(hw); |
184 | |
185 | /* Don't touch the hardware controlled clocks */ |
186 | if (sclk->hw_ctrld) |
187 | return; |
188 | if (sclk->clk_val == 0xFFFFU) |
189 | return; |
190 | /* Please don't disable the console port */ |
191 | if (sclk->clk_val == U300_SYSCON_SBCER_UART_CLK_EN) |
192 | return; |
193 | |
194 | writew(sclk->clk_val, syscon_vbase + U300_SYSCON_SBCDR); |
195 | } |
196 | |
197 | static int syscon_clk_is_enabled(struct clk_hw *hw) |
198 | { |
199 | struct clk_syscon *sclk = to_syscon(hw); |
200 | u16 val; |
201 | |
202 | /* If no enable register defined, it's always-on */ |
203 | if (!sclk->en_reg) |
204 | return 1; |
205 | |
206 | val = readw(sclk->en_reg); |
207 | val &= BIT(sclk->en_bit); |
208 | |
209 | return val ? 1 : 0; |
210 | } |
211 | |
212 | static u16 syscon_get_perf(void) |
213 | { |
214 | u16 val; |
215 | |
216 | val = readw(syscon_vbase + U300_SYSCON_CCR); |
217 | val &= U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK; |
218 | return val; |
219 | } |
220 | |
221 | static unsigned long |
222 | syscon_clk_recalc_rate(struct clk_hw *hw, |
223 | unsigned long parent_rate) |
224 | { |
225 | struct clk_syscon *sclk = to_syscon(hw); |
226 | u16 perf = syscon_get_perf(); |
227 | |
228 | switch(sclk->clk_val) { |
229 | case U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN: |
230 | case U300_SYSCON_SBCER_I2C0_CLK_EN: |
231 | case U300_SYSCON_SBCER_I2C1_CLK_EN: |
232 | case U300_SYSCON_SBCER_MMC_CLK_EN: |
233 | case U300_SYSCON_SBCER_SPI_CLK_EN: |
234 | /* The FAST clocks have one progression */ |
235 | switch(perf) { |
236 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: |
237 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: |
238 | return 13000000; |
239 | default: |
240 | return parent_rate; /* 26 MHz */ |
241 | } |
242 | case U300_SYSCON_SBCER_DMAC_CLK_EN: |
243 | case U300_SYSCON_SBCER_NANDIF_CLK_EN: |
244 | case U300_SYSCON_SBCER_XGAM_CLK_EN: |
245 | /* AMBA interconnect peripherals */ |
246 | switch(perf) { |
247 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: |
248 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: |
249 | return 6500000; |
250 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: |
251 | return 26000000; |
252 | default: |
253 | return parent_rate; /* 52 MHz */ |
254 | } |
255 | case U300_SYSCON_SBCER_SEMI_CLK_EN: |
256 | case U300_SYSCON_SBCER_EMIF_CLK_EN: |
257 | /* EMIF speeds */ |
258 | switch(perf) { |
259 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: |
260 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: |
261 | return 13000000; |
262 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: |
263 | return 52000000; |
264 | default: |
265 | return 104000000; |
266 | } |
267 | case U300_SYSCON_SBCER_CPU_CLK_EN: |
268 | /* And the fast CPU clock */ |
269 | switch(perf) { |
270 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: |
271 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: |
272 | return 13000000; |
273 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: |
274 | return 52000000; |
275 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: |
276 | return 104000000; |
277 | default: |
278 | return parent_rate; /* 208 MHz */ |
279 | } |
280 | default: |
281 | /* |
282 | * The SLOW clocks and default just inherit the rate of |
283 | * their parent (typically PLL13 13 MHz). |
284 | */ |
285 | return parent_rate; |
286 | } |
287 | } |
288 | |
289 | static long |
290 | syscon_clk_round_rate(struct clk_hw *hw, unsigned long rate, |
291 | unsigned long *prate) |
292 | { |
293 | struct clk_syscon *sclk = to_syscon(hw); |
294 | |
295 | if (sclk->clk_val != U300_SYSCON_SBCER_CPU_CLK_EN) |
296 | return *prate; |
297 | /* We really only support setting the rate of the CPU clock */ |
298 | if (rate <= 13000000) |
299 | return 13000000; |
300 | if (rate <= 52000000) |
301 | return 52000000; |
302 | if (rate <= 104000000) |
303 | return 104000000; |
304 | return 208000000; |
305 | } |
306 | |
307 | static int syscon_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
308 | unsigned long parent_rate) |
309 | { |
310 | struct clk_syscon *sclk = to_syscon(hw); |
311 | u16 val; |
312 | |
313 | /* We only support setting the rate of the CPU clock */ |
314 | if (sclk->clk_val != U300_SYSCON_SBCER_CPU_CLK_EN) |
315 | return -EINVAL; |
316 | switch (rate) { |
317 | case 13000000: |
318 | val = U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER; |
319 | break; |
320 | case 52000000: |
321 | val = U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE; |
322 | break; |
323 | case 104000000: |
324 | val = U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH; |
325 | break; |
326 | case 208000000: |
327 | val = U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST; |
328 | break; |
329 | default: |
330 | return -EINVAL; |
331 | } |
332 | val |= readw(syscon_vbase + U300_SYSCON_CCR) & |
333 | ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK ; |
334 | writew(val, syscon_vbase + U300_SYSCON_CCR); |
335 | return 0; |
336 | } |
337 | |
338 | static const struct clk_ops syscon_clk_ops = { |
339 | .prepare = syscon_clk_prepare, |
340 | .unprepare = syscon_clk_unprepare, |
341 | .enable = syscon_clk_enable, |
342 | .disable = syscon_clk_disable, |
343 | .is_enabled = syscon_clk_is_enabled, |
344 | .recalc_rate = syscon_clk_recalc_rate, |
345 | .round_rate = syscon_clk_round_rate, |
346 | .set_rate = syscon_clk_set_rate, |
347 | }; |
348 | |
349 | static struct clk * __init |
350 | syscon_clk_register(struct device *dev, const char *name, |
351 | const char *parent_name, unsigned long flags, |
352 | bool hw_ctrld, |
353 | void __iomem *res_reg, u8 res_bit, |
354 | void __iomem *en_reg, u8 en_bit, |
355 | u16 clk_val) |
356 | { |
357 | struct clk *clk; |
358 | struct clk_syscon *sclk; |
359 | struct clk_init_data init; |
360 | |
361 | sclk = kzalloc(sizeof(struct clk_syscon), GFP_KERNEL); |
362 | if (!sclk) { |
363 | pr_err("could not allocate syscon clock %s\n", |
364 | name); |
365 | return ERR_PTR(-ENOMEM); |
366 | } |
367 | init.name = name; |
368 | init.ops = &syscon_clk_ops; |
369 | init.flags = flags; |
370 | init.parent_names = (parent_name ? &parent_name : NULL); |
371 | init.num_parents = (parent_name ? 1 : 0); |
372 | sclk->hw.init = &init; |
373 | sclk->hw_ctrld = hw_ctrld; |
374 | /* Assume the block is in reset at registration */ |
375 | sclk->reset = true; |
376 | sclk->res_reg = res_reg; |
377 | sclk->res_bit = res_bit; |
378 | sclk->en_reg = en_reg; |
379 | sclk->en_bit = en_bit; |
380 | sclk->clk_val = clk_val; |
381 | |
382 | clk = clk_register(dev, &sclk->hw); |
383 | if (IS_ERR(clk)) |
384 | kfree(sclk); |
385 | |
386 | return clk; |
387 | } |
388 | |
389 | /** |
390 | * struct clk_mclk - U300 MCLK clock (MMC/SD clock) |
391 | * @hw: corresponding clock hardware entry |
392 | * @is_mspro: if this is the memory stick clock rather than MMC/SD |
393 | */ |
394 | struct clk_mclk { |
395 | struct clk_hw hw; |
396 | bool is_mspro; |
397 | }; |
398 | |
399 | #define to_mclk(_hw) container_of(_hw, struct clk_mclk, hw) |
400 | |
401 | static int mclk_clk_prepare(struct clk_hw *hw) |
402 | { |
403 | struct clk_mclk *mclk = to_mclk(hw); |
404 | u16 val; |
405 | |
406 | /* The MMC and MSPRO clocks need some special set-up */ |
407 | if (!mclk->is_mspro) { |
408 | /* Set default MMC clock divisor to 18.9 MHz */ |
409 | writew(0x0054U, syscon_vbase + U300_SYSCON_MMF0R); |
410 | val = readw(syscon_vbase + U300_SYSCON_MMCR); |
411 | /* Disable the MMC feedback clock */ |
412 | val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE; |
413 | /* Disable MSPRO frequency */ |
414 | val &= ~U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE; |
415 | writew(val, syscon_vbase + U300_SYSCON_MMCR); |
416 | } else { |
417 | val = readw(syscon_vbase + U300_SYSCON_MMCR); |
418 | /* Disable the MMC feedback clock */ |
419 | val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE; |
420 | /* Enable MSPRO frequency */ |
421 | val |= U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE; |
422 | writew(val, syscon_vbase + U300_SYSCON_MMCR); |
423 | } |
424 | |
425 | return 0; |
426 | } |
427 | |
428 | static unsigned long |
429 | mclk_clk_recalc_rate(struct clk_hw *hw, |
430 | unsigned long parent_rate) |
431 | { |
432 | u16 perf = syscon_get_perf(); |
433 | |
434 | switch (perf) { |
435 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: |
436 | /* |
437 | * Here, the 208 MHz PLL gets shut down and the always |
438 | * on 13 MHz PLL used for RTC etc kicks into use |
439 | * instead. |
440 | */ |
441 | return 13000000; |
442 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: |
443 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: |
444 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: |
445 | case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: |
446 | { |
447 | /* |
448 | * This clock is under program control. The register is |
449 | * divided in two nybbles, bit 7-4 gives cycles-1 to count |
450 | * high, bit 3-0 gives cycles-1 to count low. Distribute |
451 | * these with no more than 1 cycle difference between |
452 | * low and high and add low and high to get the actual |
453 | * divisor. The base PLL is 208 MHz. Writing 0x00 will |
454 | * divide by 1 and 1 so the highest frequency possible |
455 | * is 104 MHz. |
456 | * |
457 | * e.g. 0x54 => |
458 | * f = 208 / ((5+1) + (4+1)) = 208 / 11 = 18.9 MHz |
459 | */ |
460 | u16 val = readw(syscon_vbase + U300_SYSCON_MMF0R) & |
461 | U300_SYSCON_MMF0R_MASK; |
462 | switch (val) { |
463 | case 0x0054: |
464 | return 18900000; |
465 | case 0x0044: |
466 | return 20800000; |
467 | case 0x0043: |
468 | return 23100000; |
469 | case 0x0033: |
470 | return 26000000; |
471 | case 0x0032: |
472 | return 29700000; |
473 | case 0x0022: |
474 | return 34700000; |
475 | case 0x0021: |
476 | return 41600000; |
477 | case 0x0011: |
478 | return 52000000; |
479 | case 0x0000: |
480 | return 104000000; |
481 | default: |
482 | break; |
483 | } |
484 | } |
485 | default: |
486 | break; |
487 | } |
488 | return parent_rate; |
489 | } |
490 | |
491 | static long |
492 | mclk_clk_round_rate(struct clk_hw *hw, unsigned long rate, |
493 | unsigned long *prate) |
494 | { |
495 | if (rate <= 18900000) |
496 | return 18900000; |
497 | if (rate <= 20800000) |
498 | return 20800000; |
499 | if (rate <= 23100000) |
500 | return 23100000; |
501 | if (rate <= 26000000) |
502 | return 26000000; |
503 | if (rate <= 29700000) |
504 | return 29700000; |
505 | if (rate <= 34700000) |
506 | return 34700000; |
507 | if (rate <= 41600000) |
508 | return 41600000; |
509 | /* Highest rate */ |
510 | return 52000000; |
511 | } |
512 | |
513 | static int mclk_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
514 | unsigned long parent_rate) |
515 | { |
516 | u16 val; |
517 | u16 reg; |
518 | |
519 | switch (rate) { |
520 | case 18900000: |
521 | val = 0x0054; |
522 | break; |
523 | case 20800000: |
524 | val = 0x0044; |
525 | break; |
526 | case 23100000: |
527 | val = 0x0043; |
528 | break; |
529 | case 26000000: |
530 | val = 0x0033; |
531 | break; |
532 | case 29700000: |
533 | val = 0x0032; |
534 | break; |
535 | case 34700000: |
536 | val = 0x0022; |
537 | break; |
538 | case 41600000: |
539 | val = 0x0021; |
540 | break; |
541 | case 52000000: |
542 | val = 0x0011; |
543 | break; |
544 | case 104000000: |
545 | val = 0x0000; |
546 | break; |
547 | default: |
548 | return -EINVAL; |
549 | } |
550 | |
551 | reg = readw(syscon_vbase + U300_SYSCON_MMF0R) & |
552 | ~U300_SYSCON_MMF0R_MASK; |
553 | writew(reg | val, syscon_vbase + U300_SYSCON_MMF0R); |
554 | return 0; |
555 | } |
556 | |
557 | static const struct clk_ops mclk_ops = { |
558 | .prepare = mclk_clk_prepare, |
559 | .recalc_rate = mclk_clk_recalc_rate, |
560 | .round_rate = mclk_clk_round_rate, |
561 | .set_rate = mclk_clk_set_rate, |
562 | }; |
563 | |
564 | static struct clk * __init |
565 | mclk_clk_register(struct device *dev, const char *name, |
566 | const char *parent_name, bool is_mspro) |
567 | { |
568 | struct clk *clk; |
569 | struct clk_mclk *mclk; |
570 | struct clk_init_data init; |
571 | |
572 | mclk = kzalloc(sizeof(struct clk_mclk), GFP_KERNEL); |
573 | if (!mclk) { |
574 | pr_err("could not allocate MMC/SD clock %s\n", |
575 | name); |
576 | return ERR_PTR(-ENOMEM); |
577 | } |
578 | init.name = "mclk"; |
579 | init.ops = &mclk_ops; |
580 | init.flags = 0; |
581 | init.parent_names = (parent_name ? &parent_name : NULL); |
582 | init.num_parents = (parent_name ? 1 : 0); |
583 | mclk->hw.init = &init; |
584 | mclk->is_mspro = is_mspro; |
585 | |
586 | clk = clk_register(dev, &mclk->hw); |
587 | if (IS_ERR(clk)) |
588 | kfree(mclk); |
589 | |
590 | return clk; |
591 | } |
592 | |
593 | void __init u300_clk_init(void __iomem *base) |
594 | { |
595 | u16 val; |
596 | struct clk *clk; |
597 | |
598 | syscon_vbase = base; |
599 | |
600 | /* Set system to run at PLL208, max performance, a known state. */ |
601 | val = readw(syscon_vbase + U300_SYSCON_CCR); |
602 | val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK; |
603 | writew(val, syscon_vbase + U300_SYSCON_CCR); |
604 | /* Wait for the PLL208 to lock if not locked in yet */ |
605 | while (!(readw(syscon_vbase + U300_SYSCON_CSR) & |
606 | U300_SYSCON_CSR_PLL208_LOCK_IND)); |
607 | |
608 | /* Power management enable */ |
609 | val = readw(syscon_vbase + U300_SYSCON_PMCR); |
610 | val |= U300_SYSCON_PMCR_PWR_MGNT_ENABLE; |
611 | writew(val, syscon_vbase + U300_SYSCON_PMCR); |
612 | |
613 | /* These are always available (RTC and PLL13) */ |
614 | clk = clk_register_fixed_rate(NULL, "app_32_clk", NULL, |
615 | CLK_IS_ROOT, 32768); |
616 | /* The watchdog sits directly on the 32 kHz clock */ |
617 | clk_register_clkdev(clk, NULL, "coh901327_wdog"); |
618 | clk = clk_register_fixed_rate(NULL, "pll13", NULL, |
619 | CLK_IS_ROOT, 13000000); |
620 | |
621 | /* These derive from PLL208 */ |
622 | clk = clk_register_fixed_rate(NULL, "pll208", NULL, |
623 | CLK_IS_ROOT, 208000000); |
624 | clk = clk_register_fixed_factor(NULL, "app_208_clk", "pll208", |
625 | 0, 1, 1); |
626 | clk = clk_register_fixed_factor(NULL, "app_104_clk", "pll208", |
627 | 0, 1, 2); |
628 | clk = clk_register_fixed_factor(NULL, "app_52_clk", "pll208", |
629 | 0, 1, 4); |
630 | /* The 52 MHz is divided down to 26 MHz */ |
631 | clk = clk_register_fixed_factor(NULL, "app_26_clk", "app_52_clk", |
632 | 0, 1, 2); |
633 | |
634 | /* Directly on the AMBA interconnect */ |
635 | clk = syscon_clk_register(NULL, "cpu_clk", "app_208_clk", 0, true, |
636 | syscon_vbase + U300_SYSCON_RRR, 3, |
637 | syscon_vbase + U300_SYSCON_CERR, 3, |
638 | U300_SYSCON_SBCER_CPU_CLK_EN); |
639 | clk = syscon_clk_register(NULL, "dmac_clk", "app_52_clk", 0, true, |
640 | syscon_vbase + U300_SYSCON_RRR, 4, |
641 | syscon_vbase + U300_SYSCON_CERR, 4, |
642 | U300_SYSCON_SBCER_DMAC_CLK_EN); |
643 | clk_register_clkdev(clk, NULL, "dma"); |
644 | clk = syscon_clk_register(NULL, "fsmc_clk", "app_52_clk", 0, false, |
645 | syscon_vbase + U300_SYSCON_RRR, 6, |
646 | syscon_vbase + U300_SYSCON_CERR, 6, |
647 | U300_SYSCON_SBCER_NANDIF_CLK_EN); |
648 | clk_register_clkdev(clk, NULL, "fsmc-nand"); |
649 | clk = syscon_clk_register(NULL, "xgam_clk", "app_52_clk", 0, true, |
650 | syscon_vbase + U300_SYSCON_RRR, 8, |
651 | syscon_vbase + U300_SYSCON_CERR, 8, |
652 | U300_SYSCON_SBCER_XGAM_CLK_EN); |
653 | clk_register_clkdev(clk, NULL, "xgam"); |
654 | clk = syscon_clk_register(NULL, "semi_clk", "app_104_clk", 0, false, |
655 | syscon_vbase + U300_SYSCON_RRR, 9, |
656 | syscon_vbase + U300_SYSCON_CERR, 9, |
657 | U300_SYSCON_SBCER_SEMI_CLK_EN); |
658 | clk_register_clkdev(clk, NULL, "semi"); |
659 | |
660 | /* AHB bridge clocks */ |
661 | clk = syscon_clk_register(NULL, "ahb_subsys_clk", "app_52_clk", 0, true, |
662 | syscon_vbase + U300_SYSCON_RRR, 10, |
663 | syscon_vbase + U300_SYSCON_CERR, 10, |
664 | U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN); |
665 | clk = syscon_clk_register(NULL, "intcon_clk", "ahb_subsys_clk", 0, false, |
666 | syscon_vbase + U300_SYSCON_RRR, 12, |
667 | syscon_vbase + U300_SYSCON_CERR, 12, |
668 | /* Cannot be enabled, just taken out of reset */ |
669 | 0xFFFFU); |
670 | clk_register_clkdev(clk, NULL, "intcon"); |
671 | clk = syscon_clk_register(NULL, "emif_clk", "ahb_subsys_clk", 0, false, |
672 | syscon_vbase + U300_SYSCON_RRR, 5, |
673 | syscon_vbase + U300_SYSCON_CERR, 5, |
674 | U300_SYSCON_SBCER_EMIF_CLK_EN); |
675 | clk_register_clkdev(clk, NULL, "pl172"); |
676 | |
677 | /* FAST bridge clocks */ |
678 | clk = syscon_clk_register(NULL, "fast_clk", "app_26_clk", 0, true, |
679 | syscon_vbase + U300_SYSCON_RFR, 0, |
680 | syscon_vbase + U300_SYSCON_CEFR, 0, |
681 | U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN); |
682 | clk = syscon_clk_register(NULL, "i2c0_p_clk", "fast_clk", 0, false, |
683 | syscon_vbase + U300_SYSCON_RFR, 1, |
684 | syscon_vbase + U300_SYSCON_CEFR, 1, |
685 | U300_SYSCON_SBCER_I2C0_CLK_EN); |
686 | clk_register_clkdev(clk, NULL, "stu300.0"); |
687 | clk = syscon_clk_register(NULL, "i2c1_p_clk", "fast_clk", 0, false, |
688 | syscon_vbase + U300_SYSCON_RFR, 2, |
689 | syscon_vbase + U300_SYSCON_CEFR, 2, |
690 | U300_SYSCON_SBCER_I2C1_CLK_EN); |
691 | clk_register_clkdev(clk, NULL, "stu300.1"); |
692 | clk = syscon_clk_register(NULL, "mmc_p_clk", "fast_clk", 0, false, |
693 | syscon_vbase + U300_SYSCON_RFR, 5, |
694 | syscon_vbase + U300_SYSCON_CEFR, 5, |
695 | U300_SYSCON_SBCER_MMC_CLK_EN); |
696 | clk_register_clkdev(clk, "apb_pclk", "mmci"); |
697 | clk = syscon_clk_register(NULL, "spi_p_clk", "fast_clk", 0, false, |
698 | syscon_vbase + U300_SYSCON_RFR, 6, |
699 | syscon_vbase + U300_SYSCON_CEFR, 6, |
700 | U300_SYSCON_SBCER_SPI_CLK_EN); |
701 | /* The SPI has no external clock for the outward bus, uses the pclk */ |
702 | clk_register_clkdev(clk, NULL, "pl022"); |
703 | clk_register_clkdev(clk, "apb_pclk", "pl022"); |
704 | |
705 | /* SLOW bridge clocks */ |
706 | clk = syscon_clk_register(NULL, "slow_clk", "pll13", 0, true, |
707 | syscon_vbase + U300_SYSCON_RSR, 0, |
708 | syscon_vbase + U300_SYSCON_CESR, 0, |
709 | U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN); |
710 | clk = syscon_clk_register(NULL, "uart0_clk", "slow_clk", 0, false, |
711 | syscon_vbase + U300_SYSCON_RSR, 1, |
712 | syscon_vbase + U300_SYSCON_CESR, 1, |
713 | U300_SYSCON_SBCER_UART_CLK_EN); |
714 | /* Same clock is used for APB and outward bus */ |
715 | clk_register_clkdev(clk, NULL, "uart0"); |
716 | clk_register_clkdev(clk, "apb_pclk", "uart0"); |
717 | clk = syscon_clk_register(NULL, "gpio_clk", "slow_clk", 0, false, |
718 | syscon_vbase + U300_SYSCON_RSR, 4, |
719 | syscon_vbase + U300_SYSCON_CESR, 4, |
720 | U300_SYSCON_SBCER_GPIO_CLK_EN); |
721 | clk_register_clkdev(clk, NULL, "u300-gpio"); |
722 | clk = syscon_clk_register(NULL, "keypad_clk", "slow_clk", 0, false, |
723 | syscon_vbase + U300_SYSCON_RSR, 5, |
724 | syscon_vbase + U300_SYSCON_CESR, 6, |
725 | U300_SYSCON_SBCER_KEYPAD_CLK_EN); |
726 | clk_register_clkdev(clk, NULL, "coh901461-keypad"); |
727 | clk = syscon_clk_register(NULL, "rtc_clk", "slow_clk", 0, true, |
728 | syscon_vbase + U300_SYSCON_RSR, 6, |
729 | /* No clock enable register bit */ |
730 | NULL, 0, 0xFFFFU); |
731 | clk_register_clkdev(clk, NULL, "rtc-coh901331"); |
732 | clk = syscon_clk_register(NULL, "app_tmr_clk", "slow_clk", 0, false, |
733 | syscon_vbase + U300_SYSCON_RSR, 7, |
734 | syscon_vbase + U300_SYSCON_CESR, 7, |
735 | U300_SYSCON_SBCER_APP_TMR_CLK_EN); |
736 | clk_register_clkdev(clk, NULL, "apptimer"); |
737 | clk = syscon_clk_register(NULL, "acc_tmr_clk", "slow_clk", 0, false, |
738 | syscon_vbase + U300_SYSCON_RSR, 8, |
739 | syscon_vbase + U300_SYSCON_CESR, 8, |
740 | U300_SYSCON_SBCER_ACC_TMR_CLK_EN); |
741 | clk_register_clkdev(clk, NULL, "timer"); |
742 | |
743 | /* Then this special MMC/SD clock */ |
744 | clk = mclk_clk_register(NULL, "mmc_clk", "mmc_p_clk", false); |
745 | clk_register_clkdev(clk, NULL, "mmci"); |
746 | } |
747 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9