blob: 84ef35aceba2e4efe24d6c9d484737f06d49d81a [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 }, {
Thomas Abrahamd36bcd02012-04-24 14:03:05 -0700477 .name = "watchdog",
478 .parent = &exynos5_clk_aclk_66.clk,
479 .enable = exynos5_clk_ip_peris_ctrl,
480 .ctrlbit = (1 << 19),
481 }, {
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900482 .name = "hsmmc",
Thomas Abraham8482c812012-04-14 08:04:46 -0700483 .devname = "exynos4-sdhci.0",
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900484 .parent = &exynos5_clk_aclk_200.clk,
485 .enable = exynos5_clk_ip_fsys_ctrl,
486 .ctrlbit = (1 << 12),
487 }, {
488 .name = "hsmmc",
Thomas Abraham8482c812012-04-14 08:04:46 -0700489 .devname = "exynos4-sdhci.1",
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900490 .parent = &exynos5_clk_aclk_200.clk,
491 .enable = exynos5_clk_ip_fsys_ctrl,
492 .ctrlbit = (1 << 13),
493 }, {
494 .name = "hsmmc",
Thomas Abraham8482c812012-04-14 08:04:46 -0700495 .devname = "exynos4-sdhci.2",
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900496 .parent = &exynos5_clk_aclk_200.clk,
497 .enable = exynos5_clk_ip_fsys_ctrl,
498 .ctrlbit = (1 << 14),
499 }, {
500 .name = "hsmmc",
Thomas Abraham8482c812012-04-14 08:04:46 -0700501 .devname = "exynos4-sdhci.3",
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900502 .parent = &exynos5_clk_aclk_200.clk,
503 .enable = exynos5_clk_ip_fsys_ctrl,
504 .ctrlbit = (1 << 15),
505 }, {
506 .name = "dwmci",
507 .parent = &exynos5_clk_aclk_200.clk,
508 .enable = exynos5_clk_ip_fsys_ctrl,
509 .ctrlbit = (1 << 16),
510 }, {
511 .name = "sata",
512 .devname = "ahci",
513 .enable = exynos5_clk_ip_fsys_ctrl,
514 .ctrlbit = (1 << 6),
515 }, {
516 .name = "sata_phy",
517 .enable = exynos5_clk_ip_fsys_ctrl,
518 .ctrlbit = (1 << 24),
519 }, {
520 .name = "sata_phy_i2c",
521 .enable = exynos5_clk_ip_fsys_ctrl,
522 .ctrlbit = (1 << 25),
523 }, {
524 .name = "mfc",
525 .devname = "s5p-mfc",
526 .enable = exynos5_clk_ip_mfc_ctrl,
527 .ctrlbit = (1 << 0),
528 }, {
529 .name = "hdmi",
530 .devname = "exynos4-hdmi",
531 .enable = exynos5_clk_ip_disp1_ctrl,
532 .ctrlbit = (1 << 6),
533 }, {
534 .name = "mixer",
535 .devname = "s5p-mixer",
536 .enable = exynos5_clk_ip_disp1_ctrl,
537 .ctrlbit = (1 << 5),
538 }, {
539 .name = "jpeg",
540 .enable = exynos5_clk_ip_gen_ctrl,
541 .ctrlbit = (1 << 2),
542 }, {
543 .name = "dsim0",
544 .enable = exynos5_clk_ip_disp1_ctrl,
545 .ctrlbit = (1 << 3),
546 }, {
547 .name = "iis",
548 .devname = "samsung-i2s.1",
549 .enable = exynos5_clk_ip_peric_ctrl,
550 .ctrlbit = (1 << 20),
551 }, {
552 .name = "iis",
553 .devname = "samsung-i2s.2",
554 .enable = exynos5_clk_ip_peric_ctrl,
555 .ctrlbit = (1 << 21),
556 }, {
557 .name = "pcm",
558 .devname = "samsung-pcm.1",
559 .enable = exynos5_clk_ip_peric_ctrl,
560 .ctrlbit = (1 << 22),
561 }, {
562 .name = "pcm",
563 .devname = "samsung-pcm.2",
564 .enable = exynos5_clk_ip_peric_ctrl,
565 .ctrlbit = (1 << 23),
566 }, {
567 .name = "spdif",
568 .devname = "samsung-spdif",
569 .enable = exynos5_clk_ip_peric_ctrl,
570 .ctrlbit = (1 << 26),
571 }, {
572 .name = "ac97",
573 .devname = "samsung-ac97",
574 .enable = exynos5_clk_ip_peric_ctrl,
575 .ctrlbit = (1 << 27),
576 }, {
577 .name = "usbhost",
578 .enable = exynos5_clk_ip_fsys_ctrl ,
579 .ctrlbit = (1 << 18),
580 }, {
581 .name = "usbotg",
582 .enable = exynos5_clk_ip_fsys_ctrl,
583 .ctrlbit = (1 << 7),
584 }, {
585 .name = "gps",
586 .enable = exynos5_clk_ip_gps_ctrl,
587 .ctrlbit = ((1 << 3) | (1 << 2) | (1 << 0)),
588 }, {
589 .name = "nfcon",
590 .enable = exynos5_clk_ip_fsys_ctrl,
591 .ctrlbit = (1 << 22),
592 }, {
593 .name = "iop",
594 .enable = exynos5_clk_ip_fsys_ctrl,
595 .ctrlbit = ((1 << 30) | (1 << 26) | (1 << 23)),
596 }, {
597 .name = "core_iop",
598 .enable = exynos5_clk_ip_core_ctrl,
599 .ctrlbit = ((1 << 21) | (1 << 3)),
600 }, {
601 .name = "mcu_iop",
602 .enable = exynos5_clk_ip_fsys_ctrl,
603 .ctrlbit = (1 << 0),
604 }, {
605 .name = "i2c",
606 .devname = "s3c2440-i2c.0",
607 .parent = &exynos5_clk_aclk_66.clk,
608 .enable = exynos5_clk_ip_peric_ctrl,
609 .ctrlbit = (1 << 6),
610 }, {
611 .name = "i2c",
612 .devname = "s3c2440-i2c.1",
613 .parent = &exynos5_clk_aclk_66.clk,
614 .enable = exynos5_clk_ip_peric_ctrl,
615 .ctrlbit = (1 << 7),
616 }, {
617 .name = "i2c",
618 .devname = "s3c2440-i2c.2",
619 .parent = &exynos5_clk_aclk_66.clk,
620 .enable = exynos5_clk_ip_peric_ctrl,
621 .ctrlbit = (1 << 8),
622 }, {
623 .name = "i2c",
624 .devname = "s3c2440-i2c.3",
625 .parent = &exynos5_clk_aclk_66.clk,
626 .enable = exynos5_clk_ip_peric_ctrl,
627 .ctrlbit = (1 << 9),
628 }, {
629 .name = "i2c",
630 .devname = "s3c2440-i2c.4",
631 .parent = &exynos5_clk_aclk_66.clk,
632 .enable = exynos5_clk_ip_peric_ctrl,
633 .ctrlbit = (1 << 10),
634 }, {
635 .name = "i2c",
636 .devname = "s3c2440-i2c.5",
637 .parent = &exynos5_clk_aclk_66.clk,
638 .enable = exynos5_clk_ip_peric_ctrl,
639 .ctrlbit = (1 << 11),
640 }, {
641 .name = "i2c",
642 .devname = "s3c2440-i2c.6",
643 .parent = &exynos5_clk_aclk_66.clk,
644 .enable = exynos5_clk_ip_peric_ctrl,
645 .ctrlbit = (1 << 12),
646 }, {
647 .name = "i2c",
648 .devname = "s3c2440-i2c.7",
649 .parent = &exynos5_clk_aclk_66.clk,
650 .enable = exynos5_clk_ip_peric_ctrl,
651 .ctrlbit = (1 << 13),
652 }, {
653 .name = "i2c",
654 .devname = "s3c2440-hdmiphy-i2c",
655 .parent = &exynos5_clk_aclk_66.clk,
656 .enable = exynos5_clk_ip_peric_ctrl,
657 .ctrlbit = (1 << 14),
KyongHo Chobca10b92012-04-04 09:23:02 -0700658 }, {
659 .name = SYSMMU_CLOCK_NAME,
660 .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
661 .enable = &exynos5_clk_ip_mfc_ctrl,
662 .ctrlbit = (1 << 1),
663 }, {
664 .name = SYSMMU_CLOCK_NAME,
665 .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
666 .enable = &exynos5_clk_ip_mfc_ctrl,
667 .ctrlbit = (1 << 2),
668 }, {
669 .name = SYSMMU_CLOCK_NAME,
670 .devname = SYSMMU_CLOCK_DEVNAME(tv, 2),
671 .enable = &exynos5_clk_ip_disp1_ctrl,
672 .ctrlbit = (1 << 9)
673 }, {
674 .name = SYSMMU_CLOCK_NAME,
675 .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3),
676 .enable = &exynos5_clk_ip_gen_ctrl,
677 .ctrlbit = (1 << 7),
678 }, {
679 .name = SYSMMU_CLOCK_NAME,
680 .devname = SYSMMU_CLOCK_DEVNAME(rot, 4),
681 .enable = &exynos5_clk_ip_gen_ctrl,
682 .ctrlbit = (1 << 6)
683 }, {
684 .name = SYSMMU_CLOCK_NAME,
685 .devname = SYSMMU_CLOCK_DEVNAME(gsc0, 5),
686 .enable = &exynos5_clk_ip_gscl_ctrl,
687 .ctrlbit = (1 << 7),
688 }, {
689 .name = SYSMMU_CLOCK_NAME,
690 .devname = SYSMMU_CLOCK_DEVNAME(gsc1, 6),
691 .enable = &exynos5_clk_ip_gscl_ctrl,
692 .ctrlbit = (1 << 8),
693 }, {
694 .name = SYSMMU_CLOCK_NAME,
695 .devname = SYSMMU_CLOCK_DEVNAME(gsc2, 7),
696 .enable = &exynos5_clk_ip_gscl_ctrl,
697 .ctrlbit = (1 << 9),
698 }, {
699 .name = SYSMMU_CLOCK_NAME,
700 .devname = SYSMMU_CLOCK_DEVNAME(gsc3, 8),
701 .enable = &exynos5_clk_ip_gscl_ctrl,
702 .ctrlbit = (1 << 10),
703 }, {
704 .name = SYSMMU_CLOCK_NAME,
705 .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
706 .enable = &exynos5_clk_ip_isp0_ctrl,
707 .ctrlbit = (0x3F << 8),
708 }, {
709 .name = SYSMMU_CLOCK_NAME2,
710 .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
711 .enable = &exynos5_clk_ip_isp1_ctrl,
712 .ctrlbit = (0xF << 4),
713 }, {
714 .name = SYSMMU_CLOCK_NAME,
715 .devname = SYSMMU_CLOCK_DEVNAME(camif0, 12),
716 .enable = &exynos5_clk_ip_gscl_ctrl,
717 .ctrlbit = (1 << 11),
718 }, {
719 .name = SYSMMU_CLOCK_NAME,
720 .devname = SYSMMU_CLOCK_DEVNAME(camif1, 13),
721 .enable = &exynos5_clk_ip_gscl_ctrl,
722 .ctrlbit = (1 << 12),
723 }, {
724 .name = SYSMMU_CLOCK_NAME,
725 .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
726 .enable = &exynos5_clk_ip_acp_ctrl,
727 .ctrlbit = (1 << 7)
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900728 }
729};
730
731static struct clk exynos5_init_clocks_on[] = {
732 {
733 .name = "uart",
734 .devname = "s5pv210-uart.0",
735 .enable = exynos5_clk_ip_peric_ctrl,
736 .ctrlbit = (1 << 0),
737 }, {
738 .name = "uart",
739 .devname = "s5pv210-uart.1",
740 .enable = exynos5_clk_ip_peric_ctrl,
741 .ctrlbit = (1 << 1),
742 }, {
743 .name = "uart",
744 .devname = "s5pv210-uart.2",
745 .enable = exynos5_clk_ip_peric_ctrl,
746 .ctrlbit = (1 << 2),
747 }, {
748 .name = "uart",
749 .devname = "s5pv210-uart.3",
750 .enable = exynos5_clk_ip_peric_ctrl,
751 .ctrlbit = (1 << 3),
752 }, {
753 .name = "uart",
754 .devname = "s5pv210-uart.4",
755 .enable = exynos5_clk_ip_peric_ctrl,
756 .ctrlbit = (1 << 4),
757 }, {
758 .name = "uart",
759 .devname = "s5pv210-uart.5",
760 .enable = exynos5_clk_ip_peric_ctrl,
761 .ctrlbit = (1 << 5),
762 }
763};
764
765static struct clk exynos5_clk_pdma0 = {
766 .name = "dma",
767 .devname = "dma-pl330.0",
768 .enable = exynos5_clk_ip_fsys_ctrl,
769 .ctrlbit = (1 << 1),
770};
771
772static struct clk exynos5_clk_pdma1 = {
773 .name = "dma",
774 .devname = "dma-pl330.1",
775 .enable = exynos5_clk_ip_fsys_ctrl,
Kukjin Kim28b874a2012-05-12 16:45:47 +0900776 .ctrlbit = (1 << 2),
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900777};
778
779static struct clk exynos5_clk_mdma1 = {
780 .name = "dma",
781 .devname = "dma-pl330.2",
782 .enable = exynos5_clk_ip_gen_ctrl,
783 .ctrlbit = (1 << 4),
784};
785
786struct clk *exynos5_clkset_group_list[] = {
787 [0] = &clk_ext_xtal_mux,
788 [1] = NULL,
789 [2] = &exynos5_clk_sclk_hdmi24m,
790 [3] = &exynos5_clk_sclk_dptxphy,
791 [4] = &exynos5_clk_sclk_usbphy,
792 [5] = &exynos5_clk_sclk_hdmiphy,
793 [6] = &exynos5_clk_mout_mpll_user.clk,
794 [7] = &exynos5_clk_mout_epll.clk,
795 [8] = &exynos5_clk_sclk_vpll.clk,
796 [9] = &exynos5_clk_mout_cpll.clk,
797};
798
799struct clksrc_sources exynos5_clkset_group = {
800 .sources = exynos5_clkset_group_list,
801 .nr_sources = ARRAY_SIZE(exynos5_clkset_group_list),
802};
803
804/* Possible clock sources for aclk_266_gscl_sub Mux */
805static struct clk *clk_src_gscl_266_list[] = {
806 [0] = &clk_ext_xtal_mux,
807 [1] = &exynos5_clk_aclk_266.clk,
808};
809
810static struct clksrc_sources clk_src_gscl_266 = {
811 .sources = clk_src_gscl_266_list,
812 .nr_sources = ARRAY_SIZE(clk_src_gscl_266_list),
813};
814
815static struct clksrc_clk exynos5_clk_dout_mmc0 = {
816 .clk = {
817 .name = "dout_mmc0",
818 },
819 .sources = &exynos5_clkset_group,
820 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 0, .size = 4 },
821 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 0, .size = 4 },
822};
823
824static struct clksrc_clk exynos5_clk_dout_mmc1 = {
825 .clk = {
826 .name = "dout_mmc1",
827 },
828 .sources = &exynos5_clkset_group,
829 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 4, .size = 4 },
830 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 16, .size = 4 },
831};
832
833static struct clksrc_clk exynos5_clk_dout_mmc2 = {
834 .clk = {
835 .name = "dout_mmc2",
836 },
837 .sources = &exynos5_clkset_group,
838 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 8, .size = 4 },
839 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 0, .size = 4 },
840};
841
842static struct clksrc_clk exynos5_clk_dout_mmc3 = {
843 .clk = {
844 .name = "dout_mmc3",
845 },
846 .sources = &exynos5_clkset_group,
847 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 12, .size = 4 },
848 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 16, .size = 4 },
849};
850
851static struct clksrc_clk exynos5_clk_dout_mmc4 = {
852 .clk = {
853 .name = "dout_mmc4",
854 },
855 .sources = &exynos5_clkset_group,
856 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 16, .size = 4 },
857 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 0, .size = 4 },
858};
859
860static struct clksrc_clk exynos5_clk_sclk_uart0 = {
861 .clk = {
862 .name = "uclk1",
863 .devname = "exynos4210-uart.0",
864 .enable = exynos5_clksrc_mask_peric0_ctrl,
865 .ctrlbit = (1 << 0),
866 },
867 .sources = &exynos5_clkset_group,
868 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 0, .size = 4 },
869 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 0, .size = 4 },
870};
871
872static struct clksrc_clk exynos5_clk_sclk_uart1 = {
873 .clk = {
874 .name = "uclk1",
875 .devname = "exynos4210-uart.1",
876 .enable = exynos5_clksrc_mask_peric0_ctrl,
877 .ctrlbit = (1 << 4),
878 },
879 .sources = &exynos5_clkset_group,
880 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 4, .size = 4 },
881 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 4, .size = 4 },
882};
883
884static struct clksrc_clk exynos5_clk_sclk_uart2 = {
885 .clk = {
886 .name = "uclk1",
887 .devname = "exynos4210-uart.2",
888 .enable = exynos5_clksrc_mask_peric0_ctrl,
889 .ctrlbit = (1 << 8),
890 },
891 .sources = &exynos5_clkset_group,
892 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 8, .size = 4 },
893 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 8, .size = 4 },
894};
895
896static struct clksrc_clk exynos5_clk_sclk_uart3 = {
897 .clk = {
898 .name = "uclk1",
899 .devname = "exynos4210-uart.3",
900 .enable = exynos5_clksrc_mask_peric0_ctrl,
901 .ctrlbit = (1 << 12),
902 },
903 .sources = &exynos5_clkset_group,
904 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 12, .size = 4 },
905 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 12, .size = 4 },
906};
907
908static struct clksrc_clk exynos5_clk_sclk_mmc0 = {
909 .clk = {
910 .name = "sclk_mmc",
Thomas Abraham8482c812012-04-14 08:04:46 -0700911 .devname = "exynos4-sdhci.0",
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900912 .parent = &exynos5_clk_dout_mmc0.clk,
913 .enable = exynos5_clksrc_mask_fsys_ctrl,
914 .ctrlbit = (1 << 0),
915 },
916 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 8, .size = 8 },
917};
918
919static struct clksrc_clk exynos5_clk_sclk_mmc1 = {
920 .clk = {
921 .name = "sclk_mmc",
Thomas Abraham8482c812012-04-14 08:04:46 -0700922 .devname = "exynos4-sdhci.1",
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900923 .parent = &exynos5_clk_dout_mmc1.clk,
924 .enable = exynos5_clksrc_mask_fsys_ctrl,
925 .ctrlbit = (1 << 4),
926 },
927 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 24, .size = 8 },
928};
929
930static struct clksrc_clk exynos5_clk_sclk_mmc2 = {
931 .clk = {
932 .name = "sclk_mmc",
Thomas Abraham8482c812012-04-14 08:04:46 -0700933 .devname = "exynos4-sdhci.2",
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900934 .parent = &exynos5_clk_dout_mmc2.clk,
935 .enable = exynos5_clksrc_mask_fsys_ctrl,
936 .ctrlbit = (1 << 8),
937 },
938 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 8, .size = 8 },
939};
940
941static struct clksrc_clk exynos5_clk_sclk_mmc3 = {
942 .clk = {
943 .name = "sclk_mmc",
Thomas Abraham8482c812012-04-14 08:04:46 -0700944 .devname = "exynos4-sdhci.3",
Kukjin Kim87b3c6e2012-01-22 21:46:13 +0900945 .parent = &exynos5_clk_dout_mmc3.clk,
946 .enable = exynos5_clksrc_mask_fsys_ctrl,
947 .ctrlbit = (1 << 12),
948 },
949 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 24, .size = 8 },
950};
951
952static struct clksrc_clk exynos5_clksrcs[] = {
953 {
954 .clk = {
955 .name = "sclk_dwmci",
956 .parent = &exynos5_clk_dout_mmc4.clk,
957 .enable = exynos5_clksrc_mask_fsys_ctrl,
958 .ctrlbit = (1 << 16),
959 },
960 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 8, .size = 8 },
961 }, {
962 .clk = {
963 .name = "sclk_fimd",
964 .devname = "s3cfb.1",
965 .enable = exynos5_clksrc_mask_disp1_0_ctrl,
966 .ctrlbit = (1 << 0),
967 },
968 .sources = &exynos5_clkset_group,
969 .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 0, .size = 4 },
970 .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 0, .size = 4 },
971 }, {
972 .clk = {
973 .name = "aclk_266_gscl",
974 },
975 .sources = &clk_src_gscl_266,
976 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 8, .size = 1 },
977 }, {
978 .clk = {
979 .name = "sclk_g3d",
980 .devname = "mali-t604.0",
981 .enable = exynos5_clk_block_ctrl,
982 .ctrlbit = (1 << 1),
983 },
984 .sources = &exynos5_clkset_aclk,
985 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
986 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
987 }, {
988 .clk = {
989 .name = "sclk_gscl_wrap",
990 .devname = "s5p-mipi-csis.0",
991 .enable = exynos5_clksrc_mask_gscl_ctrl,
992 .ctrlbit = (1 << 24),
993 },
994 .sources = &exynos5_clkset_group,
995 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 24, .size = 4 },
996 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 24, .size = 4 },
997 }, {
998 .clk = {
999 .name = "sclk_gscl_wrap",
1000 .devname = "s5p-mipi-csis.1",
1001 .enable = exynos5_clksrc_mask_gscl_ctrl,
1002 .ctrlbit = (1 << 28),
1003 },
1004 .sources = &exynos5_clkset_group,
1005 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 28, .size = 4 },
1006 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 28, .size = 4 },
1007 }, {
1008 .clk = {
1009 .name = "sclk_cam0",
1010 .enable = exynos5_clksrc_mask_gscl_ctrl,
1011 .ctrlbit = (1 << 16),
1012 },
1013 .sources = &exynos5_clkset_group,
1014 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 16, .size = 4 },
1015 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 16, .size = 4 },
1016 }, {
1017 .clk = {
1018 .name = "sclk_cam1",
1019 .enable = exynos5_clksrc_mask_gscl_ctrl,
1020 .ctrlbit = (1 << 20),
1021 },
1022 .sources = &exynos5_clkset_group,
1023 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 20, .size = 4 },
1024 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 20, .size = 4 },
1025 }, {
1026 .clk = {
1027 .name = "sclk_jpeg",
1028 .parent = &exynos5_clk_mout_cpll.clk,
1029 },
1030 .reg_div = { .reg = EXYNOS5_CLKDIV_GEN, .shift = 4, .size = 3 },
1031 },
1032};
1033
1034/* Clock initialization code */
1035static struct clksrc_clk *exynos5_sysclks[] = {
1036 &exynos5_clk_mout_apll,
1037 &exynos5_clk_sclk_apll,
1038 &exynos5_clk_mout_bpll,
1039 &exynos5_clk_mout_bpll_user,
1040 &exynos5_clk_mout_cpll,
1041 &exynos5_clk_mout_epll,
1042 &exynos5_clk_mout_mpll,
1043 &exynos5_clk_mout_mpll_user,
1044 &exynos5_clk_vpllsrc,
1045 &exynos5_clk_sclk_vpll,
1046 &exynos5_clk_mout_cpu,
1047 &exynos5_clk_dout_armclk,
1048 &exynos5_clk_dout_arm2clk,
1049 &exynos5_clk_cdrex,
1050 &exynos5_clk_aclk_400,
1051 &exynos5_clk_aclk_333,
1052 &exynos5_clk_aclk_266,
1053 &exynos5_clk_aclk_200,
1054 &exynos5_clk_aclk_166,
1055 &exynos5_clk_aclk_66_pre,
1056 &exynos5_clk_aclk_66,
1057 &exynos5_clk_dout_mmc0,
1058 &exynos5_clk_dout_mmc1,
1059 &exynos5_clk_dout_mmc2,
1060 &exynos5_clk_dout_mmc3,
1061 &exynos5_clk_dout_mmc4,
1062 &exynos5_clk_aclk_acp,
1063 &exynos5_clk_pclk_acp,
1064};
1065
1066static struct clk *exynos5_clk_cdev[] = {
1067 &exynos5_clk_pdma0,
1068 &exynos5_clk_pdma1,
1069 &exynos5_clk_mdma1,
1070};
1071
1072static struct clksrc_clk *exynos5_clksrc_cdev[] = {
1073 &exynos5_clk_sclk_uart0,
1074 &exynos5_clk_sclk_uart1,
1075 &exynos5_clk_sclk_uart2,
1076 &exynos5_clk_sclk_uart3,
1077 &exynos5_clk_sclk_mmc0,
1078 &exynos5_clk_sclk_mmc1,
1079 &exynos5_clk_sclk_mmc2,
1080 &exynos5_clk_sclk_mmc3,
1081};
1082
1083static struct clk_lookup exynos5_clk_lookup[] = {
1084 CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos5_clk_sclk_uart0.clk),
1085 CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1.clk),
1086 CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2.clk),
1087 CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3.clk),
Thomas Abraham8482c812012-04-14 08:04:46 -07001088 CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk),
1089 CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk),
1090 CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk),
1091 CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk),
Kukjin Kim87b3c6e2012-01-22 21:46:13 +09001092 CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0),
1093 CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1),
1094 CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1),
1095};
1096
1097static unsigned long exynos5_epll_get_rate(struct clk *clk)
1098{
1099 return clk->rate;
1100}
1101
1102static struct clk *exynos5_clks[] __initdata = {
1103 &exynos5_clk_sclk_hdmi27m,
1104 &exynos5_clk_sclk_hdmiphy,
1105 &clk_fout_bpll,
1106 &clk_fout_cpll,
1107 &exynos5_clk_armclk,
1108};
1109
1110static u32 epll_div[][6] = {
1111 { 192000000, 0, 48, 3, 1, 0 },
1112 { 180000000, 0, 45, 3, 1, 0 },
1113 { 73728000, 1, 73, 3, 3, 47710 },
1114 { 67737600, 1, 90, 4, 3, 20762 },
1115 { 49152000, 0, 49, 3, 3, 9961 },
1116 { 45158400, 0, 45, 3, 3, 10381 },
1117 { 180633600, 0, 45, 3, 1, 10381 },
1118};
1119
1120static int exynos5_epll_set_rate(struct clk *clk, unsigned long rate)
1121{
1122 unsigned int epll_con, epll_con_k;
1123 unsigned int i;
1124 unsigned int tmp;
1125 unsigned int epll_rate;
1126 unsigned int locktime;
1127 unsigned int lockcnt;
1128
1129 /* Return if nothing changed */
1130 if (clk->rate == rate)
1131 return 0;
1132
1133 if (clk->parent)
1134 epll_rate = clk_get_rate(clk->parent);
1135 else
1136 epll_rate = clk_ext_xtal_mux.rate;
1137
1138 if (epll_rate != 24000000) {
1139 pr_err("Invalid Clock : recommended clock is 24MHz.\n");
1140 return -EINVAL;
1141 }
1142
1143 epll_con = __raw_readl(EXYNOS5_EPLL_CON0);
1144 epll_con &= ~(0x1 << 27 | \
1145 PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \
1146 PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
1147 PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1148
1149 for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
1150 if (epll_div[i][0] == rate) {
1151 epll_con_k = epll_div[i][5] << 0;
1152 epll_con |= epll_div[i][1] << 27;
1153 epll_con |= epll_div[i][2] << PLL46XX_MDIV_SHIFT;
1154 epll_con |= epll_div[i][3] << PLL46XX_PDIV_SHIFT;
1155 epll_con |= epll_div[i][4] << PLL46XX_SDIV_SHIFT;
1156 break;
1157 }
1158 }
1159
1160 if (i == ARRAY_SIZE(epll_div)) {
1161 printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
1162 __func__);
1163 return -EINVAL;
1164 }
1165
1166 epll_rate /= 1000000;
1167
1168 /* 3000 max_cycls : specification data */
1169 locktime = 3000 / epll_rate * epll_div[i][3];
1170 lockcnt = locktime * 10000 / (10000 / epll_rate);
1171
1172 __raw_writel(lockcnt, EXYNOS5_EPLL_LOCK);
1173
1174 __raw_writel(epll_con, EXYNOS5_EPLL_CON0);
1175 __raw_writel(epll_con_k, EXYNOS5_EPLL_CON1);
1176
1177 do {
1178 tmp = __raw_readl(EXYNOS5_EPLL_CON0);
1179 } while (!(tmp & 0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT));
1180
1181 clk->rate = rate;
1182
1183 return 0;
1184}
1185
1186static struct clk_ops exynos5_epll_ops = {
1187 .get_rate = exynos5_epll_get_rate,
1188 .set_rate = exynos5_epll_set_rate,
1189};
1190
1191static int xtal_rate;
1192
1193static unsigned long exynos5_fout_apll_get_rate(struct clk *clk)
1194{
1195 return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS5_APLL_CON0));
1196}
1197
1198static struct clk_ops exynos5_fout_apll_ops = {
1199 .get_rate = exynos5_fout_apll_get_rate,
1200};
1201
1202#ifdef CONFIG_PM
1203static int exynos5_clock_suspend(void)
1204{
1205 s3c_pm_do_save(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
1206
1207 return 0;
1208}
1209
1210static void exynos5_clock_resume(void)
1211{
1212 s3c_pm_do_restore_core(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
1213}
1214#else
1215#define exynos5_clock_suspend NULL
1216#define exynos5_clock_resume NULL
1217#endif
1218
1219struct syscore_ops exynos5_clock_syscore_ops = {
1220 .suspend = exynos5_clock_suspend,
1221 .resume = exynos5_clock_resume,
1222};
1223
1224void __init_or_cpufreq exynos5_setup_clocks(void)
1225{
1226 struct clk *xtal_clk;
1227 unsigned long apll;
1228 unsigned long bpll;
1229 unsigned long cpll;
1230 unsigned long mpll;
1231 unsigned long epll;
1232 unsigned long vpll;
1233 unsigned long vpllsrc;
1234 unsigned long xtal;
1235 unsigned long armclk;
1236 unsigned long mout_cdrex;
1237 unsigned long aclk_400;
1238 unsigned long aclk_333;
1239 unsigned long aclk_266;
1240 unsigned long aclk_200;
1241 unsigned long aclk_166;
1242 unsigned long aclk_66;
1243 unsigned int ptr;
1244
1245 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1246
1247 xtal_clk = clk_get(NULL, "xtal");
1248 BUG_ON(IS_ERR(xtal_clk));
1249
1250 xtal = clk_get_rate(xtal_clk);
1251
1252 xtal_rate = xtal;
1253
1254 clk_put(xtal_clk);
1255
1256 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1257
1258 apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_APLL_CON0));
1259 bpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_BPLL_CON0));
1260 cpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_CPLL_CON0));
1261 mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_MPLL_CON0));
1262 epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS5_EPLL_CON0),
1263 __raw_readl(EXYNOS5_EPLL_CON1));
1264
1265 vpllsrc = clk_get_rate(&exynos5_clk_vpllsrc.clk);
1266 vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS5_VPLL_CON0),
1267 __raw_readl(EXYNOS5_VPLL_CON1));
1268
1269 clk_fout_apll.ops = &exynos5_fout_apll_ops;
1270 clk_fout_bpll.rate = bpll;
1271 clk_fout_cpll.rate = cpll;
1272 clk_fout_mpll.rate = mpll;
1273 clk_fout_epll.rate = epll;
1274 clk_fout_vpll.rate = vpll;
1275
1276 printk(KERN_INFO "EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n"
1277 "M=%ld, E=%ld V=%ld",
1278 apll, bpll, cpll, mpll, epll, vpll);
1279
1280 armclk = clk_get_rate(&exynos5_clk_armclk);
1281 mout_cdrex = clk_get_rate(&exynos5_clk_cdrex.clk);
1282
1283 aclk_400 = clk_get_rate(&exynos5_clk_aclk_400.clk);
1284 aclk_333 = clk_get_rate(&exynos5_clk_aclk_333.clk);
1285 aclk_266 = clk_get_rate(&exynos5_clk_aclk_266.clk);
1286 aclk_200 = clk_get_rate(&exynos5_clk_aclk_200.clk);
1287 aclk_166 = clk_get_rate(&exynos5_clk_aclk_166.clk);
1288 aclk_66 = clk_get_rate(&exynos5_clk_aclk_66.clk);
1289
1290 printk(KERN_INFO "EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400=%ld\n"
1291 "ACLK333=%ld, ACLK266=%ld, ACLK200=%ld\n"
1292 "ACLK166=%ld, ACLK66=%ld\n",
1293 armclk, mout_cdrex, aclk_400,
1294 aclk_333, aclk_266, aclk_200,
1295 aclk_166, aclk_66);
1296
1297
1298 clk_fout_epll.ops = &exynos5_epll_ops;
1299
1300 if (clk_set_parent(&exynos5_clk_mout_epll.clk, &clk_fout_epll))
1301 printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
1302 clk_fout_epll.name, exynos5_clk_mout_epll.clk.name);
1303
1304 clk_set_rate(&exynos5_clk_sclk_apll.clk, 100000000);
1305 clk_set_rate(&exynos5_clk_aclk_266.clk, 300000000);
1306
1307 clk_set_rate(&exynos5_clk_aclk_acp.clk, 267000000);
1308 clk_set_rate(&exynos5_clk_pclk_acp.clk, 134000000);
1309
1310 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrcs); ptr++)
1311 s3c_set_clksrc(&exynos5_clksrcs[ptr], true);
1312}
1313
1314void __init exynos5_register_clocks(void)
1315{
1316 int ptr;
1317
1318 s3c24xx_register_clocks(exynos5_clks, ARRAY_SIZE(exynos5_clks));
1319
1320 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sysclks); ptr++)
1321 s3c_register_clksrc(exynos5_sysclks[ptr], 1);
1322
1323 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sclk_tv); ptr++)
1324 s3c_register_clksrc(exynos5_sclk_tv[ptr], 1);
1325
1326 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrc_cdev); ptr++)
1327 s3c_register_clksrc(exynos5_clksrc_cdev[ptr], 1);
1328
1329 s3c_register_clksrc(exynos5_clksrcs, ARRAY_SIZE(exynos5_clksrcs));
1330 s3c_register_clocks(exynos5_init_clocks_on, ARRAY_SIZE(exynos5_init_clocks_on));
1331
1332 s3c24xx_register_clocks(exynos5_clk_cdev, ARRAY_SIZE(exynos5_clk_cdev));
1333 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clk_cdev); ptr++)
1334 s3c_disable_clocks(exynos5_clk_cdev[ptr], 1);
1335
1336 s3c_register_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
1337 s3c_disable_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
1338 clkdev_add_table(exynos5_clk_lookup, ARRAY_SIZE(exynos5_clk_lookup));
1339
1340 register_syscore_ops(&exynos5_clock_syscore_ops);
1341 s3c_pwmclk_init();
1342}