summaryrefslogtreecommitdiff
path: root/arch/powerpc/boot/4xx.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-12-21 15:39:26 +1100
committerJosh Boyer <jwboyer@linux.vnet.ibm.com>2007-12-23 13:13:14 -0600
commit619740384cebe2601a8d307654a22d9ed85f2fcb (patch)
treea354c4b83554f2c718afea3ba6aa91d50702e03d /arch/powerpc/boot/4xx.c
parent9dae8afdf212d39bc7c25f1b1ca9b10f10f6beaa (diff)
[POWERPC] 4xx: EP405 boards support for arch/powerpc
Brings EP405 support to arch/powerpc. The IRQ routing for the CPLD comes from a device-tree property, PCI is working to the point where I can see the video card, USB device, and south bridge. This should work with both EP405 and EP405PC. I've not totally figured out how IRQs are wired on this hardware though, thus at this stage, expect only USB interrupts working, pretty much the same as what arch/ppc did. Also, the flash, nvram, rtc and temp control still have to be wired. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> 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.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
index 3d0e4f921f1..852992b146e 100644
--- a/arch/powerpc/boot/4xx.c
+++ b/arch/powerpc/boot/4xx.c
@@ -179,13 +179,16 @@ void ibm40x_dbcr_reset(void)
#define EMAC_RESET 0x20000000
void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1)
{
- /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't do this for us */
+ /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't
+ * do this for us
+ */
if (emac0)
*emac0 = EMAC_RESET;
if (emac1)
*emac1 = EMAC_RESET;
mtdcr(DCRN_MAL0_CFG, MAL_RESET);
+ while (mfdcr(DCRN_MAL0_CFG) & MAL_RESET) {};
}
/* Read 4xx EBC bus bridge registers to get mappings of the peripheral
@@ -298,3 +301,53 @@ void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
dt_fixup_clock("/plb/opb/serial@ef600500", uart0);
dt_fixup_clock("/plb/opb/serial@ef600600", uart0);
}
+
+void ibm405gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
+{
+ u32 pllmr = mfdcr(DCRN_CPC0_PLLMR);
+ u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0);
+ u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1);
+ u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
+ u32 fwdv, fbdv, cbdv, opdv, epdv, udiv;
+
+ fwdv = (8 - ((pllmr & 0xe0000000) >> 29));
+ fbdv = (pllmr & 0x1e000000) >> 25;
+ cbdv = ((pllmr & 0x00060000) >> 17) + 1;
+ opdv = ((pllmr & 0x00018000) >> 15) + 1;
+ epdv = ((pllmr & 0x00001800) >> 13) + 2;
+ udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1;
+
+ m = fwdv * fbdv * cbdv;
+
+ cpu = sysclk * m / fwdv;
+ plb = cpu / cbdv;
+ opb = plb / opdv;
+ ebc = plb / epdv;
+
+ if (cpc0_cr0 & 0x80) {
+ /* uart0 uses the external clock */
+ uart0 = ser_clk;
+ } else {
+ uart0 = cpu / udiv;
+ }
+
+ if (cpc0_cr0 & 0x40) {
+ /* uart1 uses the external clock */
+ uart1 = ser_clk;
+ } else {
+ uart1 = cpu / udiv;
+ }
+
+ /* setup the timebase clock to tick at the cpu frequency */
+ cpc0_cr1 = cpc0_cr1 & ~0x00800000;
+ mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1);
+ tb = cpu;
+
+ dt_fixup_cpu_clocks(cpu, tb, 0);
+ dt_fixup_clock("/plb", plb);
+ dt_fixup_clock("/plb/opb", opb);
+ dt_fixup_clock("/plb/ebc", ebc);
+ dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
+ dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
+}
+