diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h | 3 | ||||
| -rw-r--r-- | arch/arm/mach-s3c2443/clock.c | 187 |
2 files changed, 62 insertions, 128 deletions
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h index 64217ca796b0..d87ebe0cb625 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h | |||
| @@ -48,11 +48,8 @@ | |||
| 48 | #define S3C2443_CLKSRC_EPLLREF_MPLLREF2 (1<<7) | 48 | #define S3C2443_CLKSRC_EPLLREF_MPLLREF2 (1<<7) |
| 49 | #define S3C2443_CLKSRC_EPLLREF_MASK (3<<7) | 49 | #define S3C2443_CLKSRC_EPLLREF_MASK (3<<7) |
| 50 | 50 | ||
| 51 | #define S3C2443_CLKSRC_ESYSCLK_EPLL (1<<6) | ||
| 52 | #define S3C2443_CLKSRC_MSYSCLK_MPLL (1<<4) | ||
| 53 | #define S3C2443_CLKSRC_EXTCLK_DIV (1<<3) | 51 | #define S3C2443_CLKSRC_EXTCLK_DIV (1<<3) |
| 54 | 52 | ||
| 55 | #define S3C2443_CLKDIV0_DVS (1<<13) | ||
| 56 | #define S3C2443_CLKDIV0_HALF_HCLK (1<<3) | 53 | #define S3C2443_CLKDIV0_HALF_HCLK (1<<3) |
| 57 | #define S3C2443_CLKDIV0_HALF_PCLK (1<<2) | 54 | #define S3C2443_CLKDIV0_HALF_PCLK (1<<2) |
| 58 | 55 | ||
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); |
