upload tizen1.0 source
[kernel/linux-2.6.36.git] / arch / arm / plat-samsung / clock.c
1 /* linux/arch/arm/plat-s3c24xx/clock.c
2  *
3  * Copyright 2004-2005 Simtec Electronics
4  *      Ben Dooks <ben@simtec.co.uk>
5  *
6  * S3C24XX Core 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>
35 #include <linux/platform_device.h>
36 #include <linux/sysdev.h>
37 #include <linux/interrupt.h>
38 #include <linux/ioport.h>
39 #include <linux/clk.h>
40 #include <linux/spinlock.h>
41 #include <linux/io.h>
42 #include <linux/debugfs.h>
43
44 #include <mach/hardware.h>
45 #include <asm/irq.h>
46
47 #include <plat/cpu-freq.h>
48
49 #include <plat/clock.h>
50 #include <plat/cpu.h>
51
52 #include <linux/serial_core.h>
53 #include <plat/regs-serial.h> /* for s3c24xx_uart_devs */
54
55 /* clock information */
56
57 static LIST_HEAD(clocks);
58
59 /* We originally used an mutex here, but some contexts (see resume)
60  * are calling functions such as clk_set_parent() with IRQs disabled
61  * causing an BUG to be triggered.
62  */
63 DEFINE_SPINLOCK(clocks_lock);
64
65 /* enable and disable calls for use with the clk struct */
66
67 static int clk_null_enable(struct clk *clk, int enable)
68 {
69         return 0;
70 }
71
72 static int dev_is_s3c_uart(struct device *dev)
73 {
74         struct platform_device **pdev = s3c24xx_uart_devs;
75         int i;
76         for (i = 0; i < ARRAY_SIZE(s3c24xx_uart_devs); i++, pdev++)
77                 if (*pdev && dev == &(*pdev)->dev)
78                         return 1;
79         return 0;
80 }
81
82 /*
83  * Serial drivers call get_clock() very early, before platform bus
84  * has been set up, this requires a special check to let them get
85  * a proper clock
86  */
87
88 static int dev_is_platform_device(struct device *dev)
89 {
90         return dev->bus == &platform_bus_type ||
91                (dev->bus == NULL && dev_is_s3c_uart(dev));
92 }
93
94 /* Clock API calls */
95
96 struct clk *clk_get(struct device *dev, const char *id)
97 {
98         struct clk *p;
99         struct clk *clk = ERR_PTR(-ENOENT);
100         int idno;
101         unsigned long flags;
102
103         if (dev == NULL || !dev_is_platform_device(dev))
104                 idno = -1;
105         else
106                 idno = to_platform_device(dev)->id;
107
108         spin_lock_irqsave(&clocks_lock, flags);
109
110         list_for_each_entry(p, &clocks, list) {
111                 if (p->id == idno &&
112                     strcmp(id, p->name) == 0 &&
113                     try_module_get(p->owner)) {
114                         clk = p;
115                         break;
116                 }
117         }
118
119         /* check for the case where a device was supplied, but the
120          * clock that was being searched for is not device specific */
121
122         if (IS_ERR(clk)) {
123                 list_for_each_entry(p, &clocks, list) {
124                         if (p->id == -1 && strcmp(id, p->name) == 0 &&
125                             try_module_get(p->owner)) {
126                                 clk = p;
127                                 break;
128                         }
129                 }
130         }
131
132         spin_unlock_irqrestore(&clocks_lock, flags);
133         return clk;
134 }
135
136 void clk_put(struct clk *clk)
137 {
138         module_put(clk->owner);
139 }
140
141 int clk_enable(struct clk *clk)
142 {
143         unsigned long flags;
144
145         if (IS_ERR(clk) || clk == NULL)
146                 return -EINVAL;
147
148         clk_enable(clk->parent);
149
150         spin_lock_irqsave(&clocks_lock, flags);
151
152         if ((clk->usage++) == 0)
153                 (clk->enable)(clk, 1);
154
155         spin_unlock_irqrestore(&clocks_lock, flags);
156         return 0;
157 }
158
159 void clk_disable(struct clk *clk)
160 {
161         unsigned long flags;
162
163         if (IS_ERR(clk) || clk == NULL)
164                 return;
165
166         if(clk->usage == 0)
167                 goto parent_clk;
168
169         spin_lock_irqsave(&clocks_lock, flags);
170
171         WARN(clk->usage <= 0, "ERROR: Clock %s:%d usage counter mismatch"
172                         " (%d) at clk_disable.\n", clk->name, clk->id,
173                         clk->usage);
174
175         if ((--clk->usage) == 0)
176                 (clk->enable)(clk, 0);
177
178         spin_unlock_irqrestore(&clocks_lock, flags);
179
180 parent_clk:
181         clk_disable(clk->parent);
182 }
183
184
185 unsigned long clk_get_rate(struct clk *clk)
186 {
187         if (IS_ERR(clk))
188                 return 0;
189
190         if (clk->rate != 0)
191                 return clk->rate;
192
193         if (clk->ops != NULL && clk->ops->get_rate != NULL)
194                 return (clk->ops->get_rate)(clk);
195
196         if (clk->parent != NULL)
197                 return clk_get_rate(clk->parent);
198
199         return clk->rate;
200 }
201
202 long clk_round_rate(struct clk *clk, unsigned long rate)
203 {
204         if (!IS_ERR(clk) && clk->ops && clk->ops->round_rate)
205                 return (clk->ops->round_rate)(clk, rate);
206
207         return rate;
208 }
209
210 int clk_set_rate(struct clk *clk, unsigned long rate)
211 {
212         int ret;
213         unsigned long flags;
214
215         if (IS_ERR(clk))
216                 return -EINVAL;
217
218         /* We do not default just do a clk->rate = rate as
219          * the clock may have been made this way by choice.
220          */
221
222         WARN_ON(clk->ops == NULL);
223         WARN_ON(clk->ops && clk->ops->set_rate == NULL);
224
225         if (clk->ops == NULL || clk->ops->set_rate == NULL)
226                 return -EINVAL;
227
228         spin_lock_irqsave(&clocks_lock, flags);
229         ret = (clk->ops->set_rate)(clk, rate);
230         spin_unlock_irqrestore(&clocks_lock, flags);
231
232         return ret;
233 }
234
235 struct clk *clk_get_parent(struct clk *clk)
236 {
237         return clk->parent;
238 }
239
240 int clk_set_parent(struct clk *clk, struct clk *parent)
241 {
242         int ret = 0;
243         unsigned long flags;
244
245         if (IS_ERR(clk))
246                 return -EINVAL;
247
248         spin_lock_irqsave(&clocks_lock, flags);
249
250         if (clk->ops && clk->ops->set_parent)
251                 ret = (clk->ops->set_parent)(clk, parent);
252
253         spin_unlock_irqrestore(&clocks_lock, flags);
254
255         return ret;
256 }
257
258 EXPORT_SYMBOL(clk_get);
259 EXPORT_SYMBOL(clk_put);
260 EXPORT_SYMBOL(clk_enable);
261 EXPORT_SYMBOL(clk_disable);
262 EXPORT_SYMBOL(clk_get_rate);
263 EXPORT_SYMBOL(clk_round_rate);
264 EXPORT_SYMBOL(clk_set_rate);
265 EXPORT_SYMBOL(clk_get_parent);
266 EXPORT_SYMBOL(clk_set_parent);
267
268 /* base clocks */
269
270 int clk_default_setrate(struct clk *clk, unsigned long rate)
271 {
272         clk->rate = rate;
273         return 0;
274 }
275
276 struct clk_ops clk_ops_def_setrate = {
277         .set_rate       = clk_default_setrate,
278 };
279
280 struct clk clk_xtal = {
281         .name           = "xtal",
282         .id             = -1,
283         .rate           = 0,
284         .parent         = NULL,
285         .ctrlbit        = 0,
286 };
287
288 struct clk clk_ext = {
289         .name           = "ext",
290         .id             = -1,
291 };
292
293 struct clk clk_epll = {
294         .name           = "epll",
295         .id             = -1,
296 };
297
298 struct clk clk_mpll = {
299         .name           = "mpll",
300         .id             = -1,
301         .ops            = &clk_ops_def_setrate,
302 };
303
304 struct clk clk_upll = {
305         .name           = "upll",
306         .id             = -1,
307         .parent         = NULL,
308         .ctrlbit        = 0,
309 };
310
311 struct clk clk_f = {
312         .name           = "fclk",
313         .id             = -1,
314         .rate           = 0,
315         .parent         = &clk_mpll,
316         .ctrlbit        = 0,
317 };
318
319 struct clk clk_h = {
320         .name           = "hclk",
321         .id             = -1,
322         .rate           = 0,
323         .parent         = NULL,
324         .ctrlbit        = 0,
325         .ops            = &clk_ops_def_setrate,
326 };
327
328 struct clk clk_p = {
329         .name           = "pclk",
330         .id             = -1,
331         .rate           = 0,
332         .parent         = NULL,
333         .ctrlbit        = 0,
334         .ops            = &clk_ops_def_setrate,
335 };
336
337 struct clk clk_usb_bus = {
338         .name           = "usb-bus",
339         .id             = -1,
340         .rate           = 0,
341         .parent         = &clk_upll,
342 };
343
344
345 struct clk s3c24xx_uclk = {
346         .name           = "uclk",
347         .id             = -1,
348 };
349
350 /* initialise the clock system */
351
352 /**
353  * s3c24xx_register_clock() - register a clock
354  * @clk: The clock to register
355  *
356  * Add the specified clock to the list of clocks known by the system.
357  */
358 int s3c24xx_register_clock(struct clk *clk)
359 {
360         unsigned long flags;
361
362         if (clk->enable == NULL)
363                 clk->enable = clk_null_enable;
364
365         /* add to the list of available clocks */
366
367         /* Quick check to see if this clock has already been registered. */
368         BUG_ON(clk->list.prev != clk->list.next);
369
370         spin_lock_irqsave(&clocks_lock, flags);
371         list_add(&clk->list, &clocks);
372         spin_unlock_irqrestore(&clocks_lock, flags);
373
374         return 0;
375 }
376
377 /**
378  * s3c24xx_register_clocks() - register an array of clock pointers
379  * @clks: Pointer to an array of struct clk pointers
380  * @nr_clks: The number of clocks in the @clks array.
381  *
382  * Call s3c24xx_register_clock() for all the clock pointers contained
383  * in the @clks list. Returns the number of failures.
384  */
385 int s3c24xx_register_clocks(struct clk **clks, int nr_clks)
386 {
387         int fails = 0;
388
389         for (; nr_clks > 0; nr_clks--, clks++) {
390                 if (s3c24xx_register_clock(*clks) < 0) {
391                         struct clk *clk = *clks;
392                         printk(KERN_ERR "%s: failed to register %p: %s\n",
393                                __func__, clk, clk->name);
394                         fails++;
395                 }
396         }
397
398         return fails;
399 }
400
401 /**
402  * s3c_register_clocks() - register an array of clocks
403  * @clkp: Pointer to the first clock in the array.
404  * @nr_clks: Number of clocks to register.
405  *
406  * Call s3c24xx_register_clock() on the @clkp array given, printing an
407  * error if it fails to register the clock (unlikely).
408  */
409 void __init s3c_register_clocks(struct clk *clkp, int nr_clks)
410 {
411         int ret;
412
413         for (; nr_clks > 0; nr_clks--, clkp++) {
414                 ret = s3c24xx_register_clock(clkp);
415
416                 if (ret < 0) {
417                         printk(KERN_ERR "Failed to register clock %s (%d)\n",
418                                clkp->name, ret);
419                 }
420         }
421 }
422
423 /**
424  * s3c_disable_clocks() - disable an array of clocks
425  * @clkp: Pointer to the first clock in the array.
426  * @nr_clks: Number of clocks to register.
427  *
428  * for internal use only at initialisation time. disable the clocks in the
429  * @clkp array.
430  */
431
432 void __init s3c_disable_clocks(struct clk *clkp, int nr_clks)
433 {
434         for (; nr_clks > 0; nr_clks--, clkp++)
435                 (clkp->enable)(clkp, 0);
436 }
437
438 /* initialise all the clocks */
439
440 int __init s3c24xx_register_baseclocks(unsigned long xtal)
441 {
442         printk(KERN_INFO "S3C24XX Clocks, Copyright 2004 Simtec Electronics\n");
443
444         clk_xtal.rate = xtal;
445
446         /* register our clocks */
447
448         if (s3c24xx_register_clock(&clk_xtal) < 0)
449                 printk(KERN_ERR "failed to register master xtal\n");
450
451         if (s3c24xx_register_clock(&clk_mpll) < 0)
452                 printk(KERN_ERR "failed to register mpll clock\n");
453
454         if (s3c24xx_register_clock(&clk_upll) < 0)
455                 printk(KERN_ERR "failed to register upll clock\n");
456
457         if (s3c24xx_register_clock(&clk_f) < 0)
458                 printk(KERN_ERR "failed to register cpu fclk\n");
459
460         if (s3c24xx_register_clock(&clk_h) < 0)
461                 printk(KERN_ERR "failed to register cpu hclk\n");
462
463         if (s3c24xx_register_clock(&clk_p) < 0)
464                 printk(KERN_ERR "failed to register cpu pclk\n");
465
466         return 0;
467 }
468
469 #ifdef CONFIG_DEBUG_FS
470 /*
471  *      debugfs support to trace clock tree hierarchy and attributes
472  */
473 static struct dentry *clk_debugfs_root;
474
475 static int clk_debugfs_register_one(struct clk *c)
476 {
477         int err;
478         struct dentry *d, *child, *child_tmp;
479         struct clk *pa = c->parent;
480         char s[255];
481         char *p = s;
482
483         p += sprintf(p, "%s:%d", c->name, c->id);
484         d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
485         if (!d)
486                 return -ENOMEM;
487         c->dent = d;
488
489         d = debugfs_create_u32("usecount", S_IRUGO, c->dent, (u32 *)&c->usage);
490         if (!d) {
491                 err = -ENOMEM;
492                 goto err_out;
493         }
494         d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
495         if (!d) {
496                 err = -ENOMEM;
497                 goto err_out;
498         }
499         d = debugfs_create_x32("ctrlbit", S_IRUGO, c->dent, (u32 *)&c->ctrlbit);
500         if (!d) {
501                 err = -ENOMEM;
502                 goto err_out;
503         }
504         return 0;
505
506 err_out:
507         d = c->dent;
508         list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
509                 debugfs_remove(child);
510         debugfs_remove(c->dent);
511         return err;
512 }
513
514 static int clk_debugfs_register(struct clk *c)
515 {
516         int err;
517         struct clk *pa = c->parent;
518
519         if (pa && !pa->dent) {
520                 err = clk_debugfs_register(pa);
521                 if (err) {
522                         pr_err("ERROR registering parent %s:%d (%d)\n",
523                                         pa->name, pa->id, err);
524                         return err;
525                 }
526         }
527
528         if (!c->dent) {
529                 err = clk_debugfs_register_one(c);
530                 if (err) {
531                         pr_err("ERROR registering %s:%d (%d)\n",
532                                         c->name, c->id, err);
533                         return err;
534                 }
535         }
536         return 0;
537 }
538
539 static int __init clk_debugfs_init(void)
540 {
541         struct clk *c;
542         struct dentry *d;
543         int err;
544
545         d = debugfs_create_dir("clock", NULL);
546         if (!d)
547                 return -ENOMEM;
548         clk_debugfs_root = d;
549
550         list_for_each_entry(c, &clocks, list) {
551                 err = clk_debugfs_register(c);
552                 if (err)
553                         goto err_out;
554         }
555         return 0;
556 err_out:
557         debugfs_remove_recursive(clk_debugfs_root);
558         return err;
559 }
560 late_initcall(clk_debugfs_init);
561
562 #endif /* CONFIG_DEBUG_FS */