summaryrefslogtreecommitdiff
path: root/cpu/ppc4xx
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/ppc4xx')
-rw-r--r--cpu/ppc4xx/405gp_pci.c37
-rw-r--r--cpu/ppc4xx/4xx_enet.c78
-rw-r--r--cpu/ppc4xx/cpu.c35
-rw-r--r--cpu/ppc4xx/cpu_init.c126
-rw-r--r--cpu/ppc4xx/i2c.c3
-rw-r--r--cpu/ppc4xx/interrupts.c127
-rw-r--r--cpu/ppc4xx/miiphy.c59
-rw-r--r--cpu/ppc4xx/sdram.c306
-rw-r--r--cpu/ppc4xx/sdram.h78
-rw-r--r--cpu/ppc4xx/serial.c55
-rw-r--r--cpu/ppc4xx/spd_sdram.c6
-rw-r--r--cpu/ppc4xx/speed.c260
-rw-r--r--cpu/ppc4xx/start.S116
-rw-r--r--cpu/ppc4xx/vecnum.h43
14 files changed, 1162 insertions, 167 deletions
diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c
index 64431ab13a..cf5eccb01f 100644
--- a/cpu/ppc4xx/405gp_pci.c
+++ b/cpu/ppc4xx/405gp_pci.c
@@ -77,10 +77,16 @@
#include <asm/processor.h>
#include <pci.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
#ifdef CONFIG_PCI
+#if defined(CONFIG_PMC405)
+ushort pmc405_pci_subsys_deviceid(void);
+#endif
+
/*#define DEBUG*/
/*-----------------------------------------------------------------------------+
@@ -88,21 +94,16 @@
*-----------------------------------------------------------------------------*/
void pci_405gp_init(struct pci_controller *hose)
{
- DECLARE_GLOBAL_DATA_PTR;
-
int i, reg_num = 0;
bd_t *bd = gd->bd;
unsigned short temp_short;
unsigned long ptmpcila[2] = {CFG_PCI_PTM1PCI, CFG_PCI_PTM2PCI};
#if defined(CONFIG_CPCI405) || defined(CONFIG_PMC405)
- unsigned long ptmla[2] = {bd->bi_memstart, bd->bi_flashstart};
- unsigned long ptmms[2] = {~(bd->bi_memsize - 1) | 1, ~(bd->bi_flashsize - 1) | 1};
char *ptmla_str, *ptmms_str;
-#else
+#endif
unsigned long ptmla[2] = {CFG_PCI_PTM1LA, CFG_PCI_PTM2LA};
unsigned long ptmms[2] = {CFG_PCI_PTM1MS, CFG_PCI_PTM2MS};
-#endif
#if defined(CONFIG_PIP405) || defined (CONFIG_MIP405)
unsigned long pmmla[3] = {0x80000000, 0xA0000000, 0};
unsigned long pmmma[3] = {0xE0000001, 0xE0000001, 0};
@@ -372,7 +373,7 @@ void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
{
unsigned int cmdstat = 0;
- pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+ pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
/* always enable io space on vga boards */
pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
@@ -437,7 +438,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);
@@ -464,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);
@@ -501,7 +515,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 +533,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 86dc2d066e..fab65aff78 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 a26533c59c..71303bcc49 100644
--- a/cpu/ppc4xx/cpu.c
+++ b/cpu/ppc4xx/cpu.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2000-2003
+ * (C) Copyright 2000-2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -37,6 +37,10 @@
#include <asm/cache.h>
#include <ppc4xx.h>
+#if !defined(CONFIG_405)
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
#if defined(CONFIG_440)
#define FREQ_EBC (sys_info.freqEPB)
@@ -78,7 +82,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 +93,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 +104,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);
@@ -116,7 +124,6 @@ static int do_chip_reset(unsigned long sys0, unsigned long sys1);
int checkcpu (void)
{
#if !defined(CONFIG_405) /* not used on Xilinx 405 FPGA implementations */
- DECLARE_GLOBAL_DATA_PTR;
uint pvr = get_pvr();
ulong clock = gd->cpu_clk;
char buf[32];
@@ -220,12 +227,20 @@ int checkcpu (void)
case PVR_440EP_RB: /* 440EP rev B and 440GR rev A have same PVR */
puts("EP Rev. B");
break;
+
+ case PVR_440EP_RC: /* 440EP rev C and 440GR rev B have same PVR */
+ puts("EP Rev. C");
+ break;
#endif /* CONFIG_440EP */
#ifdef CONFIG_440GR
case PVR_440GR_RA: /* 440EP rev B and 440GR rev A have same PVR */
puts("GR Rev. A");
break;
+
+ case PVR_440GR_RB: /* 440EP rev C and 440GR rev B have same PVR */
+ puts("GR Rev. B");
+ break;
#endif /* CONFIG_440GR */
#endif /* CONFIG_440 */
@@ -237,6 +252,14 @@ int checkcpu (void)
puts("SP Rev. B");
break;
+ case PVR_440SPe_RA:
+ puts("SPe Rev. A");
+ break;
+
+ case PVR_440SPe_RB:
+ puts("SPe Rev. B");
+ break;
+
default:
printf (" UNKNOWN (PVR=%08x)", pvr);
break;
diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c
index 79cfba3a45..b27567fa4d 100644
--- a/cpu/ppc4xx/cpu_init.c
+++ b/cpu/ppc4xx/cpu_init.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
@@ -27,6 +27,10 @@
#include <asm/processor.h>
#include <ppc4xx.h>
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
#define mtebc(reg, data) mtdcr(ebccfga,reg);mtdcr(ebccfgd,data)
@@ -97,6 +101,117 @@
# endif
#endif /* CFG_INIT_DCACHE_CS */
+#if defined(CFG_440_GPIO_TABLE)
+gpio_param_s gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CFG_440_GPIO_TABLE;
+
+void set_chip_gpio_configuration(gpio_param_s (*gpio_tab)[GPIO_GROUP_MAX][GPIO_MAX])
+{
+ unsigned char i=0, j=0, reg_offset = 0, gpio_core;
+ unsigned long gpio_reg, gpio_core_add;
+
+ for (gpio_core=0; gpio_core<GPIO_GROUP_MAX; gpio_core++) {
+ j = 0;
+ reg_offset = 0;
+ /* GPIO config of the GPIOs 0 to 31 */
+ for (i=0; i<GPIO_MAX; i++, j++) {
+ if (i == GPIO_MAX/2) {
+ reg_offset = 4;
+ j = i-16;
+ }
+
+ gpio_core_add = (*gpio_tab)[gpio_core][i].add;
+
+ if (((*gpio_tab)[gpio_core][i].in_out == GPIO_IN) ||
+ ((*gpio_tab)[gpio_core][i].in_out == GPIO_BI)) {
+
+ switch ((*gpio_tab)[gpio_core][i].alt_nb) {
+ case GPIO_SEL:
+ break;
+
+ case GPIO_ALT1:
+ gpio_reg = in32(GPIO_IS1(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2));
+ out32(GPIO_IS1(gpio_core_add+reg_offset), gpio_reg);
+ break;
+
+ case GPIO_ALT2:
+ gpio_reg = in32(GPIO_IS2(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2));
+ out32(GPIO_IS2(gpio_core_add+reg_offset), gpio_reg);
+ break;
+
+ case GPIO_ALT3:
+ gpio_reg = in32(GPIO_IS3(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_IN_SEL >> (j*2));
+ out32(GPIO_IS3(gpio_core_add+reg_offset), gpio_reg);
+ break;
+ }
+ }
+
+ if (((*gpio_tab)[gpio_core][i].in_out == GPIO_OUT) ||
+ ((*gpio_tab)[gpio_core][i].in_out == GPIO_BI)) {
+
+ switch ((*gpio_tab)[gpio_core][i].alt_nb) {
+ case GPIO_SEL:
+ if (gpio_core == GPIO0) {
+ gpio_reg = in32(GPIO0_TCR) | (0x80000000 >> (j));
+ out32(GPIO0_TCR, gpio_reg);
+ }
+
+ if (gpio_core == GPIO1) {
+ gpio_reg = in32(GPIO1_TCR) | (0x80000000 >> (j));
+ out32(GPIO1_TCR, gpio_reg);
+ }
+
+ gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg);
+ gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg);
+ break;
+
+ case GPIO_ALT1:
+ gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT1_SEL >> (j*2));
+ out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg);
+ gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT1_SEL >> (j*2));
+ out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg);
+ break;
+
+ case GPIO_ALT2:
+ gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT2_SEL >> (j*2));
+ out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg);
+ gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT2_SEL >> (j*2));
+ out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg);
+ break;
+
+ case GPIO_ALT3:
+ gpio_reg = in32(GPIO_OS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT3_SEL >> (j*2));
+ out32(GPIO_OS(gpio_core_add+reg_offset), gpio_reg);
+ gpio_reg = in32(GPIO_TS(gpio_core_add+reg_offset))
+ & ~(GPIO_MASK >> (j*2));
+ gpio_reg = gpio_reg | (GPIO_ALT3_SEL >> (j*2));
+ out32(GPIO_TS(gpio_core_add+reg_offset), gpio_reg);
+ break;
+ }
+ }
+ }
+ }
+}
+#endif /* CFG_440_GPIO_TABLE */
/*
* Breath some life into the CPU...
@@ -125,10 +240,16 @@ cpu_init_f (void)
mtdcr(cpc0_epctl, CPC0_EPRCSR_E0NFE | CPC0_EPRCSR_E1NFE);
#endif /* CONFIG_405EP */
+#if defined(CFG_440_GPIO_TABLE)
+ set_chip_gpio_configuration(&gpio_tab);
+#endif /* CFG_440_GPIO_TABLE */
+
/*
* External Bus Controller (EBC) Setup
*/
#if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
+#if (defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
+ defined(CONFIG_405EP) || defined(CONFIG_405))
/*
* Move the next instructions into icache, since these modify the flash
* we are running from!
@@ -144,6 +265,7 @@ cpu_init_f (void)
asm volatile(" ori 3, 3, 0xA000" ::: "r3");
asm volatile(" mtctr 3" ::: "ctr");
asm volatile("2: bdnz 2b" ::: "ctr", "cr0");
+#endif
mtebc(pb0ap, CFG_EBC_PB0AP);
mtebc(pb0cr, CFG_EBC_PB0CR);
@@ -209,8 +331,6 @@ cpu_init_f (void)
int cpu_init_r (void)
{
#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
- DECLARE_GLOBAL_DATA_PTR;
-
bd_t *bd = gd->bd;
unsigned long reg;
#if defined(CONFIG_405GP)
diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c
index be94b571ff..7db1cd8046 100644
--- a/cpu/ppc4xx/i2c.c
+++ b/cpu/ppc4xx/i2c.c
@@ -16,6 +16,8 @@
#ifdef CONFIG_HARD_I2C
+DECLARE_GLOBAL_DATA_PTR;
+
#define IIC_OK 0
#define IIC_NOK 1
#define IIC_NOK_LA 2 /* Lost arbitration */
@@ -350,7 +352,6 @@ int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
{
uchar xaddr[4];
int ret;
- DECLARE_GLOBAL_DATA_PTR;
if ( alen > 4 ) {
printf ("I2C read: addr len %d not supported\n", alen);
diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c
index 1d8dc7c221..886f405156 100644
--- a/cpu/ppc4xx/interrupts.c
+++ b/cpu/ppc4xx/interrupts.c
@@ -36,6 +36,8 @@
#include <commproc.h>
#include "vecnum.h"
+DECLARE_GLOBAL_DATA_PTR;
+
/****************************************************************************/
/*
@@ -48,18 +50,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 */
@@ -96,8 +102,6 @@ static __inline__ void set_evpr(unsigned long val)
int interrupt_init_cpu (unsigned *decrementer_count)
{
- DECLARE_GLOBAL_DATA_PTR;
-
int vec;
unsigned long val;
@@ -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 f26f2a203a..aa580ed48f 100644
--- a/cpu/ppc4xx/miiphy.c
+++ b/cpu/ppc4xx/miiphy.c
@@ -50,7 +50,7 @@
#include <405_mal.h>
#include <miiphy.h>
-
+#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/sdram.c b/cpu/ppc4xx/sdram.c
index e9548cdcf3..faeea5c91e 100644
--- a/cpu/ppc4xx/sdram.c
+++ b/cpu/ppc4xx/sdram.c
@@ -1,7 +1,10 @@
/*
- * (C) Copyright 2005
+ * (C) Copyright 2005-2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
+ * (C) Copyright 2006
+ * DAVE Srl <www.dave-tech.it>
+ *
* (C) Copyright 2002-2004
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
*
@@ -15,7 +18,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -27,63 +30,161 @@
#include <common.h>
#include <ppc4xx.h>
#include <asm/processor.h>
+#include "sdram.h"
#ifdef CONFIG_SDRAM_BANK0
-#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data)
-
-
-struct sdram_conf_s {
- unsigned long size;
- unsigned long reg;
-};
-
-typedef struct sdram_conf_s sdram_conf_t;
-
#ifndef CFG_SDRAM_TABLE
sdram_conf_t mb0cf[] = {
- {(128 << 20), 0x000A4001}, /* (0-128MB) Address Mode 3, 13x10(4) */
- {(64 << 20), 0x00084001}, /* (0-64MB) Address Mode 3, 13x9(4) */
- {(32 << 20), 0x00062001}, /* (0-32MB) Address Mode 2, 12x9(4) */
- {(16 << 20), 0x00046001}, /* (0-16MB) Address Mode 4, 12x8(4) */
- {(4 << 20), 0x00008001}, /* (0-4MB) Address Mode 5, 11x8(2) */
+ {(128 << 20), 13, 0x000A4001}, /* (0-128MB) Address Mode 3, 13x10(4) */
+ {(64 << 20), 13, 0x00084001}, /* (0-64MB) Address Mode 3, 13x9(4) */
+ {(32 << 20), 12, 0x00062001}, /* (0-32MB) Address Mode 2, 12x9(4) */
+ {(16 << 20), 12, 0x00046001}, /* (0-16MB) Address Mode 4, 12x8(4) */
+ {(4 << 20), 11, 0x00008001}, /* (0-4MB) Address Mode 5, 11x8(2) */
};
#else
sdram_conf_t mb0cf[] = CFG_SDRAM_TABLE;
#endif
-#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
+#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
#ifndef CONFIG_440
-/*
- * Autodetect onboard SDRAM on 405 platforms
- */
-void sdram_init(void)
+#ifdef CFG_SDRAM_CASL
+static ulong ns2clks(ulong ns)
{
- ulong sdtr1;
- ulong rtr;
- int i;
+ ulong bus_period_x_10 = ONE_BILLION / (get_bus_freq(0) / 10);
+ return ((ns * 10) + bus_period_x_10) / bus_period_x_10;
+}
+#endif /* CFG_SDRAM_CASL */
+
+static ulong compute_sdtr1(ulong speed)
+{
+#ifdef CFG_SDRAM_CASL
+ ulong tmp;
+ ulong sdtr1 = 0;
+
+ /* CASL */
+ if (CFG_SDRAM_CASL < 2)
+ sdtr1 |= (1 << SDRAM0_TR_CASL);
+ else
+ if (CFG_SDRAM_CASL > 4)
+ sdtr1 |= (3 << SDRAM0_TR_CASL);
+ else
+ sdtr1 |= ((CFG_SDRAM_CASL-1) << SDRAM0_TR_CASL);
+
+ /* PTA */
+ tmp = ns2clks(CFG_SDRAM_PTA);
+ if ((tmp >= 2) && (tmp <= 4))
+ sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA);
+ else
+ sdtr1 |= ((4-1) << SDRAM0_TR_PTA);
+
+ /* CTP */
+ tmp = ns2clks(CFG_SDRAM_CTP);
+ if ((tmp >= 2) && (tmp <= 4))
+ sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP);
+ else
+ sdtr1 |= ((4-1) << SDRAM0_TR_CTP);
+
+ /* LDF */
+ tmp = ns2clks(CFG_SDRAM_LDF);
+ if ((tmp >= 2) && (tmp <= 4))
+ sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF);
+ else
+ sdtr1 |= ((2-1) << SDRAM0_TR_LDF);
+
+ /* RFTA */
+ tmp = ns2clks(CFG_SDRAM_RFTA);
+ if ((tmp >= 4) && (tmp <= 10))
+ sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA);
+ else
+ sdtr1 |= ((10-4) << SDRAM0_TR_RFTA);
+
+ /* RCD */
+ tmp = ns2clks(CFG_SDRAM_RCD);
+ if ((tmp >= 2) && (tmp <= 4))
+ sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD);
+ else
+ sdtr1 |= ((4-1) << SDRAM0_TR_RCD);
+
+ return sdtr1;
+#else /* CFG_SDRAM_CASL */
/*
- * Support for 100MHz and 133MHz SDRAM
+ * If no values are configured in the board config file
+ * use the default values, which seem to be ok for most
+ * boards.
+ *
+ * REMARK:
+ * For new board ports we strongly recommend to define the
+ * correct values for the used SDRAM chips in your board
+ * config file (see PPChameleonEVB.h)
*/
- if (get_bus_freq(0) > 100000000) {
+ if (speed > 100000000) {
/*
* 133 MHz SDRAM
*/
- sdtr1 = 0x01074015;
- rtr = 0x07f00000;
+ return 0x01074015;
} else {
/*
* default: 100 MHz SDRAM
*/
- sdtr1 = 0x0086400d;
- rtr = 0x05f00000;
+ return 0x0086400d;
}
+#endif /* CFG_SDRAM_CASL */
+}
+
+/* refresh is expressed in ms */
+static ulong compute_rtr(ulong speed, ulong rows, ulong refresh)
+{
+#ifdef CFG_SDRAM_CASL
+ ulong tmp;
+
+ tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000);
+ tmp /= 1000000;
+
+ return ((tmp & 0x00003FF8) << 16);
+#else /* CFG_SDRAM_CASL */
+ if (speed > 100000000) {
+ /*
+ * 133 MHz SDRAM
+ */
+ return 0x07f00000;
+ } else {
+ /*
+ * default: 100 MHz SDRAM
+ */
+ return 0x05f00000;
+ }
+#endif /* CFG_SDRAM_CASL */
+}
+
+/*
+ * Autodetect onboard SDRAM on 405 platforms
+ */
+void sdram_init(void)
+{
+ ulong speed;
+ ulong sdtr1;
+ int i;
+
+ /*
+ * Determine SDRAM speed
+ */
+ speed = get_bus_freq(0); /* parameter not used on ppc4xx */
+
+ /*
+ * sdtr1 (register SDRAM0_TR) must take into account timings listed
+ * in SDRAM chip datasheet. rtr (register SDRAM0_RTR) must take into
+ * account actual SDRAM size. So we can set up sdtr1 according to what
+ * is specified in board configuration file while rtr dependds on SDRAM
+ * size we are assuming before detection.
+ */
+ sdtr1 = compute_sdtr1(speed);
for (i=0; i<N_MB0CF; i++) {
/*
@@ -96,7 +197,7 @@ void sdram_init(void)
*/
mtsdram0(mem_mb0cf, mb0cf[i].reg);
mtsdram0(mem_sdtr1, sdtr1);
- mtsdram0(mem_rtr, rtr);
+ mtsdram0(mem_rtr, compute_rtr(speed, mb0cf[i].rows, 64));
udelay(200);
@@ -120,16 +221,135 @@ void sdram_init(void)
#else /* CONFIG_440 */
+#define NUM_TRIES 64
+#define NUM_READS 10
+
+static void sdram_tr1_set(int ram_address, int* tr1_value)
+{
+ int i;
+ int j, k;
+ volatile unsigned int* ram_pointer = (unsigned int *)ram_address;
+ int first_good = -1, last_bad = 0x1ff;
+
+ unsigned long test[NUM_TRIES] = {
+ 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
+ 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
+ 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
+ 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
+ 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
+ 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
+ 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
+ 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
+ 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
+ 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
+ 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
+ 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
+ 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
+
+ /* go through all possible SDRAM0_TR1[RDCT] values */
+ for (i=0; i<=0x1ff; i++) {
+ /* set the current value for TR1 */
+ mtsdram(mem_tr1, (0x80800800 | i));
+
+ /* write values */
+ for (j=0; j<NUM_TRIES; j++) {
+ ram_pointer[j] = test[j];
+
+ /* clear any cache at ram location */
+ __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
+ }
+
+ /* read values back */
+ for (j=0; j<NUM_TRIES; j++) {
+ for (k=0; k<NUM_READS; k++) {
+ /* clear any cache at ram location */
+ __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
+
+ if (ram_pointer[j] != test[j])
+ break;
+ }
+
+ /* read error */
+ if (k != NUM_READS)
+ break;
+ }
+
+ /* we have a SDRAM0_TR1[RDCT] that is part of the window */
+ if (j == NUM_TRIES) {
+ if (first_good == -1)
+ first_good = i; /* found beginning of window */
+ } else { /* bad read */
+ /* if we have not had a good read then don't care */
+ if (first_good != -1) {
+ /* first failure after a good read */
+ last_bad = i-1;
+ break;
+ }
+ }
+ }
+
+ /* return the current value for TR1 */
+ *tr1_value = (first_good + last_bad) / 2;
+}
+
+
+#ifdef CONFIG_SDRAM_ECC
+static void ecc_init(ulong start, ulong size)
+{
+ ulong current_addr; /* current byte address */
+ ulong end_addr; /* end of memory region */
+ ulong addr_inc; /* address skip between writes */
+ ulong cfg0_reg; /* for restoring ECC state */
+
+ /*
+ * TODO: Enable dcache before running this test (speedup)
+ */
+
+ mfsdram(mem_cfg0, cfg0_reg);
+ mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_GEN);
+
+ /*
+ * look at geometry of SDRAM (data width) to determine whether we
+ * can skip words when writing
+ */
+ if ((cfg0_reg & SDRAM_CFG0_DRAMWDTH) == SDRAM_CFG0_DRAMWDTH_32)
+ addr_inc = 4;
+ else
+ addr_inc = 8;
+
+ current_addr = start;
+ end_addr = start + size;
+
+ while (current_addr < end_addr) {
+ *((ulong *)current_addr) = 0x00000000;
+ current_addr += addr_inc;
+ }
+
+ /*
+ * TODO: Flush dcache and disable it again
+ */
+
+ /*
+ * Enable ecc checking and parity errors
+ */
+ mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_CHK);
+}
+#endif
+
/*
* Autodetect onboard DDR SDRAM on 440 platforms
*
* NOTE: Some of the hardcoded values are hardware dependant,
- * so this should be extended for other future boards
- * using this routine!
+ * so this should be extended for other future boards
+ * using this routine!
*/
long int initdram(int board_type)
{
int i;
+ int tr1_bank1;
for (i=0; i<N_MB0CF; i++) {
/*
@@ -140,11 +360,11 @@ long int initdram(int board_type)
/*
* Setup some default
*/
- mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */
- mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
+ mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */
+ mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
mtsdram(mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */
mtsdram(mem_wddctr, 0x00000000); /* wrcp=0 dcd=0 */
- mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
+ mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
/*
* Following for CAS Latency = 2.5 @ 133 MHz PLB
@@ -159,11 +379,21 @@ 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) {
/*
+ * Optimize TR1 to current hardware environment
+ */
+ sdram_tr1_set(0x00000000, &tr1_bank1);
+ mtsdram(mem_tr1, (tr1_bank1 | 0x80800800));
+
+#ifdef CONFIG_SDRAM_ECC
+ ecc_init(0, mb0cf[i].size);
+#endif
+
+ /*
* OK, size detected -> all done
*/
return mb0cf[i].size;
diff --git a/cpu/ppc4xx/sdram.h b/cpu/ppc4xx/sdram.h
new file mode 100644
index 0000000000..62b5442f3b
--- /dev/null
+++ b/cpu/ppc4xx/sdram.h
@@ -0,0 +1,78 @@
+/*
+ * (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * (C) Copyright 2006
+ * DAVE Srl <www.dave-tech.it>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SDRAM_H_
+#define _SDRAM_H_
+
+#include <config.h>
+
+#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data)
+
+#define ONE_BILLION 1000000000
+
+struct sdram_conf_s {
+ unsigned long size;
+ int rows;
+ unsigned long reg;
+};
+
+typedef struct sdram_conf_s sdram_conf_t;
+
+/* Bitfields offsets */
+#define SDRAM0_TR_CASL (31 - 8)
+#define SDRAM0_TR_PTA (31 - 13)
+#define SDRAM0_TR_CTP (31 - 15)
+#define SDRAM0_TR_LDF (31 - 17)
+#define SDRAM0_TR_RFTA (31 - 29)
+#define SDRAM0_TR_RCD (31 - 31)
+
+#ifdef CFG_SDRAM_CL
+/* SDRAM timings [ns] according to AMCC/IBM names (see SDRAM_faq.doc) */
+#define CFG_SDRAM_CASL CFG_SDRAM_CL
+#define CFG_SDRAM_PTA CFG_SDRAM_tRP
+#define CFG_SDRAM_CTP (CFG_SDRAM_tRC - CFG_SDRAM_tRCD - CFG_SDRAM_tRP)
+#define CFG_SDRAM_LDF 0
+#ifdef CFG_SDRAM_tRFC
+#define CFG_SDRAM_RFTA CFG_SDRAM_tRFC
+#else
+#define CFG_SDRAM_RFTA CFG_SDRAM_tRC
+#endif
+#define CFG_SDRAM_RCD CFG_SDRAM_tRCD
+#endif /* #ifdef CFG_SDRAM_CL */
+
+/*
+ * Some defines for the 440 DDR controller
+ */
+#define SDRAM_CFG0_DC_EN 0x80000000 /* SDRAM Controller Enable */
+#define SDRAM_CFG0_MEMCHK 0x30000000 /* Memory data error checking mask*/
+#define SDRAM_CFG0_MEMCHK_NON 0x00000000 /* No ECC generation */
+#define SDRAM_CFG0_MEMCHK_GEN 0x20000000 /* ECC generation */
+#define SDRAM_CFG0_MEMCHK_CHK 0x30000000 /* ECC generation and checking */
+#define SDRAM_CFG0_DRAMWDTH 0x02000000 /* DRAM width mask */
+#define SDRAM_CFG0_DRAMWDTH_32 0x00000000 /* 32 bits */
+#define SDRAM_CFG0_DRAMWDTH_64 0x02000000 /* 64 bits */
+
+#endif
diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c
index e7f6bcbe1e..ad3ca6e819 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
@@ -59,6 +59,8 @@
#include <malloc.h>
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
/*****************************************************************************/
#ifdef CONFIG_IOP480
@@ -161,8 +163,6 @@
int serial_init (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
volatile char val;
unsigned short br_reg;
@@ -185,8 +185,6 @@ int serial_init (void)
void serial_setbrg (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
unsigned short br_reg;
br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1);
@@ -277,11 +275,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 +309,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 */
@@ -431,8 +433,6 @@ int serial_init_dev (unsigned long dev_base)
int serial_init(void)
#endif
{
- DECLARE_GLOBAL_DATA_PTR;
-
unsigned long reg;
unsigned long udiv;
unsigned short bdiv;
@@ -441,7 +441,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 +471,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) {
@@ -520,8 +523,6 @@ int serial_init_dev (unsigned long dev_base)
int serial_init (void)
#endif
{
- DECLARE_GLOBAL_DATA_PTR;
-
unsigned long reg;
unsigned long tmp;
unsigned long clk;
@@ -597,8 +598,6 @@ void serial_setbrg_dev (unsigned long dev_base)
void serial_setbrg (void)
#endif
{
- DECLARE_GLOBAL_DATA_PTR;
-
unsigned long tmp;
unsigned long clk;
unsigned long udiv;
@@ -615,8 +614,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 */
@@ -880,8 +899,6 @@ int serial_buffered_tstc (void)
#if (CONFIG_KGDB_SER_INDEX & 2)
void kgdb_serial_init (void)
{
- DECLARE_GLOBAL_DATA_PTR;
-
volatile char val;
unsigned short br_reg;
diff --git a/cpu/ppc4xx/spd_sdram.c b/cpu/ppc4xx/spd_sdram.c
index ebd5f3998f..c24456bea8 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.
*/
@@ -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
diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c
index 553c491e24..e552c03473 100644
--- a/cpu/ppc4xx/speed.c
+++ b/cpu/ppc4xx/speed.c
@@ -26,10 +26,14 @@
#include <ppc4xx.h>
#include <asm/processor.h>
-/* ------------------------------------------------------------------------- */
+DECLARE_GLOBAL_DATA_PTR;
#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
@@ -522,8 +772,6 @@ ulong get_PCI_freq (void)
int get_clocks (void)
{
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405) || defined(CONFIG_405EP)
- DECLARE_GLOBAL_DATA_PTR;
-
sys_info_t sys_info;
get_sys_info (&sys_info);
@@ -533,8 +781,6 @@ int get_clocks (void)
#endif /* defined(CONFIG_405GP) || defined(CONFIG_405CR) */
#ifdef CONFIG_IOP480
- DECLARE_GLOBAL_DATA_PTR;
-
gd->cpu_clk = 66000000;
gd->bus_clk = 66000000;
#endif
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 48b430d14d..699fa7fd75 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -155,6 +155,11 @@
/**************************************************************************/
_start_440:
+ /*----------------------------------------------------------------+
+ | Core bug fix. Clear the esr
+ +-----------------------------------------------------------------*/
+ li r0,0
+ 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,31 @@ _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 CPU clock.
+ +-----------------------------------------------------------------*/
+ li r0,0
+ mtspr ccr1, r0
+
+ /*----------------------------------------------------------------+
+ | Reset the timebase.
+ | The previous write to CCR1 sets the timebase source.
+ +-----------------------------------------------------------------*/
+ mtspr tbl, r0
+ mtspr tbu, r0
+#endif
+
/*----------------------------------------------------------------*/
/* Setup interrupt vectors */
/*----------------------------------------------------------------*/
@@ -261,15 +291,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,23 +381,6 @@ _start:
mtspr tcr,r0 /* disable all */
mtspr esr,r0 /* clear exception syndrome register */
mtxer r0 /* clear integer exception register */
-#if !defined(CONFIG_440GX)
- lis r1,0x0002 /* set CE bit (Critical Exceptions) */
- ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */
- mtmsr r1 /* change MSR */
-#elif !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
- bl __440gx_msr_set
- b __440gx_msr_continue
-
-__440gx_msr_set:
- lis r1, 0x0002 /* set CE bit (Critical Exceptions) */
- ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */
- mtspr srr1,r1
- mflr r1
- mtspr srr0,r1
- rfi
-__440gx_msr_continue:
-#endif
/*----------------------------------------------------------------*/
/* Debug setup -- some (not very good) ice's need an event*/
@@ -394,7 +418,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 +445,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
@@ -458,9 +495,6 @@ __440gx_msr_continue:
mtspr esr,r0 /* clear Exception Syndrome Reg */
mttcr r0 /* timer control register */
mtexier r0 /* disable all interrupts */
- addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
- oris r4,r4,0x2 /* set CE bit (Critical Exceptions) */
- mtmsr r4 /* change MSR */
addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */
ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */
mtdbsr r4 /* clear/reset the dbsr */
@@ -571,9 +605,6 @@ __440gx_msr_continue:
mttcr r4 /* clear Timer Control Reg */
mtxer r4 /* clear Fixed-Point Exception Reg */
mtevpr r4 /* clear Exception Vector Prefix Reg */
- addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
- oris r4,r4,0x0002 /* set CE bit (Critical Exceptions) */
- mtmsr r4 /* change MSR */
addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */
/* dbsr is cleared by setting bits to 1) */
mtdbsr r4 /* clear/reset the dbsr */
@@ -1220,13 +1251,20 @@ ppcSync:
*/
.globl relocate_code
relocate_code:
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
- dccci 0,0 /* Invalidate data cache, now no longer our stack */
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SPE)
+ /*
+ * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
+ * to speed up the boot process. Now this cache needs to be disabled.
+ */
+ iccci 0,0 /* Invalidate inst cache */
+ dccci 0,0 /* Invalidate data cache, now no longer our stack */
sync
+ isync
addi r1,r0,0x0000 /* TLB entry #0 */
tlbre r0,r1,0x0002 /* Read contents */
ori r0,r0,0x0c00 /* Or in the inhibit, write through bit */
tlbwe r0,r1,0x0002 /* Save it out */
+ sync
isync
#endif
mr r1, r3 /* Set new stack pointer */
@@ -1428,6 +1466,24 @@ trap_init:
cmplw 0, r7, r8
blt 4b
+#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 */
+#else
+ bl __440gx_msr_set
+ b __440gx_msr_continue
+
+__440gx_msr_set:
+ addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
+ oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
+ mtspr srr1,r7
+ mflr r7
+ mtspr srr0,r7
+ rfi
+__440gx_msr_continue:
+#endif
+
mtlr r4 /* restore link register */
blr
diff --git a/cpu/ppc4xx/vecnum.h b/cpu/ppc4xx/vecnum.h
index cbfe41db9c..93cef026a3 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 */