aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko St?bner <heiko@sntech.de>2011-10-14 02:08:56 -0400
committerKukjin Kim <kgene.kim@samsung.com>2011-10-14 02:15:49 -0400
commitaab08eebdf87d3e6eda5c81f119423af63f5aee1 (patch)
treedc8b3182c00b3e4b4989d6c9a559153068804094
parentd9a3bfbd7e80ecf24d2322659d5c0542f9d95e78 (diff)
ARM: S3C2443: Move clk_arm and clk_armdiv to common code
The system-layout of the armdiv and armclk is common to S3C2443/S3C2416/S3C2450 and only differs in the array of possible dividers. Therefore it is possible to reuse the clock definitions for all of these SoCs. Signed-off-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r--arch/arm/mach-s3c2443/clock.c85
-rw-r--r--arch/arm/plat-s3c24xx/s3c2443-clock.c87
2 files changed, 89 insertions, 83 deletions
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 88edc55838a1..6fda4bf09cdd 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -61,10 +61,10 @@
61 * 61 *
62 * this clock is sourced from msysclk and can have a number of 62 * this clock is sourced from msysclk and can have a number of
63 * divider values applied to it to then be fed into armclk. 63 * divider values applied to it to then be fed into armclk.
64 * The real clock definition is done in s3c2443-clock.c,
65 * only the armdiv divisor table must be defined here.
64*/ 66*/
65 67
66/* armdiv divisor table */
67
68static unsigned int armdiv[16] = { 68static unsigned int armdiv[16] = {
69 [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1, 69 [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1,
70 [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2, 70 [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2,
@@ -83,85 +83,6 @@ static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
83 return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT]; 83 return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
84} 84}
85 85
86static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
87 unsigned long rate)
88{
89 unsigned long parent = clk_get_rate(clk->parent);
90 unsigned long calc;
91 unsigned best = 256; /* bigger than any value */
92 unsigned div;
93 int ptr;
94
95 for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
96 div = armdiv[ptr];
97 calc = parent / div;
98 if (calc <= rate && div < best)
99 best = div;
100 }
101
102 return parent / best;
103}
104
105static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
106{
107 unsigned long parent = clk_get_rate(clk->parent);
108 unsigned long calc;
109 unsigned div;
110 unsigned best = 256; /* bigger than any value */
111 int ptr;
112 int val = -1;
113
114 for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
115 div = armdiv[ptr];
116 calc = parent / div;
117 if (calc <= rate && div < best) {
118 best = div;
119 val = ptr;
120 }
121 }
122
123 if (val >= 0) {
124 unsigned long clkcon0;
125
126 clkcon0 = __raw_readl(S3C2443_CLKDIV0);
127 clkcon0 &= ~S3C2443_CLKDIV0_ARMDIV_MASK;
128 clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
129 __raw_writel(clkcon0, S3C2443_CLKDIV0);
130 }
131
132 return (val == -1) ? -EINVAL : 0;
133}
134
135static struct clk clk_armdiv = {
136 .name = "armdiv",
137 .parent = &clk_msysclk.clk,
138 .ops = &(struct clk_ops) {
139 .round_rate = s3c2443_armclk_roundrate,
140 .set_rate = s3c2443_armclk_setrate,
141 },
142};
143
144/* armclk
145 *
146 * this is the clock fed into the ARM core itself, from armdiv or from hclk.
147 */
148
149static struct clk *clk_arm_sources[] = {
150 [0] = &clk_armdiv,
151 [1] = &clk_h,
152};
153
154static struct clksrc_clk clk_arm = {
155 .clk = {
156 .name = "armclk",
157 },
158 .sources = &(struct clksrc_sources) {
159 .sources = clk_arm_sources,
160 .nr_sources = ARRAY_SIZE(clk_arm_sources),
161 },
162 .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
163};
164
165/* hsspi 86/* hsspi
166 * 87 *
167 * high-speed spi clock, sourced from esysclk 88 * high-speed spi clock, sourced from esysclk
@@ -260,14 +181,12 @@ static struct clk init_clocks[] = {
260/* clocks to add straight away */ 181/* clocks to add straight away */
261 182
262static struct clksrc_clk *clksrcs[] __initdata = { 183static struct clksrc_clk *clksrcs[] __initdata = {
263 &clk_arm,
264 &clk_hsspi, 184 &clk_hsspi,
265 &clk_hsmmc_div, 185 &clk_hsmmc_div,
266}; 186};
267 187
268static struct clk *clks[] __initdata = { 188static struct clk *clks[] __initdata = {
269 &clk_hsmmc, 189 &clk_hsmmc,
270 &clk_armdiv,
271}; 190};
272 191
273void __init_or_cpufreq s3c2443_setup_clocks(void) 192void __init_or_cpufreq s3c2443_setup_clocks(void)
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index 3f2117b8c0d4..f9c5b0343cf3 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -160,10 +160,95 @@ static struct clk clk_prediv = {
160 }, 160 },
161}; 161};
162 162
163/* armdiv
164 *
165 * this clock is sourced from msysclk and can have a number of
166 * divider values applied to it to then be fed into armclk.
167*/
168
163static unsigned int *armdiv; 169static unsigned int *armdiv;
164static int nr_armdiv; 170static int nr_armdiv;
165static int armdivmask; 171static int armdivmask;
166 172
173static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
174 unsigned long rate)
175{
176 unsigned long parent = clk_get_rate(clk->parent);
177 unsigned long calc;
178 unsigned best = 256; /* bigger than any value */
179 unsigned div;
180 int ptr;
181
182 for (ptr = 0; ptr < nr_armdiv; ptr++) {
183 div = armdiv[ptr];
184 calc = parent / div;
185 if (calc <= rate && div < best)
186 best = div;
187 }
188
189 return parent / best;
190}
191
192static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
193{
194 unsigned long parent = clk_get_rate(clk->parent);
195 unsigned long calc;
196 unsigned div;
197 unsigned best = 256; /* bigger than any value */
198 int ptr;
199 int val = -1;
200
201 for (ptr = 0; ptr < nr_armdiv; ptr++) {
202 div = armdiv[ptr];
203 calc = parent / div;
204 if (calc <= rate && div < best) {
205 best = div;
206 val = ptr;
207 }
208 }
209
210 if (val >= 0) {
211 unsigned long clkcon0;
212
213 clkcon0 = __raw_readl(S3C2443_CLKDIV0);
214 clkcon0 &= ~armdivmask;
215 clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
216 __raw_writel(clkcon0, S3C2443_CLKDIV0);
217 }
218
219 return (val == -1) ? -EINVAL : 0;
220}
221
222static struct clk clk_armdiv = {
223 .name = "armdiv",
224 .parent = &clk_msysclk.clk,
225 .ops = &(struct clk_ops) {
226 .round_rate = s3c2443_armclk_roundrate,
227 .set_rate = s3c2443_armclk_setrate,
228 },
229};
230
231/* armclk
232 *
233 * this is the clock fed into the ARM core itself, from armdiv or from hclk.
234 */
235
236static struct clk *clk_arm_sources[] = {
237 [0] = &clk_armdiv,
238 [1] = &clk_h,
239};
240
241static struct clksrc_clk clk_arm = {
242 .clk = {
243 .name = "armclk",
244 },
245 .sources = &(struct clksrc_sources) {
246 .sources = clk_arm_sources,
247 .nr_sources = ARRAY_SIZE(clk_arm_sources),
248 },
249 .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
250};
251
167/* usbhost 252/* usbhost
168 * 253 *
169 * usb host bus-clock, usually 48MHz to provide USB bus clock timing 254 * usb host bus-clock, usually 48MHz to provide USB bus clock timing
@@ -462,6 +547,7 @@ static struct clk *clks[] __initdata = {
462 &clk_ext, 547 &clk_ext,
463 &clk_epll, 548 &clk_epll,
464 &clk_usb_bus, 549 &clk_usb_bus,
550 &clk_armdiv,
465}; 551};
466 552
467static struct clksrc_clk *clksrcs[] __initdata = { 553static struct clksrc_clk *clksrcs[] __initdata = {
@@ -471,6 +557,7 @@ static struct clksrc_clk *clksrcs[] __initdata = {
471 &clk_epllref, 557 &clk_epllref,
472 &clk_esysclk, 558 &clk_esysclk,
473 &clk_msysclk, 559 &clk_msysclk,
560 &clk_arm,
474}; 561};
475 562
476void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, 563void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,