ARM: S5PV310: Add video clocks
[cascardo/linux.git] / arch / arm / mach-s5pv310 / clock.c
1 /* linux/arch/arm/mach-s5pv310/clock.c
2  *
3  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com/
5  *
6  * S5PV310 - 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/kernel.h>
14 #include <linux/err.h>
15 #include <linux/io.h>
16
17 #include <plat/cpu-freq.h>
18 #include <plat/clock.h>
19 #include <plat/cpu.h>
20 #include <plat/pll.h>
21 #include <plat/s5p-clock.h>
22 #include <plat/clock-clksrc.h>
23
24 #include <mach/map.h>
25 #include <mach/regs-clock.h>
26
27 static struct clk clk_sclk_hdmi27m = {
28         .name           = "sclk_hdmi27m",
29         .id             = -1,
30         .rate           = 27000000,
31 };
32
33 static struct clk clk_sclk_hdmiphy = {
34         .name           = "sclk_hdmiphy",
35         .id             = -1,
36 };
37
38 static struct clk clk_sclk_usbphy0 = {
39         .name           = "sclk_usbphy0",
40         .id             = -1,
41         .rate           = 27000000,
42 };
43
44 static struct clk clk_sclk_usbphy1 = {
45         .name           = "sclk_usbphy1",
46         .id             = -1,
47 };
48
49 static int s5pv310_clksrc_mask_top_ctrl(struct clk *clk, int enable)
50 {
51         return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
52 }
53
54 static int s5pv310_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
55 {
56         return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
57 }
58
59 static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
60 {
61         return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
62 }
63
64 static int s5pv310_clk_ip_cam_ctrl(struct clk *clk, int enable)
65 {
66         return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
67 }
68
69 static int s5pv310_clk_ip_image_ctrl(struct clk *clk, int enable)
70 {
71         return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
72 }
73
74 static int s5pv310_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
75 {
76         return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
77 }
78
79 static int s5pv310_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
80 {
81         return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
82 }
83
84 static int s5pv310_clk_ip_fsys_ctrl(struct clk *clk, int enable)
85 {
86         return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
87 }
88
89 static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable)
90 {
91         return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
92 }
93
94 static int s5pv310_clk_ip_perir_ctrl(struct clk *clk, int enable)
95 {
96         return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
97 }
98
99 /* Core list of CMU_CPU side */
100
101 static struct clksrc_clk clk_mout_apll = {
102         .clk    = {
103                 .name           = "mout_apll",
104                 .id             = -1,
105         },
106         .sources        = &clk_src_apll,
107         .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
108 };
109
110 static struct clksrc_clk clk_sclk_apll = {
111         .clk    = {
112                 .name           = "sclk_apll",
113                 .id             = -1,
114                 .parent         = &clk_mout_apll.clk,
115         },
116         .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
117 };
118
119 static struct clksrc_clk clk_mout_epll = {
120         .clk    = {
121                 .name           = "mout_epll",
122                 .id             = -1,
123         },
124         .sources        = &clk_src_epll,
125         .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
126 };
127
128 static struct clksrc_clk clk_mout_mpll = {
129         .clk = {
130                 .name           = "mout_mpll",
131                 .id             = -1,
132         },
133         .sources        = &clk_src_mpll,
134         .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 8, .size = 1 },
135 };
136
137 static struct clk *clkset_moutcore_list[] = {
138         [0] = &clk_sclk_apll.clk,
139         [1] = &clk_mout_mpll.clk,
140 };
141
142 static struct clksrc_sources clkset_moutcore = {
143         .sources        = clkset_moutcore_list,
144         .nr_sources     = ARRAY_SIZE(clkset_moutcore_list),
145 };
146
147 static struct clksrc_clk clk_moutcore = {
148         .clk    = {
149                 .name           = "moutcore",
150                 .id             = -1,
151         },
152         .sources        = &clkset_moutcore,
153         .reg_src        = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
154 };
155
156 static struct clksrc_clk clk_coreclk = {
157         .clk    = {
158                 .name           = "core_clk",
159                 .id             = -1,
160                 .parent         = &clk_moutcore.clk,
161         },
162         .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
163 };
164
165 static struct clksrc_clk clk_armclk = {
166         .clk    = {
167                 .name           = "armclk",
168                 .id             = -1,
169                 .parent         = &clk_coreclk.clk,
170         },
171 };
172
173 static struct clksrc_clk clk_aclk_corem0 = {
174         .clk    = {
175                 .name           = "aclk_corem0",
176                 .id             = -1,
177                 .parent         = &clk_coreclk.clk,
178         },
179         .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
180 };
181
182 static struct clksrc_clk clk_aclk_cores = {
183         .clk    = {
184                 .name           = "aclk_cores",
185                 .id             = -1,
186                 .parent         = &clk_coreclk.clk,
187         },
188         .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
189 };
190
191 static struct clksrc_clk clk_aclk_corem1 = {
192         .clk    = {
193                 .name           = "aclk_corem1",
194                 .id             = -1,
195                 .parent         = &clk_coreclk.clk,
196         },
197         .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
198 };
199
200 static struct clksrc_clk clk_periphclk = {
201         .clk    = {
202                 .name           = "periphclk",
203                 .id             = -1,
204                 .parent         = &clk_coreclk.clk,
205         },
206         .reg_div        = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
207 };
208
209 /* Core list of CMU_CORE side */
210
211 static struct clk *clkset_corebus_list[] = {
212         [0] = &clk_mout_mpll.clk,
213         [1] = &clk_sclk_apll.clk,
214 };
215
216 static struct clksrc_sources clkset_mout_corebus = {
217         .sources        = clkset_corebus_list,
218         .nr_sources     = ARRAY_SIZE(clkset_corebus_list),
219 };
220
221 static struct clksrc_clk clk_mout_corebus = {
222         .clk    = {
223                 .name           = "mout_corebus",
224                 .id             = -1,
225         },
226         .sources        = &clkset_mout_corebus,
227         .reg_src        = { .reg = S5P_CLKSRC_CORE, .shift = 4, .size = 1 },
228 };
229
230 static struct clksrc_clk clk_sclk_dmc = {
231         .clk    = {
232                 .name           = "sclk_dmc",
233                 .id             = -1,
234                 .parent         = &clk_mout_corebus.clk,
235         },
236         .reg_div        = { .reg = S5P_CLKDIV_CORE0, .shift = 12, .size = 3 },
237 };
238
239 static struct clksrc_clk clk_aclk_cored = {
240         .clk    = {
241                 .name           = "aclk_cored",
242                 .id             = -1,
243                 .parent         = &clk_sclk_dmc.clk,
244         },
245         .reg_div        = { .reg = S5P_CLKDIV_CORE0, .shift = 16, .size = 3 },
246 };
247
248 static struct clksrc_clk clk_aclk_corep = {
249         .clk    = {
250                 .name           = "aclk_corep",
251                 .id             = -1,
252                 .parent         = &clk_aclk_cored.clk,
253         },
254         .reg_div        = { .reg = S5P_CLKDIV_CORE0, .shift = 20, .size = 3 },
255 };
256
257 static struct clksrc_clk clk_aclk_acp = {
258         .clk    = {
259                 .name           = "aclk_acp",
260                 .id             = -1,
261                 .parent         = &clk_mout_corebus.clk,
262         },
263         .reg_div        = { .reg = S5P_CLKDIV_CORE0, .shift = 0, .size = 3 },
264 };
265
266 static struct clksrc_clk clk_pclk_acp = {
267         .clk    = {
268                 .name           = "pclk_acp",
269                 .id             = -1,
270                 .parent         = &clk_aclk_acp.clk,
271         },
272         .reg_div        = { .reg = S5P_CLKDIV_CORE0, .shift = 4, .size = 3 },
273 };
274
275 /* Core list of CMU_TOP side */
276
277 static struct clk *clkset_aclk_top_list[] = {
278         [0] = &clk_mout_mpll.clk,
279         [1] = &clk_sclk_apll.clk,
280 };
281
282 static struct clksrc_sources clkset_aclk = {
283         .sources        = clkset_aclk_top_list,
284         .nr_sources     = ARRAY_SIZE(clkset_aclk_top_list),
285 };
286
287 static struct clksrc_clk clk_aclk_200 = {
288         .clk    = {
289                 .name           = "aclk_200",
290                 .id             = -1,
291         },
292         .sources        = &clkset_aclk,
293         .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
294         .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
295 };
296
297 static struct clksrc_clk clk_aclk_100 = {
298         .clk    = {
299                 .name           = "aclk_100",
300                 .id             = -1,
301         },
302         .sources        = &clkset_aclk,
303         .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
304         .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
305 };
306
307 static struct clksrc_clk clk_aclk_160 = {
308         .clk    = {
309                 .name           = "aclk_160",
310                 .id             = -1,
311         },
312         .sources        = &clkset_aclk,
313         .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
314         .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
315 };
316
317 static struct clksrc_clk clk_aclk_133 = {
318         .clk    = {
319                 .name           = "aclk_133",
320                 .id             = -1,
321         },
322         .sources        = &clkset_aclk,
323         .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
324         .reg_div        = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
325 };
326
327 static struct clk *clkset_vpllsrc_list[] = {
328         [0] = &clk_fin_vpll,
329         [1] = &clk_sclk_hdmi27m,
330 };
331
332 static struct clksrc_sources clkset_vpllsrc = {
333         .sources        = clkset_vpllsrc_list,
334         .nr_sources     = ARRAY_SIZE(clkset_vpllsrc_list),
335 };
336
337 static struct clksrc_clk clk_vpllsrc = {
338         .clk    = {
339                 .name           = "vpll_src",
340                 .id             = -1,
341                 .enable         = s5pv310_clksrc_mask_top_ctrl,
342                 .ctrlbit        = (1 << 0),
343         },
344         .sources        = &clkset_vpllsrc,
345         .reg_src        = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
346 };
347
348 static struct clk *clkset_sclk_vpll_list[] = {
349         [0] = &clk_vpllsrc.clk,
350         [1] = &clk_fout_vpll,
351 };
352
353 static struct clksrc_sources clkset_sclk_vpll = {
354         .sources        = clkset_sclk_vpll_list,
355         .nr_sources     = ARRAY_SIZE(clkset_sclk_vpll_list),
356 };
357
358 static struct clksrc_clk clk_sclk_vpll = {
359         .clk    = {
360                 .name           = "sclk_vpll",
361                 .id             = -1,
362         },
363         .sources        = &clkset_sclk_vpll,
364         .reg_src        = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
365 };
366
367 static struct clk init_clocks_disable[] = {
368         {
369                 .name           = "timers",
370                 .id             = -1,
371                 .parent         = &clk_aclk_100.clk,
372                 .enable         = s5pv310_clk_ip_peril_ctrl,
373                 .ctrlbit        = (1<<24),
374         }, {
375                 .name           = "csis",
376                 .id             = 0,
377                 .enable         = s5pv310_clk_ip_cam_ctrl,
378                 .ctrlbit        = (1 << 4),
379         }, {
380                 .name           = "csis",
381                 .id             = 1,
382                 .enable         = s5pv310_clk_ip_cam_ctrl,
383                 .ctrlbit        = (1 << 5),
384         }, {
385                 .name           = "fimc",
386                 .id             = 0,
387                 .enable         = s5pv310_clk_ip_cam_ctrl,
388                 .ctrlbit        = (1 << 0),
389         }, {
390                 .name           = "fimc",
391                 .id             = 1,
392                 .enable         = s5pv310_clk_ip_cam_ctrl,
393                 .ctrlbit        = (1 << 1),
394         }, {
395                 .name           = "fimc",
396                 .id             = 2,
397                 .enable         = s5pv310_clk_ip_cam_ctrl,
398                 .ctrlbit        = (1 << 2),
399         }, {
400                 .name           = "fimc",
401                 .id             = 3,
402                 .enable         = s5pv310_clk_ip_cam_ctrl,
403                 .ctrlbit        = (1 << 3),
404         }, {
405                 .name           = "fimd",
406                 .id             = 0,
407                 .enable         = s5pv310_clk_ip_lcd0_ctrl,
408                 .ctrlbit        = (1 << 0),
409         }, {
410                 .name           = "fimd",
411                 .id             = 1,
412                 .enable         = s5pv310_clk_ip_lcd1_ctrl,
413                 .ctrlbit        = (1 << 0),
414         }, {
415                 .name           = "hsmmc",
416                 .id             = 0,
417                 .parent         = &clk_aclk_133.clk,
418                 .enable         = s5pv310_clk_ip_fsys_ctrl,
419                 .ctrlbit        = (1 << 5),
420         }, {
421                 .name           = "hsmmc",
422                 .id             = 1,
423                 .parent         = &clk_aclk_133.clk,
424                 .enable         = s5pv310_clk_ip_fsys_ctrl,
425                 .ctrlbit        = (1 << 6),
426         }, {
427                 .name           = "hsmmc",
428                 .id             = 2,
429                 .parent         = &clk_aclk_133.clk,
430                 .enable         = s5pv310_clk_ip_fsys_ctrl,
431                 .ctrlbit        = (1 << 7),
432         }, {
433                 .name           = "hsmmc",
434                 .id             = 3,
435                 .parent         = &clk_aclk_133.clk,
436                 .enable         = s5pv310_clk_ip_fsys_ctrl,
437                 .ctrlbit        = (1 << 8),
438         }, {
439                 .name           = "hsmmc",
440                 .id             = 4,
441                 .parent         = &clk_aclk_133.clk,
442                 .enable         = s5pv310_clk_ip_fsys_ctrl,
443                 .ctrlbit        = (1 << 9),
444         }, {
445                 .name           = "sata",
446                 .id             = -1,
447                 .enable         = s5pv310_clk_ip_fsys_ctrl,
448                 .ctrlbit        = (1 << 10),
449         }, {
450                 .name           = "adc",
451                 .id             = -1,
452                 .enable         = s5pv310_clk_ip_peril_ctrl,
453                 .ctrlbit        = (1 << 15),
454         }, {
455                 .name           = "watchdog",
456                 .id             = -1,
457                 .enable         = s5pv310_clk_ip_perir_ctrl,
458                 .ctrlbit        = (1 << 14),
459         }, {
460                 .name           = "usbhost",
461                 .id             = -1,
462                 .enable         = s5pv310_clk_ip_fsys_ctrl ,
463                 .ctrlbit        = (1 << 12),
464         }, {
465                 .name           = "otg",
466                 .id             = -1,
467                 .enable         = s5pv310_clk_ip_fsys_ctrl,
468                 .ctrlbit        = (1 << 13),
469         }, {
470                 .name           = "spi",
471                 .id             = 0,
472                 .enable         = s5pv310_clk_ip_peril_ctrl,
473                 .ctrlbit        = (1 << 16),
474         }, {
475                 .name           = "spi",
476                 .id             = 1,
477                 .enable         = s5pv310_clk_ip_peril_ctrl,
478                 .ctrlbit        = (1 << 17),
479         }, {
480                 .name           = "spi",
481                 .id             = 2,
482                 .enable         = s5pv310_clk_ip_peril_ctrl,
483                 .ctrlbit        = (1 << 18),
484         }, {
485                 .name           = "fimg2d",
486                 .id             = -1,
487                 .enable         = s5pv310_clk_ip_image_ctrl,
488                 .ctrlbit        = (1 << 0),
489         }, {
490                 .name           = "i2c",
491                 .id             = 0,
492                 .parent         = &clk_aclk_100.clk,
493                 .enable         = s5pv310_clk_ip_peril_ctrl,
494                 .ctrlbit        = (1 << 6),
495         }, {
496                 .name           = "i2c",
497                 .id             = 1,
498                 .parent         = &clk_aclk_100.clk,
499                 .enable         = s5pv310_clk_ip_peril_ctrl,
500                 .ctrlbit        = (1 << 7),
501         }, {
502                 .name           = "i2c",
503                 .id             = 2,
504                 .parent         = &clk_aclk_100.clk,
505                 .enable         = s5pv310_clk_ip_peril_ctrl,
506                 .ctrlbit        = (1 << 8),
507         }, {
508                 .name           = "i2c",
509                 .id             = 3,
510                 .parent         = &clk_aclk_100.clk,
511                 .enable         = s5pv310_clk_ip_peril_ctrl,
512                 .ctrlbit        = (1 << 9),
513         }, {
514                 .name           = "i2c",
515                 .id             = 4,
516                 .parent         = &clk_aclk_100.clk,
517                 .enable         = s5pv310_clk_ip_peril_ctrl,
518                 .ctrlbit        = (1 << 10),
519         }, {
520                 .name           = "i2c",
521                 .id             = 5,
522                 .parent         = &clk_aclk_100.clk,
523                 .enable         = s5pv310_clk_ip_peril_ctrl,
524                 .ctrlbit        = (1 << 11),
525         }, {
526                 .name           = "i2c",
527                 .id             = 6,
528                 .parent         = &clk_aclk_100.clk,
529                 .enable         = s5pv310_clk_ip_peril_ctrl,
530                 .ctrlbit        = (1 << 12),
531         }, {
532                 .name           = "i2c",
533                 .id             = 7,
534                 .parent         = &clk_aclk_100.clk,
535                 .enable         = s5pv310_clk_ip_peril_ctrl,
536                 .ctrlbit        = (1 << 13),
537         },
538 };
539
540 static struct clk init_clocks[] = {
541         {
542                 .name           = "uart",
543                 .id             = 0,
544                 .enable         = s5pv310_clk_ip_peril_ctrl,
545                 .ctrlbit        = (1 << 0),
546         }, {
547                 .name           = "uart",
548                 .id             = 1,
549                 .enable         = s5pv310_clk_ip_peril_ctrl,
550                 .ctrlbit        = (1 << 1),
551         }, {
552                 .name           = "uart",
553                 .id             = 2,
554                 .enable         = s5pv310_clk_ip_peril_ctrl,
555                 .ctrlbit        = (1 << 2),
556         }, {
557                 .name           = "uart",
558                 .id             = 3,
559                 .enable         = s5pv310_clk_ip_peril_ctrl,
560                 .ctrlbit        = (1 << 3),
561         }, {
562                 .name           = "uart",
563                 .id             = 4,
564                 .enable         = s5pv310_clk_ip_peril_ctrl,
565                 .ctrlbit        = (1 << 4),
566         }, {
567                 .name           = "uart",
568                 .id             = 5,
569                 .enable         = s5pv310_clk_ip_peril_ctrl,
570                 .ctrlbit        = (1 << 5),
571         }
572 };
573
574 static struct clk *clkset_group_list[] = {
575         [0] = &clk_ext_xtal_mux,
576         [1] = &clk_xusbxti,
577         [2] = &clk_sclk_hdmi27m,
578         [3] = &clk_sclk_usbphy0,
579         [4] = &clk_sclk_usbphy1,
580         [5] = &clk_sclk_hdmiphy,
581         [6] = &clk_mout_mpll.clk,
582         [7] = &clk_mout_epll.clk,
583         [8] = &clk_sclk_vpll.clk,
584 };
585
586 static struct clksrc_sources clkset_group = {
587         .sources        = clkset_group_list,
588         .nr_sources     = ARRAY_SIZE(clkset_group_list),
589 };
590
591 static struct clk *clkset_mout_g2d0_list[] = {
592         [0] = &clk_mout_mpll.clk,
593         [1] = &clk_sclk_apll.clk,
594 };
595
596 static struct clksrc_sources clkset_mout_g2d0 = {
597         .sources        = clkset_mout_g2d0_list,
598         .nr_sources     = ARRAY_SIZE(clkset_mout_g2d0_list),
599 };
600
601 static struct clksrc_clk clk_mout_g2d0 = {
602         .clk    = {
603                 .name           = "mout_g2d0",
604                 .id             = -1,
605         },
606         .sources        = &clkset_mout_g2d0,
607         .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
608 };
609
610 static struct clk *clkset_mout_g2d1_list[] = {
611         [0] = &clk_mout_epll.clk,
612         [1] = &clk_sclk_vpll.clk,
613 };
614
615 static struct clksrc_sources clkset_mout_g2d1 = {
616         .sources        = clkset_mout_g2d1_list,
617         .nr_sources     = ARRAY_SIZE(clkset_mout_g2d1_list),
618 };
619
620 static struct clksrc_clk clk_mout_g2d1 = {
621         .clk    = {
622                 .name           = "mout_g2d1",
623                 .id             = -1,
624         },
625         .sources        = &clkset_mout_g2d1,
626         .reg_src        = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
627 };
628
629 static struct clk *clkset_mout_g2d_list[] = {
630         [0] = &clk_mout_g2d0.clk,
631         [1] = &clk_mout_g2d1.clk,
632 };
633
634 static struct clksrc_sources clkset_mout_g2d = {
635         .sources        = clkset_mout_g2d_list,
636         .nr_sources     = ARRAY_SIZE(clkset_mout_g2d_list),
637 };
638
639 static struct clksrc_clk clk_dout_mmc0 = {
640         .clk            = {
641                 .name           = "dout_mmc0",
642                 .id             = -1,
643         },
644         .sources = &clkset_group,
645         .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
646         .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
647 };
648
649 static struct clksrc_clk clk_dout_mmc1 = {
650         .clk            = {
651                 .name           = "dout_mmc1",
652                 .id             = -1,
653         },
654         .sources = &clkset_group,
655         .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
656         .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
657 };
658
659 static struct clksrc_clk clk_dout_mmc2 = {
660         .clk            = {
661                 .name           = "dout_mmc2",
662                 .id             = -1,
663         },
664         .sources = &clkset_group,
665         .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
666         .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
667 };
668
669 static struct clksrc_clk clk_dout_mmc3 = {
670         .clk            = {
671                 .name           = "dout_mmc3",
672                 .id             = -1,
673         },
674         .sources = &clkset_group,
675         .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
676         .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
677 };
678
679 static struct clksrc_clk clk_dout_mmc4 = {
680         .clk            = {
681                 .name           = "dout_mmc4",
682                 .id             = -1,
683         },
684         .sources = &clkset_group,
685         .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
686         .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
687 };
688
689 static struct clksrc_clk clksrcs[] = {
690         {
691                 .clk    = {
692                         .name           = "uclk1",
693                         .id             = 0,
694                         .enable         = s5pv310_clksrc_mask_peril0_ctrl,
695                         .ctrlbit        = (1 << 0),
696                 },
697                 .sources = &clkset_group,
698                 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
699                 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
700         }, {
701                 .clk            = {
702                         .name           = "uclk1",
703                         .id             = 1,
704                         .enable         = s5pv310_clksrc_mask_peril0_ctrl,
705                         .ctrlbit        = (1 << 4),
706                 },
707                 .sources = &clkset_group,
708                 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
709                 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
710         }, {
711                 .clk            = {
712                         .name           = "uclk1",
713                         .id             = 2,
714                         .enable         = s5pv310_clksrc_mask_peril0_ctrl,
715                         .ctrlbit        = (1 << 8),
716                 },
717                 .sources = &clkset_group,
718                 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
719                 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
720         }, {
721                 .clk            = {
722                         .name           = "uclk1",
723                         .id             = 3,
724                         .enable         = s5pv310_clksrc_mask_peril0_ctrl,
725                         .ctrlbit        = (1 << 12),
726                 },
727                 .sources = &clkset_group,
728                 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
729                 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
730         }, {
731                 .clk            = {
732                         .name           = "sclk_pwm",
733                         .id             = -1,
734                         .enable         = s5pv310_clksrc_mask_peril0_ctrl,
735                         .ctrlbit        = (1 << 24),
736                 },
737                 .sources = &clkset_group,
738                 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
739                 .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
740         }, {
741                 .clk            = {
742                         .name           = "sclk_mmc",
743                         .id             = 0,
744                         .parent         = &clk_dout_mmc0.clk,
745                         .enable         = s5pv310_clksrc_mask_fsys_ctrl,
746                         .ctrlbit        = (1 << 0),
747                 },
748                 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
749         }, {
750                 .clk            = {
751                         .name           = "sclk_mmc",
752                         .id             = 1,
753                         .parent         = &clk_dout_mmc1.clk,
754                         .enable         = s5pv310_clksrc_mask_fsys_ctrl,
755                         .ctrlbit        = (1 << 4),
756                 },
757                 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
758         }, {
759                 .clk            = {
760                         .name           = "sclk_mmc",
761                         .id             = 2,
762                         .parent         = &clk_dout_mmc2.clk,
763                         .enable         = s5pv310_clksrc_mask_fsys_ctrl,
764                         .ctrlbit        = (1 << 8),
765                 },
766                 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
767         }, {
768                 .clk            = {
769                         .name           = "sclk_mmc",
770                         .id             = 3,
771                         .parent         = &clk_dout_mmc3.clk,
772                         .enable         = s5pv310_clksrc_mask_fsys_ctrl,
773                         .ctrlbit        = (1 << 12),
774                 },
775                 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
776         }, {
777                 .clk            = {
778                         .name           = "sclk_mmc",
779                         .id             = 4,
780                         .parent         = &clk_dout_mmc4.clk,
781                         .enable         = s5pv310_clksrc_mask_fsys_ctrl,
782                         .ctrlbit        = (1 << 16),
783                 },
784                 .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
785         }
786 };
787
788 /* Clock initialization code */
789 static struct clksrc_clk *sysclks[] = {
790         &clk_mout_apll,
791         &clk_sclk_apll,
792         &clk_mout_epll,
793         &clk_mout_mpll,
794         &clk_moutcore,
795         &clk_coreclk,
796         &clk_armclk,
797         &clk_aclk_corem0,
798         &clk_aclk_cores,
799         &clk_aclk_corem1,
800         &clk_periphclk,
801         &clk_mout_corebus,
802         &clk_sclk_dmc,
803         &clk_aclk_cored,
804         &clk_aclk_corep,
805         &clk_aclk_acp,
806         &clk_pclk_acp,
807         &clk_vpllsrc,
808         &clk_sclk_vpll,
809         &clk_aclk_200,
810         &clk_aclk_100,
811         &clk_aclk_160,
812         &clk_aclk_133,
813         &clk_dout_mmc0,
814         &clk_dout_mmc1,
815         &clk_dout_mmc2,
816         &clk_dout_mmc3,
817         &clk_dout_mmc4,
818 };
819
820 void __init_or_cpufreq s5pv310_setup_clocks(void)
821 {
822         struct clk *xtal_clk;
823         unsigned long apll;
824         unsigned long mpll;
825         unsigned long epll;
826         unsigned long vpll;
827         unsigned long vpllsrc;
828         unsigned long xtal;
829         unsigned long armclk;
830         unsigned long sclk_dmc;
831         unsigned long aclk_200;
832         unsigned long aclk_100;
833         unsigned long aclk_160;
834         unsigned long aclk_133;
835         unsigned int ptr;
836
837         printk(KERN_DEBUG "%s: registering clocks\n", __func__);
838
839         xtal_clk = clk_get(NULL, "xtal");
840         BUG_ON(IS_ERR(xtal_clk));
841
842         xtal = clk_get_rate(xtal_clk);
843         clk_put(xtal_clk);
844
845         printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
846
847         apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508);
848         mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508);
849         epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
850                                 __raw_readl(S5P_EPLL_CON1), pll_4600);
851
852         vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
853         vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
854                                 __raw_readl(S5P_VPLL_CON1), pll_4650);
855
856         clk_fout_apll.rate = apll;
857         clk_fout_mpll.rate = mpll;
858         clk_fout_epll.rate = epll;
859         clk_fout_vpll.rate = vpll;
860
861         printk(KERN_INFO "S5PV310: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
862                         apll, mpll, epll, vpll);
863
864         armclk = clk_get_rate(&clk_armclk.clk);
865         sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
866
867         aclk_200 = clk_get_rate(&clk_aclk_200.clk);
868         aclk_100 = clk_get_rate(&clk_aclk_100.clk);
869         aclk_160 = clk_get_rate(&clk_aclk_160.clk);
870         aclk_133 = clk_get_rate(&clk_aclk_133.clk);
871
872         printk(KERN_INFO "S5PV310: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
873                          "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
874                         armclk, sclk_dmc, aclk_200,
875                         aclk_100, aclk_160, aclk_133);
876
877         clk_f.rate = armclk;
878         clk_h.rate = sclk_dmc;
879         clk_p.rate = aclk_100;
880
881         for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
882                 s3c_set_clksrc(&clksrcs[ptr], true);
883 }
884
885 static struct clk *clks[] __initdata = {
886         /* Nothing here yet */
887 };
888
889 void __init s5pv310_register_clocks(void)
890 {
891         struct clk *clkp;
892         int ret;
893         int ptr;
894
895         ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
896         if (ret > 0)
897                 printk(KERN_ERR "Failed to register %u clocks\n", ret);
898
899         for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
900                 s3c_register_clksrc(sysclks[ptr], 1);
901
902         s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
903         s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
904
905         clkp = init_clocks_disable;
906         for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
907                 ret = s3c24xx_register_clock(clkp);
908                 if (ret < 0) {
909                         printk(KERN_ERR "Failed to register clock %s (%d)\n",
910                                clkp->name, ret);
911                 }
912                 (clkp->enable)(clkp, 0);
913         }
914
915         s3c_pwmclk_init();
916 }