ARM: tegra: Convert PMC to a driver
[cascardo/linux.git] / arch / arm / mach-s5p64x0 / clock-s5p6450.c
1 /* linux/arch/arm/mach-s5p64x0/clock-s5p6450.c
2  *
3  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com
5  *
6  * S5P6450 - 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/device.h>
21 #include <linux/io.h>
22
23 #include <mach/hardware.h>
24 #include <mach/map.h>
25 #include <mach/regs-clock.h>
26
27 #include <plat/cpu-freq.h>
28 #include <plat/clock.h>
29 #include <plat/cpu.h>
30 #include <plat/pll.h>
31 #include <plat/s5p-clock.h>
32 #include <plat/clock-clksrc.h>
33
34 #include "clock.h"
35 #include "common.h"
36
37 static struct clksrc_clk clk_mout_dpll = {
38         .clk    = {
39                 .name           = "mout_dpll",
40         },
41         .sources        = &clk_src_dpll,
42         .reg_src        = { .reg = S5P64X0_CLK_SRC0, .shift = 5, .size = 1 },
43 };
44
45 static u32 epll_div[][5] = {
46         { 133000000,    27307,  55, 2, 2 },
47         { 100000000,    43691,  41, 2, 2 },
48         { 480000000,    0,      80, 2, 0 },
49 };
50
51 static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate)
52 {
53         unsigned int epll_con, epll_con_k;
54         unsigned int i;
55
56         if (clk->rate == rate)  /* Return if nothing changed */
57                 return 0;
58
59         epll_con = __raw_readl(S5P64X0_EPLL_CON);
60         epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K);
61
62         epll_con_k &= ~(PLL90XX_KDIV_MASK);
63         epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
64
65         for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
66                  if (epll_div[i][0] == rate) {
67                         epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
68                         epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
69                                     (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
70                                     (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
71                         break;
72                 }
73         }
74
75         if (i == ARRAY_SIZE(epll_div)) {
76                 printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
77                 return -EINVAL;
78         }
79
80         __raw_writel(epll_con, S5P64X0_EPLL_CON);
81         __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
82
83         printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
84                         clk->rate, rate);
85
86         clk->rate = rate;
87
88         return 0;
89 }
90
91 static struct clk_ops s5p6450_epll_ops = {
92         .get_rate = s5p_epll_get_rate,
93         .set_rate = s5p6450_epll_set_rate,
94 };
95
96 static struct clksrc_clk clk_dout_epll = {
97         .clk    = {
98                 .name           = "dout_epll",
99                 .parent         = &clk_mout_epll.clk,
100         },
101         .reg_div        = { .reg = S5P64X0_CLK_DIV1, .shift = 24, .size = 4 },
102 };
103
104 static struct clksrc_clk clk_mout_hclk_sel = {
105         .clk    = {
106                 .name           = "mout_hclk_sel",
107         },
108         .sources        = &clkset_hclk_low,
109         .reg_src        = { .reg = S5P64X0_OTHERS, .shift = 15, .size = 1 },
110 };
111
112 static struct clk *clkset_hclk_list[] = {
113         &clk_mout_hclk_sel.clk,
114         &clk_armclk.clk,
115 };
116
117 static struct clksrc_sources clkset_hclk = {
118         .sources        = clkset_hclk_list,
119         .nr_sources     = ARRAY_SIZE(clkset_hclk_list),
120 };
121
122 static struct clksrc_clk clk_hclk = {
123         .clk    = {
124                 .name           = "clk_hclk",
125         },
126         .sources        = &clkset_hclk,
127         .reg_src        = { .reg = S5P64X0_OTHERS, .shift = 14, .size = 1 },
128         .reg_div        = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 },
129 };
130
131 static struct clksrc_clk clk_pclk = {
132         .clk    = {
133                 .name           = "clk_pclk",
134                 .parent         = &clk_hclk.clk,
135         },
136         .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 },
137 };
138 static struct clksrc_clk clk_dout_pwm_ratio0 = {
139         .clk    = {
140                 .name           = "clk_dout_pwm_ratio0",
141                 .parent         = &clk_mout_hclk_sel.clk,
142         },
143         .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 16, .size = 4 },
144 };
145
146 static struct clksrc_clk clk_pclk_to_wdt_pwm = {
147         .clk    = {
148                 .name           = "clk_pclk_to_wdt_pwm",
149                 .parent         = &clk_dout_pwm_ratio0.clk,
150         },
151         .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 20, .size = 4 },
152 };
153
154 static struct clksrc_clk clk_hclk_low = {
155         .clk    = {
156                 .name           = "clk_hclk_low",
157         },
158         .sources        = &clkset_hclk_low,
159         .reg_src        = { .reg = S5P64X0_OTHERS, .shift = 6, .size = 1 },
160         .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 },
161 };
162
163 static struct clksrc_clk clk_pclk_low = {
164         .clk    = {
165                 .name           = "clk_pclk_low",
166                 .parent         = &clk_hclk_low.clk,
167         },
168         .reg_div        = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 },
169 };
170
171 /*
172  * The following clocks will be disabled during clock initialization. It is
173  * recommended to keep the following clocks disabled until the driver requests
174  * for enabling the clock.
175  */
176 static struct clk init_clocks_off[] = {
177         {
178                 .name           = "usbhost",
179                 .parent         = &clk_hclk_low.clk,
180                 .enable         = s5p64x0_hclk0_ctrl,
181                 .ctrlbit        = (1 << 3),
182         }, {
183                 .name           = "dma",
184                 .devname        = "dma-pl330",
185                 .parent         = &clk_hclk_low.clk,
186                 .enable         = s5p64x0_hclk0_ctrl,
187                 .ctrlbit        = (1 << 12),
188         }, {
189                 .name           = "hsmmc",
190                 .devname        = "s3c-sdhci.0",
191                 .parent         = &clk_hclk_low.clk,
192                 .enable         = s5p64x0_hclk0_ctrl,
193                 .ctrlbit        = (1 << 17),
194         }, {
195                 .name           = "hsmmc",
196                 .devname        = "s3c-sdhci.1",
197                 .parent         = &clk_hclk_low.clk,
198                 .enable         = s5p64x0_hclk0_ctrl,
199                 .ctrlbit        = (1 << 18),
200         }, {
201                 .name           = "hsmmc",
202                 .devname        = "s3c-sdhci.2",
203                 .parent         = &clk_hclk_low.clk,
204                 .enable         = s5p64x0_hclk0_ctrl,
205                 .ctrlbit        = (1 << 19),
206         }, {
207                 .name           = "usbotg",
208                 .parent         = &clk_hclk_low.clk,
209                 .enable         = s5p64x0_hclk0_ctrl,
210                 .ctrlbit        = (1 << 20),
211         }, {
212                 .name           = "lcd",
213                 .parent         = &clk_h,
214                 .enable         = s5p64x0_hclk1_ctrl,
215                 .ctrlbit        = (1 << 1),
216         }, {
217                 .name           = "watchdog",
218                 .parent         = &clk_pclk_low.clk,
219                 .enable         = s5p64x0_pclk_ctrl,
220                 .ctrlbit        = (1 << 5),
221         }, {
222                 .name           = "rtc",
223                 .parent         = &clk_pclk_low.clk,
224                 .enable         = s5p64x0_pclk_ctrl,
225                 .ctrlbit        = (1 << 6),
226         }, {
227                 .name           = "adc",
228                 .parent         = &clk_pclk_low.clk,
229                 .enable         = s5p64x0_pclk_ctrl,
230                 .ctrlbit        = (1 << 12),
231         }, {
232                 .name           = "i2c",
233                 .devname        = "s3c2440-i2c.0",
234                 .parent         = &clk_pclk_low.clk,
235                 .enable         = s5p64x0_pclk_ctrl,
236                 .ctrlbit        = (1 << 17),
237         }, {
238                 .name           = "spi",
239                 .devname        = "s5p64x0-spi.0",
240                 .parent         = &clk_pclk_low.clk,
241                 .enable         = s5p64x0_pclk_ctrl,
242                 .ctrlbit        = (1 << 21),
243         }, {
244                 .name           = "spi",
245                 .devname        = "s5p64x0-spi.1",
246                 .parent         = &clk_pclk_low.clk,
247                 .enable         = s5p64x0_pclk_ctrl,
248                 .ctrlbit        = (1 << 22),
249         }, {
250                 .name           = "i2c",
251                 .devname        = "s3c2440-i2c.1",
252                 .parent         = &clk_pclk_low.clk,
253                 .enable         = s5p64x0_pclk_ctrl,
254                 .ctrlbit        = (1 << 27),
255         }, {
256                 .name           = "dmc0",
257                 .parent         = &clk_pclk.clk,
258                 .enable         = s5p64x0_pclk_ctrl,
259                 .ctrlbit        = (1 << 30),
260         }
261 };
262
263 /*
264  * The following clocks will be enabled during clock initialization.
265  */
266 static struct clk init_clocks[] = {
267         {
268                 .name           = "intc",
269                 .parent         = &clk_hclk.clk,
270                 .enable         = s5p64x0_hclk0_ctrl,
271                 .ctrlbit        = (1 << 1),
272         }, {
273                 .name           = "mem",
274                 .parent         = &clk_hclk.clk,
275                 .enable         = s5p64x0_hclk0_ctrl,
276                 .ctrlbit        = (1 << 21),
277         }, {
278                 .name           = "uart",
279                 .devname        = "s3c6400-uart.0",
280                 .parent         = &clk_pclk_low.clk,
281                 .enable         = s5p64x0_pclk_ctrl,
282                 .ctrlbit        = (1 << 1),
283         }, {
284                 .name           = "uart",
285                 .devname        = "s3c6400-uart.1",
286                 .parent         = &clk_pclk_low.clk,
287                 .enable         = s5p64x0_pclk_ctrl,
288                 .ctrlbit        = (1 << 2),
289         }, {
290                 .name           = "uart",
291                 .devname        = "s3c6400-uart.2",
292                 .parent         = &clk_pclk_low.clk,
293                 .enable         = s5p64x0_pclk_ctrl,
294                 .ctrlbit        = (1 << 3),
295         }, {
296                 .name           = "uart",
297                 .devname        = "s3c6400-uart.3",
298                 .parent         = &clk_pclk_low.clk,
299                 .enable         = s5p64x0_pclk_ctrl,
300                 .ctrlbit        = (1 << 4),
301         }, {
302                 .name           = "timers",
303                 .parent         = &clk_pclk_to_wdt_pwm.clk,
304                 .enable         = s5p64x0_pclk_ctrl,
305                 .ctrlbit        = (1 << 7),
306         }, {
307                 .name           = "gpio",
308                 .parent         = &clk_pclk_low.clk,
309                 .enable         = s5p64x0_pclk_ctrl,
310                 .ctrlbit        = (1 << 18),
311         },
312 };
313
314 static struct clk *clkset_uart_list[] = {
315         &clk_dout_epll.clk,
316         &clk_dout_mpll.clk,
317 };
318
319 static struct clksrc_sources clkset_uart = {
320         .sources        = clkset_uart_list,
321         .nr_sources     = ARRAY_SIZE(clkset_uart_list),
322 };
323
324 static struct clk *clkset_mali_list[] = {
325         &clk_mout_epll.clk,
326         &clk_mout_apll.clk,
327         &clk_mout_mpll.clk,
328 };
329
330 static struct clksrc_sources clkset_mali = {
331         .sources        = clkset_mali_list,
332         .nr_sources     = ARRAY_SIZE(clkset_mali_list),
333 };
334
335 static struct clk *clkset_group2_list[] = {
336         &clk_dout_epll.clk,
337         &clk_dout_mpll.clk,
338         &clk_ext_xtal_mux,
339 };
340
341 static struct clksrc_sources clkset_group2 = {
342         .sources        = clkset_group2_list,
343         .nr_sources     = ARRAY_SIZE(clkset_group2_list),
344 };
345
346 static struct clk *clkset_dispcon_list[] = {
347         &clk_dout_epll.clk,
348         &clk_dout_mpll.clk,
349         &clk_ext_xtal_mux,
350         &clk_mout_dpll.clk,
351 };
352
353 static struct clksrc_sources clkset_dispcon = {
354         .sources        = clkset_dispcon_list,
355         .nr_sources     = ARRAY_SIZE(clkset_dispcon_list),
356 };
357
358 static struct clk *clkset_hsmmc44_list[] = {
359         &clk_dout_epll.clk,
360         &clk_dout_mpll.clk,
361         &clk_ext_xtal_mux,
362         &s5p_clk_27m,
363         &clk_48m,
364 };
365
366 static struct clksrc_sources clkset_hsmmc44 = {
367         .sources        = clkset_hsmmc44_list,
368         .nr_sources     = ARRAY_SIZE(clkset_hsmmc44_list),
369 };
370
371 static struct clk *clkset_sclk_audio0_list[] = {
372         [0] = &clk_dout_epll.clk,
373         [1] = &clk_dout_mpll.clk,
374         [2] = &clk_ext_xtal_mux,
375         [3] = NULL,
376         [4] = NULL,
377 };
378
379 static struct clksrc_sources clkset_sclk_audio0 = {
380         .sources        = clkset_sclk_audio0_list,
381         .nr_sources     = ARRAY_SIZE(clkset_sclk_audio0_list),
382 };
383
384 static struct clksrc_clk clk_sclk_audio0 = {
385         .clk            = {
386                 .name           = "audio-bus",
387                 .devname        = "samsung-i2s.0",
388                 .enable         = s5p64x0_sclk_ctrl,
389                 .ctrlbit        = (1 << 8),
390                 .parent         = &clk_dout_epll.clk,
391         },
392         .sources        = &clkset_sclk_audio0,
393         .reg_src        = { .reg = S5P64X0_CLK_SRC1, .shift = 10, .size = 3 },
394         .reg_div        = { .reg = S5P64X0_CLK_DIV2, .shift = 8, .size = 4 },
395 };
396
397 static struct clksrc_clk clksrcs[] = {
398         {
399                 .clk    = {
400                         .name           = "sclk_fimc",
401                         .ctrlbit        = (1 << 10),
402                         .enable         = s5p64x0_sclk_ctrl,
403                 },
404                 .sources = &clkset_group2,
405                 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 },
406                 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 },
407         }, {
408                 .clk    = {
409                         .name           = "aclk_mali",
410                         .ctrlbit        = (1 << 2),
411                         .enable         = s5p64x0_sclk1_ctrl,
412                 },
413                 .sources = &clkset_mali,
414                 .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 },
415                 .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 },
416         }, {
417                 .clk    = {
418                         .name           = "sclk_2d",
419                         .ctrlbit        = (1 << 12),
420                         .enable         = s5p64x0_sclk_ctrl,
421                 },
422                 .sources = &clkset_mali,
423                 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 30, .size = 2 },
424                 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 20, .size = 4 },
425         }, {
426                 .clk    = {
427                         .name           = "sclk_usi",
428                         .ctrlbit        = (1 << 7),
429                         .enable         = s5p64x0_sclk_ctrl,
430                 },
431                 .sources = &clkset_group2,
432                 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 10, .size = 2 },
433                 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 16, .size = 4 },
434         }, {
435                 .clk    = {
436                         .name           = "sclk_camif",
437                         .ctrlbit        = (1 << 6),
438                         .enable         = s5p64x0_sclk_ctrl,
439                 },
440                 .sources = &clkset_group2,
441                 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 28, .size = 2 },
442                 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 20, .size = 4 },
443         }, {
444                 .clk    = {
445                         .name           = "sclk_dispcon",
446                         .ctrlbit        = (1 << 1),
447                         .enable         = s5p64x0_sclk1_ctrl,
448                 },
449                 .sources = &clkset_dispcon,
450                 .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 },
451                 .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 },
452         }, {
453                 .clk    = {
454                         .name           = "sclk_hsmmc44",
455                         .ctrlbit        = (1 << 30),
456                         .enable         = s5p64x0_sclk_ctrl,
457                 },
458                 .sources = &clkset_hsmmc44,
459                 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 6, .size = 3 },
460                 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 28, .size = 4 },
461         },
462 };
463
464 static struct clksrc_clk clk_sclk_mmc0 = {
465         .clk    = {
466                 .name           = "sclk_mmc",
467                 .devname        = "s3c-sdhci.0",
468                 .ctrlbit        = (1 << 24),
469                 .enable         = s5p64x0_sclk_ctrl,
470         },
471         .sources = &clkset_group2,
472         .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
473         .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
474 };
475
476 static struct clksrc_clk clk_sclk_mmc1 = {
477         .clk    = {
478                 .name           = "sclk_mmc",
479                 .devname        = "s3c-sdhci.1",
480                 .ctrlbit        = (1 << 25),
481                 .enable         = s5p64x0_sclk_ctrl,
482         },
483         .sources = &clkset_group2,
484         .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
485         .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
486 };
487
488 static struct clksrc_clk clk_sclk_mmc2 = {
489         .clk    = {
490                 .name           = "sclk_mmc",
491                 .devname        = "s3c-sdhci.2",
492                 .ctrlbit        = (1 << 26),
493                 .enable         = s5p64x0_sclk_ctrl,
494         },
495         .sources = &clkset_group2,
496         .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
497         .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
498 };
499
500 static struct clksrc_clk clk_sclk_uclk = {
501         .clk    = {
502                 .name           = "uclk1",
503                 .ctrlbit        = (1 << 5),
504                 .enable         = s5p64x0_sclk_ctrl,
505         },
506         .sources = &clkset_uart,
507         .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
508         .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
509 };
510
511 static struct clksrc_clk clk_sclk_spi0 = {
512         .clk    = {
513                 .name           = "sclk_spi",
514                 .devname        = "s5p64x0-spi.0",
515                 .ctrlbit        = (1 << 20),
516                 .enable         = s5p64x0_sclk_ctrl,
517         },
518         .sources = &clkset_group2,
519         .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
520         .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
521 };
522
523 static struct clksrc_clk clk_sclk_spi1 = {
524         .clk    = {
525                 .name           = "sclk_spi",
526                 .devname        = "s5p64x0-spi.1",
527                 .ctrlbit        = (1 << 21),
528                 .enable         = s5p64x0_sclk_ctrl,
529         },
530         .sources = &clkset_group2,
531         .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
532         .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
533 };
534
535 static struct clk clk_i2s0 = {
536         .name           = "iis",
537         .devname        = "samsung-i2s.0",
538         .parent         = &clk_pclk_low.clk,
539         .enable         = s5p64x0_pclk_ctrl,
540         .ctrlbit        = (1 << 26),
541 };
542
543 static struct clk clk_i2s1 = {
544         .name           = "iis",
545         .devname        = "samsung-i2s.1",
546         .parent         = &clk_pclk_low.clk,
547         .enable         = s5p64x0_pclk_ctrl,
548         .ctrlbit        = (1 << 15),
549 };
550
551 static struct clk clk_i2s2 = {
552         .name           = "iis",
553         .devname        = "samsung-i2s.2",
554         .parent         = &clk_pclk_low.clk,
555         .enable         = s5p64x0_pclk_ctrl,
556         .ctrlbit        = (1 << 16),
557 };
558
559 static struct clk *clk_cdev[] = {
560         &clk_i2s0,
561         &clk_i2s1,
562         &clk_i2s2,
563 };
564
565 static struct clksrc_clk *clksrc_cdev[] = {
566         &clk_sclk_uclk,
567         &clk_sclk_spi0,
568         &clk_sclk_spi1,
569         &clk_sclk_mmc0,
570         &clk_sclk_mmc1,
571         &clk_sclk_mmc2,
572         &clk_sclk_audio0,
573 };
574
575 static struct clk_lookup s5p6450_clk_lookup[] = {
576         CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
577         CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
578         CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
579         CLKDEV_INIT("s5p64x0-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
580         CLKDEV_INIT("s5p64x0-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
581         CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
582         CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
583         CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
584         CLKDEV_INIT("samsung-i2s.0", "i2s_opclk0", &clk_i2s0),
585         CLKDEV_INIT("samsung-i2s.0", "i2s_opclk1", &clk_sclk_audio0.clk),
586         CLKDEV_INIT("samsung-i2s.1", "i2s_opclk0", &clk_i2s1),
587         CLKDEV_INIT("samsung-i2s.2", "i2s_opclk0", &clk_i2s2),
588 };
589
590 /* Clock initialization code */
591 static struct clksrc_clk *sysclks[] = {
592         &clk_mout_apll,
593         &clk_mout_epll,
594         &clk_dout_epll,
595         &clk_mout_mpll,
596         &clk_dout_mpll,
597         &clk_armclk,
598         &clk_mout_hclk_sel,
599         &clk_dout_pwm_ratio0,
600         &clk_pclk_to_wdt_pwm,
601         &clk_hclk,
602         &clk_pclk,
603         &clk_hclk_low,
604         &clk_pclk_low,
605 };
606
607 static struct clk dummy_apb_pclk = {
608         .name           = "apb_pclk",
609         .id             = -1,
610 };
611
612 void __init_or_cpufreq s5p6450_setup_clocks(void)
613 {
614         struct clk *xtal_clk;
615
616         unsigned long xtal;
617         unsigned long fclk;
618         unsigned long hclk;
619         unsigned long hclk_low;
620         unsigned long pclk;
621         unsigned long pclk_low;
622
623         unsigned long apll;
624         unsigned long mpll;
625         unsigned long epll;
626         unsigned long dpll;
627         unsigned int ptr;
628
629         /* Set S5P6450 functions for clk_fout_epll */
630
631         clk_fout_epll.enable = s5p_epll_enable;
632         clk_fout_epll.ops = &s5p6450_epll_ops;
633
634         clk_48m.enable = s5p64x0_clk48m_ctrl;
635
636         xtal_clk = clk_get(NULL, "ext_xtal");
637         BUG_ON(IS_ERR(xtal_clk));
638
639         xtal = clk_get_rate(xtal_clk);
640         clk_put(xtal_clk);
641
642         apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502);
643         mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502);
644         epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON),
645                                 __raw_readl(S5P64X0_EPLL_CON_K));
646         dpll = s5p_get_pll46xx(xtal, __raw_readl(S5P6450_DPLL_CON),
647                                 __raw_readl(S5P6450_DPLL_CON_K), pll_4650c);
648
649         clk_fout_apll.rate = apll;
650         clk_fout_mpll.rate = mpll;
651         clk_fout_epll.rate = epll;
652         clk_fout_dpll.rate = dpll;
653
654         printk(KERN_INFO "S5P6450: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
655                         " E=%ld.%ldMHz, D=%ld.%ldMHz\n",
656                         print_mhz(apll), print_mhz(mpll), print_mhz(epll),
657                         print_mhz(dpll));
658
659         fclk = clk_get_rate(&clk_armclk.clk);
660         hclk = clk_get_rate(&clk_hclk.clk);
661         pclk = clk_get_rate(&clk_pclk.clk);
662         hclk_low = clk_get_rate(&clk_hclk_low.clk);
663         pclk_low = clk_get_rate(&clk_pclk_low.clk);
664
665         printk(KERN_INFO "S5P6450: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
666                         " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
667                         print_mhz(hclk), print_mhz(hclk_low),
668                         print_mhz(pclk), print_mhz(pclk_low));
669
670         clk_f.rate = fclk;
671         clk_h.rate = hclk;
672         clk_p.rate = pclk;
673
674         for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
675                 s3c_set_clksrc(&clksrcs[ptr], true);
676 }
677
678 void __init s5p6450_register_clocks(void)
679 {
680         int ptr;
681         unsigned int cnt;
682
683         for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
684                 s3c_register_clksrc(sysclks[ptr], 1);
685
686
687         s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
688         for (cnt = 0; cnt < ARRAY_SIZE(clk_cdev); cnt++)
689                 s3c_disable_clocks(clk_cdev[cnt], 1);
690
691         s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
692         s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
693         for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
694                 s3c_register_clksrc(clksrc_cdev[ptr], 1);
695
696         s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
697         s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
698         clkdev_add_table(s5p6450_clk_lookup, ARRAY_SIZE(s5p6450_clk_lookup));
699
700         s3c24xx_register_clock(&dummy_apb_pclk);
701 }