ARM: S5P6440: Change dout_mpll clock type to clksrc_clk clock type.
[deliverable/linux.git] / arch / arm / mach-s5p6440 / clock.c
CommitLineData
e96b234b 1/* linux/arch/arm/mach-s5p6440/clock.c
1a0e8a52
KK
2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P6440 - 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/hardware.h>
24#include <mach/map.h>
25
26#include <plat/cpu-freq.h>
27#include <mach/regs-clock.h>
28#include <plat/clock.h>
29#include <plat/cpu.h>
30#include <plat/clock-clksrc.h>
31#include <plat/s5p-clock.h>
32#include <plat/pll.h>
33#include <plat/s5p6440.h>
34
35/* APLL Mux output clock */
36static struct clksrc_clk clk_mout_apll = {
37 .clk = {
38 .name = "mout_apll",
39 .id = -1,
40 },
41 .sources = &clk_src_apll,
42 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
43};
44
45static int s5p6440_epll_enable(struct clk *clk, int enable)
46{
47 unsigned int ctrlbit = clk->ctrlbit;
48 unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
49
50 if (enable)
51 __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
52 else
53 __raw_writel(epll_con, S5P_EPLL_CON);
54
55 return 0;
56}
57
58static unsigned long s5p6440_epll_get_rate(struct clk *clk)
59{
60 return clk->rate;
61}
62
63static u32 epll_div[][5] = {
64 { 36000000, 0, 48, 1, 4 },
65 { 48000000, 0, 32, 1, 3 },
66 { 60000000, 0, 40, 1, 3 },
67 { 72000000, 0, 48, 1, 3 },
68 { 84000000, 0, 28, 1, 2 },
69 { 96000000, 0, 32, 1, 2 },
70 { 32768000, 45264, 43, 1, 4 },
71 { 45158000, 6903, 30, 1, 3 },
72 { 49152000, 50332, 32, 1, 3 },
73 { 67738000, 10398, 45, 1, 3 },
74 { 73728000, 9961, 49, 1, 3 }
75};
76
77static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
78{
79 unsigned int epll_con, epll_con_k;
80 unsigned int i;
81
82 if (clk->rate == rate) /* Return if nothing changed */
83 return 0;
84
85 epll_con = __raw_readl(S5P_EPLL_CON);
86 epll_con_k = __raw_readl(S5P_EPLL_CON_K);
87
88 epll_con_k &= ~(PLL90XX_KDIV_MASK);
89 epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
90
91 for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
92 if (epll_div[i][0] == rate) {
93 epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
94 epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
95 (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
96 (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
97 break;
98 }
99 }
100
101 if (i == ARRAY_SIZE(epll_div)) {
102 printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
103 return -EINVAL;
104 }
105
106 __raw_writel(epll_con, S5P_EPLL_CON);
107 __raw_writel(epll_con_k, S5P_EPLL_CON_K);
108
109 clk->rate = rate;
110
111 return 0;
112}
113
114static struct clk_ops s5p6440_epll_ops = {
115 .get_rate = s5p6440_epll_get_rate,
116 .set_rate = s5p6440_epll_set_rate,
117};
118
119static 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_CLK_SRC0, .shift = 2, .size = 1 },
126};
127
128static 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_CLK_SRC0, .shift = 1, .size = 1 },
135};
136
137static struct clk clk_h_low = {
138 .name = "hclk_low",
139 .id = -1,
140 .rate = 0,
141 .parent = NULL,
142 .ctrlbit = 0,
143 .ops = &clk_ops_def_setrate,
144};
145
146static struct clk clk_p_low = {
147 .name = "pclk_low",
148 .id = -1,
149 .rate = 0,
150 .parent = NULL,
151 .ctrlbit = 0,
152 .ops = &clk_ops_def_setrate,
153};
154
155enum perf_level {
156 L0 = 532*1000,
157 L1 = 266*1000,
158 L2 = 133*1000,
159};
160
161static const u32 clock_table[][3] = {
162 /*{ARM_CLK, DIVarm, DIVhclk}*/
163 {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P_CLKDIV0_HCLK_SHIFT)},
164 {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P_CLKDIV0_HCLK_SHIFT)},
165 {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P_CLKDIV0_HCLK_SHIFT)},
166};
167
168static unsigned long s5p6440_armclk_get_rate(struct clk *clk)
169{
170 unsigned long rate = clk_get_rate(clk->parent);
171 u32 clkdiv;
172
173 /* divisor mask starts at bit0, so no need to shift */
174 clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK;
175
176 return rate / (clkdiv + 1);
177}
178
179static unsigned long s5p6440_armclk_round_rate(struct clk *clk,
180 unsigned long rate)
181{
182 u32 iter;
183
184 for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
185 if (rate > clock_table[iter][0])
186 return clock_table[iter-1][0];
187 }
188
189 return clock_table[ARRAY_SIZE(clock_table) - 1][0];
190}
191
192static int s5p6440_armclk_set_rate(struct clk *clk, unsigned long rate)
193{
194 u32 round_tmp;
195 u32 iter;
196 u32 clk_div0_tmp;
197 u32 cur_rate = clk->ops->get_rate(clk);
198 unsigned long flags;
199
200 round_tmp = clk->ops->round_rate(clk, rate);
201 if (round_tmp == cur_rate)
202 return 0;
203
204
205 for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
206 if (round_tmp == clock_table[iter][0])
207 break;
208 }
209
210 if (iter >= ARRAY_SIZE(clock_table))
211 iter = ARRAY_SIZE(clock_table) - 1;
212
213 local_irq_save(flags);
214 if (cur_rate > round_tmp) {
215 /* Frequency Down */
216 clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
217 clk_div0_tmp |= clock_table[iter][1];
218 __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
219
220 clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
221 ~(S5P_CLKDIV0_HCLK_MASK);
222 clk_div0_tmp |= clock_table[iter][2];
223 __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
224
225
226 } else {
227 /* Frequency Up */
228 clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
229 ~(S5P_CLKDIV0_HCLK_MASK);
230 clk_div0_tmp |= clock_table[iter][2];
231 __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
232
233 clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
234 clk_div0_tmp |= clock_table[iter][1];
235 __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
236 }
237 local_irq_restore(flags);
238
239 clk->rate = clock_table[iter][0];
240
241 return 0;
242}
243
244static struct clk_ops s5p6440_clkarm_ops = {
245 .get_rate = s5p6440_armclk_get_rate,
246 .set_rate = s5p6440_armclk_set_rate,
247 .round_rate = s5p6440_armclk_round_rate,
248};
249
30d58349
TA
250static struct clksrc_clk clk_dout_mpll = {
251 .clk = {
252 .name = "dout_mpll",
253 .id = -1,
254 .parent = &clk_mout_mpll.clk,
1a0e8a52 255 },
30d58349 256 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 1 },
1a0e8a52
KK
257};
258
259int s5p6440_clk48m_ctrl(struct clk *clk, int enable)
260{
261 unsigned long flags;
262 u32 val;
263
264 /* can't rely on clock lock, this register has other usages */
265 local_irq_save(flags);
266
267 val = __raw_readl(S5P_OTHERS);
268 if (enable)
269 val |= S5P_OTHERS_USB_SIG_MASK;
270 else
271 val &= ~S5P_OTHERS_USB_SIG_MASK;
272
273 __raw_writel(val, S5P_OTHERS);
274
275 local_irq_restore(flags);
276
277 return 0;
278}
279
280static int s5p6440_pclk_ctrl(struct clk *clk, int enable)
281{
282 return s5p_gatectrl(S5P_CLK_GATE_PCLK, clk, enable);
283}
284
285static int s5p6440_hclk0_ctrl(struct clk *clk, int enable)
286{
287 return s5p_gatectrl(S5P_CLK_GATE_HCLK0, clk, enable);
288}
289
290static int s5p6440_hclk1_ctrl(struct clk *clk, int enable)
291{
292 return s5p_gatectrl(S5P_CLK_GATE_HCLK1, clk, enable);
293}
294
295static int s5p6440_sclk_ctrl(struct clk *clk, int enable)
296{
297 return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable);
298}
299
300static int s5p6440_mem_ctrl(struct clk *clk, int enable)
301{
302 return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable);
303}
304
305/*
306 * The following clocks will be disabled during clock initialization. It is
307 * recommended to keep the following clocks disabled until the driver requests
308 * for enabling the clock.
309 */
310static struct clk init_clocks_disable[] = {
311 {
312 .name = "nand",
313 .id = -1,
314 .parent = &clk_h,
315 .enable = s5p6440_mem_ctrl,
316 .ctrlbit = S5P_CLKCON_MEM0_HCLK_NFCON,
317 }, {
318 .name = "adc",
319 .id = -1,
320 .parent = &clk_p_low,
321 .enable = s5p6440_pclk_ctrl,
322 .ctrlbit = S5P_CLKCON_PCLK_TSADC,
323 }, {
324 .name = "i2c",
325 .id = -1,
326 .parent = &clk_p_low,
327 .enable = s5p6440_pclk_ctrl,
328 .ctrlbit = S5P_CLKCON_PCLK_IIC0,
329 }, {
330 .name = "i2s_v40",
331 .id = 0,
332 .parent = &clk_p_low,
333 .enable = s5p6440_pclk_ctrl,
334 .ctrlbit = S5P_CLKCON_PCLK_IIS2,
335 }, {
336 .name = "spi",
337 .id = 0,
338 .parent = &clk_p_low,
339 .enable = s5p6440_pclk_ctrl,
340 .ctrlbit = S5P_CLKCON_PCLK_SPI0,
341 }, {
342 .name = "spi",
343 .id = 1,
344 .parent = &clk_p_low,
345 .enable = s5p6440_pclk_ctrl,
346 .ctrlbit = S5P_CLKCON_PCLK_SPI1,
347 }, {
348 .name = "sclk_spi_48",
349 .id = 0,
350 .parent = &clk_48m,
351 .enable = s5p6440_sclk_ctrl,
352 .ctrlbit = S5P_CLKCON_SCLK0_SPI0_48,
353 }, {
354 .name = "sclk_spi_48",
355 .id = 1,
356 .parent = &clk_48m,
357 .enable = s5p6440_sclk_ctrl,
358 .ctrlbit = S5P_CLKCON_SCLK0_SPI1_48,
359 }, {
360 .name = "mmc_48m",
361 .id = 0,
362 .parent = &clk_48m,
363 .enable = s5p6440_sclk_ctrl,
364 .ctrlbit = S5P_CLKCON_SCLK0_MMC0_48,
365 }, {
366 .name = "mmc_48m",
367 .id = 1,
368 .parent = &clk_48m,
369 .enable = s5p6440_sclk_ctrl,
370 .ctrlbit = S5P_CLKCON_SCLK0_MMC1_48,
371 }, {
372 .name = "mmc_48m",
373 .id = 2,
374 .parent = &clk_48m,
375 .enable = s5p6440_sclk_ctrl,
376 .ctrlbit = S5P_CLKCON_SCLK0_MMC2_48,
377 }, {
378 .name = "otg",
379 .id = -1,
380 .parent = &clk_h_low,
381 .enable = s5p6440_hclk0_ctrl,
382 .ctrlbit = S5P_CLKCON_HCLK0_USB
383 }, {
384 .name = "post",
385 .id = -1,
386 .parent = &clk_h_low,
387 .enable = s5p6440_hclk0_ctrl,
388 .ctrlbit = S5P_CLKCON_HCLK0_POST0
389 }, {
390 .name = "lcd",
391 .id = -1,
392 .parent = &clk_h_low,
393 .enable = s5p6440_hclk1_ctrl,
394 .ctrlbit = S5P_CLKCON_HCLK1_DISPCON,
395 }, {
396 .name = "hsmmc",
397 .id = 0,
398 .parent = &clk_h_low,
399 .enable = s5p6440_hclk0_ctrl,
400 .ctrlbit = S5P_CLKCON_HCLK0_HSMMC0,
401 }, {
402 .name = "hsmmc",
403 .id = 1,
404 .parent = &clk_h_low,
405 .enable = s5p6440_hclk0_ctrl,
406 .ctrlbit = S5P_CLKCON_HCLK0_HSMMC1,
407 }, {
408 .name = "hsmmc",
409 .id = 2,
410 .parent = &clk_h_low,
411 .enable = s5p6440_hclk0_ctrl,
412 .ctrlbit = S5P_CLKCON_HCLK0_HSMMC2,
413 }, {
414 .name = "rtc",
415 .id = -1,
416 .parent = &clk_p_low,
417 .enable = s5p6440_pclk_ctrl,
418 .ctrlbit = S5P_CLKCON_PCLK_RTC,
419 }, {
420 .name = "watchdog",
421 .id = -1,
422 .parent = &clk_p_low,
423 .enable = s5p6440_pclk_ctrl,
424 .ctrlbit = S5P_CLKCON_PCLK_WDT,
425 }, {
426 .name = "timers",
427 .id = -1,
428 .parent = &clk_p_low,
429 .enable = s5p6440_pclk_ctrl,
430 .ctrlbit = S5P_CLKCON_PCLK_PWM,
431 }
432};
433
434/*
435 * The following clocks will be enabled during clock initialization.
436 */
437static struct clk init_clocks[] = {
438 {
439 .name = "gpio",
440 .id = -1,
441 .parent = &clk_p_low,
442 .enable = s5p6440_pclk_ctrl,
443 .ctrlbit = S5P_CLKCON_PCLK_GPIO,
444 }, {
445 .name = "uart",
446 .id = 0,
447 .parent = &clk_p_low,
448 .enable = s5p6440_pclk_ctrl,
449 .ctrlbit = S5P_CLKCON_PCLK_UART0,
450 }, {
451 .name = "uart",
452 .id = 1,
453 .parent = &clk_p_low,
454 .enable = s5p6440_pclk_ctrl,
455 .ctrlbit = S5P_CLKCON_PCLK_UART1,
456 }, {
457 .name = "uart",
458 .id = 2,
459 .parent = &clk_p_low,
460 .enable = s5p6440_pclk_ctrl,
461 .ctrlbit = S5P_CLKCON_PCLK_UART2,
462 }, {
463 .name = "uart",
464 .id = 3,
465 .parent = &clk_p_low,
466 .enable = s5p6440_pclk_ctrl,
467 .ctrlbit = S5P_CLKCON_PCLK_UART3,
468 }
469};
470
471static struct clk clk_iis_cd_v40 = {
472 .name = "iis_cdclk_v40",
473 .id = -1,
474};
475
476static struct clk clk_pcm_cd = {
477 .name = "pcm_cdclk",
478 .id = -1,
479};
480
481static struct clk *clkset_spi_mmc_list[] = {
482 &clk_mout_epll.clk,
30d58349 483 &clk_dout_mpll.clk,
1a0e8a52
KK
484 &clk_fin_epll,
485};
486
487static struct clksrc_sources clkset_spi_mmc = {
488 .sources = clkset_spi_mmc_list,
489 .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list),
490};
491
492static struct clk *clkset_uart_list[] = {
493 &clk_mout_epll.clk,
30d58349 494 &clk_dout_mpll.clk,
1a0e8a52
KK
495};
496
497static struct clksrc_sources clkset_uart = {
498 .sources = clkset_uart_list,
499 .nr_sources = ARRAY_SIZE(clkset_uart_list),
500};
501
502static struct clksrc_clk clksrcs[] = {
503 {
504 .clk = {
505 .name = "mmc_bus",
506 .id = 0,
507 .ctrlbit = S5P_CLKCON_SCLK0_MMC0,
508 .enable = s5p6440_sclk_ctrl,
509 },
510 .sources = &clkset_spi_mmc,
511 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 },
512 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 },
513 }, {
514 .clk = {
515 .name = "mmc_bus",
516 .id = 1,
517 .ctrlbit = S5P_CLKCON_SCLK0_MMC1,
518 .enable = s5p6440_sclk_ctrl,
519 },
520 .sources = &clkset_spi_mmc,
521 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 },
522 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 },
523 }, {
524 .clk = {
525 .name = "mmc_bus",
526 .id = 2,
527 .ctrlbit = S5P_CLKCON_SCLK0_MMC2,
528 .enable = s5p6440_sclk_ctrl,
529 },
530 .sources = &clkset_spi_mmc,
531 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 },
532 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 },
533 }, {
534 .clk = {
535 .name = "uclk1",
536 .id = -1,
537 .ctrlbit = S5P_CLKCON_SCLK0_UART,
538 .enable = s5p6440_sclk_ctrl,
539 },
540 .sources = &clkset_uart,
541 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 13, .size = 1 },
542 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 },
543 }, {
544 .clk = {
545 .name = "spi_epll",
546 .id = 0,
547 .ctrlbit = S5P_CLKCON_SCLK0_SPI0,
548 .enable = s5p6440_sclk_ctrl,
549 },
550 .sources = &clkset_spi_mmc,
551 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 },
552 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
553 }, {
554 .clk = {
555 .name = "spi_epll",
556 .id = 1,
557 .ctrlbit = S5P_CLKCON_SCLK0_SPI1,
558 .enable = s5p6440_sclk_ctrl,
559 },
560 .sources = &clkset_spi_mmc,
561 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 },
562 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
563 }
564};
565
566/* Clock initialisation code */
fb049114 567static struct clksrc_clk *sysclks[] = {
1a0e8a52
KK
568 &clk_mout_apll,
569 &clk_mout_epll,
570 &clk_mout_mpll,
30d58349 571 &clk_dout_mpll,
1a0e8a52
KK
572};
573
574void __init_or_cpufreq s5p6440_setup_clocks(void)
575{
576 struct clk *xtal_clk;
577 unsigned long xtal;
578 unsigned long fclk;
579 unsigned long hclk;
580 unsigned long hclk_low;
581 unsigned long pclk;
582 unsigned long pclk_low;
583 unsigned long epll;
584 unsigned long apll;
585 unsigned long mpll;
586 unsigned int ptr;
587 u32 clkdiv0;
588 u32 clkdiv3;
589
590 /* Set S5P6440 functions for clk_fout_epll */
591 clk_fout_epll.enable = s5p6440_epll_enable;
592 clk_fout_epll.ops = &s5p6440_epll_ops;
593
594 /* Set S5P6440 functions for arm clock */
595 clk_arm.parent = &clk_mout_apll.clk;
596 clk_arm.ops = &s5p6440_clkarm_ops;
597 clk_48m.enable = s5p6440_clk48m_ctrl;
598
599 clkdiv0 = __raw_readl(S5P_CLK_DIV0);
600 clkdiv3 = __raw_readl(S5P_CLK_DIV3);
601
602 xtal_clk = clk_get(NULL, "ext_xtal");
603 BUG_ON(IS_ERR(xtal_clk));
604
605 xtal = clk_get_rate(xtal_clk);
606 clk_put(xtal_clk);
607
608 epll = s5p_get_pll90xx(xtal, __raw_readl(S5P_EPLL_CON),
609 __raw_readl(S5P_EPLL_CON_K));
610 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
611 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502);
612
613 printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
614 " E=%ld.%ldMHz\n",
615 print_mhz(apll), print_mhz(mpll), print_mhz(epll));
616
617 fclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_ARM);
618 hclk = fclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK);
619 pclk = hclk / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK);
620
621 if (__raw_readl(S5P_OTHERS) & S5P_OTHERS_HCLK_LOW_SEL_MPLL) {
622 /* Asynchronous mode */
623 hclk_low = mpll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
624 } else {
625 /* Synchronous mode */
626 hclk_low = apll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
627 }
628
629 pclk_low = hclk_low / GET_DIV(clkdiv3, S5P_CLKDIV3_PCLK_LOW);
630
631 printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
632 " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
633 print_mhz(hclk), print_mhz(hclk_low),
634 print_mhz(pclk), print_mhz(pclk_low));
635
636 clk_fout_mpll.rate = mpll;
637 clk_fout_epll.rate = epll;
638 clk_fout_apll.rate = apll;
639
640 clk_f.rate = fclk;
641 clk_h.rate = hclk;
642 clk_p.rate = pclk;
643 clk_h_low.rate = hclk_low;
644 clk_p_low.rate = pclk_low;
645
1a0e8a52
KK
646 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
647 s3c_set_clksrc(&clksrcs[ptr], true);
648}
649
650static struct clk *clks[] __initdata = {
651 &clk_ext,
1a0e8a52
KK
652 &clk_iis_cd_v40,
653 &clk_pcm_cd,
654 &clk_p_low,
655 &clk_h_low,
656};
657
658void __init s5p6440_register_clocks(void)
659{
660 struct clk *clkp;
661 int ret;
662 int ptr;
663
664 ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
665 if (ret > 0)
666 printk(KERN_ERR "Failed to register %u clocks\n", ret);
667
fb049114
TA
668 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
669 s3c_register_clksrc(sysclks[ptr], 1);
670
1a0e8a52
KK
671 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
672 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
673
674 clkp = init_clocks_disable;
675 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
676
677 ret = s3c24xx_register_clock(clkp);
678 if (ret < 0) {
679 printk(KERN_ERR "Failed to register clock %s (%d)\n",
680 clkp->name, ret);
681 }
682 (clkp->enable)(clkp, 0);
683 }
684
685 s3c_pwmclk_init();
686}
This page took 0.061376 seconds and 5 git commands to generate.