Commit e0ac62d7 authored by wdenk's avatar wdenk
Browse files

* Make Ethernet autonegotiation on INCA-IP work for all clock rates;

  allow selection of clock frequency as "make" target

* Implement memory autosizing code for IceCube boards

* Configure network port on INCA-IP for autonegotiation

* Fix overflow problem in network timeout code

* Patch by Richard Woodruff, 8 Aug 2003:
  Allow crc32 to be used at address 0x000 (crc32_no_comp, too).
parent ae3af05e
......@@ -2,6 +2,18 @@
Changes for U-Boot 0.4.5:
======================================================================
* Make Ethernet autonegotiation on INCA-IP work for all clock rates;
allow selection of clock frequency as "make" target
* Implement memory autosizing code for IceCube boards
* Configure network port on INCA-IP for autonegotiation
* Fix overflow problem in network timeout code
* Patch by Richard Woodruff, 8 Aug 2003:
Allow crc32 to be used at address 0x000 (crc32_no_comp, too).
* Update for TQM board defaults:
disable clocks_in_mhz, enable boot count limit
......
......@@ -848,8 +848,30 @@ sc520_spunk_rel_config : unconfig
## MIPS32 4Kc
#########################################################################
incaip_config : unconfig
@./mkconfig $(@:_config=) mips mips incaip
xtract_incaip = $(subst _100MHz,,$(subst _133MHz,,$(subst _150MHz,,$(subst _config,,$1))))
incaip_100MHz_config \
incaip_133MHz_config \
incaip_150MHz_config \
incaip_config: unconfig
@ >include/config.h
@[ -z "$(findstring _100MHz,$@)" ] || \
{ echo "#define CPU_CLOCK_RATE 100000000" >>include/config.h ; \
echo "... with 100MHz system clock" ; \
}
@[ -z "$(findstring _133MHz,$@)" ] || \
{ echo "#define CPU_CLOCK_RATE 133000000" >>include/config.h ; \
echo "... with 133MHz system clock" ; \
}
@[ -z "$(findstring _150MHz,$@)" ] || \
{ echo "#define CPU_CLOCK_RATE 150000000" >>include/config.h ; \
echo "... with 150MHz system clock" ; \
}
@./mkconfig -a $(call xtract_incaip,$@) mips mips incaip
#########################################################################
## MIPS64 5Kc
#########################################################################
purple_config : unconfig
@./mkconfig $(@:_config=) mips mips purple
......
......@@ -25,35 +25,84 @@
#include <mpc5xxx.h>
#include <pci.h>
long int initdram (int board_type)
static long int dram_size(long int *base, long int maxsize)
{
#ifndef CFG_RAMBOOT
/* configure SDRAM start/end */
#if defined(CONFIG_MPC5200)
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x00000018;/* 32M at 0x0 */
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x02000000;/* disabled */
volatile long int *addr;
ulong cnt, val;
ulong save[32]; /* to make test non-destructive */
unsigned char i = 0;
/* setup config registers */
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2233a00;
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004;
for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
addr = base + cnt; /* pointer arith! */
save[i++] = *addr;
*addr = ~cnt;
}
/* write 0 to base address */
addr = base;
save[i] = *addr;
*addr = 0;
/* check at base address */
if ((val = *addr) != 0) {
*addr = save[i];
return (0);
}
for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
addr = base + cnt; /* pointer arith! */
val = *addr;
*addr = save[--i];
if (val != (~cnt)) {
return (cnt * sizeof (long));
}
}
return (maxsize);
}
static void sdram_start (int hi_addr)
{
long hi_addr_bit = hi_addr ? 0x01000000 : 0;
/* unlock mode register */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0000;
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0000 | hi_addr_bit;
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002;
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002 | hi_addr_bit;
/* set mode register */
#if defined(CONFIG_MPC5200)
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x408d0000;
#elif defined(CONFIG_MGT5100)
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
#endif
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002;
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002 | hi_addr_bit;
/* auto refresh */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0004;
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0004 | hi_addr_bit;
/* set mode register */
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
/* normal operation */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0x504f0000;
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0x504f0000 | hi_addr_bit;
}
long int initdram (int board_type)
{
ulong test1, test2, dramsize = 0;
#ifndef CFG_RAMBOOT
/* configure SDRAM start/end */
#if defined(CONFIG_MPC5200)
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */
/* setup config registers */
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2233a00;
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004;
#elif defined(CONFIG_MGT5100)
*(vu_long *)MPC5XXX_SDRAM_START = 0x00000000;
*(vu_long *)MPC5XXX_SDRAM_STOP = 0x000007ff;/* 64M */
*(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */
*(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
/* setup config registers */
......@@ -62,33 +111,32 @@ long int initdram (int board_type)
/* address select register */
*(vu_long *)MPC5XXX_SDRAM_XLBSEL = 0x03000000;
/* unlock mode register */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd14f0000;
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd14f0002;
/* set mode register */
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd14f0002;
/* auto refresh */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd14f0004;
/* set mode register */
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
/* normal operation */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0x514f0000;
#endif
sdram_start(0);
test1 = dram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
sdram_start(1);
test2 = dram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
if (test1 > test2) {
sdram_start(0);
dramsize = test1;
} else {
dramsize = test2;
}
#if defined(CONFIG_MPC5200)
*(vu_long *)MPC5XXX_SDRAM_CS0CFG =
(0x13 + __builtin_ffs(dramsize >> 20) - 1);
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
#elif defined(CONFIG_MGT5100)
*(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15);
#endif
#else
#ifdef CONFIG_MGT5100
*(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
#endif
#endif
/* return total ram size */
#if defined(CONFIG_MGT5100)
return (64 * 1024 * 1024);
#elif defined(CONFIG_MPC5200)
return (32 * 1024 * 1024);
#endif
return dramsize;
}
int checkboard (void)
......
......@@ -116,14 +116,15 @@ unsigned long flash_init (void)
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON by default */
debug ("Protect %senvironment: %08lx ... %08lx\n",
# ifdef CFG_ENV_ADDR_REDUND
"primary ",
debug ("Protect primary environment: %08lx ... %08lx\n",
(ulong)CFG_ENV_ADDR,
(ulong)CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1);
# else
"",
# endif
debug ("Protect environment: %08lx ... %08lx\n",
(ulong)CFG_ENV_ADDR,
(ulong)CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1);
# endif
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
......
......@@ -51,9 +51,6 @@ static int mpc5200_read_config_dword(struct pci_controller *hose,
*value = in_le32((volatile u32 *)CONFIG_PCI_IO_PHYS);
eieio();
*(volatile u32 *)MPC5XXX_PCI_CAR = 0;
/* skip MPC5200 */
if (offset == 0 && *value == 0x58031057)
*value = 0xffffffff;
return 0;
}
......
......@@ -103,7 +103,7 @@ boot_cold:
boot_warm:
mfmsr r5 /* save msr contents */
#if defined(CFG_DEFAULT_MBAR)
#if defined(CFG_DEFAULT_MBAR) && !defined(CFG_RAMBOOT)
lis r3, CFG_MBAR@h
ori r3, r3, CFG_MBAR@l
#if defined(CONFIG_MPC5200)
......
......@@ -41,4 +41,18 @@ to install a U-Boot image into flash.
go 0xb0000000
Ethernet autonegotiation needs some time to complete. Instead of
delaying the boot process in all cases, we just start the
autonegotiation process when U-Boot comes up and that is all. Most
likely, it will complete by the time the network transfer is
attempted for the first time. In the worst case, if a transfer is
attempted before the autonegotiation is complete, just a single
packet would be lost resulting in a single timeout error, and then
the transfer would proceed normally. So the time that we would have
lost unconditionally waiting for the autonegotiation to complete, we
have to wait only if the file transfer is started immediately after
reset. We've verified that this works for all the clock
configurations.
(C) 2003 Wolfgang Denk
......@@ -70,10 +70,8 @@
typedef struct
{
union
{
struct
{
union {
struct {
volatile u32 HOLD :1;
volatile u32 ICpt :1;
volatile u32 IEop :1;
......@@ -89,10 +87,8 @@ typedef struct
volatile u32 RxDataPtr;
union
{
struct
{
union {
struct {
volatile u32 C :1;
volatile u32 Sop :1;
volatile u32 Eop :1;
......@@ -108,10 +104,8 @@ typedef struct
typedef struct
{
union
{
struct
{
union {
struct {
volatile u32 HOLD :1;
volatile u32 Eop :1;
volatile u32 Sop :1;
......@@ -159,8 +153,7 @@ int inca_switch_initialize(bd_t * bis)
printf("Entered inca_switch_initialize()\n");
#endif
if (!(dev = (struct eth_device *) malloc (sizeof *dev)))
{
if (!(dev = (struct eth_device *) malloc (sizeof *dev))) {
printf("Failed to allocate memory\n");
return 0;
}
......@@ -196,8 +189,8 @@ static int inca_switch_init(struct eth_device *dev, bd_t * bis)
printf("Entering inca_switch_init()\n");
#endif
/* Set MAC address.
*/
/* Set MAC address.
*/
wTmp = (u16)dev->enetaddr[0];
regValue = (wTmp << 8) | dev->enetaddr[1];
......@@ -211,35 +204,32 @@ static int inca_switch_init(struct eth_device *dev, bd_t * bis)
SW_WRITE_REG(INCA_IP_Switch_PMAC_SA2, regValue);
/* Initialize the descriptor rings.
*/
/* Initialize the descriptor rings.
*/
for (i = 0; i < NUM_RX_DESC; i++)
{
inca_rx_descriptor_t * rx_desc = KSEG1ADDR(&rx_ring[i]);
memset(rx_desc, 0, sizeof(rx_ring[i]));
/* Set maximum size of receive buffer.
*/
/* Set maximum size of receive buffer.
*/
rx_desc->params.field.NFB = PKTSIZE_ALIGN;
/* Set the offset of the receive buffer. Zero means
* that the offset mechanism is not used.
*/
/* Set the offset of the receive buffer. Zero means
* that the offset mechanism is not used.
*/
rx_desc->params.field.offset = 0;
/* Check if it is the last descriptor.
*/
if (i == (NUM_RX_DESC - 1))
{
/* Let the last descriptor point to the first
* one.
*/
if (i == (NUM_RX_DESC - 1)) {
/* Let the last descriptor point to the first
* one.
*/
rx_desc->nextRxDescPtr = KSEG1ADDR((u32)rx_ring);
}
else
{
/* Set the address of the next descriptor.
*/
} else {
/* Set the address of the next descriptor.
*/
rx_desc->nextRxDescPtr = (u32)KSEG1ADDR(&rx_ring[i+1]);
}
......@@ -251,8 +241,7 @@ static int inca_switch_init(struct eth_device *dev, bd_t * bis)
printf("tx_ring = 0x%08X 0x%08X\n", (u32)tx_ring, (u32)&tx_ring[0]);
#endif
for (i = 0; i < NUM_TX_DESC; i++)
{
for (i = 0; i < NUM_TX_DESC; i++) {
inca_tx_descriptor_t * tx_desc = KSEG1ADDR(&tx_ring[i]);
memset(tx_desc, 0, sizeof(tx_ring[i]));
......@@ -263,46 +252,43 @@ static int inca_switch_init(struct eth_device *dev, bd_t * bis)
/* Check if it is the last descriptor.
*/
if (i == (NUM_TX_DESC - 1))
{
if (i == (NUM_TX_DESC - 1)) {
/* Let the last descriptor point to the
* first one.
*/
tx_desc->nextTxDescPtr = KSEG1ADDR((u32)tx_ring);
}
else
{
} else {
/* Set the address of the next descriptor.
*/
tx_desc->nextTxDescPtr = (u32)KSEG1ADDR(&tx_ring[i+1]);
}
}
/* Initialize RxDMA.
*/
/* Initialize RxDMA.
*/
DMA_READ_REG(INCA_IP_DMA_DMA_RXISR, v);
#if 0
printf("RX status = 0x%08X\n", v);
#endif
/* Writing to the FRDA of CHANNEL.
*/
/* Writing to the FRDA of CHANNEL.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_RXFRDA0, (u32)rx_ring);
/* Writing to the COMMAND REG.
*/
/* Writing to the COMMAND REG.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0,
INCA_IP_DMA_DMA_RXCCR0_INIT);
/* Initialize TxDMA.
*/
/* Initialize TxDMA.
*/
DMA_READ_REG(INCA_IP_DMA_DMA_TXISR, v);
#if 0
printf("TX status = 0x%08X\n", v);
#endif
/* Writing to the FRDA of CHANNEL.
*/
/* Writing to the FRDA of CHANNEL.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXFRDA0, (u32)tx_ring);
tx_new = rx_new = 0;
......@@ -313,12 +299,12 @@ static int inca_switch_init(struct eth_device *dev, bd_t * bis)
#if 0
rx_ring[rx_hold].params.field.HOLD = 1;
#endif
/* enable spanning tree forwarding, enable the CPU port */
/* ST_PT:
CPS (CPU port status) 0x3 (forwarding)
LPS (LAN port status) 0x3 (forwarding)
PPS (PC port status) 0x3 (forwarding)
*/
/* enable spanning tree forwarding, enable the CPU port */
/* ST_PT:
* CPS (CPU port status) 0x3 (forwarding)
* LPS (LAN port status) 0x3 (forwarding)
* PPS (PC port status) 0x3 (forwarding)
*/
SW_WRITE_REG(INCA_IP_Switch_ST_PT,0x3f);
#if 0
......@@ -342,23 +328,19 @@ static int inca_switch_send(struct eth_device *dev, volatile void *packet,
printf("Entered inca_switch_send()\n");
#endif
if (length <= 0)
{
if (length <= 0) {
printf ("%s: bad packet size: %d\n", dev->name, length);
goto Done;
}
for(i = 0; tx_desc->C == 0; i++)
{
if (i >= TOUT_LOOP)
{
for(i = 0; tx_desc->C == 0; i++) {
if (i >= TOUT_LOOP) {
printf("%s: tx error buffer not ready\n", dev->name);
goto Done;
}
}
if (tx_old_hold >= 0)
{
if (tx_old_hold >= 0) {
KSEG1ADDR(&tx_ring[tx_old_hold])->params.field.HOLD = 1;
}
tx_old_hold = tx_hold;
......@@ -376,13 +358,10 @@ static int inca_switch_send(struct eth_device *dev, volatile void *packet,
tx_new = (tx_new + 1) % NUM_TX_DESC;
if (! initialized)
{
if (! initialized) {
command = INCA_IP_DMA_DMA_TXCCR0_INIT;
initialized = 1;
}
else
{
} else {
command = INCA_IP_DMA_DMA_TXCCR0_HR;
}
......@@ -394,10 +373,8 @@ static int inca_switch_send(struct eth_device *dev, volatile void *packet,
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, regValue);
#if 1
for(i = 0; KSEG1ADDR(&tx_ring[tx_hold])->C == 0; i++)
{
if (i >= TOUT_LOOP)
{
for(i = 0; KSEG1ADDR(&tx_ring[tx_hold])->C == 0; i++) {
if (i >= TOUT_LOOP) {
printf("%s: tx buffer not ready\n", dev->name);
goto Done;
}
......@@ -421,12 +398,10 @@ static int inca_switch_recv(struct eth_device *dev)
printf("Entered inca_switch_recv()\n");
#endif
for (;;)
{
for (;;) {
rx_desc = KSEG1ADDR(&rx_ring[rx_new]);
if (rx_desc->status.field.C == 0)
{
if (rx_desc->status.field.C == 0) {
break;
}
......@@ -434,8 +409,7 @@ static int inca_switch_recv(struct eth_device *dev)
rx_ring[rx_new].params.field.HOLD = 1;
#endif
if (! rx_desc->status.field.Eop)
{
if (! rx_desc->status.field.Eop) {
printf("Partly received packet!!!\n");
break;
}
......@@ -454,16 +428,13 @@ static int inca_switch_recv(struct eth_device *dev)
}
#endif
if (length)
{
if (length) {
#if 0
printf("Received %d bytes\n", length);
#endif
NetReceive((void*)KSEG1ADDR(NetRxPackets[rx_new]),
length - 4);
}
else
{
} else {
#if 1
printf("Zero length!!!\n");
#endif
......@@ -495,16 +466,16 @@ static void inca_switch_halt(struct eth_device *dev)
initialized = 0;
#endif
#if 1
/* Disable forwarding to the CPU port.
*/
/* Disable forwarding to the CPU port.
*/
SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf);
/* Close RxDMA channel.
*/
/* Close RxDMA channel.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
/* Close TxDMA channel.
*/
/* Close TxDMA channel.
*/
DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_TXCCR0_OFF);
......@@ -519,88 +490,89 @@ static void inca_init_switch_chip(void)
{
u32 regValue;
/* To workaround a problem with collision counter
* (see Errata sheet).
*/
/* To workaround a problem with collision counter
* (see Errata sheet).
*/
SW_WRITE_REG(INCA_IP_Switch_PC_TX_CTL, 0x00000001);
SW_WRITE_REG(INCA_IP_Switch_LAN_TX_CTL, 0x00000001);
#if 1
/* init MDIO configuration:
MDS (Poll speed): 0x01 (4ms)
PHY_LAN_ADDR: 0x06
PHY_PC_ADDR: 0x05
UEP (Use External PHY): 0x00 (Internal PHY is used)
PS (Port Select): 0x00 (PT/UMM for LAN)
PT (PHY Test): 0x00 (no test mode)
UMM (Use MDIO Mode): 0x00 (state machine is disabled)
*/
/* init MDIO configuration:
* MDS (Poll speed): 0x01 (4ms)
* PHY_LAN_ADDR: 0x06
* PHY_PC_ADDR: 0x05
* UEP (Use External PHY): 0x00 (Internal PHY is used)
* PS (Port Select): 0x00 (PT/UMM for LAN)
* PT (PHY Test): 0x00 (no test mode)
* UMM (Use MDIO Mode): 0x00 (state machine is disabled)
*/
SW_WRITE_REG(INCA_IP_Switch_MDIO_CFG, 0x4c50);
/* init PHY:
SL (Auto Neg. Speed for LAN)
SP (Auto Neg. Speed for PC)
LL (Link Status for LAN)
LP (Link Status for PC)
DL (Duplex Status for LAN)
DP (Duplex Status for PC)
PL (Auto Neg. Pause Status for LAN)
PP (Auto Neg. Pause Status for PC)
*/
/* init PHY:
* SL (Auto Neg. Speed for LAN)
* SP (Auto Neg. Speed for PC)
* LL (Link Status for LAN)
* LP (Link Status for PC)
* DL (Duplex Status for LAN)
* DP (Duplex Status for PC)
* PL (Auto Neg. Pause Status for LAN)