diff options
author | Ben Dooks <ben-linux@fluff.org> | 2010-01-30 03:25:49 -0500 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2010-03-07 17:56:11 -0500 |
commit | 4bed36b2c5b3248ae6f9aaf5194fbe85153e4026 (patch) | |
tree | 1f99b1d559b83c16444bd55dc2743343512d7103 /arch/arm/mach-s3c2443/clock.c | |
parent | 9aa753c4422492547a190df8a3b6a56282669f9b (diff) |
ARM: S3C2443: Further clksrc-clk conversions
Move more of the core clocks that where left over from the last commit
as they are much more core to the system operation. This should allow
for easier tracking of any problems.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch/arm/mach-s3c2443/clock.c')
-rw-r--r-- | arch/arm/mach-s3c2443/clock.c | 187 |
1 files changed, 62 insertions, 125 deletions
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index f89e71f50345..1307f69abf98 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* linux/arch/arm/mach-s3c2443/clock.c | 1 | /* linux/arch/arm/mach-s3c2443/clock.c |
2 | * | 2 | * |
3 | * Copyright (c) 2007,2010 Simtec Electronics | 3 | * Copyright (c) 2007, 2010 Simtec Electronics |
4 | * Ben Dooks <ben@simtec.co.uk> | 4 | * Ben Dooks <ben@simtec.co.uk> |
5 | * | 5 | * |
6 | * S3C2443 Clock control support | 6 | * S3C2443 Clock control support |
@@ -145,33 +145,24 @@ static struct clk clk_mdivclk = { | |||
145 | }, | 145 | }, |
146 | }; | 146 | }; |
147 | 147 | ||
148 | static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent) | 148 | static struct clk *clk_msysclk_sources[] = { |
149 | { | 149 | [0] = &clk_mpllref, |
150 | unsigned long clksrc = __raw_readl(S3C2443_CLKSRC); | 150 | [1] = &clk_mpll, |
151 | 151 | [2] = &clk_mdivclk, | |
152 | clksrc &= ~(S3C2443_CLKSRC_MSYSCLK_MPLL | | 152 | [3] = &clk_mpllref, |
153 | S3C2443_CLKSRC_EXTCLK_DIV); | 153 | }; |
154 | |||
155 | if (parent == &clk_mpll) | ||
156 | clksrc |= S3C2443_CLKSRC_MSYSCLK_MPLL; | ||
157 | else if (parent == &clk_mdivclk) | ||
158 | clksrc |= S3C2443_CLKSRC_EXTCLK_DIV; | ||
159 | else if (parent != &clk_mpllref) | ||
160 | return -EINVAL; | ||
161 | |||
162 | __raw_writel(clksrc, S3C2443_CLKSRC); | ||
163 | clk->parent = parent; | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | 154 | ||
168 | static struct clk clk_msysclk = { | 155 | static struct clksrc_clk clk_msysclk = { |
169 | .name = "msysclk", | 156 | .clk = { |
170 | .parent = &clk_xtal, | 157 | .name = "msysclk", |
171 | .id = -1, | 158 | .parent = &clk_xtal, |
172 | .ops = &(struct clk_ops) { | 159 | .id = -1, |
173 | .set_parent = s3c2443_setparent_msysclk, | 160 | }, |
161 | .sources = &(struct clksrc_sources) { | ||
162 | .sources = clk_msysclk_sources, | ||
163 | .nr_sources = ARRAY_SIZE(clk_msysclk_sources), | ||
174 | }, | 164 | }, |
165 | .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 }, | ||
175 | }; | 166 | }; |
176 | 167 | ||
177 | /* armdiv | 168 | /* armdiv |
@@ -183,38 +174,29 @@ static struct clk clk_msysclk = { | |||
183 | static struct clk clk_armdiv = { | 174 | static struct clk clk_armdiv = { |
184 | .name = "armdiv", | 175 | .name = "armdiv", |
185 | .id = -1, | 176 | .id = -1, |
186 | .parent = &clk_msysclk, | 177 | .parent = &clk_msysclk.clk, |
187 | }; | 178 | }; |
188 | 179 | ||
189 | /* armclk | 180 | /* armclk |
190 | * | 181 | * |
191 | * this is the clock fed into the ARM core itself, either from | 182 | * this is the clock fed into the ARM core itself, from armdiv or from hclk. |
192 | * armdiv or from hclk. | ||
193 | */ | 183 | */ |
194 | 184 | ||
195 | static int s3c2443_setparent_armclk(struct clk *clk, struct clk *parent) | 185 | static struct clk *clk_arm_sources[] = { |
196 | { | 186 | [0] = &clk_armdiv, |
197 | unsigned long clkdiv0; | 187 | [1] = &clk_h, |
198 | 188 | }; | |
199 | clkdiv0 = __raw_readl(S3C2443_CLKDIV0); | ||
200 | |||
201 | if (parent == &clk_armdiv) | ||
202 | clkdiv0 &= ~S3C2443_CLKDIV0_DVS; | ||
203 | else if (parent == &clk_h) | ||
204 | clkdiv0 |= S3C2443_CLKDIV0_DVS; | ||
205 | else | ||
206 | return -EINVAL; | ||
207 | |||
208 | __raw_writel(clkdiv0, S3C2443_CLKDIV0); | ||
209 | return 0; | ||
210 | } | ||
211 | 189 | ||
212 | static struct clk clk_arm = { | 190 | static struct clksrc_clk clk_arm = { |
213 | .name = "armclk", | 191 | .clk = { |
214 | .id = -1, | 192 | .name = "armclk", |
215 | .ops = &(struct clk_ops) { | 193 | .id = -1, |
216 | .set_parent = s3c2443_setparent_armclk, | ||
217 | }, | 194 | }, |
195 | .sources = &(struct clksrc_sources) { | ||
196 | .sources = clk_arm_sources, | ||
197 | .nr_sources = ARRAY_SIZE(clk_arm_sources), | ||
198 | }, | ||
199 | .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 }, | ||
218 | }; | 200 | }; |
219 | 201 | ||
220 | /* esysclk | 202 | /* esysclk |
@@ -222,30 +204,22 @@ static struct clk clk_arm = { | |||
222 | * this is sourced from either the EPLL or the EPLLref clock | 204 | * this is sourced from either the EPLL or the EPLLref clock |
223 | */ | 205 | */ |
224 | 206 | ||
225 | static int s3c2443_setparent_esysclk(struct clk *clk, struct clk *parent) | 207 | static struct clk *clk_sysclk_sources[] = { |
226 | { | 208 | [0] = &clk_epllref.clk, |
227 | unsigned long clksrc = __raw_readl(S3C2443_CLKSRC); | 209 | [1] = &clk_epll, |
228 | 210 | }; | |
229 | if (parent == &clk_epll) | ||
230 | clksrc |= S3C2443_CLKSRC_ESYSCLK_EPLL; | ||
231 | else if (parent == &clk_epllref.clk) | ||
232 | clksrc &= ~S3C2443_CLKSRC_ESYSCLK_EPLL; | ||
233 | else | ||
234 | return -EINVAL; | ||
235 | |||
236 | __raw_writel(clksrc, S3C2443_CLKSRC); | ||
237 | clk->parent = parent; | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | 211 | ||
242 | static struct clk clk_esysclk = { | 212 | static struct clksrc_clk clk_esysclk = { |
243 | .name = "esysclk", | 213 | .clk = { |
244 | .parent = &clk_epll, | 214 | .name = "esysclk", |
245 | .id = -1, | 215 | .parent = &clk_epll, |
246 | .ops = &(struct clk_ops) { | 216 | .id = -1, |
247 | .set_parent = s3c2443_setparent_esysclk, | ||
248 | }, | 217 | }, |
218 | .sources = &(struct clksrc_sources) { | ||
219 | .sources = clk_sysclk_sources, | ||
220 | .nr_sources = ARRAY_SIZE(clk_sysclk_sources), | ||
221 | }, | ||
222 | .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 }, | ||
249 | }; | 223 | }; |
250 | 224 | ||
251 | /* uartclk | 225 | /* uartclk |
@@ -257,7 +231,7 @@ static struct clksrc_clk clk_uart = { | |||
257 | .clk = { | 231 | .clk = { |
258 | .name = "uartclk", | 232 | .name = "uartclk", |
259 | .id = -1, | 233 | .id = -1, |
260 | .parent = &clk_esysclk, | 234 | .parent = &clk_esysclk.clk, |
261 | }, | 235 | }, |
262 | .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 }, | 236 | .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 }, |
263 | }; | 237 | }; |
@@ -272,7 +246,7 @@ static struct clksrc_clk clk_hsspi = { | |||
272 | .clk = { | 246 | .clk = { |
273 | .name = "hsspi", | 247 | .name = "hsspi", |
274 | .id = -1, | 248 | .id = -1, |
275 | .parent = &clk_esysclk, | 249 | .parent = &clk_esysclk.clk, |
276 | .ctrlbit = S3C2443_SCLKCON_HSSPICLK, | 250 | .ctrlbit = S3C2443_SCLKCON_HSSPICLK, |
277 | .enable = s3c2443_clkcon_enable_s, | 251 | .enable = s3c2443_clkcon_enable_s, |
278 | }, | 252 | }, |
@@ -288,7 +262,7 @@ static struct clksrc_clk clk_usb_bus_host = { | |||
288 | .clk = { | 262 | .clk = { |
289 | .name = "usb-bus-host-parent", | 263 | .name = "usb-bus-host-parent", |
290 | .id = -1, | 264 | .id = -1, |
291 | .parent = &clk_esysclk, | 265 | .parent = &clk_esysclk.clk, |
292 | .ctrlbit = S3C2443_SCLKCON_USBHOST, | 266 | .ctrlbit = S3C2443_SCLKCON_USBHOST, |
293 | .enable = s3c2443_clkcon_enable_s, | 267 | .enable = s3c2443_clkcon_enable_s, |
294 | }, | 268 | }, |
@@ -306,7 +280,7 @@ static struct clksrc_clk clk_hsmmc_div = { | |||
306 | .clk = { | 280 | .clk = { |
307 | .name = "hsmmc-div", | 281 | .name = "hsmmc-div", |
308 | .id = -1, | 282 | .id = -1, |
309 | .parent = &clk_esysclk, | 283 | .parent = &clk_esysclk.clk, |
310 | }, | 284 | }, |
311 | .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 }, | 285 | .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 }, |
312 | }; | 286 | }; |
@@ -358,7 +332,7 @@ static struct clksrc_clk clk_i2s_eplldiv = { | |||
358 | .clk = { | 332 | .clk = { |
359 | .name = "i2s-eplldiv", | 333 | .name = "i2s-eplldiv", |
360 | .id = -1, | 334 | .id = -1, |
361 | .parent = &clk_esysclk, | 335 | .parent = &clk_esysclk.clk, |
362 | }, | 336 | }, |
363 | .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, }, | 337 | .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, }, |
364 | }; | 338 | }; |
@@ -401,7 +375,7 @@ static struct clksrc_clk clk_cam = { | |||
401 | .clk = { | 375 | .clk = { |
402 | .name = "camif-upll", /* same as 2440 name */ | 376 | .name = "camif-upll", /* same as 2440 name */ |
403 | .id = -1, | 377 | .id = -1, |
404 | .parent = &clk_esysclk, | 378 | .parent = &clk_esysclk.clk, |
405 | .ctrlbit = S3C2443_SCLKCON_CAMCLK, | 379 | .ctrlbit = S3C2443_SCLKCON_CAMCLK, |
406 | .enable = s3c2443_clkcon_enable_s, | 380 | .enable = s3c2443_clkcon_enable_s, |
407 | }, | 381 | }, |
@@ -417,7 +391,7 @@ static struct clksrc_clk clk_display = { | |||
417 | .clk = { | 391 | .clk = { |
418 | .name = "display-if", | 392 | .name = "display-if", |
419 | .id = -1, | 393 | .id = -1, |
420 | .parent = &clk_esysclk, | 394 | .parent = &clk_esysclk.clk, |
421 | .ctrlbit = S3C2443_SCLKCON_DISPCLK, | 395 | .ctrlbit = S3C2443_SCLKCON_DISPCLK, |
422 | .enable = s3c2443_clkcon_enable_s, | 396 | .enable = s3c2443_clkcon_enable_s, |
423 | }, | 397 | }, |
@@ -443,7 +417,7 @@ static unsigned long s3c2443_prediv_getrate(struct clk *clk) | |||
443 | static struct clk clk_prediv = { | 417 | static struct clk clk_prediv = { |
444 | .name = "prediv", | 418 | .name = "prediv", |
445 | .id = -1, | 419 | .id = -1, |
446 | .parent = &clk_msysclk, | 420 | .parent = &clk_msysclk.clk, |
447 | .ops = &(struct clk_ops) { | 421 | .ops = &(struct clk_ops) { |
448 | .get_rate = s3c2443_prediv_getrate, | 422 | .get_rate = s3c2443_prediv_getrate, |
449 | }, | 423 | }, |
@@ -629,19 +603,11 @@ static struct clk init_clocks[] = { | |||
629 | 603 | ||
630 | /* clocks to add where we need to check their parentage */ | 604 | /* clocks to add where we need to check their parentage */ |
631 | 605 | ||
632 | /* s3c2443_clk_initparents | ||
633 | * | ||
634 | * Initialise the parents for the clocks that we get at start-time | ||
635 | */ | ||
636 | |||
637 | static int __init clk_init_set_parent(struct clk *clk, struct clk *parent) | ||
638 | { | ||
639 | printk(KERN_DEBUG "clock %s: parent %s\n", clk->name, parent->name); | ||
640 | return clk_set_parent(clk, parent); | ||
641 | } | ||
642 | |||
643 | static struct clksrc_clk __initdata *init_list[] = { | 606 | static struct clksrc_clk __initdata *init_list[] = { |
644 | &clk_epllref, /* should be first */ | 607 | &clk_epllref, /* should be first */ |
608 | &clk_esysclk, | ||
609 | &clk_msysclk, | ||
610 | &clk_arm, | ||
645 | &clk_i2s_eplldiv, | 611 | &clk_i2s_eplldiv, |
646 | &clk_i2s, | 612 | &clk_i2s, |
647 | &clk_cam, | 613 | &clk_cam, |
@@ -653,39 +619,10 @@ static struct clksrc_clk __initdata *init_list[] = { | |||
653 | 619 | ||
654 | static void __init s3c2443_clk_initparents(void) | 620 | static void __init s3c2443_clk_initparents(void) |
655 | { | 621 | { |
656 | unsigned long clksrc = __raw_readl(S3C2443_CLKSRC); | ||
657 | struct clk *parent; | ||
658 | int ptr; | 622 | int ptr; |
659 | 623 | ||
660 | /* esysclk source */ | ||
661 | |||
662 | parent = (clksrc & S3C2443_CLKSRC_ESYSCLK_EPLL) ? | ||
663 | &clk_epll : &clk_epllref.clk; | ||
664 | |||
665 | clk_init_set_parent(&clk_esysclk, parent); | ||
666 | |||
667 | /* msysclk source */ | ||
668 | |||
669 | if (clksrc & S3C2443_CLKSRC_MSYSCLK_MPLL) { | ||
670 | parent = &clk_mpll; | ||
671 | } else { | ||
672 | parent = (clksrc & S3C2443_CLKSRC_EXTCLK_DIV) ? | ||
673 | &clk_mdivclk : &clk_mpllref; | ||
674 | } | ||
675 | |||
676 | clk_init_set_parent(&clk_msysclk, parent); | ||
677 | |||
678 | /* arm */ | ||
679 | |||
680 | if (__raw_readl(S3C2443_CLKDIV0) & S3C2443_CLKDIV0_DVS) | ||
681 | parent = &clk_h; | ||
682 | else | ||
683 | parent = &clk_armdiv; | ||
684 | |||
685 | clk_init_set_parent(&clk_arm, parent); | ||
686 | |||
687 | for (ptr = 0; ptr < ARRAY_SIZE(init_list); ptr++) | 624 | for (ptr = 0; ptr < ARRAY_SIZE(init_list); ptr++) |
688 | s3c_set_clksrc(init_list[ptr], false); | 625 | s3c_set_clksrc(init_list[ptr], true); |
689 | } | 626 | } |
690 | 627 | ||
691 | /* armdiv divisor table */ | 628 | /* armdiv divisor table */ |
@@ -720,6 +657,9 @@ static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0) | |||
720 | static struct clksrc_clk *clksrcs[] __initdata = { | 657 | static struct clksrc_clk *clksrcs[] __initdata = { |
721 | &clk_usb_bus_host, | 658 | &clk_usb_bus_host, |
722 | &clk_epllref, | 659 | &clk_epllref, |
660 | &clk_esysclk, | ||
661 | &clk_msysclk, | ||
662 | &clk_arm, | ||
723 | &clk_uart, | 663 | &clk_uart, |
724 | &clk_display, | 664 | &clk_display, |
725 | &clk_cam, | 665 | &clk_cam, |
@@ -733,12 +673,9 @@ static struct clk *clks[] __initdata = { | |||
733 | &clk_ext, | 673 | &clk_ext, |
734 | &clk_epll, | 674 | &clk_epll, |
735 | &clk_usb_bus, | 675 | &clk_usb_bus, |
736 | &clk_esysclk, | ||
737 | &clk_mpllref, | 676 | &clk_mpllref, |
738 | &clk_msysclk, | ||
739 | &clk_hsmmc, | 677 | &clk_hsmmc, |
740 | &clk_armdiv, | 678 | &clk_armdiv, |
741 | &clk_arm, | ||
742 | &clk_prediv, | 679 | &clk_prediv, |
743 | }; | 680 | }; |
744 | 681 | ||
@@ -758,7 +695,7 @@ void __init_or_cpufreq s3c2443_setup_clocks(void) | |||
758 | clk_put(xtal_clk); | 695 | clk_put(xtal_clk); |
759 | 696 | ||
760 | pll = s3c2443_get_mpll(mpllcon, xtal); | 697 | pll = s3c2443_get_mpll(mpllcon, xtal); |
761 | clk_msysclk.rate = pll; | 698 | clk_msysclk.clk.rate = pll; |
762 | 699 | ||
763 | fclk = pll / s3c2443_fclk_div(clkdiv0); | 700 | fclk = pll / s3c2443_fclk_div(clkdiv0); |
764 | hclk = s3c2443_prediv_getrate(&clk_prediv); | 701 | hclk = s3c2443_prediv_getrate(&clk_prediv); |