Merge branch 'for-35' of git://repo.or.cz/linux-kbuild
[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_ip4_ctrl(struct clk *clk, int enable)
177 {
178         return s5p_gatectrl(S5P_CLKGATE_IP4, clk, enable);
179 }
180
181 static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
182 {
183         return s5p_gatectrl(S5P_CLK_SRC_MASK0, 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           = "otg",
280                 .id             = -1,
281                 .parent         = &clk_hclk_psys.clk,
282                 .enable         = s5pv210_clk_ip1_ctrl,
283                 .ctrlbit        = (1<<16),
284         }, {
285                 .name           = "usb-host",
286                 .id             = -1,
287                 .parent         = &clk_hclk_psys.clk,
288                 .enable         = s5pv210_clk_ip1_ctrl,
289                 .ctrlbit        = (1<<17),
290         }, {
291                 .name           = "lcd",
292                 .id             = -1,
293                 .parent         = &clk_hclk_dsys.clk,
294                 .enable         = s5pv210_clk_ip1_ctrl,
295                 .ctrlbit        = (1<<0),
296         }, {
297                 .name           = "cfcon",
298                 .id             = 0,
299                 .parent         = &clk_hclk_psys.clk,
300                 .enable         = s5pv210_clk_ip1_ctrl,
301                 .ctrlbit        = (1<<25),
302         }, {
303                 .name           = "hsmmc",
304                 .id             = 0,
305                 .parent         = &clk_hclk_psys.clk,
306                 .enable         = s5pv210_clk_ip2_ctrl,
307                 .ctrlbit        = (1<<16),
308         }, {
309                 .name           = "hsmmc",
310                 .id             = 1,
311                 .parent         = &clk_hclk_psys.clk,
312                 .enable         = s5pv210_clk_ip2_ctrl,
313                 .ctrlbit        = (1<<17),
314         }, {
315                 .name           = "hsmmc",
316                 .id             = 2,
317                 .parent         = &clk_hclk_psys.clk,
318                 .enable         = s5pv210_clk_ip2_ctrl,
319                 .ctrlbit        = (1<<18),
320         }, {
321                 .name           = "hsmmc",
322                 .id             = 3,
323                 .parent         = &clk_hclk_psys.clk,
324                 .enable         = s5pv210_clk_ip2_ctrl,
325                 .ctrlbit        = (1<<19),
326         }, {
327                 .name           = "systimer",
328                 .id             = -1,
329                 .parent         = &clk_pclk_psys.clk,
330                 .enable         = s5pv210_clk_ip3_ctrl,
331                 .ctrlbit        = (1<<16),
332         }, {
333                 .name           = "watchdog",
334                 .id             = -1,
335                 .parent         = &clk_pclk_psys.clk,
336                 .enable         = s5pv210_clk_ip3_ctrl,
337                 .ctrlbit        = (1<<22),
338         }, {
339                 .name           = "rtc",
340                 .id             = -1,
341                 .parent         = &clk_pclk_psys.clk,
342                 .enable         = s5pv210_clk_ip3_ctrl,
343                 .ctrlbit        = (1<<15),
344         }, {
345                 .name           = "i2c",
346                 .id             = 0,
347                 .parent         = &clk_pclk_psys.clk,
348                 .enable         = s5pv210_clk_ip3_ctrl,
349                 .ctrlbit        = (1<<7),
350         }, {
351                 .name           = "i2c",
352                 .id             = 1,
353                 .parent         = &clk_pclk_psys.clk,
354                 .enable         = s5pv210_clk_ip3_ctrl,
355                 .ctrlbit        = (1<<8),
356         }, {
357                 .name           = "i2c",
358                 .id             = 2,
359                 .parent         = &clk_pclk_psys.clk,
360                 .enable         = s5pv210_clk_ip3_ctrl,
361                 .ctrlbit        = (1<<9),
362         }, {
363                 .name           = "spi",
364                 .id             = 0,
365                 .parent         = &clk_pclk_psys.clk,
366                 .enable         = s5pv210_clk_ip3_ctrl,
367                 .ctrlbit        = (1<<12),
368         }, {
369                 .name           = "spi",
370                 .id             = 1,
371                 .parent         = &clk_pclk_psys.clk,
372                 .enable         = s5pv210_clk_ip3_ctrl,
373                 .ctrlbit        = (1<<13),
374         }, {
375                 .name           = "spi",
376                 .id             = 2,
377                 .parent         = &clk_pclk_psys.clk,
378                 .enable         = s5pv210_clk_ip3_ctrl,
379                 .ctrlbit        = (1<<14),
380         }, {
381                 .name           = "timers",
382                 .id             = -1,
383                 .parent         = &clk_pclk_psys.clk,
384                 .enable         = s5pv210_clk_ip3_ctrl,
385                 .ctrlbit        = (1<<23),
386         }, {
387                 .name           = "adc",
388                 .id             = -1,
389                 .parent         = &clk_pclk_psys.clk,
390                 .enable         = s5pv210_clk_ip3_ctrl,
391                 .ctrlbit        = (1<<24),
392         }, {
393                 .name           = "keypad",
394                 .id             = -1,
395                 .parent         = &clk_pclk_psys.clk,
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
419 static struct clk init_clocks[] = {
420         {
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         }, {
428                 .name           = "uart",
429                 .id             = 0,
430                 .parent         = &clk_pclk_psys.clk,
431                 .enable         = s5pv210_clk_ip3_ctrl,
432                 .ctrlbit        = (1<<7),
433         }, {
434                 .name           = "uart",
435                 .id             = 1,
436                 .parent         = &clk_pclk_psys.clk,
437                 .enable         = s5pv210_clk_ip3_ctrl,
438                 .ctrlbit        = (1<<8),
439         }, {
440                 .name           = "uart",
441                 .id             = 2,
442                 .parent         = &clk_pclk_psys.clk,
443                 .enable         = s5pv210_clk_ip3_ctrl,
444                 .ctrlbit        = (1<<9),
445         }, {
446                 .name           = "uart",
447                 .id             = 3,
448                 .parent         = &clk_pclk_psys.clk,
449                 .enable         = s5pv210_clk_ip3_ctrl,
450                 .ctrlbit        = (1<<10),
451         },
452 };
453
454 static struct clk *clkset_uart_list[] = {
455         [6] = &clk_mout_mpll.clk,
456         [7] = &clk_mout_epll.clk,
457 };
458
459 static struct clksrc_sources clkset_uart = {
460         .sources        = clkset_uart_list,
461         .nr_sources     = ARRAY_SIZE(clkset_uart_list),
462 };
463
464 static 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
471 static struct clksrc_sources clkset_group1 = {
472         .sources        = clkset_group1_list,
473         .nr_sources     = ARRAY_SIZE(clkset_group1_list),
474 };
475
476 static struct clk *clkset_sclk_onenand_list[] = {
477         [0] = &clk_hclk_psys.clk,
478         [1] = &clk_hclk_dsys.clk,
479 };
480
481 static struct clksrc_sources clkset_sclk_onenand = {
482         .sources        = clkset_sclk_onenand_list,
483         .nr_sources     = ARRAY_SIZE(clkset_sclk_onenand_list),
484 };
485
486 static struct clk *clkset_sclk_dac_list[] = {
487         [0] = &clk_sclk_vpll.clk,
488         [1] = &clk_sclk_hdmiphy,
489 };
490
491 static struct clksrc_sources clkset_sclk_dac = {
492         .sources        = clkset_sclk_dac_list,
493         .nr_sources     = ARRAY_SIZE(clkset_sclk_dac_list),
494 };
495
496 static 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
507 static 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
516 static struct clk *clkset_sclk_hdmi_list[] = {
517         [0] = &clk_sclk_pixel.clk,
518         [1] = &clk_sclk_hdmiphy,
519 };
520
521 static struct clksrc_sources clkset_sclk_hdmi = {
522         .sources        = clkset_sclk_hdmi_list,
523         .nr_sources     = ARRAY_SIZE(clkset_sclk_hdmi_list),
524 };
525
526 static 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
537 static struct clk *clkset_sclk_mixer_list[] = {
538         [0] = &clk_sclk_dac.clk,
539         [1] = &clk_sclk_hdmi.clk,
540 };
541
542 static struct clksrc_sources clkset_sclk_mixer = {
543         .sources        = clkset_sclk_mixer_list,
544         .nr_sources     = ARRAY_SIZE(clkset_sclk_mixer_list),
545 };
546
547 static 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
559 static struct clksrc_sources clkset_sclk_audio0 = {
560         .sources        = clkset_sclk_audio0_list,
561         .nr_sources     = ARRAY_SIZE(clkset_sclk_audio0_list),
562 };
563
564 static 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
576 static 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
588 static struct clksrc_sources clkset_sclk_audio1 = {
589         .sources        = clkset_sclk_audio1_list,
590         .nr_sources     = ARRAY_SIZE(clkset_sclk_audio1_list),
591 };
592
593 static 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
605 static 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
617 static struct clksrc_sources clkset_sclk_audio2 = {
618         .sources        = clkset_sclk_audio2_list,
619         .nr_sources     = ARRAY_SIZE(clkset_sclk_audio2_list),
620 };
621
622 static 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
634 static 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
640 static struct clksrc_sources clkset_sclk_spdif = {
641         .sources        = clkset_sclk_spdif_list,
642         .nr_sources     = ARRAY_SIZE(clkset_sclk_spdif_list),
643 };
644
645 static 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
657 static struct clksrc_sources clkset_group2 = {
658         .sources        = clkset_group2_list,
659         .nr_sources     = ARRAY_SIZE(clkset_group2_list),
660 };
661
662 static struct clksrc_clk clksrcs[] = {
663         {
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         }, {
680                 .clk    = {
681                         .name           = "uclk1",
682                         .id             = 0,
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 },
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 },
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 },
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 },
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 },
913         },
914 };
915
916 /* Clock initialisation code */
917 static struct clksrc_clk *sysclks[] = {
918         &clk_mout_apll,
919         &clk_mout_epll,
920         &clk_mout_mpll,
921         &clk_armclk,
922         &clk_hclk_msys,
923         &clk_sclk_a2m,
924         &clk_hclk_dsys,
925         &clk_hclk_psys,
926         &clk_pclk_msys,
927         &clk_pclk_dsys,
928         &clk_pclk_psys,
929         &clk_vpllsrc,
930         &clk_sclk_vpll,
931         &clk_sclk_dac,
932         &clk_sclk_pixel,
933         &clk_sclk_hdmi,
934 };
935
936 void __init_or_cpufreq s5pv210_setup_clocks(void)
937 {
938         struct clk *xtal_clk;
939         unsigned long xtal;
940         unsigned long vpllsrc;
941         unsigned long armclk;
942         unsigned long hclk_msys;
943         unsigned long hclk_dsys;
944         unsigned long hclk_psys;
945         unsigned long pclk_msys;
946         unsigned long pclk_dsys;
947         unsigned long pclk_psys;
948         unsigned long apll;
949         unsigned long mpll;
950         unsigned long epll;
951         unsigned long vpll;
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);
974         vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
975         vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
976
977         clk_fout_apll.rate = apll;
978         clk_fout_mpll.rate = mpll;
979         clk_fout_epll.rate = epll;
980         clk_fout_vpll.rate = vpll;
981
982         printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
983                         apll, mpll, epll, vpll);
984
985         armclk = clk_get_rate(&clk_armclk.clk);
986         hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
987         hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk);
988         hclk_psys = clk_get_rate(&clk_hclk_psys.clk);
989         pclk_msys = clk_get_rate(&clk_pclk_msys.clk);
990         pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk);
991         pclk_psys = clk_get_rate(&clk_pclk_psys.clk);
992
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,
996                         pclk_msys, pclk_dsys, pclk_psys);
997
998         clk_f.rate = armclk;
999         clk_h.rate = hclk_psys;
1000         clk_p.rate = pclk_psys;
1001
1002         for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1003                 s3c_set_clksrc(&clksrcs[ptr], true);
1004 }
1005
1006 static struct clk *clks[] __initdata = {
1007         &clk_sclk_hdmi27m,
1008         &clk_sclk_hdmiphy,
1009         &clk_sclk_usbphy0,
1010         &clk_sclk_usbphy1,
1011         &clk_pcmcdclk0,
1012         &clk_pcmcdclk1,
1013         &clk_pcmcdclk2,
1014 };
1015
1016 void __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
1026         for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1027                 s3c_register_clksrc(sysclks[ptr], 1);
1028
1029         s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1030         s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1031
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 }