diff options
Diffstat (limited to 'arch/powerpc/platforms/512x')
-rw-r--r-- | arch/powerpc/platforms/512x/clock.c | 34 | ||||
-rw-r--r-- | arch/powerpc/platforms/512x/mpc512x_shared.c | 32 |
2 files changed, 48 insertions, 18 deletions
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index 9f771e05457c..52d57d281724 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #include <linux/of_platform.h> | 27 | #include <linux/of_platform.h> |
28 | #include <asm/mpc5xxx.h> | 28 | #include <asm/mpc5xxx.h> |
29 | #include <asm/mpc5121.h> | ||
29 | #include <asm/clk_interface.h> | 30 | #include <asm/clk_interface.h> |
30 | 31 | ||
31 | #undef CLK_DEBUG | 32 | #undef CLK_DEBUG |
@@ -122,7 +123,7 @@ struct mpc512x_clockctl { | |||
122 | u32 dccr; /* DIU Clk Cnfg Reg */ | 123 | u32 dccr; /* DIU Clk Cnfg Reg */ |
123 | }; | 124 | }; |
124 | 125 | ||
125 | struct mpc512x_clockctl __iomem *clockctl; | 126 | static struct mpc512x_clockctl __iomem *clockctl; |
126 | 127 | ||
127 | static int mpc5121_clk_enable(struct clk *clk) | 128 | static int mpc5121_clk_enable(struct clk *clk) |
128 | { | 129 | { |
@@ -184,7 +185,7 @@ static unsigned long spmf_mult(void) | |||
184 | 36, 40, 44, 48, | 185 | 36, 40, 44, 48, |
185 | 52, 56, 60, 64 | 186 | 52, 56, 60, 64 |
186 | }; | 187 | }; |
187 | int spmf = (clockctl->spmr >> 24) & 0xf; | 188 | int spmf = (in_be32(&clockctl->spmr) >> 24) & 0xf; |
188 | return spmf_to_mult[spmf]; | 189 | return spmf_to_mult[spmf]; |
189 | } | 190 | } |
190 | 191 | ||
@@ -206,7 +207,7 @@ static unsigned long sysdiv_div_x_2(void) | |||
206 | 52, 56, 58, 62, | 207 | 52, 56, 58, 62, |
207 | 60, 64, 66, | 208 | 60, 64, 66, |
208 | }; | 209 | }; |
209 | int sysdiv = (clockctl->scfr2 >> 26) & 0x3f; | 210 | int sysdiv = (in_be32(&clockctl->scfr2) >> 26) & 0x3f; |
210 | return sysdiv_to_div_x_2[sysdiv]; | 211 | return sysdiv_to_div_x_2[sysdiv]; |
211 | } | 212 | } |
212 | 213 | ||
@@ -230,7 +231,7 @@ static unsigned long sys_to_ref(unsigned long rate) | |||
230 | 231 | ||
231 | static long ips_to_ref(unsigned long rate) | 232 | static long ips_to_ref(unsigned long rate) |
232 | { | 233 | { |
233 | int ips_div = (clockctl->scfr1 >> 23) & 0x7; | 234 | int ips_div = (in_be32(&clockctl->scfr1) >> 23) & 0x7; |
234 | 235 | ||
235 | rate *= ips_div; /* csb_clk = ips_clk * ips_div */ | 236 | rate *= ips_div; /* csb_clk = ips_clk * ips_div */ |
236 | rate *= 2; /* sys_clk = csb_clk * 2 */ | 237 | rate *= 2; /* sys_clk = csb_clk * 2 */ |
@@ -284,7 +285,7 @@ static struct clk sys_clk = { | |||
284 | 285 | ||
285 | static void diu_clk_calc(struct clk *clk) | 286 | static void diu_clk_calc(struct clk *clk) |
286 | { | 287 | { |
287 | int diudiv_x_2 = clockctl->scfr1 & 0xff; | 288 | int diudiv_x_2 = in_be32(&clockctl->scfr1) & 0xff; |
288 | unsigned long rate; | 289 | unsigned long rate; |
289 | 290 | ||
290 | rate = sys_clk.rate; | 291 | rate = sys_clk.rate; |
@@ -311,7 +312,7 @@ static void half_clk_calc(struct clk *clk) | |||
311 | 312 | ||
312 | static void generic_div_clk_calc(struct clk *clk) | 313 | static void generic_div_clk_calc(struct clk *clk) |
313 | { | 314 | { |
314 | int div = (clockctl->scfr1 >> clk->div_shift) & 0x7; | 315 | int div = (in_be32(&clockctl->scfr1) >> clk->div_shift) & 0x7; |
315 | 316 | ||
316 | clk->rate = clk->parent->rate / div; | 317 | clk->rate = clk->parent->rate / div; |
317 | } | 318 | } |
@@ -329,7 +330,7 @@ static struct clk csb_clk = { | |||
329 | 330 | ||
330 | static void e300_clk_calc(struct clk *clk) | 331 | static void e300_clk_calc(struct clk *clk) |
331 | { | 332 | { |
332 | int spmf = (clockctl->spmr >> 16) & 0xf; | 333 | int spmf = (in_be32(&clockctl->spmr) >> 16) & 0xf; |
333 | int ratex2 = clk->parent->rate * spmf; | 334 | int ratex2 = clk->parent->rate * spmf; |
334 | 335 | ||
335 | clk->rate = ratex2 / 2; | 336 | clk->rate = ratex2 / 2; |
@@ -551,7 +552,7 @@ static struct clk ac97_clk = { | |||
551 | .calc = ac97_clk_calc, | 552 | .calc = ac97_clk_calc, |
552 | }; | 553 | }; |
553 | 554 | ||
554 | struct clk *rate_clks[] = { | 555 | static struct clk *rate_clks[] = { |
555 | &ref_clk, | 556 | &ref_clk, |
556 | &sys_clk, | 557 | &sys_clk, |
557 | &diu_clk, | 558 | &diu_clk, |
@@ -607,7 +608,7 @@ static void rate_clks_init(void) | |||
607 | * There are two clk enable registers with 32 enable bits each | 608 | * There are two clk enable registers with 32 enable bits each |
608 | * psc clocks and device clocks are all stored in dev_clks | 609 | * psc clocks and device clocks are all stored in dev_clks |
609 | */ | 610 | */ |
610 | struct clk dev_clks[2][32]; | 611 | static struct clk dev_clks[2][32]; |
611 | 612 | ||
612 | /* | 613 | /* |
613 | * Given a psc number return the dev_clk | 614 | * Given a psc number return the dev_clk |
@@ -648,12 +649,12 @@ static void psc_calc_rate(struct clk *clk, int pscnum, struct device_node *np) | |||
648 | out_be32(&clockctl->pccr[pscnum], 0x00020000); | 649 | out_be32(&clockctl->pccr[pscnum], 0x00020000); |
649 | out_be32(&clockctl->pccr[pscnum], 0x00030000); | 650 | out_be32(&clockctl->pccr[pscnum], 0x00030000); |
650 | 651 | ||
651 | if (clockctl->pccr[pscnum] & 0x80) { | 652 | if (in_be32(&clockctl->pccr[pscnum]) & 0x80) { |
652 | clk->rate = spdif_rxclk.rate; | 653 | clk->rate = spdif_rxclk.rate; |
653 | return; | 654 | return; |
654 | } | 655 | } |
655 | 656 | ||
656 | switch ((clockctl->pccr[pscnum] >> 14) & 0x3) { | 657 | switch ((in_be32(&clockctl->pccr[pscnum]) >> 14) & 0x3) { |
657 | case 0: | 658 | case 0: |
658 | mclk_src = sys_clk.rate; | 659 | mclk_src = sys_clk.rate; |
659 | break; | 660 | break; |
@@ -668,7 +669,7 @@ static void psc_calc_rate(struct clk *clk, int pscnum, struct device_node *np) | |||
668 | break; | 669 | break; |
669 | } | 670 | } |
670 | 671 | ||
671 | mclk_div = ((clockctl->pccr[pscnum] >> 17) & 0x7fff) + 1; | 672 | mclk_div = ((in_be32(&clockctl->pccr[pscnum]) >> 17) & 0x7fff) + 1; |
672 | clk->rate = mclk_src / mclk_div; | 673 | clk->rate = mclk_src / mclk_div; |
673 | } | 674 | } |
674 | 675 | ||
@@ -680,13 +681,12 @@ static void psc_calc_rate(struct clk *clk, int pscnum, struct device_node *np) | |||
680 | static void psc_clks_init(void) | 681 | static void psc_clks_init(void) |
681 | { | 682 | { |
682 | struct device_node *np; | 683 | struct device_node *np; |
683 | const u32 *cell_index; | ||
684 | struct platform_device *ofdev; | 684 | struct platform_device *ofdev; |
685 | u32 reg; | ||
685 | 686 | ||
686 | for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { | 687 | for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { |
687 | cell_index = of_get_property(np, "cell-index", NULL); | 688 | if (!of_property_read_u32(np, "reg", ®)) { |
688 | if (cell_index) { | 689 | int pscnum = (reg & 0xf00) >> 8; |
689 | int pscnum = *cell_index; | ||
690 | struct clk *clk = psc_dev_clk(pscnum); | 690 | struct clk *clk = psc_dev_clk(pscnum); |
691 | 691 | ||
692 | clk->flags = CLK_HAS_RATE | CLK_HAS_CTRL; | 692 | clk->flags = CLK_HAS_RATE | CLK_HAS_CTRL; |
@@ -696,7 +696,7 @@ static void psc_clks_init(void) | |||
696 | * AC97 is special rate clock does | 696 | * AC97 is special rate clock does |
697 | * not go through normal path | 697 | * not go through normal path |
698 | */ | 698 | */ |
699 | if (strcmp("ac97", np->name) == 0) | 699 | if (of_device_is_compatible(np, "fsl,mpc5121-psc-ac97")) |
700 | clk->rate = ac97_clk.rate; | 700 | clk->rate = ac97_clk.rate; |
701 | else | 701 | else |
702 | psc_calc_rate(clk, pscnum, np); | 702 | psc_calc_rate(clk, pscnum, np); |
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index c7f47cfa9c29..d30235b7e3f7 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c | |||
@@ -426,8 +426,38 @@ void __init mpc512x_psc_fifo_init(void) | |||
426 | 426 | ||
427 | void __init mpc512x_init(void) | 427 | void __init mpc512x_init(void) |
428 | { | 428 | { |
429 | mpc512x_declare_of_platform_devices(); | ||
430 | mpc5121_clk_init(); | 429 | mpc5121_clk_init(); |
430 | mpc512x_declare_of_platform_devices(); | ||
431 | mpc512x_restart_init(); | 431 | mpc512x_restart_init(); |
432 | mpc512x_psc_fifo_init(); | 432 | mpc512x_psc_fifo_init(); |
433 | } | 433 | } |
434 | |||
435 | /** | ||
436 | * mpc512x_cs_config - Setup chip select configuration | ||
437 | * @cs: chip select number | ||
438 | * @val: chip select configuration value | ||
439 | * | ||
440 | * Perform chip select configuration for devices on LocalPlus Bus. | ||
441 | * Intended to dynamically reconfigure the chip select parameters | ||
442 | * for configurable devices on the bus. | ||
443 | */ | ||
444 | int mpc512x_cs_config(unsigned int cs, u32 val) | ||
445 | { | ||
446 | static struct mpc512x_lpc __iomem *lpc; | ||
447 | struct device_node *np; | ||
448 | |||
449 | if (cs > 7) | ||
450 | return -EINVAL; | ||
451 | |||
452 | if (!lpc) { | ||
453 | np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-lpc"); | ||
454 | lpc = of_iomap(np, 0); | ||
455 | of_node_put(np); | ||
456 | if (!lpc) | ||
457 | return -ENOMEM; | ||
458 | } | ||
459 | |||
460 | out_be32(&lpc->cs_cfg[cs], val); | ||
461 | return 0; | ||
462 | } | ||
463 | EXPORT_SYMBOL(mpc512x_cs_config); | ||