From ed4633c93a01220431b9bf8a69dcaed7b3894023 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 13 Jun 2006 18:55:07 +0200 Subject: Minor cleanup for PCS440EP board Patch by Stefan Roese, 13 Jun 2006 --- cpu/ppc4xx/spd_sdram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/spd_sdram.c b/cpu/ppc4xx/spd_sdram.c index ebd5f39..c0a6933 100644 --- a/cpu/ppc4xx/spd_sdram.c +++ b/cpu/ppc4xx/spd_sdram.c @@ -745,7 +745,7 @@ long int spd_sdram(void) { */ check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) /* * Soft-reset SDRAM controller. */ -- cgit v1.1 From 6c5879f380be38d85fef0d3aba3353358f4b2ff4 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Fri, 30 Jun 2006 16:30:46 +0200 Subject: Add support for AMCC 440SPe CPU based eval board (Yucca). --- cpu/ppc4xx/405gp_pci.c | 9 +- cpu/ppc4xx/4xx_enet.c | 78 +++++++++++---- cpu/ppc4xx/cpu.c | 18 +++- cpu/ppc4xx/interrupts.c | 123 ++++++++++++++++++++--- cpu/ppc4xx/miiphy.c | 59 ++++++++--- cpu/ppc4xx/serial.c | 39 ++++++-- cpu/ppc4xx/speed.c | 254 +++++++++++++++++++++++++++++++++++++++++++++++- cpu/ppc4xx/start.S | 70 +++++++++++-- cpu/ppc4xx/vecnum.h | 43 +++++++- 9 files changed, 623 insertions(+), 70 deletions(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c index 64431ab..2fda60e 100644 --- a/cpu/ppc4xx/405gp_pci.c +++ b/cpu/ppc4xx/405gp_pci.c @@ -437,7 +437,7 @@ void pci_440_init (struct pci_controller *hose) * The PCI initialization sequence enable bit must be set ... if not abort * pci setup since updating the bit requires chip reset. *--------------------------------------------------------------------------*/ -#if defined(CONFIG_440GX) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE) unsigned long strap; mfsdr(sdr_sdstp1,strap); @@ -501,7 +501,7 @@ void pci_440_init (struct pci_controller *hose) out16r( PCIX0_CLS, 0x00060000 ); /* Bridge, host bridge */ #endif -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) out32r( PCIX0_BRDGOPT1, 0x04000060 ); /* PLB Rq pri highest */ out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 0x83 ); /* Enable host config, clear Timeout, ensure int src1 */ #elif defined(PCIX0_BRDGOPT1) @@ -519,8 +519,13 @@ void pci_440_init (struct pci_controller *hose) out32r( PCIX0_POM0SA, 0 ); /* disable */ out32r( PCIX0_POM1SA, 0 ); /* disable */ out32r( PCIX0_POM2SA, 0 ); /* disable */ +#if defined(CONFIG_440SPE) + out32r( PCIX0_POM0LAL, 0x10000000 ); + out32r( PCIX0_POM0LAH, 0x0000000c ); +#else out32r( PCIX0_POM0LAL, 0x00000000 ); out32r( PCIX0_POM0LAH, 0x00000003 ); +#endif out32r( PCIX0_POM0PCIAL, CFG_PCI_MEMBASE ); out32r( PCIX0_POM0PCIAH, 0x00000000 ); out32r( PCIX0_POM0SA, 0xf0000001 ); /* 256MB, enabled */ diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c index 86dc2d0..fab65af 100644 --- a/cpu/ppc4xx/4xx_enet.c +++ b/cpu/ppc4xx/4xx_enet.c @@ -181,6 +181,9 @@ static void ppc_4xx_eth_halt (struct eth_device *dev) { EMAC_4XX_HW_PST hw_p = dev->priv; uint32_t failsafe = 10000; +#if defined(CONFIG_440SPE) + unsigned long mfr; +#endif out32 (EMAC_IER + hw_p->hw_addr, 0x00000000); /* disable emac interrupts */ @@ -202,8 +205,23 @@ static void ppc_4xx_eth_halt (struct eth_device *dev) } /* EMAC RESET */ +#if defined(CONFIG_440SPE) + /* provide clocks for EMAC internal loopback */ + mfsdr (sdr_mfr, mfr); + mfr |= 0x08000000; + mtsdr(sdr_mfr, mfr); +#endif + out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST); +#if defined(CONFIG_440SPE) + /* remove clocks for EMAC internal loopback */ + mfsdr (sdr_mfr, mfr); + mfr &= ~0x08000000; + mtsdr(sdr_mfr, mfr); +#endif + + #ifndef CONFIG_NETCONSOLE hw_p->print_speed = 1; /* print speed message again next time */ #endif @@ -301,7 +319,7 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis) return ((int)pfc1); } -#endif +#endif /* CONFIG_440_GX */ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) { @@ -314,12 +332,16 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) unsigned mode_reg; unsigned short devnum; unsigned short reg_short; -#if defined(CONFIG_440GX) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE) sys_info_t sysinfo; -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) int ethgroup = -1; #endif #endif +#if defined(CONFIG_440SPE) + unsigned long mfr; +#endif + EMAC_4XX_HW_PST hw_p = dev->priv; @@ -330,7 +352,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) return -1; } -#if defined(CONFIG_440GX) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE) /* Need to get the OPB frequency so we can access the PHY */ get_sys_info (&sysinfo); #endif @@ -360,6 +382,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) hw_p->stats.pkts_tx = 0; hw_p->stats.pkts_rx = 0; hw_p->stats.pkts_handled = 0; + hw_p->print_speed = 1; /* print speed message again next time */ #endif hw_p->tx_err_index = 0; /* Transmit Error Index for tx_err_log */ @@ -373,7 +396,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) hw_p->tx_i_index = 0; /* Transmit Interrupt Queue Index */ hw_p->tx_u_index = 0; /* Transmit User Queue Index */ -#if defined(CONFIG_440) && !defined(CONFIG_440SP) +#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) /* set RMII mode */ /* NOTE: 440GX spec states that mode is mutually exclusive */ /* NOTE: Therefore, disable all other EMACS, since we handle */ @@ -406,6 +429,12 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) __asm__ volatile ("eieio"); /* reset emac so we have access to the phy */ +#if defined(CONFIG_440SPE) + /* provide clocks for EMAC internal loopback */ + mfsdr (sdr_mfr, mfr); + mfr |= 0x08000000; + mtsdr(sdr_mfr, mfr); +#endif out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST); __asm__ volatile ("eieio"); @@ -416,7 +445,14 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) failsafe--; } -#if defined(CONFIG_440GX) || defined(CONFIG_440SP) +#if defined(CONFIG_440SPE) + /* remove clocks for EMAC internal loopback */ + mfsdr (sdr_mfr, mfr); + mfr &= ~0x08000000; + mtsdr(sdr_mfr, mfr); +#endif + +#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE) /* Whack the M1 register */ mode_reg = 0x0; mode_reg &= ~0x00000038; @@ -468,7 +504,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) if (hw_p->first_init == 0) { miiphy_reset (dev->name, reg); -#if defined(CONFIG_440GX) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE) #if defined(CONFIG_CIS8201_PHY) /* * Cicada 8201 PHY needs to have an extended register whacked @@ -544,7 +580,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) (int) speed, (duplex == HALF) ? "HALF" : "FULL"); } -#if defined(CONFIG_440) && !defined(CONFIG_440SP) +#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) #if defined(CONFIG_440EP) || defined(CONFIG_440GR) mfsdr(sdr_mfr, reg); if (speed == 100) { @@ -575,7 +611,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) #endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */ /* set the Mal configuration reg */ -#if defined(CONFIG_440GX) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE) mtdcr (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT | MAL_CR_EOPIE | 0x00330000); #else @@ -759,8 +795,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) /* set speed */ if (speed == _1000BASET) { -#if defined(CONFIG_440SP) -#define SDR0_PFC1_EM_1000 0x00200000 +#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) unsigned long pfc1; mfsdr (sdr_pfc1, pfc1); pfc1 |= SDR0_PFC1_EM_1000; @@ -787,7 +822,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) /* set receive low/high water mark register */ #if defined(CONFIG_440) - /* 440GP has a 64 byte burst length */ + /* 440s has a 64 byte burst length */ out32 (EMAC_RX_HI_LO_WMARK + hw_p->hw_addr, 0x80009000); #else /* 405s have a 16 byte burst length */ @@ -895,7 +930,7 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr, #if defined (CONFIG_440) -#if defined(CONFIG_440SP) +#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) /* * Hack: On 440SP all enet irq sources are located on UIC1 * Needs some cleanup. --sr @@ -1367,21 +1402,20 @@ int ppc_4xx_eth_initialize (bd_t * bis) #endif /* set phy num and mode */ bis->bi_phynum[0] = CONFIG_PHY_ADDR; + bis->bi_phymode[0] = 0; + #if defined(CONFIG_PHY1_ADDR) bis->bi_phynum[1] = CONFIG_PHY1_ADDR; + bis->bi_phymode[1] = 0; #endif #if defined(CONFIG_440GX) bis->bi_phynum[2] = CONFIG_PHY2_ADDR; bis->bi_phynum[3] = CONFIG_PHY3_ADDR; - bis->bi_phymode[0] = 0; - bis->bi_phymode[1] = 0; bis->bi_phymode[2] = 2; bis->bi_phymode[3] = 2; -#if defined (CONFIG_440GX) ppc_4xx_eth_setup_bridge(0, bis); #endif -#endif for (eth_num = 0; eth_num < LAST_EMAC_NUM; eth_num++) { @@ -1478,9 +1512,15 @@ int ppc_4xx_eth_initialize (bd_t * bis) if (0 == virgin) { /* set the MAL IER ??? names may change with new spec ??? */ +#if defined(CONFIG_440SPE) + mal_ier = + MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE | + MAL_IER_DE | MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE ; +#else mal_ier = MAL_IER_DE | MAL_IER_NE | MAL_IER_TE | MAL_IER_OPBE | MAL_IER_PLBE; +#endif mtdcr (malesr, 0xffffffff); /* clear pending interrupts */ mtdcr (maltxdeir, 0xffffffff); /* clear pending interrupts */ mtdcr (malrxdeir, 0xffffffff); /* clear pending interrupts */ @@ -1510,11 +1550,13 @@ int ppc_4xx_eth_initialize (bd_t * bis) #else emac0_dev = dev; #endif + +#if defined(CONFIG_NET_MULTI) #if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) miiphy_register (dev->name, emac4xx_miiphy_read, emac4xx_miiphy_write); #endif - +#endif } /* end for each supported device */ return (1); } diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index a26533c..3e85a88 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -78,7 +78,9 @@ int pci_arbiter_enabled(void) return (mfdcr(cpc0_strp1) & CPC0_STRP1_PAE_MASK); #endif -#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \ + defined(CONFIG_440GR) || defined(CONFIG_440SP) || \ + defined(CONFIG_440SPE) unsigned long val; mfsdr(sdr_sdstp1, val); @@ -87,8 +89,8 @@ int pci_arbiter_enabled(void) } #endif -#if defined(CONFIG_405EP)|| defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ - defined(CONFIG_440GX) || defined(CONFIG_440SP) +#if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ + defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE) #define I2C_BOOTROM @@ -98,7 +100,9 @@ int i2c_bootrom_enabled(void) return (mfdcr(cpc0_boot) & CPC0_BOOT_SEP); #endif -#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \ + defined(CONFIG_440GR) || defined(CONFIG_440SP) || \ + defined(CONFIG_440SPE) unsigned long val; mfsdr(sdr_sdcs, val); @@ -237,6 +241,12 @@ int checkcpu (void) puts("SP Rev. B"); break; + case PVR_440SPe_RA: + puts("SPe 3GA533C"); + break; + case PVR_440SPe_RB: + puts("SPe 3GB533C"); + break; default: printf (" UNKNOWN (PVR=%08x)", pvr); break; diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c index 1d8dc7c..fdae846 100644 --- a/cpu/ppc4xx/interrupts.c +++ b/cpu/ppc4xx/interrupts.c @@ -48,18 +48,22 @@ struct irq_action { }; static struct irq_action irq_vecs[32]; +void uic0_interrupt( void * parms); /* UIC0 handler */ #if defined(CONFIG_440) static struct irq_action irq_vecs1[32]; /* For UIC1 */ void uic1_interrupt( void * parms); /* UIC1 handler */ -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) static struct irq_action irq_vecs2[32]; /* For UIC2 */ - -void uic0_interrupt( void * parms); /* UIC0 handler */ void uic2_interrupt( void * parms); /* UIC2 handler */ -#endif /* CONFIG_440GX */ +#endif /* CONFIG_440GX CONFIG_440SPE */ + +#if defined(CONFIG_440SPE) +static struct irq_action irq_vecs3[32]; /* For UIC3 */ +void uic3_interrupt( void * parms); /* UIC3 handler */ +#endif /* CONFIG_440SPE */ #endif /* CONFIG_440 */ @@ -115,11 +119,16 @@ int interrupt_init_cpu (unsigned *decrementer_count) irq_vecs1[vec].handler = NULL; irq_vecs1[vec].arg = NULL; irq_vecs1[vec].count = 0; -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) irq_vecs2[vec].handler = NULL; irq_vecs2[vec].arg = NULL; irq_vecs2[vec].count = 0; #endif /* CONFIG_440GX */ +#if defined(CONFIG_440SPE) + irq_vecs3[vec].handler = NULL; + irq_vecs3[vec].arg = NULL; + irq_vecs3[vec].count = 0; +#endif /* CONFIG_440SPE */ #endif } @@ -221,6 +230,34 @@ void external_interrupt(struct pt_regs *regs) } /* external_interrupt CONFIG_440GX */ +#elif defined(CONFIG_440SPE) +void external_interrupt(struct pt_regs *regs) +{ + ulong uic_msr; + + /* + * Read masked interrupt status register to determine interrupt source + */ + /* 440 SPe uses base uic register */ + uic_msr = mfdcr(uic0msr); + + if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) ) + uic1_interrupt(0); + + if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) ) + uic2_interrupt(0); + + if ( (UICB0_UIC3CI & uic_msr) || (UICB0_UIC3NCI & uic_msr) ) + uic3_interrupt(0); + + if (uic_msr & ~(UICB0_ALL)) + uic0_interrupt(0); + + mtdcr(uic0sr, uic_msr); + + return; +} /* external_interrupt CONFIG_440SPE */ + #else void external_interrupt(struct pt_regs *regs) @@ -266,7 +303,7 @@ void external_interrupt(struct pt_regs *regs) } #endif -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) /* Handler for UIC0 interrupt */ void uic0_interrupt( void * parms) { @@ -357,8 +394,8 @@ void uic1_interrupt( void * parms) } #endif /* defined(CONFIG_440) */ -#if defined(CONFIG_440GX) -/* Handler for UIC1 interrupt */ +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) +/* Handler for UIC2 interrupt */ void uic2_interrupt( void * parms) { ulong uic2_msr; @@ -384,7 +421,7 @@ void uic2_interrupt( void * parms) (*irq_vecs2[vec].handler)(irq_vecs2[vec].arg); } else { mtdcr(uic2er, mfdcr(uic2er) & ~(0x80000000 >> vec)); - printf ("Masking bogus interrupt vector (uic1) 0x%x\n", vec); + printf ("Masking bogus interrupt vector (uic2) 0x%x\n", vec); } /* @@ -402,6 +439,51 @@ void uic2_interrupt( void * parms) } #endif /* defined(CONFIG_440GX) */ +#if defined(CONFIG_440SPE) +/* Handler for UIC3 interrupt */ +void uic3_interrupt( void * parms) +{ + ulong uic3_msr; + ulong msr_shift; + int vec; + + /* + * Read masked interrupt status register to determine interrupt source + */ + uic3_msr = mfdcr(uic3msr); + msr_shift = uic3_msr; + vec = 0; + + while (msr_shift != 0) { + if (msr_shift & 0x80000000) { + /* + * Increment irq counter (for debug purpose only) + */ + irq_vecs3[vec].count++; + + if (irq_vecs3[vec].handler != NULL) { + /* call isr */ + (*irq_vecs3[vec].handler)(irq_vecs3[vec].arg); + } else { + mtdcr(uic3er, mfdcr(uic3er) & ~(0x80000000 >> vec)); + printf ("Masking bogus interrupt vector (uic3) 0x%x\n", vec); + } + + /* + * After servicing the interrupt, we have to remove the status indicator. + */ + mtdcr(uic3sr, (0x80000000 >> vec)); + } + + /* + * Shift msr to next position and increment vector + */ + msr_shift <<= 1; + vec++; + } +} +#endif /* defined(CONFIG_440SPE) */ + /****************************************************************************/ /* @@ -414,7 +496,7 @@ void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg) int i = vec; #if defined(CONFIG_440) -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) if ((vec > 31) && (vec < 64)) { i = vec - 32; irqa = irq_vecs1; @@ -441,7 +523,7 @@ void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg) irqa[i].arg = arg; #if defined(CONFIG_440) -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) if ((vec > 31) && (vec < 64)) mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i)); else if (vec > 63) @@ -464,7 +546,7 @@ void irq_free_handler (int vec) int i = vec; #if defined(CONFIG_440) -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) if ((vec > 31) && (vec < 64)) { irqa = irq_vecs1; i = vec - 32; @@ -485,7 +567,7 @@ void irq_free_handler (int vec) #endif #if defined(CONFIG_440) -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) if ((vec > 31) && (vec < 64)) mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i)); else if (vec > 63) @@ -553,7 +635,7 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("\n"); #endif -#if defined(CONFIG_440GX) +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) printf ("\nUIC 2\n"); printf ("Nr Routine Arg Count\n"); @@ -566,6 +648,19 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("\n"); #endif +#if defined(CONFIG_440SPE) + printf ("\nUIC 3\n"); + printf ("Nr Routine Arg Count\n"); + + for (vec=0; vec<32; vec++) { + if (irq_vecs3[vec].handler != NULL) + printf ("%02d %08lx %08lx %d\n", + vec+63, (ulong)irq_vecs3[vec].handler, + (ulong)irq_vecs3[vec].arg, irq_vecs3[vec].count); + } + printf("\n"); +#endif + return 0; } #endif /* CONFIG_COMMANDS & CFG_CMD_IRQ */ diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c index f26f2a2..aa580ed 100644 --- a/cpu/ppc4xx/miiphy.c +++ b/cpu/ppc4xx/miiphy.c @@ -50,7 +50,7 @@ #include <405_mal.h> #include - +#undef ET_DEBUG /***********************************************************/ /* Dump out to the screen PHY regs */ /***********************************************************/ @@ -90,6 +90,10 @@ int phy_setup_aneg (char *devname, unsigned char addr) PHY_ANLPAR_10); miiphy_write (devname, addr, PHY_ANAR, adv); + miiphy_read (devname, addr, PHY_1000BTCR, &adv); + adv |= (0x0300); + miiphy_write (devname, addr, PHY_1000BTCR, adv); + /* Start/Restart aneg */ miiphy_read (devname, addr, PHY_BMCR, &ctl); ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); @@ -104,7 +108,7 @@ int phy_setup_aneg (char *devname, unsigned char addr) /***********************************************************/ unsigned int miiphy_getemac_offset (void) { -#if (defined(CONFIG_440) && !defined(CONFIG_440SP)) && defined(CONFIG_NET_MULTI) +#if (defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)) && defined(CONFIG_NET_MULTI) unsigned long zmii; unsigned long eoffset; @@ -155,10 +159,12 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr, i = 0; /* see if it is ready for sec */ - while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == 0) { + while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) { udelay (7); if (i > 5) { -#if 0 +#ifdef ET_DEBUG + sta_reg = in32 (EMAC_STACR + emac_reg); + printf ("read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ printf ("read err 1\n"); #endif return -1; @@ -167,31 +173,41 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr, } sta_reg = reg; /* reg address */ /* set clock (50Mhz) and read flags */ -#if defined(CONFIG_440GX) - sta_reg |= EMAC_STACR_READ; +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) +#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */ + sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_READ; +#else + sta_reg |= EMAC_STACR_READ; +#endif #else sta_reg = (sta_reg | EMAC_STACR_READ) & ~EMAC_STACR_CLK_100MHZ; #endif -#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) +#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && !defined(CONFIG__440SP) && !defined(CONFIG__440SPE) sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ; #endif sta_reg = sta_reg | (addr << 5); /* Phy address */ - + sta_reg = sta_reg | EMAC_STACR_OC_MASK; /* new IBM emac v4 */ out32 (EMAC_STACR + emac_reg, sta_reg); -#if 0 /* test-only */ +#ifdef ET_DEBUG printf ("a2: write: EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ #endif sta_reg = in32 (EMAC_STACR + emac_reg); +#ifdef ET_DEBUG + printf ("a21: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ +#endif i = 0; - while ((sta_reg & EMAC_STACR_OC) == 0) { + while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) { udelay (7); if (i > 5) { return -1; } i++; sta_reg = in32 (EMAC_STACR + emac_reg); +#ifdef ET_DEBUG + printf ("a22: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ +#endif } if ((sta_reg & EMAC_STACR_PHYE) != 0) { return -1; @@ -219,7 +235,7 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr, /* see if it is ready for 1000 nsec */ i = 0; - while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == 0) { + while ((in32 (EMAC_STACR + emac_reg) & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) { if (i > 5) return -1; udelay (7); @@ -228,16 +244,21 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr, sta_reg = 0; sta_reg = reg; /* reg address */ /* set clock (50Mhz) and read flags */ -#if defined(CONFIG_440GX) - sta_reg |= EMAC_STACR_WRITE; +#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) +#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */ + sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_WRITE; +#else + sta_reg |= EMAC_STACR_WRITE; +#endif #else sta_reg = (sta_reg | EMAC_STACR_WRITE) & ~EMAC_STACR_CLK_100MHZ; #endif -#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) +#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && !defined(CONFIG__440SP) && !defined(CONFIG__440SPE) sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ; /* Set clock frequency (PLB freq. dependend) */ #endif - sta_reg = sta_reg | ((unsigned long) addr << 5); /* Phy address */ + sta_reg = sta_reg | ((unsigned long) addr << 5);/* Phy address */ + sta_reg = sta_reg | EMAC_STACR_OC_MASK; /* new IBM emac v4 */ memcpy (&sta_reg, &value, 2); /* put in data */ out32 (EMAC_STACR + emac_reg, sta_reg); @@ -245,12 +266,18 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr, /* wait for completion */ i = 0; sta_reg = in32 (EMAC_STACR + emac_reg); - while ((sta_reg & EMAC_STACR_OC) == 0) { +#ifdef ET_DEBUG + printf ("a31: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ +#endif + while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK) { udelay (7); if (i > 5) return -1; i++; sta_reg = in32 (EMAC_STACR + emac_reg); +#ifdef ET_DEBUG + printf ("a32: read : EMAC_STACR=0x%0x\n", sta_reg); /* test-only */ +#endif } if ((sta_reg & EMAC_STACR_PHYE) != 0) diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c index e7f6bcb..2734520 100644 --- a/cpu/ppc4xx/serial.c +++ b/cpu/ppc4xx/serial.c @@ -277,11 +277,11 @@ int serial_tstc () #define UART1_BASE CFG_PERIPHERAL_BASE + 0x00000300 #endif -#if defined(CONFIG_440SP) +#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) #define UART2_BASE CFG_PERIPHERAL_BASE + 0x00000600 #endif -#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) || defined(CONFIG_440SPE) #define CR0_MASK 0xdfffffff #define CR0_EXTCLK_ENA 0x00800000 #define CR0_UDIV_POS 0 @@ -311,14 +311,18 @@ int serial_tstc () #if defined(CONFIG_UART1_CONSOLE) #define ACTING_UART0_BASE UART1_BASE #define ACTING_UART1_BASE UART0_BASE -#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \ + defined(CONFIG_440GR) || defined(CONFIG_440SP) || \ + defined(CONFIG_440SPE) #define UART0_SDR sdr_uart1 #define UART1_SDR sdr_uart0 #endif /* CONFIG_440GX */ #else #define ACTING_UART0_BASE UART0_BASE #define ACTING_UART1_BASE UART1_BASE -#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \ + defined(CONFIG_440GR) || defined(CONFIG_440SP) || \ + defined(CONFIG_440SPE) #define UART0_SDR sdr_uart0 #define UART1_SDR sdr_uart1 #endif /* CONFIG_440GX */ @@ -441,7 +445,8 @@ int serial_init(void) unsigned long tmp; #endif -#if defined(CONFIG_440GX) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || \ + defined(CONFIG_440SPE) #if defined(CONFIG_SERIAL_MULTI) if (UART0_BASE == dev_base) { mfsdr(UART0_SDR,reg); @@ -470,7 +475,9 @@ int serial_init(void) serial_divs (gd->baudrate, &udiv, &bdiv); #endif -#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) +#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \ + defined(CONFIG_440GR) || defined(CONFIG_440SP) || \ + defined(CONFIG_440SPE) reg |= udiv << CR0_UDIV_POS; /* set the UART divisor */ #if defined(CONFIG_SERIAL_MULTI) if (UART0_BASE == dev_base) { @@ -615,8 +622,28 @@ void serial_setbrg (void) #else udiv = ((mfdcr (cntrl0) & 0x3e) >> 1) + 1; #endif /* CONFIG_405EP */ + +#if !defined(CFG_EXT_SERIAL_CLOCK) && \ + ( defined(CONFIG_440GX) || defined(CONFIG_440EP) || \ + defined(CONFIG_440GR) || defined(CONFIG_440SP) || \ + defined(CONFIG_440SPE) ) + serial_divs (gd->baudrate, &udiv, &bdiv); + tmp = udiv << CR0_UDIV_POS; /* set the UART divisor */ +#if defined(CONFIG_SERIAL_MULTI) + if (UART0_BASE == dev_base) { + mtsdr (UART0_SDR, tmp); + } else { + mtsdr (UART1_SDR, tmp); + } +#else + mtsdr (UART0_SDR, tmp); +#endif + +#else + tmp = gd->baudrate * udiv * 16; bdiv = (clk + tmp / 2) / tmp; +#endif /* !defined(CFG_EXT_SERIAL_CLOCK) && (...) */ #if defined(CONFIG_SERIAL_MULTI) out8 (dev_base + UART_LCR, 0x80); /* set DLAB bit */ diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c index 553c491..7778271 100644 --- a/cpu/ppc4xx/speed.c +++ b/cpu/ppc4xx/speed.c @@ -29,7 +29,11 @@ /* ------------------------------------------------------------------------- */ #define ONE_BILLION 1000000000 - +#ifdef DEBUG +#define DEBUGF(fmt,args...) printf(fmt ,##args) +#else +#define DEBUGF(fmt,args...) +#endif #if defined(CONFIG_405GP) || defined(CONFIG_405CR) @@ -283,7 +287,7 @@ ulong get_PCI_freq (void) return sys_info.freqPCI; } -#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) +#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) void get_sys_info (sys_info_t * sysInfo) { unsigned long strp0; @@ -326,6 +330,26 @@ void get_sys_info (sys_info_t * sysInfo) unsigned long m; unsigned long prbdv0; +#if defined(CONFIG_440SPE) + unsigned long sys_freq; + unsigned long sys_per=0; + unsigned long msr; + unsigned long pci_clock_per; + unsigned long sdr_ddrpll; + + /*-------------------------------------------------------------------------+ + | Get the system clock period. + +-------------------------------------------------------------------------*/ + sys_per = determine_sysper(); + + msr = (mfmsr () & ~(MSR_EE)); /* disable interrupts */ + + /*-------------------------------------------------------------------------+ + | Calculate the system clock speed from the period. + +-------------------------------------------------------------------------*/ + sys_freq=(ONE_BILLION/sys_per)*1000; +#endif + /* Extract configured divisors */ mfsdr( sdr_sdstp0,strp0 ); mfsdr( sdr_sdstp1,strp1 ); @@ -360,12 +384,238 @@ void get_sys_info (sys_info_t * sysInfo) m = sysInfo->pllExtBusDiv * sysInfo->pllOpbDiv * sysInfo->pllFwdDivB; /* Now calculate the individual clocks */ +#if defined(CONFIG_440SPE) + sysInfo->freqVCOMhz = (m * sys_freq) ; +#else sysInfo->freqVCOMhz = (m * CONFIG_SYS_CLK_FREQ) + (m>>1); +#endif sysInfo->freqProcessor = sysInfo->freqVCOMhz/sysInfo->pllFwdDivA; sysInfo->freqPLB = sysInfo->freqVCOMhz/sysInfo->pllFwdDivB/prbdv0; sysInfo->freqOPB = sysInfo->freqPLB/sysInfo->pllOpbDiv; sysInfo->freqEPB = sysInfo->freqOPB/sysInfo->pllExtBusDiv; +#if defined(CONFIG_440SPE) + /* Determine PCI Clock Period */ + pci_clock_per = determine_pci_clock_per(); + sysInfo->freqPCI = (ONE_BILLION/pci_clock_per) * 1000; + mfsdr(sdr_ddr0, sdr_ddrpll); + sysInfo->freqDDR = ((sysInfo->freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll)); +#endif + + +} + +#endif + +#if defined(CONFIG_440SPE) +unsigned long determine_sysper(void) +{ + unsigned int fpga_clocking_reg; + unsigned int master_clock_selection; + unsigned long master_clock_per = 0; + unsigned long fb_div_selection; + unsigned int vco_div_reg_value; + unsigned long vco_div_selection; + unsigned long sys_per = 0; + int extClkVal; + + /*-------------------------------------------------------------------------+ + | Read FPGA reg 0 and reg 1 to get FPGA reg information + +-------------------------------------------------------------------------*/ + fpga_clocking_reg = in16(FPGA_REG16); + + + /* Determine Master Clock Source Selection */ + master_clock_selection = fpga_clocking_reg & FPGA_REG16_MASTER_CLK_MASK; + + switch(master_clock_selection) { + case FPGA_REG16_MASTER_CLK_66_66: + master_clock_per = PERIOD_66_66MHZ; + break; + case FPGA_REG16_MASTER_CLK_50: + master_clock_per = PERIOD_50_00MHZ; + break; + case FPGA_REG16_MASTER_CLK_33_33: + master_clock_per = PERIOD_33_33MHZ; + break; + case FPGA_REG16_MASTER_CLK_25: + master_clock_per = PERIOD_25_00MHZ; + break; + case FPGA_REG16_MASTER_CLK_EXT: + if ((extClkVal==EXTCLK_33_33) + && (extClkVal==EXTCLK_50) + && (extClkVal==EXTCLK_66_66) + && (extClkVal==EXTCLK_83)) { + /* calculate master clock period from external clock value */ + master_clock_per=(ONE_BILLION/extClkVal) * 1000; + } else { + /* Unsupported */ + DEBUGF ("%s[%d] *** master clock selection failed ***\n", __FUNCTION__,__LINE__); + hang(); + } + break; + default: + /* Unsupported */ + DEBUGF ("%s[%d] *** master clock selection failed ***\n", __FUNCTION__,__LINE__); + hang(); + break; + } + + /* Determine FB divisors values */ + if ((fpga_clocking_reg & FPGA_REG16_FB1_DIV_MASK) == FPGA_REG16_FB1_DIV_LOW) { + if ((fpga_clocking_reg & FPGA_REG16_FB2_DIV_MASK) == FPGA_REG16_FB2_DIV_LOW) + fb_div_selection = FPGA_FB_DIV_6; + else + fb_div_selection = FPGA_FB_DIV_12; + } else { + if ((fpga_clocking_reg & FPGA_REG16_FB2_DIV_MASK) == FPGA_REG16_FB2_DIV_LOW) + fb_div_selection = FPGA_FB_DIV_10; + else + fb_div_selection = FPGA_FB_DIV_20; + } + + /* Determine VCO divisors values */ + vco_div_reg_value = fpga_clocking_reg & FPGA_REG16_VCO_DIV_MASK; + + switch(vco_div_reg_value) { + case FPGA_REG16_VCO_DIV_4: + vco_div_selection = FPGA_VCO_DIV_4; + break; + case FPGA_REG16_VCO_DIV_6: + vco_div_selection = FPGA_VCO_DIV_6; + break; + case FPGA_REG16_VCO_DIV_8: + vco_div_selection = FPGA_VCO_DIV_8; + break; + case FPGA_REG16_VCO_DIV_10: + default: + vco_div_selection = FPGA_VCO_DIV_10; + break; + } + + if (master_clock_selection == FPGA_REG16_MASTER_CLK_EXT) { + switch(master_clock_per) { + case PERIOD_25_00MHZ: + if (fb_div_selection == FPGA_FB_DIV_12) { + if (vco_div_selection == FPGA_VCO_DIV_4) + sys_per = PERIOD_75_00MHZ; + if (vco_div_selection == FPGA_VCO_DIV_6) + sys_per = PERIOD_50_00MHZ; + } + break; + case PERIOD_33_33MHZ: + if (fb_div_selection == FPGA_FB_DIV_6) { + if (vco_div_selection == FPGA_VCO_DIV_4) + sys_per = PERIOD_50_00MHZ; + if (vco_div_selection == FPGA_VCO_DIV_6) + sys_per = PERIOD_33_33MHZ; + } + if (fb_div_selection == FPGA_FB_DIV_10) { + if (vco_div_selection == FPGA_VCO_DIV_4) + sys_per = PERIOD_83_33MHZ; + if (vco_div_selection == FPGA_VCO_DIV_10) + sys_per = PERIOD_33_33MHZ; + } + if (fb_div_selection == FPGA_FB_DIV_12) { + if (vco_div_selection == FPGA_VCO_DIV_4) + sys_per = PERIOD_100_00MHZ; + if (vco_div_selection == FPGA_VCO_DIV_6) + sys_per = PERIOD_66_66MHZ; + if (vco_div_selection == FPGA_VCO_DIV_8) + sys_per = PERIOD_50_00MHZ; + } + break; + case PERIOD_50_00MHZ: + if (fb_div_selection == FPGA_FB_DIV_6) { + if (vco_div_selection == FPGA_VCO_DIV_4) + sys_per = PERIOD_75_00MHZ; + if (vco_div_selection == FPGA_VCO_DIV_6) + sys_per = PERIOD_50_00MHZ; + } + if (fb_div_selection == FPGA_FB_DIV_10) { + if (vco_div_selection == FPGA_VCO_DIV_6) + sys_per = PERIOD_83_33MHZ; + if (vco_div_selection == FPGA_VCO_DIV_10) + sys_per = PERIOD_50_00MHZ; + } + if (fb_div_selection == FPGA_FB_DIV_12) { + if (vco_div_selection == FPGA_VCO_DIV_6) + sys_per = PERIOD_100_00MHZ; + if (vco_div_selection == FPGA_VCO_DIV_8) + sys_per = PERIOD_75_00MHZ; + } + break; + case PERIOD_66_66MHZ: + if (fb_div_selection == FPGA_FB_DIV_6) { + if (vco_div_selection == FPGA_VCO_DIV_4) + sys_per = PERIOD_100_00MHZ; + if (vco_div_selection == FPGA_VCO_DIV_6) + sys_per = PERIOD_66_66MHZ; + if (vco_div_selection == FPGA_VCO_DIV_8) + sys_per = PERIOD_50_00MHZ; + } + if (fb_div_selection == FPGA_FB_DIV_10) { + if (vco_div_selection == FPGA_VCO_DIV_8) + sys_per = PERIOD_83_33MHZ; + if (vco_div_selection == FPGA_VCO_DIV_10) + sys_per = PERIOD_66_66MHZ; + } + if (fb_div_selection == FPGA_FB_DIV_12) { + if (vco_div_selection == FPGA_VCO_DIV_8) + sys_per = PERIOD_100_00MHZ; + } + break; + default: + break; + } + + if (sys_per == 0) { + /* Other combinations are not supported */ + DEBUGF ("%s[%d] *** sys period compute failed ***\n", __FUNCTION__,__LINE__); + hang(); + } + } else { + /* calcul system clock without cheking */ + /* if engineering option clock no check is selected */ + /* sys_per = master_clock_per * vco_div_selection / fb_div_selection */ + sys_per = (master_clock_per/fb_div_selection) * vco_div_selection; + } + + return(sys_per); + +} + +/*-------------------------------------------------------------------------+ +| determine_pci_clock_per. ++-------------------------------------------------------------------------*/ +unsigned long determine_pci_clock_per(void) +{ + unsigned long pci_clock_selection, pci_period; + + /*-------------------------------------------------------------------------+ + | Read FPGA reg 6 to get PCI 0 FPGA reg information + +-------------------------------------------------------------------------*/ + pci_clock_selection = in16(FPGA_REG16); /* was reg6 averifier */ + + + pci_clock_selection = pci_clock_selection & FPGA_REG16_PCI0_CLK_MASK; + + switch (pci_clock_selection) { + case FPGA_REG16_PCI0_CLK_133_33: + pci_period = PERIOD_133_33MHZ; + break; + case FPGA_REG16_PCI0_CLK_100: + pci_period = PERIOD_100_00MHZ; + break; + case FPGA_REG16_PCI0_CLK_66_66: + pci_period = PERIOD_66_66MHZ; + break; + default: + pci_period = PERIOD_33_33MHZ;; + break; + } + + return(pci_period); } #endif diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 48b430d..c1e787f 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -155,6 +155,11 @@ /**************************************************************************/ _start_440: + /*----------------------------------------------------------------+ + | Core bug fix. Clear the esr + +-----------------------------------------------------------------*/ + addi r0,r0,0x0000 + mtspr esr,r0 /*----------------------------------------------------------------*/ /* Clear and set up some registers. */ /*----------------------------------------------------------------*/ @@ -166,7 +171,7 @@ _start_440: mtspr srr1,r0 mtspr csrr0,r0 mtspr csrr1,r0 -#if defined(CONFIG_440GX) || defined(CONFIG_440SP) /* NOTE: 440GX adds machine check status regs */ +#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE) /* NOTE: 440GX adds machine check status regs */ mtspr mcsrr0,r0 mtspr mcsrr1,r0 mfspr r1, mcsr @@ -200,6 +205,33 @@ _start_440: ori r1,r1,0x6000 /* cache touch */ mtspr ccr0,r1 +#if defined (CONFIG_440SPE) + /*----------------------------------------------------------------+ + | Initialize Core Configuration Reg1. + | a. ICDPEI: Record even parity. Normal operation. + | b. ICTPEI: Record even parity. Normal operation. + | c. DCTPEI: Record even parity. Normal operation. + | d. DCDPEI: Record even parity. Normal operation. + | e. DCUPEI: Record even parity. Normal operation. + | f. DCMPEI: Record even parity. Normal operation. + | g. FCOM: Normal operation + | h. MMUPEI: Record even parity. Normal operation. + | i. FFF: Flush only as much data as necessary. + | j. TCS: Timebase increments from externally supplied clock + +-----------------------------------------------------------------*/ + addis r0, r0, 0x0000 + ori r0, r0, 0x0080 + mtspr ccr1, r0 + + /*----------------------------------------------------------------+ + | Reset the timebase. + | The previous write to CCR1 sets the timebase source. + +-----------------------------------------------------------------*/ + addi r0, r0, 0x0000 + mtspr tbl, r0 + mtspr tbu, r0 +#endif + /*----------------------------------------------------------------*/ /* Setup interrupt vectors */ /*----------------------------------------------------------------*/ @@ -261,15 +293,26 @@ _start_440: mtspr ivlim,r1 mtspr dvlim,r1 + /*----------------------------------------------------------------+ + |Initialize MMUCR[STID] = 0. + +-----------------------------------------------------------------*/ + mfspr r0,mmucr + addis r1,0,0xFFFF + ori r1,r1,0xFF00 + and r0,r0,r1 + mtspr mmucr,r0 + /*----------------------------------------------------------------*/ /* Clear all TLB entries -- TID = 0, TS = 0 */ /*----------------------------------------------------------------*/ - mtspr mmucr,r0 + addis r0,0,0x0000 li r1,0x003f /* 64 TLB entries */ mtctr r1 -0: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/ +rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/ + tlbwe r0,r1,0x0001 + tlbwe r0,r1,0x0002 subi r1,r1,0x0001 - bdnz 0b + bdnz rsttlb /*----------------------------------------------------------------*/ /* TLB entry setup -- step thru tlbtab */ @@ -340,7 +383,7 @@ _start: mtspr tcr,r0 /* disable all */ mtspr esr,r0 /* clear exception syndrome register */ mtxer r0 /* clear integer exception register */ -#if !defined(CONFIG_440GX) +#if !defined(CONFIG_440GX) && !defined(CONFIG_440SPE) lis r1,0x0002 /* set CE bit (Critical Exceptions) */ ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */ mtmsr r1 /* change MSR */ @@ -394,7 +437,7 @@ __440gx_msr_continue: addi r3,r3,32 bdnz ..d_ag #else -#if defined (CONFIG_440GX) || defined(CONFIG_440SP) +#if defined (CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE) mtdcr l2_cache_cfg,r0 /* Ensure L2 Cache is off */ #endif mtdcr isram0_sb1cr,r0 /* Disable bank 1 */ @@ -421,6 +464,19 @@ __440gx_msr_continue: lis r1, 0x8003 ori r1,r1, 0x0980 /* fourth 64k */ mtdcr isram0_sb3cr,r1 +#elif defined(CONFIG_440SPE) + lis r1,0x0000 /* BAS = 0000_0000 */ + ori r1,r1,0x0984 /* first 64k */ + mtdcr isram0_sb0cr,r1 + lis r1,0x0001 + ori r1,r1,0x0984 /* second 64k */ + mtdcr isram0_sb1cr,r1 + lis r1, 0x0002 + ori r1,r1, 0x0984 /* third 64k */ + mtdcr isram0_sb2cr,r1 + lis r1, 0x0003 + ori r1,r1, 0x0984 /* fourth 64k */ + mtdcr isram0_sb3cr,r1 #else ori r1,r1,0x0380 /* 8k rw */ mtdcr isram0_sb0cr,r1 @@ -1220,7 +1276,7 @@ ppcSync: */ .globl relocate_code relocate_code: -#if defined(CONFIG_440EP) || defined(CONFIG_440GR) +#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SPE) dccci 0,0 /* Invalidate data cache, now no longer our stack */ sync addi r1,r0,0x0000 /* TLB entry #0 */ diff --git a/cpu/ppc4xx/vecnum.h b/cpu/ppc4xx/vecnum.h index cbfe41d..93cef02 100644 --- a/cpu/ppc4xx/vecnum.h +++ b/cpu/ppc4xx/vecnum.h @@ -31,7 +31,48 @@ #ifndef _VECNUMS_H_ #define _VECNUMS_H_ -#if defined(CONFIG_440SP) +#if defined(CONFIG_440SPE) +/* UIC 0 */ +#define VECNUM_U0 0 /* UART0 */ +#define VECNUM_U1 1 /* UART1 */ +#define VECNUM_IIC0 2 /* IIC0 */ +#define VECNUM_IIC1 3 /* IIC1 */ +#define VECNUM_PIM 4 /* PCI inbound message */ +#define VECNUM_PCRW 5 /* PCI command reg write */ +#define VECNUM_PPM 6 /* PCI power management */ +#define VECNUM_MSI0 7 /* PCI MSI level 0 */ +#define VECNUM_MSI1 8 /* PCI MSI level 0 */ +#define VECNUM_MSI2 9 /* PCI MSI level 0 */ +#define VECNUM_D0 12 /* DMA channel 0 */ +#define VECNUM_D1 13 /* DMA channel 1 */ +#define VECNUM_D2 14 /* DMA channel 2 */ +#define VECNUM_D3 15 /* DMA channel 3 */ +#define VECNUM_UIC1NC 30 /* UIC1 non-critical interrupt */ +#define VECNUM_UIC1C 31 /* UIC1 critical interrupt */ + +/* UIC 1 */ +#define VECNUM_MS (32 + 1 ) /* MAL SERR */ +#define VECNUM_TXDE (32 + 2 ) /* MAL TXDE */ +#define VECNUM_RXDE (32 + 3 ) /* MAL RXDE */ +#define VECNUM_MTE (32 + 6 ) /* MAL Tx EOB */ +#define VECNUM_MRE (32 + 7 ) /* MAL Rx EOB */ +#define VECNUM_CT0 (32 + 12 ) /* GPT compare timer 0 */ +#define VECNUM_CT1 (32 + 13 ) /* GPT compare timer 1 */ +#define VECNUM_CT2 (32 + 14 ) /* GPT compare timer 2 */ +#define VECNUM_CT3 (32 + 15 ) /* GPT compare timer 3 */ +#define VECNUM_CT4 (32 + 16 ) /* GPT compare timer 4 */ +#define VECNUM_ETH0 (32 + 28) /* Ethernet interrupt status */ +#define VECNUM_EWU0 (32 + 29) /* Emac wakeup */ + +/* UIC 2 */ +#define VECNUM_EIR5 (62 + 24) /* External interrupt 5 */ +#define VECNUM_EIR4 (62 + 25) /* External interrupt 4 */ +#define VECNUM_EIR3 (62 + 26) /* External interrupt 3 */ +#define VECNUM_EIR2 (62 + 27) /* External interrupt 2 */ +#define VECNUM_EIR1 (62 + 28) /* External interrupt 1 */ +#define VECNUM_EIR0 (62 + 29) /* External interrupt 0 */ + +#elif defined(CONFIG_440SP) /* UIC 0 */ #define VECNUM_U0 0 /* UART0 */ -- cgit v1.1 From bba68377320608b3c3f7c0fef30452bdaa8b0408 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Fri, 30 Jun 2006 18:35:04 +0200 Subject: Fix CONFIG_440_GX define usage. --- cpu/ppc4xx/start.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index f37c1d6..17d3aa3 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -1468,7 +1468,7 @@ trap_init: cmplw 0, r7, r8 blt 4b -#if !defined(CONFIG_440_GX) && !defined(CONFIG_440SPE) +#if !defined(CONFIG_440GX) && !defined(CONFIG_440SPE) addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */ oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */ mtmsr r7 /* change MSR */ -- cgit v1.1 From fe84b48a94beb88a977a88e3d14b6ea882cdc91a Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Mon, 3 Jul 2006 23:42:36 +0200 Subject: Cleanup config file and bootup output for Yucca board. --- cpu/ppc4xx/cpu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 6a84b09..71303bc 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -253,11 +253,13 @@ int checkcpu (void) break; case PVR_440SPe_RA: - puts("SPe 3GA533C"); + puts("SPe Rev. A"); break; + case PVR_440SPe_RB: - puts("SPe 3GB533C"); + puts("SPe Rev. B"); break; + default: printf (" UNKNOWN (PVR=%08x)", pvr); break; -- cgit v1.1 From fbb0b559ae564d80b5ea3199ad530aa0e419a668 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 4 Jul 2006 00:55:47 +0200 Subject: Add system memory to the PCI region list for AMCC PPC44x CPUs. Enabled it for Yucca board. --- cpu/ppc4xx/405gp_pci.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c index 0ccb3d8..cf5eccb 100644 --- a/cpu/ppc4xx/405gp_pci.c +++ b/cpu/ppc4xx/405gp_pci.c @@ -465,17 +465,30 @@ void pci_440_init (struct pci_controller *hose) hose->first_busno = 0; hose->last_busno = 0xff; + /* PCI I/O space */ pci_set_region(hose->regions + reg_num++, 0x00000000, PCIX0_IOBASE, 0x10000, PCI_REGION_IO); + /* PCI memory space */ pci_set_region(hose->regions + reg_num++, CFG_PCI_TARGBASE, CFG_PCI_MEMBASE, 0x10000000, PCI_REGION_MEM ); + +#if defined(CONFIG_PCI_SYS_MEM_BUS) && defined(CONFIG_PCI_SYS_MEM_PHYS) && \ + defined(CONFIG_PCI_SYS_MEM_SIZE) + /* System memory space */ + pci_set_region(hose->regions + reg_num++, + CONFIG_PCI_SYS_MEM_BUS, + CONFIG_PCI_SYS_MEM_PHYS, + CONFIG_PCI_SYS_MEM_SIZE, + PCI_REGION_MEM | PCI_REGION_MEMORY ); +#endif + hose->region_count = reg_num; pci_setup_indirect(hose, PCIX0_CFGADR, PCIX0_CFGDATA); -- cgit v1.1 From edd6cf20e1be63f84e0f5af0280473cf31f0e86c Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 6 Jul 2006 21:17:24 +0200 Subject: Fix timer problems on AMCC yucca board. Set Timer Clock Select to use CPU clock as a timer input source. --- cpu/ppc4xx/start.S | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 17d3aa3..0a6f81d 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -158,7 +158,7 @@ _start_440: /*----------------------------------------------------------------+ | Core bug fix. Clear the esr +-----------------------------------------------------------------*/ - addi r0,r0,0x0000 + li r0,0 mtspr esr,r0 /*----------------------------------------------------------------*/ /* Clear and set up some registers. */ @@ -217,17 +217,15 @@ _start_440: | g. FCOM: Normal operation | h. MMUPEI: Record even parity. Normal operation. | i. FFF: Flush only as much data as necessary. - | j. TCS: Timebase increments from externally supplied clock + | j. TCS: Timebase increments from CPU clock. +-----------------------------------------------------------------*/ - addis r0, r0, 0x0000 - ori r0, r0, 0x0080 + li r0,0 mtspr ccr1, r0 /*----------------------------------------------------------------+ | Reset the timebase. | The previous write to CCR1 sets the timebase source. +-----------------------------------------------------------------*/ - addi r0, r0, 0x0000 mtspr tbl, r0 mtspr tbu, r0 #endif -- cgit v1.1 From b87dfd2854809ddcf4be54d772752e7ed137386f Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 19 Jul 2006 13:50:38 +0200 Subject: Add support for TB5200 board The TB5200 ("Tinybox") is a small baseboard for the TQM5200 module integrated in a little aluminium case. Patch by Martin Krause, 8 Jun 2006 Some code cleanup --- cpu/ppc4xx/serial.c | 2 +- cpu/ppc4xx/start.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c index 3749811..4631519 100644 --- a/cpu/ppc4xx/serial.c +++ b/cpu/ppc4xx/serial.c @@ -635,7 +635,7 @@ void serial_setbrg (void) tmp = gd->baudrate * udiv * 16; bdiv = (clk + tmp / 2) / tmp; -#endif /* !defined(CFG_EXT_SERIAL_CLOCK) && (...) */ +#endif /* !defined(CFG_EXT_SERIAL_CLOCK) && (...) */ #if defined(CONFIG_SERIAL_MULTI) out8 (dev_base + UART_LCR, 0x80); /* set DLAB bit */ diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 0a6f81d..699fa7f 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -159,7 +159,7 @@ _start_440: | Core bug fix. Clear the esr +-----------------------------------------------------------------*/ li r0,0 - mtspr esr,r0 + mtspr esr,r0 /*----------------------------------------------------------------*/ /* Clear and set up some registers. */ /*----------------------------------------------------------------*/ -- cgit v1.1 From b9365a26a1030ce13f2c5bb3619d721750b9e409 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Fri, 21 Jul 2006 11:56:05 +0200 Subject: Code cleanup --- cpu/ppc4xx/serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c index 4631519..ad3ca6e 100644 --- a/cpu/ppc4xx/serial.c +++ b/cpu/ppc4xx/serial.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000 + * (C) Copyright 2000-2006 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this -- cgit v1.1 From a2c95a72247990dee9a03b26b4dc9fc0182c97ed Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 28 Jul 2006 18:34:58 +0200 Subject: PPC440 DDR setup: Set SDRAM0_CFG0[PMU]=0 for best performance AMCC suggested to set the PMU bit to 0 for best performace on the PPC440 DDR controller. Please see doc/README.440-DDR-performance for details. Patch by Stefan Roese, 28 Jul 2006 --- cpu/ppc4xx/sdram.c | 2 +- cpu/ppc4xx/spd_sdram.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'cpu/ppc4xx') diff --git a/cpu/ppc4xx/sdram.c b/cpu/ppc4xx/sdram.c index e31d59d..faeea5c 100644 --- a/cpu/ppc4xx/sdram.c +++ b/cpu/ppc4xx/sdram.c @@ -379,7 +379,7 @@ long int initdram(int board_type) /* * Enable the controller, then wait for DCEN to complete */ - mtsdram(mem_cfg0, 0x86000000); /* DCEN=1, PMUD=1, 64-bit */ + mtsdram(mem_cfg0, 0x82000000); /* DCEN=1, PMUD=0, 64-bit */ udelay(10000); if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) { diff --git a/cpu/ppc4xx/spd_sdram.c b/cpu/ppc4xx/spd_sdram.c index c0a6933..c24456b 100644 --- a/cpu/ppc4xx/spd_sdram.c +++ b/cpu/ppc4xx/spd_sdram.c @@ -1007,9 +1007,9 @@ void program_cfg0(unsigned long* dimm_populated, } /* - * program Page Management Unit + * program Page Management Unit (0 == enabled) */ - cfg0 |= SDRAM_CFG0_PMUD; + cfg0 &= ~SDRAM_CFG0_PMUD; /* * program Memory Controller Options 0 -- cgit v1.1