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