blob: 3320ad140ebebd7911c64cb74b5381ac6711a016 [file] [log] [blame]
Kukjin Kim87b3c6e2012-01-22 21:46:13 +09001/*
2 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * Clock support for EXYNOS5 SoCs
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#include <linux/kernel.h>
13#include <linux/err.h>
14#include <linux/io.h>
15#include <linux/syscore_ops.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#include <plat/pm.h>
24
25#include <mach/map.h>
26#include <mach/regs-clock.h>
27#include <mach/sysmmu.h>
28
29#include "common.h"
30
31#ifdef CONFIG_PM_SLEEP
32static struct sleep_save exynos5_clock_save[] = {
33 /* will be implemented */
34};
35#endif
36
37static struct clk exynos5_clk_sclk_dptxphy = {
38 .name = "sclk_dptx",
39};
40
41static struct clk exynos5_clk_sclk_hdmi24m = {
42 .name = "sclk_hdmi24m",
43 .rate = 24000000,
44};
45
46static struct clk exynos5_clk_sclk_hdmi27m = {
47 .name = "sclk_hdmi27m",
48 .rate = 27000000,
49};
50
51static struct clk exynos5_clk_sclk_hdmiphy = {
52 .name = "sclk_hdmiphy",
53};
54
55static struct clk exynos5_clk_sclk_usbphy = {
56 .name = "sclk_usbphy",
57 .rate = 48000000,
58};
59
60static int exynos5_clksrc_mask_top_ctrl(struct clk *clk, int enable)
61{
62 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_TOP, clk, enable);
63}
64
65static int exynos5_clksrc_mask_disp1_0_ctrl(struct clk *clk, int enable)
66{
67 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_DISP1_0, clk, enable);
68}
69
70static int exynos5_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
71{
72 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_FSYS, clk, enable);
73}
74
75static int exynos5_clksrc_mask_gscl_ctrl(struct clk *clk, int enable)
76{
77 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_GSCL, clk, enable);
78}
79
80static int exynos5_clksrc_mask_peric0_ctrl(struct clk *clk, int enable)
81{
82 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable);
83}
84
KyongHo Chobca10b92012-04-04 09:23:02 -070085static int exynos5_clk_ip_acp_ctrl(struct clk *clk, int enable)
86{
87 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ACP, clk, enable);
88}
89
Kukjin Kim87b3c6e2012-01-22 21:46:13 +090090static int exynos5_clk_ip_core_ctrl(struct clk *clk, int enable)
91{
92 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CORE, clk, enable);
93}
94
95static int exynos5_clk_ip_disp1_ctrl(struct clk *clk, int enable)
96{
97 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_DISP1, clk, enable);
98}
99
100static int exynos5_clk_ip_fsys_ctrl(struct clk *clk, int enable)
101{
102 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_FSYS, clk, enable);
103}
104
105static int exynos5_clk_block_ctrl(struct clk *clk, int enable)
106{
107 return s5p_gatectrl(EXYNOS5_CLKGATE_BLOCK, clk, enable);
108}
109
110static int exynos5_clk_ip_gen_ctrl(struct clk *clk, int enable)
111{
112 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GEN, clk, enable);
113}
114
115static int exynos5_clk_ip_gps_ctrl(struct clk *clk, int enable)
116{
117 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GPS, clk, enable);
118}
119
120static int exynos5_clk_ip_mfc_ctrl(struct clk *clk, int enable)
121{
122 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_MFC, clk, enable);
123}
124
125static int exynos5_clk_ip_peric_ctrl(struct clk *clk, int enable)
126{
127 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIC, clk, enable);
128}
129
130static int exynos5_clk_ip_peris_ctrl(struct clk *clk, int enable)
131{
132 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS, clk, enable);
133}
134
KyongHo Chobca10b92012-04-04 09:23:02 -0700135static int exynos5_clk_ip_gscl_ctrl(struct clk *clk, int enable)
136{
137 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GSCL, clk, enable);
138}
139
140static int exynos5_clk_ip_isp0_ctrl(struct clk *clk, int enable)
141{
142 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP0, clk, enable);
143}
144
145static int exynos5_clk_ip_isp1_ctrl(struct clk *clk, int enable)
146{
147 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP1, clk, enable);
148}
149
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900150/* Core list of CMU_CPU side */
151
152static struct clksrc_clk exynos5_clk_mout_apll = {
153 .clk = {
154 .name = "mout_apll",
155 },
156 .sources = &clk_src_apll,
157 .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 0, .size = 1 },
158};
159
160static struct clksrc_clk exynos5_clk_sclk_apll = {
161 .clk = {
162 .name = "sclk_apll",
163 .parent = &exynos5_clk_mout_apll.clk,
164 },
165 .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 },
166};
167
168static struct clksrc_clk exynos5_clk_mout_bpll = {
169 .clk = {
170 .name = "mout_bpll",
171 },
172 .sources = &clk_src_bpll,
173 .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 },
174};
175
176static struct clk *exynos5_clk_src_bpll_user_list[] = {
177 [0] = &clk_fin_mpll,
178 [1] = &exynos5_clk_mout_bpll.clk,
179};
180
181static struct clksrc_sources exynos5_clk_src_bpll_user = {
182 .sources = exynos5_clk_src_bpll_user_list,
183 .nr_sources = ARRAY_SIZE(exynos5_clk_src_bpll_user_list),
184};
185
186static struct clksrc_clk exynos5_clk_mout_bpll_user = {
187 .clk = {
188 .name = "mout_bpll_user",
189 },
190 .sources = &exynos5_clk_src_bpll_user,
191 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 24, .size = 1 },
192};
193
194static struct clksrc_clk exynos5_clk_mout_cpll = {
195 .clk = {
196 .name = "mout_cpll",
197 },
198 .sources = &clk_src_cpll,
199 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 8, .size = 1 },
200};
201
202static struct clksrc_clk exynos5_clk_mout_epll = {
203 .clk = {
204 .name = "mout_epll",
205 },
206 .sources = &clk_src_epll,
207 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 },
208};
209
210struct clksrc_clk exynos5_clk_mout_mpll = {
211 .clk = {
212 .name = "mout_mpll",
213 },
214 .sources = &clk_src_mpll,
215 .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 },
216};
217
218static struct clk *exynos_clkset_vpllsrc_list[] = {
219 [0] = &clk_fin_vpll,
220 [1] = &exynos5_clk_sclk_hdmi27m,
221};
222
223static struct clksrc_sources exynos5_clkset_vpllsrc = {
224 .sources = exynos_clkset_vpllsrc_list,
225 .nr_sources = ARRAY_SIZE(exynos_clkset_vpllsrc_list),
226};
227
228static struct clksrc_clk exynos5_clk_vpllsrc = {
229 .clk = {
230 .name = "vpll_src",
231 .enable = exynos5_clksrc_mask_top_ctrl,
232 .ctrlbit = (1 << 0),
233 },
234 .sources = &exynos5_clkset_vpllsrc,
235 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 0, .size = 1 },
236};
237
238static struct clk *exynos5_clkset_sclk_vpll_list[] = {
239 [0] = &exynos5_clk_vpllsrc.clk,
240 [1] = &clk_fout_vpll,
241};
242
243static struct clksrc_sources exynos5_clkset_sclk_vpll = {
244 .sources = exynos5_clkset_sclk_vpll_list,
245 .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_vpll_list),
246};
247
248static struct clksrc_clk exynos5_clk_sclk_vpll = {
249 .clk = {
250 .name = "sclk_vpll",
251 },
252 .sources = &exynos5_clkset_sclk_vpll,
253 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 16, .size = 1 },
254};
255
256static struct clksrc_clk exynos5_clk_sclk_pixel = {
257 .clk = {
258 .name = "sclk_pixel",
259 .parent = &exynos5_clk_sclk_vpll.clk,
260 },
261 .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 28, .size = 4 },
262};
263
264static struct clk *exynos5_clkset_sclk_hdmi_list[] = {
265 [0] = &exynos5_clk_sclk_pixel.clk,
266 [1] = &exynos5_clk_sclk_hdmiphy,
267};
268
269static struct clksrc_sources exynos5_clkset_sclk_hdmi = {
270 .sources = exynos5_clkset_sclk_hdmi_list,
271 .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_hdmi_list),
272};
273
274static struct clksrc_clk exynos5_clk_sclk_hdmi = {
275 .clk = {
276 .name = "sclk_hdmi",
277 .enable = exynos5_clksrc_mask_disp1_0_ctrl,
278 .ctrlbit = (1 << 20),
279 },
280 .sources = &exynos5_clkset_sclk_hdmi,
281 .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 20, .size = 1 },
282};
283
284static struct clksrc_clk *exynos5_sclk_tv[] = {
285 &exynos5_clk_sclk_pixel,
286 &exynos5_clk_sclk_hdmi,
287};
288
289static struct clk *exynos5_clk_src_mpll_user_list[] = {
290 [0] = &clk_fin_mpll,
291 [1] = &exynos5_clk_mout_mpll.clk,
292};
293
294static struct clksrc_sources exynos5_clk_src_mpll_user = {
295 .sources = exynos5_clk_src_mpll_user_list,
296 .nr_sources = ARRAY_SIZE(exynos5_clk_src_mpll_user_list),
297};
298
299static struct clksrc_clk exynos5_clk_mout_mpll_user = {
300 .clk = {
301 .name = "mout_mpll_user",
302 },
303 .sources = &exynos5_clk_src_mpll_user,
304 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 20, .size = 1 },
305};
306
307static struct clk *exynos5_clkset_mout_cpu_list[] = {
308 [0] = &exynos5_clk_mout_apll.clk,
309 [1] = &exynos5_clk_mout_mpll.clk,
310};
311
312static struct clksrc_sources exynos5_clkset_mout_cpu = {
313 .sources = exynos5_clkset_mout_cpu_list,
314 .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_cpu_list),
315};
316
317static struct clksrc_clk exynos5_clk_mout_cpu = {
318 .clk = {
319 .name = "mout_cpu",
320 },
321 .sources = &exynos5_clkset_mout_cpu,
322 .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 16, .size = 1 },
323};
324
325static struct clksrc_clk exynos5_clk_dout_armclk = {
326 .clk = {
327 .name = "dout_armclk",
328 .parent = &exynos5_clk_mout_cpu.clk,
329 },
330 .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 0, .size = 3 },
331};
332
333static struct clksrc_clk exynos5_clk_dout_arm2clk = {
334 .clk = {
335 .name = "dout_arm2clk",
336 .parent = &exynos5_clk_dout_armclk.clk,
337 },
338 .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 28, .size = 3 },
339};
340
341static struct clk exynos5_clk_armclk = {
342 .name = "armclk",
343 .parent = &exynos5_clk_dout_arm2clk.clk,
344};
345
346/* Core list of CMU_CDREX side */
347
348static struct clk *exynos5_clkset_cdrex_list[] = {
349 [0] = &exynos5_clk_mout_mpll.clk,
350 [1] = &exynos5_clk_mout_bpll.clk,
351};
352
353static struct clksrc_sources exynos5_clkset_cdrex = {
354 .sources = exynos5_clkset_cdrex_list,
355 .nr_sources = ARRAY_SIZE(exynos5_clkset_cdrex_list),
356};
357
358static struct clksrc_clk exynos5_clk_cdrex = {
359 .clk = {
360 .name = "clk_cdrex",
361 },
362 .sources = &exynos5_clkset_cdrex,
363 .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 4, .size = 1 },
364 .reg_div = { .reg = EXYNOS5_CLKDIV_CDREX, .shift = 16, .size = 3 },
365};
366
367static struct clksrc_clk exynos5_clk_aclk_acp = {
368 .clk = {
369 .name = "aclk_acp",
370 .parent = &exynos5_clk_mout_mpll.clk,
371 },
372 .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 0, .size = 3 },
373};
374
375static struct clksrc_clk exynos5_clk_pclk_acp = {
376 .clk = {
377 .name = "pclk_acp",
378 .parent = &exynos5_clk_aclk_acp.clk,
379 },
380 .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 4, .size = 3 },
381};
382
383/* Core list of CMU_TOP side */
384
385struct clk *exynos5_clkset_aclk_top_list[] = {
386 [0] = &exynos5_clk_mout_mpll_user.clk,
387 [1] = &exynos5_clk_mout_bpll_user.clk,
388};
389
390struct clksrc_sources exynos5_clkset_aclk = {
391 .sources = exynos5_clkset_aclk_top_list,
392 .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_top_list),
393};
394
395static struct clksrc_clk exynos5_clk_aclk_400 = {
396 .clk = {
397 .name = "aclk_400",
398 },
399 .sources = &exynos5_clkset_aclk,
400 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
401 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
402};
403
404struct clk *exynos5_clkset_aclk_333_166_list[] = {
405 [0] = &exynos5_clk_mout_cpll.clk,
406 [1] = &exynos5_clk_mout_mpll_user.clk,
407};
408
409struct clksrc_sources exynos5_clkset_aclk_333_166 = {
410 .sources = exynos5_clkset_aclk_333_166_list,
411 .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_333_166_list),
412};
413
414static struct clksrc_clk exynos5_clk_aclk_333 = {
415 .clk = {
416 .name = "aclk_333",
417 },
418 .sources = &exynos5_clkset_aclk_333_166,
419 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 16, .size = 1 },
420 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 20, .size = 3 },
421};
422
423static struct clksrc_clk exynos5_clk_aclk_166 = {
424 .clk = {
425 .name = "aclk_166",
426 },
427 .sources = &exynos5_clkset_aclk_333_166,
428 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 8, .size = 1 },
429 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 8, .size = 3 },
430};
431
432static struct clksrc_clk exynos5_clk_aclk_266 = {
433 .clk = {
434 .name = "aclk_266",
435 .parent = &exynos5_clk_mout_mpll_user.clk,
436 },
437 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 16, .size = 3 },
438};
439
440static struct clksrc_clk exynos5_clk_aclk_200 = {
441 .clk = {
442 .name = "aclk_200",
443 },
444 .sources = &exynos5_clkset_aclk,
445 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 12, .size = 1 },
446 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 12, .size = 3 },
447};
448
449static struct clksrc_clk exynos5_clk_aclk_66_pre = {
450 .clk = {
451 .name = "aclk_66_pre",
452 .parent = &exynos5_clk_mout_mpll_user.clk,
453 },
454 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP1, .shift = 24, .size = 3 },
455};
456
457static struct clksrc_clk exynos5_clk_aclk_66 = {
458 .clk = {
459 .name = "aclk_66",
460 .parent = &exynos5_clk_aclk_66_pre.clk,
461 },
462 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 0, .size = 3 },
463};
464
465static struct clk exynos5_init_clocks_off[] = {
466 {
467 .name = "timers",
468 .parent = &exynos5_clk_aclk_66.clk,
469 .enable = exynos5_clk_ip_peric_ctrl,
470 .ctrlbit = (1 << 24),
471 }, {
472 .name = "rtc",
473 .parent = &exynos5_clk_aclk_66.clk,
474 .enable = exynos5_clk_ip_peris_ctrl,
475 .ctrlbit = (1 << 20),
476 }, {
477 .name = "hsmmc",
478 .devname = "s3c-sdhci.0",
479 .parent = &exynos5_clk_aclk_200.clk,
480 .enable = exynos5_clk_ip_fsys_ctrl,
481 .ctrlbit = (1 << 12),
482 }, {
483 .name = "hsmmc",
484 .devname = "s3c-sdhci.1",
485 .parent = &exynos5_clk_aclk_200.clk,
486 .enable = exynos5_clk_ip_fsys_ctrl,
487 .ctrlbit = (1 << 13),
488 }, {
489 .name = "hsmmc",
490 .devname = "s3c-sdhci.2",
491 .parent = &exynos5_clk_aclk_200.clk,
492 .enable = exynos5_clk_ip_fsys_ctrl,
493 .ctrlbit = (1 << 14),
494 }, {
495 .name = "hsmmc",
496 .devname = "s3c-sdhci.3",
497 .parent = &exynos5_clk_aclk_200.clk,
498 .enable = exynos5_clk_ip_fsys_ctrl,
499 .ctrlbit = (1 << 15),
500 }, {
501 .name = "dwmci",
502 .parent = &exynos5_clk_aclk_200.clk,
503 .enable = exynos5_clk_ip_fsys_ctrl,
504 .ctrlbit = (1 << 16),
505 }, {
506 .name = "sata",
507 .devname = "ahci",
508 .enable = exynos5_clk_ip_fsys_ctrl,
509 .ctrlbit = (1 << 6),
510 }, {
511 .name = "sata_phy",
512 .enable = exynos5_clk_ip_fsys_ctrl,
513 .ctrlbit = (1 << 24),
514 }, {
515 .name = "sata_phy_i2c",
516 .enable = exynos5_clk_ip_fsys_ctrl,
517 .ctrlbit = (1 << 25),
518 }, {
519 .name = "mfc",
520 .devname = "s5p-mfc",
521 .enable = exynos5_clk_ip_mfc_ctrl,
522 .ctrlbit = (1 << 0),
523 }, {
524 .name = "hdmi",
525 .devname = "exynos4-hdmi",
526 .enable = exynos5_clk_ip_disp1_ctrl,
527 .ctrlbit = (1 << 6),
528 }, {
529 .name = "mixer",
530 .devname = "s5p-mixer",
531 .enable = exynos5_clk_ip_disp1_ctrl,
532 .ctrlbit = (1 << 5),
533 }, {
534 .name = "jpeg",
535 .enable = exynos5_clk_ip_gen_ctrl,
536 .ctrlbit = (1 << 2),
537 }, {
538 .name = "dsim0",
539 .enable = exynos5_clk_ip_disp1_ctrl,
540 .ctrlbit = (1 << 3),
541 }, {
542 .name = "iis",
543 .devname = "samsung-i2s.1",
544 .enable = exynos5_clk_ip_peric_ctrl,
545 .ctrlbit = (1 << 20),
546 }, {
547 .name = "iis",
548 .devname = "samsung-i2s.2",
549 .enable = exynos5_clk_ip_peric_ctrl,
550 .ctrlbit = (1 << 21),
551 }, {
552 .name = "pcm",
553 .devname = "samsung-pcm.1",
554 .enable = exynos5_clk_ip_peric_ctrl,
555 .ctrlbit = (1 << 22),
556 }, {
557 .name = "pcm",
558 .devname = "samsung-pcm.2",
559 .enable = exynos5_clk_ip_peric_ctrl,
560 .ctrlbit = (1 << 23),
561 }, {
562 .name = "spdif",
563 .devname = "samsung-spdif",
564 .enable = exynos5_clk_ip_peric_ctrl,
565 .ctrlbit = (1 << 26),
566 }, {
567 .name = "ac97",
568 .devname = "samsung-ac97",
569 .enable = exynos5_clk_ip_peric_ctrl,
570 .ctrlbit = (1 << 27),
571 }, {
572 .name = "usbhost",
573 .enable = exynos5_clk_ip_fsys_ctrl ,
574 .ctrlbit = (1 << 18),
575 }, {
576 .name = "usbotg",
577 .enable = exynos5_clk_ip_fsys_ctrl,
578 .ctrlbit = (1 << 7),
579 }, {
580 .name = "gps",
581 .enable = exynos5_clk_ip_gps_ctrl,
582 .ctrlbit = ((1 << 3) | (1 << 2) | (1 << 0)),
583 }, {
584 .name = "nfcon",
585 .enable = exynos5_clk_ip_fsys_ctrl,
586 .ctrlbit = (1 << 22),
587 }, {
588 .name = "iop",
589 .enable = exynos5_clk_ip_fsys_ctrl,
590 .ctrlbit = ((1 << 30) | (1 << 26) | (1 << 23)),
591 }, {
592 .name = "core_iop",
593 .enable = exynos5_clk_ip_core_ctrl,
594 .ctrlbit = ((1 << 21) | (1 << 3)),
595 }, {
596 .name = "mcu_iop",
597 .enable = exynos5_clk_ip_fsys_ctrl,
598 .ctrlbit = (1 << 0),
599 }, {
600 .name = "i2c",
601 .devname = "s3c2440-i2c.0",
602 .parent = &exynos5_clk_aclk_66.clk,
603 .enable = exynos5_clk_ip_peric_ctrl,
604 .ctrlbit = (1 << 6),
605 }, {
606 .name = "i2c",
607 .devname = "s3c2440-i2c.1",
608 .parent = &exynos5_clk_aclk_66.clk,
609 .enable = exynos5_clk_ip_peric_ctrl,
610 .ctrlbit = (1 << 7),
611 }, {
612 .name = "i2c",
613 .devname = "s3c2440-i2c.2",
614 .parent = &exynos5_clk_aclk_66.clk,
615 .enable = exynos5_clk_ip_peric_ctrl,
616 .ctrlbit = (1 << 8),
617 }, {
618 .name = "i2c",
619 .devname = "s3c2440-i2c.3",
620 .parent = &exynos5_clk_aclk_66.clk,
621 .enable = exynos5_clk_ip_peric_ctrl,
622 .ctrlbit = (1 << 9),
623 }, {
624 .name = "i2c",
625 .devname = "s3c2440-i2c.4",
626 .parent = &exynos5_clk_aclk_66.clk,
627 .enable = exynos5_clk_ip_peric_ctrl,
628 .ctrlbit = (1 << 10),
629 }, {
630 .name = "i2c",
631 .devname = "s3c2440-i2c.5",
632 .parent = &exynos5_clk_aclk_66.clk,
633 .enable = exynos5_clk_ip_peric_ctrl,
634 .ctrlbit = (1 << 11),
635 }, {
636 .name = "i2c",
637 .devname = "s3c2440-i2c.6",
638 .parent = &exynos5_clk_aclk_66.clk,
639 .enable = exynos5_clk_ip_peric_ctrl,
640 .ctrlbit = (1 << 12),
641 }, {
642 .name = "i2c",
643 .devname = "s3c2440-i2c.7",
644 .parent = &exynos5_clk_aclk_66.clk,
645 .enable = exynos5_clk_ip_peric_ctrl,
646 .ctrlbit = (1 << 13),
647 }, {
648 .name = "i2c",
649 .devname = "s3c2440-hdmiphy-i2c",
650 .parent = &exynos5_clk_aclk_66.clk,
651 .enable = exynos5_clk_ip_peric_ctrl,
652 .ctrlbit = (1 << 14),
KyongHo Chobca10b92012-04-04 09:23:02 -0700653 }, {
654 .name = SYSMMU_CLOCK_NAME,
655 .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
656 .enable = &exynos5_clk_ip_mfc_ctrl,
657 .ctrlbit = (1 << 1),
658 }, {
659 .name = SYSMMU_CLOCK_NAME,
660 .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
661 .enable = &exynos5_clk_ip_mfc_ctrl,
662 .ctrlbit = (1 << 2),
663 }, {
664 .name = SYSMMU_CLOCK_NAME,
665 .devname = SYSMMU_CLOCK_DEVNAME(tv, 2),
666 .enable = &exynos5_clk_ip_disp1_ctrl,
667 .ctrlbit = (1 << 9)
668 }, {
669 .name = SYSMMU_CLOCK_NAME,
670 .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3),
671 .enable = &exynos5_clk_ip_gen_ctrl,
672 .ctrlbit = (1 << 7),
673 }, {
674 .name = SYSMMU_CLOCK_NAME,
675 .devname = SYSMMU_CLOCK_DEVNAME(rot, 4),
676 .enable = &exynos5_clk_ip_gen_ctrl,
677 .ctrlbit = (1 << 6)
678 }, {
679 .name = SYSMMU_CLOCK_NAME,
680 .devname = SYSMMU_CLOCK_DEVNAME(gsc0, 5),
681 .enable = &exynos5_clk_ip_gscl_ctrl,
682 .ctrlbit = (1 << 7),
683 }, {
684 .name = SYSMMU_CLOCK_NAME,
685 .devname = SYSMMU_CLOCK_DEVNAME(gsc1, 6),
686 .enable = &exynos5_clk_ip_gscl_ctrl,
687 .ctrlbit = (1 << 8),
688 }, {
689 .name = SYSMMU_CLOCK_NAME,
690 .devname = SYSMMU_CLOCK_DEVNAME(gsc2, 7),
691 .enable = &exynos5_clk_ip_gscl_ctrl,
692 .ctrlbit = (1 << 9),
693 }, {
694 .name = SYSMMU_CLOCK_NAME,
695 .devname = SYSMMU_CLOCK_DEVNAME(gsc3, 8),
696 .enable = &exynos5_clk_ip_gscl_ctrl,
697 .ctrlbit = (1 << 10),
698 }, {
699 .name = SYSMMU_CLOCK_NAME,
700 .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
701 .enable = &exynos5_clk_ip_isp0_ctrl,
702 .ctrlbit = (0x3F << 8),
703 }, {
704 .name = SYSMMU_CLOCK_NAME2,
705 .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
706 .enable = &exynos5_clk_ip_isp1_ctrl,
707 .ctrlbit = (0xF << 4),
708 }, {
709 .name = SYSMMU_CLOCK_NAME,
710 .devname = SYSMMU_CLOCK_DEVNAME(camif0, 12),
711 .enable = &exynos5_clk_ip_gscl_ctrl,
712 .ctrlbit = (1 << 11),
713 }, {
714 .name = SYSMMU_CLOCK_NAME,
715 .devname = SYSMMU_CLOCK_DEVNAME(camif1, 13),
716 .enable = &exynos5_clk_ip_gscl_ctrl,
717 .ctrlbit = (1 << 12),
718 }, {
719 .name = SYSMMU_CLOCK_NAME,
720 .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
721 .enable = &exynos5_clk_ip_acp_ctrl,
722 .ctrlbit = (1 << 7)
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900723 }
724};
725
726static struct clk exynos5_init_clocks_on[] = {
727 {
728 .name = "uart",
729 .devname = "s5pv210-uart.0",
730 .enable = exynos5_clk_ip_peric_ctrl,
731 .ctrlbit = (1 << 0),
732 }, {
733 .name = "uart",
734 .devname = "s5pv210-uart.1",
735 .enable = exynos5_clk_ip_peric_ctrl,
736 .ctrlbit = (1 << 1),
737 }, {
738 .name = "uart",
739 .devname = "s5pv210-uart.2",
740 .enable = exynos5_clk_ip_peric_ctrl,
741 .ctrlbit = (1 << 2),
742 }, {
743 .name = "uart",
744 .devname = "s5pv210-uart.3",
745 .enable = exynos5_clk_ip_peric_ctrl,
746 .ctrlbit = (1 << 3),
747 }, {
748 .name = "uart",
749 .devname = "s5pv210-uart.4",
750 .enable = exynos5_clk_ip_peric_ctrl,
751 .ctrlbit = (1 << 4),
752 }, {
753 .name = "uart",
754 .devname = "s5pv210-uart.5",
755 .enable = exynos5_clk_ip_peric_ctrl,
756 .ctrlbit = (1 << 5),
757 }
758};
759
760static struct clk exynos5_clk_pdma0 = {
761 .name = "dma",
762 .devname = "dma-pl330.0",
763 .enable = exynos5_clk_ip_fsys_ctrl,
764 .ctrlbit = (1 << 1),
765};
766
767static struct clk exynos5_clk_pdma1 = {
768 .name = "dma",
769 .devname = "dma-pl330.1",
770 .enable = exynos5_clk_ip_fsys_ctrl,
771 .ctrlbit = (1 << 1),
772};
773
774static struct clk exynos5_clk_mdma1 = {
775 .name = "dma",
776 .devname = "dma-pl330.2",
777 .enable = exynos5_clk_ip_gen_ctrl,
778 .ctrlbit = (1 << 4),
779};
780
781struct clk *exynos5_clkset_group_list[] = {
782 [0] = &clk_ext_xtal_mux,
783 [1] = NULL,
784 [2] = &exynos5_clk_sclk_hdmi24m,
785 [3] = &exynos5_clk_sclk_dptxphy,
786 [4] = &exynos5_clk_sclk_usbphy,
787 [5] = &exynos5_clk_sclk_hdmiphy,
788 [6] = &exynos5_clk_mout_mpll_user.clk,
789 [7] = &exynos5_clk_mout_epll.clk,
790 [8] = &exynos5_clk_sclk_vpll.clk,
791 [9] = &exynos5_clk_mout_cpll.clk,
792};
793
794struct clksrc_sources exynos5_clkset_group = {
795 .sources = exynos5_clkset_group_list,
796 .nr_sources = ARRAY_SIZE(exynos5_clkset_group_list),
797};
798
799/* Possible clock sources for aclk_266_gscl_sub Mux */
800static struct clk *clk_src_gscl_266_list[] = {
801 [0] = &clk_ext_xtal_mux,
802 [1] = &exynos5_clk_aclk_266.clk,
803};
804
805static struct clksrc_sources clk_src_gscl_266 = {
806 .sources = clk_src_gscl_266_list,
807 .nr_sources = ARRAY_SIZE(clk_src_gscl_266_list),
808};
809
810static struct clksrc_clk exynos5_clk_dout_mmc0 = {
811 .clk = {
812 .name = "dout_mmc0",
813 },
814 .sources = &exynos5_clkset_group,
815 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 0, .size = 4 },
816 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 0, .size = 4 },
817};
818
819static struct clksrc_clk exynos5_clk_dout_mmc1 = {
820 .clk = {
821 .name = "dout_mmc1",
822 },
823 .sources = &exynos5_clkset_group,
824 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 4, .size = 4 },
825 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 16, .size = 4 },
826};
827
828static struct clksrc_clk exynos5_clk_dout_mmc2 = {
829 .clk = {
830 .name = "dout_mmc2",
831 },
832 .sources = &exynos5_clkset_group,
833 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 8, .size = 4 },
834 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 0, .size = 4 },
835};
836
837static struct clksrc_clk exynos5_clk_dout_mmc3 = {
838 .clk = {
839 .name = "dout_mmc3",
840 },
841 .sources = &exynos5_clkset_group,
842 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 12, .size = 4 },
843 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 16, .size = 4 },
844};
845
846static struct clksrc_clk exynos5_clk_dout_mmc4 = {
847 .clk = {
848 .name = "dout_mmc4",
849 },
850 .sources = &exynos5_clkset_group,
851 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 16, .size = 4 },
852 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 0, .size = 4 },
853};
854
855static struct clksrc_clk exynos5_clk_sclk_uart0 = {
856 .clk = {
857 .name = "uclk1",
858 .devname = "exynos4210-uart.0",
859 .enable = exynos5_clksrc_mask_peric0_ctrl,
860 .ctrlbit = (1 << 0),
861 },
862 .sources = &exynos5_clkset_group,
863 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 0, .size = 4 },
864 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 0, .size = 4 },
865};
866
867static struct clksrc_clk exynos5_clk_sclk_uart1 = {
868 .clk = {
869 .name = "uclk1",
870 .devname = "exynos4210-uart.1",
871 .enable = exynos5_clksrc_mask_peric0_ctrl,
872 .ctrlbit = (1 << 4),
873 },
874 .sources = &exynos5_clkset_group,
875 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 4, .size = 4 },
876 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 4, .size = 4 },
877};
878
879static struct clksrc_clk exynos5_clk_sclk_uart2 = {
880 .clk = {
881 .name = "uclk1",
882 .devname = "exynos4210-uart.2",
883 .enable = exynos5_clksrc_mask_peric0_ctrl,
884 .ctrlbit = (1 << 8),
885 },
886 .sources = &exynos5_clkset_group,
887 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 8, .size = 4 },
888 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 8, .size = 4 },
889};
890
891static struct clksrc_clk exynos5_clk_sclk_uart3 = {
892 .clk = {
893 .name = "uclk1",
894 .devname = "exynos4210-uart.3",
895 .enable = exynos5_clksrc_mask_peric0_ctrl,
896 .ctrlbit = (1 << 12),
897 },
898 .sources = &exynos5_clkset_group,
899 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 12, .size = 4 },
900 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 12, .size = 4 },
901};
902
903static struct clksrc_clk exynos5_clk_sclk_mmc0 = {
904 .clk = {
905 .name = "sclk_mmc",
906 .devname = "s3c-sdhci.0",
907 .parent = &exynos5_clk_dout_mmc0.clk,
908 .enable = exynos5_clksrc_mask_fsys_ctrl,
909 .ctrlbit = (1 << 0),
910 },
911 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 8, .size = 8 },
912};
913
914static struct clksrc_clk exynos5_clk_sclk_mmc1 = {
915 .clk = {
916 .name = "sclk_mmc",
917 .devname = "s3c-sdhci.1",
918 .parent = &exynos5_clk_dout_mmc1.clk,
919 .enable = exynos5_clksrc_mask_fsys_ctrl,
920 .ctrlbit = (1 << 4),
921 },
922 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 24, .size = 8 },
923};
924
925static struct clksrc_clk exynos5_clk_sclk_mmc2 = {
926 .clk = {
927 .name = "sclk_mmc",
928 .devname = "s3c-sdhci.2",
929 .parent = &exynos5_clk_dout_mmc2.clk,
930 .enable = exynos5_clksrc_mask_fsys_ctrl,
931 .ctrlbit = (1 << 8),
932 },
933 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 8, .size = 8 },
934};
935
936static struct clksrc_clk exynos5_clk_sclk_mmc3 = {
937 .clk = {
938 .name = "sclk_mmc",
939 .devname = "s3c-sdhci.3",
940 .parent = &exynos5_clk_dout_mmc3.clk,
941 .enable = exynos5_clksrc_mask_fsys_ctrl,
942 .ctrlbit = (1 << 12),
943 },
944 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 24, .size = 8 },
945};
946
947static struct clksrc_clk exynos5_clksrcs[] = {
948 {
949 .clk = {
950 .name = "sclk_dwmci",
951 .parent = &exynos5_clk_dout_mmc4.clk,
952 .enable = exynos5_clksrc_mask_fsys_ctrl,
953 .ctrlbit = (1 << 16),
954 },
955 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 8, .size = 8 },
956 }, {
957 .clk = {
958 .name = "sclk_fimd",
959 .devname = "s3cfb.1",
960 .enable = exynos5_clksrc_mask_disp1_0_ctrl,
961 .ctrlbit = (1 << 0),
962 },
963 .sources = &exynos5_clkset_group,
964 .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 0, .size = 4 },
965 .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 0, .size = 4 },
966 }, {
967 .clk = {
968 .name = "aclk_266_gscl",
969 },
970 .sources = &clk_src_gscl_266,
971 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 8, .size = 1 },
972 }, {
973 .clk = {
974 .name = "sclk_g3d",
975 .devname = "mali-t604.0",
976 .enable = exynos5_clk_block_ctrl,
977 .ctrlbit = (1 << 1),
978 },
979 .sources = &exynos5_clkset_aclk,
980 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
981 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
982 }, {
983 .clk = {
984 .name = "sclk_gscl_wrap",
985 .devname = "s5p-mipi-csis.0",
986 .enable = exynos5_clksrc_mask_gscl_ctrl,
987 .ctrlbit = (1 << 24),
988 },
989 .sources = &exynos5_clkset_group,
990 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 24, .size = 4 },
991 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 24, .size = 4 },
992 }, {
993 .clk = {
994 .name = "sclk_gscl_wrap",
995 .devname = "s5p-mipi-csis.1",
996 .enable = exynos5_clksrc_mask_gscl_ctrl,
997 .ctrlbit = (1 << 28),
998 },
999 .sources = &exynos5_clkset_group,
1000 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 28, .size = 4 },
1001 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 28, .size = 4 },
1002 }, {
1003 .clk = {
1004 .name = "sclk_cam0",
1005 .enable = exynos5_clksrc_mask_gscl_ctrl,
1006 .ctrlbit = (1 << 16),
1007 },
1008 .sources = &exynos5_clkset_group,
1009 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 16, .size = 4 },
1010 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 16, .size = 4 },
1011 }, {
1012 .clk = {
1013 .name = "sclk_cam1",
1014 .enable = exynos5_clksrc_mask_gscl_ctrl,
1015 .ctrlbit = (1 << 20),
1016 },
1017 .sources = &exynos5_clkset_group,
1018 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 20, .size = 4 },
1019 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 20, .size = 4 },
1020 }, {
1021 .clk = {
1022 .name = "sclk_jpeg",
1023 .parent = &exynos5_clk_mout_cpll.clk,
1024 },
1025 .reg_div = { .reg = EXYNOS5_CLKDIV_GEN, .shift = 4, .size = 3 },
1026 },
1027};
1028
1029/* Clock initialization code */
1030static struct clksrc_clk *exynos5_sysclks[] = {
1031 &exynos5_clk_mout_apll,
1032 &exynos5_clk_sclk_apll,
1033 &exynos5_clk_mout_bpll,
1034 &exynos5_clk_mout_bpll_user,
1035 &exynos5_clk_mout_cpll,
1036 &exynos5_clk_mout_epll,
1037 &exynos5_clk_mout_mpll,
1038 &exynos5_clk_mout_mpll_user,
1039 &exynos5_clk_vpllsrc,
1040 &exynos5_clk_sclk_vpll,
1041 &exynos5_clk_mout_cpu,
1042 &exynos5_clk_dout_armclk,
1043 &exynos5_clk_dout_arm2clk,
1044 &exynos5_clk_cdrex,
1045 &exynos5_clk_aclk_400,
1046 &exynos5_clk_aclk_333,
1047 &exynos5_clk_aclk_266,
1048 &exynos5_clk_aclk_200,
1049 &exynos5_clk_aclk_166,
1050 &exynos5_clk_aclk_66_pre,
1051 &exynos5_clk_aclk_66,
1052 &exynos5_clk_dout_mmc0,
1053 &exynos5_clk_dout_mmc1,
1054 &exynos5_clk_dout_mmc2,
1055 &exynos5_clk_dout_mmc3,
1056 &exynos5_clk_dout_mmc4,
1057 &exynos5_clk_aclk_acp,
1058 &exynos5_clk_pclk_acp,
1059};
1060
1061static struct clk *exynos5_clk_cdev[] = {
1062 &exynos5_clk_pdma0,
1063 &exynos5_clk_pdma1,
1064 &exynos5_clk_mdma1,
1065};
1066
1067static struct clksrc_clk *exynos5_clksrc_cdev[] = {
1068 &exynos5_clk_sclk_uart0,
1069 &exynos5_clk_sclk_uart1,
1070 &exynos5_clk_sclk_uart2,
1071 &exynos5_clk_sclk_uart3,
1072 &exynos5_clk_sclk_mmc0,
1073 &exynos5_clk_sclk_mmc1,
1074 &exynos5_clk_sclk_mmc2,
1075 &exynos5_clk_sclk_mmc3,
1076};
1077
1078static struct clk_lookup exynos5_clk_lookup[] = {
1079 CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos5_clk_sclk_uart0.clk),
1080 CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1.clk),
1081 CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2.clk),
1082 CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3.clk),
1083 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk),
1084 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk),
1085 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk),
1086 CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk),
1087 CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0),
1088 CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1),
1089 CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1),
1090};
1091
1092static unsigned long exynos5_epll_get_rate(struct clk *clk)
1093{
1094 return clk->rate;
1095}
1096
1097static struct clk *exynos5_clks[] __initdata = {
1098 &exynos5_clk_sclk_hdmi27m,
1099 &exynos5_clk_sclk_hdmiphy,
1100 &clk_fout_bpll,
1101 &clk_fout_cpll,
1102 &exynos5_clk_armclk,
1103};
1104
1105static u32 epll_div[][6] = {
1106 { 192000000, 0, 48, 3, 1, 0 },
1107 { 180000000, 0, 45, 3, 1, 0 },
1108 { 73728000, 1, 73, 3, 3, 47710 },
1109 { 67737600, 1, 90, 4, 3, 20762 },
1110 { 49152000, 0, 49, 3, 3, 9961 },
1111 { 45158400, 0, 45, 3, 3, 10381 },
1112 { 180633600, 0, 45, 3, 1, 10381 },
1113};
1114
1115static int exynos5_epll_set_rate(struct clk *clk, unsigned long rate)
1116{
1117 unsigned int epll_con, epll_con_k;
1118 unsigned int i;
1119 unsigned int tmp;
1120 unsigned int epll_rate;
1121 unsigned int locktime;
1122 unsigned int lockcnt;
1123
1124 /* Return if nothing changed */
1125 if (clk->rate == rate)
1126 return 0;
1127
1128 if (clk->parent)
1129 epll_rate = clk_get_rate(clk->parent);
1130 else
1131 epll_rate = clk_ext_xtal_mux.rate;
1132
1133 if (epll_rate != 24000000) {
1134 pr_err("Invalid Clock : recommended clock is 24MHz.\n");
1135 return -EINVAL;
1136 }
1137
1138 epll_con = __raw_readl(EXYNOS5_EPLL_CON0);
1139 epll_con &= ~(0x1 << 27 | \
1140 PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \
1141 PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
1142 PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1143
1144 for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
1145 if (epll_div[i][0] == rate) {
1146 epll_con_k = epll_div[i][5] << 0;
1147 epll_con |= epll_div[i][1] << 27;
1148 epll_con |= epll_div[i][2] << PLL46XX_MDIV_SHIFT;
1149 epll_con |= epll_div[i][3] << PLL46XX_PDIV_SHIFT;
1150 epll_con |= epll_div[i][4] << PLL46XX_SDIV_SHIFT;
1151 break;
1152 }
1153 }
1154
1155 if (i == ARRAY_SIZE(epll_div)) {
1156 printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
1157 __func__);
1158 return -EINVAL;
1159 }
1160
1161 epll_rate /= 1000000;
1162
1163 /* 3000 max_cycls : specification data */
1164 locktime = 3000 / epll_rate * epll_div[i][3];
1165 lockcnt = locktime * 10000 / (10000 / epll_rate);
1166
1167 __raw_writel(lockcnt, EXYNOS5_EPLL_LOCK);
1168
1169 __raw_writel(epll_con, EXYNOS5_EPLL_CON0);
1170 __raw_writel(epll_con_k, EXYNOS5_EPLL_CON1);
1171
1172 do {
1173 tmp = __raw_readl(EXYNOS5_EPLL_CON0);
1174 } while (!(tmp & 0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT));
1175
1176 clk->rate = rate;
1177
1178 return 0;
1179}
1180
1181static struct clk_ops exynos5_epll_ops = {
1182 .get_rate = exynos5_epll_get_rate,
1183 .set_rate = exynos5_epll_set_rate,
1184};
1185
1186static int xtal_rate;
1187
1188static unsigned long exynos5_fout_apll_get_rate(struct clk *clk)
1189{
1190 return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS5_APLL_CON0));
1191}
1192
1193static struct clk_ops exynos5_fout_apll_ops = {
1194 .get_rate = exynos5_fout_apll_get_rate,
1195};
1196
1197#ifdef CONFIG_PM
1198static int exynos5_clock_suspend(void)
1199{
1200 s3c_pm_do_save(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
1201
1202 return 0;
1203}
1204
1205static void exynos5_clock_resume(void)
1206{
1207 s3c_pm_do_restore_core(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
1208}
1209#else
1210#define exynos5_clock_suspend NULL
1211#define exynos5_clock_resume NULL
1212#endif
1213
1214struct syscore_ops exynos5_clock_syscore_ops = {
1215 .suspend = exynos5_clock_suspend,
1216 .resume = exynos5_clock_resume,
1217};
1218
1219void __init_or_cpufreq exynos5_setup_clocks(void)
1220{
1221 struct clk *xtal_clk;
1222 unsigned long apll;
1223 unsigned long bpll;
1224 unsigned long cpll;
1225 unsigned long mpll;
1226 unsigned long epll;
1227 unsigned long vpll;
1228 unsigned long vpllsrc;
1229 unsigned long xtal;
1230 unsigned long armclk;
1231 unsigned long mout_cdrex;
1232 unsigned long aclk_400;
1233 unsigned long aclk_333;
1234 unsigned long aclk_266;
1235 unsigned long aclk_200;
1236 unsigned long aclk_166;
1237 unsigned long aclk_66;
1238 unsigned int ptr;
1239
1240 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1241
1242 xtal_clk = clk_get(NULL, "xtal");
1243 BUG_ON(IS_ERR(xtal_clk));
1244
1245 xtal = clk_get_rate(xtal_clk);
1246
1247 xtal_rate = xtal;
1248
1249 clk_put(xtal_clk);
1250
1251 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1252
1253 apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_APLL_CON0));
1254 bpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_BPLL_CON0));
1255 cpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_CPLL_CON0));
1256 mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_MPLL_CON0));
1257 epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS5_EPLL_CON0),
1258 __raw_readl(EXYNOS5_EPLL_CON1));
1259
1260 vpllsrc = clk_get_rate(&exynos5_clk_vpllsrc.clk);
1261 vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS5_VPLL_CON0),
1262 __raw_readl(EXYNOS5_VPLL_CON1));
1263
1264 clk_fout_apll.ops = &exynos5_fout_apll_ops;
1265 clk_fout_bpll.rate = bpll;
1266 clk_fout_cpll.rate = cpll;
1267 clk_fout_mpll.rate = mpll;
1268 clk_fout_epll.rate = epll;
1269 clk_fout_vpll.rate = vpll;
1270
1271 printk(KERN_INFO "EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n"
1272 "M=%ld, E=%ld V=%ld",
1273 apll, bpll, cpll, mpll, epll, vpll);
1274
1275 armclk = clk_get_rate(&exynos5_clk_armclk);
1276 mout_cdrex = clk_get_rate(&exynos5_clk_cdrex.clk);
1277
1278 aclk_400 = clk_get_rate(&exynos5_clk_aclk_400.clk);
1279 aclk_333 = clk_get_rate(&exynos5_clk_aclk_333.clk);
1280 aclk_266 = clk_get_rate(&exynos5_clk_aclk_266.clk);
1281 aclk_200 = clk_get_rate(&exynos5_clk_aclk_200.clk);
1282 aclk_166 = clk_get_rate(&exynos5_clk_aclk_166.clk);
1283 aclk_66 = clk_get_rate(&exynos5_clk_aclk_66.clk);
1284
1285 printk(KERN_INFO "EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400=%ld\n"
1286 "ACLK333=%ld, ACLK266=%ld, ACLK200=%ld\n"
1287 "ACLK166=%ld, ACLK66=%ld\n",
1288 armclk, mout_cdrex, aclk_400,
1289 aclk_333, aclk_266, aclk_200,
1290 aclk_166, aclk_66);
1291
1292
1293 clk_fout_epll.ops = &exynos5_epll_ops;
1294
1295 if (clk_set_parent(&exynos5_clk_mout_epll.clk, &clk_fout_epll))
1296 printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
1297 clk_fout_epll.name, exynos5_clk_mout_epll.clk.name);
1298
1299 clk_set_rate(&exynos5_clk_sclk_apll.clk, 100000000);
1300 clk_set_rate(&exynos5_clk_aclk_266.clk, 300000000);
1301
1302 clk_set_rate(&exynos5_clk_aclk_acp.clk, 267000000);
1303 clk_set_rate(&exynos5_clk_pclk_acp.clk, 134000000);
1304
1305 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrcs); ptr++)
1306 s3c_set_clksrc(&exynos5_clksrcs[ptr], true);
1307}
1308
1309void __init exynos5_register_clocks(void)
1310{
1311 int ptr;
1312
1313 s3c24xx_register_clocks(exynos5_clks, ARRAY_SIZE(exynos5_clks));
1314
1315 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sysclks); ptr++)
1316 s3c_register_clksrc(exynos5_sysclks[ptr], 1);
1317
1318 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sclk_tv); ptr++)
1319 s3c_register_clksrc(exynos5_sclk_tv[ptr], 1);
1320
1321 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrc_cdev); ptr++)
1322 s3c_register_clksrc(exynos5_clksrc_cdev[ptr], 1);
1323
1324 s3c_register_clksrc(exynos5_clksrcs, ARRAY_SIZE(exynos5_clksrcs));
1325 s3c_register_clocks(exynos5_init_clocks_on, ARRAY_SIZE(exynos5_init_clocks_on));
1326
1327 s3c24xx_register_clocks(exynos5_clk_cdev, ARRAY_SIZE(exynos5_clk_cdev));
1328 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clk_cdev); ptr++)
1329 s3c_disable_clocks(exynos5_clk_cdev[ptr], 1);
1330
1331 s3c_register_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
1332 s3c_disable_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
1333 clkdev_add_table(exynos5_clk_lookup, ARRAY_SIZE(exynos5_clk_lookup));
1334
1335 register_syscore_ops(&exynos5_clock_syscore_ops);
1336 s3c_pwmclk_init();
1337}