Root/
1 | /* linux/arch/arm/mach-s3c2440/clock.c |
2 | * |
3 | * Copyright (c) 2004-2005 Simtec Electronics |
4 | * http://armlinux.simtec.co.uk/ |
5 | * Ben Dooks <ben@simtec.co.uk> |
6 | * |
7 | * S3C2440 Clock support |
8 | * |
9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2 of the License, or |
12 | * (at your option) any later version. |
13 | * |
14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 | */ |
23 | |
24 | #include <linux/init.h> |
25 | #include <linux/module.h> |
26 | #include <linux/kernel.h> |
27 | #include <linux/list.h> |
28 | #include <linux/errno.h> |
29 | #include <linux/err.h> |
30 | #include <linux/device.h> |
31 | #include <linux/sysdev.h> |
32 | #include <linux/interrupt.h> |
33 | #include <linux/ioport.h> |
34 | #include <linux/mutex.h> |
35 | #include <linux/clk.h> |
36 | #include <linux/io.h> |
37 | |
38 | #include <mach/hardware.h> |
39 | #include <asm/atomic.h> |
40 | #include <asm/irq.h> |
41 | |
42 | #include <mach/regs-clock.h> |
43 | |
44 | #include <plat/clock.h> |
45 | #include <plat/cpu.h> |
46 | |
47 | /* S3C2440 extended clock support */ |
48 | |
49 | static unsigned long s3c2440_camif_upll_round(struct clk *clk, |
50 | unsigned long rate) |
51 | { |
52 | unsigned long parent_rate = clk_get_rate(clk->parent); |
53 | int div; |
54 | |
55 | if (rate > parent_rate) |
56 | return parent_rate; |
57 | |
58 | /* note, we remove the +/- 1 calculations for the divisor */ |
59 | |
60 | div = (parent_rate / rate) / 2; |
61 | |
62 | if (div < 1) |
63 | div = 1; |
64 | else if (div > 16) |
65 | div = 16; |
66 | |
67 | return parent_rate / (div * 2); |
68 | } |
69 | |
70 | static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate) |
71 | { |
72 | unsigned long parent_rate = clk_get_rate(clk->parent); |
73 | unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); |
74 | |
75 | rate = s3c2440_camif_upll_round(clk, rate); |
76 | |
77 | camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK); |
78 | |
79 | if (rate != parent_rate) { |
80 | camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL; |
81 | camdivn |= (((parent_rate / rate) / 2) - 1); |
82 | } |
83 | |
84 | __raw_writel(camdivn, S3C2440_CAMDIVN); |
85 | |
86 | return 0; |
87 | } |
88 | |
89 | /* Extra S3C2440 clocks */ |
90 | |
91 | static struct clk s3c2440_clk_cam = { |
92 | .name = "camif", |
93 | .id = -1, |
94 | .enable = s3c2410_clkcon_enable, |
95 | .ctrlbit = S3C2440_CLKCON_CAMERA, |
96 | }; |
97 | |
98 | static struct clk s3c2440_clk_cam_upll = { |
99 | .name = "camif-upll", |
100 | .id = -1, |
101 | .ops = &(struct clk_ops) { |
102 | .set_rate = s3c2440_camif_upll_setrate, |
103 | .round_rate = s3c2440_camif_upll_round, |
104 | }, |
105 | }; |
106 | |
107 | static struct clk s3c2440_clk_ac97 = { |
108 | .name = "ac97", |
109 | .id = -1, |
110 | .enable = s3c2410_clkcon_enable, |
111 | .ctrlbit = S3C2440_CLKCON_CAMERA, |
112 | }; |
113 | |
114 | static int s3c2440_clk_add(struct sys_device *sysdev) |
115 | { |
116 | struct clk *clock_upll; |
117 | struct clk *clock_h; |
118 | struct clk *clock_p; |
119 | |
120 | clock_p = clk_get(NULL, "pclk"); |
121 | clock_h = clk_get(NULL, "hclk"); |
122 | clock_upll = clk_get(NULL, "upll"); |
123 | |
124 | if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) { |
125 | printk(KERN_ERR "S3C2440: Failed to get parent clocks\n"); |
126 | return -EINVAL; |
127 | } |
128 | |
129 | s3c2440_clk_cam.parent = clock_h; |
130 | s3c2440_clk_ac97.parent = clock_p; |
131 | s3c2440_clk_cam_upll.parent = clock_upll; |
132 | |
133 | s3c24xx_register_clock(&s3c2440_clk_ac97); |
134 | s3c24xx_register_clock(&s3c2440_clk_cam); |
135 | s3c24xx_register_clock(&s3c2440_clk_cam_upll); |
136 | |
137 | clk_disable(&s3c2440_clk_ac97); |
138 | clk_disable(&s3c2440_clk_cam); |
139 | |
140 | return 0; |
141 | } |
142 | |
143 | static struct sysdev_driver s3c2440_clk_driver = { |
144 | .add = s3c2440_clk_add, |
145 | }; |
146 | |
147 | static __init int s3c24xx_clk_driver(void) |
148 | { |
149 | return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver); |
150 | } |
151 | |
152 | arch_initcall(s3c24xx_clk_driver); |
153 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9