blob: 16f0b907739073f254f0d69d471cc2e81add4fb8 [file] [log] [blame]
Byungho Minc1cc3db2009-06-23 21:39:56 +09001/* linux/arch/arm/plat-s5pc1xx/s5pc100-clock.c
2 *
3 * Copyright 2009 Samsung Electronics, Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 based common clock support
7 *
8 * Based on plat-s3c64xx/s3c6400-clock.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/list.h>
19#include <linux/errno.h>
20#include <linux/err.h>
21#include <linux/clk.h>
22#include <linux/sysdev.h>
23#include <linux/io.h>
24
25#include <mach/hardware.h>
26#include <mach/map.h>
27
28#include <plat/cpu-freq.h>
29
30#include <plat/regs-clock.h>
31#include <plat/clock.h>
32#include <plat/cpu.h>
33#include <plat/pll.h>
34#include <plat/devs.h>
35#include <plat/s5pc100.h>
36
37/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
38 * ext_xtal_mux for want of an actual name from the manual.
39*/
40
41static struct clk clk_ext_xtal_mux = {
42 .name = "ext_xtal",
43 .id = -1,
44};
45
46#define clk_fin_apll clk_ext_xtal_mux
47#define clk_fin_mpll clk_ext_xtal_mux
48#define clk_fin_epll clk_ext_xtal_mux
49#define clk_fin_hpll clk_ext_xtal_mux
50
51#define clk_fout_mpll clk_mpll
Kyungmin Parkff916f22009-11-17 08:41:13 +010052#define clk_vclk_54m clk_54m
Byungho Minc1cc3db2009-06-23 21:39:56 +090053
54struct clk_sources {
55 unsigned int nr_sources;
56 struct clk **sources;
57};
58
59struct clksrc_clk {
60 struct clk clk;
61 unsigned int mask;
62 unsigned int shift;
63
64 struct clk_sources *sources;
65
66 unsigned int divider_shift;
67 void __iomem *reg_divider;
68 void __iomem *reg_source;
69};
70
Kyungmin Parkff916f22009-11-17 08:41:13 +010071/* APLL */
Byungho Minc1cc3db2009-06-23 21:39:56 +090072static struct clk clk_fout_apll = {
73 .name = "fout_apll",
74 .id = -1,
Kyungmin Parkff916f22009-11-17 08:41:13 +010075 .rate = 27000000,
Byungho Minc1cc3db2009-06-23 21:39:56 +090076};
77
78static struct clk *clk_src_apll_list[] = {
79 [0] = &clk_fin_apll,
80 [1] = &clk_fout_apll,
81};
82
83static struct clk_sources clk_src_apll = {
84 .sources = clk_src_apll_list,
85 .nr_sources = ARRAY_SIZE(clk_src_apll_list),
86};
87
88static struct clksrc_clk clk_mout_apll = {
89 .clk = {
90 .name = "mout_apll",
91 .id = -1,
92 },
Kyungmin Park9ebaf2f2009-11-17 08:41:12 +010093 .shift = S5PC100_CLKSRC0_APLL_SHIFT,
94 .mask = S5PC100_CLKSRC0_APLL_MASK,
Byungho Minc1cc3db2009-06-23 21:39:56 +090095 .sources = &clk_src_apll,
Kyungmin Park9ebaf2f2009-11-17 08:41:12 +010096 .reg_source = S5PC100_CLKSRC0,
Byungho Minc1cc3db2009-06-23 21:39:56 +090097};
98
Kyungmin Parkff916f22009-11-17 08:41:13 +010099static unsigned long s5pc100_clk_dout_apll_get_rate(struct clk *clk)
100{
101 unsigned long rate = clk_get_rate(clk->parent);
102 unsigned int ratio;
103
104 ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_APLL_MASK;
105 ratio >>= S5PC100_CLKDIV0_APLL_SHIFT;
106
107 return rate / (ratio + 1);
108}
109
110static struct clk clk_dout_apll = {
111 .name = "dout_apll",
112 .id = -1,
113 .parent = &clk_mout_apll.clk,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000114 .ops = &(struct clk_ops) {
115 .get_rate = s5pc100_clk_dout_apll_get_rate,
116 },
Kyungmin Parkff916f22009-11-17 08:41:13 +0100117};
118
119static unsigned long s5pc100_clk_arm_get_rate(struct clk *clk)
120{
121 unsigned long rate = clk_get_rate(clk->parent);
122 unsigned int ratio;
123
124 ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_ARM_MASK;
125 ratio >>= S5PC100_CLKDIV0_ARM_SHIFT;
126
127 return rate / (ratio + 1);
128}
129
130static unsigned long s5pc100_clk_arm_round_rate(struct clk *clk,
131 unsigned long rate)
132{
133 unsigned long parent = clk_get_rate(clk->parent);
134 u32 div;
135
136 if (parent < rate)
137 return rate;
138
139 div = (parent / rate) - 1;
140 if (div > S5PC100_CLKDIV0_ARM_MASK)
141 div = S5PC100_CLKDIV0_ARM_MASK;
142
143 return parent / (div + 1);
144}
145
146static int s5pc100_clk_arm_set_rate(struct clk *clk, unsigned long rate)
147{
148 unsigned long parent = clk_get_rate(clk->parent);
149 u32 div;
150 u32 val;
151
152 if (rate < parent / (S5PC100_CLKDIV0_ARM_MASK + 1))
153 return -EINVAL;
154
155 rate = clk_round_rate(clk, rate);
156 div = clk_get_rate(clk->parent) / rate;
157
158 val = __raw_readl(S5PC100_CLKDIV0);
159 val &= S5PC100_CLKDIV0_ARM_MASK;
160 val |= (div - 1);
161 __raw_writel(val, S5PC100_CLKDIV0);
162
163 return 0;
164}
165
166static struct clk clk_arm = {
167 .name = "armclk",
168 .id = -1,
169 .parent = &clk_dout_apll,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000170 .ops = &(struct clk_ops) {
171 .get_rate = s5pc100_clk_arm_get_rate,
172 .set_rate = s5pc100_clk_arm_set_rate,
173 .round_rate = s5pc100_clk_arm_round_rate,
174 },
Kyungmin Parkff916f22009-11-17 08:41:13 +0100175};
176
177static unsigned long s5pc100_clk_dout_d0_bus_get_rate(struct clk *clk)
178{
179 unsigned long rate = clk_get_rate(clk->parent);
180 unsigned int ratio;
181
182 ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_D0_MASK;
183 ratio >>= S5PC100_CLKDIV0_D0_SHIFT;
184
185 return rate / (ratio + 1);
186}
187
188static struct clk clk_dout_d0_bus = {
189 .name = "dout_d0_bus",
190 .id = -1,
191 .parent = &clk_arm,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000192 .ops = &(struct clk_ops) {
193 .get_rate = s5pc100_clk_dout_d0_bus_get_rate,
194 },
Kyungmin Parkff916f22009-11-17 08:41:13 +0100195};
196
197static unsigned long s5pc100_clk_dout_pclkd0_get_rate(struct clk *clk)
198{
199 unsigned long rate = clk_get_rate(clk->parent);
200 unsigned int ratio;
201
202 ratio = __raw_readl(S5PC100_CLKDIV0) & S5PC100_CLKDIV0_PCLKD0_MASK;
203 ratio >>= S5PC100_CLKDIV0_PCLKD0_SHIFT;
204
205 return rate / (ratio + 1);
206}
207
208static struct clk clk_dout_pclkd0 = {
209 .name = "dout_pclkd0",
210 .id = -1,
211 .parent = &clk_dout_d0_bus,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000212 .ops = &(struct clk_ops) {
213 .get_rate = s5pc100_clk_dout_pclkd0_get_rate,
214 },
Kyungmin Parkff916f22009-11-17 08:41:13 +0100215};
216
217static unsigned long s5pc100_clk_dout_apll2_get_rate(struct clk *clk)
218{
219 unsigned long rate = clk_get_rate(clk->parent);
220 unsigned int ratio;
221
222 ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_APLL2_MASK;
223 ratio >>= S5PC100_CLKDIV1_APLL2_SHIFT;
224
225 return rate / (ratio + 1);
226}
227
228static struct clk clk_dout_apll2 = {
229 .name = "dout_apll2",
230 .id = -1,
231 .parent = &clk_mout_apll.clk,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000232 .ops = &(struct clk_ops) {
233 .get_rate = s5pc100_clk_dout_apll2_get_rate,
234 },
Kyungmin Parkff916f22009-11-17 08:41:13 +0100235};
236
237/* MPLL */
238static struct clk *clk_src_mpll_list[] = {
239 [0] = &clk_fin_mpll,
240 [1] = &clk_fout_mpll,
241};
242
243static struct clk_sources clk_src_mpll = {
244 .sources = clk_src_mpll_list,
245 .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
246};
247
248static struct clksrc_clk clk_mout_mpll = {
249 .clk = {
250 .name = "mout_mpll",
251 .id = -1,
252 },
253 .shift = S5PC100_CLKSRC0_MPLL_SHIFT,
254 .mask = S5PC100_CLKSRC0_MPLL_MASK,
255 .sources = &clk_src_mpll,
256 .reg_source = S5PC100_CLKSRC0,
257};
258
259static struct clk *clkset_am_list[] = {
260 [0] = &clk_mout_mpll.clk,
261 [1] = &clk_dout_apll2,
262};
263
264static struct clk_sources clk_src_am = {
265 .sources = clkset_am_list,
266 .nr_sources = ARRAY_SIZE(clkset_am_list),
267};
268
269static struct clksrc_clk clk_mout_am = {
270 .clk = {
271 .name = "mout_am",
272 .id = -1,
273 },
274 .shift = S5PC100_CLKSRC0_AMMUX_SHIFT,
275 .mask = S5PC100_CLKSRC0_AMMUX_MASK,
276 .sources = &clk_src_am,
277 .reg_source = S5PC100_CLKSRC0,
278};
279
280static unsigned long s5pc100_clk_dout_d1_bus_get_rate(struct clk *clk)
281{
282 unsigned long rate = clk_get_rate(clk->parent);
283 unsigned int ratio;
284
285 printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
286
287 ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_D1_MASK;
288 ratio >>= S5PC100_CLKDIV1_D1_SHIFT;
289
290 return rate / (ratio + 1);
291}
292
293static struct clk clk_dout_d1_bus = {
294 .name = "dout_d1_bus",
295 .id = -1,
296 .parent = &clk_mout_am.clk,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000297 .ops = &(struct clk_ops) {
298 .get_rate = s5pc100_clk_dout_d1_bus_get_rate,
299 },
Kyungmin Parkff916f22009-11-17 08:41:13 +0100300};
301
302static struct clk *clkset_onenand_list[] = {
303 [0] = &clk_dout_d0_bus,
304 [1] = &clk_dout_d1_bus,
305};
306
307static struct clk_sources clk_src_onenand = {
308 .sources = clkset_onenand_list,
309 .nr_sources = ARRAY_SIZE(clkset_onenand_list),
310};
311
312static struct clksrc_clk clk_mout_onenand = {
313 .clk = {
314 .name = "mout_onenand",
315 .id = -1,
316 },
317 .shift = S5PC100_CLKSRC0_ONENAND_SHIFT,
318 .mask = S5PC100_CLKSRC0_ONENAND_MASK,
319 .sources = &clk_src_onenand,
320 .reg_source = S5PC100_CLKSRC0,
321};
322
323static unsigned long s5pc100_clk_dout_pclkd1_get_rate(struct clk *clk)
324{
325 unsigned long rate = clk_get_rate(clk->parent);
326 unsigned int ratio;
327
328 printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
329
330 ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_PCLKD1_MASK;
331 ratio >>= S5PC100_CLKDIV1_PCLKD1_SHIFT;
332
333 return rate / (ratio + 1);
334}
335
336static struct clk clk_dout_pclkd1 = {
337 .name = "dout_pclkd1",
338 .id = -1,
339 .parent = &clk_dout_d1_bus,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000340 .ops = &(struct clk_ops) {
341 .get_rate = s5pc100_clk_dout_pclkd1_get_rate,
342 },
Kyungmin Parkff916f22009-11-17 08:41:13 +0100343};
344
345static unsigned long s5pc100_clk_dout_mpll2_get_rate(struct clk *clk)
346{
347 unsigned long rate = clk_get_rate(clk->parent);
348 unsigned int ratio;
349
350 printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
351
352 ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
353 ratio >>= S5PC100_CLKDIV1_MPLL2_SHIFT;
354
355 return rate / (ratio + 1);
356}
357
358static struct clk clk_dout_mpll2 = {
359 .name = "dout_mpll2",
360 .id = -1,
361 .parent = &clk_mout_am.clk,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000362 .ops = &(struct clk_ops) {
363 .get_rate = s5pc100_clk_dout_mpll2_get_rate,
364 },
Kyungmin Parkff916f22009-11-17 08:41:13 +0100365};
366
367static unsigned long s5pc100_clk_dout_cam_get_rate(struct clk *clk)
368{
369 unsigned long rate = clk_get_rate(clk->parent);
370 unsigned int ratio;
371
372 printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
373
374 ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_CAM_MASK;
375 ratio >>= S5PC100_CLKDIV1_CAM_SHIFT;
376
377 return rate / (ratio + 1);
378}
379
380static struct clk clk_dout_cam = {
381 .name = "dout_cam",
382 .id = -1,
383 .parent = &clk_dout_mpll2,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000384 .ops = &(struct clk_ops) {
385 .get_rate = s5pc100_clk_dout_cam_get_rate,
386 },
Kyungmin Parkff916f22009-11-17 08:41:13 +0100387};
388
389static unsigned long s5pc100_clk_dout_mpll_get_rate(struct clk *clk)
390{
391 unsigned long rate = clk_get_rate(clk->parent);
392 unsigned int ratio;
393
394 printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
395
396 ratio = __raw_readl(S5PC100_CLKDIV1) & S5PC100_CLKDIV1_MPLL_MASK;
397 ratio >>= S5PC100_CLKDIV1_MPLL_SHIFT;
398
399 return rate / (ratio + 1);
400}
401
402static struct clk clk_dout_mpll = {
403 .name = "dout_mpll",
404 .id = -1,
405 .parent = &clk_mout_am.clk,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000406 .ops = &(struct clk_ops) {
407 .get_rate = s5pc100_clk_dout_mpll_get_rate,
408 },
Kyungmin Parkff916f22009-11-17 08:41:13 +0100409};
410
411/* EPLL */
Byungho Minc1cc3db2009-06-23 21:39:56 +0900412static struct clk clk_fout_epll = {
413 .name = "fout_epll",
414 .id = -1,
415};
416
417static struct clk *clk_src_epll_list[] = {
418 [0] = &clk_fin_epll,
419 [1] = &clk_fout_epll,
420};
421
422static struct clk_sources clk_src_epll = {
423 .sources = clk_src_epll_list,
424 .nr_sources = ARRAY_SIZE(clk_src_epll_list),
425};
426
427static struct clksrc_clk clk_mout_epll = {
428 .clk = {
429 .name = "mout_epll",
430 .id = -1,
431 },
Kyungmin Park9ebaf2f2009-11-17 08:41:12 +0100432 .shift = S5PC100_CLKSRC0_EPLL_SHIFT,
433 .mask = S5PC100_CLKSRC0_EPLL_MASK,
Byungho Minc1cc3db2009-06-23 21:39:56 +0900434 .sources = &clk_src_epll,
Kyungmin Park9ebaf2f2009-11-17 08:41:12 +0100435 .reg_source = S5PC100_CLKSRC0,
Byungho Minc1cc3db2009-06-23 21:39:56 +0900436};
437
Kyungmin Parkff916f22009-11-17 08:41:13 +0100438/* HPLL */
439static struct clk clk_fout_hpll = {
440 .name = "fout_hpll",
441 .id = -1,
Byungho Minc1cc3db2009-06-23 21:39:56 +0900442};
443
Kyungmin Parkff916f22009-11-17 08:41:13 +0100444static struct clk *clk_src_hpll_list[] = {
445 [0] = &clk_27m,
446 [1] = &clk_fout_hpll,
Byungho Minc1cc3db2009-06-23 21:39:56 +0900447};
448
Kyungmin Parkff916f22009-11-17 08:41:13 +0100449static struct clk_sources clk_src_hpll = {
450 .sources = clk_src_hpll_list,
451 .nr_sources = ARRAY_SIZE(clk_src_hpll_list),
452};
453
454static struct clksrc_clk clk_mout_hpll = {
455 .clk = {
456 .name = "mout_hpll",
Byungho Minc1cc3db2009-06-23 21:39:56 +0900457 .id = -1,
458 },
Kyungmin Parkff916f22009-11-17 08:41:13 +0100459 .shift = S5PC100_CLKSRC0_HPLL_SHIFT,
460 .mask = S5PC100_CLKSRC0_HPLL_MASK,
461 .sources = &clk_src_hpll,
Kyungmin Park9ebaf2f2009-11-17 08:41:12 +0100462 .reg_source = S5PC100_CLKSRC0,
Byungho Minc1cc3db2009-06-23 21:39:56 +0900463};
464
Kyungmin Parkff916f22009-11-17 08:41:13 +0100465/* Peripherals */
466/*
467 * The peripheral clocks are all controlled via clocksource followed
468 * by an optional divider and gate stage. We currently roll this into
469 * one clock which hides the intermediate clock from the mux.
470 *
471 * Note, the JPEG clock can only be an even divider...
472 *
473 * The scaler and LCD clocks depend on the S5PC100 version, and also
474 * have a common parent divisor so are not included here.
475 */
Byungho Minc1cc3db2009-06-23 21:39:56 +0900476
477static inline struct clksrc_clk *to_clksrc(struct clk *clk)
478{
479 return container_of(clk, struct clksrc_clk, clk);
480}
481
Kyungmin Parkff916f22009-11-17 08:41:13 +0100482static unsigned long s5pc100_getrate_clksrc(struct clk *clk)
Byungho Minc1cc3db2009-06-23 21:39:56 +0900483{
484 struct clksrc_clk *sclk = to_clksrc(clk);
485 unsigned long rate = clk_get_rate(clk->parent);
486 u32 clkdiv = __raw_readl(sclk->reg_divider);
487
488 clkdiv >>= sclk->divider_shift;
489 clkdiv &= 0xf;
490 clkdiv++;
491
492 rate /= clkdiv;
493 return rate;
494}
495
Kyungmin Parkff916f22009-11-17 08:41:13 +0100496static int s5pc100_setrate_clksrc(struct clk *clk, unsigned long rate)
Byungho Minc1cc3db2009-06-23 21:39:56 +0900497{
498 struct clksrc_clk *sclk = to_clksrc(clk);
499 void __iomem *reg = sclk->reg_divider;
500 unsigned int div;
501 u32 val;
502
503 rate = clk_round_rate(clk, rate);
504 div = clk_get_rate(clk->parent) / rate;
505 if (div > 16)
506 return -EINVAL;
507
508 val = __raw_readl(reg);
Kyungmin Parkff916f22009-11-17 08:41:13 +0100509 val &= ~(0xf << sclk->divider_shift);
510 val |= (div - 1) << sclk->divider_shift;
Byungho Minc1cc3db2009-06-23 21:39:56 +0900511 __raw_writel(val, reg);
512
513 return 0;
514}
515
Kyungmin Parkff916f22009-11-17 08:41:13 +0100516static int s5pc100_setparent_clksrc(struct clk *clk, struct clk *parent)
Byungho Minc1cc3db2009-06-23 21:39:56 +0900517{
518 struct clksrc_clk *sclk = to_clksrc(clk);
519 struct clk_sources *srcs = sclk->sources;
520 u32 clksrc = __raw_readl(sclk->reg_source);
521 int src_nr = -1;
522 int ptr;
523
524 for (ptr = 0; ptr < srcs->nr_sources; ptr++)
525 if (srcs->sources[ptr] == parent) {
526 src_nr = ptr;
527 break;
528 }
529
530 if (src_nr >= 0) {
531 clksrc &= ~sclk->mask;
532 clksrc |= src_nr << sclk->shift;
533
534 __raw_writel(clksrc, sclk->reg_source);
535 return 0;
536 }
537
538 return -EINVAL;
539}
540
Kyungmin Parkff916f22009-11-17 08:41:13 +0100541static unsigned long s5pc100_roundrate_clksrc(struct clk *clk,
Byungho Minc1cc3db2009-06-23 21:39:56 +0900542 unsigned long rate)
543{
544 unsigned long parent_rate = clk_get_rate(clk->parent);
545 int div;
546
547 if (rate > parent_rate)
548 rate = parent_rate;
549 else {
550 div = rate / parent_rate;
551
552 if (div == 0)
553 div = 1;
554 if (div > 16)
555 div = 16;
556
557 rate = parent_rate / div;
558 }
559
560 return rate;
561}
562
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000563static struct clk_ops s5pc100_clksrc_ops = {
564 .set_parent = s5pc100_setparent_clksrc,
565 .get_rate = s5pc100_getrate_clksrc,
566 .set_rate = s5pc100_setrate_clksrc,
567 .round_rate = s5pc100_roundrate_clksrc,
568};
569
Kyungmin Parkff916f22009-11-17 08:41:13 +0100570static struct clk *clkset_spi_list[] = {
571 &clk_mout_epll.clk,
572 &clk_dout_mpll2,
573 &clk_fin_epll,
574 &clk_mout_hpll.clk,
575};
576
577static struct clk_sources clkset_spi = {
578 .sources = clkset_spi_list,
579 .nr_sources = ARRAY_SIZE(clkset_spi_list),
580};
581
582static struct clksrc_clk clk_spi0 = {
583 .clk = {
584 .name = "spi_bus",
585 .id = 0,
586 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI0,
587 .enable = s5pc100_sclk0_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000588
Kyungmin Parkff916f22009-11-17 08:41:13 +0100589 },
590 .shift = S5PC100_CLKSRC1_SPI0_SHIFT,
591 .mask = S5PC100_CLKSRC1_SPI0_MASK,
592 .sources = &clkset_spi,
593 .divider_shift = S5PC100_CLKDIV2_SPI0_SHIFT,
594 .reg_divider = S5PC100_CLKDIV2,
595 .reg_source = S5PC100_CLKSRC1,
596};
597
598static struct clksrc_clk clk_spi1 = {
599 .clk = {
600 .name = "spi_bus",
601 .id = 1,
602 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI1,
603 .enable = s5pc100_sclk0_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000604 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100605 },
606 .shift = S5PC100_CLKSRC1_SPI1_SHIFT,
607 .mask = S5PC100_CLKSRC1_SPI1_MASK,
608 .sources = &clkset_spi,
609 .divider_shift = S5PC100_CLKDIV2_SPI1_SHIFT,
610 .reg_divider = S5PC100_CLKDIV2,
611 .reg_source = S5PC100_CLKSRC1,
612};
613
614static struct clksrc_clk clk_spi2 = {
615 .clk = {
616 .name = "spi_bus",
617 .id = 2,
618 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI2,
619 .enable = s5pc100_sclk0_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000620 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100621 },
622 .shift = S5PC100_CLKSRC1_SPI2_SHIFT,
623 .mask = S5PC100_CLKSRC1_SPI2_MASK,
624 .sources = &clkset_spi,
625 .divider_shift = S5PC100_CLKDIV2_SPI2_SHIFT,
626 .reg_divider = S5PC100_CLKDIV2,
627 .reg_source = S5PC100_CLKSRC1,
628};
629
630static struct clk *clkset_uart_list[] = {
631 &clk_mout_epll.clk,
632 &clk_dout_mpll,
633};
634
635static struct clk_sources clkset_uart = {
636 .sources = clkset_uart_list,
637 .nr_sources = ARRAY_SIZE(clkset_uart_list),
638};
639
Byungho Minc1cc3db2009-06-23 21:39:56 +0900640static struct clksrc_clk clk_uart_uclk1 = {
641 .clk = {
642 .name = "uclk1",
643 .id = -1,
644 .ctrlbit = S5PC100_CLKGATE_SCLK0_UART,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100645 .enable = s5pc100_sclk0_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000646 .ops = &s5pc100_clksrc_ops,
Byungho Minc1cc3db2009-06-23 21:39:56 +0900647 },
648 .shift = S5PC100_CLKSRC1_UART_SHIFT,
649 .mask = S5PC100_CLKSRC1_UART_MASK,
650 .sources = &clkset_uart,
651 .divider_shift = S5PC100_CLKDIV2_UART_SHIFT,
Kyungmin Park9ebaf2f2009-11-17 08:41:12 +0100652 .reg_divider = S5PC100_CLKDIV2,
653 .reg_source = S5PC100_CLKSRC1,
Byungho Minc1cc3db2009-06-23 21:39:56 +0900654};
655
Kyungmin Parkff916f22009-11-17 08:41:13 +0100656static struct clk clk_iis_cd0 = {
657 .name = "iis_cdclk0",
658 .id = -1,
659};
660
661static struct clk clk_iis_cd1 = {
662 .name = "iis_cdclk1",
663 .id = -1,
664};
665
666static struct clk clk_iis_cd2 = {
667 .name = "iis_cdclk2",
668 .id = -1,
669};
670
671static struct clk clk_pcm_cd0 = {
672 .name = "pcm_cdclk0",
673 .id = -1,
674};
675
676static struct clk clk_pcm_cd1 = {
677 .name = "pcm_cdclk1",
678 .id = -1,
679};
680
681static struct clk *clkset_audio0_list[] = {
682 &clk_mout_epll.clk,
683 &clk_dout_mpll,
684 &clk_fin_epll,
685 &clk_iis_cd0,
686 &clk_pcm_cd0,
687 &clk_mout_hpll.clk,
688};
689
690static struct clk_sources clkset_audio0 = {
691 .sources = clkset_audio0_list,
692 .nr_sources = ARRAY_SIZE(clkset_audio0_list),
693};
694
695static struct clksrc_clk clk_audio0 = {
696 .clk = {
697 .name = "audio-bus",
698 .id = 0,
699 .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO0,
700 .enable = s5pc100_sclk1_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000701 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100702 },
703 .shift = S5PC100_CLKSRC3_AUDIO0_SHIFT,
704 .mask = S5PC100_CLKSRC3_AUDIO0_MASK,
705 .sources = &clkset_audio0,
706 .divider_shift = S5PC100_CLKDIV4_AUDIO0_SHIFT,
707 .reg_divider = S5PC100_CLKDIV4,
708 .reg_source = S5PC100_CLKSRC3,
709};
710
711static struct clk *clkset_audio1_list[] = {
712 &clk_mout_epll.clk,
713 &clk_dout_mpll,
714 &clk_fin_epll,
715 &clk_iis_cd1,
716 &clk_pcm_cd1,
717 &clk_mout_hpll.clk,
718};
719
720static struct clk_sources clkset_audio1 = {
721 .sources = clkset_audio1_list,
722 .nr_sources = ARRAY_SIZE(clkset_audio1_list),
723};
724
725static struct clksrc_clk clk_audio1 = {
726 .clk = {
727 .name = "audio-bus",
728 .id = 1,
729 .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO1,
730 .enable = s5pc100_sclk1_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000731 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100732 },
733 .shift = S5PC100_CLKSRC3_AUDIO1_SHIFT,
734 .mask = S5PC100_CLKSRC3_AUDIO1_MASK,
735 .sources = &clkset_audio1,
736 .divider_shift = S5PC100_CLKDIV4_AUDIO1_SHIFT,
737 .reg_divider = S5PC100_CLKDIV4,
738 .reg_source = S5PC100_CLKSRC3,
739};
740
741static struct clk *clkset_audio2_list[] = {
742 &clk_mout_epll.clk,
743 &clk_dout_mpll,
744 &clk_fin_epll,
745 &clk_iis_cd2,
746 &clk_mout_hpll.clk,
747};
748
749static struct clk_sources clkset_audio2 = {
750 .sources = clkset_audio2_list,
751 .nr_sources = ARRAY_SIZE(clkset_audio2_list),
752};
753
754static struct clksrc_clk clk_audio2 = {
755 .clk = {
756 .name = "audio-bus",
757 .id = 2,
758 .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO2,
759 .enable = s5pc100_sclk1_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000760 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100761 },
762 .shift = S5PC100_CLKSRC3_AUDIO2_SHIFT,
763 .mask = S5PC100_CLKSRC3_AUDIO2_MASK,
764 .sources = &clkset_audio2,
765 .divider_shift = S5PC100_CLKDIV4_AUDIO2_SHIFT,
766 .reg_divider = S5PC100_CLKDIV4,
767 .reg_source = S5PC100_CLKSRC3,
768};
769
770static struct clk *clkset_spdif_list[] = {
771 &clk_audio0.clk,
772 &clk_audio1.clk,
773 &clk_audio2.clk,
774};
775
776static struct clk_sources clkset_spdif = {
777 .sources = clkset_spdif_list,
778 .nr_sources = ARRAY_SIZE(clkset_spdif_list),
779};
780
781static struct clksrc_clk clk_spdif = {
782 .clk = {
783 .name = "spdif",
784 .id = -1,
785 },
786 .shift = S5PC100_CLKSRC3_SPDIF_SHIFT,
787 .mask = S5PC100_CLKSRC3_SPDIF_MASK,
788 .sources = &clkset_spdif,
789 .reg_source = S5PC100_CLKSRC3,
790};
791
792static struct clk *clkset_lcd_fimc_list[] = {
793 &clk_mout_epll.clk,
794 &clk_dout_mpll,
795 &clk_mout_hpll.clk,
796 &clk_vclk_54m,
797};
798
799static struct clk_sources clkset_lcd_fimc = {
800 .sources = clkset_lcd_fimc_list,
801 .nr_sources = ARRAY_SIZE(clkset_lcd_fimc_list),
802};
803
804static struct clksrc_clk clk_lcd = {
805 .clk = {
806 .name = "lcd",
807 .id = -1,
808 .ctrlbit = S5PC100_CLKGATE_SCLK1_LCD,
809 .enable = s5pc100_sclk1_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000810 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100811 },
812 .shift = S5PC100_CLKSRC2_LCD_SHIFT,
813 .mask = S5PC100_CLKSRC2_LCD_MASK,
814 .sources = &clkset_lcd_fimc,
815 .divider_shift = S5PC100_CLKDIV3_LCD_SHIFT,
816 .reg_divider = S5PC100_CLKDIV3,
817 .reg_source = S5PC100_CLKSRC2,
818};
819
820static struct clksrc_clk clk_fimc0 = {
821 .clk = {
822 .name = "fimc",
823 .id = 0,
824 .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC0,
825 .enable = s5pc100_sclk1_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000826 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100827 },
828 .shift = S5PC100_CLKSRC2_FIMC0_SHIFT,
829 .mask = S5PC100_CLKSRC2_FIMC0_MASK,
830 .sources = &clkset_lcd_fimc,
831 .divider_shift = S5PC100_CLKDIV3_FIMC0_SHIFT,
832 .reg_divider = S5PC100_CLKDIV3,
833 .reg_source = S5PC100_CLKSRC2,
834};
835
836static struct clksrc_clk clk_fimc1 = {
837 .clk = {
838 .name = "fimc",
839 .id = 1,
840 .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC1,
841 .enable = s5pc100_sclk1_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000842 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100843 },
844 .shift = S5PC100_CLKSRC2_FIMC1_SHIFT,
845 .mask = S5PC100_CLKSRC2_FIMC1_MASK,
846 .sources = &clkset_lcd_fimc,
847 .divider_shift = S5PC100_CLKDIV3_FIMC1_SHIFT,
848 .reg_divider = S5PC100_CLKDIV3,
849 .reg_source = S5PC100_CLKSRC2,
850};
851
852static struct clksrc_clk clk_fimc2 = {
853 .clk = {
854 .name = "fimc",
855 .id = 2,
856 .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC2,
857 .enable = s5pc100_sclk1_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000858 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100859 },
860 .shift = S5PC100_CLKSRC2_FIMC2_SHIFT,
861 .mask = S5PC100_CLKSRC2_FIMC2_MASK,
862 .sources = &clkset_lcd_fimc,
863 .divider_shift = S5PC100_CLKDIV3_FIMC2_SHIFT,
864 .reg_divider = S5PC100_CLKDIV3,
865 .reg_source = S5PC100_CLKSRC2,
866};
867
868static struct clk *clkset_mmc_list[] = {
869 &clk_mout_epll.clk,
870 &clk_dout_mpll,
871 &clk_fin_epll,
872 &clk_mout_hpll.clk ,
873};
874
875static struct clk_sources clkset_mmc = {
876 .sources = clkset_mmc_list,
877 .nr_sources = ARRAY_SIZE(clkset_mmc_list),
878};
879
880static struct clksrc_clk clk_mmc0 = {
881 .clk = {
882 .name = "mmc_bus",
883 .id = 0,
884 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC0,
885 .enable = s5pc100_sclk0_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000886 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100887 },
888 .shift = S5PC100_CLKSRC2_MMC0_SHIFT,
889 .mask = S5PC100_CLKSRC2_MMC0_MASK,
890 .sources = &clkset_mmc,
891 .divider_shift = S5PC100_CLKDIV3_MMC0_SHIFT,
892 .reg_divider = S5PC100_CLKDIV3,
893 .reg_source = S5PC100_CLKSRC2,
894};
895
896static struct clksrc_clk clk_mmc1 = {
897 .clk = {
898 .name = "mmc_bus",
899 .id = 1,
900 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC1,
901 .enable = s5pc100_sclk0_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000902 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100903 },
904 .shift = S5PC100_CLKSRC2_MMC1_SHIFT,
905 .mask = S5PC100_CLKSRC2_MMC1_MASK,
906 .sources = &clkset_mmc,
907 .divider_shift = S5PC100_CLKDIV3_MMC1_SHIFT,
908 .reg_divider = S5PC100_CLKDIV3,
909 .reg_source = S5PC100_CLKSRC2,
910};
911
912static struct clksrc_clk clk_mmc2 = {
913 .clk = {
914 .name = "mmc_bus",
915 .id = 2,
916 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC2,
917 .enable = s5pc100_sclk0_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000918 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100919 },
920 .shift = S5PC100_CLKSRC2_MMC2_SHIFT,
921 .mask = S5PC100_CLKSRC2_MMC2_MASK,
922 .sources = &clkset_mmc,
923 .divider_shift = S5PC100_CLKDIV3_MMC2_SHIFT,
924 .reg_divider = S5PC100_CLKDIV3,
925 .reg_source = S5PC100_CLKSRC2,
926};
927
928
929static struct clk *clkset_usbhost_list[] = {
930 &clk_mout_epll.clk,
931 &clk_dout_mpll,
932 &clk_mout_hpll.clk,
933 &clk_48m,
934};
935
936static struct clk_sources clkset_usbhost = {
937 .sources = clkset_usbhost_list,
938 .nr_sources = ARRAY_SIZE(clkset_usbhost_list),
939};
940
941static struct clksrc_clk clk_usbhost = {
942 .clk = {
943 .name = "usbhost",
944 .id = -1,
945 .ctrlbit = S5PC100_CLKGATE_SCLK0_USBHOST,
946 .enable = s5pc100_sclk0_ctrl,
Ben Dooksb3bf41b2009-12-01 01:24:37 +0000947 .ops = &s5pc100_clksrc_ops,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100948 },
949 .shift = S5PC100_CLKSRC1_UHOST_SHIFT,
950 .mask = S5PC100_CLKSRC1_UHOST_MASK,
951 .sources = &clkset_usbhost,
952 .divider_shift = S5PC100_CLKDIV2_UHOST_SHIFT,
953 .reg_divider = S5PC100_CLKDIV2,
954 .reg_source = S5PC100_CLKSRC1,
955};
956
Byungho Minc1cc3db2009-06-23 21:39:56 +0900957/* Clock initialisation code */
958
959static struct clksrc_clk *init_parents[] = {
960 &clk_mout_apll,
Byungho Minc1cc3db2009-06-23 21:39:56 +0900961 &clk_mout_mpll,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100962 &clk_mout_am,
963 &clk_mout_onenand,
964 &clk_mout_epll,
965 &clk_mout_hpll,
966 &clk_spi0,
967 &clk_spi1,
968 &clk_spi2,
Byungho Minc1cc3db2009-06-23 21:39:56 +0900969 &clk_uart_uclk1,
Kyungmin Parkff916f22009-11-17 08:41:13 +0100970 &clk_audio0,
971 &clk_audio1,
972 &clk_audio2,
973 &clk_spdif,
974 &clk_lcd,
975 &clk_fimc0,
976 &clk_fimc1,
977 &clk_fimc2,
978 &clk_mmc0,
979 &clk_mmc1,
980 &clk_mmc2,
981 &clk_usbhost,
Byungho Minc1cc3db2009-06-23 21:39:56 +0900982};
983
Kyungmin Parkff916f22009-11-17 08:41:13 +0100984static void __init_or_cpufreq s5pc100_set_clksrc(struct clksrc_clk *clk)
Byungho Minc1cc3db2009-06-23 21:39:56 +0900985{
986 struct clk_sources *srcs = clk->sources;
987 u32 clksrc = __raw_readl(clk->reg_source);
988
989 clksrc &= clk->mask;
990 clksrc >>= clk->shift;
991
992 if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
993 printk(KERN_ERR "%s: bad source %d\n",
994 clk->clk.name, clksrc);
995 return;
996 }
997
998 clk->clk.parent = srcs->sources[clksrc];
999
Kyungmin Parkff916f22009-11-17 08:41:13 +01001000 printk(KERN_INFO "%s: source is %s (%d), rate is %ld.%03ld MHz\n",
1001 clk->clk.name, clk->clk.parent->name, clksrc,
1002 print_mhz(clk_get_rate(&clk->clk)));
Byungho Minc1cc3db2009-06-23 21:39:56 +09001003}
1004
1005#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
1006
1007void __init_or_cpufreq s5pc100_setup_clocks(void)
1008{
1009 struct clk *xtal_clk;
1010 unsigned long xtal;
1011 unsigned long armclk;
1012 unsigned long hclkd0;
1013 unsigned long hclk;
1014 unsigned long pclkd0;
1015 unsigned long pclk;
Kyungmin Parkff916f22009-11-17 08:41:13 +01001016 unsigned long apll, mpll, epll, hpll;
Byungho Minc1cc3db2009-06-23 21:39:56 +09001017 unsigned int ptr;
1018 u32 clkdiv0, clkdiv1;
1019
1020 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1021
Kyungmin Park9ebaf2f2009-11-17 08:41:12 +01001022 clkdiv0 = __raw_readl(S5PC100_CLKDIV0);
1023 clkdiv1 = __raw_readl(S5PC100_CLKDIV1);
Byungho Minc1cc3db2009-06-23 21:39:56 +09001024
Kyungmin Parkff916f22009-11-17 08:41:13 +01001025 printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n", __func__, clkdiv0, clkdiv1);
Byungho Minc1cc3db2009-06-23 21:39:56 +09001026
1027 xtal_clk = clk_get(NULL, "xtal");
1028 BUG_ON(IS_ERR(xtal_clk));
1029
1030 xtal = clk_get_rate(xtal_clk);
1031 clk_put(xtal_clk);
1032
1033 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1034
Kyungmin Park9ebaf2f2009-11-17 08:41:12 +01001035 apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_APLL_CON));
1036 mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_MPLL_CON));
1037 epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_EPLL_CON));
Byungho Minc1cc3db2009-06-23 21:39:56 +09001038 hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON));
1039
Kyungmin Parkff916f22009-11-17 08:41:13 +01001040 printk(KERN_INFO "S5PC100: Apll=%ld.%03ld Mhz, Mpll=%ld.%03ld Mhz"
1041 ", Epll=%ld.%03ld Mhz, Hpll=%ld.%03ld Mhz\n",
1042 print_mhz(apll), print_mhz(mpll),
1043 print_mhz(epll), print_mhz(hpll));
Byungho Minc1cc3db2009-06-23 21:39:56 +09001044
Kyungmin Park9ebaf2f2009-11-17 08:41:12 +01001045 armclk = apll / GET_DIV(clkdiv0, S5PC100_CLKDIV0_APLL);
Byungho Minc1cc3db2009-06-23 21:39:56 +09001046 armclk = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_ARM);
1047 hclkd0 = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_D0);
1048 pclkd0 = hclkd0 / GET_DIV(clkdiv0, S5PC100_CLKDIV0_PCLKD0);
1049 hclk = mpll / GET_DIV(clkdiv1, S5PC100_CLKDIV1_D1);
1050 pclk = hclk / GET_DIV(clkdiv1, S5PC100_CLKDIV1_PCLKD1);
1051
Kyungmin Parkff916f22009-11-17 08:41:13 +01001052 printk(KERN_INFO "S5PC100: ARMCLK=%ld.%03ld MHz, HCLKD0=%ld.%03ld MHz,"
1053 " PCLKD0=%ld.%03ld MHz\n, HCLK=%ld.%03ld MHz,"
1054 " PCLK=%ld.%03ld MHz\n",
1055 print_mhz(armclk), print_mhz(hclkd0),
1056 print_mhz(pclkd0), print_mhz(hclk), print_mhz(pclk));
Byungho Minc1cc3db2009-06-23 21:39:56 +09001057
1058 clk_fout_apll.rate = apll;
1059 clk_fout_mpll.rate = mpll;
1060 clk_fout_epll.rate = epll;
Kyungmin Parkff916f22009-11-17 08:41:13 +01001061 clk_fout_hpll.rate = hpll;
Byungho Minc1cc3db2009-06-23 21:39:56 +09001062
1063 clk_h.rate = hclk;
1064 clk_p.rate = pclk;
Kyungmin Parkff916f22009-11-17 08:41:13 +01001065 clk_f.rate = armclk;
Byungho Minc1cc3db2009-06-23 21:39:56 +09001066
1067 for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
Kyungmin Parkff916f22009-11-17 08:41:13 +01001068 s5pc100_set_clksrc(init_parents[ptr]);
Byungho Minc1cc3db2009-06-23 21:39:56 +09001069}
1070
1071static struct clk *clks[] __initdata = {
1072 &clk_ext_xtal_mux,
Kyungmin Parkff916f22009-11-17 08:41:13 +01001073 &clk_mout_apll.clk,
1074 &clk_dout_apll,
1075 &clk_dout_d0_bus,
1076 &clk_dout_pclkd0,
1077 &clk_dout_apll2,
1078 &clk_mout_mpll.clk,
1079 &clk_mout_am.clk,
1080 &clk_dout_d1_bus,
1081 &clk_mout_onenand.clk,
1082 &clk_dout_pclkd1,
1083 &clk_dout_mpll2,
1084 &clk_dout_cam,
1085 &clk_dout_mpll,
Byungho Minc1cc3db2009-06-23 21:39:56 +09001086 &clk_mout_epll.clk,
1087 &clk_fout_epll,
Kyungmin Parkff916f22009-11-17 08:41:13 +01001088 &clk_iis_cd0,
1089 &clk_iis_cd1,
1090 &clk_iis_cd2,
1091 &clk_pcm_cd0,
1092 &clk_pcm_cd1,
1093 &clk_spi0.clk,
1094 &clk_spi1.clk,
1095 &clk_spi2.clk,
Byungho Minc1cc3db2009-06-23 21:39:56 +09001096 &clk_uart_uclk1.clk,
Kyungmin Parkff916f22009-11-17 08:41:13 +01001097 &clk_audio0.clk,
1098 &clk_audio1.clk,
1099 &clk_audio2.clk,
1100 &clk_spdif.clk,
1101 &clk_lcd.clk,
1102 &clk_fimc0.clk,
1103 &clk_fimc1.clk,
1104 &clk_fimc2.clk,
1105 &clk_mmc0.clk,
1106 &clk_mmc1.clk,
1107 &clk_mmc2.clk,
1108 &clk_usbhost.clk,
1109 &clk_arm,
Byungho Minc1cc3db2009-06-23 21:39:56 +09001110};
1111
1112void __init s5pc100_register_clocks(void)
1113{
1114 struct clk *clkp;
1115 int ret;
1116 int ptr;
1117
1118 for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
1119 clkp = clks[ptr];
1120 ret = s3c24xx_register_clock(clkp);
1121 if (ret < 0) {
1122 printk(KERN_ERR "Failed to register clock %s (%d)\n",
1123 clkp->name, ret);
1124 }
1125 }
Byungho Minc1cc3db2009-06-23 21:39:56 +09001126}