diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-05-09 03:00:40 -0400 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-05-09 03:00:40 -0400 |
commit | c818f97bc3266f0fbf619f2348d951272f8ac335 (patch) | |
tree | 949aaaaa018e9fe3809de9093bd379b19e2b469a /arch | |
parent | 2acd1b6f889c04f8f303a5a11993f60fda6a7885 (diff) |
ARM i.MX: remove now unused clock files
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-imx/clock-imx1.c | 636 | ||||
-rw-r--r-- | arch/arm/mach-imx/clock-imx21.c | 1239 | ||||
-rw-r--r-- | arch/arm/mach-imx/clock-imx25.c | 346 | ||||
-rw-r--r-- | arch/arm/mach-imx/clock-imx27.c | 785 | ||||
-rw-r--r-- | arch/arm/mach-imx/clock-imx31.c | 630 | ||||
-rw-r--r-- | arch/arm/mach-imx/clock-imx35.c | 536 | ||||
-rw-r--r-- | arch/arm/mach-imx/clock-imx6q.c | 2111 | ||||
-rw-r--r-- | arch/arm/mach-imx/clock-mx51-mx53.c | 1675 |
8 files changed, 0 insertions, 7958 deletions
diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c deleted file mode 100644 index 4aabeb241563..000000000000 --- a/arch/arm/mach-imx/clock-imx1.c +++ /dev/null | |||
@@ -1,636 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/list.h> | ||
21 | #include <linux/math64.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/clkdev.h> | ||
26 | |||
27 | #include <mach/clock.h> | ||
28 | #include <mach/hardware.h> | ||
29 | #include <mach/common.h> | ||
30 | |||
31 | #define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off))) | ||
32 | |||
33 | /* CCM register addresses */ | ||
34 | #define CCM_CSCR IO_ADDR_CCM(0x0) | ||
35 | #define CCM_MPCTL0 IO_ADDR_CCM(0x4) | ||
36 | #define CCM_SPCTL0 IO_ADDR_CCM(0xc) | ||
37 | #define CCM_PCDR IO_ADDR_CCM(0x20) | ||
38 | |||
39 | #define CCM_CSCR_CLKO_OFFSET 29 | ||
40 | #define CCM_CSCR_CLKO_MASK (0x7 << 29) | ||
41 | #define CCM_CSCR_USB_OFFSET 26 | ||
42 | #define CCM_CSCR_USB_MASK (0x7 << 26) | ||
43 | #define CCM_CSCR_OSC_EN_SHIFT 17 | ||
44 | #define CCM_CSCR_SYSTEM_SEL (1 << 16) | ||
45 | #define CCM_CSCR_BCLK_OFFSET 10 | ||
46 | #define CCM_CSCR_BCLK_MASK (0xf << 10) | ||
47 | #define CCM_CSCR_PRESC (1 << 15) | ||
48 | |||
49 | #define CCM_PCDR_PCLK3_OFFSET 16 | ||
50 | #define CCM_PCDR_PCLK3_MASK (0x7f << 16) | ||
51 | #define CCM_PCDR_PCLK2_OFFSET 4 | ||
52 | #define CCM_PCDR_PCLK2_MASK (0xf << 4) | ||
53 | #define CCM_PCDR_PCLK1_OFFSET 0 | ||
54 | #define CCM_PCDR_PCLK1_MASK 0xf | ||
55 | |||
56 | #define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off))) | ||
57 | |||
58 | /* SCM register addresses */ | ||
59 | #define SCM_GCCR IO_ADDR_SCM(0xc) | ||
60 | |||
61 | #define SCM_GCCR_DMA_CLK_EN_OFFSET 3 | ||
62 | #define SCM_GCCR_CSI_CLK_EN_OFFSET 2 | ||
63 | #define SCM_GCCR_MMA_CLK_EN_OFFSET 1 | ||
64 | #define SCM_GCCR_USBD_CLK_EN_OFFSET 0 | ||
65 | |||
66 | static int _clk_enable(struct clk *clk) | ||
67 | { | ||
68 | unsigned int reg; | ||
69 | |||
70 | reg = __raw_readl(clk->enable_reg); | ||
71 | reg |= 1 << clk->enable_shift; | ||
72 | __raw_writel(reg, clk->enable_reg); | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static void _clk_disable(struct clk *clk) | ||
78 | { | ||
79 | unsigned int reg; | ||
80 | |||
81 | reg = __raw_readl(clk->enable_reg); | ||
82 | reg &= ~(1 << clk->enable_shift); | ||
83 | __raw_writel(reg, clk->enable_reg); | ||
84 | } | ||
85 | |||
86 | static int _clk_can_use_parent(const struct clk *clk_arr[], unsigned int size, | ||
87 | struct clk *parent) | ||
88 | { | ||
89 | int i; | ||
90 | |||
91 | for (i = 0; i < size; i++) | ||
92 | if (parent == clk_arr[i]) | ||
93 | return i; | ||
94 | |||
95 | return -EINVAL; | ||
96 | } | ||
97 | |||
98 | static unsigned long | ||
99 | _clk_simple_round_rate(struct clk *clk, unsigned long rate, unsigned int limit) | ||
100 | { | ||
101 | int div; | ||
102 | unsigned long parent_rate; | ||
103 | |||
104 | parent_rate = clk_get_rate(clk->parent); | ||
105 | |||
106 | div = parent_rate / rate; | ||
107 | if (parent_rate % rate) | ||
108 | div++; | ||
109 | |||
110 | if (div > limit) | ||
111 | div = limit; | ||
112 | |||
113 | return parent_rate / div; | ||
114 | } | ||
115 | |||
116 | static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate) | ||
117 | { | ||
118 | return clk->parent->round_rate(clk->parent, rate); | ||
119 | } | ||
120 | |||
121 | static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) | ||
122 | { | ||
123 | return clk->parent->set_rate(clk->parent, rate); | ||
124 | } | ||
125 | |||
126 | static unsigned long clk16m_get_rate(struct clk *clk) | ||
127 | { | ||
128 | return 16000000; | ||
129 | } | ||
130 | |||
131 | static struct clk clk16m = { | ||
132 | .get_rate = clk16m_get_rate, | ||
133 | .enable = _clk_enable, | ||
134 | .enable_reg = CCM_CSCR, | ||
135 | .enable_shift = CCM_CSCR_OSC_EN_SHIFT, | ||
136 | .disable = _clk_disable, | ||
137 | }; | ||
138 | |||
139 | /* in Hz */ | ||
140 | static unsigned long clk32_rate; | ||
141 | |||
142 | static unsigned long clk32_get_rate(struct clk *clk) | ||
143 | { | ||
144 | return clk32_rate; | ||
145 | } | ||
146 | |||
147 | static struct clk clk32 = { | ||
148 | .get_rate = clk32_get_rate, | ||
149 | }; | ||
150 | |||
151 | static unsigned long clk32_premult_get_rate(struct clk *clk) | ||
152 | { | ||
153 | return clk_get_rate(clk->parent) * 512; | ||
154 | } | ||
155 | |||
156 | static struct clk clk32_premult = { | ||
157 | .parent = &clk32, | ||
158 | .get_rate = clk32_premult_get_rate, | ||
159 | }; | ||
160 | |||
161 | static const struct clk *prem_clk_clocks[] = { | ||
162 | &clk32_premult, | ||
163 | &clk16m, | ||
164 | }; | ||
165 | |||
166 | static int prem_clk_set_parent(struct clk *clk, struct clk *parent) | ||
167 | { | ||
168 | int i; | ||
169 | unsigned int reg = __raw_readl(CCM_CSCR); | ||
170 | |||
171 | i = _clk_can_use_parent(prem_clk_clocks, ARRAY_SIZE(prem_clk_clocks), | ||
172 | parent); | ||
173 | |||
174 | switch (i) { | ||
175 | case 0: | ||
176 | reg &= ~CCM_CSCR_SYSTEM_SEL; | ||
177 | break; | ||
178 | case 1: | ||
179 | reg |= CCM_CSCR_SYSTEM_SEL; | ||
180 | break; | ||
181 | default: | ||
182 | return i; | ||
183 | } | ||
184 | |||
185 | __raw_writel(reg, CCM_CSCR); | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static struct clk prem_clk = { | ||
191 | .set_parent = prem_clk_set_parent, | ||
192 | }; | ||
193 | |||
194 | static unsigned long system_clk_get_rate(struct clk *clk) | ||
195 | { | ||
196 | return mxc_decode_pll(__raw_readl(CCM_SPCTL0), | ||
197 | clk_get_rate(clk->parent)); | ||
198 | } | ||
199 | |||
200 | static struct clk system_clk = { | ||
201 | .parent = &prem_clk, | ||
202 | .get_rate = system_clk_get_rate, | ||
203 | }; | ||
204 | |||
205 | static unsigned long mcu_clk_get_rate(struct clk *clk) | ||
206 | { | ||
207 | return mxc_decode_pll(__raw_readl(CCM_MPCTL0), | ||
208 | clk_get_rate(clk->parent)); | ||
209 | } | ||
210 | |||
211 | static struct clk mcu_clk = { | ||
212 | .parent = &clk32_premult, | ||
213 | .get_rate = mcu_clk_get_rate, | ||
214 | }; | ||
215 | |||
216 | static unsigned long fclk_get_rate(struct clk *clk) | ||
217 | { | ||
218 | unsigned long fclk = clk_get_rate(clk->parent); | ||
219 | |||
220 | if (__raw_readl(CCM_CSCR) & CCM_CSCR_PRESC) | ||
221 | fclk /= 2; | ||
222 | |||
223 | return fclk; | ||
224 | } | ||
225 | |||
226 | static struct clk fclk = { | ||
227 | .parent = &mcu_clk, | ||
228 | .get_rate = fclk_get_rate, | ||
229 | }; | ||
230 | |||
231 | /* | ||
232 | * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA ) | ||
233 | */ | ||
234 | static unsigned long hclk_get_rate(struct clk *clk) | ||
235 | { | ||
236 | return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) & | ||
237 | CCM_CSCR_BCLK_MASK) >> CCM_CSCR_BCLK_OFFSET) + 1); | ||
238 | } | ||
239 | |||
240 | static unsigned long hclk_round_rate(struct clk *clk, unsigned long rate) | ||
241 | { | ||
242 | return _clk_simple_round_rate(clk, rate, 16); | ||
243 | } | ||
244 | |||
245 | static int hclk_set_rate(struct clk *clk, unsigned long rate) | ||
246 | { | ||
247 | unsigned int div; | ||
248 | unsigned int reg; | ||
249 | unsigned long parent_rate; | ||
250 | |||
251 | parent_rate = clk_get_rate(clk->parent); | ||
252 | |||
253 | div = parent_rate / rate; | ||
254 | |||
255 | if (div > 16 || div < 1 || ((parent_rate / div) != rate)) | ||
256 | return -EINVAL; | ||
257 | |||
258 | div--; | ||
259 | |||
260 | reg = __raw_readl(CCM_CSCR); | ||
261 | reg &= ~CCM_CSCR_BCLK_MASK; | ||
262 | reg |= div << CCM_CSCR_BCLK_OFFSET; | ||
263 | __raw_writel(reg, CCM_CSCR); | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static struct clk hclk = { | ||
269 | .parent = &system_clk, | ||
270 | .get_rate = hclk_get_rate, | ||
271 | .round_rate = hclk_round_rate, | ||
272 | .set_rate = hclk_set_rate, | ||
273 | }; | ||
274 | |||
275 | static unsigned long clk48m_get_rate(struct clk *clk) | ||
276 | { | ||
277 | return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) & | ||
278 | CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET) + 1); | ||
279 | } | ||
280 | |||
281 | static unsigned long clk48m_round_rate(struct clk *clk, unsigned long rate) | ||
282 | { | ||
283 | return _clk_simple_round_rate(clk, rate, 8); | ||
284 | } | ||
285 | |||
286 | static int clk48m_set_rate(struct clk *clk, unsigned long rate) | ||
287 | { | ||
288 | unsigned int div; | ||
289 | unsigned int reg; | ||
290 | unsigned long parent_rate; | ||
291 | |||
292 | parent_rate = clk_get_rate(clk->parent); | ||
293 | |||
294 | div = parent_rate / rate; | ||
295 | |||
296 | if (div > 8 || div < 1 || ((parent_rate / div) != rate)) | ||
297 | return -EINVAL; | ||
298 | |||
299 | div--; | ||
300 | |||
301 | reg = __raw_readl(CCM_CSCR); | ||
302 | reg &= ~CCM_CSCR_USB_MASK; | ||
303 | reg |= div << CCM_CSCR_USB_OFFSET; | ||
304 | __raw_writel(reg, CCM_CSCR); | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static struct clk clk48m = { | ||
310 | .parent = &system_clk, | ||
311 | .get_rate = clk48m_get_rate, | ||
312 | .round_rate = clk48m_round_rate, | ||
313 | .set_rate = clk48m_set_rate, | ||
314 | }; | ||
315 | |||
316 | /* | ||
317 | * get peripheral clock 1 ( UART[12], Timer[12], PWM ) | ||
318 | */ | ||
319 | static unsigned long perclk1_get_rate(struct clk *clk) | ||
320 | { | ||
321 | return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) & | ||
322 | CCM_PCDR_PCLK1_MASK) >> CCM_PCDR_PCLK1_OFFSET) + 1); | ||
323 | } | ||
324 | |||
325 | static unsigned long perclk1_round_rate(struct clk *clk, unsigned long rate) | ||
326 | { | ||
327 | return _clk_simple_round_rate(clk, rate, 16); | ||
328 | } | ||
329 | |||
330 | static int perclk1_set_rate(struct clk *clk, unsigned long rate) | ||
331 | { | ||
332 | unsigned int div; | ||
333 | unsigned int reg; | ||
334 | unsigned long parent_rate; | ||
335 | |||
336 | parent_rate = clk_get_rate(clk->parent); | ||
337 | |||
338 | div = parent_rate / rate; | ||
339 | |||
340 | if (div > 16 || div < 1 || ((parent_rate / div) != rate)) | ||
341 | return -EINVAL; | ||
342 | |||
343 | div--; | ||
344 | |||
345 | reg = __raw_readl(CCM_PCDR); | ||
346 | reg &= ~CCM_PCDR_PCLK1_MASK; | ||
347 | reg |= div << CCM_PCDR_PCLK1_OFFSET; | ||
348 | __raw_writel(reg, CCM_PCDR); | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | /* | ||
354 | * get peripheral clock 2 ( LCD, SD, SPI[12] ) | ||
355 | */ | ||
356 | static unsigned long perclk2_get_rate(struct clk *clk) | ||
357 | { | ||
358 | return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) & | ||
359 | CCM_PCDR_PCLK2_MASK) >> CCM_PCDR_PCLK2_OFFSET) + 1); | ||
360 | } | ||
361 | |||
362 | static unsigned long perclk2_round_rate(struct clk *clk, unsigned long rate) | ||
363 | { | ||
364 | return _clk_simple_round_rate(clk, rate, 16); | ||
365 | } | ||
366 | |||
367 | static int perclk2_set_rate(struct clk *clk, unsigned long rate) | ||
368 | { | ||
369 | unsigned int div; | ||
370 | unsigned int reg; | ||
371 | unsigned long parent_rate; | ||
372 | |||
373 | parent_rate = clk_get_rate(clk->parent); | ||
374 | |||
375 | div = parent_rate / rate; | ||
376 | |||
377 | if (div > 16 || div < 1 || ((parent_rate / div) != rate)) | ||
378 | return -EINVAL; | ||
379 | |||
380 | div--; | ||
381 | |||
382 | reg = __raw_readl(CCM_PCDR); | ||
383 | reg &= ~CCM_PCDR_PCLK2_MASK; | ||
384 | reg |= div << CCM_PCDR_PCLK2_OFFSET; | ||
385 | __raw_writel(reg, CCM_PCDR); | ||
386 | |||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * get peripheral clock 3 ( SSI ) | ||
392 | */ | ||
393 | static unsigned long perclk3_get_rate(struct clk *clk) | ||
394 | { | ||
395 | return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) & | ||
396 | CCM_PCDR_PCLK3_MASK) >> CCM_PCDR_PCLK3_OFFSET) + 1); | ||
397 | } | ||
398 | |||
399 | static unsigned long perclk3_round_rate(struct clk *clk, unsigned long rate) | ||
400 | { | ||
401 | return _clk_simple_round_rate(clk, rate, 128); | ||
402 | } | ||
403 | |||
404 | static int perclk3_set_rate(struct clk *clk, unsigned long rate) | ||
405 | { | ||
406 | unsigned int div; | ||
407 | unsigned int reg; | ||
408 | unsigned long parent_rate; | ||
409 | |||
410 | parent_rate = clk_get_rate(clk->parent); | ||
411 | |||
412 | div = parent_rate / rate; | ||
413 | |||
414 | if (div > 128 || div < 1 || ((parent_rate / div) != rate)) | ||
415 | return -EINVAL; | ||
416 | |||
417 | div--; | ||
418 | |||
419 | reg = __raw_readl(CCM_PCDR); | ||
420 | reg &= ~CCM_PCDR_PCLK3_MASK; | ||
421 | reg |= div << CCM_PCDR_PCLK3_OFFSET; | ||
422 | __raw_writel(reg, CCM_PCDR); | ||
423 | |||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | static struct clk perclk[] = { | ||
428 | { | ||
429 | .id = 0, | ||
430 | .parent = &system_clk, | ||
431 | .get_rate = perclk1_get_rate, | ||
432 | .round_rate = perclk1_round_rate, | ||
433 | .set_rate = perclk1_set_rate, | ||
434 | }, { | ||
435 | .id = 1, | ||
436 | .parent = &system_clk, | ||
437 | .get_rate = perclk2_get_rate, | ||
438 | .round_rate = perclk2_round_rate, | ||
439 | .set_rate = perclk2_set_rate, | ||
440 | }, { | ||
441 | .id = 2, | ||
442 | .parent = &system_clk, | ||
443 | .get_rate = perclk3_get_rate, | ||
444 | .round_rate = perclk3_round_rate, | ||
445 | .set_rate = perclk3_set_rate, | ||
446 | } | ||
447 | }; | ||
448 | |||
449 | static const struct clk *clko_clocks[] = { | ||
450 | &perclk[0], | ||
451 | &hclk, | ||
452 | &clk48m, | ||
453 | &clk16m, | ||
454 | &prem_clk, | ||
455 | &fclk, | ||
456 | }; | ||
457 | |||
458 | static int clko_set_parent(struct clk *clk, struct clk *parent) | ||
459 | { | ||
460 | int i; | ||
461 | unsigned int reg; | ||
462 | |||
463 | i = _clk_can_use_parent(clko_clocks, ARRAY_SIZE(clko_clocks), parent); | ||
464 | if (i < 0) | ||
465 | return i; | ||
466 | |||
467 | reg = __raw_readl(CCM_CSCR) & ~CCM_CSCR_CLKO_MASK; | ||
468 | reg |= i << CCM_CSCR_CLKO_OFFSET; | ||
469 | __raw_writel(reg, CCM_CSCR); | ||
470 | |||
471 | if (clko_clocks[i]->set_rate && clko_clocks[i]->round_rate) { | ||
472 | clk->set_rate = _clk_parent_set_rate; | ||
473 | clk->round_rate = _clk_parent_round_rate; | ||
474 | } else { | ||
475 | clk->set_rate = NULL; | ||
476 | clk->round_rate = NULL; | ||
477 | } | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static struct clk clko_clk = { | ||
483 | .set_parent = clko_set_parent, | ||
484 | }; | ||
485 | |||
486 | static struct clk dma_clk = { | ||
487 | .parent = &hclk, | ||
488 | .round_rate = _clk_parent_round_rate, | ||
489 | .set_rate = _clk_parent_set_rate, | ||
490 | .enable = _clk_enable, | ||
491 | .enable_reg = SCM_GCCR, | ||
492 | .enable_shift = SCM_GCCR_DMA_CLK_EN_OFFSET, | ||
493 | .disable = _clk_disable, | ||
494 | }; | ||
495 | |||
496 | static struct clk csi_clk = { | ||
497 | .parent = &hclk, | ||
498 | .round_rate = _clk_parent_round_rate, | ||
499 | .set_rate = _clk_parent_set_rate, | ||
500 | .enable = _clk_enable, | ||
501 | .enable_reg = SCM_GCCR, | ||
502 | .enable_shift = SCM_GCCR_CSI_CLK_EN_OFFSET, | ||
503 | .disable = _clk_disable, | ||
504 | }; | ||
505 | |||
506 | static struct clk mma_clk = { | ||
507 | .parent = &hclk, | ||
508 | .round_rate = _clk_parent_round_rate, | ||
509 | .set_rate = _clk_parent_set_rate, | ||
510 | .enable = _clk_enable, | ||
511 | .enable_reg = SCM_GCCR, | ||
512 | .enable_shift = SCM_GCCR_MMA_CLK_EN_OFFSET, | ||
513 | .disable = _clk_disable, | ||
514 | }; | ||
515 | |||
516 | static struct clk usbd_clk = { | ||
517 | .parent = &clk48m, | ||
518 | .round_rate = _clk_parent_round_rate, | ||
519 | .set_rate = _clk_parent_set_rate, | ||
520 | .enable = _clk_enable, | ||
521 | .enable_reg = SCM_GCCR, | ||
522 | .enable_shift = SCM_GCCR_USBD_CLK_EN_OFFSET, | ||
523 | .disable = _clk_disable, | ||
524 | }; | ||
525 | |||
526 | static struct clk gpt_clk = { | ||
527 | .parent = &perclk[0], | ||
528 | .round_rate = _clk_parent_round_rate, | ||
529 | .set_rate = _clk_parent_set_rate, | ||
530 | }; | ||
531 | |||
532 | static struct clk uart_clk = { | ||
533 | .parent = &perclk[0], | ||
534 | .round_rate = _clk_parent_round_rate, | ||
535 | .set_rate = _clk_parent_set_rate, | ||
536 | }; | ||
537 | |||
538 | static struct clk i2c_clk = { | ||
539 | .parent = &hclk, | ||
540 | .round_rate = _clk_parent_round_rate, | ||
541 | .set_rate = _clk_parent_set_rate, | ||
542 | }; | ||
543 | |||
544 | static struct clk spi_clk = { | ||
545 | .parent = &perclk[1], | ||
546 | .round_rate = _clk_parent_round_rate, | ||
547 | .set_rate = _clk_parent_set_rate, | ||
548 | }; | ||
549 | |||
550 | static struct clk sdhc_clk = { | ||
551 | .parent = &perclk[1], | ||
552 | .round_rate = _clk_parent_round_rate, | ||
553 | .set_rate = _clk_parent_set_rate, | ||
554 | }; | ||
555 | |||
556 | static struct clk lcdc_clk = { | ||
557 | .parent = &perclk[1], | ||
558 | .round_rate = _clk_parent_round_rate, | ||
559 | .set_rate = _clk_parent_set_rate, | ||
560 | }; | ||
561 | |||
562 | static struct clk mshc_clk = { | ||
563 | .parent = &hclk, | ||
564 | .round_rate = _clk_parent_round_rate, | ||
565 | .set_rate = _clk_parent_set_rate, | ||
566 | }; | ||
567 | |||
568 | static struct clk ssi_clk = { | ||
569 | .parent = &perclk[2], | ||
570 | .round_rate = _clk_parent_round_rate, | ||
571 | .set_rate = _clk_parent_set_rate, | ||
572 | }; | ||
573 | |||
574 | static struct clk rtc_clk = { | ||
575 | .parent = &clk32, | ||
576 | }; | ||
577 | |||
578 | #define _REGISTER_CLOCK(d, n, c) \ | ||
579 | { \ | ||
580 | .dev_id = d, \ | ||
581 | .con_id = n, \ | ||
582 | .clk = &c, \ | ||
583 | }, | ||
584 | static struct clk_lookup lookups[] __initdata = { | ||
585 | _REGISTER_CLOCK(NULL, "dma", dma_clk) | ||
586 | _REGISTER_CLOCK("mx1-camera.0", NULL, csi_clk) | ||
587 | _REGISTER_CLOCK(NULL, "mma", mma_clk) | ||
588 | _REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk) | ||
589 | _REGISTER_CLOCK(NULL, "gpt", gpt_clk) | ||
590 | _REGISTER_CLOCK("imx1-uart.0", NULL, uart_clk) | ||
591 | _REGISTER_CLOCK("imx1-uart.1", NULL, uart_clk) | ||
592 | _REGISTER_CLOCK("imx1-uart.2", NULL, uart_clk) | ||
593 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) | ||
594 | _REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk) | ||
595 | _REGISTER_CLOCK("imx1-cspi.1", NULL, spi_clk) | ||
596 | _REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk) | ||
597 | _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) | ||
598 | _REGISTER_CLOCK(NULL, "mshc", mshc_clk) | ||
599 | _REGISTER_CLOCK(NULL, "ssi", ssi_clk) | ||
600 | _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk) | ||
601 | }; | ||
602 | |||
603 | int __init mx1_clocks_init(unsigned long fref) | ||
604 | { | ||
605 | unsigned int reg; | ||
606 | |||
607 | /* disable clocks we are able to */ | ||
608 | __raw_writel(0, SCM_GCCR); | ||
609 | |||
610 | clk32_rate = fref; | ||
611 | reg = __raw_readl(CCM_CSCR); | ||
612 | |||
613 | /* detect clock reference for system PLL */ | ||
614 | if (reg & CCM_CSCR_SYSTEM_SEL) { | ||
615 | prem_clk.parent = &clk16m; | ||
616 | } else { | ||
617 | /* ensure that oscillator is disabled */ | ||
618 | reg &= ~(1 << CCM_CSCR_OSC_EN_SHIFT); | ||
619 | __raw_writel(reg, CCM_CSCR); | ||
620 | prem_clk.parent = &clk32_premult; | ||
621 | } | ||
622 | |||
623 | /* detect reference for CLKO */ | ||
624 | reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET; | ||
625 | clko_clk.parent = (struct clk *)clko_clocks[reg]; | ||
626 | |||
627 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
628 | |||
629 | clk_enable(&hclk); | ||
630 | clk_enable(&fclk); | ||
631 | |||
632 | mxc_timer_init(&gpt_clk, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), | ||
633 | MX1_TIM1_INT); | ||
634 | |||
635 | return 0; | ||
636 | } | ||
diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c deleted file mode 100644 index ee15d8c9db08..000000000000 --- a/arch/arm/mach-imx/clock-imx21.c +++ /dev/null | |||
@@ -1,1239 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright 2008 Juergen Beisert, kernel@pengutronix.de | ||
4 | * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version 2 | ||
9 | * of the License, or (at your option) any later version. | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
18 | * MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/clk.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/clkdev.h> | ||
25 | |||
26 | #include <mach/clock.h> | ||
27 | #include <mach/hardware.h> | ||
28 | #include <mach/common.h> | ||
29 | #include <asm/div64.h> | ||
30 | |||
31 | #define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off))) | ||
32 | |||
33 | /* Register offsets */ | ||
34 | #define CCM_CSCR IO_ADDR_CCM(0x0) | ||
35 | #define CCM_MPCTL0 IO_ADDR_CCM(0x4) | ||
36 | #define CCM_MPCTL1 IO_ADDR_CCM(0x8) | ||
37 | #define CCM_SPCTL0 IO_ADDR_CCM(0xc) | ||
38 | #define CCM_SPCTL1 IO_ADDR_CCM(0x10) | ||
39 | #define CCM_OSC26MCTL IO_ADDR_CCM(0x14) | ||
40 | #define CCM_PCDR0 IO_ADDR_CCM(0x18) | ||
41 | #define CCM_PCDR1 IO_ADDR_CCM(0x1c) | ||
42 | #define CCM_PCCR0 IO_ADDR_CCM(0x20) | ||
43 | #define CCM_PCCR1 IO_ADDR_CCM(0x24) | ||
44 | #define CCM_CCSR IO_ADDR_CCM(0x28) | ||
45 | #define CCM_PMCTL IO_ADDR_CCM(0x2c) | ||
46 | #define CCM_PMCOUNT IO_ADDR_CCM(0x30) | ||
47 | #define CCM_WKGDCTL IO_ADDR_CCM(0x34) | ||
48 | |||
49 | #define CCM_CSCR_PRESC_OFFSET 29 | ||
50 | #define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET) | ||
51 | |||
52 | #define CCM_CSCR_USB_OFFSET 26 | ||
53 | #define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET) | ||
54 | #define CCM_CSCR_SD_OFFSET 24 | ||
55 | #define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET) | ||
56 | #define CCM_CSCR_SPLLRES (1 << 22) | ||
57 | #define CCM_CSCR_MPLLRES (1 << 21) | ||
58 | #define CCM_CSCR_SSI2_OFFSET 20 | ||
59 | #define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET) | ||
60 | #define CCM_CSCR_SSI1_OFFSET 19 | ||
61 | #define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET) | ||
62 | #define CCM_CSCR_FIR_OFFSET 18 | ||
63 | #define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET) | ||
64 | #define CCM_CSCR_SP (1 << 17) | ||
65 | #define CCM_CSCR_MCU (1 << 16) | ||
66 | #define CCM_CSCR_BCLK_OFFSET 10 | ||
67 | #define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET) | ||
68 | #define CCM_CSCR_IPDIV_OFFSET 9 | ||
69 | #define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET) | ||
70 | |||
71 | #define CCM_CSCR_OSC26MDIV (1 << 4) | ||
72 | #define CCM_CSCR_OSC26M (1 << 3) | ||
73 | #define CCM_CSCR_FPM (1 << 2) | ||
74 | #define CCM_CSCR_SPEN (1 << 1) | ||
75 | #define CCM_CSCR_MPEN 1 | ||
76 | |||
77 | #define CCM_MPCTL0_CPLM (1 << 31) | ||
78 | #define CCM_MPCTL0_PD_OFFSET 26 | ||
79 | #define CCM_MPCTL0_PD_MASK (0xf << 26) | ||
80 | #define CCM_MPCTL0_MFD_OFFSET 16 | ||
81 | #define CCM_MPCTL0_MFD_MASK (0x3ff << 16) | ||
82 | #define CCM_MPCTL0_MFI_OFFSET 10 | ||
83 | #define CCM_MPCTL0_MFI_MASK (0xf << 10) | ||
84 | #define CCM_MPCTL0_MFN_OFFSET 0 | ||
85 | #define CCM_MPCTL0_MFN_MASK 0x3ff | ||
86 | |||
87 | #define CCM_MPCTL1_LF (1 << 15) | ||
88 | #define CCM_MPCTL1_BRMO (1 << 6) | ||
89 | |||
90 | #define CCM_SPCTL0_CPLM (1 << 31) | ||
91 | #define CCM_SPCTL0_PD_OFFSET 26 | ||
92 | #define CCM_SPCTL0_PD_MASK (0xf << 26) | ||
93 | #define CCM_SPCTL0_MFD_OFFSET 16 | ||
94 | #define CCM_SPCTL0_MFD_MASK (0x3ff << 16) | ||
95 | #define CCM_SPCTL0_MFI_OFFSET 10 | ||
96 | #define CCM_SPCTL0_MFI_MASK (0xf << 10) | ||
97 | #define CCM_SPCTL0_MFN_OFFSET 0 | ||
98 | #define CCM_SPCTL0_MFN_MASK 0x3ff | ||
99 | |||
100 | #define CCM_SPCTL1_LF (1 << 15) | ||
101 | #define CCM_SPCTL1_BRMO (1 << 6) | ||
102 | |||
103 | #define CCM_OSC26MCTL_PEAK_OFFSET 16 | ||
104 | #define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16) | ||
105 | #define CCM_OSC26MCTL_AGC_OFFSET 8 | ||
106 | #define CCM_OSC26MCTL_AGC_MASK (0x3f << 8) | ||
107 | #define CCM_OSC26MCTL_ANATEST_OFFSET 0 | ||
108 | #define CCM_OSC26MCTL_ANATEST_MASK 0x3f | ||
109 | |||
110 | #define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26 | ||
111 | #define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26) | ||
112 | #define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16 | ||
113 | #define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16) | ||
114 | #define CCM_PCDR0_NFCDIV_OFFSET 12 | ||
115 | #define CCM_PCDR0_NFCDIV_MASK (0xf << 12) | ||
116 | #define CCM_PCDR0_48MDIV_OFFSET 5 | ||
117 | #define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET) | ||
118 | #define CCM_PCDR0_FIRIDIV_OFFSET 0 | ||
119 | #define CCM_PCDR0_FIRIDIV_MASK 0x1f | ||
120 | #define CCM_PCDR1_PERDIV4_OFFSET 24 | ||
121 | #define CCM_PCDR1_PERDIV4_MASK (0x3f << 24) | ||
122 | #define CCM_PCDR1_PERDIV3_OFFSET 16 | ||
123 | #define CCM_PCDR1_PERDIV3_MASK (0x3f << 16) | ||
124 | #define CCM_PCDR1_PERDIV2_OFFSET 8 | ||
125 | #define CCM_PCDR1_PERDIV2_MASK (0x3f << 8) | ||
126 | #define CCM_PCDR1_PERDIV1_OFFSET 0 | ||
127 | #define CCM_PCDR1_PERDIV1_MASK 0x3f | ||
128 | |||
129 | #define CCM_PCCR_HCLK_CSI_OFFSET 31 | ||
130 | #define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0 | ||
131 | #define CCM_PCCR_HCLK_DMA_OFFSET 30 | ||
132 | #define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0 | ||
133 | #define CCM_PCCR_HCLK_BROM_OFFSET 28 | ||
134 | #define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0 | ||
135 | #define CCM_PCCR_HCLK_EMMA_OFFSET 27 | ||
136 | #define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0 | ||
137 | #define CCM_PCCR_HCLK_LCDC_OFFSET 26 | ||
138 | #define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0 | ||
139 | #define CCM_PCCR_HCLK_SLCDC_OFFSET 25 | ||
140 | #define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0 | ||
141 | #define CCM_PCCR_HCLK_USBOTG_OFFSET 24 | ||
142 | #define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0 | ||
143 | #define CCM_PCCR_HCLK_BMI_OFFSET 23 | ||
144 | #define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK) | ||
145 | #define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0 | ||
146 | #define CCM_PCCR_PERCLK4_OFFSET 22 | ||
147 | #define CCM_PCCR_PERCLK4_REG CCM_PCCR0 | ||
148 | #define CCM_PCCR_SLCDC_OFFSET 21 | ||
149 | #define CCM_PCCR_SLCDC_REG CCM_PCCR0 | ||
150 | #define CCM_PCCR_FIRI_BAUD_OFFSET 20 | ||
151 | #define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK) | ||
152 | #define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0 | ||
153 | #define CCM_PCCR_NFC_OFFSET 19 | ||
154 | #define CCM_PCCR_NFC_REG CCM_PCCR0 | ||
155 | #define CCM_PCCR_LCDC_OFFSET 18 | ||
156 | #define CCM_PCCR_LCDC_REG CCM_PCCR0 | ||
157 | #define CCM_PCCR_SSI1_BAUD_OFFSET 17 | ||
158 | #define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0 | ||
159 | #define CCM_PCCR_SSI2_BAUD_OFFSET 16 | ||
160 | #define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0 | ||
161 | #define CCM_PCCR_EMMA_OFFSET 15 | ||
162 | #define CCM_PCCR_EMMA_REG CCM_PCCR0 | ||
163 | #define CCM_PCCR_USBOTG_OFFSET 14 | ||
164 | #define CCM_PCCR_USBOTG_REG CCM_PCCR0 | ||
165 | #define CCM_PCCR_DMA_OFFSET 13 | ||
166 | #define CCM_PCCR_DMA_REG CCM_PCCR0 | ||
167 | #define CCM_PCCR_I2C1_OFFSET 12 | ||
168 | #define CCM_PCCR_I2C1_REG CCM_PCCR0 | ||
169 | #define CCM_PCCR_GPIO_OFFSET 11 | ||
170 | #define CCM_PCCR_GPIO_REG CCM_PCCR0 | ||
171 | #define CCM_PCCR_SDHC2_OFFSET 10 | ||
172 | #define CCM_PCCR_SDHC2_REG CCM_PCCR0 | ||
173 | #define CCM_PCCR_SDHC1_OFFSET 9 | ||
174 | #define CCM_PCCR_SDHC1_REG CCM_PCCR0 | ||
175 | #define CCM_PCCR_FIRI_OFFSET 8 | ||
176 | #define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK) | ||
177 | #define CCM_PCCR_FIRI_REG CCM_PCCR0 | ||
178 | #define CCM_PCCR_SSI2_IPG_OFFSET 7 | ||
179 | #define CCM_PCCR_SSI2_REG CCM_PCCR0 | ||
180 | #define CCM_PCCR_SSI1_IPG_OFFSET 6 | ||
181 | #define CCM_PCCR_SSI1_REG CCM_PCCR0 | ||
182 | #define CCM_PCCR_CSPI2_OFFSET 5 | ||
183 | #define CCM_PCCR_CSPI2_REG CCM_PCCR0 | ||
184 | #define CCM_PCCR_CSPI1_OFFSET 4 | ||
185 | #define CCM_PCCR_CSPI1_REG CCM_PCCR0 | ||
186 | #define CCM_PCCR_UART4_OFFSET 3 | ||
187 | #define CCM_PCCR_UART4_REG CCM_PCCR0 | ||
188 | #define CCM_PCCR_UART3_OFFSET 2 | ||
189 | #define CCM_PCCR_UART3_REG CCM_PCCR0 | ||
190 | #define CCM_PCCR_UART2_OFFSET 1 | ||
191 | #define CCM_PCCR_UART2_REG CCM_PCCR0 | ||
192 | #define CCM_PCCR_UART1_OFFSET 0 | ||
193 | #define CCM_PCCR_UART1_REG CCM_PCCR0 | ||
194 | |||
195 | #define CCM_PCCR_OWIRE_OFFSET 31 | ||
196 | #define CCM_PCCR_OWIRE_REG CCM_PCCR1 | ||
197 | #define CCM_PCCR_KPP_OFFSET 30 | ||
198 | #define CCM_PCCR_KPP_REG CCM_PCCR1 | ||
199 | #define CCM_PCCR_RTC_OFFSET 29 | ||
200 | #define CCM_PCCR_RTC_REG CCM_PCCR1 | ||
201 | #define CCM_PCCR_PWM_OFFSET 28 | ||
202 | #define CCM_PCCR_PWM_REG CCM_PCCR1 | ||
203 | #define CCM_PCCR_GPT3_OFFSET 27 | ||
204 | #define CCM_PCCR_GPT3_REG CCM_PCCR1 | ||
205 | #define CCM_PCCR_GPT2_OFFSET 26 | ||
206 | #define CCM_PCCR_GPT2_REG CCM_PCCR1 | ||
207 | #define CCM_PCCR_GPT1_OFFSET 25 | ||
208 | #define CCM_PCCR_GPT1_REG CCM_PCCR1 | ||
209 | #define CCM_PCCR_WDT_OFFSET 24 | ||
210 | #define CCM_PCCR_WDT_REG CCM_PCCR1 | ||
211 | #define CCM_PCCR_CSPI3_OFFSET 23 | ||
212 | #define CCM_PCCR_CSPI3_REG CCM_PCCR1 | ||
213 | |||
214 | #define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET) | ||
215 | #define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET) | ||
216 | #define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET) | ||
217 | #define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET) | ||
218 | #define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET) | ||
219 | #define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET) | ||
220 | #define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET) | ||
221 | #define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET) | ||
222 | #define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET) | ||
223 | #define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET) | ||
224 | #define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET) | ||
225 | #define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET) | ||
226 | #define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET) | ||
227 | #define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET) | ||
228 | #define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET) | ||
229 | #define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET) | ||
230 | #define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET) | ||
231 | #define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET) | ||
232 | #define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET) | ||
233 | #define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET) | ||
234 | #define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET) | ||
235 | #define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET) | ||
236 | #define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET) | ||
237 | #define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET) | ||
238 | #define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET) | ||
239 | #define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET) | ||
240 | #define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET) | ||
241 | #define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET) | ||
242 | #define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET) | ||
243 | #define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET) | ||
244 | #define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET) | ||
245 | #define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET) | ||
246 | #define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET) | ||
247 | #define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET) | ||
248 | #define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET) | ||
249 | #define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET) | ||
250 | #define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET) | ||
251 | |||
252 | #define CCM_CCSR_32KSR (1 << 15) | ||
253 | |||
254 | #define CCM_CCSR_CLKMODE1 (1 << 9) | ||
255 | #define CCM_CCSR_CLKMODE0 (1 << 8) | ||
256 | |||
257 | #define CCM_CCSR_CLKOSEL_OFFSET 0 | ||
258 | #define CCM_CCSR_CLKOSEL_MASK 0x1f | ||
259 | |||
260 | #define SYS_FMCR 0x14 /* Functional Muxing Control Reg */ | ||
261 | #define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ | ||
262 | |||
263 | static int _clk_enable(struct clk *clk) | ||
264 | { | ||
265 | u32 reg; | ||
266 | |||
267 | reg = __raw_readl(clk->enable_reg); | ||
268 | reg |= 1 << clk->enable_shift; | ||
269 | __raw_writel(reg, clk->enable_reg); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static void _clk_disable(struct clk *clk) | ||
274 | { | ||
275 | u32 reg; | ||
276 | |||
277 | reg = __raw_readl(clk->enable_reg); | ||
278 | reg &= ~(1 << clk->enable_shift); | ||
279 | __raw_writel(reg, clk->enable_reg); | ||
280 | } | ||
281 | |||
282 | static unsigned long _clk_generic_round_rate(struct clk *clk, | ||
283 | unsigned long rate, | ||
284 | u32 max_divisor) | ||
285 | { | ||
286 | u32 div; | ||
287 | unsigned long parent_rate; | ||
288 | |||
289 | parent_rate = clk_get_rate(clk->parent); | ||
290 | |||
291 | div = parent_rate / rate; | ||
292 | if (parent_rate % rate) | ||
293 | div++; | ||
294 | |||
295 | if (div > max_divisor) | ||
296 | div = max_divisor; | ||
297 | |||
298 | return parent_rate / div; | ||
299 | } | ||
300 | |||
301 | static int _clk_spll_enable(struct clk *clk) | ||
302 | { | ||
303 | u32 reg; | ||
304 | |||
305 | reg = __raw_readl(CCM_CSCR); | ||
306 | reg |= CCM_CSCR_SPEN; | ||
307 | __raw_writel(reg, CCM_CSCR); | ||
308 | |||
309 | while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0) | ||
310 | ; | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static void _clk_spll_disable(struct clk *clk) | ||
315 | { | ||
316 | u32 reg; | ||
317 | |||
318 | reg = __raw_readl(CCM_CSCR); | ||
319 | reg &= ~CCM_CSCR_SPEN; | ||
320 | __raw_writel(reg, CCM_CSCR); | ||
321 | } | ||
322 | |||
323 | |||
324 | #define CSCR() (__raw_readl(CCM_CSCR)) | ||
325 | #define PCDR0() (__raw_readl(CCM_PCDR0)) | ||
326 | #define PCDR1() (__raw_readl(CCM_PCDR1)) | ||
327 | |||
328 | static unsigned long _clk_perclkx_round_rate(struct clk *clk, | ||
329 | unsigned long rate) | ||
330 | { | ||
331 | return _clk_generic_round_rate(clk, rate, 64); | ||
332 | } | ||
333 | |||
334 | static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate) | ||
335 | { | ||
336 | u32 reg; | ||
337 | u32 div; | ||
338 | unsigned long parent_rate; | ||
339 | |||
340 | parent_rate = clk_get_rate(clk->parent); | ||
341 | |||
342 | if (clk->id < 0 || clk->id > 3) | ||
343 | return -EINVAL; | ||
344 | |||
345 | div = parent_rate / rate; | ||
346 | if (div > 64 || div < 1 || ((parent_rate / div) != rate)) | ||
347 | return -EINVAL; | ||
348 | div--; | ||
349 | |||
350 | reg = | ||
351 | __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK << | ||
352 | (clk->id << 3)); | ||
353 | reg |= div << (clk->id << 3); | ||
354 | __raw_writel(reg, CCM_PCDR1); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static unsigned long _clk_usb_recalc(struct clk *clk) | ||
360 | { | ||
361 | unsigned long usb_pdf; | ||
362 | unsigned long parent_rate; | ||
363 | |||
364 | parent_rate = clk_get_rate(clk->parent); | ||
365 | |||
366 | usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET; | ||
367 | |||
368 | return parent_rate / (usb_pdf + 1U); | ||
369 | } | ||
370 | |||
371 | static unsigned long _clk_usb_round_rate(struct clk *clk, | ||
372 | unsigned long rate) | ||
373 | { | ||
374 | return _clk_generic_round_rate(clk, rate, 8); | ||
375 | } | ||
376 | |||
377 | static int _clk_usb_set_rate(struct clk *clk, unsigned long rate) | ||
378 | { | ||
379 | u32 reg; | ||
380 | u32 div; | ||
381 | unsigned long parent_rate; | ||
382 | |||
383 | parent_rate = clk_get_rate(clk->parent); | ||
384 | |||
385 | div = parent_rate / rate; | ||
386 | if (div > 8 || div < 1 || ((parent_rate / div) != rate)) | ||
387 | return -EINVAL; | ||
388 | div--; | ||
389 | |||
390 | reg = CSCR() & ~CCM_CSCR_USB_MASK; | ||
391 | reg |= div << CCM_CSCR_USB_OFFSET; | ||
392 | __raw_writel(reg, CCM_CSCR); | ||
393 | |||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf) | ||
398 | { | ||
399 | unsigned long parent_rate; | ||
400 | |||
401 | parent_rate = clk_get_rate(clk->parent); | ||
402 | |||
403 | pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */ | ||
404 | |||
405 | return 2UL * parent_rate / pdf; | ||
406 | } | ||
407 | |||
408 | static unsigned long _clk_ssi1_recalc(struct clk *clk) | ||
409 | { | ||
410 | return _clk_ssix_recalc(clk, | ||
411 | (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) | ||
412 | >> CCM_PCDR0_SSI1BAUDDIV_OFFSET); | ||
413 | } | ||
414 | |||
415 | static unsigned long _clk_ssi2_recalc(struct clk *clk) | ||
416 | { | ||
417 | return _clk_ssix_recalc(clk, | ||
418 | (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >> | ||
419 | CCM_PCDR0_SSI2BAUDDIV_OFFSET); | ||
420 | } | ||
421 | |||
422 | static unsigned long _clk_nfc_recalc(struct clk *clk) | ||
423 | { | ||
424 | unsigned long nfc_pdf; | ||
425 | unsigned long parent_rate; | ||
426 | |||
427 | parent_rate = clk_get_rate(clk->parent); | ||
428 | |||
429 | nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK) | ||
430 | >> CCM_PCDR0_NFCDIV_OFFSET; | ||
431 | |||
432 | return parent_rate / (nfc_pdf + 1); | ||
433 | } | ||
434 | |||
435 | static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate) | ||
436 | { | ||
437 | return clk->parent->round_rate(clk->parent, rate); | ||
438 | } | ||
439 | |||
440 | static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) | ||
441 | { | ||
442 | return clk->parent->set_rate(clk->parent, rate); | ||
443 | } | ||
444 | |||
445 | static unsigned long external_high_reference; /* in Hz */ | ||
446 | |||
447 | static unsigned long get_high_reference_clock_rate(struct clk *clk) | ||
448 | { | ||
449 | return external_high_reference; | ||
450 | } | ||
451 | |||
452 | /* | ||
453 | * the high frequency external clock reference | ||
454 | * Default case is 26MHz. | ||
455 | */ | ||
456 | static struct clk ckih_clk = { | ||
457 | .get_rate = get_high_reference_clock_rate, | ||
458 | }; | ||
459 | |||
460 | static unsigned long external_low_reference; /* in Hz */ | ||
461 | |||
462 | static unsigned long get_low_reference_clock_rate(struct clk *clk) | ||
463 | { | ||
464 | return external_low_reference; | ||
465 | } | ||
466 | |||
467 | /* | ||
468 | * the low frequency external clock reference | ||
469 | * Default case is 32.768kHz. | ||
470 | */ | ||
471 | static struct clk ckil_clk = { | ||
472 | .get_rate = get_low_reference_clock_rate, | ||
473 | }; | ||
474 | |||
475 | |||
476 | static unsigned long _clk_fpm_recalc(struct clk *clk) | ||
477 | { | ||
478 | return clk_get_rate(clk->parent) * 512; | ||
479 | } | ||
480 | |||
481 | /* Output of frequency pre multiplier */ | ||
482 | static struct clk fpm_clk = { | ||
483 | .parent = &ckil_clk, | ||
484 | .get_rate = _clk_fpm_recalc, | ||
485 | }; | ||
486 | |||
487 | static unsigned long get_mpll_clk(struct clk *clk) | ||
488 | { | ||
489 | uint32_t reg; | ||
490 | unsigned long ref_clk; | ||
491 | unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0; | ||
492 | unsigned long long temp; | ||
493 | |||
494 | ref_clk = clk_get_rate(clk->parent); | ||
495 | |||
496 | reg = __raw_readl(CCM_MPCTL0); | ||
497 | pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET; | ||
498 | mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET; | ||
499 | mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET; | ||
500 | mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET; | ||
501 | |||
502 | mfi = (mfi <= 5) ? 5 : mfi; | ||
503 | temp = 2LL * ref_clk * mfn; | ||
504 | do_div(temp, mfd + 1); | ||
505 | temp = 2LL * ref_clk * mfi + temp; | ||
506 | do_div(temp, pdf + 1); | ||
507 | |||
508 | return (unsigned long)temp; | ||
509 | } | ||
510 | |||
511 | static struct clk mpll_clk = { | ||
512 | .parent = &ckih_clk, | ||
513 | .get_rate = get_mpll_clk, | ||
514 | }; | ||
515 | |||
516 | static unsigned long _clk_fclk_get_rate(struct clk *clk) | ||
517 | { | ||
518 | unsigned long parent_rate; | ||
519 | u32 div; | ||
520 | |||
521 | div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET; | ||
522 | parent_rate = clk_get_rate(clk->parent); | ||
523 | |||
524 | return parent_rate / (div+1); | ||
525 | } | ||
526 | |||
527 | static struct clk fclk_clk = { | ||
528 | .parent = &mpll_clk, | ||
529 | .get_rate = _clk_fclk_get_rate | ||
530 | }; | ||
531 | |||
532 | static unsigned long get_spll_clk(struct clk *clk) | ||
533 | { | ||
534 | uint32_t reg; | ||
535 | unsigned long ref_clk; | ||
536 | unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0; | ||
537 | unsigned long long temp; | ||
538 | |||
539 | ref_clk = clk_get_rate(clk->parent); | ||
540 | |||
541 | reg = __raw_readl(CCM_SPCTL0); | ||
542 | pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET; | ||
543 | mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET; | ||
544 | mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET; | ||
545 | mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET; | ||
546 | |||
547 | mfi = (mfi <= 5) ? 5 : mfi; | ||
548 | temp = 2LL * ref_clk * mfn; | ||
549 | do_div(temp, mfd + 1); | ||
550 | temp = 2LL * ref_clk * mfi + temp; | ||
551 | do_div(temp, pdf + 1); | ||
552 | |||
553 | return (unsigned long)temp; | ||
554 | } | ||
555 | |||
556 | static struct clk spll_clk = { | ||
557 | .parent = &ckih_clk, | ||
558 | .get_rate = get_spll_clk, | ||
559 | .enable = _clk_spll_enable, | ||
560 | .disable = _clk_spll_disable, | ||
561 | }; | ||
562 | |||
563 | static unsigned long get_hclk_clk(struct clk *clk) | ||
564 | { | ||
565 | unsigned long rate; | ||
566 | unsigned long bclk_pdf; | ||
567 | |||
568 | bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK) | ||
569 | >> CCM_CSCR_BCLK_OFFSET; | ||
570 | |||
571 | rate = clk_get_rate(clk->parent); | ||
572 | return rate / (bclk_pdf + 1); | ||
573 | } | ||
574 | |||
575 | static struct clk hclk_clk = { | ||
576 | .parent = &fclk_clk, | ||
577 | .get_rate = get_hclk_clk, | ||
578 | }; | ||
579 | |||
580 | static unsigned long get_ipg_clk(struct clk *clk) | ||
581 | { | ||
582 | unsigned long rate; | ||
583 | unsigned long ipg_pdf; | ||
584 | |||
585 | ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET; | ||
586 | |||
587 | rate = clk_get_rate(clk->parent); | ||
588 | return rate / (ipg_pdf + 1); | ||
589 | } | ||
590 | |||
591 | static struct clk ipg_clk = { | ||
592 | .parent = &hclk_clk, | ||
593 | .get_rate = get_ipg_clk, | ||
594 | }; | ||
595 | |||
596 | static unsigned long _clk_perclkx_recalc(struct clk *clk) | ||
597 | { | ||
598 | unsigned long perclk_pdf; | ||
599 | unsigned long parent_rate; | ||
600 | |||
601 | parent_rate = clk_get_rate(clk->parent); | ||
602 | |||
603 | if (clk->id < 0 || clk->id > 3) | ||
604 | return 0; | ||
605 | |||
606 | perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK; | ||
607 | |||
608 | return parent_rate / (perclk_pdf + 1); | ||
609 | } | ||
610 | |||
611 | static struct clk per_clk[] = { | ||
612 | { | ||
613 | .id = 0, | ||
614 | .parent = &mpll_clk, | ||
615 | .get_rate = _clk_perclkx_recalc, | ||
616 | }, { | ||
617 | .id = 1, | ||
618 | .parent = &mpll_clk, | ||
619 | .get_rate = _clk_perclkx_recalc, | ||
620 | }, { | ||
621 | .id = 2, | ||
622 | .parent = &mpll_clk, | ||
623 | .round_rate = _clk_perclkx_round_rate, | ||
624 | .set_rate = _clk_perclkx_set_rate, | ||
625 | .get_rate = _clk_perclkx_recalc, | ||
626 | /* Enable/Disable done via lcd_clkc[1] */ | ||
627 | }, { | ||
628 | .id = 3, | ||
629 | .parent = &mpll_clk, | ||
630 | .round_rate = _clk_perclkx_round_rate, | ||
631 | .set_rate = _clk_perclkx_set_rate, | ||
632 | .get_rate = _clk_perclkx_recalc, | ||
633 | /* Enable/Disable done via csi_clk[1] */ | ||
634 | }, | ||
635 | }; | ||
636 | |||
637 | static struct clk uart_ipg_clk[]; | ||
638 | |||
639 | static struct clk uart_clk[] = { | ||
640 | { | ||
641 | .id = 0, | ||
642 | .parent = &per_clk[0], | ||
643 | .secondary = &uart_ipg_clk[0], | ||
644 | }, { | ||
645 | .id = 1, | ||
646 | .parent = &per_clk[0], | ||
647 | .secondary = &uart_ipg_clk[1], | ||
648 | }, { | ||
649 | .id = 2, | ||
650 | .parent = &per_clk[0], | ||
651 | .secondary = &uart_ipg_clk[2], | ||
652 | }, { | ||
653 | .id = 3, | ||
654 | .parent = &per_clk[0], | ||
655 | .secondary = &uart_ipg_clk[3], | ||
656 | }, | ||
657 | }; | ||
658 | |||
659 | static struct clk uart_ipg_clk[] = { | ||
660 | { | ||
661 | .id = 0, | ||
662 | .parent = &ipg_clk, | ||
663 | .enable = _clk_enable, | ||
664 | .enable_reg = CCM_PCCR_UART1_REG, | ||
665 | .enable_shift = CCM_PCCR_UART1_OFFSET, | ||
666 | .disable = _clk_disable, | ||
667 | }, { | ||
668 | .id = 1, | ||
669 | .parent = &ipg_clk, | ||
670 | .enable = _clk_enable, | ||
671 | .enable_reg = CCM_PCCR_UART2_REG, | ||
672 | .enable_shift = CCM_PCCR_UART2_OFFSET, | ||
673 | .disable = _clk_disable, | ||
674 | }, { | ||
675 | .id = 2, | ||
676 | .parent = &ipg_clk, | ||
677 | .enable = _clk_enable, | ||
678 | .enable_reg = CCM_PCCR_UART3_REG, | ||
679 | .enable_shift = CCM_PCCR_UART3_OFFSET, | ||
680 | .disable = _clk_disable, | ||
681 | }, { | ||
682 | .id = 3, | ||
683 | .parent = &ipg_clk, | ||
684 | .enable = _clk_enable, | ||
685 | .enable_reg = CCM_PCCR_UART4_REG, | ||
686 | .enable_shift = CCM_PCCR_UART4_OFFSET, | ||
687 | .disable = _clk_disable, | ||
688 | }, | ||
689 | }; | ||
690 | |||
691 | static struct clk gpt_ipg_clk[]; | ||
692 | |||
693 | static struct clk gpt_clk[] = { | ||
694 | { | ||
695 | .id = 0, | ||
696 | .parent = &per_clk[0], | ||
697 | .secondary = &gpt_ipg_clk[0], | ||
698 | }, { | ||
699 | .id = 1, | ||
700 | .parent = &per_clk[0], | ||
701 | .secondary = &gpt_ipg_clk[1], | ||
702 | }, { | ||
703 | .id = 2, | ||
704 | .parent = &per_clk[0], | ||
705 | .secondary = &gpt_ipg_clk[2], | ||
706 | }, | ||
707 | }; | ||
708 | |||
709 | static struct clk gpt_ipg_clk[] = { | ||
710 | { | ||
711 | .id = 0, | ||
712 | .parent = &ipg_clk, | ||
713 | .enable = _clk_enable, | ||
714 | .enable_reg = CCM_PCCR_GPT1_REG, | ||
715 | .enable_shift = CCM_PCCR_GPT1_OFFSET, | ||
716 | .disable = _clk_disable, | ||
717 | }, { | ||
718 | .id = 1, | ||
719 | .parent = &ipg_clk, | ||
720 | .enable = _clk_enable, | ||
721 | .enable_reg = CCM_PCCR_GPT2_REG, | ||
722 | .enable_shift = CCM_PCCR_GPT2_OFFSET, | ||
723 | .disable = _clk_disable, | ||
724 | }, { | ||
725 | .id = 2, | ||
726 | .parent = &ipg_clk, | ||
727 | .enable = _clk_enable, | ||
728 | .enable_reg = CCM_PCCR_GPT3_REG, | ||
729 | .enable_shift = CCM_PCCR_GPT3_OFFSET, | ||
730 | .disable = _clk_disable, | ||
731 | }, | ||
732 | }; | ||
733 | |||
734 | static struct clk pwm_clk[] = { | ||
735 | { | ||
736 | .parent = &per_clk[0], | ||
737 | .secondary = &pwm_clk[1], | ||
738 | }, { | ||
739 | .parent = &ipg_clk, | ||
740 | .enable = _clk_enable, | ||
741 | .enable_reg = CCM_PCCR_PWM_REG, | ||
742 | .enable_shift = CCM_PCCR_PWM_OFFSET, | ||
743 | .disable = _clk_disable, | ||
744 | }, | ||
745 | }; | ||
746 | |||
747 | static struct clk sdhc_ipg_clk[]; | ||
748 | |||
749 | static struct clk sdhc_clk[] = { | ||
750 | { | ||
751 | .id = 0, | ||
752 | .parent = &per_clk[1], | ||
753 | .secondary = &sdhc_ipg_clk[0], | ||
754 | }, { | ||
755 | .id = 1, | ||
756 | .parent = &per_clk[1], | ||
757 | .secondary = &sdhc_ipg_clk[1], | ||
758 | }, | ||
759 | }; | ||
760 | |||
761 | static struct clk sdhc_ipg_clk[] = { | ||
762 | { | ||
763 | .id = 0, | ||
764 | .parent = &ipg_clk, | ||
765 | .enable = _clk_enable, | ||
766 | .enable_reg = CCM_PCCR_SDHC1_REG, | ||
767 | .enable_shift = CCM_PCCR_SDHC1_OFFSET, | ||
768 | .disable = _clk_disable, | ||
769 | }, { | ||
770 | .id = 1, | ||
771 | .parent = &ipg_clk, | ||
772 | .enable = _clk_enable, | ||
773 | .enable_reg = CCM_PCCR_SDHC2_REG, | ||
774 | .enable_shift = CCM_PCCR_SDHC2_OFFSET, | ||
775 | .disable = _clk_disable, | ||
776 | }, | ||
777 | }; | ||
778 | |||
779 | static struct clk cspi_ipg_clk[]; | ||
780 | |||
781 | static struct clk cspi_clk[] = { | ||
782 | { | ||
783 | .id = 0, | ||
784 | .parent = &per_clk[1], | ||
785 | .secondary = &cspi_ipg_clk[0], | ||
786 | }, { | ||
787 | .id = 1, | ||
788 | .parent = &per_clk[1], | ||
789 | .secondary = &cspi_ipg_clk[1], | ||
790 | }, { | ||
791 | .id = 2, | ||
792 | .parent = &per_clk[1], | ||
793 | .secondary = &cspi_ipg_clk[2], | ||
794 | }, | ||
795 | }; | ||
796 | |||
797 | static struct clk cspi_ipg_clk[] = { | ||
798 | { | ||
799 | .id = 0, | ||
800 | .parent = &ipg_clk, | ||
801 | .enable = _clk_enable, | ||
802 | .enable_reg = CCM_PCCR_CSPI1_REG, | ||
803 | .enable_shift = CCM_PCCR_CSPI1_OFFSET, | ||
804 | .disable = _clk_disable, | ||
805 | }, { | ||
806 | .id = 1, | ||
807 | .parent = &ipg_clk, | ||
808 | .enable = _clk_enable, | ||
809 | .enable_reg = CCM_PCCR_CSPI2_REG, | ||
810 | .enable_shift = CCM_PCCR_CSPI2_OFFSET, | ||
811 | .disable = _clk_disable, | ||
812 | }, { | ||
813 | .id = 3, | ||
814 | .parent = &ipg_clk, | ||
815 | .enable = _clk_enable, | ||
816 | .enable_reg = CCM_PCCR_CSPI3_REG, | ||
817 | .enable_shift = CCM_PCCR_CSPI3_OFFSET, | ||
818 | .disable = _clk_disable, | ||
819 | }, | ||
820 | }; | ||
821 | |||
822 | static struct clk lcdc_clk[] = { | ||
823 | { | ||
824 | .parent = &per_clk[2], | ||
825 | .secondary = &lcdc_clk[1], | ||
826 | .round_rate = _clk_parent_round_rate, | ||
827 | .set_rate = _clk_parent_set_rate, | ||
828 | }, { | ||
829 | .parent = &ipg_clk, | ||
830 | .secondary = &lcdc_clk[2], | ||
831 | .enable = _clk_enable, | ||
832 | .enable_reg = CCM_PCCR_LCDC_REG, | ||
833 | .enable_shift = CCM_PCCR_LCDC_OFFSET, | ||
834 | .disable = _clk_disable, | ||
835 | }, { | ||
836 | .parent = &hclk_clk, | ||
837 | .enable = _clk_enable, | ||
838 | .enable_reg = CCM_PCCR_HCLK_LCDC_REG, | ||
839 | .enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET, | ||
840 | .disable = _clk_disable, | ||
841 | }, | ||
842 | }; | ||
843 | |||
844 | static struct clk csi_clk[] = { | ||
845 | { | ||
846 | .parent = &per_clk[3], | ||
847 | .secondary = &csi_clk[1], | ||
848 | .round_rate = _clk_parent_round_rate, | ||
849 | .set_rate = _clk_parent_set_rate, | ||
850 | }, { | ||
851 | .parent = &hclk_clk, | ||
852 | .enable = _clk_enable, | ||
853 | .enable_reg = CCM_PCCR_HCLK_CSI_REG, | ||
854 | .enable_shift = CCM_PCCR_HCLK_CSI_OFFSET, | ||
855 | .disable = _clk_disable, | ||
856 | }, | ||
857 | }; | ||
858 | |||
859 | static struct clk usb_clk[] = { | ||
860 | { | ||
861 | .parent = &spll_clk, | ||
862 | .secondary = &usb_clk[1], | ||
863 | .get_rate = _clk_usb_recalc, | ||
864 | .enable = _clk_enable, | ||
865 | .enable_reg = CCM_PCCR_USBOTG_REG, | ||
866 | .enable_shift = CCM_PCCR_USBOTG_OFFSET, | ||
867 | .disable = _clk_disable, | ||
868 | .round_rate = _clk_usb_round_rate, | ||
869 | .set_rate = _clk_usb_set_rate, | ||
870 | }, { | ||
871 | .parent = &hclk_clk, | ||
872 | .enable = _clk_enable, | ||
873 | .enable_reg = CCM_PCCR_HCLK_USBOTG_REG, | ||
874 | .enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET, | ||
875 | .disable = _clk_disable, | ||
876 | } | ||
877 | }; | ||
878 | |||
879 | static struct clk ssi_ipg_clk[]; | ||
880 | |||
881 | static struct clk ssi_clk[] = { | ||
882 | { | ||
883 | .id = 0, | ||
884 | .parent = &mpll_clk, | ||
885 | .secondary = &ssi_ipg_clk[0], | ||
886 | .get_rate = _clk_ssi1_recalc, | ||
887 | .enable = _clk_enable, | ||
888 | .enable_reg = CCM_PCCR_SSI1_BAUD_REG, | ||
889 | .enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET, | ||
890 | .disable = _clk_disable, | ||
891 | }, { | ||
892 | .id = 1, | ||
893 | .parent = &mpll_clk, | ||
894 | .secondary = &ssi_ipg_clk[1], | ||
895 | .get_rate = _clk_ssi2_recalc, | ||
896 | .enable = _clk_enable, | ||
897 | .enable_reg = CCM_PCCR_SSI2_BAUD_REG, | ||
898 | .enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET, | ||
899 | .disable = _clk_disable, | ||
900 | }, | ||
901 | }; | ||
902 | |||
903 | static struct clk ssi_ipg_clk[] = { | ||
904 | { | ||
905 | .id = 0, | ||
906 | .parent = &ipg_clk, | ||
907 | .enable = _clk_enable, | ||
908 | .enable_reg = CCM_PCCR_SSI1_REG, | ||
909 | .enable_shift = CCM_PCCR_SSI1_IPG_OFFSET, | ||
910 | .disable = _clk_disable, | ||
911 | }, { | ||
912 | .id = 1, | ||
913 | .parent = &ipg_clk, | ||
914 | .enable = _clk_enable, | ||
915 | .enable_reg = CCM_PCCR_SSI2_REG, | ||
916 | .enable_shift = CCM_PCCR_SSI2_IPG_OFFSET, | ||
917 | .disable = _clk_disable, | ||
918 | }, | ||
919 | }; | ||
920 | |||
921 | |||
922 | static struct clk nfc_clk = { | ||
923 | .parent = &fclk_clk, | ||
924 | .get_rate = _clk_nfc_recalc, | ||
925 | .enable = _clk_enable, | ||
926 | .enable_reg = CCM_PCCR_NFC_REG, | ||
927 | .enable_shift = CCM_PCCR_NFC_OFFSET, | ||
928 | .disable = _clk_disable, | ||
929 | }; | ||
930 | |||
931 | static struct clk dma_clk[] = { | ||
932 | { | ||
933 | .parent = &hclk_clk, | ||
934 | .enable = _clk_enable, | ||
935 | .enable_reg = CCM_PCCR_DMA_REG, | ||
936 | .enable_shift = CCM_PCCR_DMA_OFFSET, | ||
937 | .disable = _clk_disable, | ||
938 | .secondary = &dma_clk[1], | ||
939 | }, { | ||
940 | .enable = _clk_enable, | ||
941 | .enable_reg = CCM_PCCR_HCLK_DMA_REG, | ||
942 | .enable_shift = CCM_PCCR_HCLK_DMA_OFFSET, | ||
943 | .disable = _clk_disable, | ||
944 | }, | ||
945 | }; | ||
946 | |||
947 | static struct clk brom_clk = { | ||
948 | .parent = &hclk_clk, | ||
949 | .enable = _clk_enable, | ||
950 | .enable_reg = CCM_PCCR_HCLK_BROM_REG, | ||
951 | .enable_shift = CCM_PCCR_HCLK_BROM_OFFSET, | ||
952 | .disable = _clk_disable, | ||
953 | }; | ||
954 | |||
955 | static struct clk emma_clk[] = { | ||
956 | { | ||
957 | .parent = &hclk_clk, | ||
958 | .enable = _clk_enable, | ||
959 | .enable_reg = CCM_PCCR_EMMA_REG, | ||
960 | .enable_shift = CCM_PCCR_EMMA_OFFSET, | ||
961 | .disable = _clk_disable, | ||
962 | .secondary = &emma_clk[1], | ||
963 | }, { | ||
964 | .enable = _clk_enable, | ||
965 | .enable_reg = CCM_PCCR_HCLK_EMMA_REG, | ||
966 | .enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET, | ||
967 | .disable = _clk_disable, | ||
968 | } | ||
969 | }; | ||
970 | |||
971 | static struct clk slcdc_clk[] = { | ||
972 | { | ||
973 | .parent = &hclk_clk, | ||
974 | .enable = _clk_enable, | ||
975 | .enable_reg = CCM_PCCR_SLCDC_REG, | ||
976 | .enable_shift = CCM_PCCR_SLCDC_OFFSET, | ||
977 | .disable = _clk_disable, | ||
978 | .secondary = &slcdc_clk[1], | ||
979 | }, { | ||
980 | .enable = _clk_enable, | ||
981 | .enable_reg = CCM_PCCR_HCLK_SLCDC_REG, | ||
982 | .enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET, | ||
983 | .disable = _clk_disable, | ||
984 | } | ||
985 | }; | ||
986 | |||
987 | static struct clk wdog_clk = { | ||
988 | .parent = &ipg_clk, | ||
989 | .enable = _clk_enable, | ||
990 | .enable_reg = CCM_PCCR_WDT_REG, | ||
991 | .enable_shift = CCM_PCCR_WDT_OFFSET, | ||
992 | .disable = _clk_disable, | ||
993 | }; | ||
994 | |||
995 | static struct clk gpio_clk = { | ||
996 | .parent = &ipg_clk, | ||
997 | .enable = _clk_enable, | ||
998 | .enable_reg = CCM_PCCR_GPIO_REG, | ||
999 | .enable_shift = CCM_PCCR_GPIO_OFFSET, | ||
1000 | .disable = _clk_disable, | ||
1001 | }; | ||
1002 | |||
1003 | static struct clk i2c_clk = { | ||
1004 | .id = 0, | ||
1005 | .parent = &ipg_clk, | ||
1006 | .enable = _clk_enable, | ||
1007 | .enable_reg = CCM_PCCR_I2C1_REG, | ||
1008 | .enable_shift = CCM_PCCR_I2C1_OFFSET, | ||
1009 | .disable = _clk_disable, | ||
1010 | }; | ||
1011 | |||
1012 | static struct clk kpp_clk = { | ||
1013 | .parent = &ipg_clk, | ||
1014 | .enable = _clk_enable, | ||
1015 | .enable_reg = CCM_PCCR_KPP_REG, | ||
1016 | .enable_shift = CCM_PCCR_KPP_OFFSET, | ||
1017 | .disable = _clk_disable, | ||
1018 | }; | ||
1019 | |||
1020 | static struct clk owire_clk = { | ||
1021 | .parent = &ipg_clk, | ||
1022 | .enable = _clk_enable, | ||
1023 | .enable_reg = CCM_PCCR_OWIRE_REG, | ||
1024 | .enable_shift = CCM_PCCR_OWIRE_OFFSET, | ||
1025 | .disable = _clk_disable, | ||
1026 | }; | ||
1027 | |||
1028 | static struct clk rtc_clk = { | ||
1029 | .parent = &ipg_clk, | ||
1030 | .enable = _clk_enable, | ||
1031 | .enable_reg = CCM_PCCR_RTC_REG, | ||
1032 | .enable_shift = CCM_PCCR_RTC_OFFSET, | ||
1033 | .disable = _clk_disable, | ||
1034 | }; | ||
1035 | |||
1036 | static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate) | ||
1037 | { | ||
1038 | return _clk_generic_round_rate(clk, rate, 8); | ||
1039 | } | ||
1040 | |||
1041 | static int _clk_clko_set_rate(struct clk *clk, unsigned long rate) | ||
1042 | { | ||
1043 | u32 reg; | ||
1044 | u32 div; | ||
1045 | unsigned long parent_rate; | ||
1046 | |||
1047 | parent_rate = clk_get_rate(clk->parent); | ||
1048 | |||
1049 | div = parent_rate / rate; | ||
1050 | |||
1051 | if (div > 8 || div < 1 || ((parent_rate / div) != rate)) | ||
1052 | return -EINVAL; | ||
1053 | div--; | ||
1054 | |||
1055 | reg = __raw_readl(CCM_PCDR0); | ||
1056 | |||
1057 | if (clk->parent == &usb_clk[0]) { | ||
1058 | reg &= ~CCM_PCDR0_48MDIV_MASK; | ||
1059 | reg |= div << CCM_PCDR0_48MDIV_OFFSET; | ||
1060 | } | ||
1061 | __raw_writel(reg, CCM_PCDR0); | ||
1062 | |||
1063 | return 0; | ||
1064 | } | ||
1065 | |||
1066 | static unsigned long _clk_clko_recalc(struct clk *clk) | ||
1067 | { | ||
1068 | u32 div = 0; | ||
1069 | unsigned long parent_rate; | ||
1070 | |||
1071 | parent_rate = clk_get_rate(clk->parent); | ||
1072 | |||
1073 | if (clk->parent == &usb_clk[0]) /* 48M */ | ||
1074 | div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK | ||
1075 | >> CCM_PCDR0_48MDIV_OFFSET; | ||
1076 | div++; | ||
1077 | |||
1078 | return parent_rate / div; | ||
1079 | } | ||
1080 | |||
1081 | static struct clk clko_clk; | ||
1082 | |||
1083 | static int _clk_clko_set_parent(struct clk *clk, struct clk *parent) | ||
1084 | { | ||
1085 | u32 reg; | ||
1086 | |||
1087 | reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK; | ||
1088 | |||
1089 | if (parent == &ckil_clk) | ||
1090 | reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1091 | else if (parent == &fpm_clk) | ||
1092 | reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1093 | else if (parent == &ckih_clk) | ||
1094 | reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1095 | else if (parent == mpll_clk.parent) | ||
1096 | reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1097 | else if (parent == spll_clk.parent) | ||
1098 | reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1099 | else if (parent == &mpll_clk) | ||
1100 | reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1101 | else if (parent == &spll_clk) | ||
1102 | reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1103 | else if (parent == &fclk_clk) | ||
1104 | reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1105 | else if (parent == &hclk_clk) | ||
1106 | reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1107 | else if (parent == &ipg_clk) | ||
1108 | reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1109 | else if (parent == &per_clk[0]) | ||
1110 | reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET; | ||
1111 | else if (parent == &per_clk[1]) | ||
1112 | reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET; | ||
1113 | else if (parent == &per_clk[2]) | ||
1114 | reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET; | ||
1115 | else if (parent == &per_clk[3]) | ||
1116 | reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET; | ||
1117 | else if (parent == &ssi_clk[0]) | ||
1118 | reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET; | ||
1119 | else if (parent == &ssi_clk[1]) | ||
1120 | reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET; | ||
1121 | else if (parent == &nfc_clk) | ||
1122 | reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1123 | else if (parent == &usb_clk[0]) | ||
1124 | reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1125 | else if (parent == &clko_clk) | ||
1126 | reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET; | ||
1127 | else | ||
1128 | return -EINVAL; | ||
1129 | |||
1130 | __raw_writel(reg, CCM_CCSR); | ||
1131 | |||
1132 | return 0; | ||
1133 | } | ||
1134 | |||
1135 | static struct clk clko_clk = { | ||
1136 | .get_rate = _clk_clko_recalc, | ||
1137 | .set_rate = _clk_clko_set_rate, | ||
1138 | .round_rate = _clk_clko_round_rate, | ||
1139 | .set_parent = _clk_clko_set_parent, | ||
1140 | }; | ||
1141 | |||
1142 | |||
1143 | #define _REGISTER_CLOCK(d, n, c) \ | ||
1144 | { \ | ||
1145 | .dev_id = d, \ | ||
1146 | .con_id = n, \ | ||
1147 | .clk = &c, \ | ||
1148 | }, | ||
1149 | static struct clk_lookup lookups[] = { | ||
1150 | /* It's unlikely that any driver wants one of them directly: | ||
1151 | _REGISTER_CLOCK(NULL, "ckih", ckih_clk) | ||
1152 | _REGISTER_CLOCK(NULL, "ckil", ckil_clk) | ||
1153 | _REGISTER_CLOCK(NULL, "fpm", fpm_clk) | ||
1154 | _REGISTER_CLOCK(NULL, "mpll", mpll_clk) | ||
1155 | _REGISTER_CLOCK(NULL, "spll", spll_clk) | ||
1156 | _REGISTER_CLOCK(NULL, "fclk", fclk_clk) | ||
1157 | _REGISTER_CLOCK(NULL, "hclk", hclk_clk) | ||
1158 | _REGISTER_CLOCK(NULL, "ipg", ipg_clk) | ||
1159 | */ | ||
1160 | _REGISTER_CLOCK(NULL, "perclk1", per_clk[0]) | ||
1161 | _REGISTER_CLOCK(NULL, "perclk2", per_clk[1]) | ||
1162 | _REGISTER_CLOCK(NULL, "perclk3", per_clk[2]) | ||
1163 | _REGISTER_CLOCK(NULL, "perclk4", per_clk[3]) | ||
1164 | _REGISTER_CLOCK(NULL, "clko", clko_clk) | ||
1165 | _REGISTER_CLOCK("imx21-uart.0", NULL, uart_clk[0]) | ||
1166 | _REGISTER_CLOCK("imx21-uart.1", NULL, uart_clk[1]) | ||
1167 | _REGISTER_CLOCK("imx21-uart.2", NULL, uart_clk[2]) | ||
1168 | _REGISTER_CLOCK("imx21-uart.3", NULL, uart_clk[3]) | ||
1169 | _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0]) | ||
1170 | _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1]) | ||
1171 | _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2]) | ||
1172 | _REGISTER_CLOCK(NULL, "pwm", pwm_clk[0]) | ||
1173 | _REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0]) | ||
1174 | _REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1]) | ||
1175 | _REGISTER_CLOCK("imx21-cspi.0", NULL, cspi_clk[0]) | ||
1176 | _REGISTER_CLOCK("imx21-cspi.1", NULL, cspi_clk[1]) | ||
1177 | _REGISTER_CLOCK("imx21-cspi.2", NULL, cspi_clk[2]) | ||
1178 | _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0]) | ||
1179 | _REGISTER_CLOCK(NULL, "csi", csi_clk[0]) | ||
1180 | _REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0]) | ||
1181 | _REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0]) | ||
1182 | _REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1]) | ||
1183 | _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) | ||
1184 | _REGISTER_CLOCK(NULL, "dma", dma_clk[0]) | ||
1185 | _REGISTER_CLOCK(NULL, "brom", brom_clk) | ||
1186 | _REGISTER_CLOCK(NULL, "emma", emma_clk[0]) | ||
1187 | _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0]) | ||
1188 | _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) | ||
1189 | _REGISTER_CLOCK(NULL, "gpio", gpio_clk) | ||
1190 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) | ||
1191 | _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk) | ||
1192 | _REGISTER_CLOCK(NULL, "owire", owire_clk) | ||
1193 | _REGISTER_CLOCK(NULL, "rtc", rtc_clk) | ||
1194 | }; | ||
1195 | |||
1196 | /* | ||
1197 | * must be called very early to get information about the | ||
1198 | * available clock rate when the timer framework starts | ||
1199 | */ | ||
1200 | int __init mx21_clocks_init(unsigned long lref, unsigned long href) | ||
1201 | { | ||
1202 | u32 cscr; | ||
1203 | |||
1204 | external_low_reference = lref; | ||
1205 | external_high_reference = href; | ||
1206 | |||
1207 | /* detect clock reference for both system PLL */ | ||
1208 | cscr = CSCR(); | ||
1209 | if (cscr & CCM_CSCR_MCU) | ||
1210 | mpll_clk.parent = &ckih_clk; | ||
1211 | else | ||
1212 | mpll_clk.parent = &fpm_clk; | ||
1213 | |||
1214 | if (cscr & CCM_CSCR_SP) | ||
1215 | spll_clk.parent = &ckih_clk; | ||
1216 | else | ||
1217 | spll_clk.parent = &fpm_clk; | ||
1218 | |||
1219 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
1220 | |||
1221 | /* Turn off all clock gates */ | ||
1222 | __raw_writel(0, CCM_PCCR0); | ||
1223 | __raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1); | ||
1224 | |||
1225 | /* This turns of the serial PLL as well */ | ||
1226 | spll_clk.disable(&spll_clk); | ||
1227 | |||
1228 | /* This will propagate to all children and init all the clock rates. */ | ||
1229 | clk_enable(&per_clk[0]); | ||
1230 | clk_enable(&gpio_clk); | ||
1231 | |||
1232 | #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) | ||
1233 | clk_enable(&uart_clk[0]); | ||
1234 | #endif | ||
1235 | |||
1236 | mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), | ||
1237 | MX21_INT_GPT1); | ||
1238 | return 0; | ||
1239 | } | ||
diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c deleted file mode 100644 index b0fec74c8c91..000000000000 --- a/arch/arm/mach-imx/clock-imx25.c +++ /dev/null | |||
@@ -1,346 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 by Sascha Hauer, Pengutronix | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
16 | * MA 02110-1301, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/clkdev.h> | ||
25 | |||
26 | #include <mach/clock.h> | ||
27 | #include <mach/hardware.h> | ||
28 | #include <mach/common.h> | ||
29 | #include <mach/mx25.h> | ||
30 | |||
31 | #define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR) | ||
32 | |||
33 | #define CCM_MPCTL 0x00 | ||
34 | #define CCM_UPCTL 0x04 | ||
35 | #define CCM_CCTL 0x08 | ||
36 | #define CCM_CGCR0 0x0C | ||
37 | #define CCM_CGCR1 0x10 | ||
38 | #define CCM_CGCR2 0x14 | ||
39 | #define CCM_PCDR0 0x18 | ||
40 | #define CCM_PCDR1 0x1C | ||
41 | #define CCM_PCDR2 0x20 | ||
42 | #define CCM_PCDR3 0x24 | ||
43 | #define CCM_RCSR 0x28 | ||
44 | #define CCM_CRDR 0x2C | ||
45 | #define CCM_DCVR0 0x30 | ||
46 | #define CCM_DCVR1 0x34 | ||
47 | #define CCM_DCVR2 0x38 | ||
48 | #define CCM_DCVR3 0x3c | ||
49 | #define CCM_LTR0 0x40 | ||
50 | #define CCM_LTR1 0x44 | ||
51 | #define CCM_LTR2 0x48 | ||
52 | #define CCM_LTR3 0x4c | ||
53 | |||
54 | static unsigned long get_rate_mpll(void) | ||
55 | { | ||
56 | ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL); | ||
57 | |||
58 | return mxc_decode_pll(mpctl, 24000000); | ||
59 | } | ||
60 | |||
61 | static unsigned long get_rate_upll(void) | ||
62 | { | ||
63 | ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL); | ||
64 | |||
65 | return mxc_decode_pll(mpctl, 24000000); | ||
66 | } | ||
67 | |||
68 | unsigned long get_rate_arm(struct clk *clk) | ||
69 | { | ||
70 | unsigned long cctl = readl(CRM_BASE + CCM_CCTL); | ||
71 | unsigned long rate = get_rate_mpll(); | ||
72 | |||
73 | if (cctl & (1 << 14)) | ||
74 | rate = (rate * 3) >> 2; | ||
75 | |||
76 | return rate / ((cctl >> 30) + 1); | ||
77 | } | ||
78 | |||
79 | static unsigned long get_rate_ahb(struct clk *clk) | ||
80 | { | ||
81 | unsigned long cctl = readl(CRM_BASE + CCM_CCTL); | ||
82 | |||
83 | return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1); | ||
84 | } | ||
85 | |||
86 | static unsigned long get_rate_ipg(struct clk *clk) | ||
87 | { | ||
88 | return get_rate_ahb(NULL) >> 1; | ||
89 | } | ||
90 | |||
91 | static unsigned long get_rate_per(int per) | ||
92 | { | ||
93 | unsigned long ofs = (per & 0x3) * 8; | ||
94 | unsigned long reg = per & ~0x3; | ||
95 | unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f; | ||
96 | unsigned long fref; | ||
97 | |||
98 | if (readl(CRM_BASE + 0x64) & (1 << per)) | ||
99 | fref = get_rate_upll(); | ||
100 | else | ||
101 | fref = get_rate_ahb(NULL); | ||
102 | |||
103 | return fref / (val + 1); | ||
104 | } | ||
105 | |||
106 | static unsigned long get_rate_uart(struct clk *clk) | ||
107 | { | ||
108 | return get_rate_per(15); | ||
109 | } | ||
110 | |||
111 | static unsigned long get_rate_ssi2(struct clk *clk) | ||
112 | { | ||
113 | return get_rate_per(14); | ||
114 | } | ||
115 | |||
116 | static unsigned long get_rate_ssi1(struct clk *clk) | ||
117 | { | ||
118 | return get_rate_per(13); | ||
119 | } | ||
120 | |||
121 | static unsigned long get_rate_i2c(struct clk *clk) | ||
122 | { | ||
123 | return get_rate_per(6); | ||
124 | } | ||
125 | |||
126 | static unsigned long get_rate_nfc(struct clk *clk) | ||
127 | { | ||
128 | return get_rate_per(8); | ||
129 | } | ||
130 | |||
131 | static unsigned long get_rate_gpt(struct clk *clk) | ||
132 | { | ||
133 | return get_rate_per(5); | ||
134 | } | ||
135 | |||
136 | static unsigned long get_rate_lcdc(struct clk *clk) | ||
137 | { | ||
138 | return get_rate_per(7); | ||
139 | } | ||
140 | |||
141 | static unsigned long get_rate_esdhc1(struct clk *clk) | ||
142 | { | ||
143 | return get_rate_per(3); | ||
144 | } | ||
145 | |||
146 | static unsigned long get_rate_esdhc2(struct clk *clk) | ||
147 | { | ||
148 | return get_rate_per(4); | ||
149 | } | ||
150 | |||
151 | static unsigned long get_rate_csi(struct clk *clk) | ||
152 | { | ||
153 | return get_rate_per(0); | ||
154 | } | ||
155 | |||
156 | static unsigned long get_rate_otg(struct clk *clk) | ||
157 | { | ||
158 | unsigned long cctl = readl(CRM_BASE + CCM_CCTL); | ||
159 | unsigned long rate = get_rate_upll(); | ||
160 | |||
161 | return (cctl & (1 << 23)) ? 0 : rate / ((0x3F & (cctl >> 16)) + 1); | ||
162 | } | ||
163 | |||
164 | static int clk_cgcr_enable(struct clk *clk) | ||
165 | { | ||
166 | u32 reg; | ||
167 | |||
168 | reg = __raw_readl(clk->enable_reg); | ||
169 | reg |= 1 << clk->enable_shift; | ||
170 | __raw_writel(reg, clk->enable_reg); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static void clk_cgcr_disable(struct clk *clk) | ||
176 | { | ||
177 | u32 reg; | ||
178 | |||
179 | reg = __raw_readl(clk->enable_reg); | ||
180 | reg &= ~(1 << clk->enable_shift); | ||
181 | __raw_writel(reg, clk->enable_reg); | ||
182 | } | ||
183 | |||
184 | #define DEFINE_CLOCK(name, i, er, es, gr, sr, s) \ | ||
185 | static struct clk name = { \ | ||
186 | .id = i, \ | ||
187 | .enable_reg = CRM_BASE + er, \ | ||
188 | .enable_shift = es, \ | ||
189 | .get_rate = gr, \ | ||
190 | .set_rate = sr, \ | ||
191 | .enable = clk_cgcr_enable, \ | ||
192 | .disable = clk_cgcr_disable, \ | ||
193 | .secondary = s, \ | ||
194 | } | ||
195 | |||
196 | /* | ||
197 | * Note: the following IPG clock gating bits are wrongly marked "Reserved" in | ||
198 | * the i.MX25 Reference Manual Rev 1, table 15-13. The information below is | ||
199 | * taken from the Freescale released BSP. | ||
200 | * | ||
201 | * bit reg offset clock | ||
202 | * | ||
203 | * 0 CGCR1 0 AUDMUX | ||
204 | * 12 CGCR1 12 ESAI | ||
205 | * 16 CGCR1 16 GPIO1 | ||
206 | * 17 CGCR1 17 GPIO2 | ||
207 | * 18 CGCR1 18 GPIO3 | ||
208 | * 23 CGCR1 23 I2C1 | ||
209 | * 24 CGCR1 24 I2C2 | ||
210 | * 25 CGCR1 25 I2C3 | ||
211 | * 27 CGCR1 27 IOMUXC | ||
212 | * 28 CGCR1 28 KPP | ||
213 | * 30 CGCR1 30 OWIRE | ||
214 | * 36 CGCR2 4 RTIC | ||
215 | * 51 CGCR2 19 WDOG | ||
216 | */ | ||
217 | |||
218 | DEFINE_CLOCK(gpt_clk, 0, CCM_CGCR0, 5, get_rate_gpt, NULL, NULL); | ||
219 | DEFINE_CLOCK(uart_per_clk, 0, CCM_CGCR0, 15, get_rate_uart, NULL, NULL); | ||
220 | DEFINE_CLOCK(ssi1_per_clk, 0, CCM_CGCR0, 13, get_rate_ipg, NULL, NULL); | ||
221 | DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL); | ||
222 | DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL); | ||
223 | DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL); | ||
224 | DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL); | ||
225 | DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1, NULL, NULL); | ||
226 | DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, get_rate_esdhc1, NULL, | ||
227 | &esdhc1_ahb_clk); | ||
228 | DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2, NULL, NULL); | ||
229 | DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0, 4, get_rate_esdhc2, NULL, | ||
230 | &esdhc2_ahb_clk); | ||
231 | DEFINE_CLOCK(sdma_ahb_clk, 0, CCM_CGCR0, 26, NULL, NULL, NULL); | ||
232 | DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL); | ||
233 | DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL); | ||
234 | DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk); | ||
235 | DEFINE_CLOCK(csi_ahb_clk, 0, CCM_CGCR0, 18, get_rate_csi, NULL, NULL); | ||
236 | DEFINE_CLOCK(csi_per_clk, 0, CCM_CGCR0, 0, get_rate_csi, NULL, &csi_ahb_clk); | ||
237 | DEFINE_CLOCK(uart1_clk, 0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk); | ||
238 | DEFINE_CLOCK(uart2_clk, 0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk); | ||
239 | DEFINE_CLOCK(uart3_clk, 0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk); | ||
240 | DEFINE_CLOCK(uart4_clk, 0, CCM_CGCR2, 17, get_rate_uart, NULL, &uart_per_clk); | ||
241 | DEFINE_CLOCK(uart5_clk, 0, CCM_CGCR2, 18, get_rate_uart, NULL, &uart_per_clk); | ||
242 | DEFINE_CLOCK(nfc_clk, 0, CCM_CGCR0, 8, get_rate_nfc, NULL, NULL); | ||
243 | DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL, NULL); | ||
244 | DEFINE_CLOCK(pwm1_clk, 0, CCM_CGCR1, 31, get_rate_ipg, NULL, NULL); | ||
245 | DEFINE_CLOCK(pwm2_clk, 0, CCM_CGCR2, 0, get_rate_ipg, NULL, NULL); | ||
246 | DEFINE_CLOCK(pwm3_clk, 0, CCM_CGCR2, 1, get_rate_ipg, NULL, NULL); | ||
247 | DEFINE_CLOCK(pwm4_clk, 0, CCM_CGCR2, 2, get_rate_ipg, NULL, NULL); | ||
248 | DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL, NULL); | ||
249 | DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL, NULL); | ||
250 | DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL, NULL); | ||
251 | DEFINE_CLOCK(fec_clk, 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk); | ||
252 | DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1, 8, get_rate_ipg, NULL, NULL); | ||
253 | DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk); | ||
254 | DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL); | ||
255 | DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk); | ||
256 | DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk); | ||
257 | DEFINE_CLOCK(sdma_clk, 0, CCM_CGCR2, 6, get_rate_ipg, NULL, &sdma_ahb_clk); | ||
258 | DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGCR1, 13, get_rate_esdhc1, NULL, | ||
259 | &esdhc1_per_clk); | ||
260 | DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGCR1, 14, get_rate_esdhc2, NULL, | ||
261 | &esdhc2_per_clk); | ||
262 | DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL); | ||
263 | DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk); | ||
264 | DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL); | ||
265 | DEFINE_CLOCK(can2_clk, 1, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL); | ||
266 | DEFINE_CLOCK(iim_clk, 0, CCM_CGCR1, 26, NULL, NULL, NULL); | ||
267 | |||
268 | #define _REGISTER_CLOCK(d, n, c) \ | ||
269 | { \ | ||
270 | .dev_id = d, \ | ||
271 | .con_id = n, \ | ||
272 | .clk = &c, \ | ||
273 | }, | ||
274 | |||
275 | static struct clk_lookup lookups[] = { | ||
276 | /* i.mx25 has the i.mx21 type uart */ | ||
277 | _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) | ||
278 | _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) | ||
279 | _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) | ||
280 | _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) | ||
281 | _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) | ||
282 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk) | ||
283 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk) | ||
284 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) | ||
285 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk) | ||
286 | _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) | ||
287 | /* i.mx25 has the i.mx35 type cspi */ | ||
288 | _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk) | ||
289 | _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk) | ||
290 | _REGISTER_CLOCK("imx35-cspi.2", NULL, cspi3_clk) | ||
291 | _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk) | ||
292 | _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk) | ||
293 | _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk) | ||
294 | _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk) | ||
295 | _REGISTER_CLOCK("imx-keypad", NULL, kpp_clk) | ||
296 | _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk) | ||
297 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) | ||
298 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk) | ||
299 | _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk) | ||
300 | _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk) | ||
301 | _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk) | ||
302 | _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) | ||
303 | _REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk) | ||
304 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) | ||
305 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) | ||
306 | _REGISTER_CLOCK("sdhci-esdhc-imx25.0", NULL, esdhc1_clk) | ||
307 | _REGISTER_CLOCK("sdhci-esdhc-imx25.1", NULL, esdhc2_clk) | ||
308 | _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk) | ||
309 | _REGISTER_CLOCK(NULL, "audmux", audmux_clk) | ||
310 | _REGISTER_CLOCK("flexcan.0", NULL, can1_clk) | ||
311 | _REGISTER_CLOCK("flexcan.1", NULL, can2_clk) | ||
312 | /* i.mx25 has the i.mx35 type sdma */ | ||
313 | _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) | ||
314 | _REGISTER_CLOCK(NULL, "iim", iim_clk) | ||
315 | }; | ||
316 | |||
317 | int __init mx25_clocks_init(void) | ||
318 | { | ||
319 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
320 | |||
321 | /* Turn off all clocks except the ones we need to survive, namely: | ||
322 | * EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM, | ||
323 | * SCC | ||
324 | */ | ||
325 | __raw_writel((1 << 19), CRM_BASE + CCM_CGCR0); | ||
326 | __raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1); | ||
327 | __raw_writel((1 << 5), CRM_BASE + CCM_CGCR2); | ||
328 | #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) | ||
329 | clk_enable(&uart1_clk); | ||
330 | #endif | ||
331 | |||
332 | /* Clock source for lcdc and csi is upll */ | ||
333 | __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0), | ||
334 | CRM_BASE + 0x64); | ||
335 | |||
336 | /* Clock source for gpt is ahb_div */ | ||
337 | __raw_writel(__raw_readl(CRM_BASE+0x64) & ~(1 << 5), CRM_BASE + 0x64); | ||
338 | |||
339 | clk_enable(&iim_clk); | ||
340 | imx_print_silicon_rev("i.MX25", mx25_revision()); | ||
341 | clk_disable(&iim_clk); | ||
342 | |||
343 | mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); | ||
344 | |||
345 | return 0; | ||
346 | } | ||
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c deleted file mode 100644 index 98e04f5a87dd..000000000000 --- a/arch/arm/mach-imx/clock-imx27.c +++ /dev/null | |||
@@ -1,785 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright 2008 Juergen Beisert, kernel@pengutronix.de | ||
4 | * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version 2 | ||
9 | * of the License, or (at your option) any later version. | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
18 | * MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/clk.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/clkdev.h> | ||
25 | #include <linux/of.h> | ||
26 | |||
27 | #include <asm/div64.h> | ||
28 | |||
29 | #include <mach/clock.h> | ||
30 | #include <mach/common.h> | ||
31 | #include <mach/hardware.h> | ||
32 | |||
33 | #define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off))) | ||
34 | |||
35 | /* Register offsets */ | ||
36 | #define CCM_CSCR IO_ADDR_CCM(0x0) | ||
37 | #define CCM_MPCTL0 IO_ADDR_CCM(0x4) | ||
38 | #define CCM_MPCTL1 IO_ADDR_CCM(0x8) | ||
39 | #define CCM_SPCTL0 IO_ADDR_CCM(0xc) | ||
40 | #define CCM_SPCTL1 IO_ADDR_CCM(0x10) | ||
41 | #define CCM_OSC26MCTL IO_ADDR_CCM(0x14) | ||
42 | #define CCM_PCDR0 IO_ADDR_CCM(0x18) | ||
43 | #define CCM_PCDR1 IO_ADDR_CCM(0x1c) | ||
44 | #define CCM_PCCR0 IO_ADDR_CCM(0x20) | ||
45 | #define CCM_PCCR1 IO_ADDR_CCM(0x24) | ||
46 | #define CCM_CCSR IO_ADDR_CCM(0x28) | ||
47 | #define CCM_PMCTL IO_ADDR_CCM(0x2c) | ||
48 | #define CCM_PMCOUNT IO_ADDR_CCM(0x30) | ||
49 | #define CCM_WKGDCTL IO_ADDR_CCM(0x34) | ||
50 | |||
51 | #define CCM_CSCR_UPDATE_DIS (1 << 31) | ||
52 | #define CCM_CSCR_SSI2 (1 << 23) | ||
53 | #define CCM_CSCR_SSI1 (1 << 22) | ||
54 | #define CCM_CSCR_VPU (1 << 21) | ||
55 | #define CCM_CSCR_MSHC (1 << 20) | ||
56 | #define CCM_CSCR_SPLLRES (1 << 19) | ||
57 | #define CCM_CSCR_MPLLRES (1 << 18) | ||
58 | #define CCM_CSCR_SP (1 << 17) | ||
59 | #define CCM_CSCR_MCU (1 << 16) | ||
60 | #define CCM_CSCR_OSC26MDIV (1 << 4) | ||
61 | #define CCM_CSCR_OSC26M (1 << 3) | ||
62 | #define CCM_CSCR_FPM (1 << 2) | ||
63 | #define CCM_CSCR_SPEN (1 << 1) | ||
64 | #define CCM_CSCR_MPEN (1 << 0) | ||
65 | |||
66 | /* i.MX27 TO 2+ */ | ||
67 | #define CCM_CSCR_ARM_SRC (1 << 15) | ||
68 | |||
69 | #define CCM_SPCTL1_LF (1 << 15) | ||
70 | #define CCM_SPCTL1_BRMO (1 << 6) | ||
71 | |||
72 | static struct clk mpll_main1_clk, mpll_main2_clk; | ||
73 | |||
74 | static int clk_pccr_enable(struct clk *clk) | ||
75 | { | ||
76 | unsigned long reg; | ||
77 | |||
78 | if (!clk->enable_reg) | ||
79 | return 0; | ||
80 | |||
81 | reg = __raw_readl(clk->enable_reg); | ||
82 | reg |= 1 << clk->enable_shift; | ||
83 | __raw_writel(reg, clk->enable_reg); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static void clk_pccr_disable(struct clk *clk) | ||
89 | { | ||
90 | unsigned long reg; | ||
91 | |||
92 | if (!clk->enable_reg) | ||
93 | return; | ||
94 | |||
95 | reg = __raw_readl(clk->enable_reg); | ||
96 | reg &= ~(1 << clk->enable_shift); | ||
97 | __raw_writel(reg, clk->enable_reg); | ||
98 | } | ||
99 | |||
100 | static int clk_spll_enable(struct clk *clk) | ||
101 | { | ||
102 | unsigned long reg; | ||
103 | |||
104 | reg = __raw_readl(CCM_CSCR); | ||
105 | reg |= CCM_CSCR_SPEN; | ||
106 | __raw_writel(reg, CCM_CSCR); | ||
107 | |||
108 | while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF)); | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static void clk_spll_disable(struct clk *clk) | ||
114 | { | ||
115 | unsigned long reg; | ||
116 | |||
117 | reg = __raw_readl(CCM_CSCR); | ||
118 | reg &= ~CCM_CSCR_SPEN; | ||
119 | __raw_writel(reg, CCM_CSCR); | ||
120 | } | ||
121 | |||
122 | static int clk_cpu_set_parent(struct clk *clk, struct clk *parent) | ||
123 | { | ||
124 | int cscr = __raw_readl(CCM_CSCR); | ||
125 | |||
126 | if (clk->parent == parent) | ||
127 | return 0; | ||
128 | |||
129 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { | ||
130 | if (parent == &mpll_main1_clk) { | ||
131 | cscr |= CCM_CSCR_ARM_SRC; | ||
132 | } else { | ||
133 | if (parent == &mpll_main2_clk) | ||
134 | cscr &= ~CCM_CSCR_ARM_SRC; | ||
135 | else | ||
136 | return -EINVAL; | ||
137 | } | ||
138 | __raw_writel(cscr, CCM_CSCR); | ||
139 | clk->parent = parent; | ||
140 | return 0; | ||
141 | } | ||
142 | return -ENODEV; | ||
143 | } | ||
144 | |||
145 | static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate) | ||
146 | { | ||
147 | int div; | ||
148 | unsigned long parent_rate; | ||
149 | |||
150 | parent_rate = clk_get_rate(clk->parent); | ||
151 | |||
152 | div = parent_rate / rate; | ||
153 | if (parent_rate % rate) | ||
154 | div++; | ||
155 | |||
156 | if (div > 4) | ||
157 | div = 4; | ||
158 | |||
159 | return parent_rate / div; | ||
160 | } | ||
161 | |||
162 | static int set_rate_cpu(struct clk *clk, unsigned long rate) | ||
163 | { | ||
164 | unsigned int div; | ||
165 | uint32_t reg; | ||
166 | unsigned long parent_rate; | ||
167 | |||
168 | parent_rate = clk_get_rate(clk->parent); | ||
169 | |||
170 | div = parent_rate / rate; | ||
171 | |||
172 | if (div > 4 || div < 1 || ((parent_rate / div) != rate)) | ||
173 | return -EINVAL; | ||
174 | |||
175 | div--; | ||
176 | |||
177 | reg = __raw_readl(CCM_CSCR); | ||
178 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { | ||
179 | reg &= ~(3 << 12); | ||
180 | reg |= div << 12; | ||
181 | reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN); | ||
182 | __raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR); | ||
183 | } else { | ||
184 | printk(KERN_ERR "Can't set CPU frequency!\n"); | ||
185 | } | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static unsigned long round_rate_per(struct clk *clk, unsigned long rate) | ||
191 | { | ||
192 | u32 div; | ||
193 | unsigned long parent_rate; | ||
194 | |||
195 | parent_rate = clk_get_rate(clk->parent); | ||
196 | |||
197 | div = parent_rate / rate; | ||
198 | if (parent_rate % rate) | ||
199 | div++; | ||
200 | |||
201 | if (div > 64) | ||
202 | div = 64; | ||
203 | |||
204 | return parent_rate / div; | ||
205 | } | ||
206 | |||
207 | static int set_rate_per(struct clk *clk, unsigned long rate) | ||
208 | { | ||
209 | u32 reg; | ||
210 | u32 div; | ||
211 | unsigned long parent_rate; | ||
212 | |||
213 | parent_rate = clk_get_rate(clk->parent); | ||
214 | |||
215 | if (clk->id < 0 || clk->id > 3) | ||
216 | return -EINVAL; | ||
217 | |||
218 | div = parent_rate / rate; | ||
219 | if (div > 64 || div < 1 || ((parent_rate / div) != rate)) | ||
220 | return -EINVAL; | ||
221 | div--; | ||
222 | |||
223 | reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3)); | ||
224 | reg |= div << (clk->id << 3); | ||
225 | __raw_writel(reg, CCM_PCDR1); | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static unsigned long get_rate_usb(struct clk *clk) | ||
231 | { | ||
232 | unsigned long usb_pdf; | ||
233 | unsigned long parent_rate; | ||
234 | |||
235 | parent_rate = clk_get_rate(clk->parent); | ||
236 | |||
237 | usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7; | ||
238 | |||
239 | return parent_rate / (usb_pdf + 1U); | ||
240 | } | ||
241 | |||
242 | static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf) | ||
243 | { | ||
244 | unsigned long parent_rate; | ||
245 | |||
246 | parent_rate = clk_get_rate(clk->parent); | ||
247 | |||
248 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) | ||
249 | pdf += 4; /* MX27 TO2+ */ | ||
250 | else | ||
251 | pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */ | ||
252 | |||
253 | return 2UL * parent_rate / pdf; | ||
254 | } | ||
255 | |||
256 | static unsigned long get_rate_ssi1(struct clk *clk) | ||
257 | { | ||
258 | return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f); | ||
259 | } | ||
260 | |||
261 | static unsigned long get_rate_ssi2(struct clk *clk) | ||
262 | { | ||
263 | return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f); | ||
264 | } | ||
265 | |||
266 | static unsigned long get_rate_nfc(struct clk *clk) | ||
267 | { | ||
268 | unsigned long nfc_pdf; | ||
269 | unsigned long parent_rate; | ||
270 | |||
271 | parent_rate = clk_get_rate(clk->parent); | ||
272 | |||
273 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) | ||
274 | nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf; | ||
275 | else | ||
276 | nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf; | ||
277 | |||
278 | return parent_rate / (nfc_pdf + 1); | ||
279 | } | ||
280 | |||
281 | static unsigned long get_rate_vpu(struct clk *clk) | ||
282 | { | ||
283 | unsigned long vpu_pdf; | ||
284 | unsigned long parent_rate; | ||
285 | |||
286 | parent_rate = clk_get_rate(clk->parent); | ||
287 | |||
288 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { | ||
289 | vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f; | ||
290 | vpu_pdf += 4; | ||
291 | } else { | ||
292 | vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf; | ||
293 | vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf; | ||
294 | } | ||
295 | |||
296 | return 2UL * parent_rate / vpu_pdf; | ||
297 | } | ||
298 | |||
299 | static unsigned long round_rate_parent(struct clk *clk, unsigned long rate) | ||
300 | { | ||
301 | return clk->parent->round_rate(clk->parent, rate); | ||
302 | } | ||
303 | |||
304 | static unsigned long get_rate_parent(struct clk *clk) | ||
305 | { | ||
306 | return clk_get_rate(clk->parent); | ||
307 | } | ||
308 | |||
309 | static int set_rate_parent(struct clk *clk, unsigned long rate) | ||
310 | { | ||
311 | return clk->parent->set_rate(clk->parent, rate); | ||
312 | } | ||
313 | |||
314 | /* in Hz */ | ||
315 | static unsigned long external_high_reference = 26000000; | ||
316 | |||
317 | static unsigned long get_rate_high_reference(struct clk *clk) | ||
318 | { | ||
319 | return external_high_reference; | ||
320 | } | ||
321 | |||
322 | /* in Hz */ | ||
323 | static unsigned long external_low_reference = 32768; | ||
324 | |||
325 | static unsigned long get_rate_low_reference(struct clk *clk) | ||
326 | { | ||
327 | return external_low_reference; | ||
328 | } | ||
329 | |||
330 | static unsigned long get_rate_fpm(struct clk *clk) | ||
331 | { | ||
332 | return clk_get_rate(clk->parent) * 1024; | ||
333 | } | ||
334 | |||
335 | static unsigned long get_rate_mpll(struct clk *clk) | ||
336 | { | ||
337 | return mxc_decode_pll(__raw_readl(CCM_MPCTL0), | ||
338 | clk_get_rate(clk->parent)); | ||
339 | } | ||
340 | |||
341 | static unsigned long get_rate_mpll_main(struct clk *clk) | ||
342 | { | ||
343 | unsigned long parent_rate; | ||
344 | |||
345 | parent_rate = clk_get_rate(clk->parent); | ||
346 | |||
347 | /* i.MX27 TO2: | ||
348 | * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2 | ||
349 | * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3 | ||
350 | */ | ||
351 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0 && clk->id == 1) | ||
352 | return 2UL * parent_rate / 3UL; | ||
353 | |||
354 | return parent_rate; | ||
355 | } | ||
356 | |||
357 | static unsigned long get_rate_spll(struct clk *clk) | ||
358 | { | ||
359 | uint32_t reg; | ||
360 | unsigned long rate; | ||
361 | |||
362 | rate = clk_get_rate(clk->parent); | ||
363 | |||
364 | reg = __raw_readl(CCM_SPCTL0); | ||
365 | |||
366 | /* On TO2 we have to write the value back. Otherwise we | ||
367 | * read 0 from this register the next time. | ||
368 | */ | ||
369 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) | ||
370 | __raw_writel(reg, CCM_SPCTL0); | ||
371 | |||
372 | return mxc_decode_pll(reg, rate); | ||
373 | } | ||
374 | |||
375 | static unsigned long get_rate_cpu(struct clk *clk) | ||
376 | { | ||
377 | u32 div; | ||
378 | unsigned long rate; | ||
379 | |||
380 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) | ||
381 | div = (__raw_readl(CCM_CSCR) >> 12) & 0x3; | ||
382 | else | ||
383 | div = (__raw_readl(CCM_CSCR) >> 13) & 0x7; | ||
384 | |||
385 | rate = clk_get_rate(clk->parent); | ||
386 | return rate / (div + 1); | ||
387 | } | ||
388 | |||
389 | static unsigned long get_rate_ahb(struct clk *clk) | ||
390 | { | ||
391 | unsigned long rate, bclk_pdf; | ||
392 | |||
393 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) | ||
394 | bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3; | ||
395 | else | ||
396 | bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf; | ||
397 | |||
398 | rate = clk_get_rate(clk->parent); | ||
399 | return rate / (bclk_pdf + 1); | ||
400 | } | ||
401 | |||
402 | static unsigned long get_rate_ipg(struct clk *clk) | ||
403 | { | ||
404 | unsigned long rate, ipg_pdf; | ||
405 | |||
406 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) | ||
407 | return clk_get_rate(clk->parent); | ||
408 | else | ||
409 | ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1; | ||
410 | |||
411 | rate = clk_get_rate(clk->parent); | ||
412 | return rate / (ipg_pdf + 1); | ||
413 | } | ||
414 | |||
415 | static unsigned long get_rate_per(struct clk *clk) | ||
416 | { | ||
417 | unsigned long perclk_pdf, parent_rate; | ||
418 | |||
419 | parent_rate = clk_get_rate(clk->parent); | ||
420 | |||
421 | if (clk->id < 0 || clk->id > 3) | ||
422 | return 0; | ||
423 | |||
424 | perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f; | ||
425 | |||
426 | return parent_rate / (perclk_pdf + 1); | ||
427 | } | ||
428 | |||
429 | /* | ||
430 | * the high frequency external clock reference | ||
431 | * Default case is 26MHz. Could be changed at runtime | ||
432 | * with a call to change_external_high_reference() | ||
433 | */ | ||
434 | static struct clk ckih_clk = { | ||
435 | .get_rate = get_rate_high_reference, | ||
436 | }; | ||
437 | |||
438 | static struct clk mpll_clk = { | ||
439 | .parent = &ckih_clk, | ||
440 | .get_rate = get_rate_mpll, | ||
441 | }; | ||
442 | |||
443 | /* For i.MX27 TO2, it is the MPLL path 1 of ARM core | ||
444 | * It provides the clock source whose rate is same as MPLL | ||
445 | */ | ||
446 | static struct clk mpll_main1_clk = { | ||
447 | .id = 0, | ||
448 | .parent = &mpll_clk, | ||
449 | .get_rate = get_rate_mpll_main, | ||
450 | }; | ||
451 | |||
452 | /* For i.MX27 TO2, it is the MPLL path 2 of ARM core | ||
453 | * It provides the clock source whose rate is same MPLL * 2 / 3 | ||
454 | */ | ||
455 | static struct clk mpll_main2_clk = { | ||
456 | .id = 1, | ||
457 | .parent = &mpll_clk, | ||
458 | .get_rate = get_rate_mpll_main, | ||
459 | }; | ||
460 | |||
461 | static struct clk ahb_clk = { | ||
462 | .parent = &mpll_main2_clk, | ||
463 | .get_rate = get_rate_ahb, | ||
464 | }; | ||
465 | |||
466 | static struct clk ipg_clk = { | ||
467 | .parent = &ahb_clk, | ||
468 | .get_rate = get_rate_ipg, | ||
469 | }; | ||
470 | |||
471 | static struct clk cpu_clk = { | ||
472 | .parent = &mpll_main2_clk, | ||
473 | .set_parent = clk_cpu_set_parent, | ||
474 | .round_rate = round_rate_cpu, | ||
475 | .get_rate = get_rate_cpu, | ||
476 | .set_rate = set_rate_cpu, | ||
477 | }; | ||
478 | |||
479 | static struct clk spll_clk = { | ||
480 | .parent = &ckih_clk, | ||
481 | .get_rate = get_rate_spll, | ||
482 | .enable = clk_spll_enable, | ||
483 | .disable = clk_spll_disable, | ||
484 | }; | ||
485 | |||
486 | /* | ||
487 | * the low frequency external clock reference | ||
488 | * Default case is 32.768kHz. | ||
489 | */ | ||
490 | static struct clk ckil_clk = { | ||
491 | .get_rate = get_rate_low_reference, | ||
492 | }; | ||
493 | |||
494 | /* Output of frequency pre multiplier */ | ||
495 | static struct clk fpm_clk = { | ||
496 | .parent = &ckil_clk, | ||
497 | .get_rate = get_rate_fpm, | ||
498 | }; | ||
499 | |||
500 | #define PCCR0 CCM_PCCR0 | ||
501 | #define PCCR1 CCM_PCCR1 | ||
502 | |||
503 | #define DEFINE_CLOCK(name, i, er, es, gr, s, p) \ | ||
504 | static struct clk name = { \ | ||
505 | .id = i, \ | ||
506 | .enable_reg = er, \ | ||
507 | .enable_shift = es, \ | ||
508 | .get_rate = gr, \ | ||
509 | .enable = clk_pccr_enable, \ | ||
510 | .disable = clk_pccr_disable, \ | ||
511 | .secondary = s, \ | ||
512 | .parent = p, \ | ||
513 | } | ||
514 | |||
515 | #define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \ | ||
516 | static struct clk name = { \ | ||
517 | .id = i, \ | ||
518 | .enable_reg = er, \ | ||
519 | .enable_shift = es, \ | ||
520 | .get_rate = get_rate_##getsetround, \ | ||
521 | .set_rate = set_rate_##getsetround, \ | ||
522 | .round_rate = round_rate_##getsetround, \ | ||
523 | .enable = clk_pccr_enable, \ | ||
524 | .disable = clk_pccr_disable, \ | ||
525 | .secondary = s, \ | ||
526 | .parent = p, \ | ||
527 | } | ||
528 | |||
529 | /* Forward declaration to keep the following list in order */ | ||
530 | static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1, | ||
531 | dma_clk1, lcdc_clk2, vpu_clk1; | ||
532 | |||
533 | /* All clocks we can gate through PCCRx in the order of PCCRx bits */ | ||
534 | DEFINE_CLOCK(ssi2_clk1, 1, PCCR0, 0, NULL, NULL, &ipg_clk); | ||
535 | DEFINE_CLOCK(ssi1_clk1, 0, PCCR0, 1, NULL, NULL, &ipg_clk); | ||
536 | DEFINE_CLOCK(slcdc_clk, 0, PCCR0, 2, NULL, &slcdc_clk1, &ahb_clk); | ||
537 | DEFINE_CLOCK(sdhc3_clk1, 0, PCCR0, 3, NULL, NULL, &ipg_clk); | ||
538 | DEFINE_CLOCK(sdhc2_clk1, 0, PCCR0, 4, NULL, NULL, &ipg_clk); | ||
539 | DEFINE_CLOCK(sdhc1_clk1, 0, PCCR0, 5, NULL, NULL, &ipg_clk); | ||
540 | DEFINE_CLOCK(scc_clk, 0, PCCR0, 6, NULL, NULL, &ipg_clk); | ||
541 | DEFINE_CLOCK(sahara2_clk, 0, PCCR0, 7, NULL, &sahara2_clk1, &ahb_clk); | ||
542 | DEFINE_CLOCK(rtic_clk, 0, PCCR0, 8, NULL, &rtic_clk1, &ahb_clk); | ||
543 | DEFINE_CLOCK(rtc_clk, 0, PCCR0, 9, NULL, NULL, &ipg_clk); | ||
544 | DEFINE_CLOCK(pwm_clk1, 0, PCCR0, 11, NULL, NULL, &ipg_clk); | ||
545 | DEFINE_CLOCK(owire_clk, 0, PCCR0, 12, NULL, NULL, &ipg_clk); | ||
546 | DEFINE_CLOCK(mstick_clk1, 0, PCCR0, 13, NULL, NULL, &ipg_clk); | ||
547 | DEFINE_CLOCK(lcdc_clk1, 0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk); | ||
548 | DEFINE_CLOCK(kpp_clk, 0, PCCR0, 15, NULL, NULL, &ipg_clk); | ||
549 | DEFINE_CLOCK(iim_clk, 0, PCCR0, 16, NULL, NULL, &ipg_clk); | ||
550 | DEFINE_CLOCK(i2c2_clk, 1, PCCR0, 17, NULL, NULL, &ipg_clk); | ||
551 | DEFINE_CLOCK(i2c1_clk, 0, PCCR0, 18, NULL, NULL, &ipg_clk); | ||
552 | DEFINE_CLOCK(gpt6_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk); | ||
553 | DEFINE_CLOCK(gpt5_clk1, 0, PCCR0, 20, NULL, NULL, &ipg_clk); | ||
554 | DEFINE_CLOCK(gpt4_clk1, 0, PCCR0, 21, NULL, NULL, &ipg_clk); | ||
555 | DEFINE_CLOCK(gpt3_clk1, 0, PCCR0, 22, NULL, NULL, &ipg_clk); | ||
556 | DEFINE_CLOCK(gpt2_clk1, 0, PCCR0, 23, NULL, NULL, &ipg_clk); | ||
557 | DEFINE_CLOCK(gpt1_clk1, 0, PCCR0, 24, NULL, NULL, &ipg_clk); | ||
558 | DEFINE_CLOCK(gpio_clk, 0, PCCR0, 25, NULL, NULL, &ipg_clk); | ||
559 | DEFINE_CLOCK(fec_clk, 0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk); | ||
560 | DEFINE_CLOCK(emma_clk, 0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk); | ||
561 | DEFINE_CLOCK(dma_clk, 0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk); | ||
562 | DEFINE_CLOCK(cspi13_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk); | ||
563 | DEFINE_CLOCK(cspi2_clk1, 0, PCCR0, 30, NULL, NULL, &ipg_clk); | ||
564 | DEFINE_CLOCK(cspi1_clk1, 0, PCCR0, 31, NULL, NULL, &ipg_clk); | ||
565 | |||
566 | DEFINE_CLOCK(mstick_clk, 0, PCCR1, 2, NULL, &mstick_clk1, &ipg_clk); | ||
567 | DEFINE_CLOCK(nfc_clk, 0, PCCR1, 3, get_rate_nfc, NULL, &cpu_clk); | ||
568 | DEFINE_CLOCK(ssi2_clk, 1, PCCR1, 4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk); | ||
569 | DEFINE_CLOCK(ssi1_clk, 0, PCCR1, 5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk); | ||
570 | DEFINE_CLOCK(vpu_clk, 0, PCCR1, 6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk); | ||
571 | DEFINE_CLOCK1(per4_clk, 3, PCCR1, 7, per, NULL, &mpll_main2_clk); | ||
572 | DEFINE_CLOCK1(per3_clk, 2, PCCR1, 8, per, NULL, &mpll_main2_clk); | ||
573 | DEFINE_CLOCK1(per2_clk, 1, PCCR1, 9, per, NULL, &mpll_main2_clk); | ||
574 | DEFINE_CLOCK1(per1_clk, 0, PCCR1, 10, per, NULL, &mpll_main2_clk); | ||
575 | DEFINE_CLOCK(usb_clk1, 0, PCCR1, 11, NULL, NULL, &ahb_clk); | ||
576 | DEFINE_CLOCK(slcdc_clk1, 0, PCCR1, 12, NULL, NULL, &ahb_clk); | ||
577 | DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk); | ||
578 | DEFINE_CLOCK(rtic_clk1, 0, PCCR1, 14, NULL, NULL, &ahb_clk); | ||
579 | DEFINE_CLOCK(lcdc_clk2, 0, PCCR1, 15, NULL, NULL, &ahb_clk); | ||
580 | DEFINE_CLOCK(vpu_clk1, 0, PCCR1, 16, NULL, NULL, &ahb_clk); | ||
581 | DEFINE_CLOCK(fec_clk1, 0, PCCR1, 17, NULL, NULL, &ahb_clk); | ||
582 | DEFINE_CLOCK(emma_clk1, 0, PCCR1, 18, NULL, NULL, &ahb_clk); | ||
583 | DEFINE_CLOCK(emi_clk, 0, PCCR1, 19, NULL, NULL, &ahb_clk); | ||
584 | DEFINE_CLOCK(dma_clk1, 0, PCCR1, 20, NULL, NULL, &ahb_clk); | ||
585 | DEFINE_CLOCK(csi_clk1, 0, PCCR1, 21, NULL, NULL, &ahb_clk); | ||
586 | DEFINE_CLOCK(brom_clk, 0, PCCR1, 22, NULL, NULL, &ahb_clk); | ||
587 | DEFINE_CLOCK(pata_clk, 0, PCCR1, 23, NULL, NULL, &ahb_clk); | ||
588 | DEFINE_CLOCK(wdog_clk, 0, PCCR1, 24, NULL, NULL, &ipg_clk); | ||
589 | DEFINE_CLOCK(usb_clk, 0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk); | ||
590 | DEFINE_CLOCK(uart6_clk1, 0, PCCR1, 26, NULL, NULL, &ipg_clk); | ||
591 | DEFINE_CLOCK(uart5_clk1, 0, PCCR1, 27, NULL, NULL, &ipg_clk); | ||
592 | DEFINE_CLOCK(uart4_clk1, 0, PCCR1, 28, NULL, NULL, &ipg_clk); | ||
593 | DEFINE_CLOCK(uart3_clk1, 0, PCCR1, 29, NULL, NULL, &ipg_clk); | ||
594 | DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk); | ||
595 | DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk); | ||
596 | |||
597 | /* Clocks we cannot directly gate, but drivers need their rates */ | ||
598 | DEFINE_CLOCK(cspi1_clk, 0, NULL, 0, NULL, &cspi1_clk1, &per2_clk); | ||
599 | DEFINE_CLOCK(cspi2_clk, 1, NULL, 0, NULL, &cspi2_clk1, &per2_clk); | ||
600 | DEFINE_CLOCK(cspi3_clk, 2, NULL, 0, NULL, &cspi13_clk1, &per2_clk); | ||
601 | DEFINE_CLOCK(sdhc1_clk, 0, NULL, 0, NULL, &sdhc1_clk1, &per2_clk); | ||
602 | DEFINE_CLOCK(sdhc2_clk, 1, NULL, 0, NULL, &sdhc2_clk1, &per2_clk); | ||
603 | DEFINE_CLOCK(sdhc3_clk, 2, NULL, 0, NULL, &sdhc3_clk1, &per2_clk); | ||
604 | DEFINE_CLOCK(pwm_clk, 0, NULL, 0, NULL, &pwm_clk1, &per1_clk); | ||
605 | DEFINE_CLOCK(gpt1_clk, 0, NULL, 0, NULL, &gpt1_clk1, &per1_clk); | ||
606 | DEFINE_CLOCK(gpt2_clk, 1, NULL, 0, NULL, &gpt2_clk1, &per1_clk); | ||
607 | DEFINE_CLOCK(gpt3_clk, 2, NULL, 0, NULL, &gpt3_clk1, &per1_clk); | ||
608 | DEFINE_CLOCK(gpt4_clk, 3, NULL, 0, NULL, &gpt4_clk1, &per1_clk); | ||
609 | DEFINE_CLOCK(gpt5_clk, 4, NULL, 0, NULL, &gpt5_clk1, &per1_clk); | ||
610 | DEFINE_CLOCK(gpt6_clk, 5, NULL, 0, NULL, &gpt6_clk1, &per1_clk); | ||
611 | DEFINE_CLOCK(uart1_clk, 0, NULL, 0, NULL, &uart1_clk1, &per1_clk); | ||
612 | DEFINE_CLOCK(uart2_clk, 1, NULL, 0, NULL, &uart2_clk1, &per1_clk); | ||
613 | DEFINE_CLOCK(uart3_clk, 2, NULL, 0, NULL, &uart3_clk1, &per1_clk); | ||
614 | DEFINE_CLOCK(uart4_clk, 3, NULL, 0, NULL, &uart4_clk1, &per1_clk); | ||
615 | DEFINE_CLOCK(uart5_clk, 4, NULL, 0, NULL, &uart5_clk1, &per1_clk); | ||
616 | DEFINE_CLOCK(uart6_clk, 5, NULL, 0, NULL, &uart6_clk1, &per1_clk); | ||
617 | DEFINE_CLOCK1(lcdc_clk, 0, NULL, 0, parent, &lcdc_clk1, &per3_clk); | ||
618 | DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk); | ||
619 | |||
620 | #define _REGISTER_CLOCK(d, n, c) \ | ||
621 | { \ | ||
622 | .dev_id = d, \ | ||
623 | .con_id = n, \ | ||
624 | .clk = &c, \ | ||
625 | }, | ||
626 | |||
627 | static struct clk_lookup lookups[] = { | ||
628 | /* i.mx27 has the i.mx21 type uart */ | ||
629 | _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) | ||
630 | _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) | ||
631 | _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) | ||
632 | _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) | ||
633 | _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) | ||
634 | _REGISTER_CLOCK("imx21-uart.5", NULL, uart6_clk) | ||
635 | _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk) | ||
636 | _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk) | ||
637 | _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk) | ||
638 | _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk) | ||
639 | _REGISTER_CLOCK(NULL, "gpt5", gpt5_clk) | ||
640 | _REGISTER_CLOCK(NULL, "gpt6", gpt6_clk) | ||
641 | _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk) | ||
642 | _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) | ||
643 | _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) | ||
644 | _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk) | ||
645 | _REGISTER_CLOCK("imx27-cspi.0", NULL, cspi1_clk) | ||
646 | _REGISTER_CLOCK("imx27-cspi.1", NULL, cspi2_clk) | ||
647 | _REGISTER_CLOCK("imx27-cspi.2", NULL, cspi3_clk) | ||
648 | _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) | ||
649 | _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk) | ||
650 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk) | ||
651 | _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1) | ||
652 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk) | ||
653 | _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk1) | ||
654 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk) | ||
655 | _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1) | ||
656 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk) | ||
657 | _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1) | ||
658 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) | ||
659 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) | ||
660 | _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) | ||
661 | _REGISTER_CLOCK(NULL, "vpu", vpu_clk) | ||
662 | _REGISTER_CLOCK(NULL, "dma", dma_clk) | ||
663 | _REGISTER_CLOCK(NULL, "rtic", rtic_clk) | ||
664 | _REGISTER_CLOCK(NULL, "brom", brom_clk) | ||
665 | _REGISTER_CLOCK(NULL, "emma", emma_clk) | ||
666 | _REGISTER_CLOCK("m2m-emmaprp.0", NULL, emma_clk) | ||
667 | _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk) | ||
668 | _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) | ||
669 | _REGISTER_CLOCK(NULL, "emi", emi_clk) | ||
670 | _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk) | ||
671 | _REGISTER_CLOCK("pata_imx", NULL, pata_clk) | ||
672 | _REGISTER_CLOCK(NULL, "mstick", mstick_clk) | ||
673 | _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) | ||
674 | _REGISTER_CLOCK(NULL, "gpio", gpio_clk) | ||
675 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) | ||
676 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) | ||
677 | _REGISTER_CLOCK(NULL, "iim", iim_clk) | ||
678 | _REGISTER_CLOCK(NULL, "kpp", kpp_clk) | ||
679 | _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) | ||
680 | _REGISTER_CLOCK(NULL, "rtc", rtc_clk) | ||
681 | _REGISTER_CLOCK(NULL, "scc", scc_clk) | ||
682 | }; | ||
683 | |||
684 | /* Adjust the clock path for TO2 and later */ | ||
685 | static void __init to2_adjust_clocks(void) | ||
686 | { | ||
687 | unsigned long cscr = __raw_readl(CCM_CSCR); | ||
688 | |||
689 | if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { | ||
690 | if (cscr & CCM_CSCR_ARM_SRC) | ||
691 | cpu_clk.parent = &mpll_main1_clk; | ||
692 | |||
693 | if (!(cscr & CCM_CSCR_SSI2)) | ||
694 | ssi1_clk.parent = &spll_clk; | ||
695 | |||
696 | if (!(cscr & CCM_CSCR_SSI1)) | ||
697 | ssi1_clk.parent = &spll_clk; | ||
698 | |||
699 | if (!(cscr & CCM_CSCR_VPU)) | ||
700 | vpu_clk.parent = &spll_clk; | ||
701 | } else { | ||
702 | cpu_clk.parent = &mpll_clk; | ||
703 | cpu_clk.set_parent = NULL; | ||
704 | cpu_clk.round_rate = NULL; | ||
705 | cpu_clk.set_rate = NULL; | ||
706 | ahb_clk.parent = &mpll_clk; | ||
707 | |||
708 | per1_clk.parent = &mpll_clk; | ||
709 | per2_clk.parent = &mpll_clk; | ||
710 | per3_clk.parent = &mpll_clk; | ||
711 | per4_clk.parent = &mpll_clk; | ||
712 | |||
713 | ssi1_clk.parent = &mpll_clk; | ||
714 | ssi2_clk.parent = &mpll_clk; | ||
715 | |||
716 | vpu_clk.parent = &mpll_clk; | ||
717 | } | ||
718 | } | ||
719 | |||
720 | /* | ||
721 | * must be called very early to get information about the | ||
722 | * available clock rate when the timer framework starts | ||
723 | */ | ||
724 | int __init mx27_clocks_init(unsigned long fref) | ||
725 | { | ||
726 | u32 cscr = __raw_readl(CCM_CSCR); | ||
727 | |||
728 | external_high_reference = fref; | ||
729 | |||
730 | /* detect clock reference for both system PLLs */ | ||
731 | if (cscr & CCM_CSCR_MCU) | ||
732 | mpll_clk.parent = &ckih_clk; | ||
733 | else | ||
734 | mpll_clk.parent = &fpm_clk; | ||
735 | |||
736 | if (cscr & CCM_CSCR_SP) | ||
737 | spll_clk.parent = &ckih_clk; | ||
738 | else | ||
739 | spll_clk.parent = &fpm_clk; | ||
740 | |||
741 | to2_adjust_clocks(); | ||
742 | |||
743 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
744 | |||
745 | /* Turn off all clocks we do not need */ | ||
746 | __raw_writel(0, CCM_PCCR0); | ||
747 | __raw_writel((1 << 10) | (1 << 19), CCM_PCCR1); | ||
748 | |||
749 | spll_clk.disable(&spll_clk); | ||
750 | |||
751 | /* enable basic clocks */ | ||
752 | clk_enable(&per1_clk); | ||
753 | clk_enable(&gpio_clk); | ||
754 | clk_enable(&emi_clk); | ||
755 | clk_enable(&iim_clk); | ||
756 | imx_print_silicon_rev("i.MX27", mx27_revision()); | ||
757 | clk_disable(&iim_clk); | ||
758 | |||
759 | #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) | ||
760 | clk_enable(&uart1_clk); | ||
761 | #endif | ||
762 | |||
763 | mxc_timer_init(&gpt1_clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), | ||
764 | MX27_INT_GPT1); | ||
765 | |||
766 | return 0; | ||
767 | } | ||
768 | |||
769 | #ifdef CONFIG_OF | ||
770 | int __init mx27_clocks_init_dt(void) | ||
771 | { | ||
772 | struct device_node *np; | ||
773 | u32 fref = 26000000; /* default */ | ||
774 | |||
775 | for_each_compatible_node(np, NULL, "fixed-clock") { | ||
776 | if (!of_device_is_compatible(np, "fsl,imx-osc26m")) | ||
777 | continue; | ||
778 | |||
779 | if (!of_property_read_u32(np, "clock-frequency", &fref)) | ||
780 | break; | ||
781 | } | ||
782 | |||
783 | return mx27_clocks_init(fref); | ||
784 | } | ||
785 | #endif | ||
diff --git a/arch/arm/mach-imx/clock-imx31.c b/arch/arm/mach-imx/clock-imx31.c deleted file mode 100644 index 3a943cd4159f..000000000000 --- a/arch/arm/mach-imx/clock-imx31.c +++ /dev/null | |||
@@ -1,630 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
17 | * MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/clkdev.h> | ||
27 | |||
28 | #include <asm/div64.h> | ||
29 | |||
30 | #include <mach/clock.h> | ||
31 | #include <mach/hardware.h> | ||
32 | #include <mach/mx31.h> | ||
33 | #include <mach/common.h> | ||
34 | |||
35 | #include "crmregs-imx3.h" | ||
36 | |||
37 | #define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */ | ||
38 | |||
39 | static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) | ||
40 | { | ||
41 | u32 min_pre, temp_pre, old_err, err; | ||
42 | |||
43 | if (div >= 512) { | ||
44 | *pre = 8; | ||
45 | *post = 64; | ||
46 | } else if (div >= 64) { | ||
47 | min_pre = (div - 1) / 64 + 1; | ||
48 | old_err = 8; | ||
49 | for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) { | ||
50 | err = div % temp_pre; | ||
51 | if (err == 0) { | ||
52 | *pre = temp_pre; | ||
53 | break; | ||
54 | } | ||
55 | err = temp_pre - err; | ||
56 | if (err < old_err) { | ||
57 | old_err = err; | ||
58 | *pre = temp_pre; | ||
59 | } | ||
60 | } | ||
61 | *post = (div + *pre - 1) / *pre; | ||
62 | } else if (div <= 8) { | ||
63 | *pre = div; | ||
64 | *post = 1; | ||
65 | } else { | ||
66 | *pre = 1; | ||
67 | *post = div; | ||
68 | } | ||
69 | } | ||
70 | |||
71 | static struct clk mcu_pll_clk; | ||
72 | static struct clk serial_pll_clk; | ||
73 | static struct clk ipg_clk; | ||
74 | static struct clk ckih_clk; | ||
75 | |||
76 | static int cgr_enable(struct clk *clk) | ||
77 | { | ||
78 | u32 reg; | ||
79 | |||
80 | if (!clk->enable_reg) | ||
81 | return 0; | ||
82 | |||
83 | reg = __raw_readl(clk->enable_reg); | ||
84 | reg |= 3 << clk->enable_shift; | ||
85 | __raw_writel(reg, clk->enable_reg); | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static void cgr_disable(struct clk *clk) | ||
91 | { | ||
92 | u32 reg; | ||
93 | |||
94 | if (!clk->enable_reg) | ||
95 | return; | ||
96 | |||
97 | reg = __raw_readl(clk->enable_reg); | ||
98 | reg &= ~(3 << clk->enable_shift); | ||
99 | |||
100 | /* special case for EMI clock */ | ||
101 | if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8) | ||
102 | reg |= (1 << clk->enable_shift); | ||
103 | |||
104 | __raw_writel(reg, clk->enable_reg); | ||
105 | } | ||
106 | |||
107 | static unsigned long pll_ref_get_rate(void) | ||
108 | { | ||
109 | unsigned long ccmr; | ||
110 | unsigned int prcs; | ||
111 | |||
112 | ccmr = __raw_readl(MXC_CCM_CCMR); | ||
113 | prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; | ||
114 | if (prcs == 0x1) | ||
115 | return CKIL_CLK_FREQ * 1024; | ||
116 | else | ||
117 | return clk_get_rate(&ckih_clk); | ||
118 | } | ||
119 | |||
120 | static unsigned long usb_pll_get_rate(struct clk *clk) | ||
121 | { | ||
122 | unsigned long reg; | ||
123 | |||
124 | reg = __raw_readl(MXC_CCM_UPCTL); | ||
125 | |||
126 | return mxc_decode_pll(reg, pll_ref_get_rate()); | ||
127 | } | ||
128 | |||
129 | static unsigned long serial_pll_get_rate(struct clk *clk) | ||
130 | { | ||
131 | unsigned long reg; | ||
132 | |||
133 | reg = __raw_readl(MXC_CCM_SRPCTL); | ||
134 | |||
135 | return mxc_decode_pll(reg, pll_ref_get_rate()); | ||
136 | } | ||
137 | |||
138 | static unsigned long mcu_pll_get_rate(struct clk *clk) | ||
139 | { | ||
140 | unsigned long reg, ccmr; | ||
141 | |||
142 | ccmr = __raw_readl(MXC_CCM_CCMR); | ||
143 | |||
144 | if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS)) | ||
145 | return clk_get_rate(&ckih_clk); | ||
146 | |||
147 | reg = __raw_readl(MXC_CCM_MPCTL); | ||
148 | |||
149 | return mxc_decode_pll(reg, pll_ref_get_rate()); | ||
150 | } | ||
151 | |||
152 | static int usb_pll_enable(struct clk *clk) | ||
153 | { | ||
154 | u32 reg; | ||
155 | |||
156 | reg = __raw_readl(MXC_CCM_CCMR); | ||
157 | reg |= MXC_CCM_CCMR_UPE; | ||
158 | __raw_writel(reg, MXC_CCM_CCMR); | ||
159 | |||
160 | /* No lock bit on MX31, so using max time from spec */ | ||
161 | udelay(80); | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static void usb_pll_disable(struct clk *clk) | ||
167 | { | ||
168 | u32 reg; | ||
169 | |||
170 | reg = __raw_readl(MXC_CCM_CCMR); | ||
171 | reg &= ~MXC_CCM_CCMR_UPE; | ||
172 | __raw_writel(reg, MXC_CCM_CCMR); | ||
173 | } | ||
174 | |||
175 | static int serial_pll_enable(struct clk *clk) | ||
176 | { | ||
177 | u32 reg; | ||
178 | |||
179 | reg = __raw_readl(MXC_CCM_CCMR); | ||
180 | reg |= MXC_CCM_CCMR_SPE; | ||
181 | __raw_writel(reg, MXC_CCM_CCMR); | ||
182 | |||
183 | /* No lock bit on MX31, so using max time from spec */ | ||
184 | udelay(80); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static void serial_pll_disable(struct clk *clk) | ||
190 | { | ||
191 | u32 reg; | ||
192 | |||
193 | reg = __raw_readl(MXC_CCM_CCMR); | ||
194 | reg &= ~MXC_CCM_CCMR_SPE; | ||
195 | __raw_writel(reg, MXC_CCM_CCMR); | ||
196 | } | ||
197 | |||
198 | #define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off) | ||
199 | #define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off) | ||
200 | #define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off) | ||
201 | |||
202 | static unsigned long mcu_main_get_rate(struct clk *clk) | ||
203 | { | ||
204 | u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0); | ||
205 | |||
206 | if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL) | ||
207 | return clk_get_rate(&serial_pll_clk); | ||
208 | else | ||
209 | return clk_get_rate(&mcu_pll_clk); | ||
210 | } | ||
211 | |||
212 | static unsigned long ahb_get_rate(struct clk *clk) | ||
213 | { | ||
214 | unsigned long max_pdf; | ||
215 | |||
216 | max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK, | ||
217 | MXC_CCM_PDR0_MAX_PODF_OFFSET); | ||
218 | return clk_get_rate(clk->parent) / (max_pdf + 1); | ||
219 | } | ||
220 | |||
221 | static unsigned long ipg_get_rate(struct clk *clk) | ||
222 | { | ||
223 | unsigned long ipg_pdf; | ||
224 | |||
225 | ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK, | ||
226 | MXC_CCM_PDR0_IPG_PODF_OFFSET); | ||
227 | return clk_get_rate(clk->parent) / (ipg_pdf + 1); | ||
228 | } | ||
229 | |||
230 | static unsigned long nfc_get_rate(struct clk *clk) | ||
231 | { | ||
232 | unsigned long nfc_pdf; | ||
233 | |||
234 | nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK, | ||
235 | MXC_CCM_PDR0_NFC_PODF_OFFSET); | ||
236 | return clk_get_rate(clk->parent) / (nfc_pdf + 1); | ||
237 | } | ||
238 | |||
239 | static unsigned long hsp_get_rate(struct clk *clk) | ||
240 | { | ||
241 | unsigned long hsp_pdf; | ||
242 | |||
243 | hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK, | ||
244 | MXC_CCM_PDR0_HSP_PODF_OFFSET); | ||
245 | return clk_get_rate(clk->parent) / (hsp_pdf + 1); | ||
246 | } | ||
247 | |||
248 | static unsigned long usb_get_rate(struct clk *clk) | ||
249 | { | ||
250 | unsigned long usb_pdf, usb_prepdf; | ||
251 | |||
252 | usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK, | ||
253 | MXC_CCM_PDR1_USB_PODF_OFFSET); | ||
254 | usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK, | ||
255 | MXC_CCM_PDR1_USB_PRDF_OFFSET); | ||
256 | return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1); | ||
257 | } | ||
258 | |||
259 | static unsigned long csi_get_rate(struct clk *clk) | ||
260 | { | ||
261 | u32 reg, pre, post; | ||
262 | |||
263 | reg = __raw_readl(MXC_CCM_PDR0); | ||
264 | pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >> | ||
265 | MXC_CCM_PDR0_CSI_PRDF_OFFSET; | ||
266 | pre++; | ||
267 | post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >> | ||
268 | MXC_CCM_PDR0_CSI_PODF_OFFSET; | ||
269 | post++; | ||
270 | return clk_get_rate(clk->parent) / (pre * post); | ||
271 | } | ||
272 | |||
273 | static unsigned long csi_round_rate(struct clk *clk, unsigned long rate) | ||
274 | { | ||
275 | u32 pre, post, parent = clk_get_rate(clk->parent); | ||
276 | u32 div = parent / rate; | ||
277 | |||
278 | if (parent % rate) | ||
279 | div++; | ||
280 | |||
281 | __calc_pre_post_dividers(div, &pre, &post); | ||
282 | |||
283 | return parent / (pre * post); | ||
284 | } | ||
285 | |||
286 | static int csi_set_rate(struct clk *clk, unsigned long rate) | ||
287 | { | ||
288 | u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); | ||
289 | |||
290 | div = parent / rate; | ||
291 | |||
292 | if ((parent / div) != rate) | ||
293 | return -EINVAL; | ||
294 | |||
295 | __calc_pre_post_dividers(div, &pre, &post); | ||
296 | |||
297 | /* Set CSI clock divider */ | ||
298 | reg = __raw_readl(MXC_CCM_PDR0) & | ||
299 | ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK); | ||
300 | reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET; | ||
301 | reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET; | ||
302 | __raw_writel(reg, MXC_CCM_PDR0); | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static unsigned long ssi1_get_rate(struct clk *clk) | ||
308 | { | ||
309 | unsigned long ssi1_pdf, ssi1_prepdf; | ||
310 | |||
311 | ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK, | ||
312 | MXC_CCM_PDR1_SSI1_PODF_OFFSET); | ||
313 | ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK, | ||
314 | MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET); | ||
315 | return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1); | ||
316 | } | ||
317 | |||
318 | static unsigned long ssi2_get_rate(struct clk *clk) | ||
319 | { | ||
320 | unsigned long ssi2_pdf, ssi2_prepdf; | ||
321 | |||
322 | ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK, | ||
323 | MXC_CCM_PDR1_SSI2_PODF_OFFSET); | ||
324 | ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK, | ||
325 | MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET); | ||
326 | return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1); | ||
327 | } | ||
328 | |||
329 | static unsigned long firi_get_rate(struct clk *clk) | ||
330 | { | ||
331 | unsigned long firi_pdf, firi_prepdf; | ||
332 | |||
333 | firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK, | ||
334 | MXC_CCM_PDR1_FIRI_PODF_OFFSET); | ||
335 | firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK, | ||
336 | MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET); | ||
337 | return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1); | ||
338 | } | ||
339 | |||
340 | static unsigned long firi_round_rate(struct clk *clk, unsigned long rate) | ||
341 | { | ||
342 | u32 pre, post; | ||
343 | u32 parent = clk_get_rate(clk->parent); | ||
344 | u32 div = parent / rate; | ||
345 | |||
346 | if (parent % rate) | ||
347 | div++; | ||
348 | |||
349 | __calc_pre_post_dividers(div, &pre, &post); | ||
350 | |||
351 | return parent / (pre * post); | ||
352 | |||
353 | } | ||
354 | |||
355 | static int firi_set_rate(struct clk *clk, unsigned long rate) | ||
356 | { | ||
357 | u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); | ||
358 | |||
359 | div = parent / rate; | ||
360 | |||
361 | if ((parent / div) != rate) | ||
362 | return -EINVAL; | ||
363 | |||
364 | __calc_pre_post_dividers(div, &pre, &post); | ||
365 | |||
366 | /* Set FIRI clock divider */ | ||
367 | reg = __raw_readl(MXC_CCM_PDR1) & | ||
368 | ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK); | ||
369 | reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET; | ||
370 | reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET; | ||
371 | __raw_writel(reg, MXC_CCM_PDR1); | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static unsigned long mbx_get_rate(struct clk *clk) | ||
377 | { | ||
378 | return clk_get_rate(clk->parent) / 2; | ||
379 | } | ||
380 | |||
381 | static unsigned long mstick1_get_rate(struct clk *clk) | ||
382 | { | ||
383 | unsigned long msti_pdf; | ||
384 | |||
385 | msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK, | ||
386 | MXC_CCM_PDR2_MST1_PDF_OFFSET); | ||
387 | return clk_get_rate(clk->parent) / (msti_pdf + 1); | ||
388 | } | ||
389 | |||
390 | static unsigned long mstick2_get_rate(struct clk *clk) | ||
391 | { | ||
392 | unsigned long msti_pdf; | ||
393 | |||
394 | msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK, | ||
395 | MXC_CCM_PDR2_MST2_PDF_OFFSET); | ||
396 | return clk_get_rate(clk->parent) / (msti_pdf + 1); | ||
397 | } | ||
398 | |||
399 | static unsigned long ckih_rate; | ||
400 | |||
401 | static unsigned long clk_ckih_get_rate(struct clk *clk) | ||
402 | { | ||
403 | return ckih_rate; | ||
404 | } | ||
405 | |||
406 | static unsigned long clk_ckil_get_rate(struct clk *clk) | ||
407 | { | ||
408 | return CKIL_CLK_FREQ; | ||
409 | } | ||
410 | |||
411 | static struct clk ckih_clk = { | ||
412 | .get_rate = clk_ckih_get_rate, | ||
413 | }; | ||
414 | |||
415 | static struct clk mcu_pll_clk = { | ||
416 | .parent = &ckih_clk, | ||
417 | .get_rate = mcu_pll_get_rate, | ||
418 | }; | ||
419 | |||
420 | static struct clk mcu_main_clk = { | ||
421 | .parent = &mcu_pll_clk, | ||
422 | .get_rate = mcu_main_get_rate, | ||
423 | }; | ||
424 | |||
425 | static struct clk serial_pll_clk = { | ||
426 | .parent = &ckih_clk, | ||
427 | .get_rate = serial_pll_get_rate, | ||
428 | .enable = serial_pll_enable, | ||
429 | .disable = serial_pll_disable, | ||
430 | }; | ||
431 | |||
432 | static struct clk usb_pll_clk = { | ||
433 | .parent = &ckih_clk, | ||
434 | .get_rate = usb_pll_get_rate, | ||
435 | .enable = usb_pll_enable, | ||
436 | .disable = usb_pll_disable, | ||
437 | }; | ||
438 | |||
439 | static struct clk ahb_clk = { | ||
440 | .parent = &mcu_main_clk, | ||
441 | .get_rate = ahb_get_rate, | ||
442 | }; | ||
443 | |||
444 | #define DEFINE_CLOCK(name, i, er, es, gr, s, p) \ | ||
445 | static struct clk name = { \ | ||
446 | .id = i, \ | ||
447 | .enable_reg = er, \ | ||
448 | .enable_shift = es, \ | ||
449 | .get_rate = gr, \ | ||
450 | .enable = cgr_enable, \ | ||
451 | .disable = cgr_disable, \ | ||
452 | .secondary = s, \ | ||
453 | .parent = p, \ | ||
454 | } | ||
455 | |||
456 | #define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \ | ||
457 | static struct clk name = { \ | ||
458 | .id = i, \ | ||
459 | .enable_reg = er, \ | ||
460 | .enable_shift = es, \ | ||
461 | .get_rate = getsetround##_get_rate, \ | ||
462 | .set_rate = getsetround##_set_rate, \ | ||
463 | .round_rate = getsetround##_round_rate, \ | ||
464 | .enable = cgr_enable, \ | ||
465 | .disable = cgr_disable, \ | ||
466 | .secondary = s, \ | ||
467 | .parent = p, \ | ||
468 | } | ||
469 | |||
470 | DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); | ||
471 | DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL); | ||
472 | |||
473 | DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk); | ||
474 | DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk); | ||
475 | DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk); | ||
476 | DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk); | ||
477 | DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk); | ||
478 | DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk); | ||
479 | DEFINE_CLOCK(pata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk); | ||
480 | DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, NULL, &ahb_clk); | ||
481 | DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk); | ||
482 | DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk); | ||
483 | DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk); | ||
484 | DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk); | ||
485 | DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk); | ||
486 | DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk); | ||
487 | DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk); | ||
488 | DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk); | ||
489 | |||
490 | DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk); | ||
491 | DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk); | ||
492 | DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk); | ||
493 | DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk); | ||
494 | DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk); | ||
495 | DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk); | ||
496 | DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk); | ||
497 | DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk); | ||
498 | DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk); | ||
499 | DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk); | ||
500 | DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk); | ||
501 | DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk); | ||
502 | DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk); | ||
503 | DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk); | ||
504 | |||
505 | DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk); | ||
506 | DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk); | ||
507 | DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk); | ||
508 | DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk); | ||
509 | DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk); | ||
510 | DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk); | ||
511 | DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk); | ||
512 | |||
513 | DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk); | ||
514 | DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk); | ||
515 | DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); | ||
516 | DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); | ||
517 | DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); | ||
518 | |||
519 | #define _REGISTER_CLOCK(d, n, c) \ | ||
520 | { \ | ||
521 | .dev_id = d, \ | ||
522 | .con_id = n, \ | ||
523 | .clk = &c, \ | ||
524 | }, | ||
525 | |||
526 | static struct clk_lookup lookups[] = { | ||
527 | _REGISTER_CLOCK(NULL, "emi", emi_clk) | ||
528 | _REGISTER_CLOCK("imx31-cspi.0", NULL, cspi1_clk) | ||
529 | _REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk) | ||
530 | _REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk) | ||
531 | _REGISTER_CLOCK(NULL, "gpt", gpt_clk) | ||
532 | _REGISTER_CLOCK(NULL, "pwm", pwm_clk) | ||
533 | _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) | ||
534 | _REGISTER_CLOCK(NULL, "rtc", rtc_clk) | ||
535 | _REGISTER_CLOCK(NULL, "epit", epit1_clk) | ||
536 | _REGISTER_CLOCK(NULL, "epit", epit2_clk) | ||
537 | _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) | ||
538 | _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) | ||
539 | _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) | ||
540 | _REGISTER_CLOCK(NULL, "kpp", kpp_clk) | ||
541 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1) | ||
542 | _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2) | ||
543 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1) | ||
544 | _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2) | ||
545 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1) | ||
546 | _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2) | ||
547 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1) | ||
548 | _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2) | ||
549 | _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) | ||
550 | /* i.mx31 has the i.mx21 type uart */ | ||
551 | _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) | ||
552 | _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) | ||
553 | _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) | ||
554 | _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) | ||
555 | _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) | ||
556 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) | ||
557 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) | ||
558 | _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) | ||
559 | _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) | ||
560 | _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) | ||
561 | _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) | ||
562 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) | ||
563 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) | ||
564 | _REGISTER_CLOCK(NULL, "firi", firi_clk) | ||
565 | _REGISTER_CLOCK("pata_imx", NULL, pata_clk) | ||
566 | _REGISTER_CLOCK(NULL, "rtic", rtic_clk) | ||
567 | _REGISTER_CLOCK(NULL, "rng", rng_clk) | ||
568 | _REGISTER_CLOCK("imx31-sdma", NULL, sdma_clk1) | ||
569 | _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2) | ||
570 | _REGISTER_CLOCK(NULL, "mstick", mstick1_clk) | ||
571 | _REGISTER_CLOCK(NULL, "mstick", mstick2_clk) | ||
572 | _REGISTER_CLOCK(NULL, "scc", scc_clk) | ||
573 | _REGISTER_CLOCK(NULL, "iim", iim_clk) | ||
574 | _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) | ||
575 | _REGISTER_CLOCK(NULL, "mbx", mbx_clk) | ||
576 | }; | ||
577 | |||
578 | int __init mx31_clocks_init(unsigned long fref) | ||
579 | { | ||
580 | u32 reg; | ||
581 | |||
582 | ckih_rate = fref; | ||
583 | |||
584 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
585 | |||
586 | /* change the csi_clk parent if necessary */ | ||
587 | reg = __raw_readl(MXC_CCM_CCMR); | ||
588 | if (!(reg & MXC_CCM_CCMR_CSCS)) | ||
589 | if (clk_set_parent(&csi_clk, &usb_pll_clk)) | ||
590 | pr_err("%s: error changing csi_clk parent\n", __func__); | ||
591 | |||
592 | |||
593 | /* Turn off all possible clocks */ | ||
594 | __raw_writel((3 << 4), MXC_CCM_CGR0); | ||
595 | __raw_writel(0, MXC_CCM_CGR1); | ||
596 | __raw_writel((3 << 8) | (3 << 14) | (3 << 16)| | ||
597 | 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for | ||
598 | MX32, but still required to be set */ | ||
599 | MXC_CCM_CGR2); | ||
600 | |||
601 | /* | ||
602 | * Before turning off usb_pll make sure ipg_per_clk is generated | ||
603 | * by ipg_clk and not usb_pll. | ||
604 | */ | ||
605 | __raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR); | ||
606 | |||
607 | usb_pll_disable(&usb_pll_clk); | ||
608 | |||
609 | pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk)); | ||
610 | |||
611 | clk_enable(&gpt_clk); | ||
612 | clk_enable(&emi_clk); | ||
613 | clk_enable(&iim_clk); | ||
614 | mx31_revision(); | ||
615 | clk_disable(&iim_clk); | ||
616 | |||
617 | clk_enable(&serial_pll_clk); | ||
618 | |||
619 | if (mx31_revision() >= IMX_CHIP_REVISION_2_0) { | ||
620 | reg = __raw_readl(MXC_CCM_PMCR1); | ||
621 | /* No PLL restart on DVFS switch; enable auto EMI handshake */ | ||
622 | reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN; | ||
623 | __raw_writel(reg, MXC_CCM_PMCR1); | ||
624 | } | ||
625 | |||
626 | mxc_timer_init(&ipg_clk, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), | ||
627 | MX31_INT_GPT); | ||
628 | |||
629 | return 0; | ||
630 | } | ||
diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c deleted file mode 100644 index e56c1a83eee3..000000000000 --- a/arch/arm/mach-imx/clock-imx35.c +++ /dev/null | |||
@@ -1,536 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 by Sascha Hauer, Pengutronix | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
16 | * MA 02110-1301, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/clkdev.h> | ||
25 | |||
26 | #include <mach/clock.h> | ||
27 | #include <mach/hardware.h> | ||
28 | #include <mach/common.h> | ||
29 | |||
30 | #include "crmregs-imx3.h" | ||
31 | |||
32 | #ifdef HAVE_SET_RATE_SUPPORT | ||
33 | static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost) | ||
34 | { | ||
35 | u32 min_pre, temp_pre, old_err, err; | ||
36 | |||
37 | min_pre = (div - 1) / maxpost + 1; | ||
38 | old_err = 8; | ||
39 | |||
40 | for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) { | ||
41 | if (div > (temp_pre * maxpost)) | ||
42 | break; | ||
43 | |||
44 | if (div < (temp_pre * temp_pre)) | ||
45 | continue; | ||
46 | |||
47 | err = div % temp_pre; | ||
48 | |||
49 | if (err == 0) { | ||
50 | *pre = temp_pre; | ||
51 | break; | ||
52 | } | ||
53 | |||
54 | err = temp_pre - err; | ||
55 | |||
56 | if (err < old_err) { | ||
57 | old_err = err; | ||
58 | *pre = temp_pre; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | *post = (div + *pre - 1) / *pre; | ||
63 | } | ||
64 | |||
65 | /* get the best values for a 3-bit divider combined with a 6-bit divider */ | ||
66 | static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post) | ||
67 | { | ||
68 | if (div >= 512) { | ||
69 | *pre = 8; | ||
70 | *post = 64; | ||
71 | } else if (div >= 64) { | ||
72 | calc_dividers(div, pre, post, 64); | ||
73 | } else if (div <= 8) { | ||
74 | *pre = div; | ||
75 | *post = 1; | ||
76 | } else { | ||
77 | *pre = 1; | ||
78 | *post = div; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | /* get the best values for two cascaded 3-bit dividers */ | ||
83 | static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post) | ||
84 | { | ||
85 | if (div >= 64) { | ||
86 | *pre = *post = 8; | ||
87 | } else if (div > 8) { | ||
88 | calc_dividers(div, pre, post, 8); | ||
89 | } else { | ||
90 | *pre = 1; | ||
91 | *post = div; | ||
92 | } | ||
93 | } | ||
94 | #endif | ||
95 | |||
96 | static unsigned long get_rate_mpll(void) | ||
97 | { | ||
98 | ulong mpctl = __raw_readl(MX35_CCM_MPCTL); | ||
99 | |||
100 | return mxc_decode_pll(mpctl, 24000000); | ||
101 | } | ||
102 | |||
103 | static unsigned long get_rate_ppll(void) | ||
104 | { | ||
105 | ulong ppctl = __raw_readl(MX35_CCM_PPCTL); | ||
106 | |||
107 | return mxc_decode_pll(ppctl, 24000000); | ||
108 | } | ||
109 | |||
110 | struct arm_ahb_div { | ||
111 | unsigned char arm, ahb, sel; | ||
112 | }; | ||
113 | |||
114 | static struct arm_ahb_div clk_consumer[] = { | ||
115 | { .arm = 1, .ahb = 4, .sel = 0}, | ||
116 | { .arm = 1, .ahb = 3, .sel = 1}, | ||
117 | { .arm = 2, .ahb = 2, .sel = 0}, | ||
118 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
119 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
120 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
121 | { .arm = 4, .ahb = 1, .sel = 0}, | ||
122 | { .arm = 1, .ahb = 5, .sel = 0}, | ||
123 | { .arm = 1, .ahb = 8, .sel = 0}, | ||
124 | { .arm = 1, .ahb = 6, .sel = 1}, | ||
125 | { .arm = 2, .ahb = 4, .sel = 0}, | ||
126 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
127 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
128 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
129 | { .arm = 4, .ahb = 2, .sel = 0}, | ||
130 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
131 | }; | ||
132 | |||
133 | static unsigned long get_rate_arm(void) | ||
134 | { | ||
135 | unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0); | ||
136 | struct arm_ahb_div *aad; | ||
137 | unsigned long fref = get_rate_mpll(); | ||
138 | |||
139 | aad = &clk_consumer[(pdr0 >> 16) & 0xf]; | ||
140 | if (aad->sel) | ||
141 | fref = fref * 3 / 4; | ||
142 | |||
143 | return fref / aad->arm; | ||
144 | } | ||
145 | |||
146 | static unsigned long get_rate_ahb(struct clk *clk) | ||
147 | { | ||
148 | unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0); | ||
149 | struct arm_ahb_div *aad; | ||
150 | unsigned long fref = get_rate_arm(); | ||
151 | |||
152 | aad = &clk_consumer[(pdr0 >> 16) & 0xf]; | ||
153 | |||
154 | return fref / aad->ahb; | ||
155 | } | ||
156 | |||
157 | static unsigned long get_rate_ipg(struct clk *clk) | ||
158 | { | ||
159 | return get_rate_ahb(NULL) >> 1; | ||
160 | } | ||
161 | |||
162 | static unsigned long get_rate_uart(struct clk *clk) | ||
163 | { | ||
164 | unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3); | ||
165 | unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4); | ||
166 | unsigned long div = ((pdr4 >> 10) & 0x3f) + 1; | ||
167 | |||
168 | if (pdr3 & (1 << 14)) | ||
169 | return get_rate_arm() / div; | ||
170 | else | ||
171 | return get_rate_ppll() / div; | ||
172 | } | ||
173 | |||
174 | static unsigned long get_rate_sdhc(struct clk *clk) | ||
175 | { | ||
176 | unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3); | ||
177 | unsigned long div, rate; | ||
178 | |||
179 | if (pdr3 & (1 << 6)) | ||
180 | rate = get_rate_arm(); | ||
181 | else | ||
182 | rate = get_rate_ppll(); | ||
183 | |||
184 | switch (clk->id) { | ||
185 | default: | ||
186 | case 0: | ||
187 | div = pdr3 & 0x3f; | ||
188 | break; | ||
189 | case 1: | ||
190 | div = (pdr3 >> 8) & 0x3f; | ||
191 | break; | ||
192 | case 2: | ||
193 | div = (pdr3 >> 16) & 0x3f; | ||
194 | break; | ||
195 | } | ||
196 | |||
197 | return rate / (div + 1); | ||
198 | } | ||
199 | |||
200 | static unsigned long get_rate_mshc(struct clk *clk) | ||
201 | { | ||
202 | unsigned long pdr1 = __raw_readl(MXC_CCM_PDR1); | ||
203 | unsigned long div1, div2, rate; | ||
204 | |||
205 | if (pdr1 & (1 << 7)) | ||
206 | rate = get_rate_arm(); | ||
207 | else | ||
208 | rate = get_rate_ppll(); | ||
209 | |||
210 | div1 = (pdr1 >> 29) & 0x7; | ||
211 | div2 = (pdr1 >> 22) & 0x3f; | ||
212 | |||
213 | return rate / ((div1 + 1) * (div2 + 1)); | ||
214 | } | ||
215 | |||
216 | static unsigned long get_rate_ssi(struct clk *clk) | ||
217 | { | ||
218 | unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2); | ||
219 | unsigned long div1, div2, rate; | ||
220 | |||
221 | if (pdr2 & (1 << 6)) | ||
222 | rate = get_rate_arm(); | ||
223 | else | ||
224 | rate = get_rate_ppll(); | ||
225 | |||
226 | switch (clk->id) { | ||
227 | default: | ||
228 | case 0: | ||
229 | div1 = pdr2 & 0x3f; | ||
230 | div2 = (pdr2 >> 24) & 0x7; | ||
231 | break; | ||
232 | case 1: | ||
233 | div1 = (pdr2 >> 8) & 0x3f; | ||
234 | div2 = (pdr2 >> 27) & 0x7; | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | return rate / ((div1 + 1) * (div2 + 1)); | ||
239 | } | ||
240 | |||
241 | static unsigned long get_rate_csi(struct clk *clk) | ||
242 | { | ||
243 | unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2); | ||
244 | unsigned long rate; | ||
245 | |||
246 | if (pdr2 & (1 << 7)) | ||
247 | rate = get_rate_arm(); | ||
248 | else | ||
249 | rate = get_rate_ppll(); | ||
250 | |||
251 | return rate / (((pdr2 >> 16) & 0x3f) + 1); | ||
252 | } | ||
253 | |||
254 | static unsigned long get_rate_otg(struct clk *clk) | ||
255 | { | ||
256 | unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4); | ||
257 | unsigned long rate; | ||
258 | |||
259 | if (pdr4 & (1 << 9)) | ||
260 | rate = get_rate_arm(); | ||
261 | else | ||
262 | rate = get_rate_ppll(); | ||
263 | |||
264 | return rate / (((pdr4 >> 22) & 0x3f) + 1); | ||
265 | } | ||
266 | |||
267 | static unsigned long get_rate_ipg_per(struct clk *clk) | ||
268 | { | ||
269 | unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0); | ||
270 | unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4); | ||
271 | unsigned long div; | ||
272 | |||
273 | if (pdr0 & (1 << 26)) { | ||
274 | div = (pdr4 >> 16) & 0x3f; | ||
275 | return get_rate_arm() / (div + 1); | ||
276 | } else { | ||
277 | div = (pdr0 >> 12) & 0x7; | ||
278 | return get_rate_ahb(NULL) / (div + 1); | ||
279 | } | ||
280 | } | ||
281 | |||
282 | static unsigned long get_rate_hsp(struct clk *clk) | ||
283 | { | ||
284 | unsigned long hsp_podf = (__raw_readl(MXC_CCM_PDR0) >> 20) & 0x03; | ||
285 | unsigned long fref = get_rate_mpll(); | ||
286 | |||
287 | if (fref > 400 * 1000 * 1000) { | ||
288 | switch (hsp_podf) { | ||
289 | case 0: | ||
290 | return fref >> 2; | ||
291 | case 1: | ||
292 | return fref >> 3; | ||
293 | case 2: | ||
294 | return fref / 3; | ||
295 | } | ||
296 | } else { | ||
297 | switch (hsp_podf) { | ||
298 | case 0: | ||
299 | case 2: | ||
300 | return fref / 3; | ||
301 | case 1: | ||
302 | return fref / 6; | ||
303 | } | ||
304 | } | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static int clk_cgr_enable(struct clk *clk) | ||
310 | { | ||
311 | u32 reg; | ||
312 | |||
313 | reg = __raw_readl(clk->enable_reg); | ||
314 | reg |= 3 << clk->enable_shift; | ||
315 | __raw_writel(reg, clk->enable_reg); | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static void clk_cgr_disable(struct clk *clk) | ||
321 | { | ||
322 | u32 reg; | ||
323 | |||
324 | reg = __raw_readl(clk->enable_reg); | ||
325 | reg &= ~(3 << clk->enable_shift); | ||
326 | __raw_writel(reg, clk->enable_reg); | ||
327 | } | ||
328 | |||
329 | #define DEFINE_CLOCK(name, i, er, es, gr, sr) \ | ||
330 | static struct clk name = { \ | ||
331 | .id = i, \ | ||
332 | .enable_reg = er, \ | ||
333 | .enable_shift = es, \ | ||
334 | .get_rate = gr, \ | ||
335 | .set_rate = sr, \ | ||
336 | .enable = clk_cgr_enable, \ | ||
337 | .disable = clk_cgr_disable, \ | ||
338 | } | ||
339 | |||
340 | DEFINE_CLOCK(asrc_clk, 0, MX35_CCM_CGR0, 0, NULL, NULL); | ||
341 | DEFINE_CLOCK(pata_clk, 0, MX35_CCM_CGR0, 2, get_rate_ipg, NULL); | ||
342 | /* DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR0, 4, NULL, NULL); */ | ||
343 | DEFINE_CLOCK(can1_clk, 0, MX35_CCM_CGR0, 6, get_rate_ipg, NULL); | ||
344 | DEFINE_CLOCK(can2_clk, 1, MX35_CCM_CGR0, 8, get_rate_ipg, NULL); | ||
345 | DEFINE_CLOCK(cspi1_clk, 0, MX35_CCM_CGR0, 10, get_rate_ipg, NULL); | ||
346 | DEFINE_CLOCK(cspi2_clk, 1, MX35_CCM_CGR0, 12, get_rate_ipg, NULL); | ||
347 | DEFINE_CLOCK(ect_clk, 0, MX35_CCM_CGR0, 14, get_rate_ipg, NULL); | ||
348 | DEFINE_CLOCK(edio_clk, 0, MX35_CCM_CGR0, 16, NULL, NULL); | ||
349 | DEFINE_CLOCK(emi_clk, 0, MX35_CCM_CGR0, 18, get_rate_ipg, NULL); | ||
350 | DEFINE_CLOCK(epit1_clk, 0, MX35_CCM_CGR0, 20, get_rate_ipg, NULL); | ||
351 | DEFINE_CLOCK(epit2_clk, 1, MX35_CCM_CGR0, 22, get_rate_ipg, NULL); | ||
352 | DEFINE_CLOCK(esai_clk, 0, MX35_CCM_CGR0, 24, NULL, NULL); | ||
353 | DEFINE_CLOCK(esdhc1_clk, 0, MX35_CCM_CGR0, 26, get_rate_sdhc, NULL); | ||
354 | DEFINE_CLOCK(esdhc2_clk, 1, MX35_CCM_CGR0, 28, get_rate_sdhc, NULL); | ||
355 | DEFINE_CLOCK(esdhc3_clk, 2, MX35_CCM_CGR0, 30, get_rate_sdhc, NULL); | ||
356 | |||
357 | DEFINE_CLOCK(fec_clk, 0, MX35_CCM_CGR1, 0, get_rate_ipg, NULL); | ||
358 | DEFINE_CLOCK(gpio1_clk, 0, MX35_CCM_CGR1, 2, NULL, NULL); | ||
359 | DEFINE_CLOCK(gpio2_clk, 1, MX35_CCM_CGR1, 4, NULL, NULL); | ||
360 | DEFINE_CLOCK(gpio3_clk, 2, MX35_CCM_CGR1, 6, NULL, NULL); | ||
361 | DEFINE_CLOCK(gpt_clk, 0, MX35_CCM_CGR1, 8, get_rate_ipg, NULL); | ||
362 | DEFINE_CLOCK(i2c1_clk, 0, MX35_CCM_CGR1, 10, get_rate_ipg_per, NULL); | ||
363 | DEFINE_CLOCK(i2c2_clk, 1, MX35_CCM_CGR1, 12, get_rate_ipg_per, NULL); | ||
364 | DEFINE_CLOCK(i2c3_clk, 2, MX35_CCM_CGR1, 14, get_rate_ipg_per, NULL); | ||
365 | DEFINE_CLOCK(iomuxc_clk, 0, MX35_CCM_CGR1, 16, NULL, NULL); | ||
366 | DEFINE_CLOCK(ipu_clk, 0, MX35_CCM_CGR1, 18, get_rate_hsp, NULL); | ||
367 | DEFINE_CLOCK(kpp_clk, 0, MX35_CCM_CGR1, 20, get_rate_ipg, NULL); | ||
368 | DEFINE_CLOCK(mlb_clk, 0, MX35_CCM_CGR1, 22, get_rate_ahb, NULL); | ||
369 | DEFINE_CLOCK(mshc_clk, 0, MX35_CCM_CGR1, 24, get_rate_mshc, NULL); | ||
370 | DEFINE_CLOCK(owire_clk, 0, MX35_CCM_CGR1, 26, get_rate_ipg_per, NULL); | ||
371 | DEFINE_CLOCK(pwm_clk, 0, MX35_CCM_CGR1, 28, get_rate_ipg_per, NULL); | ||
372 | DEFINE_CLOCK(rngc_clk, 0, MX35_CCM_CGR1, 30, get_rate_ipg, NULL); | ||
373 | |||
374 | DEFINE_CLOCK(rtc_clk, 0, MX35_CCM_CGR2, 0, get_rate_ipg, NULL); | ||
375 | DEFINE_CLOCK(rtic_clk, 0, MX35_CCM_CGR2, 2, get_rate_ahb, NULL); | ||
376 | DEFINE_CLOCK(scc_clk, 0, MX35_CCM_CGR2, 4, get_rate_ipg, NULL); | ||
377 | DEFINE_CLOCK(sdma_clk, 0, MX35_CCM_CGR2, 6, NULL, NULL); | ||
378 | DEFINE_CLOCK(spba_clk, 0, MX35_CCM_CGR2, 8, get_rate_ipg, NULL); | ||
379 | DEFINE_CLOCK(spdif_clk, 0, MX35_CCM_CGR2, 10, NULL, NULL); | ||
380 | DEFINE_CLOCK(ssi1_clk, 0, MX35_CCM_CGR2, 12, get_rate_ssi, NULL); | ||
381 | DEFINE_CLOCK(ssi2_clk, 1, MX35_CCM_CGR2, 14, get_rate_ssi, NULL); | ||
382 | DEFINE_CLOCK(uart1_clk, 0, MX35_CCM_CGR2, 16, get_rate_uart, NULL); | ||
383 | DEFINE_CLOCK(uart2_clk, 1, MX35_CCM_CGR2, 18, get_rate_uart, NULL); | ||
384 | DEFINE_CLOCK(uart3_clk, 2, MX35_CCM_CGR2, 20, get_rate_uart, NULL); | ||
385 | DEFINE_CLOCK(usbotg_clk, 0, MX35_CCM_CGR2, 22, get_rate_otg, NULL); | ||
386 | DEFINE_CLOCK(wdog_clk, 0, MX35_CCM_CGR2, 24, NULL, NULL); | ||
387 | DEFINE_CLOCK(max_clk, 0, MX35_CCM_CGR2, 26, NULL, NULL); | ||
388 | DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR2, 30, NULL, NULL); | ||
389 | |||
390 | DEFINE_CLOCK(csi_clk, 0, MX35_CCM_CGR3, 0, get_rate_csi, NULL); | ||
391 | DEFINE_CLOCK(iim_clk, 0, MX35_CCM_CGR3, 2, NULL, NULL); | ||
392 | DEFINE_CLOCK(gpu2d_clk, 0, MX35_CCM_CGR3, 4, NULL, NULL); | ||
393 | |||
394 | DEFINE_CLOCK(usbahb_clk, 0, 0, 0, get_rate_ahb, NULL); | ||
395 | |||
396 | static int clk_dummy_enable(struct clk *clk) | ||
397 | { | ||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | static void clk_dummy_disable(struct clk *clk) | ||
402 | { | ||
403 | } | ||
404 | |||
405 | static unsigned long get_rate_nfc(struct clk *clk) | ||
406 | { | ||
407 | unsigned long div1; | ||
408 | |||
409 | div1 = (__raw_readl(MX35_CCM_PDR4) >> 28) + 1; | ||
410 | |||
411 | return get_rate_ahb(NULL) / div1; | ||
412 | } | ||
413 | |||
414 | /* NAND Controller: It seems it can't be disabled */ | ||
415 | static struct clk nfc_clk = { | ||
416 | .id = 0, | ||
417 | .enable_reg = 0, | ||
418 | .enable_shift = 0, | ||
419 | .get_rate = get_rate_nfc, | ||
420 | .set_rate = NULL, /* set_rate_nfc, */ | ||
421 | .enable = clk_dummy_enable, | ||
422 | .disable = clk_dummy_disable | ||
423 | }; | ||
424 | |||
425 | #define _REGISTER_CLOCK(d, n, c) \ | ||
426 | { \ | ||
427 | .dev_id = d, \ | ||
428 | .con_id = n, \ | ||
429 | .clk = &c, \ | ||
430 | }, | ||
431 | |||
432 | static struct clk_lookup lookups[] = { | ||
433 | _REGISTER_CLOCK(NULL, "asrc", asrc_clk) | ||
434 | _REGISTER_CLOCK("pata_imx", NULL, pata_clk) | ||
435 | _REGISTER_CLOCK("flexcan.0", NULL, can1_clk) | ||
436 | _REGISTER_CLOCK("flexcan.1", NULL, can2_clk) | ||
437 | _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk) | ||
438 | _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk) | ||
439 | _REGISTER_CLOCK(NULL, "ect", ect_clk) | ||
440 | _REGISTER_CLOCK(NULL, "edio", edio_clk) | ||
441 | _REGISTER_CLOCK(NULL, "emi", emi_clk) | ||
442 | _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk) | ||
443 | _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk) | ||
444 | _REGISTER_CLOCK(NULL, "esai", esai_clk) | ||
445 | _REGISTER_CLOCK("sdhci-esdhc-imx35.0", NULL, esdhc1_clk) | ||
446 | _REGISTER_CLOCK("sdhci-esdhc-imx35.1", NULL, esdhc2_clk) | ||
447 | _REGISTER_CLOCK("sdhci-esdhc-imx35.2", NULL, esdhc3_clk) | ||
448 | /* i.mx35 has the i.mx27 type fec */ | ||
449 | _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) | ||
450 | _REGISTER_CLOCK(NULL, "gpio", gpio1_clk) | ||
451 | _REGISTER_CLOCK(NULL, "gpio", gpio2_clk) | ||
452 | _REGISTER_CLOCK(NULL, "gpio", gpio3_clk) | ||
453 | _REGISTER_CLOCK("gpt.0", NULL, gpt_clk) | ||
454 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) | ||
455 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) | ||
456 | _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) | ||
457 | _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk) | ||
458 | _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) | ||
459 | _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) | ||
460 | _REGISTER_CLOCK(NULL, "kpp", kpp_clk) | ||
461 | _REGISTER_CLOCK(NULL, "mlb", mlb_clk) | ||
462 | _REGISTER_CLOCK(NULL, "mshc", mshc_clk) | ||
463 | _REGISTER_CLOCK("mxc_w1", NULL, owire_clk) | ||
464 | _REGISTER_CLOCK(NULL, "pwm", pwm_clk) | ||
465 | _REGISTER_CLOCK(NULL, "rngc", rngc_clk) | ||
466 | _REGISTER_CLOCK(NULL, "rtc", rtc_clk) | ||
467 | _REGISTER_CLOCK(NULL, "rtic", rtic_clk) | ||
468 | _REGISTER_CLOCK(NULL, "scc", scc_clk) | ||
469 | _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) | ||
470 | _REGISTER_CLOCK(NULL, "spba", spba_clk) | ||
471 | _REGISTER_CLOCK(NULL, "spdif", spdif_clk) | ||
472 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) | ||
473 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) | ||
474 | /* i.mx35 has the i.mx21 type uart */ | ||
475 | _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) | ||
476 | _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) | ||
477 | _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) | ||
478 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk) | ||
479 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk) | ||
480 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) | ||
481 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk) | ||
482 | _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk) | ||
483 | _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) | ||
484 | _REGISTER_CLOCK(NULL, "max", max_clk) | ||
485 | _REGISTER_CLOCK(NULL, "audmux", audmux_clk) | ||
486 | _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) | ||
487 | _REGISTER_CLOCK(NULL, "iim", iim_clk) | ||
488 | _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk) | ||
489 | _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) | ||
490 | }; | ||
491 | |||
492 | int __init mx35_clocks_init() | ||
493 | { | ||
494 | unsigned int cgr2 = 3 << 26; | ||
495 | |||
496 | #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) | ||
497 | cgr2 |= 3 << 16; | ||
498 | #endif | ||
499 | |||
500 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
501 | |||
502 | /* Turn off all clocks except the ones we need to survive, namely: | ||
503 | * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart | ||
504 | */ | ||
505 | __raw_writel((3 << 18), MX35_CCM_CGR0); | ||
506 | __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16), | ||
507 | MX35_CCM_CGR1); | ||
508 | __raw_writel(cgr2, MX35_CCM_CGR2); | ||
509 | __raw_writel(0, MX35_CCM_CGR3); | ||
510 | |||
511 | clk_enable(&iim_clk); | ||
512 | imx_print_silicon_rev("i.MX35", mx35_revision()); | ||
513 | clk_disable(&iim_clk); | ||
514 | |||
515 | /* | ||
516 | * Check if we came up in internal boot mode. If yes, we need some | ||
517 | * extra clocks turned on, otherwise the MX35 boot ROM code will | ||
518 | * hang after a watchdog reset. | ||
519 | */ | ||
520 | if (!(__raw_readl(MX35_CCM_RCSR) & (3 << 10))) { | ||
521 | /* Additionally turn on UART1, SCC, and IIM clocks */ | ||
522 | clk_enable(&iim_clk); | ||
523 | clk_enable(&uart1_clk); | ||
524 | clk_enable(&scc_clk); | ||
525 | } | ||
526 | |||
527 | #ifdef CONFIG_MXC_USE_EPIT | ||
528 | epit_timer_init(&epit1_clk, | ||
529 | MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); | ||
530 | #else | ||
531 | mxc_timer_init(&gpt_clk, | ||
532 | MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); | ||
533 | #endif | ||
534 | |||
535 | return 0; | ||
536 | } | ||
diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c deleted file mode 100644 index 111c328f5420..000000000000 --- a/arch/arm/mach-imx/clock-imx6q.c +++ /dev/null | |||
@@ -1,2111 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Freescale Semiconductor, Inc. | ||
3 | * Copyright 2011 Linaro Ltd. | ||
4 | * | ||
5 | * The code contained herein is licensed under the GNU General Public | ||
6 | * License. You may obtain a copy of the GNU General Public License | ||
7 | * Version 2 or later at the following locations: | ||
8 | * | ||
9 | * http://www.opensource.org/licenses/gpl-license.html | ||
10 | * http://www.gnu.org/copyleft/gpl.html | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/clkdev.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/of_irq.h> | ||
21 | #include <asm/div64.h> | ||
22 | #include <asm/mach/map.h> | ||
23 | #include <mach/clock.h> | ||
24 | #include <mach/common.h> | ||
25 | #include <mach/hardware.h> | ||
26 | |||
27 | #define PLL_BASE IMX_IO_ADDRESS(MX6Q_ANATOP_BASE_ADDR) | ||
28 | #define PLL1_SYS (PLL_BASE + 0x000) | ||
29 | #define PLL2_BUS (PLL_BASE + 0x030) | ||
30 | #define PLL3_USB_OTG (PLL_BASE + 0x010) | ||
31 | #define PLL4_AUDIO (PLL_BASE + 0x070) | ||
32 | #define PLL5_VIDEO (PLL_BASE + 0x0a0) | ||
33 | #define PLL6_MLB (PLL_BASE + 0x0d0) | ||
34 | #define PLL7_USB_HOST (PLL_BASE + 0x020) | ||
35 | #define PLL8_ENET (PLL_BASE + 0x0e0) | ||
36 | #define PFD_480 (PLL_BASE + 0x0f0) | ||
37 | #define PFD_528 (PLL_BASE + 0x100) | ||
38 | #define PLL_NUM_OFFSET 0x010 | ||
39 | #define PLL_DENOM_OFFSET 0x020 | ||
40 | |||
41 | #define PFD0 7 | ||
42 | #define PFD1 15 | ||
43 | #define PFD2 23 | ||
44 | #define PFD3 31 | ||
45 | #define PFD_FRAC_MASK 0x3f | ||
46 | |||
47 | #define BM_PLL_BYPASS (0x1 << 16) | ||
48 | #define BM_PLL_ENABLE (0x1 << 13) | ||
49 | #define BM_PLL_POWER_DOWN (0x1 << 12) | ||
50 | #define BM_PLL_LOCK (0x1 << 31) | ||
51 | #define BP_PLL_SYS_DIV_SELECT 0 | ||
52 | #define BM_PLL_SYS_DIV_SELECT (0x7f << 0) | ||
53 | #define BP_PLL_BUS_DIV_SELECT 0 | ||
54 | #define BM_PLL_BUS_DIV_SELECT (0x1 << 0) | ||
55 | #define BP_PLL_USB_DIV_SELECT 0 | ||
56 | #define BM_PLL_USB_DIV_SELECT (0x3 << 0) | ||
57 | #define BP_PLL_AV_DIV_SELECT 0 | ||
58 | #define BM_PLL_AV_DIV_SELECT (0x7f << 0) | ||
59 | #define BP_PLL_ENET_DIV_SELECT 0 | ||
60 | #define BM_PLL_ENET_DIV_SELECT (0x3 << 0) | ||
61 | #define BM_PLL_ENET_EN_PCIE (0x1 << 19) | ||
62 | #define BM_PLL_ENET_EN_SATA (0x1 << 20) | ||
63 | |||
64 | #define CCM_BASE IMX_IO_ADDRESS(MX6Q_CCM_BASE_ADDR) | ||
65 | #define CCR (CCM_BASE + 0x00) | ||
66 | #define CCDR (CCM_BASE + 0x04) | ||
67 | #define CSR (CCM_BASE + 0x08) | ||
68 | #define CCSR (CCM_BASE + 0x0c) | ||
69 | #define CACRR (CCM_BASE + 0x10) | ||
70 | #define CBCDR (CCM_BASE + 0x14) | ||
71 | #define CBCMR (CCM_BASE + 0x18) | ||
72 | #define CSCMR1 (CCM_BASE + 0x1c) | ||
73 | #define CSCMR2 (CCM_BASE + 0x20) | ||
74 | #define CSCDR1 (CCM_BASE + 0x24) | ||
75 | #define CS1CDR (CCM_BASE + 0x28) | ||
76 | #define CS2CDR (CCM_BASE + 0x2c) | ||
77 | #define CDCDR (CCM_BASE + 0x30) | ||
78 | #define CHSCCDR (CCM_BASE + 0x34) | ||
79 | #define CSCDR2 (CCM_BASE + 0x38) | ||
80 | #define CSCDR3 (CCM_BASE + 0x3c) | ||
81 | #define CSCDR4 (CCM_BASE + 0x40) | ||
82 | #define CWDR (CCM_BASE + 0x44) | ||
83 | #define CDHIPR (CCM_BASE + 0x48) | ||
84 | #define CDCR (CCM_BASE + 0x4c) | ||
85 | #define CTOR (CCM_BASE + 0x50) | ||
86 | #define CLPCR (CCM_BASE + 0x54) | ||
87 | #define CISR (CCM_BASE + 0x58) | ||
88 | #define CIMR (CCM_BASE + 0x5c) | ||
89 | #define CCOSR (CCM_BASE + 0x60) | ||
90 | #define CGPR (CCM_BASE + 0x64) | ||
91 | #define CCGR0 (CCM_BASE + 0x68) | ||
92 | #define CCGR1 (CCM_BASE + 0x6c) | ||
93 | #define CCGR2 (CCM_BASE + 0x70) | ||
94 | #define CCGR3 (CCM_BASE + 0x74) | ||
95 | #define CCGR4 (CCM_BASE + 0x78) | ||
96 | #define CCGR5 (CCM_BASE + 0x7c) | ||
97 | #define CCGR6 (CCM_BASE + 0x80) | ||
98 | #define CCGR7 (CCM_BASE + 0x84) | ||
99 | #define CMEOR (CCM_BASE + 0x88) | ||
100 | |||
101 | #define CG0 0 | ||
102 | #define CG1 2 | ||
103 | #define CG2 4 | ||
104 | #define CG3 6 | ||
105 | #define CG4 8 | ||
106 | #define CG5 10 | ||
107 | #define CG6 12 | ||
108 | #define CG7 14 | ||
109 | #define CG8 16 | ||
110 | #define CG9 18 | ||
111 | #define CG10 20 | ||
112 | #define CG11 22 | ||
113 | #define CG12 24 | ||
114 | #define CG13 26 | ||
115 | #define CG14 28 | ||
116 | #define CG15 30 | ||
117 | |||
118 | #define BM_CCSR_PLL1_SW_SEL (0x1 << 2) | ||
119 | #define BM_CCSR_STEP_SEL (0x1 << 8) | ||
120 | |||
121 | #define BP_CACRR_ARM_PODF 0 | ||
122 | #define BM_CACRR_ARM_PODF (0x7 << 0) | ||
123 | |||
124 | #define BP_CBCDR_PERIPH2_CLK2_PODF 0 | ||
125 | #define BM_CBCDR_PERIPH2_CLK2_PODF (0x7 << 0) | ||
126 | #define BP_CBCDR_MMDC_CH1_AXI_PODF 3 | ||
127 | #define BM_CBCDR_MMDC_CH1_AXI_PODF (0x7 << 3) | ||
128 | #define BP_CBCDR_AXI_SEL 6 | ||
129 | #define BM_CBCDR_AXI_SEL (0x3 << 6) | ||
130 | #define BP_CBCDR_IPG_PODF 8 | ||
131 | #define BM_CBCDR_IPG_PODF (0x3 << 8) | ||
132 | #define BP_CBCDR_AHB_PODF 10 | ||
133 | #define BM_CBCDR_AHB_PODF (0x7 << 10) | ||
134 | #define BP_CBCDR_AXI_PODF 16 | ||
135 | #define BM_CBCDR_AXI_PODF (0x7 << 16) | ||
136 | #define BP_CBCDR_MMDC_CH0_AXI_PODF 19 | ||
137 | #define BM_CBCDR_MMDC_CH0_AXI_PODF (0x7 << 19) | ||
138 | #define BP_CBCDR_PERIPH_CLK_SEL 25 | ||
139 | #define BM_CBCDR_PERIPH_CLK_SEL (0x1 << 25) | ||
140 | #define BP_CBCDR_PERIPH2_CLK_SEL 26 | ||
141 | #define BM_CBCDR_PERIPH2_CLK_SEL (0x1 << 26) | ||
142 | #define BP_CBCDR_PERIPH_CLK2_PODF 27 | ||
143 | #define BM_CBCDR_PERIPH_CLK2_PODF (0x7 << 27) | ||
144 | |||
145 | #define BP_CBCMR_GPU2D_AXI_SEL 0 | ||
146 | #define BM_CBCMR_GPU2D_AXI_SEL (0x1 << 0) | ||
147 | #define BP_CBCMR_GPU3D_AXI_SEL 1 | ||
148 | #define BM_CBCMR_GPU3D_AXI_SEL (0x1 << 1) | ||
149 | #define BP_CBCMR_GPU3D_CORE_SEL 4 | ||
150 | #define BM_CBCMR_GPU3D_CORE_SEL (0x3 << 4) | ||
151 | #define BP_CBCMR_GPU3D_SHADER_SEL 8 | ||
152 | #define BM_CBCMR_GPU3D_SHADER_SEL (0x3 << 8) | ||
153 | #define BP_CBCMR_PCIE_AXI_SEL 10 | ||
154 | #define BM_CBCMR_PCIE_AXI_SEL (0x1 << 10) | ||
155 | #define BP_CBCMR_VDO_AXI_SEL 11 | ||
156 | #define BM_CBCMR_VDO_AXI_SEL (0x1 << 11) | ||
157 | #define BP_CBCMR_PERIPH_CLK2_SEL 12 | ||
158 | #define BM_CBCMR_PERIPH_CLK2_SEL (0x3 << 12) | ||
159 | #define BP_CBCMR_VPU_AXI_SEL 14 | ||
160 | #define BM_CBCMR_VPU_AXI_SEL (0x3 << 14) | ||
161 | #define BP_CBCMR_GPU2D_CORE_SEL 16 | ||
162 | #define BM_CBCMR_GPU2D_CORE_SEL (0x3 << 16) | ||
163 | #define BP_CBCMR_PRE_PERIPH_CLK_SEL 18 | ||
164 | #define BM_CBCMR_PRE_PERIPH_CLK_SEL (0x3 << 18) | ||
165 | #define BP_CBCMR_PERIPH2_CLK2_SEL 20 | ||
166 | #define BM_CBCMR_PERIPH2_CLK2_SEL (0x1 << 20) | ||
167 | #define BP_CBCMR_PRE_PERIPH2_CLK_SEL 21 | ||
168 | #define BM_CBCMR_PRE_PERIPH2_CLK_SEL (0x3 << 21) | ||
169 | #define BP_CBCMR_GPU2D_CORE_PODF 23 | ||
170 | #define BM_CBCMR_GPU2D_CORE_PODF (0x7 << 23) | ||
171 | #define BP_CBCMR_GPU3D_CORE_PODF 26 | ||
172 | #define BM_CBCMR_GPU3D_CORE_PODF (0x7 << 26) | ||
173 | #define BP_CBCMR_GPU3D_SHADER_PODF 29 | ||
174 | #define BM_CBCMR_GPU3D_SHADER_PODF (0x7 << 29) | ||
175 | |||
176 | #define BP_CSCMR1_PERCLK_PODF 0 | ||
177 | #define BM_CSCMR1_PERCLK_PODF (0x3f << 0) | ||
178 | #define BP_CSCMR1_SSI1_SEL 10 | ||
179 | #define BM_CSCMR1_SSI1_SEL (0x3 << 10) | ||
180 | #define BP_CSCMR1_SSI2_SEL 12 | ||
181 | #define BM_CSCMR1_SSI2_SEL (0x3 << 12) | ||
182 | #define BP_CSCMR1_SSI3_SEL 14 | ||
183 | #define BM_CSCMR1_SSI3_SEL (0x3 << 14) | ||
184 | #define BP_CSCMR1_USDHC1_SEL 16 | ||
185 | #define BM_CSCMR1_USDHC1_SEL (0x1 << 16) | ||
186 | #define BP_CSCMR1_USDHC2_SEL 17 | ||
187 | #define BM_CSCMR1_USDHC2_SEL (0x1 << 17) | ||
188 | #define BP_CSCMR1_USDHC3_SEL 18 | ||
189 | #define BM_CSCMR1_USDHC3_SEL (0x1 << 18) | ||
190 | #define BP_CSCMR1_USDHC4_SEL 19 | ||
191 | #define BM_CSCMR1_USDHC4_SEL (0x1 << 19) | ||
192 | #define BP_CSCMR1_EMI_PODF 20 | ||
193 | #define BM_CSCMR1_EMI_PODF (0x7 << 20) | ||
194 | #define BP_CSCMR1_EMI_SLOW_PODF 23 | ||
195 | #define BM_CSCMR1_EMI_SLOW_PODF (0x7 << 23) | ||
196 | #define BP_CSCMR1_EMI_SEL 27 | ||
197 | #define BM_CSCMR1_EMI_SEL (0x3 << 27) | ||
198 | #define BP_CSCMR1_EMI_SLOW_SEL 29 | ||
199 | #define BM_CSCMR1_EMI_SLOW_SEL (0x3 << 29) | ||
200 | |||
201 | #define BP_CSCMR2_CAN_PODF 2 | ||
202 | #define BM_CSCMR2_CAN_PODF (0x3f << 2) | ||
203 | #define BM_CSCMR2_LDB_DI0_IPU_DIV (0x1 << 10) | ||
204 | #define BM_CSCMR2_LDB_DI1_IPU_DIV (0x1 << 11) | ||
205 | #define BP_CSCMR2_ESAI_SEL 19 | ||
206 | #define BM_CSCMR2_ESAI_SEL (0x3 << 19) | ||
207 | |||
208 | #define BP_CSCDR1_UART_PODF 0 | ||
209 | #define BM_CSCDR1_UART_PODF (0x3f << 0) | ||
210 | #define BP_CSCDR1_USDHC1_PODF 11 | ||
211 | #define BM_CSCDR1_USDHC1_PODF (0x7 << 11) | ||
212 | #define BP_CSCDR1_USDHC2_PODF 16 | ||
213 | #define BM_CSCDR1_USDHC2_PODF (0x7 << 16) | ||
214 | #define BP_CSCDR1_USDHC3_PODF 19 | ||
215 | #define BM_CSCDR1_USDHC3_PODF (0x7 << 19) | ||
216 | #define BP_CSCDR1_USDHC4_PODF 22 | ||
217 | #define BM_CSCDR1_USDHC4_PODF (0x7 << 22) | ||
218 | #define BP_CSCDR1_VPU_AXI_PODF 25 | ||
219 | #define BM_CSCDR1_VPU_AXI_PODF (0x7 << 25) | ||
220 | |||
221 | #define BP_CS1CDR_SSI1_PODF 0 | ||
222 | #define BM_CS1CDR_SSI1_PODF (0x3f << 0) | ||
223 | #define BP_CS1CDR_SSI1_PRED 6 | ||
224 | #define BM_CS1CDR_SSI1_PRED (0x7 << 6) | ||
225 | #define BP_CS1CDR_ESAI_PRED 9 | ||
226 | #define BM_CS1CDR_ESAI_PRED (0x7 << 9) | ||
227 | #define BP_CS1CDR_SSI3_PODF 16 | ||
228 | #define BM_CS1CDR_SSI3_PODF (0x3f << 16) | ||
229 | #define BP_CS1CDR_SSI3_PRED 22 | ||
230 | #define BM_CS1CDR_SSI3_PRED (0x7 << 22) | ||
231 | #define BP_CS1CDR_ESAI_PODF 25 | ||
232 | #define BM_CS1CDR_ESAI_PODF (0x7 << 25) | ||
233 | |||
234 | #define BP_CS2CDR_SSI2_PODF 0 | ||
235 | #define BM_CS2CDR_SSI2_PODF (0x3f << 0) | ||
236 | #define BP_CS2CDR_SSI2_PRED 6 | ||
237 | #define BM_CS2CDR_SSI2_PRED (0x7 << 6) | ||
238 | #define BP_CS2CDR_LDB_DI0_SEL 9 | ||
239 | #define BM_CS2CDR_LDB_DI0_SEL (0x7 << 9) | ||
240 | #define BP_CS2CDR_LDB_DI1_SEL 12 | ||
241 | #define BM_CS2CDR_LDB_DI1_SEL (0x7 << 12) | ||
242 | #define BP_CS2CDR_ENFC_SEL 16 | ||
243 | #define BM_CS2CDR_ENFC_SEL (0x3 << 16) | ||
244 | #define BP_CS2CDR_ENFC_PRED 18 | ||
245 | #define BM_CS2CDR_ENFC_PRED (0x7 << 18) | ||
246 | #define BP_CS2CDR_ENFC_PODF 21 | ||
247 | #define BM_CS2CDR_ENFC_PODF (0x3f << 21) | ||
248 | |||
249 | #define BP_CDCDR_ASRC_SERIAL_SEL 7 | ||
250 | #define BM_CDCDR_ASRC_SERIAL_SEL (0x3 << 7) | ||
251 | #define BP_CDCDR_ASRC_SERIAL_PODF 9 | ||
252 | #define BM_CDCDR_ASRC_SERIAL_PODF (0x7 << 9) | ||
253 | #define BP_CDCDR_ASRC_SERIAL_PRED 12 | ||
254 | #define BM_CDCDR_ASRC_SERIAL_PRED (0x7 << 12) | ||
255 | #define BP_CDCDR_SPDIF_SEL 20 | ||
256 | #define BM_CDCDR_SPDIF_SEL (0x3 << 20) | ||
257 | #define BP_CDCDR_SPDIF_PODF 22 | ||
258 | #define BM_CDCDR_SPDIF_PODF (0x7 << 22) | ||
259 | #define BP_CDCDR_SPDIF_PRED 25 | ||
260 | #define BM_CDCDR_SPDIF_PRED (0x7 << 25) | ||
261 | #define BP_CDCDR_HSI_TX_PODF 29 | ||
262 | #define BM_CDCDR_HSI_TX_PODF (0x7 << 29) | ||
263 | #define BP_CDCDR_HSI_TX_SEL 28 | ||
264 | #define BM_CDCDR_HSI_TX_SEL (0x1 << 28) | ||
265 | |||
266 | #define BP_CHSCCDR_IPU1_DI0_SEL 0 | ||
267 | #define BM_CHSCCDR_IPU1_DI0_SEL (0x7 << 0) | ||
268 | #define BP_CHSCCDR_IPU1_DI0_PRE_PODF 3 | ||
269 | #define BM_CHSCCDR_IPU1_DI0_PRE_PODF (0x7 << 3) | ||
270 | #define BP_CHSCCDR_IPU1_DI0_PRE_SEL 6 | ||
271 | #define BM_CHSCCDR_IPU1_DI0_PRE_SEL (0x7 << 6) | ||
272 | #define BP_CHSCCDR_IPU1_DI1_SEL 9 | ||
273 | #define BM_CHSCCDR_IPU1_DI1_SEL (0x7 << 9) | ||
274 | #define BP_CHSCCDR_IPU1_DI1_PRE_PODF 12 | ||
275 | #define BM_CHSCCDR_IPU1_DI1_PRE_PODF (0x7 << 12) | ||
276 | #define BP_CHSCCDR_IPU1_DI1_PRE_SEL 15 | ||
277 | #define BM_CHSCCDR_IPU1_DI1_PRE_SEL (0x7 << 15) | ||
278 | |||
279 | #define BP_CSCDR2_IPU2_DI0_SEL 0 | ||
280 | #define BM_CSCDR2_IPU2_DI0_SEL (0x7) | ||
281 | #define BP_CSCDR2_IPU2_DI0_PRE_PODF 3 | ||
282 | #define BM_CSCDR2_IPU2_DI0_PRE_PODF (0x7 << 3) | ||
283 | #define BP_CSCDR2_IPU2_DI0_PRE_SEL 6 | ||
284 | #define BM_CSCDR2_IPU2_DI0_PRE_SEL (0x7 << 6) | ||
285 | #define BP_CSCDR2_IPU2_DI1_SEL 9 | ||
286 | #define BM_CSCDR2_IPU2_DI1_SEL (0x7 << 9) | ||
287 | #define BP_CSCDR2_IPU2_DI1_PRE_PODF 12 | ||
288 | #define BM_CSCDR2_IPU2_DI1_PRE_PODF (0x7 << 12) | ||
289 | #define BP_CSCDR2_IPU2_DI1_PRE_SEL 15 | ||
290 | #define BM_CSCDR2_IPU2_DI1_PRE_SEL (0x7 << 15) | ||
291 | #define BP_CSCDR2_ECSPI_CLK_PODF 19 | ||
292 | #define BM_CSCDR2_ECSPI_CLK_PODF (0x3f << 19) | ||
293 | |||
294 | #define BP_CSCDR3_IPU1_HSP_SEL 9 | ||
295 | #define BM_CSCDR3_IPU1_HSP_SEL (0x3 << 9) | ||
296 | #define BP_CSCDR3_IPU1_HSP_PODF 11 | ||
297 | #define BM_CSCDR3_IPU1_HSP_PODF (0x7 << 11) | ||
298 | #define BP_CSCDR3_IPU2_HSP_SEL 14 | ||
299 | #define BM_CSCDR3_IPU2_HSP_SEL (0x3 << 14) | ||
300 | #define BP_CSCDR3_IPU2_HSP_PODF 16 | ||
301 | #define BM_CSCDR3_IPU2_HSP_PODF (0x7 << 16) | ||
302 | |||
303 | #define BM_CDHIPR_AXI_PODF_BUSY (0x1 << 0) | ||
304 | #define BM_CDHIPR_AHB_PODF_BUSY (0x1 << 1) | ||
305 | #define BM_CDHIPR_MMDC_CH1_PODF_BUSY (0x1 << 2) | ||
306 | #define BM_CDHIPR_PERIPH2_SEL_BUSY (0x1 << 3) | ||
307 | #define BM_CDHIPR_MMDC_CH0_PODF_BUSY (0x1 << 4) | ||
308 | #define BM_CDHIPR_PERIPH_SEL_BUSY (0x1 << 5) | ||
309 | #define BM_CDHIPR_ARM_PODF_BUSY (0x1 << 16) | ||
310 | |||
311 | #define BP_CLPCR_LPM 0 | ||
312 | #define BM_CLPCR_LPM (0x3 << 0) | ||
313 | #define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2) | ||
314 | #define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5) | ||
315 | #define BM_CLPCR_SBYOS (0x1 << 6) | ||
316 | #define BM_CLPCR_DIS_REF_OSC (0x1 << 7) | ||
317 | #define BM_CLPCR_VSTBY (0x1 << 8) | ||
318 | #define BP_CLPCR_STBY_COUNT 9 | ||
319 | #define BM_CLPCR_STBY_COUNT (0x3 << 9) | ||
320 | #define BM_CLPCR_COSC_PWRDOWN (0x1 << 11) | ||
321 | #define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16) | ||
322 | #define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17) | ||
323 | #define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19) | ||
324 | #define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21) | ||
325 | #define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22) | ||
326 | #define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23) | ||
327 | #define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24) | ||
328 | #define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25) | ||
329 | #define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26) | ||
330 | #define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27) | ||
331 | |||
332 | #define BP_CCOSR_CKO1_EN 7 | ||
333 | #define BP_CCOSR_CKO1_PODF 4 | ||
334 | #define BM_CCOSR_CKO1_PODF (0x7 << 4) | ||
335 | #define BP_CCOSR_CKO1_SEL 0 | ||
336 | #define BM_CCOSR_CKO1_SEL (0xf << 0) | ||
337 | |||
338 | #define FREQ_480M 480000000 | ||
339 | #define FREQ_528M 528000000 | ||
340 | #define FREQ_594M 594000000 | ||
341 | #define FREQ_650M 650000000 | ||
342 | #define FREQ_1300M 1300000000 | ||
343 | |||
344 | static struct clk pll1_sys; | ||
345 | static struct clk pll2_bus; | ||
346 | static struct clk pll3_usb_otg; | ||
347 | static struct clk pll4_audio; | ||
348 | static struct clk pll5_video; | ||
349 | static struct clk pll6_mlb; | ||
350 | static struct clk pll7_usb_host; | ||
351 | static struct clk pll8_enet; | ||
352 | static struct clk apbh_dma_clk; | ||
353 | static struct clk arm_clk; | ||
354 | static struct clk ipg_clk; | ||
355 | static struct clk ahb_clk; | ||
356 | static struct clk axi_clk; | ||
357 | static struct clk mmdc_ch0_axi_clk; | ||
358 | static struct clk mmdc_ch1_axi_clk; | ||
359 | static struct clk periph_clk; | ||
360 | static struct clk periph_pre_clk; | ||
361 | static struct clk periph_clk2_clk; | ||
362 | static struct clk periph2_clk; | ||
363 | static struct clk periph2_pre_clk; | ||
364 | static struct clk periph2_clk2_clk; | ||
365 | static struct clk gpu2d_core_clk; | ||
366 | static struct clk gpu3d_core_clk; | ||
367 | static struct clk gpu3d_shader_clk; | ||
368 | static struct clk ipg_perclk; | ||
369 | static struct clk emi_clk; | ||
370 | static struct clk emi_slow_clk; | ||
371 | static struct clk can1_clk; | ||
372 | static struct clk uart_clk; | ||
373 | static struct clk usdhc1_clk; | ||
374 | static struct clk usdhc2_clk; | ||
375 | static struct clk usdhc3_clk; | ||
376 | static struct clk usdhc4_clk; | ||
377 | static struct clk vpu_clk; | ||
378 | static struct clk hsi_tx_clk; | ||
379 | static struct clk ipu1_di0_pre_clk; | ||
380 | static struct clk ipu1_di1_pre_clk; | ||
381 | static struct clk ipu2_di0_pre_clk; | ||
382 | static struct clk ipu2_di1_pre_clk; | ||
383 | static struct clk ipu1_clk; | ||
384 | static struct clk ipu2_clk; | ||
385 | static struct clk ssi1_clk; | ||
386 | static struct clk ssi3_clk; | ||
387 | static struct clk esai_clk; | ||
388 | static struct clk ssi2_clk; | ||
389 | static struct clk spdif_clk; | ||
390 | static struct clk asrc_serial_clk; | ||
391 | static struct clk gpu2d_axi_clk; | ||
392 | static struct clk gpu3d_axi_clk; | ||
393 | static struct clk pcie_clk; | ||
394 | static struct clk vdo_axi_clk; | ||
395 | static struct clk ldb_di0_clk; | ||
396 | static struct clk ldb_di1_clk; | ||
397 | static struct clk ipu1_di0_clk; | ||
398 | static struct clk ipu1_di1_clk; | ||
399 | static struct clk ipu2_di0_clk; | ||
400 | static struct clk ipu2_di1_clk; | ||
401 | static struct clk enfc_clk; | ||
402 | static struct clk cko1_clk; | ||
403 | static struct clk dummy_clk = {}; | ||
404 | |||
405 | static unsigned long external_high_reference; | ||
406 | static unsigned long external_low_reference; | ||
407 | static unsigned long oscillator_reference; | ||
408 | |||
409 | static unsigned long get_oscillator_reference_clock_rate(struct clk *clk) | ||
410 | { | ||
411 | return oscillator_reference; | ||
412 | } | ||
413 | |||
414 | static unsigned long get_high_reference_clock_rate(struct clk *clk) | ||
415 | { | ||
416 | return external_high_reference; | ||
417 | } | ||
418 | |||
419 | static unsigned long get_low_reference_clock_rate(struct clk *clk) | ||
420 | { | ||
421 | return external_low_reference; | ||
422 | } | ||
423 | |||
424 | static struct clk ckil_clk = { | ||
425 | .get_rate = get_low_reference_clock_rate, | ||
426 | }; | ||
427 | |||
428 | static struct clk ckih_clk = { | ||
429 | .get_rate = get_high_reference_clock_rate, | ||
430 | }; | ||
431 | |||
432 | static struct clk osc_clk = { | ||
433 | .get_rate = get_oscillator_reference_clock_rate, | ||
434 | }; | ||
435 | |||
436 | static inline void __iomem *pll_get_reg_addr(struct clk *pll) | ||
437 | { | ||
438 | if (pll == &pll1_sys) | ||
439 | return PLL1_SYS; | ||
440 | else if (pll == &pll2_bus) | ||
441 | return PLL2_BUS; | ||
442 | else if (pll == &pll3_usb_otg) | ||
443 | return PLL3_USB_OTG; | ||
444 | else if (pll == &pll4_audio) | ||
445 | return PLL4_AUDIO; | ||
446 | else if (pll == &pll5_video) | ||
447 | return PLL5_VIDEO; | ||
448 | else if (pll == &pll6_mlb) | ||
449 | return PLL6_MLB; | ||
450 | else if (pll == &pll7_usb_host) | ||
451 | return PLL7_USB_HOST; | ||
452 | else if (pll == &pll8_enet) | ||
453 | return PLL8_ENET; | ||
454 | else | ||
455 | BUG(); | ||
456 | |||
457 | return NULL; | ||
458 | } | ||
459 | |||
460 | static int pll_enable(struct clk *clk) | ||
461 | { | ||
462 | int timeout = 0x100000; | ||
463 | void __iomem *reg; | ||
464 | u32 val; | ||
465 | |||
466 | reg = pll_get_reg_addr(clk); | ||
467 | val = readl_relaxed(reg); | ||
468 | val &= ~BM_PLL_BYPASS; | ||
469 | val &= ~BM_PLL_POWER_DOWN; | ||
470 | /* 480MHz PLLs have the opposite definition for power bit */ | ||
471 | if (clk == &pll3_usb_otg || clk == &pll7_usb_host) | ||
472 | val |= BM_PLL_POWER_DOWN; | ||
473 | writel_relaxed(val, reg); | ||
474 | |||
475 | /* Wait for PLL to lock */ | ||
476 | while (!(readl_relaxed(reg) & BM_PLL_LOCK) && --timeout) | ||
477 | cpu_relax(); | ||
478 | |||
479 | if (unlikely(!timeout)) | ||
480 | return -EBUSY; | ||
481 | |||
482 | /* Enable the PLL output now */ | ||
483 | val = readl_relaxed(reg); | ||
484 | val |= BM_PLL_ENABLE; | ||
485 | writel_relaxed(val, reg); | ||
486 | |||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | static void pll_disable(struct clk *clk) | ||
491 | { | ||
492 | void __iomem *reg; | ||
493 | u32 val; | ||
494 | |||
495 | reg = pll_get_reg_addr(clk); | ||
496 | val = readl_relaxed(reg); | ||
497 | val &= ~BM_PLL_ENABLE; | ||
498 | val |= BM_PLL_BYPASS; | ||
499 | val |= BM_PLL_POWER_DOWN; | ||
500 | if (clk == &pll3_usb_otg || clk == &pll7_usb_host) | ||
501 | val &= ~BM_PLL_POWER_DOWN; | ||
502 | writel_relaxed(val, reg); | ||
503 | } | ||
504 | |||
505 | static unsigned long pll1_sys_get_rate(struct clk *clk) | ||
506 | { | ||
507 | u32 div = (readl_relaxed(PLL1_SYS) & BM_PLL_SYS_DIV_SELECT) >> | ||
508 | BP_PLL_SYS_DIV_SELECT; | ||
509 | |||
510 | return clk_get_rate(clk->parent) * div / 2; | ||
511 | } | ||
512 | |||
513 | static int pll1_sys_set_rate(struct clk *clk, unsigned long rate) | ||
514 | { | ||
515 | u32 val, div; | ||
516 | |||
517 | if (rate < FREQ_650M || rate > FREQ_1300M) | ||
518 | return -EINVAL; | ||
519 | |||
520 | div = rate * 2 / clk_get_rate(clk->parent); | ||
521 | val = readl_relaxed(PLL1_SYS); | ||
522 | val &= ~BM_PLL_SYS_DIV_SELECT; | ||
523 | val |= div << BP_PLL_SYS_DIV_SELECT; | ||
524 | writel_relaxed(val, PLL1_SYS); | ||
525 | |||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | static unsigned long pll8_enet_get_rate(struct clk *clk) | ||
530 | { | ||
531 | u32 div = (readl_relaxed(PLL8_ENET) & BM_PLL_ENET_DIV_SELECT) >> | ||
532 | BP_PLL_ENET_DIV_SELECT; | ||
533 | |||
534 | switch (div) { | ||
535 | case 0: | ||
536 | return 25000000; | ||
537 | case 1: | ||
538 | return 50000000; | ||
539 | case 2: | ||
540 | return 100000000; | ||
541 | case 3: | ||
542 | return 125000000; | ||
543 | } | ||
544 | |||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | static int pll8_enet_set_rate(struct clk *clk, unsigned long rate) | ||
549 | { | ||
550 | u32 val, div; | ||
551 | |||
552 | switch (rate) { | ||
553 | case 25000000: | ||
554 | div = 0; | ||
555 | break; | ||
556 | case 50000000: | ||
557 | div = 1; | ||
558 | break; | ||
559 | case 100000000: | ||
560 | div = 2; | ||
561 | break; | ||
562 | case 125000000: | ||
563 | div = 3; | ||
564 | break; | ||
565 | default: | ||
566 | return -EINVAL; | ||
567 | } | ||
568 | |||
569 | val = readl_relaxed(PLL8_ENET); | ||
570 | val &= ~BM_PLL_ENET_DIV_SELECT; | ||
571 | val |= div << BP_PLL_ENET_DIV_SELECT; | ||
572 | writel_relaxed(val, PLL8_ENET); | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static unsigned long pll_av_get_rate(struct clk *clk) | ||
578 | { | ||
579 | void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO; | ||
580 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
581 | u32 mfn = readl_relaxed(reg + PLL_NUM_OFFSET); | ||
582 | u32 mfd = readl_relaxed(reg + PLL_DENOM_OFFSET); | ||
583 | u32 div = (readl_relaxed(reg) & BM_PLL_AV_DIV_SELECT) >> | ||
584 | BP_PLL_AV_DIV_SELECT; | ||
585 | |||
586 | return (parent_rate * div) + ((parent_rate / mfd) * mfn); | ||
587 | } | ||
588 | |||
589 | static int pll_av_set_rate(struct clk *clk, unsigned long rate) | ||
590 | { | ||
591 | void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO; | ||
592 | unsigned int parent_rate = clk_get_rate(clk->parent); | ||
593 | u32 val, div; | ||
594 | u32 mfn, mfd = 1000000; | ||
595 | s64 temp64; | ||
596 | |||
597 | if (rate < FREQ_650M || rate > FREQ_1300M) | ||
598 | return -EINVAL; | ||
599 | |||
600 | div = rate / parent_rate; | ||
601 | temp64 = (u64) (rate - div * parent_rate); | ||
602 | temp64 *= mfd; | ||
603 | do_div(temp64, parent_rate); | ||
604 | mfn = temp64; | ||
605 | |||
606 | val = readl_relaxed(reg); | ||
607 | val &= ~BM_PLL_AV_DIV_SELECT; | ||
608 | val |= div << BP_PLL_AV_DIV_SELECT; | ||
609 | writel_relaxed(val, reg); | ||
610 | writel_relaxed(mfn, reg + PLL_NUM_OFFSET); | ||
611 | writel_relaxed(mfd, reg + PLL_DENOM_OFFSET); | ||
612 | |||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | static void __iomem *pll_get_div_reg_bit(struct clk *clk, u32 *bp, u32 *bm) | ||
617 | { | ||
618 | void __iomem *reg; | ||
619 | |||
620 | if (clk == &pll2_bus) { | ||
621 | reg = PLL2_BUS; | ||
622 | *bp = BP_PLL_BUS_DIV_SELECT; | ||
623 | *bm = BM_PLL_BUS_DIV_SELECT; | ||
624 | } else if (clk == &pll3_usb_otg) { | ||
625 | reg = PLL3_USB_OTG; | ||
626 | *bp = BP_PLL_USB_DIV_SELECT; | ||
627 | *bm = BM_PLL_USB_DIV_SELECT; | ||
628 | } else if (clk == &pll7_usb_host) { | ||
629 | reg = PLL7_USB_HOST; | ||
630 | *bp = BP_PLL_USB_DIV_SELECT; | ||
631 | *bm = BM_PLL_USB_DIV_SELECT; | ||
632 | } else { | ||
633 | BUG(); | ||
634 | } | ||
635 | |||
636 | return reg; | ||
637 | } | ||
638 | |||
639 | static unsigned long pll_get_rate(struct clk *clk) | ||
640 | { | ||
641 | void __iomem *reg; | ||
642 | u32 div, bp, bm; | ||
643 | |||
644 | reg = pll_get_div_reg_bit(clk, &bp, &bm); | ||
645 | div = (readl_relaxed(reg) & bm) >> bp; | ||
646 | |||
647 | return (div == 1) ? clk_get_rate(clk->parent) * 22 : | ||
648 | clk_get_rate(clk->parent) * 20; | ||
649 | } | ||
650 | |||
651 | static int pll_set_rate(struct clk *clk, unsigned long rate) | ||
652 | { | ||
653 | void __iomem *reg; | ||
654 | u32 val, div, bp, bm; | ||
655 | |||
656 | if (rate == FREQ_528M) | ||
657 | div = 1; | ||
658 | else if (rate == FREQ_480M) | ||
659 | div = 0; | ||
660 | else | ||
661 | return -EINVAL; | ||
662 | |||
663 | reg = pll_get_div_reg_bit(clk, &bp, &bm); | ||
664 | val = readl_relaxed(reg); | ||
665 | val &= ~bm; | ||
666 | val |= div << bp; | ||
667 | writel_relaxed(val, reg); | ||
668 | |||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | #define pll2_bus_get_rate pll_get_rate | ||
673 | #define pll2_bus_set_rate pll_set_rate | ||
674 | #define pll3_usb_otg_get_rate pll_get_rate | ||
675 | #define pll3_usb_otg_set_rate pll_set_rate | ||
676 | #define pll7_usb_host_get_rate pll_get_rate | ||
677 | #define pll7_usb_host_set_rate pll_set_rate | ||
678 | #define pll4_audio_get_rate pll_av_get_rate | ||
679 | #define pll4_audio_set_rate pll_av_set_rate | ||
680 | #define pll5_video_get_rate pll_av_get_rate | ||
681 | #define pll5_video_set_rate pll_av_set_rate | ||
682 | #define pll6_mlb_get_rate NULL | ||
683 | #define pll6_mlb_set_rate NULL | ||
684 | |||
685 | #define DEF_PLL(name) \ | ||
686 | static struct clk name = { \ | ||
687 | .enable = pll_enable, \ | ||
688 | .disable = pll_disable, \ | ||
689 | .get_rate = name##_get_rate, \ | ||
690 | .set_rate = name##_set_rate, \ | ||
691 | .parent = &osc_clk, \ | ||
692 | } | ||
693 | |||
694 | DEF_PLL(pll1_sys); | ||
695 | DEF_PLL(pll2_bus); | ||
696 | DEF_PLL(pll3_usb_otg); | ||
697 | DEF_PLL(pll4_audio); | ||
698 | DEF_PLL(pll5_video); | ||
699 | DEF_PLL(pll6_mlb); | ||
700 | DEF_PLL(pll7_usb_host); | ||
701 | DEF_PLL(pll8_enet); | ||
702 | |||
703 | static unsigned long pfd_get_rate(struct clk *clk) | ||
704 | { | ||
705 | u64 tmp = (u64) clk_get_rate(clk->parent) * 18; | ||
706 | u32 frac, bp_frac; | ||
707 | |||
708 | if (apbh_dma_clk.usecount == 0) | ||
709 | apbh_dma_clk.enable(&apbh_dma_clk); | ||
710 | |||
711 | bp_frac = clk->enable_shift - 7; | ||
712 | frac = readl_relaxed(clk->enable_reg) >> bp_frac & PFD_FRAC_MASK; | ||
713 | do_div(tmp, frac); | ||
714 | |||
715 | return tmp; | ||
716 | } | ||
717 | |||
718 | static int pfd_set_rate(struct clk *clk, unsigned long rate) | ||
719 | { | ||
720 | u32 val, frac, bp_frac; | ||
721 | u64 tmp = (u64) clk_get_rate(clk->parent) * 18; | ||
722 | |||
723 | if (apbh_dma_clk.usecount == 0) | ||
724 | apbh_dma_clk.enable(&apbh_dma_clk); | ||
725 | |||
726 | /* | ||
727 | * Round up the divider so that we don't set a rate | ||
728 | * higher than what is requested | ||
729 | */ | ||
730 | tmp += rate / 2; | ||
731 | do_div(tmp, rate); | ||
732 | frac = tmp; | ||
733 | frac = (frac < 12) ? 12 : frac; | ||
734 | frac = (frac > 35) ? 35 : frac; | ||
735 | |||
736 | /* | ||
737 | * The frac field always starts from 7 bits lower | ||
738 | * position of enable bit | ||
739 | */ | ||
740 | bp_frac = clk->enable_shift - 7; | ||
741 | val = readl_relaxed(clk->enable_reg); | ||
742 | val &= ~(PFD_FRAC_MASK << bp_frac); | ||
743 | val |= frac << bp_frac; | ||
744 | writel_relaxed(val, clk->enable_reg); | ||
745 | |||
746 | tmp = (u64) clk_get_rate(clk->parent) * 18; | ||
747 | do_div(tmp, frac); | ||
748 | |||
749 | if (apbh_dma_clk.usecount == 0) | ||
750 | apbh_dma_clk.disable(&apbh_dma_clk); | ||
751 | |||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | static unsigned long pfd_round_rate(struct clk *clk, unsigned long rate) | ||
756 | { | ||
757 | u32 frac; | ||
758 | u64 tmp; | ||
759 | |||
760 | tmp = (u64) clk_get_rate(clk->parent) * 18; | ||
761 | tmp += rate / 2; | ||
762 | do_div(tmp, rate); | ||
763 | frac = tmp; | ||
764 | frac = (frac < 12) ? 12 : frac; | ||
765 | frac = (frac > 35) ? 35 : frac; | ||
766 | tmp = (u64) clk_get_rate(clk->parent) * 18; | ||
767 | do_div(tmp, frac); | ||
768 | |||
769 | return tmp; | ||
770 | } | ||
771 | |||
772 | static int pfd_enable(struct clk *clk) | ||
773 | { | ||
774 | u32 val; | ||
775 | |||
776 | if (apbh_dma_clk.usecount == 0) | ||
777 | apbh_dma_clk.enable(&apbh_dma_clk); | ||
778 | |||
779 | val = readl_relaxed(clk->enable_reg); | ||
780 | val &= ~(1 << clk->enable_shift); | ||
781 | writel_relaxed(val, clk->enable_reg); | ||
782 | |||
783 | if (apbh_dma_clk.usecount == 0) | ||
784 | apbh_dma_clk.disable(&apbh_dma_clk); | ||
785 | |||
786 | return 0; | ||
787 | } | ||
788 | |||
789 | static void pfd_disable(struct clk *clk) | ||
790 | { | ||
791 | u32 val; | ||
792 | |||
793 | if (apbh_dma_clk.usecount == 0) | ||
794 | apbh_dma_clk.enable(&apbh_dma_clk); | ||
795 | |||
796 | val = readl_relaxed(clk->enable_reg); | ||
797 | val |= 1 << clk->enable_shift; | ||
798 | writel_relaxed(val, clk->enable_reg); | ||
799 | |||
800 | if (apbh_dma_clk.usecount == 0) | ||
801 | apbh_dma_clk.disable(&apbh_dma_clk); | ||
802 | } | ||
803 | |||
804 | #define DEF_PFD(name, er, es, p) \ | ||
805 | static struct clk name = { \ | ||
806 | .enable_reg = er, \ | ||
807 | .enable_shift = es, \ | ||
808 | .enable = pfd_enable, \ | ||
809 | .disable = pfd_disable, \ | ||
810 | .get_rate = pfd_get_rate, \ | ||
811 | .set_rate = pfd_set_rate, \ | ||
812 | .round_rate = pfd_round_rate, \ | ||
813 | .parent = p, \ | ||
814 | } | ||
815 | |||
816 | DEF_PFD(pll2_pfd_352m, PFD_528, PFD0, &pll2_bus); | ||
817 | DEF_PFD(pll2_pfd_594m, PFD_528, PFD1, &pll2_bus); | ||
818 | DEF_PFD(pll2_pfd_400m, PFD_528, PFD2, &pll2_bus); | ||
819 | DEF_PFD(pll3_pfd_720m, PFD_480, PFD0, &pll3_usb_otg); | ||
820 | DEF_PFD(pll3_pfd_540m, PFD_480, PFD1, &pll3_usb_otg); | ||
821 | DEF_PFD(pll3_pfd_508m, PFD_480, PFD2, &pll3_usb_otg); | ||
822 | DEF_PFD(pll3_pfd_454m, PFD_480, PFD3, &pll3_usb_otg); | ||
823 | |||
824 | static unsigned long twd_clk_get_rate(struct clk *clk) | ||
825 | { | ||
826 | return clk_get_rate(clk->parent) / 2; | ||
827 | } | ||
828 | |||
829 | static struct clk twd_clk = { | ||
830 | .parent = &arm_clk, | ||
831 | .get_rate = twd_clk_get_rate, | ||
832 | }; | ||
833 | |||
834 | static unsigned long pll2_200m_get_rate(struct clk *clk) | ||
835 | { | ||
836 | return clk_get_rate(clk->parent) / 2; | ||
837 | } | ||
838 | |||
839 | static struct clk pll2_200m = { | ||
840 | .parent = &pll2_pfd_400m, | ||
841 | .get_rate = pll2_200m_get_rate, | ||
842 | }; | ||
843 | |||
844 | static unsigned long pll3_120m_get_rate(struct clk *clk) | ||
845 | { | ||
846 | return clk_get_rate(clk->parent) / 4; | ||
847 | } | ||
848 | |||
849 | static struct clk pll3_120m = { | ||
850 | .parent = &pll3_usb_otg, | ||
851 | .get_rate = pll3_120m_get_rate, | ||
852 | }; | ||
853 | |||
854 | static unsigned long pll3_80m_get_rate(struct clk *clk) | ||
855 | { | ||
856 | return clk_get_rate(clk->parent) / 6; | ||
857 | } | ||
858 | |||
859 | static struct clk pll3_80m = { | ||
860 | .parent = &pll3_usb_otg, | ||
861 | .get_rate = pll3_80m_get_rate, | ||
862 | }; | ||
863 | |||
864 | static unsigned long pll3_60m_get_rate(struct clk *clk) | ||
865 | { | ||
866 | return clk_get_rate(clk->parent) / 8; | ||
867 | } | ||
868 | |||
869 | static struct clk pll3_60m = { | ||
870 | .parent = &pll3_usb_otg, | ||
871 | .get_rate = pll3_60m_get_rate, | ||
872 | }; | ||
873 | |||
874 | static int pll1_sw_clk_set_parent(struct clk *clk, struct clk *parent) | ||
875 | { | ||
876 | u32 val = readl_relaxed(CCSR); | ||
877 | |||
878 | if (parent == &pll1_sys) { | ||
879 | val &= ~BM_CCSR_PLL1_SW_SEL; | ||
880 | val &= ~BM_CCSR_STEP_SEL; | ||
881 | } else if (parent == &osc_clk) { | ||
882 | val |= BM_CCSR_PLL1_SW_SEL; | ||
883 | val &= ~BM_CCSR_STEP_SEL; | ||
884 | } else if (parent == &pll2_pfd_400m) { | ||
885 | val |= BM_CCSR_PLL1_SW_SEL; | ||
886 | val |= BM_CCSR_STEP_SEL; | ||
887 | } else { | ||
888 | return -EINVAL; | ||
889 | } | ||
890 | |||
891 | writel_relaxed(val, CCSR); | ||
892 | |||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | static struct clk pll1_sw_clk = { | ||
897 | .parent = &pll1_sys, | ||
898 | .set_parent = pll1_sw_clk_set_parent, | ||
899 | }; | ||
900 | |||
901 | static void calc_pred_podf_dividers(u32 div, u32 *pred, u32 *podf) | ||
902 | { | ||
903 | u32 min_pred, temp_pred, old_err, err; | ||
904 | |||
905 | if (div >= 512) { | ||
906 | *pred = 8; | ||
907 | *podf = 64; | ||
908 | } else if (div >= 8) { | ||
909 | min_pred = (div - 1) / 64 + 1; | ||
910 | old_err = 8; | ||
911 | for (temp_pred = 8; temp_pred >= min_pred; temp_pred--) { | ||
912 | err = div % temp_pred; | ||
913 | if (err == 0) { | ||
914 | *pred = temp_pred; | ||
915 | break; | ||
916 | } | ||
917 | err = temp_pred - err; | ||
918 | if (err < old_err) { | ||
919 | old_err = err; | ||
920 | *pred = temp_pred; | ||
921 | } | ||
922 | } | ||
923 | *podf = (div + *pred - 1) / *pred; | ||
924 | } else if (div < 8) { | ||
925 | *pred = div; | ||
926 | *podf = 1; | ||
927 | } | ||
928 | } | ||
929 | |||
930 | static int _clk_enable(struct clk *clk) | ||
931 | { | ||
932 | u32 reg; | ||
933 | reg = readl_relaxed(clk->enable_reg); | ||
934 | reg |= 0x3 << clk->enable_shift; | ||
935 | writel_relaxed(reg, clk->enable_reg); | ||
936 | |||
937 | return 0; | ||
938 | } | ||
939 | |||
940 | static void _clk_disable(struct clk *clk) | ||
941 | { | ||
942 | u32 reg; | ||
943 | reg = readl_relaxed(clk->enable_reg); | ||
944 | reg &= ~(0x3 << clk->enable_shift); | ||
945 | writel_relaxed(reg, clk->enable_reg); | ||
946 | } | ||
947 | |||
948 | static int _clk_enable_1b(struct clk *clk) | ||
949 | { | ||
950 | u32 reg; | ||
951 | reg = readl_relaxed(clk->enable_reg); | ||
952 | reg |= 0x1 << clk->enable_shift; | ||
953 | writel_relaxed(reg, clk->enable_reg); | ||
954 | |||
955 | return 0; | ||
956 | } | ||
957 | |||
958 | static void _clk_disable_1b(struct clk *clk) | ||
959 | { | ||
960 | u32 reg; | ||
961 | reg = readl_relaxed(clk->enable_reg); | ||
962 | reg &= ~(0x1 << clk->enable_shift); | ||
963 | writel_relaxed(reg, clk->enable_reg); | ||
964 | } | ||
965 | |||
966 | struct divider { | ||
967 | struct clk *clk; | ||
968 | void __iomem *reg; | ||
969 | u32 bp_pred; | ||
970 | u32 bm_pred; | ||
971 | u32 bp_podf; | ||
972 | u32 bm_podf; | ||
973 | }; | ||
974 | |||
975 | #define DEF_CLK_DIV1(d, c, r, b) \ | ||
976 | static struct divider d = { \ | ||
977 | .clk = c, \ | ||
978 | .reg = r, \ | ||
979 | .bp_podf = BP_##r##_##b##_PODF, \ | ||
980 | .bm_podf = BM_##r##_##b##_PODF, \ | ||
981 | } | ||
982 | |||
983 | DEF_CLK_DIV1(arm_div, &arm_clk, CACRR, ARM); | ||
984 | DEF_CLK_DIV1(ipg_div, &ipg_clk, CBCDR, IPG); | ||
985 | DEF_CLK_DIV1(ahb_div, &ahb_clk, CBCDR, AHB); | ||
986 | DEF_CLK_DIV1(axi_div, &axi_clk, CBCDR, AXI); | ||
987 | DEF_CLK_DIV1(mmdc_ch0_axi_div, &mmdc_ch0_axi_clk, CBCDR, MMDC_CH0_AXI); | ||
988 | DEF_CLK_DIV1(mmdc_ch1_axi_div, &mmdc_ch1_axi_clk, CBCDR, MMDC_CH1_AXI); | ||
989 | DEF_CLK_DIV1(periph_clk2_div, &periph_clk2_clk, CBCDR, PERIPH_CLK2); | ||
990 | DEF_CLK_DIV1(periph2_clk2_div, &periph2_clk2_clk, CBCDR, PERIPH2_CLK2); | ||
991 | DEF_CLK_DIV1(gpu2d_core_div, &gpu2d_core_clk, CBCMR, GPU2D_CORE); | ||
992 | DEF_CLK_DIV1(gpu3d_core_div, &gpu3d_core_clk, CBCMR, GPU3D_CORE); | ||
993 | DEF_CLK_DIV1(gpu3d_shader_div, &gpu3d_shader_clk, CBCMR, GPU3D_SHADER); | ||
994 | DEF_CLK_DIV1(ipg_perclk_div, &ipg_perclk, CSCMR1, PERCLK); | ||
995 | DEF_CLK_DIV1(emi_div, &emi_clk, CSCMR1, EMI); | ||
996 | DEF_CLK_DIV1(emi_slow_div, &emi_slow_clk, CSCMR1, EMI_SLOW); | ||
997 | DEF_CLK_DIV1(can_div, &can1_clk, CSCMR2, CAN); | ||
998 | DEF_CLK_DIV1(uart_div, &uart_clk, CSCDR1, UART); | ||
999 | DEF_CLK_DIV1(usdhc1_div, &usdhc1_clk, CSCDR1, USDHC1); | ||
1000 | DEF_CLK_DIV1(usdhc2_div, &usdhc2_clk, CSCDR1, USDHC2); | ||
1001 | DEF_CLK_DIV1(usdhc3_div, &usdhc3_clk, CSCDR1, USDHC3); | ||
1002 | DEF_CLK_DIV1(usdhc4_div, &usdhc4_clk, CSCDR1, USDHC4); | ||
1003 | DEF_CLK_DIV1(vpu_div, &vpu_clk, CSCDR1, VPU_AXI); | ||
1004 | DEF_CLK_DIV1(hsi_tx_div, &hsi_tx_clk, CDCDR, HSI_TX); | ||
1005 | DEF_CLK_DIV1(ipu1_di0_pre_div, &ipu1_di0_pre_clk, CHSCCDR, IPU1_DI0_PRE); | ||
1006 | DEF_CLK_DIV1(ipu1_di1_pre_div, &ipu1_di1_pre_clk, CHSCCDR, IPU1_DI1_PRE); | ||
1007 | DEF_CLK_DIV1(ipu2_di0_pre_div, &ipu2_di0_pre_clk, CSCDR2, IPU2_DI0_PRE); | ||
1008 | DEF_CLK_DIV1(ipu2_di1_pre_div, &ipu2_di1_pre_clk, CSCDR2, IPU2_DI1_PRE); | ||
1009 | DEF_CLK_DIV1(ipu1_div, &ipu1_clk, CSCDR3, IPU1_HSP); | ||
1010 | DEF_CLK_DIV1(ipu2_div, &ipu2_clk, CSCDR3, IPU2_HSP); | ||
1011 | DEF_CLK_DIV1(cko1_div, &cko1_clk, CCOSR, CKO1); | ||
1012 | |||
1013 | #define DEF_CLK_DIV2(d, c, r, b) \ | ||
1014 | static struct divider d = { \ | ||
1015 | .clk = c, \ | ||
1016 | .reg = r, \ | ||
1017 | .bp_pred = BP_##r##_##b##_PRED, \ | ||
1018 | .bm_pred = BM_##r##_##b##_PRED, \ | ||
1019 | .bp_podf = BP_##r##_##b##_PODF, \ | ||
1020 | .bm_podf = BM_##r##_##b##_PODF, \ | ||
1021 | } | ||
1022 | |||
1023 | DEF_CLK_DIV2(ssi1_div, &ssi1_clk, CS1CDR, SSI1); | ||
1024 | DEF_CLK_DIV2(ssi3_div, &ssi3_clk, CS1CDR, SSI3); | ||
1025 | DEF_CLK_DIV2(esai_div, &esai_clk, CS1CDR, ESAI); | ||
1026 | DEF_CLK_DIV2(ssi2_div, &ssi2_clk, CS2CDR, SSI2); | ||
1027 | DEF_CLK_DIV2(enfc_div, &enfc_clk, CS2CDR, ENFC); | ||
1028 | DEF_CLK_DIV2(spdif_div, &spdif_clk, CDCDR, SPDIF); | ||
1029 | DEF_CLK_DIV2(asrc_serial_div, &asrc_serial_clk, CDCDR, ASRC_SERIAL); | ||
1030 | |||
1031 | static struct divider *dividers[] = { | ||
1032 | &arm_div, | ||
1033 | &ipg_div, | ||
1034 | &ahb_div, | ||
1035 | &axi_div, | ||
1036 | &mmdc_ch0_axi_div, | ||
1037 | &mmdc_ch1_axi_div, | ||
1038 | &periph_clk2_div, | ||
1039 | &periph2_clk2_div, | ||
1040 | &gpu2d_core_div, | ||
1041 | &gpu3d_core_div, | ||
1042 | &gpu3d_shader_div, | ||
1043 | &ipg_perclk_div, | ||
1044 | &emi_div, | ||
1045 | &emi_slow_div, | ||
1046 | &can_div, | ||
1047 | &uart_div, | ||
1048 | &usdhc1_div, | ||
1049 | &usdhc2_div, | ||
1050 | &usdhc3_div, | ||
1051 | &usdhc4_div, | ||
1052 | &vpu_div, | ||
1053 | &hsi_tx_div, | ||
1054 | &ipu1_di0_pre_div, | ||
1055 | &ipu1_di1_pre_div, | ||
1056 | &ipu2_di0_pre_div, | ||
1057 | &ipu2_di1_pre_div, | ||
1058 | &ipu1_div, | ||
1059 | &ipu2_div, | ||
1060 | &ssi1_div, | ||
1061 | &ssi3_div, | ||
1062 | &esai_div, | ||
1063 | &ssi2_div, | ||
1064 | &enfc_div, | ||
1065 | &spdif_div, | ||
1066 | &asrc_serial_div, | ||
1067 | &cko1_div, | ||
1068 | }; | ||
1069 | |||
1070 | static unsigned long ldb_di_clk_get_rate(struct clk *clk) | ||
1071 | { | ||
1072 | u32 val = readl_relaxed(CSCMR2); | ||
1073 | |||
1074 | val &= (clk == &ldb_di0_clk) ? BM_CSCMR2_LDB_DI0_IPU_DIV : | ||
1075 | BM_CSCMR2_LDB_DI1_IPU_DIV; | ||
1076 | if (val) | ||
1077 | return clk_get_rate(clk->parent) / 7; | ||
1078 | else | ||
1079 | return clk_get_rate(clk->parent) * 2 / 7; | ||
1080 | } | ||
1081 | |||
1082 | static int ldb_di_clk_set_rate(struct clk *clk, unsigned long rate) | ||
1083 | { | ||
1084 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
1085 | u32 val = readl_relaxed(CSCMR2); | ||
1086 | |||
1087 | if (rate * 7 <= parent_rate + parent_rate / 20) | ||
1088 | val |= BM_CSCMR2_LDB_DI0_IPU_DIV; | ||
1089 | else | ||
1090 | val &= ~BM_CSCMR2_LDB_DI0_IPU_DIV; | ||
1091 | |||
1092 | writel_relaxed(val, CSCMR2); | ||
1093 | |||
1094 | return 0; | ||
1095 | } | ||
1096 | |||
1097 | static unsigned long ldb_di_clk_round_rate(struct clk *clk, unsigned long rate) | ||
1098 | { | ||
1099 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
1100 | |||
1101 | if (rate * 7 <= parent_rate + parent_rate / 20) | ||
1102 | return parent_rate / 7; | ||
1103 | else | ||
1104 | return 2 * parent_rate / 7; | ||
1105 | } | ||
1106 | |||
1107 | static unsigned long _clk_get_rate(struct clk *clk) | ||
1108 | { | ||
1109 | struct divider *d; | ||
1110 | u32 val, pred, podf; | ||
1111 | int i, num; | ||
1112 | |||
1113 | if (clk == &ldb_di0_clk || clk == &ldb_di1_clk) | ||
1114 | return ldb_di_clk_get_rate(clk); | ||
1115 | |||
1116 | num = ARRAY_SIZE(dividers); | ||
1117 | for (i = 0; i < num; i++) | ||
1118 | if (dividers[i]->clk == clk) { | ||
1119 | d = dividers[i]; | ||
1120 | break; | ||
1121 | } | ||
1122 | if (i == num) | ||
1123 | return clk_get_rate(clk->parent); | ||
1124 | |||
1125 | val = readl_relaxed(d->reg); | ||
1126 | pred = ((val & d->bm_pred) >> d->bp_pred) + 1; | ||
1127 | podf = ((val & d->bm_podf) >> d->bp_podf) + 1; | ||
1128 | |||
1129 | return clk_get_rate(clk->parent) / (pred * podf); | ||
1130 | } | ||
1131 | |||
1132 | static int clk_busy_wait(struct clk *clk) | ||
1133 | { | ||
1134 | int timeout = 0x100000; | ||
1135 | u32 bm; | ||
1136 | |||
1137 | if (clk == &axi_clk) | ||
1138 | bm = BM_CDHIPR_AXI_PODF_BUSY; | ||
1139 | else if (clk == &ahb_clk) | ||
1140 | bm = BM_CDHIPR_AHB_PODF_BUSY; | ||
1141 | else if (clk == &mmdc_ch0_axi_clk) | ||
1142 | bm = BM_CDHIPR_MMDC_CH0_PODF_BUSY; | ||
1143 | else if (clk == &periph_clk) | ||
1144 | bm = BM_CDHIPR_PERIPH_SEL_BUSY; | ||
1145 | else if (clk == &arm_clk) | ||
1146 | bm = BM_CDHIPR_ARM_PODF_BUSY; | ||
1147 | else | ||
1148 | return -EINVAL; | ||
1149 | |||
1150 | while ((readl_relaxed(CDHIPR) & bm) && --timeout) | ||
1151 | cpu_relax(); | ||
1152 | |||
1153 | if (unlikely(!timeout)) | ||
1154 | return -EBUSY; | ||
1155 | |||
1156 | return 0; | ||
1157 | } | ||
1158 | |||
1159 | static int _clk_set_rate(struct clk *clk, unsigned long rate) | ||
1160 | { | ||
1161 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
1162 | struct divider *d; | ||
1163 | u32 val, div, max_div, pred = 0, podf; | ||
1164 | int i, num; | ||
1165 | |||
1166 | if (clk == &ldb_di0_clk || clk == &ldb_di1_clk) | ||
1167 | return ldb_di_clk_set_rate(clk, rate); | ||
1168 | |||
1169 | num = ARRAY_SIZE(dividers); | ||
1170 | for (i = 0; i < num; i++) | ||
1171 | if (dividers[i]->clk == clk) { | ||
1172 | d = dividers[i]; | ||
1173 | break; | ||
1174 | } | ||
1175 | if (i == num) | ||
1176 | return -EINVAL; | ||
1177 | |||
1178 | max_div = ((d->bm_pred >> d->bp_pred) + 1) * | ||
1179 | ((d->bm_podf >> d->bp_podf) + 1); | ||
1180 | |||
1181 | div = parent_rate / rate; | ||
1182 | if (div == 0) | ||
1183 | div++; | ||
1184 | |||
1185 | if ((parent_rate / div != rate) || div > max_div) | ||
1186 | return -EINVAL; | ||
1187 | |||
1188 | if (d->bm_pred) { | ||
1189 | calc_pred_podf_dividers(div, &pred, &podf); | ||
1190 | } else { | ||
1191 | pred = 1; | ||
1192 | podf = div; | ||
1193 | } | ||
1194 | |||
1195 | val = readl_relaxed(d->reg); | ||
1196 | val &= ~(d->bm_pred | d->bm_podf); | ||
1197 | val |= (pred - 1) << d->bp_pred | (podf - 1) << d->bp_podf; | ||
1198 | writel_relaxed(val, d->reg); | ||
1199 | |||
1200 | if (clk == &axi_clk || clk == &ahb_clk || | ||
1201 | clk == &mmdc_ch0_axi_clk || clk == &arm_clk) | ||
1202 | return clk_busy_wait(clk); | ||
1203 | |||
1204 | return 0; | ||
1205 | } | ||
1206 | |||
1207 | static unsigned long _clk_round_rate(struct clk *clk, unsigned long rate) | ||
1208 | { | ||
1209 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
1210 | u32 div = parent_rate / rate; | ||
1211 | u32 div_max, pred = 0, podf; | ||
1212 | struct divider *d; | ||
1213 | int i, num; | ||
1214 | |||
1215 | if (clk == &ldb_di0_clk || clk == &ldb_di1_clk) | ||
1216 | return ldb_di_clk_round_rate(clk, rate); | ||
1217 | |||
1218 | num = ARRAY_SIZE(dividers); | ||
1219 | for (i = 0; i < num; i++) | ||
1220 | if (dividers[i]->clk == clk) { | ||
1221 | d = dividers[i]; | ||
1222 | break; | ||
1223 | } | ||
1224 | if (i == num) | ||
1225 | return -EINVAL; | ||
1226 | |||
1227 | if (div == 0 || parent_rate % rate) | ||
1228 | div++; | ||
1229 | |||
1230 | if (d->bm_pred) { | ||
1231 | calc_pred_podf_dividers(div, &pred, &podf); | ||
1232 | div = pred * podf; | ||
1233 | } else { | ||
1234 | div_max = (d->bm_podf >> d->bp_podf) + 1; | ||
1235 | if (div > div_max) | ||
1236 | div = div_max; | ||
1237 | } | ||
1238 | |||
1239 | return parent_rate / div; | ||
1240 | } | ||
1241 | |||
1242 | struct multiplexer { | ||
1243 | struct clk *clk; | ||
1244 | void __iomem *reg; | ||
1245 | u32 bp; | ||
1246 | u32 bm; | ||
1247 | int pnum; | ||
1248 | struct clk *parents[]; | ||
1249 | }; | ||
1250 | |||
1251 | static struct multiplexer axi_mux = { | ||
1252 | .clk = &axi_clk, | ||
1253 | .reg = CBCDR, | ||
1254 | .bp = BP_CBCDR_AXI_SEL, | ||
1255 | .bm = BM_CBCDR_AXI_SEL, | ||
1256 | .parents = { | ||
1257 | &periph_clk, | ||
1258 | &pll2_pfd_400m, | ||
1259 | &pll3_pfd_540m, | ||
1260 | NULL | ||
1261 | }, | ||
1262 | }; | ||
1263 | |||
1264 | static struct multiplexer periph_mux = { | ||
1265 | .clk = &periph_clk, | ||
1266 | .reg = CBCDR, | ||
1267 | .bp = BP_CBCDR_PERIPH_CLK_SEL, | ||
1268 | .bm = BM_CBCDR_PERIPH_CLK_SEL, | ||
1269 | .parents = { | ||
1270 | &periph_pre_clk, | ||
1271 | &periph_clk2_clk, | ||
1272 | NULL | ||
1273 | }, | ||
1274 | }; | ||
1275 | |||
1276 | static struct multiplexer periph_pre_mux = { | ||
1277 | .clk = &periph_pre_clk, | ||
1278 | .reg = CBCMR, | ||
1279 | .bp = BP_CBCMR_PRE_PERIPH_CLK_SEL, | ||
1280 | .bm = BM_CBCMR_PRE_PERIPH_CLK_SEL, | ||
1281 | .parents = { | ||
1282 | &pll2_bus, | ||
1283 | &pll2_pfd_400m, | ||
1284 | &pll2_pfd_352m, | ||
1285 | &pll2_200m, | ||
1286 | NULL | ||
1287 | }, | ||
1288 | }; | ||
1289 | |||
1290 | static struct multiplexer periph_clk2_mux = { | ||
1291 | .clk = &periph_clk2_clk, | ||
1292 | .reg = CBCMR, | ||
1293 | .bp = BP_CBCMR_PERIPH_CLK2_SEL, | ||
1294 | .bm = BM_CBCMR_PERIPH_CLK2_SEL, | ||
1295 | .parents = { | ||
1296 | &pll3_usb_otg, | ||
1297 | &osc_clk, | ||
1298 | NULL | ||
1299 | }, | ||
1300 | }; | ||
1301 | |||
1302 | static struct multiplexer periph2_mux = { | ||
1303 | .clk = &periph2_clk, | ||
1304 | .reg = CBCDR, | ||
1305 | .bp = BP_CBCDR_PERIPH2_CLK_SEL, | ||
1306 | .bm = BM_CBCDR_PERIPH2_CLK_SEL, | ||
1307 | .parents = { | ||
1308 | &periph2_pre_clk, | ||
1309 | &periph2_clk2_clk, | ||
1310 | NULL | ||
1311 | }, | ||
1312 | }; | ||
1313 | |||
1314 | static struct multiplexer periph2_pre_mux = { | ||
1315 | .clk = &periph2_pre_clk, | ||
1316 | .reg = CBCMR, | ||
1317 | .bp = BP_CBCMR_PRE_PERIPH2_CLK_SEL, | ||
1318 | .bm = BM_CBCMR_PRE_PERIPH2_CLK_SEL, | ||
1319 | .parents = { | ||
1320 | &pll2_bus, | ||
1321 | &pll2_pfd_400m, | ||
1322 | &pll2_pfd_352m, | ||
1323 | &pll2_200m, | ||
1324 | NULL | ||
1325 | }, | ||
1326 | }; | ||
1327 | |||
1328 | static struct multiplexer periph2_clk2_mux = { | ||
1329 | .clk = &periph2_clk2_clk, | ||
1330 | .reg = CBCMR, | ||
1331 | .bp = BP_CBCMR_PERIPH2_CLK2_SEL, | ||
1332 | .bm = BM_CBCMR_PERIPH2_CLK2_SEL, | ||
1333 | .parents = { | ||
1334 | &pll3_usb_otg, | ||
1335 | &osc_clk, | ||
1336 | NULL | ||
1337 | }, | ||
1338 | }; | ||
1339 | |||
1340 | static struct multiplexer gpu2d_axi_mux = { | ||
1341 | .clk = &gpu2d_axi_clk, | ||
1342 | .reg = CBCMR, | ||
1343 | .bp = BP_CBCMR_GPU2D_AXI_SEL, | ||
1344 | .bm = BM_CBCMR_GPU2D_AXI_SEL, | ||
1345 | .parents = { | ||
1346 | &axi_clk, | ||
1347 | &ahb_clk, | ||
1348 | NULL | ||
1349 | }, | ||
1350 | }; | ||
1351 | |||
1352 | static struct multiplexer gpu3d_axi_mux = { | ||
1353 | .clk = &gpu3d_axi_clk, | ||
1354 | .reg = CBCMR, | ||
1355 | .bp = BP_CBCMR_GPU3D_AXI_SEL, | ||
1356 | .bm = BM_CBCMR_GPU3D_AXI_SEL, | ||
1357 | .parents = { | ||
1358 | &axi_clk, | ||
1359 | &ahb_clk, | ||
1360 | NULL | ||
1361 | }, | ||
1362 | }; | ||
1363 | |||
1364 | static struct multiplexer gpu3d_core_mux = { | ||
1365 | .clk = &gpu3d_core_clk, | ||
1366 | .reg = CBCMR, | ||
1367 | .bp = BP_CBCMR_GPU3D_CORE_SEL, | ||
1368 | .bm = BM_CBCMR_GPU3D_CORE_SEL, | ||
1369 | .parents = { | ||
1370 | &mmdc_ch0_axi_clk, | ||
1371 | &pll3_usb_otg, | ||
1372 | &pll2_pfd_594m, | ||
1373 | &pll2_pfd_400m, | ||
1374 | NULL | ||
1375 | }, | ||
1376 | }; | ||
1377 | |||
1378 | static struct multiplexer gpu3d_shader_mux = { | ||
1379 | .clk = &gpu3d_shader_clk, | ||
1380 | .reg = CBCMR, | ||
1381 | .bp = BP_CBCMR_GPU3D_SHADER_SEL, | ||
1382 | .bm = BM_CBCMR_GPU3D_SHADER_SEL, | ||
1383 | .parents = { | ||
1384 | &mmdc_ch0_axi_clk, | ||
1385 | &pll3_usb_otg, | ||
1386 | &pll2_pfd_594m, | ||
1387 | &pll3_pfd_720m, | ||
1388 | NULL | ||
1389 | }, | ||
1390 | }; | ||
1391 | |||
1392 | static struct multiplexer pcie_axi_mux = { | ||
1393 | .clk = &pcie_clk, | ||
1394 | .reg = CBCMR, | ||
1395 | .bp = BP_CBCMR_PCIE_AXI_SEL, | ||
1396 | .bm = BM_CBCMR_PCIE_AXI_SEL, | ||
1397 | .parents = { | ||
1398 | &axi_clk, | ||
1399 | &ahb_clk, | ||
1400 | NULL | ||
1401 | }, | ||
1402 | }; | ||
1403 | |||
1404 | static struct multiplexer vdo_axi_mux = { | ||
1405 | .clk = &vdo_axi_clk, | ||
1406 | .reg = CBCMR, | ||
1407 | .bp = BP_CBCMR_VDO_AXI_SEL, | ||
1408 | .bm = BM_CBCMR_VDO_AXI_SEL, | ||
1409 | .parents = { | ||
1410 | &axi_clk, | ||
1411 | &ahb_clk, | ||
1412 | NULL | ||
1413 | }, | ||
1414 | }; | ||
1415 | |||
1416 | static struct multiplexer vpu_axi_mux = { | ||
1417 | .clk = &vpu_clk, | ||
1418 | .reg = CBCMR, | ||
1419 | .bp = BP_CBCMR_VPU_AXI_SEL, | ||
1420 | .bm = BM_CBCMR_VPU_AXI_SEL, | ||
1421 | .parents = { | ||
1422 | &axi_clk, | ||
1423 | &pll2_pfd_400m, | ||
1424 | &pll2_pfd_352m, | ||
1425 | NULL | ||
1426 | }, | ||
1427 | }; | ||
1428 | |||
1429 | static struct multiplexer gpu2d_core_mux = { | ||
1430 | .clk = &gpu2d_core_clk, | ||
1431 | .reg = CBCMR, | ||
1432 | .bp = BP_CBCMR_GPU2D_CORE_SEL, | ||
1433 | .bm = BM_CBCMR_GPU2D_CORE_SEL, | ||
1434 | .parents = { | ||
1435 | &axi_clk, | ||
1436 | &pll3_usb_otg, | ||
1437 | &pll2_pfd_352m, | ||
1438 | &pll2_pfd_400m, | ||
1439 | NULL | ||
1440 | }, | ||
1441 | }; | ||
1442 | |||
1443 | #define DEF_SSI_MUX(id) \ | ||
1444 | static struct multiplexer ssi##id##_mux = { \ | ||
1445 | .clk = &ssi##id##_clk, \ | ||
1446 | .reg = CSCMR1, \ | ||
1447 | .bp = BP_CSCMR1_SSI##id##_SEL, \ | ||
1448 | .bm = BM_CSCMR1_SSI##id##_SEL, \ | ||
1449 | .parents = { \ | ||
1450 | &pll3_pfd_508m, \ | ||
1451 | &pll3_pfd_454m, \ | ||
1452 | &pll4_audio, \ | ||
1453 | NULL \ | ||
1454 | }, \ | ||
1455 | } | ||
1456 | |||
1457 | DEF_SSI_MUX(1); | ||
1458 | DEF_SSI_MUX(2); | ||
1459 | DEF_SSI_MUX(3); | ||
1460 | |||
1461 | #define DEF_USDHC_MUX(id) \ | ||
1462 | static struct multiplexer usdhc##id##_mux = { \ | ||
1463 | .clk = &usdhc##id##_clk, \ | ||
1464 | .reg = CSCMR1, \ | ||
1465 | .bp = BP_CSCMR1_USDHC##id##_SEL, \ | ||
1466 | .bm = BM_CSCMR1_USDHC##id##_SEL, \ | ||
1467 | .parents = { \ | ||
1468 | &pll2_pfd_400m, \ | ||
1469 | &pll2_pfd_352m, \ | ||
1470 | NULL \ | ||
1471 | }, \ | ||
1472 | } | ||
1473 | |||
1474 | DEF_USDHC_MUX(1); | ||
1475 | DEF_USDHC_MUX(2); | ||
1476 | DEF_USDHC_MUX(3); | ||
1477 | DEF_USDHC_MUX(4); | ||
1478 | |||
1479 | static struct multiplexer emi_mux = { | ||
1480 | .clk = &emi_clk, | ||
1481 | .reg = CSCMR1, | ||
1482 | .bp = BP_CSCMR1_EMI_SEL, | ||
1483 | .bm = BM_CSCMR1_EMI_SEL, | ||
1484 | .parents = { | ||
1485 | &axi_clk, | ||
1486 | &pll3_usb_otg, | ||
1487 | &pll2_pfd_400m, | ||
1488 | &pll2_pfd_352m, | ||
1489 | NULL | ||
1490 | }, | ||
1491 | }; | ||
1492 | |||
1493 | static struct multiplexer emi_slow_mux = { | ||
1494 | .clk = &emi_slow_clk, | ||
1495 | .reg = CSCMR1, | ||
1496 | .bp = BP_CSCMR1_EMI_SLOW_SEL, | ||
1497 | .bm = BM_CSCMR1_EMI_SLOW_SEL, | ||
1498 | .parents = { | ||
1499 | &axi_clk, | ||
1500 | &pll3_usb_otg, | ||
1501 | &pll2_pfd_400m, | ||
1502 | &pll2_pfd_352m, | ||
1503 | NULL | ||
1504 | }, | ||
1505 | }; | ||
1506 | |||
1507 | static struct multiplexer esai_mux = { | ||
1508 | .clk = &esai_clk, | ||
1509 | .reg = CSCMR2, | ||
1510 | .bp = BP_CSCMR2_ESAI_SEL, | ||
1511 | .bm = BM_CSCMR2_ESAI_SEL, | ||
1512 | .parents = { | ||
1513 | &pll4_audio, | ||
1514 | &pll3_pfd_508m, | ||
1515 | &pll3_pfd_454m, | ||
1516 | &pll3_usb_otg, | ||
1517 | NULL | ||
1518 | }, | ||
1519 | }; | ||
1520 | |||
1521 | #define DEF_LDB_DI_MUX(id) \ | ||
1522 | static struct multiplexer ldb_di##id##_mux = { \ | ||
1523 | .clk = &ldb_di##id##_clk, \ | ||
1524 | .reg = CS2CDR, \ | ||
1525 | .bp = BP_CS2CDR_LDB_DI##id##_SEL, \ | ||
1526 | .bm = BM_CS2CDR_LDB_DI##id##_SEL, \ | ||
1527 | .parents = { \ | ||
1528 | &pll5_video, \ | ||
1529 | &pll2_pfd_352m, \ | ||
1530 | &pll2_pfd_400m, \ | ||
1531 | &pll3_pfd_540m, \ | ||
1532 | &pll3_usb_otg, \ | ||
1533 | NULL \ | ||
1534 | }, \ | ||
1535 | } | ||
1536 | |||
1537 | DEF_LDB_DI_MUX(0); | ||
1538 | DEF_LDB_DI_MUX(1); | ||
1539 | |||
1540 | static struct multiplexer enfc_mux = { | ||
1541 | .clk = &enfc_clk, | ||
1542 | .reg = CS2CDR, | ||
1543 | .bp = BP_CS2CDR_ENFC_SEL, | ||
1544 | .bm = BM_CS2CDR_ENFC_SEL, | ||
1545 | .parents = { | ||
1546 | &pll2_pfd_352m, | ||
1547 | &pll2_bus, | ||
1548 | &pll3_usb_otg, | ||
1549 | &pll2_pfd_400m, | ||
1550 | NULL | ||
1551 | }, | ||
1552 | }; | ||
1553 | |||
1554 | static struct multiplexer spdif_mux = { | ||
1555 | .clk = &spdif_clk, | ||
1556 | .reg = CDCDR, | ||
1557 | .bp = BP_CDCDR_SPDIF_SEL, | ||
1558 | .bm = BM_CDCDR_SPDIF_SEL, | ||
1559 | .parents = { | ||
1560 | &pll4_audio, | ||
1561 | &pll3_pfd_508m, | ||
1562 | &pll3_pfd_454m, | ||
1563 | &pll3_usb_otg, | ||
1564 | NULL | ||
1565 | }, | ||
1566 | }; | ||
1567 | |||
1568 | static struct multiplexer asrc_serial_mux = { | ||
1569 | .clk = &asrc_serial_clk, | ||
1570 | .reg = CDCDR, | ||
1571 | .bp = BP_CDCDR_ASRC_SERIAL_SEL, | ||
1572 | .bm = BM_CDCDR_ASRC_SERIAL_SEL, | ||
1573 | .parents = { | ||
1574 | &pll4_audio, | ||
1575 | &pll3_pfd_508m, | ||
1576 | &pll3_pfd_454m, | ||
1577 | &pll3_usb_otg, | ||
1578 | NULL | ||
1579 | }, | ||
1580 | }; | ||
1581 | |||
1582 | static struct multiplexer hsi_tx_mux = { | ||
1583 | .clk = &hsi_tx_clk, | ||
1584 | .reg = CDCDR, | ||
1585 | .bp = BP_CDCDR_HSI_TX_SEL, | ||
1586 | .bm = BM_CDCDR_HSI_TX_SEL, | ||
1587 | .parents = { | ||
1588 | &pll3_120m, | ||
1589 | &pll2_pfd_400m, | ||
1590 | NULL | ||
1591 | }, | ||
1592 | }; | ||
1593 | |||
1594 | #define DEF_IPU_DI_PRE_MUX(r, i, d) \ | ||
1595 | static struct multiplexer ipu##i##_di##d##_pre_mux = { \ | ||
1596 | .clk = &ipu##i##_di##d##_pre_clk, \ | ||
1597 | .reg = r, \ | ||
1598 | .bp = BP_##r##_IPU##i##_DI##d##_PRE_SEL, \ | ||
1599 | .bm = BM_##r##_IPU##i##_DI##d##_PRE_SEL, \ | ||
1600 | .parents = { \ | ||
1601 | &mmdc_ch0_axi_clk, \ | ||
1602 | &pll3_usb_otg, \ | ||
1603 | &pll5_video, \ | ||
1604 | &pll2_pfd_352m, \ | ||
1605 | &pll2_pfd_400m, \ | ||
1606 | &pll3_pfd_540m, \ | ||
1607 | NULL \ | ||
1608 | }, \ | ||
1609 | } | ||
1610 | |||
1611 | DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 0); | ||
1612 | DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 1); | ||
1613 | DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 0); | ||
1614 | DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 1); | ||
1615 | |||
1616 | #define DEF_IPU_DI_MUX(r, i, d) \ | ||
1617 | static struct multiplexer ipu##i##_di##d##_mux = { \ | ||
1618 | .clk = &ipu##i##_di##d##_clk, \ | ||
1619 | .reg = r, \ | ||
1620 | .bp = BP_##r##_IPU##i##_DI##d##_SEL, \ | ||
1621 | .bm = BM_##r##_IPU##i##_DI##d##_SEL, \ | ||
1622 | .parents = { \ | ||
1623 | &ipu##i##_di##d##_pre_clk, \ | ||
1624 | &dummy_clk, \ | ||
1625 | &dummy_clk, \ | ||
1626 | &ldb_di0_clk, \ | ||
1627 | &ldb_di1_clk, \ | ||
1628 | NULL \ | ||
1629 | }, \ | ||
1630 | } | ||
1631 | |||
1632 | DEF_IPU_DI_MUX(CHSCCDR, 1, 0); | ||
1633 | DEF_IPU_DI_MUX(CHSCCDR, 1, 1); | ||
1634 | DEF_IPU_DI_MUX(CSCDR2, 2, 0); | ||
1635 | DEF_IPU_DI_MUX(CSCDR2, 2, 1); | ||
1636 | |||
1637 | #define DEF_IPU_MUX(id) \ | ||
1638 | static struct multiplexer ipu##id##_mux = { \ | ||
1639 | .clk = &ipu##id##_clk, \ | ||
1640 | .reg = CSCDR3, \ | ||
1641 | .bp = BP_CSCDR3_IPU##id##_HSP_SEL, \ | ||
1642 | .bm = BM_CSCDR3_IPU##id##_HSP_SEL, \ | ||
1643 | .parents = { \ | ||
1644 | &mmdc_ch0_axi_clk, \ | ||
1645 | &pll2_pfd_400m, \ | ||
1646 | &pll3_120m, \ | ||
1647 | &pll3_pfd_540m, \ | ||
1648 | NULL \ | ||
1649 | }, \ | ||
1650 | } | ||
1651 | |||
1652 | DEF_IPU_MUX(1); | ||
1653 | DEF_IPU_MUX(2); | ||
1654 | |||
1655 | static struct multiplexer cko1_mux = { | ||
1656 | .clk = &cko1_clk, | ||
1657 | .reg = CCOSR, | ||
1658 | .bp = BP_CCOSR_CKO1_SEL, | ||
1659 | .bm = BM_CCOSR_CKO1_SEL, | ||
1660 | .parents = { | ||
1661 | &pll3_usb_otg, | ||
1662 | &pll2_bus, | ||
1663 | &pll1_sys, | ||
1664 | &pll5_video, | ||
1665 | &dummy_clk, | ||
1666 | &axi_clk, | ||
1667 | &enfc_clk, | ||
1668 | &ipu1_di0_clk, | ||
1669 | &ipu1_di1_clk, | ||
1670 | &ipu2_di0_clk, | ||
1671 | &ipu2_di1_clk, | ||
1672 | &ahb_clk, | ||
1673 | &ipg_clk, | ||
1674 | &ipg_perclk, | ||
1675 | &ckil_clk, | ||
1676 | &pll4_audio, | ||
1677 | NULL | ||
1678 | }, | ||
1679 | }; | ||
1680 | |||
1681 | static struct multiplexer *multiplexers[] = { | ||
1682 | &axi_mux, | ||
1683 | &periph_mux, | ||
1684 | &periph_pre_mux, | ||
1685 | &periph_clk2_mux, | ||
1686 | &periph2_mux, | ||
1687 | &periph2_pre_mux, | ||
1688 | &periph2_clk2_mux, | ||
1689 | &gpu2d_axi_mux, | ||
1690 | &gpu3d_axi_mux, | ||
1691 | &gpu3d_core_mux, | ||
1692 | &gpu3d_shader_mux, | ||
1693 | &pcie_axi_mux, | ||
1694 | &vdo_axi_mux, | ||
1695 | &vpu_axi_mux, | ||
1696 | &gpu2d_core_mux, | ||
1697 | &ssi1_mux, | ||
1698 | &ssi2_mux, | ||
1699 | &ssi3_mux, | ||
1700 | &usdhc1_mux, | ||
1701 | &usdhc2_mux, | ||
1702 | &usdhc3_mux, | ||
1703 | &usdhc4_mux, | ||
1704 | &emi_mux, | ||
1705 | &emi_slow_mux, | ||
1706 | &esai_mux, | ||
1707 | &ldb_di0_mux, | ||
1708 | &ldb_di1_mux, | ||
1709 | &enfc_mux, | ||
1710 | &spdif_mux, | ||
1711 | &asrc_serial_mux, | ||
1712 | &hsi_tx_mux, | ||
1713 | &ipu1_di0_pre_mux, | ||
1714 | &ipu1_di0_mux, | ||
1715 | &ipu1_di1_pre_mux, | ||
1716 | &ipu1_di1_mux, | ||
1717 | &ipu2_di0_pre_mux, | ||
1718 | &ipu2_di0_mux, | ||
1719 | &ipu2_di1_pre_mux, | ||
1720 | &ipu2_di1_mux, | ||
1721 | &ipu1_mux, | ||
1722 | &ipu2_mux, | ||
1723 | &cko1_mux, | ||
1724 | }; | ||
1725 | |||
1726 | static int _clk_set_parent(struct clk *clk, struct clk *parent) | ||
1727 | { | ||
1728 | struct multiplexer *m; | ||
1729 | int i, num; | ||
1730 | u32 val; | ||
1731 | |||
1732 | num = ARRAY_SIZE(multiplexers); | ||
1733 | for (i = 0; i < num; i++) | ||
1734 | if (multiplexers[i]->clk == clk) { | ||
1735 | m = multiplexers[i]; | ||
1736 | break; | ||
1737 | } | ||
1738 | if (i == num) | ||
1739 | return -EINVAL; | ||
1740 | |||
1741 | i = 0; | ||
1742 | while (m->parents[i]) { | ||
1743 | if (parent == m->parents[i]) | ||
1744 | break; | ||
1745 | i++; | ||
1746 | } | ||
1747 | if (!m->parents[i] || m->parents[i] == &dummy_clk) | ||
1748 | return -EINVAL; | ||
1749 | |||
1750 | val = readl_relaxed(m->reg); | ||
1751 | val &= ~m->bm; | ||
1752 | val |= i << m->bp; | ||
1753 | writel_relaxed(val, m->reg); | ||
1754 | |||
1755 | if (clk == &periph_clk) | ||
1756 | return clk_busy_wait(clk); | ||
1757 | |||
1758 | return 0; | ||
1759 | } | ||
1760 | |||
1761 | #define DEF_NG_CLK(name, p) \ | ||
1762 | static struct clk name = { \ | ||
1763 | .get_rate = _clk_get_rate, \ | ||
1764 | .set_rate = _clk_set_rate, \ | ||
1765 | .round_rate = _clk_round_rate, \ | ||
1766 | .set_parent = _clk_set_parent, \ | ||
1767 | .parent = p, \ | ||
1768 | } | ||
1769 | |||
1770 | DEF_NG_CLK(periph_clk2_clk, &osc_clk); | ||
1771 | DEF_NG_CLK(periph_pre_clk, &pll2_bus); | ||
1772 | DEF_NG_CLK(periph_clk, &periph_pre_clk); | ||
1773 | DEF_NG_CLK(periph2_clk2_clk, &osc_clk); | ||
1774 | DEF_NG_CLK(periph2_pre_clk, &pll2_bus); | ||
1775 | DEF_NG_CLK(periph2_clk, &periph2_pre_clk); | ||
1776 | DEF_NG_CLK(axi_clk, &periph_clk); | ||
1777 | DEF_NG_CLK(emi_clk, &axi_clk); | ||
1778 | DEF_NG_CLK(arm_clk, &pll1_sw_clk); | ||
1779 | DEF_NG_CLK(ahb_clk, &periph_clk); | ||
1780 | DEF_NG_CLK(ipg_clk, &ahb_clk); | ||
1781 | DEF_NG_CLK(ipg_perclk, &ipg_clk); | ||
1782 | DEF_NG_CLK(ipu1_di0_pre_clk, &pll3_pfd_540m); | ||
1783 | DEF_NG_CLK(ipu1_di1_pre_clk, &pll3_pfd_540m); | ||
1784 | DEF_NG_CLK(ipu2_di0_pre_clk, &pll3_pfd_540m); | ||
1785 | DEF_NG_CLK(ipu2_di1_pre_clk, &pll3_pfd_540m); | ||
1786 | DEF_NG_CLK(asrc_serial_clk, &pll3_usb_otg); | ||
1787 | |||
1788 | #define DEF_CLK(name, er, es, p, s) \ | ||
1789 | static struct clk name = { \ | ||
1790 | .enable_reg = er, \ | ||
1791 | .enable_shift = es, \ | ||
1792 | .enable = _clk_enable, \ | ||
1793 | .disable = _clk_disable, \ | ||
1794 | .get_rate = _clk_get_rate, \ | ||
1795 | .set_rate = _clk_set_rate, \ | ||
1796 | .round_rate = _clk_round_rate, \ | ||
1797 | .set_parent = _clk_set_parent, \ | ||
1798 | .parent = p, \ | ||
1799 | .secondary = s, \ | ||
1800 | } | ||
1801 | |||
1802 | #define DEF_CLK_1B(name, er, es, p, s) \ | ||
1803 | static struct clk name = { \ | ||
1804 | .enable_reg = er, \ | ||
1805 | .enable_shift = es, \ | ||
1806 | .enable = _clk_enable_1b, \ | ||
1807 | .disable = _clk_disable_1b, \ | ||
1808 | .get_rate = _clk_get_rate, \ | ||
1809 | .set_rate = _clk_set_rate, \ | ||
1810 | .round_rate = _clk_round_rate, \ | ||
1811 | .set_parent = _clk_set_parent, \ | ||
1812 | .parent = p, \ | ||
1813 | .secondary = s, \ | ||
1814 | } | ||
1815 | |||
1816 | DEF_CLK(aips_tz1_clk, CCGR0, CG0, &ahb_clk, NULL); | ||
1817 | DEF_CLK(aips_tz2_clk, CCGR0, CG1, &ahb_clk, NULL); | ||
1818 | DEF_CLK(apbh_dma_clk, CCGR0, CG2, &ahb_clk, NULL); | ||
1819 | DEF_CLK(asrc_clk, CCGR0, CG3, &pll4_audio, NULL); | ||
1820 | DEF_CLK(can1_serial_clk, CCGR0, CG8, &pll3_usb_otg, NULL); | ||
1821 | DEF_CLK(can1_clk, CCGR0, CG7, &pll3_usb_otg, &can1_serial_clk); | ||
1822 | DEF_CLK(can2_serial_clk, CCGR0, CG10, &pll3_usb_otg, NULL); | ||
1823 | DEF_CLK(can2_clk, CCGR0, CG9, &pll3_usb_otg, &can2_serial_clk); | ||
1824 | DEF_CLK(ecspi1_clk, CCGR1, CG0, &pll3_60m, NULL); | ||
1825 | DEF_CLK(ecspi2_clk, CCGR1, CG1, &pll3_60m, NULL); | ||
1826 | DEF_CLK(ecspi3_clk, CCGR1, CG2, &pll3_60m, NULL); | ||
1827 | DEF_CLK(ecspi4_clk, CCGR1, CG3, &pll3_60m, NULL); | ||
1828 | DEF_CLK(ecspi5_clk, CCGR1, CG4, &pll3_60m, NULL); | ||
1829 | DEF_CLK(enet_clk, CCGR1, CG5, &ipg_clk, NULL); | ||
1830 | DEF_CLK(esai_clk, CCGR1, CG8, &pll3_usb_otg, NULL); | ||
1831 | DEF_CLK(gpt_serial_clk, CCGR1, CG11, &ipg_perclk, NULL); | ||
1832 | DEF_CLK(gpt_clk, CCGR1, CG10, &ipg_perclk, &gpt_serial_clk); | ||
1833 | DEF_CLK(gpu2d_core_clk, CCGR1, CG12, &pll2_pfd_352m, &gpu2d_axi_clk); | ||
1834 | DEF_CLK(gpu3d_core_clk, CCGR1, CG13, &pll2_pfd_594m, &gpu3d_axi_clk); | ||
1835 | DEF_CLK(gpu3d_shader_clk, CCGR1, CG13, &pll3_pfd_720m, &gpu3d_axi_clk); | ||
1836 | DEF_CLK(hdmi_iahb_clk, CCGR2, CG0, &ahb_clk, NULL); | ||
1837 | DEF_CLK(hdmi_isfr_clk, CCGR2, CG2, &pll3_pfd_540m, &hdmi_iahb_clk); | ||
1838 | DEF_CLK(i2c1_clk, CCGR2, CG3, &ipg_perclk, NULL); | ||
1839 | DEF_CLK(i2c2_clk, CCGR2, CG4, &ipg_perclk, NULL); | ||
1840 | DEF_CLK(i2c3_clk, CCGR2, CG5, &ipg_perclk, NULL); | ||
1841 | DEF_CLK(iim_clk, CCGR2, CG6, &ipg_clk, NULL); | ||
1842 | DEF_CLK(enfc_clk, CCGR2, CG7, &pll2_pfd_352m, NULL); | ||
1843 | DEF_CLK(ipu1_clk, CCGR3, CG0, &mmdc_ch0_axi_clk, NULL); | ||
1844 | DEF_CLK(ipu1_di0_clk, CCGR3, CG1, &ipu1_di0_pre_clk, NULL); | ||
1845 | DEF_CLK(ipu1_di1_clk, CCGR3, CG2, &ipu1_di1_pre_clk, NULL); | ||
1846 | DEF_CLK(ipu2_clk, CCGR3, CG3, &mmdc_ch0_axi_clk, NULL); | ||
1847 | DEF_CLK(ipu2_di0_clk, CCGR3, CG4, &ipu2_di0_pre_clk, NULL); | ||
1848 | DEF_CLK(ipu2_di1_clk, CCGR3, CG5, &ipu2_di1_pre_clk, NULL); | ||
1849 | DEF_CLK(ldb_di0_clk, CCGR3, CG6, &pll3_pfd_540m, NULL); | ||
1850 | DEF_CLK(ldb_di1_clk, CCGR3, CG7, &pll3_pfd_540m, NULL); | ||
1851 | DEF_CLK(hsi_tx_clk, CCGR3, CG8, &pll2_pfd_400m, NULL); | ||
1852 | DEF_CLK(mlb_clk, CCGR3, CG9, &pll6_mlb, NULL); | ||
1853 | DEF_CLK(mmdc_ch0_ipg_clk, CCGR3, CG12, &ipg_clk, NULL); | ||
1854 | DEF_CLK(mmdc_ch0_axi_clk, CCGR3, CG10, &periph_clk, &mmdc_ch0_ipg_clk); | ||
1855 | DEF_CLK(mmdc_ch1_ipg_clk, CCGR3, CG13, &ipg_clk, NULL); | ||
1856 | DEF_CLK(mmdc_ch1_axi_clk, CCGR3, CG11, &periph2_clk, &mmdc_ch1_ipg_clk); | ||
1857 | DEF_CLK(openvg_axi_clk, CCGR3, CG13, &axi_clk, NULL); | ||
1858 | DEF_CLK(pwm1_clk, CCGR4, CG8, &ipg_perclk, NULL); | ||
1859 | DEF_CLK(pwm2_clk, CCGR4, CG9, &ipg_perclk, NULL); | ||
1860 | DEF_CLK(pwm3_clk, CCGR4, CG10, &ipg_perclk, NULL); | ||
1861 | DEF_CLK(pwm4_clk, CCGR4, CG11, &ipg_perclk, NULL); | ||
1862 | DEF_CLK(gpmi_bch_apb_clk, CCGR4, CG12, &usdhc3_clk, NULL); | ||
1863 | DEF_CLK(gpmi_bch_clk, CCGR4, CG13, &usdhc4_clk, &gpmi_bch_apb_clk); | ||
1864 | DEF_CLK(gpmi_apb_clk, CCGR4, CG15, &usdhc3_clk, &gpmi_bch_clk); | ||
1865 | DEF_CLK(gpmi_io_clk, CCGR4, CG14, &enfc_clk, &gpmi_apb_clk); | ||
1866 | DEF_CLK(sdma_clk, CCGR5, CG3, &ahb_clk, NULL); | ||
1867 | DEF_CLK(spba_clk, CCGR5, CG6, &ipg_clk, NULL); | ||
1868 | DEF_CLK(spdif_clk, CCGR5, CG7, &pll3_usb_otg, &spba_clk); | ||
1869 | DEF_CLK(ssi1_clk, CCGR5, CG9, &pll3_pfd_508m, NULL); | ||
1870 | DEF_CLK(ssi2_clk, CCGR5, CG10, &pll3_pfd_508m, NULL); | ||
1871 | DEF_CLK(ssi3_clk, CCGR5, CG11, &pll3_pfd_508m, NULL); | ||
1872 | DEF_CLK(uart_serial_clk, CCGR5, CG13, &pll3_usb_otg, NULL); | ||
1873 | DEF_CLK(uart_clk, CCGR5, CG12, &pll3_80m, &uart_serial_clk); | ||
1874 | DEF_CLK(usboh3_clk, CCGR6, CG0, &ipg_clk, NULL); | ||
1875 | DEF_CLK(usdhc1_clk, CCGR6, CG1, &pll2_pfd_400m, NULL); | ||
1876 | DEF_CLK(usdhc2_clk, CCGR6, CG2, &pll2_pfd_400m, NULL); | ||
1877 | DEF_CLK(usdhc3_clk, CCGR6, CG3, &pll2_pfd_400m, NULL); | ||
1878 | DEF_CLK(usdhc4_clk, CCGR6, CG4, &pll2_pfd_400m, NULL); | ||
1879 | DEF_CLK(emi_slow_clk, CCGR6, CG5, &axi_clk, NULL); | ||
1880 | DEF_CLK(vdo_axi_clk, CCGR6, CG6, &axi_clk, NULL); | ||
1881 | DEF_CLK(vpu_clk, CCGR6, CG7, &axi_clk, NULL); | ||
1882 | DEF_CLK_1B(cko1_clk, CCOSR, BP_CCOSR_CKO1_EN, &pll2_bus, NULL); | ||
1883 | |||
1884 | static int pcie_clk_enable(struct clk *clk) | ||
1885 | { | ||
1886 | u32 val; | ||
1887 | |||
1888 | val = readl_relaxed(PLL8_ENET); | ||
1889 | val |= BM_PLL_ENET_EN_PCIE; | ||
1890 | writel_relaxed(val, PLL8_ENET); | ||
1891 | |||
1892 | return _clk_enable(clk); | ||
1893 | } | ||
1894 | |||
1895 | static void pcie_clk_disable(struct clk *clk) | ||
1896 | { | ||
1897 | u32 val; | ||
1898 | |||
1899 | _clk_disable(clk); | ||
1900 | |||
1901 | val = readl_relaxed(PLL8_ENET); | ||
1902 | val &= BM_PLL_ENET_EN_PCIE; | ||
1903 | writel_relaxed(val, PLL8_ENET); | ||
1904 | } | ||
1905 | |||
1906 | static struct clk pcie_clk = { | ||
1907 | .enable_reg = CCGR4, | ||
1908 | .enable_shift = CG0, | ||
1909 | .enable = pcie_clk_enable, | ||
1910 | .disable = pcie_clk_disable, | ||
1911 | .set_parent = _clk_set_parent, | ||
1912 | .parent = &axi_clk, | ||
1913 | .secondary = &pll8_enet, | ||
1914 | }; | ||
1915 | |||
1916 | static int sata_clk_enable(struct clk *clk) | ||
1917 | { | ||
1918 | u32 val; | ||
1919 | |||
1920 | val = readl_relaxed(PLL8_ENET); | ||
1921 | val |= BM_PLL_ENET_EN_SATA; | ||
1922 | writel_relaxed(val, PLL8_ENET); | ||
1923 | |||
1924 | return _clk_enable(clk); | ||
1925 | } | ||
1926 | |||
1927 | static void sata_clk_disable(struct clk *clk) | ||
1928 | { | ||
1929 | u32 val; | ||
1930 | |||
1931 | _clk_disable(clk); | ||
1932 | |||
1933 | val = readl_relaxed(PLL8_ENET); | ||
1934 | val &= BM_PLL_ENET_EN_SATA; | ||
1935 | writel_relaxed(val, PLL8_ENET); | ||
1936 | } | ||
1937 | |||
1938 | static struct clk sata_clk = { | ||
1939 | .enable_reg = CCGR5, | ||
1940 | .enable_shift = CG2, | ||
1941 | .enable = sata_clk_enable, | ||
1942 | .disable = sata_clk_disable, | ||
1943 | .parent = &ipg_clk, | ||
1944 | .secondary = &pll8_enet, | ||
1945 | }; | ||
1946 | |||
1947 | #define _REGISTER_CLOCK(d, n, c) \ | ||
1948 | { \ | ||
1949 | .dev_id = d, \ | ||
1950 | .con_id = n, \ | ||
1951 | .clk = &c, \ | ||
1952 | } | ||
1953 | |||
1954 | static struct clk_lookup lookups[] = { | ||
1955 | _REGISTER_CLOCK("2020000.uart", NULL, uart_clk), | ||
1956 | _REGISTER_CLOCK("21e8000.uart", NULL, uart_clk), | ||
1957 | _REGISTER_CLOCK("21ec000.uart", NULL, uart_clk), | ||
1958 | _REGISTER_CLOCK("21f0000.uart", NULL, uart_clk), | ||
1959 | _REGISTER_CLOCK("21f4000.uart", NULL, uart_clk), | ||
1960 | _REGISTER_CLOCK("2188000.enet", NULL, enet_clk), | ||
1961 | _REGISTER_CLOCK("2190000.usdhc", NULL, usdhc1_clk), | ||
1962 | _REGISTER_CLOCK("2194000.usdhc", NULL, usdhc2_clk), | ||
1963 | _REGISTER_CLOCK("2198000.usdhc", NULL, usdhc3_clk), | ||
1964 | _REGISTER_CLOCK("219c000.usdhc", NULL, usdhc4_clk), | ||
1965 | _REGISTER_CLOCK("21a0000.i2c", NULL, i2c1_clk), | ||
1966 | _REGISTER_CLOCK("21a4000.i2c", NULL, i2c2_clk), | ||
1967 | _REGISTER_CLOCK("21a8000.i2c", NULL, i2c3_clk), | ||
1968 | _REGISTER_CLOCK("2008000.ecspi", NULL, ecspi1_clk), | ||
1969 | _REGISTER_CLOCK("200c000.ecspi", NULL, ecspi2_clk), | ||
1970 | _REGISTER_CLOCK("2010000.ecspi", NULL, ecspi3_clk), | ||
1971 | _REGISTER_CLOCK("2014000.ecspi", NULL, ecspi4_clk), | ||
1972 | _REGISTER_CLOCK("2018000.ecspi", NULL, ecspi5_clk), | ||
1973 | _REGISTER_CLOCK("20ec000.sdma", NULL, sdma_clk), | ||
1974 | _REGISTER_CLOCK("20bc000.wdog", NULL, dummy_clk), | ||
1975 | _REGISTER_CLOCK("20c0000.wdog", NULL, dummy_clk), | ||
1976 | _REGISTER_CLOCK("smp_twd", NULL, twd_clk), | ||
1977 | _REGISTER_CLOCK(NULL, "ckih", ckih_clk), | ||
1978 | _REGISTER_CLOCK(NULL, "ckil_clk", ckil_clk), | ||
1979 | _REGISTER_CLOCK(NULL, "aips_tz1_clk", aips_tz1_clk), | ||
1980 | _REGISTER_CLOCK(NULL, "aips_tz2_clk", aips_tz2_clk), | ||
1981 | _REGISTER_CLOCK(NULL, "asrc_clk", asrc_clk), | ||
1982 | _REGISTER_CLOCK(NULL, "can2_clk", can2_clk), | ||
1983 | _REGISTER_CLOCK(NULL, "hdmi_isfr_clk", hdmi_isfr_clk), | ||
1984 | _REGISTER_CLOCK(NULL, "iim_clk", iim_clk), | ||
1985 | _REGISTER_CLOCK(NULL, "mlb_clk", mlb_clk), | ||
1986 | _REGISTER_CLOCK(NULL, "openvg_axi_clk", openvg_axi_clk), | ||
1987 | _REGISTER_CLOCK(NULL, "pwm1_clk", pwm1_clk), | ||
1988 | _REGISTER_CLOCK(NULL, "pwm2_clk", pwm2_clk), | ||
1989 | _REGISTER_CLOCK(NULL, "pwm3_clk", pwm3_clk), | ||
1990 | _REGISTER_CLOCK(NULL, "pwm4_clk", pwm4_clk), | ||
1991 | _REGISTER_CLOCK(NULL, "gpmi_io_clk", gpmi_io_clk), | ||
1992 | _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk), | ||
1993 | _REGISTER_CLOCK(NULL, "sata_clk", sata_clk), | ||
1994 | _REGISTER_CLOCK(NULL, "cko1_clk", cko1_clk), | ||
1995 | }; | ||
1996 | |||
1997 | int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) | ||
1998 | { | ||
1999 | u32 val = readl_relaxed(CLPCR); | ||
2000 | |||
2001 | val &= ~BM_CLPCR_LPM; | ||
2002 | switch (mode) { | ||
2003 | case WAIT_CLOCKED: | ||
2004 | break; | ||
2005 | case WAIT_UNCLOCKED: | ||
2006 | val |= 0x1 << BP_CLPCR_LPM; | ||
2007 | break; | ||
2008 | case STOP_POWER_ON: | ||
2009 | val |= 0x2 << BP_CLPCR_LPM; | ||
2010 | break; | ||
2011 | case WAIT_UNCLOCKED_POWER_OFF: | ||
2012 | val |= 0x1 << BP_CLPCR_LPM; | ||
2013 | val &= ~BM_CLPCR_VSTBY; | ||
2014 | val &= ~BM_CLPCR_SBYOS; | ||
2015 | break; | ||
2016 | case STOP_POWER_OFF: | ||
2017 | val |= 0x2 << BP_CLPCR_LPM; | ||
2018 | val |= 0x3 << BP_CLPCR_STBY_COUNT; | ||
2019 | val |= BM_CLPCR_VSTBY; | ||
2020 | val |= BM_CLPCR_SBYOS; | ||
2021 | break; | ||
2022 | default: | ||
2023 | return -EINVAL; | ||
2024 | } | ||
2025 | writel_relaxed(val, CLPCR); | ||
2026 | |||
2027 | return 0; | ||
2028 | } | ||
2029 | |||
2030 | static struct map_desc imx6q_clock_desc[] = { | ||
2031 | imx_map_entry(MX6Q, CCM, MT_DEVICE), | ||
2032 | imx_map_entry(MX6Q, ANATOP, MT_DEVICE), | ||
2033 | }; | ||
2034 | |||
2035 | void __init imx6q_clock_map_io(void) | ||
2036 | { | ||
2037 | iotable_init(imx6q_clock_desc, ARRAY_SIZE(imx6q_clock_desc)); | ||
2038 | } | ||
2039 | |||
2040 | int __init mx6q_clocks_init(void) | ||
2041 | { | ||
2042 | struct device_node *np; | ||
2043 | void __iomem *base; | ||
2044 | int i, irq; | ||
2045 | |||
2046 | /* retrieve the freqency of fixed clocks from device tree */ | ||
2047 | for_each_compatible_node(np, NULL, "fixed-clock") { | ||
2048 | u32 rate; | ||
2049 | if (of_property_read_u32(np, "clock-frequency", &rate)) | ||
2050 | continue; | ||
2051 | |||
2052 | if (of_device_is_compatible(np, "fsl,imx-ckil")) | ||
2053 | external_low_reference = rate; | ||
2054 | else if (of_device_is_compatible(np, "fsl,imx-ckih1")) | ||
2055 | external_high_reference = rate; | ||
2056 | else if (of_device_is_compatible(np, "fsl,imx-osc")) | ||
2057 | oscillator_reference = rate; | ||
2058 | } | ||
2059 | |||
2060 | for (i = 0; i < ARRAY_SIZE(lookups); i++) | ||
2061 | clkdev_add(&lookups[i]); | ||
2062 | |||
2063 | /* only keep necessary clocks on */ | ||
2064 | writel_relaxed(0x3 << CG0 | 0x3 << CG1 | 0x3 << CG2, CCGR0); | ||
2065 | writel_relaxed(0x3 << CG8 | 0x3 << CG9 | 0x3 << CG10, CCGR2); | ||
2066 | writel_relaxed(0x3 << CG10 | 0x3 << CG12, CCGR3); | ||
2067 | writel_relaxed(0x3 << CG4 | 0x3 << CG6 | 0x3 << CG7, CCGR4); | ||
2068 | writel_relaxed(0x3 << CG0, CCGR5); | ||
2069 | writel_relaxed(0, CCGR6); | ||
2070 | writel_relaxed(0, CCGR7); | ||
2071 | |||
2072 | clk_enable(&uart_clk); | ||
2073 | clk_enable(&mmdc_ch0_axi_clk); | ||
2074 | |||
2075 | clk_set_rate(&pll4_audio, FREQ_650M); | ||
2076 | clk_set_rate(&pll5_video, FREQ_650M); | ||
2077 | clk_set_parent(&ipu1_di0_clk, &ipu1_di0_pre_clk); | ||
2078 | clk_set_parent(&ipu1_di0_pre_clk, &pll5_video); | ||
2079 | clk_set_parent(&gpu3d_shader_clk, &pll2_pfd_594m); | ||
2080 | clk_set_rate(&gpu3d_shader_clk, FREQ_594M); | ||
2081 | clk_set_parent(&gpu3d_core_clk, &mmdc_ch0_axi_clk); | ||
2082 | clk_set_rate(&gpu3d_core_clk, FREQ_528M); | ||
2083 | clk_set_parent(&asrc_serial_clk, &pll3_usb_otg); | ||
2084 | clk_set_rate(&asrc_serial_clk, 1500000); | ||
2085 | clk_set_rate(&enfc_clk, 11000000); | ||
2086 | |||
2087 | /* | ||
2088 | * Before pinctrl API is available, we have to rely on the pad | ||
2089 | * configuration set up by bootloader. For usdhc example here, | ||
2090 | * u-boot sets up the pads for 49.5 MHz case, and we have to lower | ||
2091 | * the usdhc clock from 198 to 49.5 MHz to match the pad configuration. | ||
2092 | * | ||
2093 | * FIXME: This is should be removed after pinctrl API is available. | ||
2094 | * At that time, usdhc driver can call pinctrl API to change pad | ||
2095 | * configuration dynamically per different usdhc clock settings. | ||
2096 | */ | ||
2097 | clk_set_rate(&usdhc1_clk, 49500000); | ||
2098 | clk_set_rate(&usdhc2_clk, 49500000); | ||
2099 | clk_set_rate(&usdhc3_clk, 49500000); | ||
2100 | clk_set_rate(&usdhc4_clk, 49500000); | ||
2101 | |||
2102 | clk_set_parent(&cko1_clk, &ahb_clk); | ||
2103 | |||
2104 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt"); | ||
2105 | base = of_iomap(np, 0); | ||
2106 | WARN_ON(!base); | ||
2107 | irq = irq_of_parse_and_map(np, 0); | ||
2108 | mxc_timer_init(&gpt_clk, base, irq); | ||
2109 | |||
2110 | return 0; | ||
2111 | } | ||
diff --git a/arch/arm/mach-imx/clock-mx51-mx53.c b/arch/arm/mach-imx/clock-mx51-mx53.c deleted file mode 100644 index 08470504a088..000000000000 --- a/arch/arm/mach-imx/clock-mx51-mx53.c +++ /dev/null | |||
@@ -1,1675 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com> | ||
4 | * | ||
5 | * The code contained herein is licensed under the GNU General Public | ||
6 | * License. You may obtain a copy of the GNU General Public License | ||
7 | * Version 2 or later at the following locations: | ||
8 | * | ||
9 | * http://www.opensource.org/licenses/gpl-license.html | ||
10 | * http://www.gnu.org/copyleft/gpl.html | ||
11 | */ | ||
12 | |||
13 | #include <linux/mm.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/clkdev.h> | ||
18 | #include <linux/of.h> | ||
19 | |||
20 | #include <asm/div64.h> | ||
21 | |||
22 | #include <mach/hardware.h> | ||
23 | #include <mach/common.h> | ||
24 | #include <mach/clock.h> | ||
25 | |||
26 | #include "crm-regs-imx5.h" | ||
27 | |||
28 | /* External clock values passed-in by the board code */ | ||
29 | static unsigned long external_high_reference, external_low_reference; | ||
30 | static unsigned long oscillator_reference, ckih2_reference; | ||
31 | |||
32 | static struct clk osc_clk; | ||
33 | static struct clk pll1_main_clk; | ||
34 | static struct clk pll1_sw_clk; | ||
35 | static struct clk pll2_sw_clk; | ||
36 | static struct clk pll3_sw_clk; | ||
37 | static struct clk mx53_pll4_sw_clk; | ||
38 | static struct clk lp_apm_clk; | ||
39 | static struct clk periph_apm_clk; | ||
40 | static struct clk ahb_clk; | ||
41 | static struct clk ipg_clk; | ||
42 | static struct clk usboh3_clk; | ||
43 | static struct clk emi_fast_clk; | ||
44 | static struct clk ipu_clk; | ||
45 | static struct clk mipi_hsc1_clk; | ||
46 | static struct clk esdhc1_clk; | ||
47 | static struct clk esdhc2_clk; | ||
48 | static struct clk esdhc3_mx53_clk; | ||
49 | |||
50 | #define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ | ||
51 | |||
52 | /* calculate best pre and post dividers to get the required divider */ | ||
53 | static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post, | ||
54 | u32 max_pre, u32 max_post) | ||
55 | { | ||
56 | if (div >= max_pre * max_post) { | ||
57 | *pre = max_pre; | ||
58 | *post = max_post; | ||
59 | } else if (div >= max_pre) { | ||
60 | u32 min_pre, temp_pre, old_err, err; | ||
61 | min_pre = DIV_ROUND_UP(div, max_post); | ||
62 | old_err = max_pre; | ||
63 | for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) { | ||
64 | err = div % temp_pre; | ||
65 | if (err == 0) { | ||
66 | *pre = temp_pre; | ||
67 | break; | ||
68 | } | ||
69 | err = temp_pre - err; | ||
70 | if (err < old_err) { | ||
71 | old_err = err; | ||
72 | *pre = temp_pre; | ||
73 | } | ||
74 | } | ||
75 | *post = DIV_ROUND_UP(div, *pre); | ||
76 | } else { | ||
77 | *pre = div; | ||
78 | *post = 1; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static void _clk_ccgr_setclk(struct clk *clk, unsigned mode) | ||
83 | { | ||
84 | u32 reg = __raw_readl(clk->enable_reg); | ||
85 | |||
86 | reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift); | ||
87 | reg |= mode << clk->enable_shift; | ||
88 | |||
89 | __raw_writel(reg, clk->enable_reg); | ||
90 | } | ||
91 | |||
92 | static int _clk_ccgr_enable(struct clk *clk) | ||
93 | { | ||
94 | _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON); | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static void _clk_ccgr_disable(struct clk *clk) | ||
99 | { | ||
100 | _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF); | ||
101 | } | ||
102 | |||
103 | static int _clk_ccgr_enable_inrun(struct clk *clk) | ||
104 | { | ||
105 | _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static void _clk_ccgr_disable_inwait(struct clk *clk) | ||
110 | { | ||
111 | _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE); | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * For the 4-to-1 muxed input clock | ||
116 | */ | ||
117 | static inline u32 _get_mux(struct clk *parent, struct clk *m0, | ||
118 | struct clk *m1, struct clk *m2, struct clk *m3) | ||
119 | { | ||
120 | if (parent == m0) | ||
121 | return 0; | ||
122 | else if (parent == m1) | ||
123 | return 1; | ||
124 | else if (parent == m2) | ||
125 | return 2; | ||
126 | else if (parent == m3) | ||
127 | return 3; | ||
128 | else | ||
129 | BUG(); | ||
130 | |||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | static inline void __iomem *_mx51_get_pll_base(struct clk *pll) | ||
135 | { | ||
136 | if (pll == &pll1_main_clk) | ||
137 | return MX51_DPLL1_BASE; | ||
138 | else if (pll == &pll2_sw_clk) | ||
139 | return MX51_DPLL2_BASE; | ||
140 | else if (pll == &pll3_sw_clk) | ||
141 | return MX51_DPLL3_BASE; | ||
142 | else | ||
143 | BUG(); | ||
144 | |||
145 | return NULL; | ||
146 | } | ||
147 | |||
148 | static inline void __iomem *_mx53_get_pll_base(struct clk *pll) | ||
149 | { | ||
150 | if (pll == &pll1_main_clk) | ||
151 | return MX53_DPLL1_BASE; | ||
152 | else if (pll == &pll2_sw_clk) | ||
153 | return MX53_DPLL2_BASE; | ||
154 | else if (pll == &pll3_sw_clk) | ||
155 | return MX53_DPLL3_BASE; | ||
156 | else if (pll == &mx53_pll4_sw_clk) | ||
157 | return MX53_DPLL4_BASE; | ||
158 | else | ||
159 | BUG(); | ||
160 | |||
161 | return NULL; | ||
162 | } | ||
163 | |||
164 | static inline void __iomem *_get_pll_base(struct clk *pll) | ||
165 | { | ||
166 | if (cpu_is_mx51()) | ||
167 | return _mx51_get_pll_base(pll); | ||
168 | else | ||
169 | return _mx53_get_pll_base(pll); | ||
170 | } | ||
171 | |||
172 | static unsigned long clk_pll_get_rate(struct clk *clk) | ||
173 | { | ||
174 | long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; | ||
175 | unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl; | ||
176 | void __iomem *pllbase; | ||
177 | s64 temp; | ||
178 | unsigned long parent_rate; | ||
179 | |||
180 | parent_rate = clk_get_rate(clk->parent); | ||
181 | |||
182 | pllbase = _get_pll_base(clk); | ||
183 | |||
184 | dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); | ||
185 | pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; | ||
186 | dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; | ||
187 | |||
188 | if (pll_hfsm == 0) { | ||
189 | dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); | ||
190 | dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); | ||
191 | dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); | ||
192 | } else { | ||
193 | dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP); | ||
194 | dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD); | ||
195 | dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN); | ||
196 | } | ||
197 | pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; | ||
198 | mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; | ||
199 | mfi = (mfi <= 5) ? 5 : mfi; | ||
200 | mfd = dp_mfd & MXC_PLL_DP_MFD_MASK; | ||
201 | mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK; | ||
202 | /* Sign extend to 32-bits */ | ||
203 | if (mfn >= 0x04000000) { | ||
204 | mfn |= 0xFC000000; | ||
205 | mfn_abs = -mfn; | ||
206 | } | ||
207 | |||
208 | ref_clk = 2 * parent_rate; | ||
209 | if (dbl != 0) | ||
210 | ref_clk *= 2; | ||
211 | |||
212 | ref_clk /= (pdf + 1); | ||
213 | temp = (u64) ref_clk * mfn_abs; | ||
214 | do_div(temp, mfd + 1); | ||
215 | if (mfn < 0) | ||
216 | temp = -temp; | ||
217 | temp = (ref_clk * mfi) + temp; | ||
218 | |||
219 | return temp; | ||
220 | } | ||
221 | |||
222 | static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) | ||
223 | { | ||
224 | u32 reg; | ||
225 | void __iomem *pllbase; | ||
226 | |||
227 | long mfi, pdf, mfn, mfd = 999999; | ||
228 | s64 temp64; | ||
229 | unsigned long quad_parent_rate; | ||
230 | unsigned long pll_hfsm, dp_ctl; | ||
231 | unsigned long parent_rate; | ||
232 | |||
233 | parent_rate = clk_get_rate(clk->parent); | ||
234 | |||
235 | pllbase = _get_pll_base(clk); | ||
236 | |||
237 | quad_parent_rate = 4 * parent_rate; | ||
238 | pdf = mfi = -1; | ||
239 | while (++pdf < 16 && mfi < 5) | ||
240 | mfi = rate * (pdf+1) / quad_parent_rate; | ||
241 | if (mfi > 15) | ||
242 | return -EINVAL; | ||
243 | pdf--; | ||
244 | |||
245 | temp64 = rate * (pdf+1) - quad_parent_rate * mfi; | ||
246 | do_div(temp64, quad_parent_rate/1000000); | ||
247 | mfn = (long)temp64; | ||
248 | |||
249 | dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); | ||
250 | /* use dpdck0_2 */ | ||
251 | __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); | ||
252 | pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; | ||
253 | if (pll_hfsm == 0) { | ||
254 | reg = mfi << 4 | pdf; | ||
255 | __raw_writel(reg, pllbase + MXC_PLL_DP_OP); | ||
256 | __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); | ||
257 | __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); | ||
258 | } else { | ||
259 | reg = mfi << 4 | pdf; | ||
260 | __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP); | ||
261 | __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD); | ||
262 | __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN); | ||
263 | } | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static int _clk_pll_enable(struct clk *clk) | ||
269 | { | ||
270 | u32 reg; | ||
271 | void __iomem *pllbase; | ||
272 | int i = 0; | ||
273 | |||
274 | pllbase = _get_pll_base(clk); | ||
275 | reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); | ||
276 | if (reg & MXC_PLL_DP_CTL_UPEN) | ||
277 | return 0; | ||
278 | |||
279 | reg |= MXC_PLL_DP_CTL_UPEN; | ||
280 | __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); | ||
281 | |||
282 | /* Wait for lock */ | ||
283 | do { | ||
284 | reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); | ||
285 | if (reg & MXC_PLL_DP_CTL_LRF) | ||
286 | break; | ||
287 | |||
288 | udelay(1); | ||
289 | } while (++i < MAX_DPLL_WAIT_TRIES); | ||
290 | |||
291 | if (i == MAX_DPLL_WAIT_TRIES) { | ||
292 | pr_err("MX5: pll locking failed\n"); | ||
293 | return -EINVAL; | ||
294 | } | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static void _clk_pll_disable(struct clk *clk) | ||
300 | { | ||
301 | u32 reg; | ||
302 | void __iomem *pllbase; | ||
303 | |||
304 | pllbase = _get_pll_base(clk); | ||
305 | reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN; | ||
306 | __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); | ||
307 | } | ||
308 | |||
309 | static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent) | ||
310 | { | ||
311 | u32 reg, step; | ||
312 | |||
313 | reg = __raw_readl(MXC_CCM_CCSR); | ||
314 | |||
315 | /* When switching from pll_main_clk to a bypass clock, first select a | ||
316 | * multiplexed clock in 'step_sel', then shift the glitchless mux | ||
317 | * 'pll1_sw_clk_sel'. | ||
318 | * | ||
319 | * When switching back, do it in reverse order | ||
320 | */ | ||
321 | if (parent == &pll1_main_clk) { | ||
322 | /* Switch to pll1_main_clk */ | ||
323 | reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; | ||
324 | __raw_writel(reg, MXC_CCM_CCSR); | ||
325 | /* step_clk mux switched to lp_apm, to save power. */ | ||
326 | reg = __raw_readl(MXC_CCM_CCSR); | ||
327 | reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK; | ||
328 | reg |= (MXC_CCM_CCSR_STEP_SEL_LP_APM << | ||
329 | MXC_CCM_CCSR_STEP_SEL_OFFSET); | ||
330 | } else { | ||
331 | if (parent == &lp_apm_clk) { | ||
332 | step = MXC_CCM_CCSR_STEP_SEL_LP_APM; | ||
333 | } else if (parent == &pll2_sw_clk) { | ||
334 | step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED; | ||
335 | } else if (parent == &pll3_sw_clk) { | ||
336 | step = MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED; | ||
337 | } else | ||
338 | return -EINVAL; | ||
339 | |||
340 | reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK; | ||
341 | reg |= (step << MXC_CCM_CCSR_STEP_SEL_OFFSET); | ||
342 | |||
343 | __raw_writel(reg, MXC_CCM_CCSR); | ||
344 | /* Switch to step_clk */ | ||
345 | reg = __raw_readl(MXC_CCM_CCSR); | ||
346 | reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; | ||
347 | } | ||
348 | __raw_writel(reg, MXC_CCM_CCSR); | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static unsigned long clk_pll1_sw_get_rate(struct clk *clk) | ||
353 | { | ||
354 | u32 reg, div; | ||
355 | unsigned long parent_rate; | ||
356 | |||
357 | parent_rate = clk_get_rate(clk->parent); | ||
358 | |||
359 | reg = __raw_readl(MXC_CCM_CCSR); | ||
360 | |||
361 | if (clk->parent == &pll2_sw_clk) { | ||
362 | div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >> | ||
363 | MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1; | ||
364 | } else if (clk->parent == &pll3_sw_clk) { | ||
365 | div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >> | ||
366 | MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1; | ||
367 | } else | ||
368 | div = 1; | ||
369 | return parent_rate / div; | ||
370 | } | ||
371 | |||
372 | static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent) | ||
373 | { | ||
374 | u32 reg; | ||
375 | |||
376 | reg = __raw_readl(MXC_CCM_CCSR); | ||
377 | |||
378 | if (parent == &pll2_sw_clk) | ||
379 | reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL; | ||
380 | else | ||
381 | reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL; | ||
382 | |||
383 | __raw_writel(reg, MXC_CCM_CCSR); | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent) | ||
388 | { | ||
389 | u32 reg; | ||
390 | |||
391 | if (parent == &osc_clk) | ||
392 | reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL; | ||
393 | else | ||
394 | return -EINVAL; | ||
395 | |||
396 | __raw_writel(reg, MXC_CCM_CCSR); | ||
397 | |||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | static unsigned long clk_cpu_get_rate(struct clk *clk) | ||
402 | { | ||
403 | u32 cacrr, div; | ||
404 | unsigned long parent_rate; | ||
405 | |||
406 | parent_rate = clk_get_rate(clk->parent); | ||
407 | cacrr = __raw_readl(MXC_CCM_CACRR); | ||
408 | div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1; | ||
409 | |||
410 | return parent_rate / div; | ||
411 | } | ||
412 | |||
413 | static int clk_cpu_set_rate(struct clk *clk, unsigned long rate) | ||
414 | { | ||
415 | u32 reg, cpu_podf; | ||
416 | unsigned long parent_rate; | ||
417 | |||
418 | parent_rate = clk_get_rate(clk->parent); | ||
419 | cpu_podf = parent_rate / rate - 1; | ||
420 | /* use post divider to change freq */ | ||
421 | reg = __raw_readl(MXC_CCM_CACRR); | ||
422 | reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK; | ||
423 | reg |= cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET; | ||
424 | __raw_writel(reg, MXC_CCM_CACRR); | ||
425 | |||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent) | ||
430 | { | ||
431 | u32 reg, mux; | ||
432 | int i = 0; | ||
433 | |||
434 | mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL); | ||
435 | |||
436 | reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK; | ||
437 | reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET; | ||
438 | __raw_writel(reg, MXC_CCM_CBCMR); | ||
439 | |||
440 | /* Wait for lock */ | ||
441 | do { | ||
442 | reg = __raw_readl(MXC_CCM_CDHIPR); | ||
443 | if (!(reg & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY)) | ||
444 | break; | ||
445 | |||
446 | udelay(1); | ||
447 | } while (++i < MAX_DPLL_WAIT_TRIES); | ||
448 | |||
449 | if (i == MAX_DPLL_WAIT_TRIES) { | ||
450 | pr_err("MX5: Set parent for periph_apm clock failed\n"); | ||
451 | return -EINVAL; | ||
452 | } | ||
453 | |||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent) | ||
458 | { | ||
459 | u32 reg; | ||
460 | |||
461 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
462 | |||
463 | if (parent == &pll2_sw_clk) | ||
464 | reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL; | ||
465 | else if (parent == &periph_apm_clk) | ||
466 | reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL; | ||
467 | else | ||
468 | return -EINVAL; | ||
469 | |||
470 | __raw_writel(reg, MXC_CCM_CBCDR); | ||
471 | |||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | static struct clk main_bus_clk = { | ||
476 | .parent = &pll2_sw_clk, | ||
477 | .set_parent = _clk_main_bus_set_parent, | ||
478 | }; | ||
479 | |||
480 | static unsigned long clk_ahb_get_rate(struct clk *clk) | ||
481 | { | ||
482 | u32 reg, div; | ||
483 | unsigned long parent_rate; | ||
484 | |||
485 | parent_rate = clk_get_rate(clk->parent); | ||
486 | |||
487 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
488 | div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >> | ||
489 | MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1; | ||
490 | return parent_rate / div; | ||
491 | } | ||
492 | |||
493 | |||
494 | static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate) | ||
495 | { | ||
496 | u32 reg, div; | ||
497 | unsigned long parent_rate; | ||
498 | int i = 0; | ||
499 | |||
500 | parent_rate = clk_get_rate(clk->parent); | ||
501 | |||
502 | div = parent_rate / rate; | ||
503 | if (div > 8 || div < 1 || ((parent_rate / div) != rate)) | ||
504 | return -EINVAL; | ||
505 | |||
506 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
507 | reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK; | ||
508 | reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET; | ||
509 | __raw_writel(reg, MXC_CCM_CBCDR); | ||
510 | |||
511 | /* Wait for lock */ | ||
512 | do { | ||
513 | reg = __raw_readl(MXC_CCM_CDHIPR); | ||
514 | if (!(reg & MXC_CCM_CDHIPR_AHB_PODF_BUSY)) | ||
515 | break; | ||
516 | |||
517 | udelay(1); | ||
518 | } while (++i < MAX_DPLL_WAIT_TRIES); | ||
519 | |||
520 | if (i == MAX_DPLL_WAIT_TRIES) { | ||
521 | pr_err("MX5: clk_ahb_set_rate failed\n"); | ||
522 | return -EINVAL; | ||
523 | } | ||
524 | |||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | static unsigned long _clk_ahb_round_rate(struct clk *clk, | ||
529 | unsigned long rate) | ||
530 | { | ||
531 | u32 div; | ||
532 | unsigned long parent_rate; | ||
533 | |||
534 | parent_rate = clk_get_rate(clk->parent); | ||
535 | |||
536 | div = parent_rate / rate; | ||
537 | if (div > 8) | ||
538 | div = 8; | ||
539 | else if (div == 0) | ||
540 | div++; | ||
541 | return parent_rate / div; | ||
542 | } | ||
543 | |||
544 | |||
545 | static int _clk_max_enable(struct clk *clk) | ||
546 | { | ||
547 | u32 reg; | ||
548 | |||
549 | _clk_ccgr_enable(clk); | ||
550 | |||
551 | /* Handshake with MAX when LPM is entered. */ | ||
552 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
553 | if (cpu_is_mx51()) | ||
554 | reg &= ~MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS; | ||
555 | else if (cpu_is_mx53()) | ||
556 | reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS; | ||
557 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | static void _clk_max_disable(struct clk *clk) | ||
563 | { | ||
564 | u32 reg; | ||
565 | |||
566 | _clk_ccgr_disable_inwait(clk); | ||
567 | |||
568 | /* No Handshake with MAX when LPM is entered as its disabled. */ | ||
569 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
570 | if (cpu_is_mx51()) | ||
571 | reg |= MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS; | ||
572 | else if (cpu_is_mx53()) | ||
573 | reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS; | ||
574 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
575 | } | ||
576 | |||
577 | static unsigned long clk_ipg_get_rate(struct clk *clk) | ||
578 | { | ||
579 | u32 reg, div; | ||
580 | unsigned long parent_rate; | ||
581 | |||
582 | parent_rate = clk_get_rate(clk->parent); | ||
583 | |||
584 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
585 | div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >> | ||
586 | MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1; | ||
587 | |||
588 | return parent_rate / div; | ||
589 | } | ||
590 | |||
591 | static unsigned long clk_ipg_per_get_rate(struct clk *clk) | ||
592 | { | ||
593 | u32 reg, prediv1, prediv2, podf; | ||
594 | unsigned long parent_rate; | ||
595 | |||
596 | parent_rate = clk_get_rate(clk->parent); | ||
597 | |||
598 | if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) { | ||
599 | /* the main_bus_clk is the one before the DVFS engine */ | ||
600 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
601 | prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >> | ||
602 | MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1; | ||
603 | prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >> | ||
604 | MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1; | ||
605 | podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >> | ||
606 | MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1; | ||
607 | return parent_rate / (prediv1 * prediv2 * podf); | ||
608 | } else if (clk->parent == &ipg_clk) | ||
609 | return parent_rate; | ||
610 | else | ||
611 | BUG(); | ||
612 | } | ||
613 | |||
614 | static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent) | ||
615 | { | ||
616 | u32 reg; | ||
617 | |||
618 | reg = __raw_readl(MXC_CCM_CBCMR); | ||
619 | |||
620 | reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL; | ||
621 | reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL; | ||
622 | |||
623 | if (parent == &ipg_clk) | ||
624 | reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL; | ||
625 | else if (parent == &lp_apm_clk) | ||
626 | reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL; | ||
627 | else if (parent != &main_bus_clk) | ||
628 | return -EINVAL; | ||
629 | |||
630 | __raw_writel(reg, MXC_CCM_CBCMR); | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | #define clk_nfc_set_parent NULL | ||
636 | |||
637 | static unsigned long clk_nfc_get_rate(struct clk *clk) | ||
638 | { | ||
639 | unsigned long rate; | ||
640 | u32 reg, div; | ||
641 | |||
642 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
643 | div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >> | ||
644 | MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1; | ||
645 | rate = clk_get_rate(clk->parent) / div; | ||
646 | WARN_ON(rate == 0); | ||
647 | return rate; | ||
648 | } | ||
649 | |||
650 | static unsigned long clk_nfc_round_rate(struct clk *clk, | ||
651 | unsigned long rate) | ||
652 | { | ||
653 | u32 div; | ||
654 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
655 | |||
656 | if (!rate) | ||
657 | return -EINVAL; | ||
658 | |||
659 | div = parent_rate / rate; | ||
660 | |||
661 | if (parent_rate % rate) | ||
662 | div++; | ||
663 | |||
664 | if (div > 8) | ||
665 | return -EINVAL; | ||
666 | |||
667 | return parent_rate / div; | ||
668 | |||
669 | } | ||
670 | |||
671 | static int clk_nfc_set_rate(struct clk *clk, unsigned long rate) | ||
672 | { | ||
673 | u32 reg, div; | ||
674 | |||
675 | div = clk_get_rate(clk->parent) / rate; | ||
676 | if (div == 0) | ||
677 | div++; | ||
678 | if (((clk_get_rate(clk->parent) / div) != rate) || (div > 8)) | ||
679 | return -EINVAL; | ||
680 | |||
681 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
682 | reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK; | ||
683 | reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET; | ||
684 | __raw_writel(reg, MXC_CCM_CBCDR); | ||
685 | |||
686 | while (__raw_readl(MXC_CCM_CDHIPR) & | ||
687 | MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){ | ||
688 | } | ||
689 | |||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | static unsigned long get_high_reference_clock_rate(struct clk *clk) | ||
694 | { | ||
695 | return external_high_reference; | ||
696 | } | ||
697 | |||
698 | static unsigned long get_low_reference_clock_rate(struct clk *clk) | ||
699 | { | ||
700 | return external_low_reference; | ||
701 | } | ||
702 | |||
703 | static unsigned long get_oscillator_reference_clock_rate(struct clk *clk) | ||
704 | { | ||
705 | return oscillator_reference; | ||
706 | } | ||
707 | |||
708 | static unsigned long get_ckih2_reference_clock_rate(struct clk *clk) | ||
709 | { | ||
710 | return ckih2_reference; | ||
711 | } | ||
712 | |||
713 | static unsigned long clk_emi_slow_get_rate(struct clk *clk) | ||
714 | { | ||
715 | u32 reg, div; | ||
716 | |||
717 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
718 | div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >> | ||
719 | MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1; | ||
720 | |||
721 | return clk_get_rate(clk->parent) / div; | ||
722 | } | ||
723 | |||
724 | static unsigned long _clk_ddr_hf_get_rate(struct clk *clk) | ||
725 | { | ||
726 | unsigned long rate; | ||
727 | u32 reg, div; | ||
728 | |||
729 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
730 | div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >> | ||
731 | MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1; | ||
732 | rate = clk_get_rate(clk->parent) / div; | ||
733 | |||
734 | return rate; | ||
735 | } | ||
736 | |||
737 | /* External high frequency clock */ | ||
738 | static struct clk ckih_clk = { | ||
739 | .get_rate = get_high_reference_clock_rate, | ||
740 | }; | ||
741 | |||
742 | static struct clk ckih2_clk = { | ||
743 | .get_rate = get_ckih2_reference_clock_rate, | ||
744 | }; | ||
745 | |||
746 | static struct clk osc_clk = { | ||
747 | .get_rate = get_oscillator_reference_clock_rate, | ||
748 | }; | ||
749 | |||
750 | /* External low frequency (32kHz) clock */ | ||
751 | static struct clk ckil_clk = { | ||
752 | .get_rate = get_low_reference_clock_rate, | ||
753 | }; | ||
754 | |||
755 | static struct clk pll1_main_clk = { | ||
756 | .parent = &osc_clk, | ||
757 | .get_rate = clk_pll_get_rate, | ||
758 | .enable = _clk_pll_enable, | ||
759 | .disable = _clk_pll_disable, | ||
760 | }; | ||
761 | |||
762 | /* Clock tree block diagram (WIP): | ||
763 | * CCM: Clock Controller Module | ||
764 | * | ||
765 | * PLL output -> | | ||
766 | * | CCM Switcher -> CCM_CLK_ROOT_GEN -> | ||
767 | * PLL bypass -> | | ||
768 | * | ||
769 | */ | ||
770 | |||
771 | /* PLL1 SW supplies to ARM core */ | ||
772 | static struct clk pll1_sw_clk = { | ||
773 | .parent = &pll1_main_clk, | ||
774 | .set_parent = _clk_pll1_sw_set_parent, | ||
775 | .get_rate = clk_pll1_sw_get_rate, | ||
776 | }; | ||
777 | |||
778 | /* PLL2 SW supplies to AXI/AHB/IP buses */ | ||
779 | static struct clk pll2_sw_clk = { | ||
780 | .parent = &osc_clk, | ||
781 | .get_rate = clk_pll_get_rate, | ||
782 | .set_rate = _clk_pll_set_rate, | ||
783 | .set_parent = _clk_pll2_sw_set_parent, | ||
784 | .enable = _clk_pll_enable, | ||
785 | .disable = _clk_pll_disable, | ||
786 | }; | ||
787 | |||
788 | /* PLL3 SW supplies to serial clocks like USB, SSI, etc. */ | ||
789 | static struct clk pll3_sw_clk = { | ||
790 | .parent = &osc_clk, | ||
791 | .set_rate = _clk_pll_set_rate, | ||
792 | .get_rate = clk_pll_get_rate, | ||
793 | .enable = _clk_pll_enable, | ||
794 | .disable = _clk_pll_disable, | ||
795 | }; | ||
796 | |||
797 | /* PLL4 SW supplies to LVDS Display Bridge(LDB) */ | ||
798 | static struct clk mx53_pll4_sw_clk = { | ||
799 | .parent = &osc_clk, | ||
800 | .set_rate = _clk_pll_set_rate, | ||
801 | .enable = _clk_pll_enable, | ||
802 | .disable = _clk_pll_disable, | ||
803 | }; | ||
804 | |||
805 | /* Low-power Audio Playback Mode clock */ | ||
806 | static struct clk lp_apm_clk = { | ||
807 | .parent = &osc_clk, | ||
808 | .set_parent = _clk_lp_apm_set_parent, | ||
809 | }; | ||
810 | |||
811 | static struct clk periph_apm_clk = { | ||
812 | .parent = &pll1_sw_clk, | ||
813 | .set_parent = _clk_periph_apm_set_parent, | ||
814 | }; | ||
815 | |||
816 | static struct clk cpu_clk = { | ||
817 | .parent = &pll1_sw_clk, | ||
818 | .get_rate = clk_cpu_get_rate, | ||
819 | .set_rate = clk_cpu_set_rate, | ||
820 | }; | ||
821 | |||
822 | static struct clk ahb_clk = { | ||
823 | .parent = &main_bus_clk, | ||
824 | .get_rate = clk_ahb_get_rate, | ||
825 | .set_rate = _clk_ahb_set_rate, | ||
826 | .round_rate = _clk_ahb_round_rate, | ||
827 | }; | ||
828 | |||
829 | static struct clk iim_clk = { | ||
830 | .parent = &ipg_clk, | ||
831 | .enable_reg = MXC_CCM_CCGR0, | ||
832 | .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET, | ||
833 | }; | ||
834 | |||
835 | /* Main IP interface clock for access to registers */ | ||
836 | static struct clk ipg_clk = { | ||
837 | .parent = &ahb_clk, | ||
838 | .get_rate = clk_ipg_get_rate, | ||
839 | }; | ||
840 | |||
841 | static struct clk ipg_perclk = { | ||
842 | .parent = &lp_apm_clk, | ||
843 | .get_rate = clk_ipg_per_get_rate, | ||
844 | .set_parent = _clk_ipg_per_set_parent, | ||
845 | }; | ||
846 | |||
847 | static struct clk ahb_max_clk = { | ||
848 | .parent = &ahb_clk, | ||
849 | .enable_reg = MXC_CCM_CCGR0, | ||
850 | .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET, | ||
851 | .enable = _clk_max_enable, | ||
852 | .disable = _clk_max_disable, | ||
853 | }; | ||
854 | |||
855 | static struct clk aips_tz1_clk = { | ||
856 | .parent = &ahb_clk, | ||
857 | .secondary = &ahb_max_clk, | ||
858 | .enable_reg = MXC_CCM_CCGR0, | ||
859 | .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET, | ||
860 | .enable = _clk_ccgr_enable, | ||
861 | .disable = _clk_ccgr_disable_inwait, | ||
862 | }; | ||
863 | |||
864 | static struct clk aips_tz2_clk = { | ||
865 | .parent = &ahb_clk, | ||
866 | .secondary = &ahb_max_clk, | ||
867 | .enable_reg = MXC_CCM_CCGR0, | ||
868 | .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET, | ||
869 | .enable = _clk_ccgr_enable, | ||
870 | .disable = _clk_ccgr_disable_inwait, | ||
871 | }; | ||
872 | |||
873 | static struct clk gpc_dvfs_clk = { | ||
874 | .enable_reg = MXC_CCM_CCGR5, | ||
875 | .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET, | ||
876 | .enable = _clk_ccgr_enable, | ||
877 | .disable = _clk_ccgr_disable, | ||
878 | }; | ||
879 | |||
880 | static struct clk gpt_32k_clk = { | ||
881 | .id = 0, | ||
882 | .parent = &ckil_clk, | ||
883 | }; | ||
884 | |||
885 | static struct clk dummy_clk = { | ||
886 | .id = 0, | ||
887 | }; | ||
888 | |||
889 | static struct clk emi_slow_clk = { | ||
890 | .parent = &pll2_sw_clk, | ||
891 | .enable_reg = MXC_CCM_CCGR5, | ||
892 | .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET, | ||
893 | .enable = _clk_ccgr_enable, | ||
894 | .disable = _clk_ccgr_disable_inwait, | ||
895 | .get_rate = clk_emi_slow_get_rate, | ||
896 | }; | ||
897 | |||
898 | static int clk_ipu_enable(struct clk *clk) | ||
899 | { | ||
900 | u32 reg; | ||
901 | |||
902 | _clk_ccgr_enable(clk); | ||
903 | |||
904 | /* Enable handshake with IPU when certain clock rates are changed */ | ||
905 | reg = __raw_readl(MXC_CCM_CCDR); | ||
906 | reg &= ~MXC_CCM_CCDR_IPU_HS_MASK; | ||
907 | __raw_writel(reg, MXC_CCM_CCDR); | ||
908 | |||
909 | /* Enable handshake with IPU when LPM is entered */ | ||
910 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
911 | reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; | ||
912 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
913 | |||
914 | return 0; | ||
915 | } | ||
916 | |||
917 | static void clk_ipu_disable(struct clk *clk) | ||
918 | { | ||
919 | u32 reg; | ||
920 | |||
921 | _clk_ccgr_disable(clk); | ||
922 | |||
923 | /* Disable handshake with IPU whe dividers are changed */ | ||
924 | reg = __raw_readl(MXC_CCM_CCDR); | ||
925 | reg |= MXC_CCM_CCDR_IPU_HS_MASK; | ||
926 | __raw_writel(reg, MXC_CCM_CCDR); | ||
927 | |||
928 | /* Disable handshake with IPU when LPM is entered */ | ||
929 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
930 | reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; | ||
931 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
932 | } | ||
933 | |||
934 | static struct clk ahbmux1_clk = { | ||
935 | .parent = &ahb_clk, | ||
936 | .secondary = &ahb_max_clk, | ||
937 | .enable_reg = MXC_CCM_CCGR0, | ||
938 | .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET, | ||
939 | .enable = _clk_ccgr_enable, | ||
940 | .disable = _clk_ccgr_disable_inwait, | ||
941 | }; | ||
942 | |||
943 | static struct clk ipu_sec_clk = { | ||
944 | .parent = &emi_fast_clk, | ||
945 | .secondary = &ahbmux1_clk, | ||
946 | }; | ||
947 | |||
948 | static struct clk ddr_hf_clk = { | ||
949 | .parent = &pll1_sw_clk, | ||
950 | .get_rate = _clk_ddr_hf_get_rate, | ||
951 | }; | ||
952 | |||
953 | static struct clk ddr_clk = { | ||
954 | .parent = &ddr_hf_clk, | ||
955 | }; | ||
956 | |||
957 | /* clock definitions for MIPI HSC unit which has been removed | ||
958 | * from documentation, but not from hardware | ||
959 | */ | ||
960 | static int _clk_hsc_enable(struct clk *clk) | ||
961 | { | ||
962 | u32 reg; | ||
963 | |||
964 | _clk_ccgr_enable(clk); | ||
965 | /* Handshake with IPU when certain clock rates are changed. */ | ||
966 | reg = __raw_readl(MXC_CCM_CCDR); | ||
967 | reg &= ~MXC_CCM_CCDR_HSC_HS_MASK; | ||
968 | __raw_writel(reg, MXC_CCM_CCDR); | ||
969 | |||
970 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
971 | reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS; | ||
972 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
973 | |||
974 | return 0; | ||
975 | } | ||
976 | |||
977 | static void _clk_hsc_disable(struct clk *clk) | ||
978 | { | ||
979 | u32 reg; | ||
980 | |||
981 | _clk_ccgr_disable(clk); | ||
982 | /* No handshake with HSC as its not enabled. */ | ||
983 | reg = __raw_readl(MXC_CCM_CCDR); | ||
984 | reg |= MXC_CCM_CCDR_HSC_HS_MASK; | ||
985 | __raw_writel(reg, MXC_CCM_CCDR); | ||
986 | |||
987 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
988 | reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS; | ||
989 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
990 | } | ||
991 | |||
992 | static struct clk mipi_hsp_clk = { | ||
993 | .parent = &ipu_clk, | ||
994 | .enable_reg = MXC_CCM_CCGR4, | ||
995 | .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET, | ||
996 | .enable = _clk_hsc_enable, | ||
997 | .disable = _clk_hsc_disable, | ||
998 | .secondary = &mipi_hsc1_clk, | ||
999 | }; | ||
1000 | |||
1001 | #define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \ | ||
1002 | static struct clk name = { \ | ||
1003 | .id = i, \ | ||
1004 | .enable_reg = er, \ | ||
1005 | .enable_shift = es, \ | ||
1006 | .get_rate = pfx##_get_rate, \ | ||
1007 | .set_rate = pfx##_set_rate, \ | ||
1008 | .round_rate = pfx##_round_rate, \ | ||
1009 | .set_parent = pfx##_set_parent, \ | ||
1010 | .enable = _clk_ccgr_enable, \ | ||
1011 | .disable = _clk_ccgr_disable, \ | ||
1012 | .parent = p, \ | ||
1013 | .secondary = s, \ | ||
1014 | } | ||
1015 | |||
1016 | #define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s) \ | ||
1017 | static struct clk name = { \ | ||
1018 | .id = i, \ | ||
1019 | .enable_reg = er, \ | ||
1020 | .enable_shift = es, \ | ||
1021 | .get_rate = pfx##_get_rate, \ | ||
1022 | .set_rate = pfx##_set_rate, \ | ||
1023 | .set_parent = pfx##_set_parent, \ | ||
1024 | .enable = _clk_max_enable, \ | ||
1025 | .disable = _clk_max_disable, \ | ||
1026 | .parent = p, \ | ||
1027 | .secondary = s, \ | ||
1028 | } | ||
1029 | |||
1030 | #define CLK_GET_RATE(name, nr, bitsname) \ | ||
1031 | static unsigned long clk_##name##_get_rate(struct clk *clk) \ | ||
1032 | { \ | ||
1033 | u32 reg, pred, podf; \ | ||
1034 | \ | ||
1035 | reg = __raw_readl(MXC_CCM_CSCDR##nr); \ | ||
1036 | pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK) \ | ||
1037 | >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \ | ||
1038 | podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK) \ | ||
1039 | >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \ | ||
1040 | \ | ||
1041 | return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), \ | ||
1042 | (pred + 1) * (podf + 1)); \ | ||
1043 | } | ||
1044 | |||
1045 | #define CLK_SET_PARENT(name, nr, bitsname) \ | ||
1046 | static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \ | ||
1047 | { \ | ||
1048 | u32 reg, mux; \ | ||
1049 | \ | ||
1050 | mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, \ | ||
1051 | &pll3_sw_clk, &lp_apm_clk); \ | ||
1052 | reg = __raw_readl(MXC_CCM_CSCMR##nr) & \ | ||
1053 | ~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK; \ | ||
1054 | reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET; \ | ||
1055 | __raw_writel(reg, MXC_CCM_CSCMR##nr); \ | ||
1056 | \ | ||
1057 | return 0; \ | ||
1058 | } | ||
1059 | |||
1060 | #define CLK_SET_RATE(name, nr, bitsname) \ | ||
1061 | static int clk_##name##_set_rate(struct clk *clk, unsigned long rate) \ | ||
1062 | { \ | ||
1063 | u32 reg, div, parent_rate; \ | ||
1064 | u32 pre = 0, post = 0; \ | ||
1065 | \ | ||
1066 | parent_rate = clk_get_rate(clk->parent); \ | ||
1067 | div = parent_rate / rate; \ | ||
1068 | \ | ||
1069 | if ((parent_rate / div) != rate) \ | ||
1070 | return -EINVAL; \ | ||
1071 | \ | ||
1072 | __calc_pre_post_dividers(div, &pre, &post, \ | ||
1073 | (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >> \ | ||
1074 | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1, \ | ||
1075 | (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >> \ | ||
1076 | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\ | ||
1077 | \ | ||
1078 | /* Set sdhc1 clock divider */ \ | ||
1079 | reg = __raw_readl(MXC_CCM_CSCDR##nr) & \ | ||
1080 | ~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK \ | ||
1081 | | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK); \ | ||
1082 | reg |= (post - 1) << \ | ||
1083 | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \ | ||
1084 | reg |= (pre - 1) << \ | ||
1085 | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \ | ||
1086 | __raw_writel(reg, MXC_CCM_CSCDR##nr); \ | ||
1087 | \ | ||
1088 | return 0; \ | ||
1089 | } | ||
1090 | |||
1091 | /* UART */ | ||
1092 | CLK_GET_RATE(uart, 1, UART) | ||
1093 | CLK_SET_PARENT(uart, 1, UART) | ||
1094 | |||
1095 | static struct clk uart_root_clk = { | ||
1096 | .parent = &pll2_sw_clk, | ||
1097 | .get_rate = clk_uart_get_rate, | ||
1098 | .set_parent = clk_uart_set_parent, | ||
1099 | }; | ||
1100 | |||
1101 | /* USBOH3 */ | ||
1102 | CLK_GET_RATE(usboh3, 1, USBOH3) | ||
1103 | CLK_SET_PARENT(usboh3, 1, USBOH3) | ||
1104 | |||
1105 | static struct clk usboh3_clk = { | ||
1106 | .parent = &pll2_sw_clk, | ||
1107 | .get_rate = clk_usboh3_get_rate, | ||
1108 | .set_parent = clk_usboh3_set_parent, | ||
1109 | .enable = _clk_ccgr_enable, | ||
1110 | .disable = _clk_ccgr_disable, | ||
1111 | .enable_reg = MXC_CCM_CCGR2, | ||
1112 | .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET, | ||
1113 | }; | ||
1114 | |||
1115 | static struct clk usb_ahb_clk = { | ||
1116 | .parent = &ipg_clk, | ||
1117 | .enable = _clk_ccgr_enable, | ||
1118 | .disable = _clk_ccgr_disable, | ||
1119 | .enable_reg = MXC_CCM_CCGR2, | ||
1120 | .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET, | ||
1121 | }; | ||
1122 | |||
1123 | static int clk_usb_phy1_set_parent(struct clk *clk, struct clk *parent) | ||
1124 | { | ||
1125 | u32 reg; | ||
1126 | |||
1127 | reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL; | ||
1128 | |||
1129 | if (parent == &pll3_sw_clk) | ||
1130 | reg |= 1 << MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET; | ||
1131 | |||
1132 | __raw_writel(reg, MXC_CCM_CSCMR1); | ||
1133 | |||
1134 | return 0; | ||
1135 | } | ||
1136 | |||
1137 | static struct clk usb_phy1_clk = { | ||
1138 | .parent = &pll3_sw_clk, | ||
1139 | .set_parent = clk_usb_phy1_set_parent, | ||
1140 | .enable = _clk_ccgr_enable, | ||
1141 | .enable_reg = MXC_CCM_CCGR2, | ||
1142 | .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET, | ||
1143 | .disable = _clk_ccgr_disable, | ||
1144 | }; | ||
1145 | |||
1146 | /* eCSPI */ | ||
1147 | CLK_GET_RATE(ecspi, 2, CSPI) | ||
1148 | CLK_SET_PARENT(ecspi, 1, CSPI) | ||
1149 | |||
1150 | static struct clk ecspi_main_clk = { | ||
1151 | .parent = &pll3_sw_clk, | ||
1152 | .get_rate = clk_ecspi_get_rate, | ||
1153 | .set_parent = clk_ecspi_set_parent, | ||
1154 | }; | ||
1155 | |||
1156 | /* eSDHC */ | ||
1157 | CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1) | ||
1158 | CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1) | ||
1159 | CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1) | ||
1160 | |||
1161 | /* mx51 specific */ | ||
1162 | CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2) | ||
1163 | CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2) | ||
1164 | CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2) | ||
1165 | |||
1166 | static int clk_esdhc3_set_parent(struct clk *clk, struct clk *parent) | ||
1167 | { | ||
1168 | u32 reg; | ||
1169 | |||
1170 | reg = __raw_readl(MXC_CCM_CSCMR1); | ||
1171 | if (parent == &esdhc1_clk) | ||
1172 | reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL; | ||
1173 | else if (parent == &esdhc2_clk) | ||
1174 | reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL; | ||
1175 | else | ||
1176 | return -EINVAL; | ||
1177 | __raw_writel(reg, MXC_CCM_CSCMR1); | ||
1178 | |||
1179 | return 0; | ||
1180 | } | ||
1181 | |||
1182 | static int clk_esdhc4_set_parent(struct clk *clk, struct clk *parent) | ||
1183 | { | ||
1184 | u32 reg; | ||
1185 | |||
1186 | reg = __raw_readl(MXC_CCM_CSCMR1); | ||
1187 | if (parent == &esdhc1_clk) | ||
1188 | reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; | ||
1189 | else if (parent == &esdhc2_clk) | ||
1190 | reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; | ||
1191 | else | ||
1192 | return -EINVAL; | ||
1193 | __raw_writel(reg, MXC_CCM_CSCMR1); | ||
1194 | |||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1198 | /* mx53 specific */ | ||
1199 | static int clk_esdhc2_mx53_set_parent(struct clk *clk, struct clk *parent) | ||
1200 | { | ||
1201 | u32 reg; | ||
1202 | |||
1203 | reg = __raw_readl(MXC_CCM_CSCMR1); | ||
1204 | if (parent == &esdhc1_clk) | ||
1205 | reg &= ~MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL; | ||
1206 | else if (parent == &esdhc3_mx53_clk) | ||
1207 | reg |= MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL; | ||
1208 | else | ||
1209 | return -EINVAL; | ||
1210 | __raw_writel(reg, MXC_CCM_CSCMR1); | ||
1211 | |||
1212 | return 0; | ||
1213 | } | ||
1214 | |||
1215 | CLK_GET_RATE(esdhc3_mx53, 1, ESDHC3_MX53) | ||
1216 | CLK_SET_PARENT(esdhc3_mx53, 1, ESDHC3_MX53) | ||
1217 | CLK_SET_RATE(esdhc3_mx53, 1, ESDHC3_MX53) | ||
1218 | |||
1219 | static int clk_esdhc4_mx53_set_parent(struct clk *clk, struct clk *parent) | ||
1220 | { | ||
1221 | u32 reg; | ||
1222 | |||
1223 | reg = __raw_readl(MXC_CCM_CSCMR1); | ||
1224 | if (parent == &esdhc1_clk) | ||
1225 | reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; | ||
1226 | else if (parent == &esdhc3_mx53_clk) | ||
1227 | reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; | ||
1228 | else | ||
1229 | return -EINVAL; | ||
1230 | __raw_writel(reg, MXC_CCM_CSCMR1); | ||
1231 | |||
1232 | return 0; | ||
1233 | } | ||
1234 | |||
1235 | #define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \ | ||
1236 | static struct clk name = { \ | ||
1237 | .id = i, \ | ||
1238 | .enable_reg = er, \ | ||
1239 | .enable_shift = es, \ | ||
1240 | .get_rate = gr, \ | ||
1241 | .set_rate = sr, \ | ||
1242 | .enable = e, \ | ||
1243 | .disable = d, \ | ||
1244 | .parent = p, \ | ||
1245 | .secondary = s, \ | ||
1246 | } | ||
1247 | |||
1248 | #define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \ | ||
1249 | DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable, _clk_ccgr_disable, p, s) | ||
1250 | |||
1251 | /* Shared peripheral bus arbiter */ | ||
1252 | DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET, | ||
1253 | NULL, NULL, &ipg_clk, NULL); | ||
1254 | |||
1255 | /* UART */ | ||
1256 | DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET, | ||
1257 | NULL, NULL, &ipg_clk, &aips_tz1_clk); | ||
1258 | DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET, | ||
1259 | NULL, NULL, &ipg_clk, &aips_tz1_clk); | ||
1260 | DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET, | ||
1261 | NULL, NULL, &ipg_clk, &spba_clk); | ||
1262 | DEFINE_CLOCK(uart4_ipg_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG4_OFFSET, | ||
1263 | NULL, NULL, &ipg_clk, &spba_clk); | ||
1264 | DEFINE_CLOCK(uart5_ipg_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG6_OFFSET, | ||
1265 | NULL, NULL, &ipg_clk, &spba_clk); | ||
1266 | DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET, | ||
1267 | NULL, NULL, &uart_root_clk, &uart1_ipg_clk); | ||
1268 | DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET, | ||
1269 | NULL, NULL, &uart_root_clk, &uart2_ipg_clk); | ||
1270 | DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET, | ||
1271 | NULL, NULL, &uart_root_clk, &uart3_ipg_clk); | ||
1272 | DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG5_OFFSET, | ||
1273 | NULL, NULL, &uart_root_clk, &uart4_ipg_clk); | ||
1274 | DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG7_OFFSET, | ||
1275 | NULL, NULL, &uart_root_clk, &uart5_ipg_clk); | ||
1276 | |||
1277 | /* GPT */ | ||
1278 | DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, | ||
1279 | NULL, NULL, &ipg_clk, NULL); | ||
1280 | DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, | ||
1281 | NULL, NULL, &ipg_clk, &gpt_ipg_clk); | ||
1282 | |||
1283 | DEFINE_CLOCK(pwm1_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG6_OFFSET, | ||
1284 | NULL, NULL, &ipg_perclk, NULL); | ||
1285 | DEFINE_CLOCK(pwm2_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG8_OFFSET, | ||
1286 | NULL, NULL, &ipg_perclk, NULL); | ||
1287 | |||
1288 | /* I2C */ | ||
1289 | DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET, | ||
1290 | NULL, NULL, &ipg_perclk, NULL); | ||
1291 | DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET, | ||
1292 | NULL, NULL, &ipg_perclk, NULL); | ||
1293 | DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET, | ||
1294 | NULL, NULL, &ipg_clk, NULL); | ||
1295 | DEFINE_CLOCK(i2c3_mx53_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET, | ||
1296 | NULL, NULL, &ipg_perclk, NULL); | ||
1297 | |||
1298 | /* FEC */ | ||
1299 | DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, | ||
1300 | NULL, NULL, &ipg_clk, NULL); | ||
1301 | |||
1302 | /* NFC */ | ||
1303 | DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET, | ||
1304 | clk_nfc, &emi_slow_clk, NULL); | ||
1305 | |||
1306 | /* SSI */ | ||
1307 | DEFINE_CLOCK(ssi1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG8_OFFSET, | ||
1308 | NULL, NULL, &ipg_clk, NULL); | ||
1309 | DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG9_OFFSET, | ||
1310 | NULL, NULL, &pll3_sw_clk, &ssi1_ipg_clk); | ||
1311 | DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET, | ||
1312 | NULL, NULL, &ipg_clk, NULL); | ||
1313 | DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET, | ||
1314 | NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk); | ||
1315 | DEFINE_CLOCK(ssi3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG12_OFFSET, | ||
1316 | NULL, NULL, &ipg_clk, NULL); | ||
1317 | DEFINE_CLOCK(ssi3_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG13_OFFSET, | ||
1318 | NULL, NULL, &pll3_sw_clk, &ssi3_ipg_clk); | ||
1319 | |||
1320 | /* eCSPI */ | ||
1321 | DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET, | ||
1322 | NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable, | ||
1323 | &ipg_clk, &spba_clk); | ||
1324 | DEFINE_CLOCK(ecspi1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG10_OFFSET, | ||
1325 | NULL, NULL, &ecspi_main_clk, &ecspi1_ipg_clk); | ||
1326 | DEFINE_CLOCK_FULL(ecspi2_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG11_OFFSET, | ||
1327 | NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable, | ||
1328 | &ipg_clk, &aips_tz2_clk); | ||
1329 | DEFINE_CLOCK(ecspi2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG12_OFFSET, | ||
1330 | NULL, NULL, &ecspi_main_clk, &ecspi2_ipg_clk); | ||
1331 | |||
1332 | /* CSPI */ | ||
1333 | DEFINE_CLOCK(cspi_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET, | ||
1334 | NULL, NULL, &ipg_clk, &aips_tz2_clk); | ||
1335 | DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET, | ||
1336 | NULL, NULL, &ipg_clk, &cspi_ipg_clk); | ||
1337 | |||
1338 | /* SDMA */ | ||
1339 | DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET, | ||
1340 | NULL, NULL, &ahb_clk, NULL); | ||
1341 | |||
1342 | /* eSDHC */ | ||
1343 | DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET, | ||
1344 | NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); | ||
1345 | DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET, | ||
1346 | clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk); | ||
1347 | DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET, | ||
1348 | NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); | ||
1349 | DEFINE_CLOCK_FULL(esdhc3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG4_OFFSET, | ||
1350 | NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); | ||
1351 | DEFINE_CLOCK_FULL(esdhc4_ipg_clk, 3, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG6_OFFSET, | ||
1352 | NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); | ||
1353 | |||
1354 | /* mx51 specific */ | ||
1355 | DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET, | ||
1356 | clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk); | ||
1357 | |||
1358 | static struct clk esdhc3_clk = { | ||
1359 | .id = 2, | ||
1360 | .parent = &esdhc1_clk, | ||
1361 | .set_parent = clk_esdhc3_set_parent, | ||
1362 | .enable_reg = MXC_CCM_CCGR3, | ||
1363 | .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET, | ||
1364 | .enable = _clk_max_enable, | ||
1365 | .disable = _clk_max_disable, | ||
1366 | .secondary = &esdhc3_ipg_clk, | ||
1367 | }; | ||
1368 | static struct clk esdhc4_clk = { | ||
1369 | .id = 3, | ||
1370 | .parent = &esdhc1_clk, | ||
1371 | .set_parent = clk_esdhc4_set_parent, | ||
1372 | .enable_reg = MXC_CCM_CCGR3, | ||
1373 | .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET, | ||
1374 | .enable = _clk_max_enable, | ||
1375 | .disable = _clk_max_disable, | ||
1376 | .secondary = &esdhc4_ipg_clk, | ||
1377 | }; | ||
1378 | |||
1379 | /* mx53 specific */ | ||
1380 | static struct clk esdhc2_mx53_clk = { | ||
1381 | .id = 2, | ||
1382 | .parent = &esdhc1_clk, | ||
1383 | .set_parent = clk_esdhc2_mx53_set_parent, | ||
1384 | .enable_reg = MXC_CCM_CCGR3, | ||
1385 | .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET, | ||
1386 | .enable = _clk_max_enable, | ||
1387 | .disable = _clk_max_disable, | ||
1388 | .secondary = &esdhc3_ipg_clk, | ||
1389 | }; | ||
1390 | |||
1391 | DEFINE_CLOCK_MAX(esdhc3_mx53_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG5_OFFSET, | ||
1392 | clk_esdhc3_mx53, &pll2_sw_clk, &esdhc2_ipg_clk); | ||
1393 | |||
1394 | static struct clk esdhc4_mx53_clk = { | ||
1395 | .id = 3, | ||
1396 | .parent = &esdhc1_clk, | ||
1397 | .set_parent = clk_esdhc4_mx53_set_parent, | ||
1398 | .enable_reg = MXC_CCM_CCGR3, | ||
1399 | .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET, | ||
1400 | .enable = _clk_max_enable, | ||
1401 | .disable = _clk_max_disable, | ||
1402 | .secondary = &esdhc4_ipg_clk, | ||
1403 | }; | ||
1404 | |||
1405 | static struct clk sata_clk = { | ||
1406 | .parent = &ipg_clk, | ||
1407 | .enable = _clk_max_enable, | ||
1408 | .enable_reg = MXC_CCM_CCGR4, | ||
1409 | .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET, | ||
1410 | .disable = _clk_max_disable, | ||
1411 | }; | ||
1412 | |||
1413 | static struct clk ahci_phy_clk = { | ||
1414 | .parent = &usb_phy1_clk, | ||
1415 | }; | ||
1416 | |||
1417 | static struct clk ahci_dma_clk = { | ||
1418 | .parent = &ahb_clk, | ||
1419 | }; | ||
1420 | |||
1421 | DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk); | ||
1422 | DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk); | ||
1423 | DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk); | ||
1424 | |||
1425 | /* IPU */ | ||
1426 | DEFINE_CLOCK_FULL(ipu_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG5_OFFSET, | ||
1427 | NULL, NULL, clk_ipu_enable, clk_ipu_disable, &ahb_clk, &ipu_sec_clk); | ||
1428 | |||
1429 | DEFINE_CLOCK_FULL(emi_fast_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG7_OFFSET, | ||
1430 | NULL, NULL, _clk_ccgr_enable, _clk_ccgr_disable_inwait, | ||
1431 | &ddr_clk, NULL); | ||
1432 | |||
1433 | DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET, | ||
1434 | NULL, NULL, &pll3_sw_clk, NULL); | ||
1435 | DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET, | ||
1436 | NULL, NULL, &pll3_sw_clk, NULL); | ||
1437 | |||
1438 | /* PATA */ | ||
1439 | DEFINE_CLOCK(pata_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG0_OFFSET, | ||
1440 | NULL, NULL, &ipg_clk, &spba_clk); | ||
1441 | |||
1442 | #define _REGISTER_CLOCK(d, n, c) \ | ||
1443 | { \ | ||
1444 | .dev_id = d, \ | ||
1445 | .con_id = n, \ | ||
1446 | .clk = &c, \ | ||
1447 | }, | ||
1448 | |||
1449 | static struct clk_lookup mx51_lookups[] = { | ||
1450 | /* i.mx51 has the i.mx21 type uart */ | ||
1451 | _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) | ||
1452 | _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) | ||
1453 | _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) | ||
1454 | _REGISTER_CLOCK(NULL, "gpt", gpt_clk) | ||
1455 | /* i.mx51 has the i.mx27 type fec */ | ||
1456 | _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) | ||
1457 | _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk) | ||
1458 | _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk) | ||
1459 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) | ||
1460 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) | ||
1461 | _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk) | ||
1462 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk) | ||
1463 | _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_ahb_clk) | ||
1464 | _REGISTER_CLOCK("mxc-ehci.0", "usb_phy1", usb_phy1_clk) | ||
1465 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk) | ||
1466 | _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_ahb_clk) | ||
1467 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usboh3_clk) | ||
1468 | _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_ahb_clk) | ||
1469 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk) | ||
1470 | _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk) | ||
1471 | _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk) | ||
1472 | _REGISTER_CLOCK("mxc_nand", NULL, nfc_clk) | ||
1473 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) | ||
1474 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) | ||
1475 | _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk) | ||
1476 | /* i.mx51 has the i.mx35 type sdma */ | ||
1477 | _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) | ||
1478 | _REGISTER_CLOCK(NULL, "ckih", ckih_clk) | ||
1479 | _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk) | ||
1480 | _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk) | ||
1481 | _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) | ||
1482 | _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) | ||
1483 | /* i.mx51 has the i.mx35 type cspi */ | ||
1484 | _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk) | ||
1485 | _REGISTER_CLOCK("sdhci-esdhc-imx51.0", NULL, esdhc1_clk) | ||
1486 | _REGISTER_CLOCK("sdhci-esdhc-imx51.1", NULL, esdhc2_clk) | ||
1487 | _REGISTER_CLOCK("sdhci-esdhc-imx51.2", NULL, esdhc3_clk) | ||
1488 | _REGISTER_CLOCK("sdhci-esdhc-imx51.3", NULL, esdhc4_clk) | ||
1489 | _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk) | ||
1490 | _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) | ||
1491 | _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk) | ||
1492 | _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk) | ||
1493 | _REGISTER_CLOCK(NULL, "mipi_hsp", mipi_hsp_clk) | ||
1494 | _REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk) | ||
1495 | _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk) | ||
1496 | _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk) | ||
1497 | _REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk) | ||
1498 | _REGISTER_CLOCK("pata_imx", NULL, pata_clk) | ||
1499 | }; | ||
1500 | |||
1501 | static struct clk_lookup mx53_lookups[] = { | ||
1502 | /* i.mx53 has the i.mx21 type uart */ | ||
1503 | _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) | ||
1504 | _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) | ||
1505 | _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) | ||
1506 | _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) | ||
1507 | _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) | ||
1508 | _REGISTER_CLOCK(NULL, "gpt", gpt_clk) | ||
1509 | /* i.mx53 has the i.mx25 type fec */ | ||
1510 | _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk) | ||
1511 | _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) | ||
1512 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) | ||
1513 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) | ||
1514 | _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_mx53_clk) | ||
1515 | /* i.mx53 has the i.mx51 type ecspi */ | ||
1516 | _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) | ||
1517 | _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) | ||
1518 | /* i.mx53 has the i.mx25 type cspi */ | ||
1519 | _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk) | ||
1520 | _REGISTER_CLOCK("sdhci-esdhc-imx53.0", NULL, esdhc1_clk) | ||
1521 | _REGISTER_CLOCK("sdhci-esdhc-imx53.1", NULL, esdhc2_mx53_clk) | ||
1522 | _REGISTER_CLOCK("sdhci-esdhc-imx53.2", NULL, esdhc3_mx53_clk) | ||
1523 | _REGISTER_CLOCK("sdhci-esdhc-imx53.3", NULL, esdhc4_mx53_clk) | ||
1524 | _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk) | ||
1525 | _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk) | ||
1526 | /* i.mx53 has the i.mx35 type sdma */ | ||
1527 | _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) | ||
1528 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) | ||
1529 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) | ||
1530 | _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk) | ||
1531 | _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk) | ||
1532 | _REGISTER_CLOCK("pata_imx", NULL, pata_clk) | ||
1533 | _REGISTER_CLOCK("imx53-ahci.0", "ahci", sata_clk) | ||
1534 | _REGISTER_CLOCK("imx53-ahci.0", "ahci_phy", ahci_phy_clk) | ||
1535 | _REGISTER_CLOCK("imx53-ahci.0", "ahci_dma", ahci_dma_clk) | ||
1536 | }; | ||
1537 | |||
1538 | static void clk_tree_init(void) | ||
1539 | { | ||
1540 | u32 reg; | ||
1541 | |||
1542 | ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk); | ||
1543 | |||
1544 | /* | ||
1545 | * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at | ||
1546 | * 8MHz, its derived from lp_apm. | ||
1547 | * | ||
1548 | * FIXME: Verify if true for all boards | ||
1549 | */ | ||
1550 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
1551 | reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK; | ||
1552 | reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK; | ||
1553 | reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK; | ||
1554 | reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET); | ||
1555 | __raw_writel(reg, MXC_CCM_CBCDR); | ||
1556 | } | ||
1557 | |||
1558 | int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, | ||
1559 | unsigned long ckih1, unsigned long ckih2) | ||
1560 | { | ||
1561 | int i; | ||
1562 | |||
1563 | external_low_reference = ckil; | ||
1564 | external_high_reference = ckih1; | ||
1565 | ckih2_reference = ckih2; | ||
1566 | oscillator_reference = osc; | ||
1567 | |||
1568 | for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++) | ||
1569 | clkdev_add(&mx51_lookups[i]); | ||
1570 | |||
1571 | clk_tree_init(); | ||
1572 | |||
1573 | clk_enable(&cpu_clk); | ||
1574 | clk_enable(&main_bus_clk); | ||
1575 | |||
1576 | clk_enable(&iim_clk); | ||
1577 | imx_print_silicon_rev("i.MX51", mx51_revision()); | ||
1578 | clk_disable(&iim_clk); | ||
1579 | |||
1580 | /* move usb_phy_clk to 24MHz */ | ||
1581 | clk_set_parent(&usb_phy1_clk, &osc_clk); | ||
1582 | |||
1583 | /* set the usboh3_clk parent to pll2_sw_clk */ | ||
1584 | clk_set_parent(&usboh3_clk, &pll2_sw_clk); | ||
1585 | |||
1586 | /* Set SDHC parents to be PLL2 */ | ||
1587 | clk_set_parent(&esdhc1_clk, &pll2_sw_clk); | ||
1588 | clk_set_parent(&esdhc2_clk, &pll2_sw_clk); | ||
1589 | |||
1590 | /* set SDHC root clock as 166.25MHZ*/ | ||
1591 | clk_set_rate(&esdhc1_clk, 166250000); | ||
1592 | clk_set_rate(&esdhc2_clk, 166250000); | ||
1593 | |||
1594 | /* System timer */ | ||
1595 | mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), | ||
1596 | MX51_INT_GPT); | ||
1597 | return 0; | ||
1598 | } | ||
1599 | |||
1600 | int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, | ||
1601 | unsigned long ckih1, unsigned long ckih2) | ||
1602 | { | ||
1603 | int i; | ||
1604 | |||
1605 | external_low_reference = ckil; | ||
1606 | external_high_reference = ckih1; | ||
1607 | ckih2_reference = ckih2; | ||
1608 | oscillator_reference = osc; | ||
1609 | |||
1610 | for (i = 0; i < ARRAY_SIZE(mx53_lookups); i++) | ||
1611 | clkdev_add(&mx53_lookups[i]); | ||
1612 | |||
1613 | clk_tree_init(); | ||
1614 | |||
1615 | clk_set_parent(&uart_root_clk, &pll3_sw_clk); | ||
1616 | clk_enable(&cpu_clk); | ||
1617 | clk_enable(&main_bus_clk); | ||
1618 | |||
1619 | clk_enable(&iim_clk); | ||
1620 | imx_print_silicon_rev("i.MX53", mx53_revision()); | ||
1621 | clk_disable(&iim_clk); | ||
1622 | |||
1623 | /* Set SDHC parents to be PLL2 */ | ||
1624 | clk_set_parent(&esdhc1_clk, &pll2_sw_clk); | ||
1625 | clk_set_parent(&esdhc3_mx53_clk, &pll2_sw_clk); | ||
1626 | |||
1627 | /* set SDHC root clock as 200MHZ*/ | ||
1628 | clk_set_rate(&esdhc1_clk, 200000000); | ||
1629 | clk_set_rate(&esdhc3_mx53_clk, 200000000); | ||
1630 | |||
1631 | /* System timer */ | ||
1632 | mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), | ||
1633 | MX53_INT_GPT); | ||
1634 | return 0; | ||
1635 | } | ||
1636 | |||
1637 | #ifdef CONFIG_OF | ||
1638 | static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc, | ||
1639 | unsigned long *ckih1, unsigned long *ckih2) | ||
1640 | { | ||
1641 | struct device_node *np; | ||
1642 | |||
1643 | /* retrieve the freqency of fixed clocks from device tree */ | ||
1644 | for_each_compatible_node(np, NULL, "fixed-clock") { | ||
1645 | u32 rate; | ||
1646 | if (of_property_read_u32(np, "clock-frequency", &rate)) | ||
1647 | continue; | ||
1648 | |||
1649 | if (of_device_is_compatible(np, "fsl,imx-ckil")) | ||
1650 | *ckil = rate; | ||
1651 | else if (of_device_is_compatible(np, "fsl,imx-osc")) | ||
1652 | *osc = rate; | ||
1653 | else if (of_device_is_compatible(np, "fsl,imx-ckih1")) | ||
1654 | *ckih1 = rate; | ||
1655 | else if (of_device_is_compatible(np, "fsl,imx-ckih2")) | ||
1656 | *ckih2 = rate; | ||
1657 | } | ||
1658 | } | ||
1659 | |||
1660 | int __init mx51_clocks_init_dt(void) | ||
1661 | { | ||
1662 | unsigned long ckil, osc, ckih1, ckih2; | ||
1663 | |||
1664 | clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2); | ||
1665 | return mx51_clocks_init(ckil, osc, ckih1, ckih2); | ||
1666 | } | ||
1667 | |||
1668 | int __init mx53_clocks_init_dt(void) | ||
1669 | { | ||
1670 | unsigned long ckil, osc, ckih1, ckih2; | ||
1671 | |||
1672 | clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2); | ||
1673 | return mx53_clocks_init(ckil, osc, ckih1, ckih2); | ||
1674 | } | ||
1675 | #endif | ||