aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/4xx.c
diff options
context:
space:
mode:
authorMatthias Fuchs <matthias.fuchs@esd-electronics.com>2007-12-06 17:23:05 -0500
committerJosh Boyer <jwboyer@linux.vnet.ibm.com>2008-01-08 08:58:09 -0500
commit2af59f7d5c3e342db4bdd28c59090aee05577aef (patch)
tree39048f450e9046bff5c76c2c97ce0c8f72c5ddba /arch/powerpc/boot/4xx.c
parent5834584e4ea0b03c767e315a5879551b240c5652 (diff)
[POWERPC] 4xx: Add 405GPr and 405EP support in boot wrapper
This patch adds support for 405GPr processors with optional new mode strapping. ibm405gp_fixup_clocks() can now be used for 405GP and 405GPr CPUs. This is in preparation of porting the cpci405 platform support from arch/ppc to arch/powerpc. This patch also adds ibm405ep_fixup_clocks() to support 405EP CPUs from the boot wrapper. Signed-off-by: Matthias Fuchs <matthias.fuchs@esd-electronics.com> Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Diffstat (limited to 'arch/powerpc/boot/4xx.c')
-rw-r--r--arch/powerpc/boot/4xx.c81
1 files changed, 74 insertions, 7 deletions
diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
index 33f25b671340..61a4045324cb 100644
--- a/arch/powerpc/boot/4xx.c
+++ b/arch/powerpc/boot/4xx.c
@@ -499,20 +499,45 @@ void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk)
499 u32 pllmr = mfdcr(DCRN_CPC0_PLLMR); 499 u32 pllmr = mfdcr(DCRN_CPC0_PLLMR);
500 u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0); 500 u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0);
501 u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1); 501 u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1);
502 u32 psr = mfdcr(DCRN_405_CPC0_PSR);
502 u32 cpu, plb, opb, ebc, tb, uart0, uart1, m; 503 u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
503 u32 fwdv, fbdv, cbdv, opdv, epdv, udiv; 504 u32 fwdv, fwdvb, fbdv, cbdv, opdv, epdv, ppdv, udiv;
504 505
505 fwdv = (8 - ((pllmr & 0xe0000000) >> 29)); 506 fwdv = (8 - ((pllmr & 0xe0000000) >> 29));
506 fbdv = (pllmr & 0x1e000000) >> 25; 507 fbdv = (pllmr & 0x1e000000) >> 25;
507 cbdv = ((pllmr & 0x00060000) >> 17) + 1; 508 if (fbdv == 0)
508 opdv = ((pllmr & 0x00018000) >> 15) + 1; 509 fbdv = 16;
509 epdv = ((pllmr & 0x00001800) >> 13) + 2; 510 cbdv = ((pllmr & 0x00060000) >> 17) + 1; /* CPU:PLB */
511 opdv = ((pllmr & 0x00018000) >> 15) + 1; /* PLB:OPB */
512 ppdv = ((pllmr & 0x00001800) >> 13) + 1; /* PLB:PCI */
513 epdv = ((pllmr & 0x00001800) >> 11) + 2; /* PLB:EBC */
510 udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1; 514 udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1;
511 515
512 m = fwdv * fbdv * cbdv; 516 /* check for 405GPr */
517 if ((mfpvr() & 0xfffffff0) == (0x50910951 & 0xfffffff0)) {
518 fwdvb = 8 - (pllmr & 0x00000007);
519 if (!(psr & 0x00001000)) /* PCI async mode enable == 0 */
520 if (psr & 0x00000020) /* New mode enable */
521 m = fwdvb * 2 * ppdv;
522 else
523 m = fwdvb * cbdv * ppdv;
524 else if (psr & 0x00000020) /* New mode enable */
525 if (psr & 0x00000800) /* PerClk synch mode */
526 m = fwdvb * 2 * epdv;
527 else
528 m = fbdv * fwdv;
529 else if (epdv == fbdv)
530 m = fbdv * cbdv * epdv;
531 else
532 m = fbdv * fwdvb * cbdv;
513 533
514 cpu = sys_clk * m / fwdv; 534 cpu = sys_clk * m / fwdv;
515 plb = cpu / cbdv; 535 plb = sys_clk * m / (fwdvb * cbdv);
536 } else {
537 m = fwdv * fbdv * cbdv;
538 cpu = sys_clk * m / fwdv;
539 plb = cpu / cbdv;
540 }
516 opb = plb / opdv; 541 opb = plb / opdv;
517 ebc = plb / epdv; 542 ebc = plb / epdv;
518 543
@@ -541,3 +566,45 @@ void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk)
541 dt_fixup_clock("/plb/opb/serial@ef600400", uart1); 566 dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
542} 567}
543 568
569
570void ibm405ep_fixup_clocks(unsigned int sys_clk)
571{
572 u32 pllmr0 = mfdcr(DCRN_CPC0_PLLMR0);
573 u32 pllmr1 = mfdcr(DCRN_CPC0_PLLMR1);
574 u32 cpc0_ucr = mfdcr(DCRN_CPC0_UCR);
575 u32 cpu, plb, opb, ebc, uart0, uart1;
576 u32 fwdva, fwdvb, fbdv, cbdv, opdv, epdv;
577 u32 pllmr0_ccdv, tb, m;
578
579 fwdva = 8 - ((pllmr1 & 0x00070000) >> 16);
580 fwdvb = 8 - ((pllmr1 & 0x00007000) >> 12);
581 fbdv = (pllmr1 & 0x00f00000) >> 20;
582 if (fbdv == 0)
583 fbdv = 16;
584
585 cbdv = ((pllmr0 & 0x00030000) >> 16) + 1; /* CPU:PLB */
586 epdv = ((pllmr0 & 0x00000300) >> 8) + 2; /* PLB:EBC */
587 opdv = ((pllmr0 & 0x00003000) >> 12) + 1; /* PLB:OPB */
588
589 m = fbdv * fwdvb;
590
591 pllmr0_ccdv = ((pllmr0 & 0x00300000) >> 20) + 1;
592 if (pllmr1 & 0x80000000)
593 cpu = sys_clk * m / (fwdva * pllmr0_ccdv);
594 else
595 cpu = sys_clk / pllmr0_ccdv;
596
597 plb = cpu / cbdv;
598 opb = plb / opdv;
599 ebc = plb / epdv;
600 tb = cpu;
601 uart0 = cpu / (cpc0_ucr & 0x0000007f);
602 uart1 = cpu / ((cpc0_ucr & 0x00007f00) >> 8);
603
604 dt_fixup_cpu_clocks(cpu, tb, 0);
605 dt_fixup_clock("/plb", plb);
606 dt_fixup_clock("/plb/opb", opb);
607 dt_fixup_clock("/plb/ebc", ebc);
608 dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
609 dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
610}