blob: 95c6d46c3dd64b0d9ba8208071097a72899431db [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* linux/arch/arm/mach-s3c2410/clock.c
2 *
3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 Clock control support
7 *
8 * Based on, and code from linux/arch/arm/mach-versatile/clock.c
9 **
10 ** Copyright (C) 2004 ARM Limited.
11 ** Written by Deep Blue Solutions Limited.
12 *
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27*/
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/list.h>
33#include <linux/errno.h>
34#include <linux/err.h>
Russell Kingd052d1b2005-10-29 19:07:23 +010035#include <linux/platform_device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include <linux/sysdev.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <linux/interrupt.h>
38#include <linux/ioport.h>
Russell Kingf8ce2542006-01-07 16:15:52 +000039#include <linux/clk.h>
Arjan van de Ven00431702006-01-12 18:42:23 +000040#include <linux/mutex.h>
Ben Dooks8e40a2f2006-03-20 17:10:04 +000041#include <linux/delay.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
43#include <asm/hardware.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <asm/irq.h>
45#include <asm/io.h>
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <asm/arch/regs-clock.h>
Ben Dooks3fc3e1c2006-03-20 17:10:07 +000048#include <asm/arch/regs-gpio.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
50#include "clock.h"
51#include "cpu.h"
52
53/* clock information */
54
55static LIST_HEAD(clocks);
Arjan van de Ven00431702006-01-12 18:42:23 +000056static DEFINE_MUTEX(clocks_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
58/* old functions */
59
60void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
61{
62 unsigned long clkcon;
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
64 clkcon = __raw_readl(S3C2410_CLKCON);
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
66 if (enable)
67 clkcon |= clocks;
Ben Dooks2a513ce2006-02-08 21:09:05 +000068 else
69 clkcon &= ~clocks;
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
71 /* ensure none of the special function bits set */
72 clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
73
74 __raw_writel(clkcon, S3C2410_CLKCON);
Linus Torvalds1da177e2005-04-16 15:20:36 -070075}
76
77/* enable and disable calls for use with the clk struct */
78
79static int clk_null_enable(struct clk *clk, int enable)
80{
81 return 0;
82}
83
84int s3c24xx_clkcon_enable(struct clk *clk, int enable)
85{
86 s3c24xx_clk_enable(clk->ctrlbit, enable);
87 return 0;
88}
89
90/* Clock API calls */
91
92struct clk *clk_get(struct device *dev, const char *id)
93{
94 struct clk *p;
95 struct clk *clk = ERR_PTR(-ENOENT);
96 int idno;
97
Ben Dooksc086f282005-10-18 07:51:34 +010098 if (dev == NULL || dev->bus != &platform_bus_type)
99 idno = -1;
100 else
101 idno = to_platform_device(dev)->id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Arjan van de Ven00431702006-01-12 18:42:23 +0000103 mutex_lock(&clocks_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
105 list_for_each_entry(p, &clocks, list) {
106 if (p->id == idno &&
107 strcmp(id, p->name) == 0 &&
108 try_module_get(p->owner)) {
109 clk = p;
110 break;
111 }
112 }
113
114 /* check for the case where a device was supplied, but the
115 * clock that was being searched for is not device specific */
116
117 if (IS_ERR(clk)) {
118 list_for_each_entry(p, &clocks, list) {
119 if (p->id == -1 && strcmp(id, p->name) == 0 &&
120 try_module_get(p->owner)) {
121 clk = p;
122 break;
123 }
124 }
125 }
126
Arjan van de Ven00431702006-01-12 18:42:23 +0000127 mutex_unlock(&clocks_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 return clk;
129}
130
131void clk_put(struct clk *clk)
132{
133 module_put(clk->owner);
134}
135
136int clk_enable(struct clk *clk)
137{
Ben Dooks2a513ce2006-02-08 21:09:05 +0000138 if (IS_ERR(clk) || clk == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 return -EINVAL;
140
Ben Dooks2a513ce2006-02-08 21:09:05 +0000141 clk_enable(clk->parent);
142
143 mutex_lock(&clocks_mutex);
144
145 if ((clk->usage++) == 0)
146 (clk->enable)(clk, 1);
147
148 mutex_unlock(&clocks_mutex);
149 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150}
151
152void clk_disable(struct clk *clk)
153{
Ben Dooks2a513ce2006-02-08 21:09:05 +0000154 if (IS_ERR(clk) || clk == NULL)
155 return;
156
157 mutex_lock(&clocks_mutex);
158
159 if ((--clk->usage) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 (clk->enable)(clk, 0);
Ben Dooks2a513ce2006-02-08 21:09:05 +0000161
162 mutex_unlock(&clocks_mutex);
163 clk_disable(clk->parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164}
165
166
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167unsigned long clk_get_rate(struct clk *clk)
168{
169 if (IS_ERR(clk))
170 return 0;
171
172 if (clk->rate != 0)
173 return clk->rate;
174
175 while (clk->parent != NULL && clk->rate == 0)
176 clk = clk->parent;
177
178 return clk->rate;
179}
180
181long clk_round_rate(struct clk *clk, unsigned long rate)
182{
Ben Dooks6e8908e2006-03-20 21:00:08 +0000183 if (!IS_ERR(clk) && clk->round_rate)
184 return (clk->round_rate)(clk, rate);
185
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 return rate;
187}
188
189int clk_set_rate(struct clk *clk, unsigned long rate)
190{
Ben Dooks6e8908e2006-03-20 21:00:08 +0000191 int ret;
192
193 if (IS_ERR(clk))
194 return -EINVAL;
195
196 mutex_lock(&clocks_mutex);
197 ret = (clk->set_rate)(clk, rate);
198 mutex_unlock(&clocks_mutex);
199
200 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201}
202
203struct clk *clk_get_parent(struct clk *clk)
204{
205 return clk->parent;
206}
207
Ben Dooksd3468da2006-03-20 17:10:04 +0000208int clk_set_parent(struct clk *clk, struct clk *parent)
209{
210 int ret = 0;
211
212 if (IS_ERR(clk))
213 return -EINVAL;
214
215 mutex_lock(&clocks_mutex);
216
217 if (clk->set_parent)
218 ret = (clk->set_parent)(clk, parent);
219
220 mutex_unlock(&clocks_mutex);
221
222 return ret;
223}
224
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225EXPORT_SYMBOL(clk_get);
226EXPORT_SYMBOL(clk_put);
227EXPORT_SYMBOL(clk_enable);
228EXPORT_SYMBOL(clk_disable);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229EXPORT_SYMBOL(clk_get_rate);
230EXPORT_SYMBOL(clk_round_rate);
231EXPORT_SYMBOL(clk_set_rate);
232EXPORT_SYMBOL(clk_get_parent);
Ben Dooksd3468da2006-03-20 17:10:04 +0000233EXPORT_SYMBOL(clk_set_parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234
Ben Dooks8e40a2f2006-03-20 17:10:04 +0000235/* base clock enable */
236
237static int s3c24xx_upll_enable(struct clk *clk, int enable)
238{
239 unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
240 unsigned long orig = clkslow;
241
242 if (enable)
243 clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
244 else
245 clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
246
247 __raw_writel(clkslow, S3C2410_CLKSLOW);
248
249 /* if we started the UPLL, then allow to settle */
250
251 if (enable && !(orig & S3C2410_CLKSLOW_UCLK_OFF))
252 udelay(200);
253
254 return 0;
255}
256
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257/* base clocks */
258
259static struct clk clk_xtal = {
260 .name = "xtal",
261 .id = -1,
262 .rate = 0,
263 .parent = NULL,
264 .ctrlbit = 0,
265};
266
Ben Dooks8e40a2f2006-03-20 17:10:04 +0000267static struct clk clk_upll = {
268 .name = "upll",
269 .id = -1,
270 .parent = NULL,
271 .enable = s3c24xx_upll_enable,
272 .ctrlbit = 0,
273};
274
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275static struct clk clk_f = {
276 .name = "fclk",
277 .id = -1,
278 .rate = 0,
279 .parent = NULL,
280 .ctrlbit = 0,
281};
282
283static struct clk clk_h = {
284 .name = "hclk",
285 .id = -1,
286 .rate = 0,
287 .parent = NULL,
288 .ctrlbit = 0,
289};
290
291static struct clk clk_p = {
292 .name = "pclk",
293 .id = -1,
294 .rate = 0,
295 .parent = NULL,
296 .ctrlbit = 0,
297};
298
299/* clocks that could be registered by external code */
300
Ben Dooks3fc3e1c2006-03-20 17:10:07 +0000301static int s3c24xx_dclk_enable(struct clk *clk, int enable)
302{
303 unsigned long dclkcon = __raw_readl(S3C2410_DCLKCON);
304
305 if (enable)
306 dclkcon |= clk->ctrlbit;
307 else
308 dclkcon &= ~clk->ctrlbit;
309
310 __raw_writel(dclkcon, S3C2410_DCLKCON);
311
312 return 0;
313}
314
315static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
316{
317 unsigned long dclkcon;
318 unsigned int uclk;
319
320 if (parent == &clk_upll)
321 uclk = 1;
322 else if (parent == &clk_p)
323 uclk = 0;
324 else
325 return -EINVAL;
326
327 clk->parent = parent;
328
329 dclkcon = __raw_readl(S3C2410_DCLKCON);
330
331 if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
332 if (uclk)
333 dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
334 else
335 dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
336 } else {
337 if (uclk)
338 dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
339 else
340 dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
341 }
342
343 __raw_writel(dclkcon, S3C2410_DCLKCON);
344
345 return 0;
346}
347
348
349static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
350{
351 unsigned long mask;
352 unsigned long source;
353
354 /* calculate the MISCCR setting for the clock */
355
356 if (parent == &clk_xtal)
357 source = S3C2410_MISCCR_CLK0_MPLL;
358 else if (parent == &clk_upll)
359 source = S3C2410_MISCCR_CLK0_UPLL;
360 else if (parent == &clk_f)
361 source = S3C2410_MISCCR_CLK0_FCLK;
362 else if (parent == &clk_p)
363 source = S3C2410_MISCCR_CLK0_PCLK;
364 else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
365 source = S3C2410_MISCCR_CLK0_DCLK0;
366 else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
367 source = S3C2410_MISCCR_CLK0_DCLK0;
368 else
369 return -EINVAL;
370
371 if (clk == &s3c24xx_dclk0)
372 mask = S3C2410_MISCCR_CLK0_MASK;
373 else {
374 source <<= 4;
375 mask = S3C2410_MISCCR_CLK1_MASK;
376 }
377
378 s3c2410_modify_misccr(mask, source);
379 return 0;
380}
381
382/* external clock definitions */
383
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384struct clk s3c24xx_dclk0 = {
385 .name = "dclk0",
386 .id = -1,
Ben Dooks3fc3e1c2006-03-20 17:10:07 +0000387 .ctrlbit = S3C2410_DCLKCON_DCLK0EN,
388 .enable = s3c24xx_dclk_enable,
389 .set_parent = s3c24xx_dclk_setparent,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390};
391
392struct clk s3c24xx_dclk1 = {
393 .name = "dclk1",
394 .id = -1,
Ben Dooks3fc3e1c2006-03-20 17:10:07 +0000395 .ctrlbit = S3C2410_DCLKCON_DCLK0EN,
396 .enable = s3c24xx_dclk_enable,
397 .set_parent = s3c24xx_dclk_setparent,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398};
399
400struct clk s3c24xx_clkout0 = {
401 .name = "clkout0",
402 .id = -1,
Ben Dooks3fc3e1c2006-03-20 17:10:07 +0000403 .set_parent = s3c24xx_clkout_setparent,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404};
405
406struct clk s3c24xx_clkout1 = {
407 .name = "clkout1",
408 .id = -1,
Ben Dooks3fc3e1c2006-03-20 17:10:07 +0000409 .set_parent = s3c24xx_clkout_setparent,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410};
411
412struct clk s3c24xx_uclk = {
413 .name = "uclk",
414 .id = -1,
415};
416
417
Ben Dooks8e40a2f2006-03-20 17:10:04 +0000418/* standard clock definitions */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
420static struct clk init_clocks[] = {
Ben Dooksfe38ea52006-01-09 21:16:18 +0000421 {
422 .name = "nand",
423 .id = -1,
424 .parent = &clk_h,
425 .enable = s3c24xx_clkcon_enable,
426 .ctrlbit = S3C2410_CLKCON_NAND,
427 }, {
428 .name = "lcd",
429 .id = -1,
430 .parent = &clk_h,
431 .enable = s3c24xx_clkcon_enable,
432 .ctrlbit = S3C2410_CLKCON_LCDC,
433 }, {
434 .name = "usb-host",
435 .id = -1,
436 .parent = &clk_h,
437 .enable = s3c24xx_clkcon_enable,
438 .ctrlbit = S3C2410_CLKCON_USBH,
439 }, {
440 .name = "usb-device",
441 .id = -1,
442 .parent = &clk_h,
443 .enable = s3c24xx_clkcon_enable,
444 .ctrlbit = S3C2410_CLKCON_USBD,
445 }, {
446 .name = "timers",
447 .id = -1,
448 .parent = &clk_p,
449 .enable = s3c24xx_clkcon_enable,
450 .ctrlbit = S3C2410_CLKCON_PWMT,
451 }, {
452 .name = "sdi",
453 .id = -1,
454 .parent = &clk_p,
455 .enable = s3c24xx_clkcon_enable,
456 .ctrlbit = S3C2410_CLKCON_SDI,
457 }, {
458 .name = "uart",
459 .id = 0,
460 .parent = &clk_p,
461 .enable = s3c24xx_clkcon_enable,
462 .ctrlbit = S3C2410_CLKCON_UART0,
463 }, {
464 .name = "uart",
465 .id = 1,
466 .parent = &clk_p,
467 .enable = s3c24xx_clkcon_enable,
468 .ctrlbit = S3C2410_CLKCON_UART1,
469 }, {
470 .name = "uart",
471 .id = 2,
472 .parent = &clk_p,
473 .enable = s3c24xx_clkcon_enable,
474 .ctrlbit = S3C2410_CLKCON_UART2,
475 }, {
476 .name = "gpio",
477 .id = -1,
478 .parent = &clk_p,
479 .enable = s3c24xx_clkcon_enable,
480 .ctrlbit = S3C2410_CLKCON_GPIO,
481 }, {
482 .name = "rtc",
483 .id = -1,
484 .parent = &clk_p,
485 .enable = s3c24xx_clkcon_enable,
486 .ctrlbit = S3C2410_CLKCON_RTC,
487 }, {
488 .name = "adc",
489 .id = -1,
490 .parent = &clk_p,
491 .enable = s3c24xx_clkcon_enable,
492 .ctrlbit = S3C2410_CLKCON_ADC,
493 }, {
494 .name = "i2c",
495 .id = -1,
496 .parent = &clk_p,
497 .enable = s3c24xx_clkcon_enable,
498 .ctrlbit = S3C2410_CLKCON_IIC,
499 }, {
500 .name = "iis",
501 .id = -1,
502 .parent = &clk_p,
503 .enable = s3c24xx_clkcon_enable,
504 .ctrlbit = S3C2410_CLKCON_IIS,
505 }, {
506 .name = "spi",
507 .id = -1,
508 .parent = &clk_p,
509 .enable = s3c24xx_clkcon_enable,
510 .ctrlbit = S3C2410_CLKCON_SPI,
511 }, {
512 .name = "watchdog",
513 .id = -1,
514 .parent = &clk_p,
515 .ctrlbit = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 }
517};
518
519/* initialise the clock system */
520
521int s3c24xx_register_clock(struct clk *clk)
522{
523 clk->owner = THIS_MODULE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524
525 if (clk->enable == NULL)
526 clk->enable = clk_null_enable;
527
Ben Dooks2a513ce2006-02-08 21:09:05 +0000528 /* if this is a standard clock, set the usage state */
529
Ben Dooks3fc3e1c2006-03-20 17:10:07 +0000530 if (clk->ctrlbit && clk->enable == s3c24xx_clkcon_enable) {
Ben Dooks2a513ce2006-02-08 21:09:05 +0000531 unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
532
533 clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0;
534 }
535
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 /* add to the list of available clocks */
537
Arjan van de Ven00431702006-01-12 18:42:23 +0000538 mutex_lock(&clocks_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 list_add(&clk->list, &clocks);
Arjan van de Ven00431702006-01-12 18:42:23 +0000540 mutex_unlock(&clocks_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541
542 return 0;
543}
544
545/* initalise all the clocks */
546
547int __init s3c24xx_setup_clocks(unsigned long xtal,
548 unsigned long fclk,
549 unsigned long hclk,
550 unsigned long pclk)
551{
Ben Dooks8e40a2f2006-03-20 17:10:04 +0000552 unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
Ben Dooksd6b0bf22005-08-29 22:46:30 +0100553 unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 struct clk *clkp = init_clocks;
555 int ptr;
556 int ret;
557
558 printk(KERN_INFO "S3C2410 Clocks, (c) 2004 Simtec Electronics\n");
559
560 /* initialise the main system clocks */
561
562 clk_xtal.rate = xtal;
Ben Dooks8e40a2f2006-03-20 17:10:04 +0000563 clk_upll.rate = s3c2410_get_pll(upllcon, xtal);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564
565 clk_h.rate = hclk;
566 clk_p.rate = pclk;
567 clk_f.rate = fclk;
568
Ben Dooksfe38ea52006-01-09 21:16:18 +0000569 /* We must be careful disabling the clocks we are not intending to
570 * be using at boot time, as subsytems such as the LCD which do
571 * their own DMA requests to the bus can cause the system to lockup
572 * if they where in the middle of requesting bus access.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 *
Ben Dooksfe38ea52006-01-09 21:16:18 +0000574 * Disabling the LCD clock if the LCD is active is very dangerous,
575 * and therefore the bootloader should be careful to not enable
576 * the LCD clock if it is not needed.
577 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578
Ben Dooks2a513ce2006-02-08 21:09:05 +0000579 mutex_lock(&clocks_mutex);
580
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0);
582 s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0);
583 s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0);
584 s3c24xx_clk_enable(S3C2410_CLKCON_ADC, 0);
585 s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0);
586 s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0);
587
Ben Dooks2a513ce2006-02-08 21:09:05 +0000588 mutex_unlock(&clocks_mutex);
589
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 /* assume uart clocks are correctly setup */
591
592 /* register our clocks */
593
594 if (s3c24xx_register_clock(&clk_xtal) < 0)
595 printk(KERN_ERR "failed to register master xtal\n");
596
Ben Dooks8e40a2f2006-03-20 17:10:04 +0000597 if (s3c24xx_register_clock(&clk_upll) < 0)
598 printk(KERN_ERR "failed to register upll clock\n");
599
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 if (s3c24xx_register_clock(&clk_f) < 0)
601 printk(KERN_ERR "failed to register cpu fclk\n");
602
603 if (s3c24xx_register_clock(&clk_h) < 0)
604 printk(KERN_ERR "failed to register cpu hclk\n");
605
606 if (s3c24xx_register_clock(&clk_p) < 0)
607 printk(KERN_ERR "failed to register cpu pclk\n");
608
609 /* register clocks from clock array */
610
611 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
612 ret = s3c24xx_register_clock(clkp);
613 if (ret < 0) {
614 printk(KERN_ERR "Failed to register clock %s (%d)\n",
615 clkp->name, ret);
616 }
617 }
618
Ben Dooksd6b0bf22005-08-29 22:46:30 +0100619 /* show the clock-slow value */
620
621 printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
622 print_mhz(xtal / ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
623 (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
624 (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
625 (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
626
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 return 0;
628}