]> bbs.cooldavid.org Git - net-next-2.6.git/blame - arch/arm/mach-s5pv210/clock.c
ARM: S5PV210: Add sclk clocks of type 'struct clksrc_clk' clock
[net-next-2.6.git] / arch / arm / mach-s5pv210 / clock.c
CommitLineData
0c1945d3
KK
1/* linux/arch/arm/mach-s5pv210/clock.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - 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/init.h>
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/list.h>
17#include <linux/errno.h>
18#include <linux/err.h>
19#include <linux/clk.h>
20#include <linux/sysdev.h>
21#include <linux/io.h>
22
23#include <mach/map.h>
24
25#include <plat/cpu-freq.h>
26#include <mach/regs-clock.h>
27#include <plat/clock.h>
28#include <plat/cpu.h>
29#include <plat/pll.h>
30#include <plat/s5p-clock.h>
31#include <plat/clock-clksrc.h>
32#include <plat/s5pv210.h>
33
59cda520
TA
34static struct clksrc_clk clk_mout_apll = {
35 .clk = {
36 .name = "mout_apll",
37 .id = -1,
38 },
39 .sources = &clk_src_apll,
40 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
41};
42
43static struct clksrc_clk clk_mout_epll = {
44 .clk = {
45 .name = "mout_epll",
46 .id = -1,
47 },
48 .sources = &clk_src_epll,
49 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
50};
51
52static struct clksrc_clk clk_mout_mpll = {
53 .clk = {
54 .name = "mout_mpll",
55 .id = -1,
56 },
57 .sources = &clk_src_mpll,
58 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
59};
60
374e0bf5
TA
61static struct clk *clkset_armclk_list[] = {
62 [0] = &clk_mout_apll.clk,
63 [1] = &clk_mout_mpll.clk,
64};
65
66static struct clksrc_sources clkset_armclk = {
67 .sources = clkset_armclk_list,
68 .nr_sources = ARRAY_SIZE(clkset_armclk_list),
69};
70
71static struct clksrc_clk clk_armclk = {
72 .clk = {
73 .name = "armclk",
74 .id = -1,
75 },
76 .sources = &clkset_armclk,
77 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
78 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
79};
80
af76a201
TA
81static struct clksrc_clk clk_hclk_msys = {
82 .clk = {
83 .name = "hclk_msys",
84 .id = -1,
85 .parent = &clk_armclk.clk,
86 },
87 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
88};
89
6ed91a20
TA
90static struct clksrc_clk clk_pclk_msys = {
91 .clk = {
92 .name = "pclk_msys",
93 .id = -1,
94 .parent = &clk_hclk_msys.clk,
95 },
96 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
97};
98
0fe967a1
TA
99static struct clksrc_clk clk_sclk_a2m = {
100 .clk = {
101 .name = "sclk_a2m",
102 .id = -1,
103 .parent = &clk_mout_apll.clk,
104 },
105 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
106};
107
108static struct clk *clkset_hclk_sys_list[] = {
109 [0] = &clk_mout_mpll.clk,
110 [1] = &clk_sclk_a2m.clk,
111};
112
113static struct clksrc_sources clkset_hclk_sys = {
114 .sources = clkset_hclk_sys_list,
115 .nr_sources = ARRAY_SIZE(clkset_hclk_sys_list),
116};
117
118static struct clksrc_clk clk_hclk_dsys = {
119 .clk = {
120 .name = "hclk_dsys",
121 .id = -1,
122 },
123 .sources = &clkset_hclk_sys,
124 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
125 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
126};
127
58772cd3
TA
128static struct clksrc_clk clk_pclk_dsys = {
129 .clk = {
130 .name = "pclk_dsys",
131 .id = -1,
132 .parent = &clk_hclk_dsys.clk,
133 },
134 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
135};
136
acfa245f
TA
137static struct clksrc_clk clk_hclk_psys = {
138 .clk = {
139 .name = "hclk_psys",
140 .id = -1,
141 },
142 .sources = &clkset_hclk_sys,
143 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
144 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
145};
146
f44cf78b
TA
147static struct clksrc_clk clk_pclk_psys = {
148 .clk = {
149 .name = "pclk_psys",
150 .id = -1,
151 .parent = &clk_hclk_psys.clk,
152 },
153 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
154};
155
0c1945d3
KK
156static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
157{
158 return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
159}
160
161static int s5pv210_clk_ip1_ctrl(struct clk *clk, int enable)
162{
163 return s5p_gatectrl(S5P_CLKGATE_IP1, clk, enable);
164}
165
166static int s5pv210_clk_ip2_ctrl(struct clk *clk, int enable)
167{
168 return s5p_gatectrl(S5P_CLKGATE_IP2, clk, enable);
169}
170
171static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
172{
173 return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
174}
175
f64cacc3
TA
176static int s5pv210_clk_ip4_ctrl(struct clk *clk, int enable)
177{
178 return s5p_gatectrl(S5P_CLKGATE_IP4, clk, enable);
179}
180
f445dbd5
TA
181static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
182{
183 return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
184}
185
186static struct clk clk_sclk_hdmi27m = {
187 .name = "sclk_hdmi27m",
188 .id = -1,
189 .rate = 27000000,
190};
191
2cf4c2e6
TA
192static struct clk clk_sclk_hdmiphy = {
193 .name = "sclk_hdmiphy",
194 .id = -1,
195};
196
197static struct clk clk_sclk_usbphy0 = {
198 .name = "sclk_usbphy0",
199 .id = -1,
200};
201
202static struct clk clk_sclk_usbphy1 = {
203 .name = "sclk_usbphy1",
204 .id = -1,
205};
206
4583487c
TA
207static struct clk clk_pcmcdclk0 = {
208 .name = "pcmcdclk",
209 .id = -1,
210};
211
212static struct clk clk_pcmcdclk1 = {
213 .name = "pcmcdclk",
214 .id = -1,
215};
216
217static struct clk clk_pcmcdclk2 = {
218 .name = "pcmcdclk",
219 .id = -1,
220};
221
f445dbd5
TA
222static struct clk *clkset_vpllsrc_list[] = {
223 [0] = &clk_fin_vpll,
224 [1] = &clk_sclk_hdmi27m,
225};
226
227static struct clksrc_sources clkset_vpllsrc = {
228 .sources = clkset_vpllsrc_list,
229 .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list),
230};
231
232static struct clksrc_clk clk_vpllsrc = {
233 .clk = {
234 .name = "vpll_src",
235 .id = -1,
236 .enable = s5pv210_clk_mask0_ctrl,
237 .ctrlbit = (1 << 7),
238 },
239 .sources = &clkset_vpllsrc,
240 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 28, .size = 1 },
241};
242
243static struct clk *clkset_sclk_vpll_list[] = {
244 [0] = &clk_vpllsrc.clk,
245 [1] = &clk_fout_vpll,
246};
247
248static struct clksrc_sources clkset_sclk_vpll = {
249 .sources = clkset_sclk_vpll_list,
250 .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list),
251};
252
253static struct clksrc_clk clk_sclk_vpll = {
254 .clk = {
255 .name = "sclk_vpll",
256 .id = -1,
257 },
258 .sources = &clkset_sclk_vpll,
259 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
260};
261
664f5b20
TA
262static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
263{
264 return clk_get_rate(clk->parent) / 2;
265}
266
267static struct clk_ops clk_hclk_imem_ops = {
268 .get_rate = s5pv210_clk_imem_get_rate,
269};
270
0c1945d3
KK
271static struct clk init_clocks_disable[] = {
272 {
273 .name = "rot",
274 .id = -1,
0fe967a1 275 .parent = &clk_hclk_dsys.clk,
0c1945d3
KK
276 .enable = s5pv210_clk_ip0_ctrl,
277 .ctrlbit = (1<<29),
278 }, {
279 .name = "otg",
280 .id = -1,
acfa245f 281 .parent = &clk_hclk_psys.clk,
0c1945d3
KK
282 .enable = s5pv210_clk_ip1_ctrl,
283 .ctrlbit = (1<<16),
284 }, {
285 .name = "usb-host",
286 .id = -1,
acfa245f 287 .parent = &clk_hclk_psys.clk,
0c1945d3
KK
288 .enable = s5pv210_clk_ip1_ctrl,
289 .ctrlbit = (1<<17),
290 }, {
291 .name = "lcd",
292 .id = -1,
0fe967a1 293 .parent = &clk_hclk_dsys.clk,
0c1945d3
KK
294 .enable = s5pv210_clk_ip1_ctrl,
295 .ctrlbit = (1<<0),
296 }, {
297 .name = "cfcon",
298 .id = 0,
acfa245f 299 .parent = &clk_hclk_psys.clk,
0c1945d3
KK
300 .enable = s5pv210_clk_ip1_ctrl,
301 .ctrlbit = (1<<25),
302 }, {
303 .name = "hsmmc",
304 .id = 0,
acfa245f 305 .parent = &clk_hclk_psys.clk,
0c1945d3
KK
306 .enable = s5pv210_clk_ip2_ctrl,
307 .ctrlbit = (1<<16),
308 }, {
309 .name = "hsmmc",
310 .id = 1,
acfa245f 311 .parent = &clk_hclk_psys.clk,
0c1945d3
KK
312 .enable = s5pv210_clk_ip2_ctrl,
313 .ctrlbit = (1<<17),
314 }, {
315 .name = "hsmmc",
316 .id = 2,
acfa245f 317 .parent = &clk_hclk_psys.clk,
0c1945d3
KK
318 .enable = s5pv210_clk_ip2_ctrl,
319 .ctrlbit = (1<<18),
320 }, {
321 .name = "hsmmc",
322 .id = 3,
acfa245f 323 .parent = &clk_hclk_psys.clk,
0c1945d3
KK
324 .enable = s5pv210_clk_ip2_ctrl,
325 .ctrlbit = (1<<19),
326 }, {
327 .name = "systimer",
328 .id = -1,
f44cf78b 329 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
330 .enable = s5pv210_clk_ip3_ctrl,
331 .ctrlbit = (1<<16),
332 }, {
333 .name = "watchdog",
334 .id = -1,
f44cf78b 335 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
336 .enable = s5pv210_clk_ip3_ctrl,
337 .ctrlbit = (1<<22),
338 }, {
339 .name = "rtc",
340 .id = -1,
f44cf78b 341 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
342 .enable = s5pv210_clk_ip3_ctrl,
343 .ctrlbit = (1<<15),
344 }, {
345 .name = "i2c",
346 .id = 0,
f44cf78b 347 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
348 .enable = s5pv210_clk_ip3_ctrl,
349 .ctrlbit = (1<<7),
350 }, {
351 .name = "i2c",
352 .id = 1,
f44cf78b 353 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
354 .enable = s5pv210_clk_ip3_ctrl,
355 .ctrlbit = (1<<8),
356 }, {
357 .name = "i2c",
358 .id = 2,
f44cf78b 359 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
360 .enable = s5pv210_clk_ip3_ctrl,
361 .ctrlbit = (1<<9),
362 }, {
363 .name = "spi",
364 .id = 0,
f44cf78b 365 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
366 .enable = s5pv210_clk_ip3_ctrl,
367 .ctrlbit = (1<<12),
368 }, {
369 .name = "spi",
370 .id = 1,
f44cf78b 371 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
372 .enable = s5pv210_clk_ip3_ctrl,
373 .ctrlbit = (1<<13),
374 }, {
375 .name = "spi",
376 .id = 2,
f44cf78b 377 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
378 .enable = s5pv210_clk_ip3_ctrl,
379 .ctrlbit = (1<<14),
380 }, {
381 .name = "timers",
382 .id = -1,
f44cf78b 383 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
384 .enable = s5pv210_clk_ip3_ctrl,
385 .ctrlbit = (1<<23),
386 }, {
387 .name = "adc",
388 .id = -1,
f44cf78b 389 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
390 .enable = s5pv210_clk_ip3_ctrl,
391 .ctrlbit = (1<<24),
392 }, {
393 .name = "keypad",
394 .id = -1,
f44cf78b 395 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
396 .enable = s5pv210_clk_ip3_ctrl,
397 .ctrlbit = (1<<21),
398 }, {
399 .name = "i2s_v50",
400 .id = 0,
401 .parent = &clk_p,
402 .enable = s5pv210_clk_ip3_ctrl,
403 .ctrlbit = (1<<4),
404 }, {
405 .name = "i2s_v32",
406 .id = 0,
407 .parent = &clk_p,
408 .enable = s5pv210_clk_ip3_ctrl,
409 .ctrlbit = (1<<4),
410 }, {
411 .name = "i2s_v32",
412 .id = 1,
413 .parent = &clk_p,
414 .enable = s5pv210_clk_ip3_ctrl,
415 .ctrlbit = (1<<4),
416 }
417};
418
419static struct clk init_clocks[] = {
420 {
664f5b20
TA
421 .name = "hclk_imem",
422 .id = -1,
423 .parent = &clk_hclk_msys.clk,
424 .ctrlbit = (1 << 5),
425 .enable = s5pv210_clk_ip0_ctrl,
426 .ops = &clk_hclk_imem_ops,
427 }, {
0c1945d3
KK
428 .name = "uart",
429 .id = 0,
f44cf78b 430 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
431 .enable = s5pv210_clk_ip3_ctrl,
432 .ctrlbit = (1<<7),
433 }, {
434 .name = "uart",
435 .id = 1,
f44cf78b 436 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
437 .enable = s5pv210_clk_ip3_ctrl,
438 .ctrlbit = (1<<8),
439 }, {
440 .name = "uart",
441 .id = 2,
f44cf78b 442 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
443 .enable = s5pv210_clk_ip3_ctrl,
444 .ctrlbit = (1<<9),
445 }, {
446 .name = "uart",
447 .id = 3,
f44cf78b 448 .parent = &clk_pclk_psys.clk,
0c1945d3
KK
449 .enable = s5pv210_clk_ip3_ctrl,
450 .ctrlbit = (1<<10),
451 },
452};
453
0c1945d3
KK
454static struct clk *clkset_uart_list[] = {
455 [6] = &clk_mout_mpll.clk,
456 [7] = &clk_mout_epll.clk,
457};
458
459static struct clksrc_sources clkset_uart = {
460 .sources = clkset_uart_list,
461 .nr_sources = ARRAY_SIZE(clkset_uart_list),
462};
463
2cf4c2e6
TA
464static struct clk *clkset_group1_list[] = {
465 [0] = &clk_sclk_a2m.clk,
466 [1] = &clk_mout_mpll.clk,
467 [2] = &clk_mout_epll.clk,
468 [3] = &clk_sclk_vpll.clk,
469};
470
471static struct clksrc_sources clkset_group1 = {
472 .sources = clkset_group1_list,
473 .nr_sources = ARRAY_SIZE(clkset_group1_list),
474};
475
476static struct clk *clkset_sclk_onenand_list[] = {
477 [0] = &clk_hclk_psys.clk,
478 [1] = &clk_hclk_dsys.clk,
479};
480
481static struct clksrc_sources clkset_sclk_onenand = {
482 .sources = clkset_sclk_onenand_list,
483 .nr_sources = ARRAY_SIZE(clkset_sclk_onenand_list),
484};
485
9e20614b
TA
486static struct clk *clkset_sclk_dac_list[] = {
487 [0] = &clk_sclk_vpll.clk,
488 [1] = &clk_sclk_hdmiphy,
489};
490
491static struct clksrc_sources clkset_sclk_dac = {
492 .sources = clkset_sclk_dac_list,
493 .nr_sources = ARRAY_SIZE(clkset_sclk_dac_list),
494};
495
496static struct clksrc_clk clk_sclk_dac = {
497 .clk = {
498 .name = "sclk_dac",
499 .id = -1,
500 .ctrlbit = (1 << 10),
501 .enable = s5pv210_clk_ip1_ctrl,
502 },
503 .sources = &clkset_sclk_dac,
504 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 },
505};
506
507static struct clksrc_clk clk_sclk_pixel = {
508 .clk = {
509 .name = "sclk_pixel",
510 .id = -1,
511 .parent = &clk_sclk_vpll.clk,
512 },
513 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4},
514};
515
516static struct clk *clkset_sclk_hdmi_list[] = {
517 [0] = &clk_sclk_pixel.clk,
518 [1] = &clk_sclk_hdmiphy,
519};
520
521static struct clksrc_sources clkset_sclk_hdmi = {
522 .sources = clkset_sclk_hdmi_list,
523 .nr_sources = ARRAY_SIZE(clkset_sclk_hdmi_list),
524};
525
526static struct clksrc_clk clk_sclk_hdmi = {
527 .clk = {
528 .name = "sclk_hdmi",
529 .id = -1,
530 .enable = s5pv210_clk_ip1_ctrl,
531 .ctrlbit = (1 << 11),
532 },
533 .sources = &clkset_sclk_hdmi,
534 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
535};
536
537static struct clk *clkset_sclk_mixer_list[] = {
538 [0] = &clk_sclk_dac.clk,
539 [1] = &clk_sclk_hdmi.clk,
540};
541
542static struct clksrc_sources clkset_sclk_mixer = {
543 .sources = clkset_sclk_mixer_list,
544 .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list),
545};
546
4583487c
TA
547static struct clk *clkset_sclk_audio0_list[] = {
548 [0] = &clk_ext_xtal_mux,
549 [1] = &clk_pcmcdclk0,
550 [2] = &clk_sclk_hdmi27m,
551 [3] = &clk_sclk_usbphy0,
552 [4] = &clk_sclk_usbphy1,
553 [5] = &clk_sclk_hdmiphy,
554 [6] = &clk_mout_mpll.clk,
555 [7] = &clk_mout_epll.clk,
556 [8] = &clk_sclk_vpll.clk,
557};
558
559static struct clksrc_sources clkset_sclk_audio0 = {
560 .sources = clkset_sclk_audio0_list,
561 .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list),
562};
563
564static struct clksrc_clk clk_sclk_audio0 = {
565 .clk = {
566 .name = "sclk_audio",
567 .id = 0,
568 .enable = s5pv210_clk_ip3_ctrl,
569 .ctrlbit = (1 << 4),
570 },
571 .sources = &clkset_sclk_audio0,
572 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 },
573 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
574};
575
576static struct clk *clkset_sclk_audio1_list[] = {
577 [0] = &clk_ext_xtal_mux,
578 [1] = &clk_pcmcdclk1,
579 [2] = &clk_sclk_hdmi27m,
580 [3] = &clk_sclk_usbphy0,
581 [4] = &clk_sclk_usbphy1,
582 [5] = &clk_sclk_hdmiphy,
583 [6] = &clk_mout_mpll.clk,
584 [7] = &clk_mout_epll.clk,
585 [8] = &clk_sclk_vpll.clk,
586};
587
588static struct clksrc_sources clkset_sclk_audio1 = {
589 .sources = clkset_sclk_audio1_list,
590 .nr_sources = ARRAY_SIZE(clkset_sclk_audio1_list),
591};
592
593static struct clksrc_clk clk_sclk_audio1 = {
594 .clk = {
595 .name = "sclk_audio",
596 .id = 1,
597 .enable = s5pv210_clk_ip3_ctrl,
598 .ctrlbit = (1 << 5),
599 },
600 .sources = &clkset_sclk_audio1,
601 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 },
602 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 },
603};
604
605static struct clk *clkset_sclk_audio2_list[] = {
606 [0] = &clk_ext_xtal_mux,
607 [1] = &clk_pcmcdclk0,
608 [2] = &clk_sclk_hdmi27m,
609 [3] = &clk_sclk_usbphy0,
610 [4] = &clk_sclk_usbphy1,
611 [5] = &clk_sclk_hdmiphy,
612 [6] = &clk_mout_mpll.clk,
613 [7] = &clk_mout_epll.clk,
614 [8] = &clk_sclk_vpll.clk,
615};
616
617static struct clksrc_sources clkset_sclk_audio2 = {
618 .sources = clkset_sclk_audio2_list,
619 .nr_sources = ARRAY_SIZE(clkset_sclk_audio2_list),
620};
621
622static struct clksrc_clk clk_sclk_audio2 = {
623 .clk = {
624 .name = "sclk_audio",
625 .id = 2,
626 .enable = s5pv210_clk_ip3_ctrl,
627 .ctrlbit = (1 << 6),
628 },
629 .sources = &clkset_sclk_audio2,
630 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 },
631 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 },
632};
633
634static struct clk *clkset_sclk_spdif_list[] = {
635 [0] = &clk_sclk_audio0.clk,
636 [1] = &clk_sclk_audio1.clk,
637 [2] = &clk_sclk_audio2.clk,
638};
639
640static struct clksrc_sources clkset_sclk_spdif = {
641 .sources = clkset_sclk_spdif_list,
642 .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list),
643};
644
f64cacc3
TA
645static struct clk *clkset_group2_list[] = {
646 [0] = &clk_ext_xtal_mux,
647 [1] = &clk_xusbxti,
648 [2] = &clk_sclk_hdmi27m,
649 [3] = &clk_sclk_usbphy0,
650 [4] = &clk_sclk_usbphy1,
651 [5] = &clk_sclk_hdmiphy,
652 [6] = &clk_mout_mpll.clk,
653 [7] = &clk_mout_epll.clk,
654 [8] = &clk_sclk_vpll.clk,
655};
656
657static struct clksrc_sources clkset_group2 = {
658 .sources = clkset_group2_list,
659 .nr_sources = ARRAY_SIZE(clkset_group2_list),
660};
661
0c1945d3
KK
662static struct clksrc_clk clksrcs[] = {
663 {
2cf4c2e6
TA
664 .clk = {
665 .name = "sclk_dmc",
666 .id = -1,
667 },
668 .sources = &clkset_group1,
669 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
670 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
671 }, {
672 .clk = {
673 .name = "sclk_onenand",
674 .id = -1,
675 },
676 .sources = &clkset_sclk_onenand,
677 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
678 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
679 }, {
0c1945d3
KK
680 .clk = {
681 .name = "uclk1",
f64cacc3 682 .id = 0,
0c1945d3
KK
683 .ctrlbit = (1<<17),
684 .enable = s5pv210_clk_ip3_ctrl,
685 },
686 .sources = &clkset_uart,
687 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
688 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
f64cacc3
TA
689 }, {
690 .clk = {
691 .name = "uclk1",
692 .id = 1,
693 .enable = s5pv210_clk_ip3_ctrl,
694 .ctrlbit = (1 << 18),
695 },
696 .sources = &clkset_uart,
697 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
698 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
699 }, {
700 .clk = {
701 .name = "uclk1",
702 .id = 2,
703 .enable = s5pv210_clk_ip3_ctrl,
704 .ctrlbit = (1 << 19),
705 },
706 .sources = &clkset_uart,
707 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
708 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
709 }, {
710 .clk = {
711 .name = "uclk1",
712 .id = 3,
713 .enable = s5pv210_clk_ip3_ctrl,
714 .ctrlbit = (1 << 20),
715 },
716 .sources = &clkset_uart,
717 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
718 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
9e20614b
TA
719 }, {
720 .clk = {
721 .name = "sclk_mixer",
722 .id = -1,
723 .enable = s5pv210_clk_ip1_ctrl,
724 .ctrlbit = (1 << 9),
725 },
726 .sources = &clkset_sclk_mixer,
727 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
4583487c
TA
728 }, {
729 .clk = {
730 .name = "sclk_spdif",
731 .id = -1,
732 .enable = s5pv210_clk_mask0_ctrl,
733 .ctrlbit = (1 << 27),
734 },
735 .sources = &clkset_sclk_spdif,
736 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
f64cacc3
TA
737 }, {
738 .clk = {
739 .name = "sclk_fimc",
740 .id = 0,
741 .enable = s5pv210_clk_ip0_ctrl,
742 .ctrlbit = (1 << 24),
743 },
744 .sources = &clkset_group2,
745 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 },
746 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
747 }, {
748 .clk = {
749 .name = "sclk_fimc",
750 .id = 1,
751 .enable = s5pv210_clk_ip0_ctrl,
752 .ctrlbit = (1 << 25),
753 },
754 .sources = &clkset_group2,
755 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 },
756 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
757 }, {
758 .clk = {
759 .name = "sclk_fimc",
760 .id = 2,
761 .enable = s5pv210_clk_ip0_ctrl,
762 .ctrlbit = (1 << 26),
763 },
764 .sources = &clkset_group2,
765 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 },
766 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
767 }, {
768 .clk = {
769 .name = "sclk_cam",
770 .id = 0,
771 },
772 .sources = &clkset_group2,
773 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 },
774 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
775 }, {
776 .clk = {
777 .name = "sclk_cam",
778 .id = 1,
779 },
780 .sources = &clkset_group2,
781 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 },
782 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 },
783 }, {
784 .clk = {
785 .name = "sclk_fimd",
786 .id = -1,
787 .enable = s5pv210_clk_ip1_ctrl,
788 .ctrlbit = (1 << 0),
789 },
790 .sources = &clkset_group2,
791 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
792 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
793 }, {
794 .clk = {
795 .name = "sclk_mmc",
796 .id = 0,
797 .enable = s5pv210_clk_ip2_ctrl,
798 .ctrlbit = (1 << 16),
799 },
800 .sources = &clkset_group2,
801 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
802 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
803 }, {
804 .clk = {
805 .name = "sclk_mmc",
806 .id = 1,
807 .enable = s5pv210_clk_ip2_ctrl,
808 .ctrlbit = (1 << 17),
809 },
810 .sources = &clkset_group2,
811 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
812 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
813 }, {
814 .clk = {
815 .name = "sclk_mmc",
816 .id = 2,
817 .enable = s5pv210_clk_ip2_ctrl,
818 .ctrlbit = (1 << 18),
819 },
820 .sources = &clkset_group2,
821 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
822 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
823 }, {
824 .clk = {
825 .name = "sclk_mmc",
826 .id = 3,
827 .enable = s5pv210_clk_ip2_ctrl,
828 .ctrlbit = (1 << 19),
829 },
830 .sources = &clkset_group2,
831 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
832 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
833 }, {
834 .clk = {
835 .name = "sclk_mfc",
836 .id = -1,
837 .enable = s5pv210_clk_ip0_ctrl,
838 .ctrlbit = (1 << 16),
839 },
840 .sources = &clkset_group1,
841 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
842 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
843 }, {
844 .clk = {
845 .name = "sclk_g2d",
846 .id = -1,
847 .enable = s5pv210_clk_ip0_ctrl,
848 .ctrlbit = (1 << 12),
849 },
850 .sources = &clkset_group1,
851 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
852 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
853 }, {
854 .clk = {
855 .name = "sclk_g3d",
856 .id = -1,
857 .enable = s5pv210_clk_ip0_ctrl,
858 .ctrlbit = (1 << 8),
859 },
860 .sources = &clkset_group1,
861 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
862 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
863 }, {
864 .clk = {
865 .name = "sclk_csis",
866 .id = -1,
867 .enable = s5pv210_clk_ip0_ctrl,
868 .ctrlbit = (1 << 31),
869 },
870 .sources = &clkset_group2,
871 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
872 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
873 }, {
874 .clk = {
875 .name = "sclk_spi",
876 .id = 0,
877 .enable = s5pv210_clk_ip3_ctrl,
878 .ctrlbit = (1 << 12),
879 },
880 .sources = &clkset_group2,
881 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
882 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
883 }, {
884 .clk = {
885 .name = "sclk_spi",
886 .id = 1,
887 .enable = s5pv210_clk_ip3_ctrl,
888 .ctrlbit = (1 << 13),
889 },
890 .sources = &clkset_group2,
891 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
892 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
893 }, {
894 .clk = {
895 .name = "sclk_pwi",
896 .id = -1,
897 .enable = &s5pv210_clk_ip4_ctrl,
898 .ctrlbit = (1 << 2),
899 },
900 .sources = &clkset_group2,
901 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 },
902 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 },
903 }, {
904 .clk = {
905 .name = "sclk_pwm",
906 .id = -1,
907 .enable = s5pv210_clk_ip3_ctrl,
908 .ctrlbit = (1 << 23),
909 },
910 .sources = &clkset_group2,
911 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
912 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 },
9e20614b 913 },
0c1945d3
KK
914};
915
916/* Clock initialisation code */
eb1ef1ed 917static struct clksrc_clk *sysclks[] = {
0c1945d3
KK
918 &clk_mout_apll,
919 &clk_mout_epll,
920 &clk_mout_mpll,
374e0bf5 921 &clk_armclk,
af76a201 922 &clk_hclk_msys,
0fe967a1
TA
923 &clk_sclk_a2m,
924 &clk_hclk_dsys,
acfa245f 925 &clk_hclk_psys,
6ed91a20 926 &clk_pclk_msys,
58772cd3 927 &clk_pclk_dsys,
f44cf78b 928 &clk_pclk_psys,
f445dbd5
TA
929 &clk_vpllsrc,
930 &clk_sclk_vpll,
9e20614b
TA
931 &clk_sclk_dac,
932 &clk_sclk_pixel,
933 &clk_sclk_hdmi,
0c1945d3
KK
934};
935
0c1945d3
KK
936void __init_or_cpufreq s5pv210_setup_clocks(void)
937{
938 struct clk *xtal_clk;
939 unsigned long xtal;
f445dbd5 940 unsigned long vpllsrc;
0c1945d3 941 unsigned long armclk;
af76a201 942 unsigned long hclk_msys;
0fe967a1 943 unsigned long hclk_dsys;
acfa245f 944 unsigned long hclk_psys;
6ed91a20 945 unsigned long pclk_msys;
58772cd3 946 unsigned long pclk_dsys;
f44cf78b 947 unsigned long pclk_psys;
0c1945d3
KK
948 unsigned long apll;
949 unsigned long mpll;
950 unsigned long epll;
f445dbd5 951 unsigned long vpll;
0c1945d3
KK
952 unsigned int ptr;
953 u32 clkdiv0, clkdiv1;
954
955 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
956
957 clkdiv0 = __raw_readl(S5P_CLK_DIV0);
958 clkdiv1 = __raw_readl(S5P_CLK_DIV1);
959
960 printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
961 __func__, clkdiv0, clkdiv1);
962
963 xtal_clk = clk_get(NULL, "xtal");
964 BUG_ON(IS_ERR(xtal_clk));
965
966 xtal = clk_get_rate(xtal_clk);
967 clk_put(xtal_clk);
968
969 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
970
971 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
972 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
973 epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
f445dbd5
TA
974 vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
975 vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
0c1945d3 976
c62ec6a9
TA
977 clk_fout_apll.rate = apll;
978 clk_fout_mpll.rate = mpll;
979 clk_fout_epll.rate = epll;
f445dbd5 980 clk_fout_vpll.rate = vpll;
c62ec6a9 981
f445dbd5
TA
982 printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
983 apll, mpll, epll, vpll);
0c1945d3 984
374e0bf5 985 armclk = clk_get_rate(&clk_armclk.clk);
af76a201 986 hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
0fe967a1 987 hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk);
acfa245f 988 hclk_psys = clk_get_rate(&clk_hclk_psys.clk);
6ed91a20 989 pclk_msys = clk_get_rate(&clk_pclk_msys.clk);
58772cd3 990 pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk);
f44cf78b 991 pclk_psys = clk_get_rate(&clk_pclk_psys.clk);
0c1945d3 992
acfa245f
TA
993 printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n"
994 "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
995 armclk, hclk_msys, hclk_dsys, hclk_psys,
f44cf78b 996 pclk_msys, pclk_dsys, pclk_psys);
0c1945d3 997
0c1945d3 998 clk_f.rate = armclk;
acfa245f 999 clk_h.rate = hclk_psys;
f44cf78b 1000 clk_p.rate = pclk_psys;
0c1945d3 1001
0c1945d3
KK
1002 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1003 s3c_set_clksrc(&clksrcs[ptr], true);
1004}
1005
1006static struct clk *clks[] __initdata = {
f445dbd5 1007 &clk_sclk_hdmi27m,
2cf4c2e6
TA
1008 &clk_sclk_hdmiphy,
1009 &clk_sclk_usbphy0,
1010 &clk_sclk_usbphy1,
4583487c
TA
1011 &clk_pcmcdclk0,
1012 &clk_pcmcdclk1,
1013 &clk_pcmcdclk2,
0c1945d3
KK
1014};
1015
1016void __init s5pv210_register_clocks(void)
1017{
1018 struct clk *clkp;
1019 int ret;
1020 int ptr;
1021
1022 ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1023 if (ret > 0)
1024 printk(KERN_ERR "Failed to register %u clocks\n", ret);
1025
eb1ef1ed
TA
1026 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1027 s3c_register_clksrc(sysclks[ptr], 1);
1028
0c1945d3
KK
1029 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1030 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1031
0c1945d3
KK
1032 clkp = init_clocks_disable;
1033 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
1034 ret = s3c24xx_register_clock(clkp);
1035 if (ret < 0) {
1036 printk(KERN_ERR "Failed to register clock %s (%d)\n",
1037 clkp->name, ret);
1038 }
1039 (clkp->enable)(clkp, 0);
1040 }
1041
1042 s3c_pwmclk_init();
1043}