aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos4/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos4/clock.c')
-rw-r--r--arch/arm/mach-exynos4/clock.c1216
1 files changed, 1216 insertions, 0 deletions
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
new file mode 100644
index 000000000000..871f9d508fde
--- /dev/null
+++ b/arch/arm/mach-exynos4/clock.c
@@ -0,0 +1,1216 @@
1/* linux/arch/arm/mach-exynos4/clock.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - Clock support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/err.h>
15#include <linux/io.h>
16
17#include <plat/cpu-freq.h>
18#include <plat/clock.h>
19#include <plat/cpu.h>
20#include <plat/pll.h>
21#include <plat/s5p-clock.h>
22#include <plat/clock-clksrc.h>
23
24#include <mach/map.h>
25#include <mach/regs-clock.h>
26#include <mach/sysmmu.h>
27
28static struct clk clk_sclk_hdmi27m = {
29 .name = "sclk_hdmi27m",
30 .id = -1,
31 .rate = 27000000,
32};
33
34static struct clk clk_sclk_hdmiphy = {
35 .name = "sclk_hdmiphy",
36 .id = -1,
37};
38
39static struct clk clk_sclk_usbphy0 = {
40 .name = "sclk_usbphy0",
41 .id = -1,
42 .rate = 27000000,
43};
44
45static struct clk clk_sclk_usbphy1 = {
46 .name = "sclk_usbphy1",
47 .id = -1,
48};
49
50static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
51{
52 return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
53}
54
55static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
56{
57 return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
58}
59
60static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
61{
62 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
63}
64
65static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
66{
67 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
68}
69
70static int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
71{
72 return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
73}
74
75static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
76{
77 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
78}
79
80static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
81{
82 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
83}
84
85static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
86{
87 return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
88}
89
90static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
91{
92 return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
93}
94
95static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
96{
97 return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable);
98}
99
100static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
101{
102 return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
103}
104
105static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
106{
107 return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
108}
109
110static int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
111{
112 return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
113}
114
115static int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
116{
117 return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
118}
119
120static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
121{
122 return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
123}
124
125static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
126{
127 return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
128}
129
130/* Core list of CMU_CPU side */
131
132static struct clksrc_clk clk_mout_apll = {
133 .clk = {
134 .name = "mout_apll",
135 .id = -1,
136 },
137 .sources = &clk_src_apll,
138 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
139};
140
141static struct clksrc_clk clk_sclk_apll = {
142 .clk = {
143 .name = "sclk_apll",
144 .id = -1,
145 .parent = &clk_mout_apll.clk,
146 },
147 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
148};
149
150static struct clksrc_clk clk_mout_epll = {
151 .clk = {
152 .name = "mout_epll",
153 .id = -1,
154 },
155 .sources = &clk_src_epll,
156 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
157};
158
159static struct clksrc_clk clk_mout_mpll = {
160 .clk = {
161 .name = "mout_mpll",
162 .id = -1,
163 },
164 .sources = &clk_src_mpll,
165 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 8, .size = 1 },
166};
167
168static struct clk *clkset_moutcore_list[] = {
169 [0] = &clk_mout_apll.clk,
170 [1] = &clk_mout_mpll.clk,
171};
172
173static struct clksrc_sources clkset_moutcore = {
174 .sources = clkset_moutcore_list,
175 .nr_sources = ARRAY_SIZE(clkset_moutcore_list),
176};
177
178static struct clksrc_clk clk_moutcore = {
179 .clk = {
180 .name = "moutcore",
181 .id = -1,
182 },
183 .sources = &clkset_moutcore,
184 .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
185};
186
187static struct clksrc_clk clk_coreclk = {
188 .clk = {
189 .name = "core_clk",
190 .id = -1,
191 .parent = &clk_moutcore.clk,
192 },
193 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
194};
195
196static struct clksrc_clk clk_armclk = {
197 .clk = {
198 .name = "armclk",
199 .id = -1,
200 .parent = &clk_coreclk.clk,
201 },
202};
203
204static struct clksrc_clk clk_aclk_corem0 = {
205 .clk = {
206 .name = "aclk_corem0",
207 .id = -1,
208 .parent = &clk_coreclk.clk,
209 },
210 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
211};
212
213static struct clksrc_clk clk_aclk_cores = {
214 .clk = {
215 .name = "aclk_cores",
216 .id = -1,
217 .parent = &clk_coreclk.clk,
218 },
219 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
220};
221
222static struct clksrc_clk clk_aclk_corem1 = {
223 .clk = {
224 .name = "aclk_corem1",
225 .id = -1,
226 .parent = &clk_coreclk.clk,
227 },
228 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
229};
230
231static struct clksrc_clk clk_periphclk = {
232 .clk = {
233 .name = "periphclk",
234 .id = -1,
235 .parent = &clk_coreclk.clk,
236 },
237 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
238};
239
240/* Core list of CMU_CORE side */
241
242static struct clk *clkset_corebus_list[] = {
243 [0] = &clk_mout_mpll.clk,
244 [1] = &clk_sclk_apll.clk,
245};
246
247static struct clksrc_sources clkset_mout_corebus = {
248 .sources = clkset_corebus_list,
249 .nr_sources = ARRAY_SIZE(clkset_corebus_list),
250};
251
252static struct clksrc_clk clk_mout_corebus = {
253 .clk = {
254 .name = "mout_corebus",
255 .id = -1,
256 },
257 .sources = &clkset_mout_corebus,
258 .reg_src = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
259};
260
261static struct clksrc_clk clk_sclk_dmc = {
262 .clk = {
263 .name = "sclk_dmc",
264 .id = -1,
265 .parent = &clk_mout_corebus.clk,
266 },
267 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
268};
269
270static struct clksrc_clk clk_aclk_cored = {
271 .clk = {
272 .name = "aclk_cored",
273 .id = -1,
274 .parent = &clk_sclk_dmc.clk,
275 },
276 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
277};
278
279static struct clksrc_clk clk_aclk_corep = {
280 .clk = {
281 .name = "aclk_corep",
282 .id = -1,
283 .parent = &clk_aclk_cored.clk,
284 },
285 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
286};
287
288static struct clksrc_clk clk_aclk_acp = {
289 .clk = {
290 .name = "aclk_acp",
291 .id = -1,
292 .parent = &clk_mout_corebus.clk,
293 },
294 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
295};
296
297static struct clksrc_clk clk_pclk_acp = {
298 .clk = {
299 .name = "pclk_acp",
300 .id = -1,
301 .parent = &clk_aclk_acp.clk,
302 },
303 .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
304};
305
306/* Core list of CMU_TOP side */
307
308static struct clk *clkset_aclk_top_list[] = {
309 [0] = &clk_mout_mpll.clk,
310 [1] = &clk_sclk_apll.clk,
311};
312
313static struct clksrc_sources clkset_aclk = {
314 .sources = clkset_aclk_top_list,
315 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
316};
317
318static struct clksrc_clk clk_aclk_200 = {
319 .clk = {
320 .name = "aclk_200",
321 .id = -1,
322 },
323 .sources = &clkset_aclk,
324 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
325 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
326};
327
328static struct clksrc_clk clk_aclk_100 = {
329 .clk = {
330 .name = "aclk_100",
331 .id = -1,
332 },
333 .sources = &clkset_aclk,
334 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
335 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
336};
337
338static struct clksrc_clk clk_aclk_160 = {
339 .clk = {
340 .name = "aclk_160",
341 .id = -1,
342 },
343 .sources = &clkset_aclk,
344 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
345 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
346};
347
348static struct clksrc_clk clk_aclk_133 = {
349 .clk = {
350 .name = "aclk_133",
351 .id = -1,
352 },
353 .sources = &clkset_aclk,
354 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
355 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
356};
357
358static struct clk *clkset_vpllsrc_list[] = {
359 [0] = &clk_fin_vpll,
360 [1] = &clk_sclk_hdmi27m,
361};
362
363static struct clksrc_sources clkset_vpllsrc = {
364 .sources = clkset_vpllsrc_list,
365 .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list),
366};
367
368static struct clksrc_clk clk_vpllsrc = {
369 .clk = {
370 .name = "vpll_src",
371 .id = -1,
372 .enable = exynos4_clksrc_mask_top_ctrl,
373 .ctrlbit = (1 << 0),
374 },
375 .sources = &clkset_vpllsrc,
376 .reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
377};
378
379static struct clk *clkset_sclk_vpll_list[] = {
380 [0] = &clk_vpllsrc.clk,
381 [1] = &clk_fout_vpll,
382};
383
384static struct clksrc_sources clkset_sclk_vpll = {
385 .sources = clkset_sclk_vpll_list,
386 .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list),
387};
388
389static struct clksrc_clk clk_sclk_vpll = {
390 .clk = {
391 .name = "sclk_vpll",
392 .id = -1,
393 },
394 .sources = &clkset_sclk_vpll,
395 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
396};
397
398static struct clk init_clocks_off[] = {
399 {
400 .name = "timers",
401 .id = -1,
402 .parent = &clk_aclk_100.clk,
403 .enable = exynos4_clk_ip_peril_ctrl,
404 .ctrlbit = (1<<24),
405 }, {
406 .name = "csis",
407 .id = 0,
408 .enable = exynos4_clk_ip_cam_ctrl,
409 .ctrlbit = (1 << 4),
410 }, {
411 .name = "csis",
412 .id = 1,
413 .enable = exynos4_clk_ip_cam_ctrl,
414 .ctrlbit = (1 << 5),
415 }, {
416 .name = "fimc",
417 .id = 0,
418 .enable = exynos4_clk_ip_cam_ctrl,
419 .ctrlbit = (1 << 0),
420 }, {
421 .name = "fimc",
422 .id = 1,
423 .enable = exynos4_clk_ip_cam_ctrl,
424 .ctrlbit = (1 << 1),
425 }, {
426 .name = "fimc",
427 .id = 2,
428 .enable = exynos4_clk_ip_cam_ctrl,
429 .ctrlbit = (1 << 2),
430 }, {
431 .name = "fimc",
432 .id = 3,
433 .enable = exynos4_clk_ip_cam_ctrl,
434 .ctrlbit = (1 << 3),
435 }, {
436 .name = "fimd",
437 .id = 0,
438 .enable = exynos4_clk_ip_lcd0_ctrl,
439 .ctrlbit = (1 << 0),
440 }, {
441 .name = "fimd",
442 .id = 1,
443 .enable = exynos4_clk_ip_lcd1_ctrl,
444 .ctrlbit = (1 << 0),
445 }, {
446 .name = "sataphy",
447 .id = -1,
448 .parent = &clk_aclk_133.clk,
449 .enable = exynos4_clk_ip_fsys_ctrl,
450 .ctrlbit = (1 << 3),
451 }, {
452 .name = "hsmmc",
453 .id = 0,
454 .parent = &clk_aclk_133.clk,
455 .enable = exynos4_clk_ip_fsys_ctrl,
456 .ctrlbit = (1 << 5),
457 }, {
458 .name = "hsmmc",
459 .id = 1,
460 .parent = &clk_aclk_133.clk,
461 .enable = exynos4_clk_ip_fsys_ctrl,
462 .ctrlbit = (1 << 6),
463 }, {
464 .name = "hsmmc",
465 .id = 2,
466 .parent = &clk_aclk_133.clk,
467 .enable = exynos4_clk_ip_fsys_ctrl,
468 .ctrlbit = (1 << 7),
469 }, {
470 .name = "hsmmc",
471 .id = 3,
472 .parent = &clk_aclk_133.clk,
473 .enable = exynos4_clk_ip_fsys_ctrl,
474 .ctrlbit = (1 << 8),
475 }, {
476 .name = "hsmmc",
477 .id = 4,
478 .parent = &clk_aclk_133.clk,
479 .enable = exynos4_clk_ip_fsys_ctrl,
480 .ctrlbit = (1 << 9),
481 }, {
482 .name = "sata",
483 .id = -1,
484 .parent = &clk_aclk_133.clk,
485 .enable = exynos4_clk_ip_fsys_ctrl,
486 .ctrlbit = (1 << 10),
487 }, {
488 .name = "pdma",
489 .id = 0,
490 .enable = exynos4_clk_ip_fsys_ctrl,
491 .ctrlbit = (1 << 0),
492 }, {
493 .name = "pdma",
494 .id = 1,
495 .enable = exynos4_clk_ip_fsys_ctrl,
496 .ctrlbit = (1 << 1),
497 }, {
498 .name = "adc",
499 .id = -1,
500 .enable = exynos4_clk_ip_peril_ctrl,
501 .ctrlbit = (1 << 15),
502 }, {
503 .name = "keypad",
504 .id = -1,
505 .enable = exynos4_clk_ip_perir_ctrl,
506 .ctrlbit = (1 << 16),
507 }, {
508 .name = "rtc",
509 .id = -1,
510 .enable = exynos4_clk_ip_perir_ctrl,
511 .ctrlbit = (1 << 15),
512 }, {
513 .name = "watchdog",
514 .id = -1,
515 .parent = &clk_aclk_100.clk,
516 .enable = exynos4_clk_ip_perir_ctrl,
517 .ctrlbit = (1 << 14),
518 }, {
519 .name = "usbhost",
520 .id = -1,
521 .enable = exynos4_clk_ip_fsys_ctrl ,
522 .ctrlbit = (1 << 12),
523 }, {
524 .name = "otg",
525 .id = -1,
526 .enable = exynos4_clk_ip_fsys_ctrl,
527 .ctrlbit = (1 << 13),
528 }, {
529 .name = "spi",
530 .id = 0,
531 .enable = exynos4_clk_ip_peril_ctrl,
532 .ctrlbit = (1 << 16),
533 }, {
534 .name = "spi",
535 .id = 1,
536 .enable = exynos4_clk_ip_peril_ctrl,
537 .ctrlbit = (1 << 17),
538 }, {
539 .name = "spi",
540 .id = 2,
541 .enable = exynos4_clk_ip_peril_ctrl,
542 .ctrlbit = (1 << 18),
543 }, {
544 .name = "iis",
545 .id = 0,
546 .enable = exynos4_clk_ip_peril_ctrl,
547 .ctrlbit = (1 << 19),
548 }, {
549 .name = "iis",
550 .id = 1,
551 .enable = exynos4_clk_ip_peril_ctrl,
552 .ctrlbit = (1 << 20),
553 }, {
554 .name = "iis",
555 .id = 2,
556 .enable = exynos4_clk_ip_peril_ctrl,
557 .ctrlbit = (1 << 21),
558 }, {
559 .name = "ac97",
560 .id = -1,
561 .enable = exynos4_clk_ip_peril_ctrl,
562 .ctrlbit = (1 << 27),
563 }, {
564 .name = "fimg2d",
565 .id = -1,
566 .enable = exynos4_clk_ip_image_ctrl,
567 .ctrlbit = (1 << 0),
568 }, {
569 .name = "i2c",
570 .id = 0,
571 .parent = &clk_aclk_100.clk,
572 .enable = exynos4_clk_ip_peril_ctrl,
573 .ctrlbit = (1 << 6),
574 }, {
575 .name = "i2c",
576 .id = 1,
577 .parent = &clk_aclk_100.clk,
578 .enable = exynos4_clk_ip_peril_ctrl,
579 .ctrlbit = (1 << 7),
580 }, {
581 .name = "i2c",
582 .id = 2,
583 .parent = &clk_aclk_100.clk,
584 .enable = exynos4_clk_ip_peril_ctrl,
585 .ctrlbit = (1 << 8),
586 }, {
587 .name = "i2c",
588 .id = 3,
589 .parent = &clk_aclk_100.clk,
590 .enable = exynos4_clk_ip_peril_ctrl,
591 .ctrlbit = (1 << 9),
592 }, {
593 .name = "i2c",
594 .id = 4,
595 .parent = &clk_aclk_100.clk,
596 .enable = exynos4_clk_ip_peril_ctrl,
597 .ctrlbit = (1 << 10),
598 }, {
599 .name = "i2c",
600 .id = 5,
601 .parent = &clk_aclk_100.clk,
602 .enable = exynos4_clk_ip_peril_ctrl,
603 .ctrlbit = (1 << 11),
604 }, {
605 .name = "i2c",
606 .id = 6,
607 .parent = &clk_aclk_100.clk,
608 .enable = exynos4_clk_ip_peril_ctrl,
609 .ctrlbit = (1 << 12),
610 }, {
611 .name = "i2c",
612 .id = 7,
613 .parent = &clk_aclk_100.clk,
614 .enable = exynos4_clk_ip_peril_ctrl,
615 .ctrlbit = (1 << 13),
616 }, {
617 .name = "SYSMMU_MDMA",
618 .id = -1,
619 .enable = exynos4_clk_ip_image_ctrl,
620 .ctrlbit = (1 << 5),
621 }, {
622 .name = "SYSMMU_FIMC0",
623 .id = -1,
624 .enable = exynos4_clk_ip_cam_ctrl,
625 .ctrlbit = (1 << 7),
626 }, {
627 .name = "SYSMMU_FIMC1",
628 .id = -1,
629 .enable = exynos4_clk_ip_cam_ctrl,
630 .ctrlbit = (1 << 8),
631 }, {
632 .name = "SYSMMU_FIMC2",
633 .id = -1,
634 .enable = exynos4_clk_ip_cam_ctrl,
635 .ctrlbit = (1 << 9),
636 }, {
637 .name = "SYSMMU_FIMC3",
638 .id = -1,
639 .enable = exynos4_clk_ip_cam_ctrl,
640 .ctrlbit = (1 << 10),
641 }, {
642 .name = "SYSMMU_JPEG",
643 .id = -1,
644 .enable = exynos4_clk_ip_cam_ctrl,
645 .ctrlbit = (1 << 11),
646 }, {
647 .name = "SYSMMU_FIMD0",
648 .id = -1,
649 .enable = exynos4_clk_ip_lcd0_ctrl,
650 .ctrlbit = (1 << 4),
651 }, {
652 .name = "SYSMMU_FIMD1",
653 .id = -1,
654 .enable = exynos4_clk_ip_lcd1_ctrl,
655 .ctrlbit = (1 << 4),
656 }, {
657 .name = "SYSMMU_PCIe",
658 .id = -1,
659 .enable = exynos4_clk_ip_fsys_ctrl,
660 .ctrlbit = (1 << 18),
661 }, {
662 .name = "SYSMMU_G2D",
663 .id = -1,
664 .enable = exynos4_clk_ip_image_ctrl,
665 .ctrlbit = (1 << 3),
666 }, {
667 .name = "SYSMMU_ROTATOR",
668 .id = -1,
669 .enable = exynos4_clk_ip_image_ctrl,
670 .ctrlbit = (1 << 4),
671 }, {
672 .name = "SYSMMU_TV",
673 .id = -1,
674 .enable = exynos4_clk_ip_tv_ctrl,
675 .ctrlbit = (1 << 4),
676 }, {
677 .name = "SYSMMU_MFC_L",
678 .id = -1,
679 .enable = exynos4_clk_ip_mfc_ctrl,
680 .ctrlbit = (1 << 1),
681 }, {
682 .name = "SYSMMU_MFC_R",
683 .id = -1,
684 .enable = exynos4_clk_ip_mfc_ctrl,
685 .ctrlbit = (1 << 2),
686 }
687};
688
689static struct clk init_clocks[] = {
690 {
691 .name = "uart",
692 .id = 0,
693 .enable = exynos4_clk_ip_peril_ctrl,
694 .ctrlbit = (1 << 0),
695 }, {
696 .name = "uart",
697 .id = 1,
698 .enable = exynos4_clk_ip_peril_ctrl,
699 .ctrlbit = (1 << 1),
700 }, {
701 .name = "uart",
702 .id = 2,
703 .enable = exynos4_clk_ip_peril_ctrl,
704 .ctrlbit = (1 << 2),
705 }, {
706 .name = "uart",
707 .id = 3,
708 .enable = exynos4_clk_ip_peril_ctrl,
709 .ctrlbit = (1 << 3),
710 }, {
711 .name = "uart",
712 .id = 4,
713 .enable = exynos4_clk_ip_peril_ctrl,
714 .ctrlbit = (1 << 4),
715 }, {
716 .name = "uart",
717 .id = 5,
718 .enable = exynos4_clk_ip_peril_ctrl,
719 .ctrlbit = (1 << 5),
720 }
721};
722
723static struct clk *clkset_group_list[] = {
724 [0] = &clk_ext_xtal_mux,
725 [1] = &clk_xusbxti,
726 [2] = &clk_sclk_hdmi27m,
727 [3] = &clk_sclk_usbphy0,
728 [4] = &clk_sclk_usbphy1,
729 [5] = &clk_sclk_hdmiphy,
730 [6] = &clk_mout_mpll.clk,
731 [7] = &clk_mout_epll.clk,
732 [8] = &clk_sclk_vpll.clk,
733};
734
735static struct clksrc_sources clkset_group = {
736 .sources = clkset_group_list,
737 .nr_sources = ARRAY_SIZE(clkset_group_list),
738};
739
740static struct clk *clkset_mout_g2d0_list[] = {
741 [0] = &clk_mout_mpll.clk,
742 [1] = &clk_sclk_apll.clk,
743};
744
745static struct clksrc_sources clkset_mout_g2d0 = {
746 .sources = clkset_mout_g2d0_list,
747 .nr_sources = ARRAY_SIZE(clkset_mout_g2d0_list),
748};
749
750static struct clksrc_clk clk_mout_g2d0 = {
751 .clk = {
752 .name = "mout_g2d0",
753 .id = -1,
754 },
755 .sources = &clkset_mout_g2d0,
756 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
757};
758
759static struct clk *clkset_mout_g2d1_list[] = {
760 [0] = &clk_mout_epll.clk,
761 [1] = &clk_sclk_vpll.clk,
762};
763
764static struct clksrc_sources clkset_mout_g2d1 = {
765 .sources = clkset_mout_g2d1_list,
766 .nr_sources = ARRAY_SIZE(clkset_mout_g2d1_list),
767};
768
769static struct clksrc_clk clk_mout_g2d1 = {
770 .clk = {
771 .name = "mout_g2d1",
772 .id = -1,
773 },
774 .sources = &clkset_mout_g2d1,
775 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
776};
777
778static struct clk *clkset_mout_g2d_list[] = {
779 [0] = &clk_mout_g2d0.clk,
780 [1] = &clk_mout_g2d1.clk,
781};
782
783static struct clksrc_sources clkset_mout_g2d = {
784 .sources = clkset_mout_g2d_list,
785 .nr_sources = ARRAY_SIZE(clkset_mout_g2d_list),
786};
787
788static struct clksrc_clk clk_dout_mmc0 = {
789 .clk = {
790 .name = "dout_mmc0",
791 .id = -1,
792 },
793 .sources = &clkset_group,
794 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
795 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
796};
797
798static struct clksrc_clk clk_dout_mmc1 = {
799 .clk = {
800 .name = "dout_mmc1",
801 .id = -1,
802 },
803 .sources = &clkset_group,
804 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
805 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
806};
807
808static struct clksrc_clk clk_dout_mmc2 = {
809 .clk = {
810 .name = "dout_mmc2",
811 .id = -1,
812 },
813 .sources = &clkset_group,
814 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
815 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
816};
817
818static struct clksrc_clk clk_dout_mmc3 = {
819 .clk = {
820 .name = "dout_mmc3",
821 .id = -1,
822 },
823 .sources = &clkset_group,
824 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
825 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
826};
827
828static struct clksrc_clk clk_dout_mmc4 = {
829 .clk = {
830 .name = "dout_mmc4",
831 .id = -1,
832 },
833 .sources = &clkset_group,
834 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
835 .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
836};
837
838static struct clksrc_clk clksrcs[] = {
839 {
840 .clk = {
841 .name = "uclk1",
842 .id = 0,
843 .enable = exynos4_clksrc_mask_peril0_ctrl,
844 .ctrlbit = (1 << 0),
845 },
846 .sources = &clkset_group,
847 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
848 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
849 }, {
850 .clk = {
851 .name = "uclk1",
852 .id = 1,
853 .enable = exynos4_clksrc_mask_peril0_ctrl,
854 .ctrlbit = (1 << 4),
855 },
856 .sources = &clkset_group,
857 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
858 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
859 }, {
860 .clk = {
861 .name = "uclk1",
862 .id = 2,
863 .enable = exynos4_clksrc_mask_peril0_ctrl,
864 .ctrlbit = (1 << 8),
865 },
866 .sources = &clkset_group,
867 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
868 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
869 }, {
870 .clk = {
871 .name = "uclk1",
872 .id = 3,
873 .enable = exynos4_clksrc_mask_peril0_ctrl,
874 .ctrlbit = (1 << 12),
875 },
876 .sources = &clkset_group,
877 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
878 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
879 }, {
880 .clk = {
881 .name = "sclk_pwm",
882 .id = -1,
883 .enable = exynos4_clksrc_mask_peril0_ctrl,
884 .ctrlbit = (1 << 24),
885 },
886 .sources = &clkset_group,
887 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
888 .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
889 }, {
890 .clk = {
891 .name = "sclk_csis",
892 .id = 0,
893 .enable = exynos4_clksrc_mask_cam_ctrl,
894 .ctrlbit = (1 << 24),
895 },
896 .sources = &clkset_group,
897 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
898 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
899 }, {
900 .clk = {
901 .name = "sclk_csis",
902 .id = 1,
903 .enable = exynos4_clksrc_mask_cam_ctrl,
904 .ctrlbit = (1 << 28),
905 },
906 .sources = &clkset_group,
907 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
908 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
909 }, {
910 .clk = {
911 .name = "sclk_cam",
912 .id = 0,
913 .enable = exynos4_clksrc_mask_cam_ctrl,
914 .ctrlbit = (1 << 16),
915 },
916 .sources = &clkset_group,
917 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
918 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
919 }, {
920 .clk = {
921 .name = "sclk_cam",
922 .id = 1,
923 .enable = exynos4_clksrc_mask_cam_ctrl,
924 .ctrlbit = (1 << 20),
925 },
926 .sources = &clkset_group,
927 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
928 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
929 }, {
930 .clk = {
931 .name = "sclk_fimc",
932 .id = 0,
933 .enable = exynos4_clksrc_mask_cam_ctrl,
934 .ctrlbit = (1 << 0),
935 },
936 .sources = &clkset_group,
937 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
938 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
939 }, {
940 .clk = {
941 .name = "sclk_fimc",
942 .id = 1,
943 .enable = exynos4_clksrc_mask_cam_ctrl,
944 .ctrlbit = (1 << 4),
945 },
946 .sources = &clkset_group,
947 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
948 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
949 }, {
950 .clk = {
951 .name = "sclk_fimc",
952 .id = 2,
953 .enable = exynos4_clksrc_mask_cam_ctrl,
954 .ctrlbit = (1 << 8),
955 },
956 .sources = &clkset_group,
957 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
958 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
959 }, {
960 .clk = {
961 .name = "sclk_fimc",
962 .id = 3,
963 .enable = exynos4_clksrc_mask_cam_ctrl,
964 .ctrlbit = (1 << 12),
965 },
966 .sources = &clkset_group,
967 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
968 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
969 }, {
970 .clk = {
971 .name = "sclk_fimd",
972 .id = 0,
973 .enable = exynos4_clksrc_mask_lcd0_ctrl,
974 .ctrlbit = (1 << 0),
975 },
976 .sources = &clkset_group,
977 .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
978 .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
979 }, {
980 .clk = {
981 .name = "sclk_fimd",
982 .id = 1,
983 .enable = exynos4_clksrc_mask_lcd1_ctrl,
984 .ctrlbit = (1 << 0),
985 },
986 .sources = &clkset_group,
987 .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
988 .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
989 }, {
990 .clk = {
991 .name = "sclk_sata",
992 .id = -1,
993 .enable = exynos4_clksrc_mask_fsys_ctrl,
994 .ctrlbit = (1 << 24),
995 },
996 .sources = &clkset_mout_corebus,
997 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
998 .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
999 }, {
1000 .clk = {
1001 .name = "sclk_spi",
1002 .id = 0,
1003 .enable = exynos4_clksrc_mask_peril1_ctrl,
1004 .ctrlbit = (1 << 16),
1005 },
1006 .sources = &clkset_group,
1007 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
1008 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
1009 }, {
1010 .clk = {
1011 .name = "sclk_spi",
1012 .id = 1,
1013 .enable = exynos4_clksrc_mask_peril1_ctrl,
1014 .ctrlbit = (1 << 20),
1015 },
1016 .sources = &clkset_group,
1017 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
1018 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
1019 }, {
1020 .clk = {
1021 .name = "sclk_spi",
1022 .id = 2,
1023 .enable = exynos4_clksrc_mask_peril1_ctrl,
1024 .ctrlbit = (1 << 24),
1025 },
1026 .sources = &clkset_group,
1027 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
1028 .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
1029 }, {
1030 .clk = {
1031 .name = "sclk_fimg2d",
1032 .id = -1,
1033 },
1034 .sources = &clkset_mout_g2d,
1035 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
1036 .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
1037 }, {
1038 .clk = {
1039 .name = "sclk_mmc",
1040 .id = 0,
1041 .parent = &clk_dout_mmc0.clk,
1042 .enable = exynos4_clksrc_mask_fsys_ctrl,
1043 .ctrlbit = (1 << 0),
1044 },
1045 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
1046 }, {
1047 .clk = {
1048 .name = "sclk_mmc",
1049 .id = 1,
1050 .parent = &clk_dout_mmc1.clk,
1051 .enable = exynos4_clksrc_mask_fsys_ctrl,
1052 .ctrlbit = (1 << 4),
1053 },
1054 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
1055 }, {
1056 .clk = {
1057 .name = "sclk_mmc",
1058 .id = 2,
1059 .parent = &clk_dout_mmc2.clk,
1060 .enable = exynos4_clksrc_mask_fsys_ctrl,
1061 .ctrlbit = (1 << 8),
1062 },
1063 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
1064 }, {
1065 .clk = {
1066 .name = "sclk_mmc",
1067 .id = 3,
1068 .parent = &clk_dout_mmc3.clk,
1069 .enable = exynos4_clksrc_mask_fsys_ctrl,
1070 .ctrlbit = (1 << 12),
1071 },
1072 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
1073 }, {
1074 .clk = {
1075 .name = "sclk_mmc",
1076 .id = 4,
1077 .parent = &clk_dout_mmc4.clk,
1078 .enable = exynos4_clksrc_mask_fsys_ctrl,
1079 .ctrlbit = (1 << 16),
1080 },
1081 .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
1082 }
1083};
1084
1085/* Clock initialization code */
1086static struct clksrc_clk *sysclks[] = {
1087 &clk_mout_apll,
1088 &clk_sclk_apll,
1089 &clk_mout_epll,
1090 &clk_mout_mpll,
1091 &clk_moutcore,
1092 &clk_coreclk,
1093 &clk_armclk,
1094 &clk_aclk_corem0,
1095 &clk_aclk_cores,
1096 &clk_aclk_corem1,
1097 &clk_periphclk,
1098 &clk_mout_corebus,
1099 &clk_sclk_dmc,
1100 &clk_aclk_cored,
1101 &clk_aclk_corep,
1102 &clk_aclk_acp,
1103 &clk_pclk_acp,
1104 &clk_vpllsrc,
1105 &clk_sclk_vpll,
1106 &clk_aclk_200,
1107 &clk_aclk_100,
1108 &clk_aclk_160,
1109 &clk_aclk_133,
1110 &clk_dout_mmc0,
1111 &clk_dout_mmc1,
1112 &clk_dout_mmc2,
1113 &clk_dout_mmc3,
1114 &clk_dout_mmc4,
1115};
1116
1117static int xtal_rate;
1118
1119static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
1120{
1121 return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508);
1122}
1123
1124static struct clk_ops exynos4_fout_apll_ops = {
1125 .get_rate = exynos4_fout_apll_get_rate,
1126};
1127
1128void __init_or_cpufreq exynos4_setup_clocks(void)
1129{
1130 struct clk *xtal_clk;
1131 unsigned long apll;
1132 unsigned long mpll;
1133 unsigned long epll;
1134 unsigned long vpll;
1135 unsigned long vpllsrc;
1136 unsigned long xtal;
1137 unsigned long armclk;
1138 unsigned long sclk_dmc;
1139 unsigned long aclk_200;
1140 unsigned long aclk_100;
1141 unsigned long aclk_160;
1142 unsigned long aclk_133;
1143 unsigned int ptr;
1144
1145 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1146
1147 xtal_clk = clk_get(NULL, "xtal");
1148 BUG_ON(IS_ERR(xtal_clk));
1149
1150 xtal = clk_get_rate(xtal_clk);
1151
1152 xtal_rate = xtal;
1153
1154 clk_put(xtal_clk);
1155
1156 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1157
1158 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508);
1159 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508);
1160 epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
1161 __raw_readl(S5P_EPLL_CON1), pll_4600);
1162
1163 vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1164 vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
1165 __raw_readl(S5P_VPLL_CON1), pll_4650);
1166
1167 clk_fout_apll.ops = &exynos4_fout_apll_ops;
1168 clk_fout_mpll.rate = mpll;
1169 clk_fout_epll.rate = epll;
1170 clk_fout_vpll.rate = vpll;
1171
1172 printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1173 apll, mpll, epll, vpll);
1174
1175 armclk = clk_get_rate(&clk_armclk.clk);
1176 sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
1177
1178 aclk_200 = clk_get_rate(&clk_aclk_200.clk);
1179 aclk_100 = clk_get_rate(&clk_aclk_100.clk);
1180 aclk_160 = clk_get_rate(&clk_aclk_160.clk);
1181 aclk_133 = clk_get_rate(&clk_aclk_133.clk);
1182
1183 printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
1184 "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
1185 armclk, sclk_dmc, aclk_200,
1186 aclk_100, aclk_160, aclk_133);
1187
1188 clk_f.rate = armclk;
1189 clk_h.rate = sclk_dmc;
1190 clk_p.rate = aclk_100;
1191
1192 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1193 s3c_set_clksrc(&clksrcs[ptr], true);
1194}
1195
1196static struct clk *clks[] __initdata = {
1197 /* Nothing here yet */
1198};
1199
1200void __init exynos4_register_clocks(void)
1201{
1202 int ptr;
1203
1204 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1205
1206 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1207 s3c_register_clksrc(sysclks[ptr], 1);
1208
1209 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1210 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1211
1212 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1213 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1214
1215 s3c_pwmclk_init();
1216}