Merge branch 'dev' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
[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 unsigned long xtal;
35
36 static struct clksrc_clk clk_mout_apll = {
37         .clk    = {
38                 .name           = "mout_apll",
39         },
40         .sources        = &clk_src_apll,
41         .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
42 };
43
44 static struct clksrc_clk clk_mout_epll = {
45         .clk    = {
46                 .name           = "mout_epll",
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         },
56         .sources        = &clk_src_mpll,
57         .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
58 };
59
60 static struct clk *clkset_armclk_list[] = {
61         [0] = &clk_mout_apll.clk,
62         [1] = &clk_mout_mpll.clk,
63 };
64
65 static struct clksrc_sources clkset_armclk = {
66         .sources        = clkset_armclk_list,
67         .nr_sources     = ARRAY_SIZE(clkset_armclk_list),
68 };
69
70 static struct clksrc_clk clk_armclk = {
71         .clk    = {
72                 .name           = "armclk",
73         },
74         .sources        = &clkset_armclk,
75         .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
76         .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
77 };
78
79 static struct clksrc_clk clk_hclk_msys = {
80         .clk    = {
81                 .name           = "hclk_msys",
82                 .parent         = &clk_armclk.clk,
83         },
84         .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
85 };
86
87 static struct clksrc_clk clk_pclk_msys = {
88         .clk    = {
89                 .name           = "pclk_msys",
90                 .parent         = &clk_hclk_msys.clk,
91         },
92         .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
93 };
94
95 static struct clksrc_clk clk_sclk_a2m = {
96         .clk    = {
97                 .name           = "sclk_a2m",
98                 .parent         = &clk_mout_apll.clk,
99         },
100         .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
101 };
102
103 static struct clk *clkset_hclk_sys_list[] = {
104         [0] = &clk_mout_mpll.clk,
105         [1] = &clk_sclk_a2m.clk,
106 };
107
108 static struct clksrc_sources clkset_hclk_sys = {
109         .sources        = clkset_hclk_sys_list,
110         .nr_sources     = ARRAY_SIZE(clkset_hclk_sys_list),
111 };
112
113 static struct clksrc_clk clk_hclk_dsys = {
114         .clk    = {
115                 .name   = "hclk_dsys",
116         },
117         .sources        = &clkset_hclk_sys,
118         .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
119         .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
120 };
121
122 static struct clksrc_clk clk_pclk_dsys = {
123         .clk    = {
124                 .name   = "pclk_dsys",
125                 .parent = &clk_hclk_dsys.clk,
126         },
127         .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
128 };
129
130 static struct clksrc_clk clk_hclk_psys = {
131         .clk    = {
132                 .name   = "hclk_psys",
133         },
134         .sources        = &clkset_hclk_sys,
135         .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
136         .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
137 };
138
139 static struct clksrc_clk clk_pclk_psys = {
140         .clk    = {
141                 .name   = "pclk_psys",
142                 .parent = &clk_hclk_psys.clk,
143         },
144         .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
145 };
146
147 static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
148 {
149         return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
150 }
151
152 static int s5pv210_clk_ip1_ctrl(struct clk *clk, int enable)
153 {
154         return s5p_gatectrl(S5P_CLKGATE_IP1, clk, enable);
155 }
156
157 static int s5pv210_clk_ip2_ctrl(struct clk *clk, int enable)
158 {
159         return s5p_gatectrl(S5P_CLKGATE_IP2, clk, enable);
160 }
161
162 static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
163 {
164         return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
165 }
166
167 static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
168 {
169         return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
170 }
171
172 static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable)
173 {
174         return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable);
175 }
176
177 static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
178 {
179         return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
180 }
181
182 static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
183 {
184         return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
185 }
186
187 static struct clk clk_sclk_hdmi27m = {
188         .name           = "sclk_hdmi27m",
189         .rate           = 27000000,
190 };
191
192 static struct clk clk_sclk_hdmiphy = {
193         .name           = "sclk_hdmiphy",
194 };
195
196 static struct clk clk_sclk_usbphy0 = {
197         .name           = "sclk_usbphy0",
198 };
199
200 static struct clk clk_sclk_usbphy1 = {
201         .name           = "sclk_usbphy1",
202 };
203
204 static struct clk clk_pcmcdclk0 = {
205         .name           = "pcmcdclk",
206 };
207
208 static struct clk clk_pcmcdclk1 = {
209         .name           = "pcmcdclk",
210 };
211
212 static struct clk clk_pcmcdclk2 = {
213         .name           = "pcmcdclk",
214 };
215
216 static struct clk dummy_apb_pclk = {
217         .name           = "apb_pclk",
218         .id             = -1,
219 };
220
221 static struct clk *clkset_vpllsrc_list[] = {
222         [0] = &clk_fin_vpll,
223         [1] = &clk_sclk_hdmi27m,
224 };
225
226 static struct clksrc_sources clkset_vpllsrc = {
227         .sources        = clkset_vpllsrc_list,
228         .nr_sources     = ARRAY_SIZE(clkset_vpllsrc_list),
229 };
230
231 static struct clksrc_clk clk_vpllsrc = {
232         .clk    = {
233                 .name           = "vpll_src",
234                 .enable         = s5pv210_clk_mask0_ctrl,
235                 .ctrlbit        = (1 << 7),
236         },
237         .sources        = &clkset_vpllsrc,
238         .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 28, .size = 1 },
239 };
240
241 static struct clk *clkset_sclk_vpll_list[] = {
242         [0] = &clk_vpllsrc.clk,
243         [1] = &clk_fout_vpll,
244 };
245
246 static struct clksrc_sources clkset_sclk_vpll = {
247         .sources        = clkset_sclk_vpll_list,
248         .nr_sources     = ARRAY_SIZE(clkset_sclk_vpll_list),
249 };
250
251 static struct clksrc_clk clk_sclk_vpll = {
252         .clk    = {
253                 .name           = "sclk_vpll",
254         },
255         .sources        = &clkset_sclk_vpll,
256         .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
257 };
258
259 static struct clk *clkset_moutdmc0src_list[] = {
260         [0] = &clk_sclk_a2m.clk,
261         [1] = &clk_mout_mpll.clk,
262         [2] = NULL,
263         [3] = NULL,
264 };
265
266 static struct clksrc_sources clkset_moutdmc0src = {
267         .sources        = clkset_moutdmc0src_list,
268         .nr_sources     = ARRAY_SIZE(clkset_moutdmc0src_list),
269 };
270
271 static struct clksrc_clk clk_mout_dmc0 = {
272         .clk    = {
273                 .name           = "mout_dmc0",
274         },
275         .sources        = &clkset_moutdmc0src,
276         .reg_src        = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
277 };
278
279 static struct clksrc_clk clk_sclk_dmc0 = {
280         .clk    = {
281                 .name           = "sclk_dmc0",
282                 .parent         = &clk_mout_dmc0.clk,
283         },
284         .reg_div        = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
285 };
286
287 static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
288 {
289         return clk_get_rate(clk->parent) / 2;
290 }
291
292 static struct clk_ops clk_hclk_imem_ops = {
293         .get_rate       = s5pv210_clk_imem_get_rate,
294 };
295
296 static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk)
297 {
298         return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
299 }
300
301 static struct clk_ops clk_fout_apll_ops = {
302         .get_rate       = s5pv210_clk_fout_apll_get_rate,
303 };
304
305 static struct clk init_clocks_off[] = {
306         {
307                 .name           = "dma",
308                 .devname        = "dma-pl330.0",
309                 .parent         = &clk_hclk_psys.clk,
310                 .enable         = s5pv210_clk_ip0_ctrl,
311                 .ctrlbit        = (1 << 3),
312         }, {
313                 .name           = "dma",
314                 .devname        = "dma-pl330.1",
315                 .parent         = &clk_hclk_psys.clk,
316                 .enable         = s5pv210_clk_ip0_ctrl,
317                 .ctrlbit        = (1 << 4),
318         }, {
319                 .name           = "rot",
320                 .parent         = &clk_hclk_dsys.clk,
321                 .enable         = s5pv210_clk_ip0_ctrl,
322                 .ctrlbit        = (1<<29),
323         }, {
324                 .name           = "fimc",
325                 .devname        = "s5pv210-fimc.0",
326                 .parent         = &clk_hclk_dsys.clk,
327                 .enable         = s5pv210_clk_ip0_ctrl,
328                 .ctrlbit        = (1 << 24),
329         }, {
330                 .name           = "fimc",
331                 .devname        = "s5pv210-fimc.1",
332                 .parent         = &clk_hclk_dsys.clk,
333                 .enable         = s5pv210_clk_ip0_ctrl,
334                 .ctrlbit        = (1 << 25),
335         }, {
336                 .name           = "fimc",
337                 .devname        = "s5pv210-fimc.2",
338                 .parent         = &clk_hclk_dsys.clk,
339                 .enable         = s5pv210_clk_ip0_ctrl,
340                 .ctrlbit        = (1 << 26),
341         }, {
342                 .name           = "mfc",
343                 .devname        = "s5p-mfc",
344                 .parent         = &clk_pclk_psys.clk,
345                 .enable         = s5pv210_clk_ip0_ctrl,
346                 .ctrlbit        = (1 << 16),
347         }, {
348                 .name           = "dac",
349                 .devname        = "s5p-sdo",
350                 .parent         = &clk_hclk_dsys.clk,
351                 .enable         = s5pv210_clk_ip1_ctrl,
352                 .ctrlbit        = (1 << 10),
353         }, {
354                 .name           = "mixer",
355                 .devname        = "s5p-mixer",
356                 .parent         = &clk_hclk_dsys.clk,
357                 .enable         = s5pv210_clk_ip1_ctrl,
358                 .ctrlbit        = (1 << 9),
359         }, {
360                 .name           = "vp",
361                 .devname        = "s5p-mixer",
362                 .parent         = &clk_hclk_dsys.clk,
363                 .enable         = s5pv210_clk_ip1_ctrl,
364                 .ctrlbit        = (1 << 8),
365         }, {
366                 .name           = "hdmi",
367                 .devname        = "s5pv210-hdmi",
368                 .parent         = &clk_hclk_dsys.clk,
369                 .enable         = s5pv210_clk_ip1_ctrl,
370                 .ctrlbit        = (1 << 11),
371         }, {
372                 .name           = "hdmiphy",
373                 .devname        = "s5pv210-hdmi",
374                 .enable         = exynos4_clk_hdmiphy_ctrl,
375                 .ctrlbit        = (1 << 0),
376         }, {
377                 .name           = "dacphy",
378                 .devname        = "s5p-sdo",
379                 .enable         = exynos4_clk_dac_ctrl,
380                 .ctrlbit        = (1 << 0),
381         }, {
382                 .name           = "otg",
383                 .parent         = &clk_hclk_psys.clk,
384                 .enable         = s5pv210_clk_ip1_ctrl,
385                 .ctrlbit        = (1<<16),
386         }, {
387                 .name           = "usb-host",
388                 .parent         = &clk_hclk_psys.clk,
389                 .enable         = s5pv210_clk_ip1_ctrl,
390                 .ctrlbit        = (1<<17),
391         }, {
392                 .name           = "lcd",
393                 .parent         = &clk_hclk_dsys.clk,
394                 .enable         = s5pv210_clk_ip1_ctrl,
395                 .ctrlbit        = (1<<0),
396         }, {
397                 .name           = "cfcon",
398                 .parent         = &clk_hclk_psys.clk,
399                 .enable         = s5pv210_clk_ip1_ctrl,
400                 .ctrlbit        = (1<<25),
401         }, {
402                 .name           = "hsmmc",
403                 .devname        = "s3c-sdhci.0",
404                 .parent         = &clk_hclk_psys.clk,
405                 .enable         = s5pv210_clk_ip2_ctrl,
406                 .ctrlbit        = (1<<16),
407         }, {
408                 .name           = "hsmmc",
409                 .devname        = "s3c-sdhci.1",
410                 .parent         = &clk_hclk_psys.clk,
411                 .enable         = s5pv210_clk_ip2_ctrl,
412                 .ctrlbit        = (1<<17),
413         }, {
414                 .name           = "hsmmc",
415                 .devname        = "s3c-sdhci.2",
416                 .parent         = &clk_hclk_psys.clk,
417                 .enable         = s5pv210_clk_ip2_ctrl,
418                 .ctrlbit        = (1<<18),
419         }, {
420                 .name           = "hsmmc",
421                 .devname        = "s3c-sdhci.3",
422                 .parent         = &clk_hclk_psys.clk,
423                 .enable         = s5pv210_clk_ip2_ctrl,
424                 .ctrlbit        = (1<<19),
425         }, {
426                 .name           = "systimer",
427                 .parent         = &clk_pclk_psys.clk,
428                 .enable         = s5pv210_clk_ip3_ctrl,
429                 .ctrlbit        = (1<<16),
430         }, {
431                 .name           = "watchdog",
432                 .parent         = &clk_pclk_psys.clk,
433                 .enable         = s5pv210_clk_ip3_ctrl,
434                 .ctrlbit        = (1<<22),
435         }, {
436                 .name           = "rtc",
437                 .parent         = &clk_pclk_psys.clk,
438                 .enable         = s5pv210_clk_ip3_ctrl,
439                 .ctrlbit        = (1<<15),
440         }, {
441                 .name           = "i2c",
442                 .devname        = "s3c2440-i2c.0",
443                 .parent         = &clk_pclk_psys.clk,
444                 .enable         = s5pv210_clk_ip3_ctrl,
445                 .ctrlbit        = (1<<7),
446         }, {
447                 .name           = "i2c",
448                 .devname        = "s3c2440-i2c.1",
449                 .parent         = &clk_pclk_psys.clk,
450                 .enable         = s5pv210_clk_ip3_ctrl,
451                 .ctrlbit        = (1 << 10),
452         }, {
453                 .name           = "i2c",
454                 .devname        = "s3c2440-i2c.2",
455                 .parent         = &clk_pclk_psys.clk,
456                 .enable         = s5pv210_clk_ip3_ctrl,
457                 .ctrlbit        = (1<<9),
458         }, {
459                 .name           = "i2c",
460                 .devname        = "s3c2440-hdmiphy-i2c",
461                 .parent         = &clk_pclk_psys.clk,
462                 .enable         = s5pv210_clk_ip3_ctrl,
463                 .ctrlbit        = (1 << 11),
464         }, {
465                 .name           = "spi",
466                 .devname        = "s3c64xx-spi.0",
467                 .parent         = &clk_pclk_psys.clk,
468                 .enable         = s5pv210_clk_ip3_ctrl,
469                 .ctrlbit        = (1<<12),
470         }, {
471                 .name           = "spi",
472                 .devname        = "s3c64xx-spi.1",
473                 .parent         = &clk_pclk_psys.clk,
474                 .enable         = s5pv210_clk_ip3_ctrl,
475                 .ctrlbit        = (1<<13),
476         }, {
477                 .name           = "spi",
478                 .devname        = "s3c64xx-spi.2",
479                 .parent         = &clk_pclk_psys.clk,
480                 .enable         = s5pv210_clk_ip3_ctrl,
481                 .ctrlbit        = (1<<14),
482         }, {
483                 .name           = "timers",
484                 .parent         = &clk_pclk_psys.clk,
485                 .enable         = s5pv210_clk_ip3_ctrl,
486                 .ctrlbit        = (1<<23),
487         }, {
488                 .name           = "adc",
489                 .parent         = &clk_pclk_psys.clk,
490                 .enable         = s5pv210_clk_ip3_ctrl,
491                 .ctrlbit        = (1<<24),
492         }, {
493                 .name           = "keypad",
494                 .parent         = &clk_pclk_psys.clk,
495                 .enable         = s5pv210_clk_ip3_ctrl,
496                 .ctrlbit        = (1<<21),
497         }, {
498                 .name           = "iis",
499                 .devname        = "samsung-i2s.0",
500                 .parent         = &clk_p,
501                 .enable         = s5pv210_clk_ip3_ctrl,
502                 .ctrlbit        = (1<<4),
503         }, {
504                 .name           = "iis",
505                 .devname        = "samsung-i2s.1",
506                 .parent         = &clk_p,
507                 .enable         = s5pv210_clk_ip3_ctrl,
508                 .ctrlbit        = (1 << 5),
509         }, {
510                 .name           = "iis",
511                 .devname        = "samsung-i2s.2",
512                 .parent         = &clk_p,
513                 .enable         = s5pv210_clk_ip3_ctrl,
514                 .ctrlbit        = (1 << 6),
515         }, {
516                 .name           = "spdif",
517                 .parent         = &clk_p,
518                 .enable         = s5pv210_clk_ip3_ctrl,
519                 .ctrlbit        = (1 << 0),
520         },
521 };
522
523 static struct clk init_clocks[] = {
524         {
525                 .name           = "hclk_imem",
526                 .parent         = &clk_hclk_msys.clk,
527                 .ctrlbit        = (1 << 5),
528                 .enable         = s5pv210_clk_ip0_ctrl,
529                 .ops            = &clk_hclk_imem_ops,
530         }, {
531                 .name           = "uart",
532                 .devname        = "s5pv210-uart.0",
533                 .parent         = &clk_pclk_psys.clk,
534                 .enable         = s5pv210_clk_ip3_ctrl,
535                 .ctrlbit        = (1 << 17),
536         }, {
537                 .name           = "uart",
538                 .devname        = "s5pv210-uart.1",
539                 .parent         = &clk_pclk_psys.clk,
540                 .enable         = s5pv210_clk_ip3_ctrl,
541                 .ctrlbit        = (1 << 18),
542         }, {
543                 .name           = "uart",
544                 .devname        = "s5pv210-uart.2",
545                 .parent         = &clk_pclk_psys.clk,
546                 .enable         = s5pv210_clk_ip3_ctrl,
547                 .ctrlbit        = (1 << 19),
548         }, {
549                 .name           = "uart",
550                 .devname        = "s5pv210-uart.3",
551                 .parent         = &clk_pclk_psys.clk,
552                 .enable         = s5pv210_clk_ip3_ctrl,
553                 .ctrlbit        = (1 << 20),
554         }, {
555                 .name           = "sromc",
556                 .parent         = &clk_hclk_psys.clk,
557                 .enable         = s5pv210_clk_ip1_ctrl,
558                 .ctrlbit        = (1 << 26),
559         },
560 };
561
562 static struct clk *clkset_uart_list[] = {
563         [6] = &clk_mout_mpll.clk,
564         [7] = &clk_mout_epll.clk,
565 };
566
567 static struct clksrc_sources clkset_uart = {
568         .sources        = clkset_uart_list,
569         .nr_sources     = ARRAY_SIZE(clkset_uart_list),
570 };
571
572 static struct clk *clkset_group1_list[] = {
573         [0] = &clk_sclk_a2m.clk,
574         [1] = &clk_mout_mpll.clk,
575         [2] = &clk_mout_epll.clk,
576         [3] = &clk_sclk_vpll.clk,
577 };
578
579 static struct clksrc_sources clkset_group1 = {
580         .sources        = clkset_group1_list,
581         .nr_sources     = ARRAY_SIZE(clkset_group1_list),
582 };
583
584 static struct clk *clkset_sclk_onenand_list[] = {
585         [0] = &clk_hclk_psys.clk,
586         [1] = &clk_hclk_dsys.clk,
587 };
588
589 static struct clksrc_sources clkset_sclk_onenand = {
590         .sources        = clkset_sclk_onenand_list,
591         .nr_sources     = ARRAY_SIZE(clkset_sclk_onenand_list),
592 };
593
594 static struct clk *clkset_sclk_dac_list[] = {
595         [0] = &clk_sclk_vpll.clk,
596         [1] = &clk_sclk_hdmiphy,
597 };
598
599 static struct clksrc_sources clkset_sclk_dac = {
600         .sources        = clkset_sclk_dac_list,
601         .nr_sources     = ARRAY_SIZE(clkset_sclk_dac_list),
602 };
603
604 static struct clksrc_clk clk_sclk_dac = {
605         .clk            = {
606                 .name           = "sclk_dac",
607                 .enable         = s5pv210_clk_mask0_ctrl,
608                 .ctrlbit        = (1 << 2),
609         },
610         .sources        = &clkset_sclk_dac,
611         .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 },
612 };
613
614 static struct clksrc_clk clk_sclk_pixel = {
615         .clk            = {
616                 .name           = "sclk_pixel",
617                 .parent         = &clk_sclk_vpll.clk,
618         },
619         .reg_div        = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4},
620 };
621
622 static struct clk *clkset_sclk_hdmi_list[] = {
623         [0] = &clk_sclk_pixel.clk,
624         [1] = &clk_sclk_hdmiphy,
625 };
626
627 static struct clksrc_sources clkset_sclk_hdmi = {
628         .sources        = clkset_sclk_hdmi_list,
629         .nr_sources     = ARRAY_SIZE(clkset_sclk_hdmi_list),
630 };
631
632 static struct clksrc_clk clk_sclk_hdmi = {
633         .clk            = {
634                 .name           = "sclk_hdmi",
635                 .enable         = s5pv210_clk_mask0_ctrl,
636                 .ctrlbit        = (1 << 0),
637         },
638         .sources        = &clkset_sclk_hdmi,
639         .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
640 };
641
642 static struct clk *clkset_sclk_mixer_list[] = {
643         [0] = &clk_sclk_dac.clk,
644         [1] = &clk_sclk_hdmi.clk,
645 };
646
647 static struct clksrc_sources clkset_sclk_mixer = {
648         .sources        = clkset_sclk_mixer_list,
649         .nr_sources     = ARRAY_SIZE(clkset_sclk_mixer_list),
650 };
651
652 static struct clksrc_clk clk_sclk_mixer = {
653         .clk            = {
654                 .name           = "sclk_mixer",
655                 .enable         = s5pv210_clk_mask0_ctrl,
656                 .ctrlbit        = (1 << 1),
657         },
658         .sources = &clkset_sclk_mixer,
659         .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
660 };
661
662 static struct clksrc_clk *sclk_tv[] = {
663         &clk_sclk_dac,
664         &clk_sclk_pixel,
665         &clk_sclk_hdmi,
666         &clk_sclk_mixer,
667 };
668
669 static struct clk *clkset_sclk_audio0_list[] = {
670         [0] = &clk_ext_xtal_mux,
671         [1] = &clk_pcmcdclk0,
672         [2] = &clk_sclk_hdmi27m,
673         [3] = &clk_sclk_usbphy0,
674         [4] = &clk_sclk_usbphy1,
675         [5] = &clk_sclk_hdmiphy,
676         [6] = &clk_mout_mpll.clk,
677         [7] = &clk_mout_epll.clk,
678         [8] = &clk_sclk_vpll.clk,
679 };
680
681 static struct clksrc_sources clkset_sclk_audio0 = {
682         .sources        = clkset_sclk_audio0_list,
683         .nr_sources     = ARRAY_SIZE(clkset_sclk_audio0_list),
684 };
685
686 static struct clksrc_clk clk_sclk_audio0 = {
687         .clk            = {
688                 .name           = "sclk_audio",
689                 .devname        = "soc-audio.0",
690                 .enable         = s5pv210_clk_mask0_ctrl,
691                 .ctrlbit        = (1 << 24),
692         },
693         .sources = &clkset_sclk_audio0,
694         .reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 },
695         .reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
696 };
697
698 static struct clk *clkset_sclk_audio1_list[] = {
699         [0] = &clk_ext_xtal_mux,
700         [1] = &clk_pcmcdclk1,
701         [2] = &clk_sclk_hdmi27m,
702         [3] = &clk_sclk_usbphy0,
703         [4] = &clk_sclk_usbphy1,
704         [5] = &clk_sclk_hdmiphy,
705         [6] = &clk_mout_mpll.clk,
706         [7] = &clk_mout_epll.clk,
707         [8] = &clk_sclk_vpll.clk,
708 };
709
710 static struct clksrc_sources clkset_sclk_audio1 = {
711         .sources        = clkset_sclk_audio1_list,
712         .nr_sources     = ARRAY_SIZE(clkset_sclk_audio1_list),
713 };
714
715 static struct clksrc_clk clk_sclk_audio1 = {
716         .clk            = {
717                 .name           = "sclk_audio",
718                 .devname        = "soc-audio.1",
719                 .enable         = s5pv210_clk_mask0_ctrl,
720                 .ctrlbit        = (1 << 25),
721         },
722         .sources = &clkset_sclk_audio1,
723         .reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 },
724         .reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 },
725 };
726
727 static struct clk *clkset_sclk_audio2_list[] = {
728         [0] = &clk_ext_xtal_mux,
729         [1] = &clk_pcmcdclk0,
730         [2] = &clk_sclk_hdmi27m,
731         [3] = &clk_sclk_usbphy0,
732         [4] = &clk_sclk_usbphy1,
733         [5] = &clk_sclk_hdmiphy,
734         [6] = &clk_mout_mpll.clk,
735         [7] = &clk_mout_epll.clk,
736         [8] = &clk_sclk_vpll.clk,
737 };
738
739 static struct clksrc_sources clkset_sclk_audio2 = {
740         .sources        = clkset_sclk_audio2_list,
741         .nr_sources     = ARRAY_SIZE(clkset_sclk_audio2_list),
742 };
743
744 static struct clksrc_clk clk_sclk_audio2 = {
745         .clk            = {
746                 .name           = "sclk_audio",
747                 .devname        = "soc-audio.2",
748                 .enable         = s5pv210_clk_mask0_ctrl,
749                 .ctrlbit        = (1 << 26),
750         },
751         .sources = &clkset_sclk_audio2,
752         .reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 },
753         .reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 },
754 };
755
756 static struct clk *clkset_sclk_spdif_list[] = {
757         [0] = &clk_sclk_audio0.clk,
758         [1] = &clk_sclk_audio1.clk,
759         [2] = &clk_sclk_audio2.clk,
760 };
761
762 static struct clksrc_sources clkset_sclk_spdif = {
763         .sources        = clkset_sclk_spdif_list,
764         .nr_sources     = ARRAY_SIZE(clkset_sclk_spdif_list),
765 };
766
767 static struct clksrc_clk clk_sclk_spdif = {
768         .clk            = {
769                 .name           = "sclk_spdif",
770                 .enable         = s5pv210_clk_mask0_ctrl,
771                 .ctrlbit        = (1 << 27),
772                 .ops            = &s5p_sclk_spdif_ops,
773         },
774         .sources = &clkset_sclk_spdif,
775         .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
776 };
777
778 static struct clk *clkset_group2_list[] = {
779         [0] = &clk_ext_xtal_mux,
780         [1] = &clk_xusbxti,
781         [2] = &clk_sclk_hdmi27m,
782         [3] = &clk_sclk_usbphy0,
783         [4] = &clk_sclk_usbphy1,
784         [5] = &clk_sclk_hdmiphy,
785         [6] = &clk_mout_mpll.clk,
786         [7] = &clk_mout_epll.clk,
787         [8] = &clk_sclk_vpll.clk,
788 };
789
790 static struct clksrc_sources clkset_group2 = {
791         .sources        = clkset_group2_list,
792         .nr_sources     = ARRAY_SIZE(clkset_group2_list),
793 };
794
795 static struct clksrc_clk clksrcs[] = {
796         {
797                 .clk    = {
798                         .name           = "sclk_dmc",
799                 },
800                 .sources = &clkset_group1,
801                 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
802                 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
803         }, {
804                 .clk    = {
805                         .name           = "sclk_onenand",
806                 },
807                 .sources = &clkset_sclk_onenand,
808                 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
809                 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
810         }, {
811                 .clk    = {
812                         .name           = "uclk1",
813                         .devname        = "s5pv210-uart.0",
814                         .enable         = s5pv210_clk_mask0_ctrl,
815                         .ctrlbit        = (1 << 12),
816                 },
817                 .sources = &clkset_uart,
818                 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
819                 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
820         }, {
821                 .clk            = {
822                         .name           = "uclk1",
823                         .devname        = "s5pv210-uart.1",
824                         .enable         = s5pv210_clk_mask0_ctrl,
825                         .ctrlbit        = (1 << 13),
826                 },
827                 .sources = &clkset_uart,
828                 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
829                 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
830         }, {
831                 .clk            = {
832                         .name           = "uclk1",
833                         .devname        = "s5pv210-uart.2",
834                         .enable         = s5pv210_clk_mask0_ctrl,
835                         .ctrlbit        = (1 << 14),
836                 },
837                 .sources = &clkset_uart,
838                 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
839                 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
840         }, {
841                 .clk            = {
842                         .name           = "uclk1",
843                         .devname        = "s5pv210-uart.3",
844                         .enable         = s5pv210_clk_mask0_ctrl,
845                         .ctrlbit        = (1 << 15),
846                 },
847                 .sources = &clkset_uart,
848                 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
849                 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
850         }, {
851                 .clk    = {
852                         .name           = "sclk_fimc",
853                         .devname        = "s5pv210-fimc.0",
854                         .enable         = s5pv210_clk_mask1_ctrl,
855                         .ctrlbit        = (1 << 2),
856                 },
857                 .sources = &clkset_group2,
858                 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 },
859                 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
860         }, {
861                 .clk    = {
862                         .name           = "sclk_fimc",
863                         .devname        = "s5pv210-fimc.1",
864                         .enable         = s5pv210_clk_mask1_ctrl,
865                         .ctrlbit        = (1 << 3),
866                 },
867                 .sources = &clkset_group2,
868                 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 },
869                 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
870         }, {
871                 .clk    = {
872                         .name           = "sclk_fimc",
873                         .devname        = "s5pv210-fimc.2",
874                         .enable         = s5pv210_clk_mask1_ctrl,
875                         .ctrlbit        = (1 << 4),
876                 },
877                 .sources = &clkset_group2,
878                 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 },
879                 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
880         }, {
881                 .clk            = {
882                         .name           = "sclk_cam0",
883                         .enable         = s5pv210_clk_mask0_ctrl,
884                         .ctrlbit        = (1 << 3),
885                 },
886                 .sources = &clkset_group2,
887                 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 },
888                 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
889         }, {
890                 .clk            = {
891                         .name           = "sclk_cam1",
892                         .enable         = s5pv210_clk_mask0_ctrl,
893                         .ctrlbit        = (1 << 4),
894                 },
895                 .sources = &clkset_group2,
896                 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 },
897                 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 },
898         }, {
899                 .clk            = {
900                         .name           = "sclk_fimd",
901                         .enable         = s5pv210_clk_mask0_ctrl,
902                         .ctrlbit        = (1 << 5),
903                 },
904                 .sources = &clkset_group2,
905                 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
906                 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
907         }, {
908                 .clk            = {
909                         .name           = "sclk_mmc",
910                         .devname        = "s3c-sdhci.0",
911                         .enable         = s5pv210_clk_mask0_ctrl,
912                         .ctrlbit        = (1 << 8),
913                 },
914                 .sources = &clkset_group2,
915                 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
916                 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
917         }, {
918                 .clk            = {
919                         .name           = "sclk_mmc",
920                         .devname        = "s3c-sdhci.1",
921                         .enable         = s5pv210_clk_mask0_ctrl,
922                         .ctrlbit        = (1 << 9),
923                 },
924                 .sources = &clkset_group2,
925                 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
926                 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
927         }, {
928                 .clk            = {
929                         .name           = "sclk_mmc",
930                         .devname        = "s3c-sdhci.2",
931                         .enable         = s5pv210_clk_mask0_ctrl,
932                         .ctrlbit        = (1 << 10),
933                 },
934                 .sources = &clkset_group2,
935                 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
936                 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
937         }, {
938                 .clk            = {
939                         .name           = "sclk_mmc",
940                         .devname        = "s3c-sdhci.3",
941                         .enable         = s5pv210_clk_mask0_ctrl,
942                         .ctrlbit        = (1 << 11),
943                 },
944                 .sources = &clkset_group2,
945                 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
946                 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
947         }, {
948                 .clk            = {
949                         .name           = "sclk_mfc",
950                         .devname        = "s5p-mfc",
951                         .enable         = s5pv210_clk_ip0_ctrl,
952                         .ctrlbit        = (1 << 16),
953                 },
954                 .sources = &clkset_group1,
955                 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
956                 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
957         }, {
958                 .clk            = {
959                         .name           = "sclk_g2d",
960                         .enable         = s5pv210_clk_ip0_ctrl,
961                         .ctrlbit        = (1 << 12),
962                 },
963                 .sources = &clkset_group1,
964                 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
965                 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
966         }, {
967                 .clk            = {
968                         .name           = "sclk_g3d",
969                         .enable         = s5pv210_clk_ip0_ctrl,
970                         .ctrlbit        = (1 << 8),
971                 },
972                 .sources = &clkset_group1,
973                 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
974                 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
975         }, {
976                 .clk            = {
977                         .name           = "sclk_csis",
978                         .enable         = s5pv210_clk_mask0_ctrl,
979                         .ctrlbit        = (1 << 6),
980                 },
981                 .sources = &clkset_group2,
982                 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
983                 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
984         }, {
985                 .clk            = {
986                         .name           = "sclk_spi",
987                         .devname        = "s3c64xx-spi.0",
988                         .enable         = s5pv210_clk_mask0_ctrl,
989                         .ctrlbit        = (1 << 16),
990                 },
991                 .sources = &clkset_group2,
992                 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
993                 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
994         }, {
995                 .clk            = {
996                         .name           = "sclk_spi",
997                         .devname        = "s3c64xx-spi.1",
998                         .enable         = s5pv210_clk_mask0_ctrl,
999                         .ctrlbit        = (1 << 17),
1000                 },
1001                 .sources = &clkset_group2,
1002                 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
1003                 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
1004         }, {
1005                 .clk            = {
1006                         .name           = "sclk_pwi",
1007                         .enable         = s5pv210_clk_mask0_ctrl,
1008                         .ctrlbit        = (1 << 29),
1009                 },
1010                 .sources = &clkset_group2,
1011                 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 },
1012                 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 },
1013         }, {
1014                 .clk            = {
1015                         .name           = "sclk_pwm",
1016                         .enable         = s5pv210_clk_mask0_ctrl,
1017                         .ctrlbit        = (1 << 19),
1018                 },
1019                 .sources = &clkset_group2,
1020                 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
1021                 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 },
1022         },
1023 };
1024
1025 /* Clock initialisation code */
1026 static struct clksrc_clk *sysclks[] = {
1027         &clk_mout_apll,
1028         &clk_mout_epll,
1029         &clk_mout_mpll,
1030         &clk_armclk,
1031         &clk_hclk_msys,
1032         &clk_sclk_a2m,
1033         &clk_hclk_dsys,
1034         &clk_hclk_psys,
1035         &clk_pclk_msys,
1036         &clk_pclk_dsys,
1037         &clk_pclk_psys,
1038         &clk_vpllsrc,
1039         &clk_sclk_vpll,
1040         &clk_mout_dmc0,
1041         &clk_sclk_dmc0,
1042         &clk_sclk_audio0,
1043         &clk_sclk_audio1,
1044         &clk_sclk_audio2,
1045         &clk_sclk_spdif,
1046 };
1047
1048 static u32 epll_div[][6] = {
1049         {  48000000, 0, 48, 3, 3, 0 },
1050         {  96000000, 0, 48, 3, 2, 0 },
1051         { 144000000, 1, 72, 3, 2, 0 },
1052         { 192000000, 0, 48, 3, 1, 0 },
1053         { 288000000, 1, 72, 3, 1, 0 },
1054         {  32750000, 1, 65, 3, 4, 35127 },
1055         {  32768000, 1, 65, 3, 4, 35127 },
1056         {  45158400, 0, 45, 3, 3, 10355 },
1057         {  45000000, 0, 45, 3, 3, 10355 },
1058         {  45158000, 0, 45, 3, 3, 10355 },
1059         {  49125000, 0, 49, 3, 3, 9961 },
1060         {  49152000, 0, 49, 3, 3, 9961 },
1061         {  67737600, 1, 67, 3, 3, 48366 },
1062         {  67738000, 1, 67, 3, 3, 48366 },
1063         {  73800000, 1, 73, 3, 3, 47710 },
1064         {  73728000, 1, 73, 3, 3, 47710 },
1065         {  36000000, 1, 32, 3, 4, 0 },
1066         {  60000000, 1, 60, 3, 3, 0 },
1067         {  72000000, 1, 72, 3, 3, 0 },
1068         {  80000000, 1, 80, 3, 3, 0 },
1069         {  84000000, 0, 42, 3, 2, 0 },
1070         {  50000000, 0, 50, 3, 3, 0 },
1071 };
1072
1073 static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
1074 {
1075         unsigned int epll_con, epll_con_k;
1076         unsigned int i;
1077
1078         /* Return if nothing changed */
1079         if (clk->rate == rate)
1080                 return 0;
1081
1082         epll_con = __raw_readl(S5P_EPLL_CON);
1083         epll_con_k = __raw_readl(S5P_EPLL_CON1);
1084
1085         epll_con_k &= ~PLL46XX_KDIV_MASK;
1086         epll_con &= ~(1 << 27 |
1087                         PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
1088                         PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
1089                         PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1090
1091         for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
1092                 if (epll_div[i][0] == rate) {
1093                         epll_con_k |= epll_div[i][5] << 0;
1094                         epll_con |= (epll_div[i][1] << 27 |
1095                                         epll_div[i][2] << PLL46XX_MDIV_SHIFT |
1096                                         epll_div[i][3] << PLL46XX_PDIV_SHIFT |
1097                                         epll_div[i][4] << PLL46XX_SDIV_SHIFT);
1098                         break;
1099                 }
1100         }
1101
1102         if (i == ARRAY_SIZE(epll_div)) {
1103                 printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
1104                                 __func__);
1105                 return -EINVAL;
1106         }
1107
1108         __raw_writel(epll_con, S5P_EPLL_CON);
1109         __raw_writel(epll_con_k, S5P_EPLL_CON1);
1110
1111         printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
1112                         clk->rate, rate);
1113
1114         clk->rate = rate;
1115
1116         return 0;
1117 }
1118
1119 static struct clk_ops s5pv210_epll_ops = {
1120         .set_rate = s5pv210_epll_set_rate,
1121         .get_rate = s5p_epll_get_rate,
1122 };
1123
1124 static u32 vpll_div[][5] = {
1125         {  54000000, 3, 53, 3, 0 },
1126         { 108000000, 3, 53, 2, 0 },
1127 };
1128
1129 static unsigned long s5pv210_vpll_get_rate(struct clk *clk)
1130 {
1131         return clk->rate;
1132 }
1133
1134 static int s5pv210_vpll_set_rate(struct clk *clk, unsigned long rate)
1135 {
1136         unsigned int vpll_con;
1137         unsigned int i;
1138
1139         /* Return if nothing changed */
1140         if (clk->rate == rate)
1141                 return 0;
1142
1143         vpll_con = __raw_readl(S5P_VPLL_CON);
1144         vpll_con &= ~(0x1 << 27 |                                       \
1145                         PLL90XX_MDIV_MASK << PLL90XX_MDIV_SHIFT |       \
1146                         PLL90XX_PDIV_MASK << PLL90XX_PDIV_SHIFT |       \
1147                         PLL90XX_SDIV_MASK << PLL90XX_SDIV_SHIFT);
1148
1149         for (i = 0; i < ARRAY_SIZE(vpll_div); i++) {
1150                 if (vpll_div[i][0] == rate) {
1151                         vpll_con |= vpll_div[i][1] << PLL90XX_PDIV_SHIFT;
1152                         vpll_con |= vpll_div[i][2] << PLL90XX_MDIV_SHIFT;
1153                         vpll_con |= vpll_div[i][3] << PLL90XX_SDIV_SHIFT;
1154                         vpll_con |= vpll_div[i][4] << 27;
1155                         break;
1156                 }
1157         }
1158
1159         if (i == ARRAY_SIZE(vpll_div)) {
1160                 printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
1161                                 __func__);
1162                 return -EINVAL;
1163         }
1164
1165         __raw_writel(vpll_con, S5P_VPLL_CON);
1166
1167         /* Wait for VPLL lock */
1168         while (!(__raw_readl(S5P_VPLL_CON) & (1 << PLL90XX_LOCKED_SHIFT)))
1169                 continue;
1170
1171         clk->rate = rate;
1172         return 0;
1173 }
1174 static struct clk_ops s5pv210_vpll_ops = {
1175         .get_rate = s5pv210_vpll_get_rate,
1176         .set_rate = s5pv210_vpll_set_rate,
1177 };
1178
1179 void __init_or_cpufreq s5pv210_setup_clocks(void)
1180 {
1181         struct clk *xtal_clk;
1182         unsigned long vpllsrc;
1183         unsigned long armclk;
1184         unsigned long hclk_msys;
1185         unsigned long hclk_dsys;
1186         unsigned long hclk_psys;
1187         unsigned long pclk_msys;
1188         unsigned long pclk_dsys;
1189         unsigned long pclk_psys;
1190         unsigned long apll;
1191         unsigned long mpll;
1192         unsigned long epll;
1193         unsigned long vpll;
1194         unsigned int ptr;
1195         u32 clkdiv0, clkdiv1;
1196
1197         /* Set functions for clk_fout_epll */
1198         clk_fout_epll.enable = s5p_epll_enable;
1199         clk_fout_epll.ops = &s5pv210_epll_ops;
1200
1201         printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1202
1203         clkdiv0 = __raw_readl(S5P_CLK_DIV0);
1204         clkdiv1 = __raw_readl(S5P_CLK_DIV1);
1205
1206         printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
1207                                 __func__, clkdiv0, clkdiv1);
1208
1209         xtal_clk = clk_get(NULL, "xtal");
1210         BUG_ON(IS_ERR(xtal_clk));
1211
1212         xtal = clk_get_rate(xtal_clk);
1213         clk_put(xtal_clk);
1214
1215         printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1216
1217         apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
1218         mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
1219         epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON),
1220                                 __raw_readl(S5P_EPLL_CON1), pll_4600);
1221         vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1222         vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
1223
1224         clk_fout_apll.ops = &clk_fout_apll_ops;
1225         clk_fout_mpll.rate = mpll;
1226         clk_fout_epll.rate = epll;
1227         clk_fout_vpll.ops = &s5pv210_vpll_ops;
1228         clk_fout_vpll.rate = vpll;
1229
1230         printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1231                         apll, mpll, epll, vpll);
1232
1233         armclk = clk_get_rate(&clk_armclk.clk);
1234         hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
1235         hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk);
1236         hclk_psys = clk_get_rate(&clk_hclk_psys.clk);
1237         pclk_msys = clk_get_rate(&clk_pclk_msys.clk);
1238         pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk);
1239         pclk_psys = clk_get_rate(&clk_pclk_psys.clk);
1240
1241         printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n"
1242                          "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
1243                         armclk, hclk_msys, hclk_dsys, hclk_psys,
1244                         pclk_msys, pclk_dsys, pclk_psys);
1245
1246         clk_f.rate = armclk;
1247         clk_h.rate = hclk_psys;
1248         clk_p.rate = pclk_psys;
1249
1250         for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1251                 s3c_set_clksrc(&clksrcs[ptr], true);
1252 }
1253
1254 static struct clk *clks[] __initdata = {
1255         &clk_sclk_hdmi27m,
1256         &clk_sclk_hdmiphy,
1257         &clk_sclk_usbphy0,
1258         &clk_sclk_usbphy1,
1259         &clk_pcmcdclk0,
1260         &clk_pcmcdclk1,
1261         &clk_pcmcdclk2,
1262 };
1263
1264 void __init s5pv210_register_clocks(void)
1265 {
1266         int ptr;
1267
1268         s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1269
1270         for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1271                 s3c_register_clksrc(sysclks[ptr], 1);
1272
1273         for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
1274                 s3c_register_clksrc(sclk_tv[ptr], 1);
1275
1276         s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1277         s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1278
1279         s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1280         s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1281
1282         s3c24xx_register_clock(&dummy_apb_pclk);
1283         s3c_pwmclk_init();
1284 }