* Patch by Sangmoon Kim, 23 Sep 2003:

fix pll_pci_to_mem_multiplier table for MPC8245

* Patch by Anders Larsen, 22 Sep 2003:
  enable timed autoboot on PXA

* Patch by David Mller, 22 Sep 2003:

  - add $(CFLAGS) to "-print-libgcc-filename" so compiler driver
    returns correct libgcc file path
  - "latency" reduction of busy-loop waiting to improve "U-Boot" boot
    time on s3c24x0 systems

* Patch by Jon Diekema, 19 Sep 2003:
  - Add CFG_FAULT_ECHO_LINK_DOWN option to echo the inverted Ethernet
    link state to the fault LED.
  - In NetLoop, make the Fault LED reflect the link status.  The link
    status gets updated on entry, and on timeouts.
master
wdenk 21 years ago
parent ef1464cc01
commit fc3e2165ef
  1. 19
      CHANGELOG
  2. 2
      Makefile
  3. 8
      README
  4. 23
      common/miiphyutil.c
  5. 4
      cpu/mpc824x/speed.c
  6. 20
      cpu/pxa/interrupts.c
  7. 160
      drivers/s3c24x0_i2c.c
  8. 3
      include/miiphy.h
  9. 28
      net/net.c

@ -2,6 +2,25 @@
Changes for U-Boot 1.0.0:
======================================================================
* Patch by Sangmoon Kim, 23 Sep 2003:
fix pll_pci_to_mem_multiplier table for MPC8245
* Patch by Anders Larsen, 22 Sep 2003:
enable timed autoboot on PXA
* Patch by David Müller, 22 Sep 2003:
- add $(CFLAGS) to "-print-libgcc-filename" so compiler driver
returns correct libgcc file path
- "latency" reduction of busy-loop waiting to improve "U-Boot" boot
time on s3c24x0 systems
* Patch by Jon Diekema, 19 Sep 2003:
- Add CFG_FAULT_ECHO_LINK_DOWN option to echo the inverted Ethernet
link state to the fault LED.
- In NetLoop, make the Fault LED reflect the link status. The link
status gets updated on entry, and on timeouts.
* Patch by Anders Larsen, 18 Sep 2003:
allow mkimage to build and run on Cygwin-hosted systems

@ -118,7 +118,7 @@ LIBS += post/libpost.a post/cpu/libcpu.a
LIBS += common/libcommon.a
LIBS += lib_generic/libgeneric.a
# Add GCC lib
PLATFORM_LIBS += -L $(shell dirname `$(CC) -print-libgcc-file-name`) -lgcc
PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
#########################################################################
#########################################################################

@ -1749,6 +1749,14 @@ Note: once the monitor has been relocated, then it will complain if
the default environment is used; a new CRC is computed as soon as you
use the "saveenv" command to store a valid environment.
- CFG_FAULT_ECHO_LINK_DOWN:
Echo the inverted Ethernet link state to the fault LED.
Note: If this option is active, then CFG_FAULT_MII_ADDR
also needs to be defined.
- CFG_FAULT_MII_ADDR:
MII address of the PHY to check for the Ethernet link state.
Low Level (hardware related) configuration options:
---------------------------------------------------

@ -169,4 +169,27 @@ int miiphy_duplex (unsigned char addr)
}
}
#ifdef CFG_FAULT_ECHO_LINK_DOWN
/*****************************************************************************
*
* Determine link status
*/
int miiphy_link (unsigned char addr)
{
unsigned short reg;
if (miiphy_read (addr, PHY_BMSR, &reg)) {
printf ("PHY_BMSR read failed, assuming no link\n");
return (0);
}
/* Determine if a link is active */
if ((reg & PHY_BMSR_LS) != 0) {
return (1);
} else {
return (0);
}
}
#endif
#endif /* CONFIG_MII || (CONFIG_COMMANDS & CFG_CMD_MII) */

@ -61,8 +61,8 @@ short pll_pci_to_mem_multiplier[] = {
25, 0, 10, 0, 15, 15, 0, 0,
#elif defined(CONFIG_MPC8245)
30, 30, 10, 10, 20, 10, 10, 10,
10, 20, 20, 15, 20, 15, 20, 0,
30, 0, 15, 40, 20, 25, 20, 40,
10, 20, 20, 15, 20, 15, 20, 30,
30, 40, 15, 40, 20, 25, 20, 40,
25, 20, 10, 20, 15, 15, 15, 0,
#else
#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)

@ -202,3 +202,23 @@ void udelay_masked (unsigned long usec)
while (tmo >= get_timer_masked ())
/*NOP*/;
}
/*
* This function is derived from PowerPC code (read timebase as long long).
* On ARM it just returns the timer value.
*/
unsigned long long get_ticks(void)
{
return get_timer(0);
}
/*
* This function is derived from PowerPC code (timebase clock frequency).
* On ARM it returns the number of timer ticks per second.
*/
ulong get_tbclk (void)
{
ulong tbclk;
tbclk = CFG_HZ;
return tbclk;
}

@ -91,40 +91,40 @@ static void SetI2CSCL(int x)
}
static int WaitForXfer(void)
static int WaitForXfer (void)
{
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
S3C24X0_I2C *const i2c = S3C24X0_GetBase_I2C ();
int i, status;
i = I2C_TIMEOUT * 1000;
i = I2C_TIMEOUT * 10000;
status = i2c->IICCON;
while ((i > 0) && !(status & I2CCON_IRPND)) {
udelay(1000);
udelay (100);
status = i2c->IICCON;
i--;
}
return(status & I2CCON_IRPND) ? I2C_OK : I2C_NOK_TOUT;
return (status & I2CCON_IRPND) ? I2C_OK : I2C_NOK_TOUT;
}
static int IsACK(void)
static int IsACK (void)
{
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
S3C24X0_I2C *const i2c = S3C24X0_GetBase_I2C ();
return(!(i2c->IICSTAT & I2CSTAT_NACK));
return (!(i2c->IICSTAT & I2CSTAT_NACK));
}
static void ReadWriteByte(void)
static void ReadWriteByte (void)
{
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
S3C24X0_I2C *const i2c = S3C24X0_GetBase_I2C ();
i2c->IICCON &= ~I2CCON_IRPND;
}
void i2c_init (int speed, int slaveadd)
{
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
S3C24X0_I2C *const i2c = S3C24X0_GetBase_I2C ();
S3C24X0_GPIO *const gpio = S3C24X0_GetBase_GPIO ();
ulong freq, pres = 16, div;
int i, status;
@ -133,12 +133,12 @@ void i2c_init (int speed, int slaveadd)
i = I2C_TIMEOUT * 1000;
status = i2c->IICSTAT;
while ((i > 0) && (status & I2CSTAT_BSY)) {
udelay(1000);
udelay (1000);
status = i2c->IICSTAT;
i--;
}
if ((status & I2CSTAT_BSY) || GetI2CSDA() == 0) {
if ((status & I2CSTAT_BSY) || GetI2CSDA () == 0) {
#ifdef CONFIG_S3C2410
ulong old_gpecon = gpio->GPECON;
#endif
@ -157,14 +157,18 @@ void i2c_init (int speed, int slaveadd)
#endif
/* toggle I2CSCL until bus idle */
SetI2CSCL(0); udelay(1000);
SetI2CSCL (0);
udelay (1000);
i = 10;
while ((i > 0) && (GetI2CSDA() != 1)) {
SetI2CSCL(1); udelay(1000);
SetI2CSCL(0); udelay(1000);
while ((i > 0) && (GetI2CSDA () != 1)) {
SetI2CSCL (1);
udelay (1000);
SetI2CSCL (0);
udelay (1000);
i--;
}
SetI2CSCL(1); udelay(1000);
SetI2CSCL (1);
udelay (1000);
/* restore pin functions */
#ifdef CONFIG_S3C2410
@ -176,17 +180,17 @@ void i2c_init (int speed, int slaveadd)
}
/* calculate prescaler and divisor values */
freq = get_PCLK();
if ((freq / pres / (16+1)) > speed)
freq = get_PCLK ();
if ((freq / pres / (16 + 1)) > speed)
/* set prescaler to 512 */
pres = 512;
div = 0;
while ((freq / pres / (div+1)) > speed)
while ((freq / pres / (div + 1)) > speed)
div++;
/* set prescaler, divisor according to freq, also set
ACKGEN, IRQ */
* ACKGEN, IRQ */
i2c->IICCON = (div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0);
/* init to SLAVE REVEIVE and set slaveaddr */
@ -198,49 +202,41 @@ void i2c_init (int speed, int slaveadd)
}
/*
cmd_type is 0 for write 1 for read.
addr_len can take any value from 0-255, it is only limited
by the char, we could make it larger if needed. If it is
0 we skip the address write cycle.
*/
* cmd_type is 0 for write, 1 for read.
*
* addr_len can take any value from 0-255, it is only limited
* by the char, we could make it larger if needed. If it is
* 0 we skip the address write cycle.
*/
static
int i2c_transfer(unsigned char cmd_type,
int i2c_transfer (unsigned char cmd_type,
unsigned char chip,
unsigned char addr[],
unsigned char addr_len,
unsigned char data[],
unsigned short data_len)
unsigned char data[], unsigned short data_len)
{
S3C24X0_I2C * const i2c = S3C24X0_GetBase_I2C();
S3C24X0_I2C *const i2c = S3C24X0_GetBase_I2C ();
int i, status, result;
if (data == 0 || data_len == 0) {
/*Don't support data transfer of no length or to address 0*/
printf( "i2c_transfer: bad call\n" );
/*Don't support data transfer of no length or to address 0 */
printf ("i2c_transfer: bad call\n");
return I2C_NOK;
}
/*CheckDelay(); */
/* Check I2C bus idle */
i = I2C_TIMEOUT * 1000;
status = i2c->IICSTAT;
while ((i > 0) && (status & I2CSTAT_BSY)) {
udelay(1000);
udelay (1000);
status = i2c->IICSTAT;
i--;
}
if (status & I2CSTAT_BSY) {
result = I2C_NOK_TOUT;
return(result);
}
if (status & I2CSTAT_BSY)
return I2C_NOK_TOUT;
i2c->IICCON |= 0x80;
result = I2C_OK;
switch (cmd_type) {
@ -251,16 +247,16 @@ int i2c_transfer(unsigned char cmd_type,
i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP;
i = 0;
while ((i < addr_len) && (result == I2C_OK)) {
result = WaitForXfer();
result = WaitForXfer ();
i2c->IICDS = addr[i];
ReadWriteByte();
ReadWriteByte ();
i++;
}
i = 0;
while ((i < data_len) && (result == I2C_OK)) {
result = WaitForXfer();
result = WaitForXfer ();
i2c->IICDS = data[i];
ReadWriteByte();
ReadWriteByte ();
i++;
}
} else {
@ -269,19 +265,19 @@ int i2c_transfer(unsigned char cmd_type,
i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP;
i = 0;
while ((i < data_len) && (result = I2C_OK)) {
result = WaitForXfer();
result = WaitForXfer ();
i2c->IICDS = data[i];
ReadWriteByte();
ReadWriteByte ();
i++;
}
}
if (result == I2C_OK)
result = WaitForXfer();
result = WaitForXfer ();
/* send STOP */
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA;
ReadWriteByte();
ReadWriteByte ();
break;
case I2C_READ:
@ -290,28 +286,29 @@ int i2c_transfer(unsigned char cmd_type,
i2c->IICDS = chip;
/* send START */
i2c->IICSTAT |= I2C_START_STOP;
result = WaitForXfer();
if (IsACK()) {
result = WaitForXfer ();
if (IsACK ()) {
i = 0;
while ((i < addr_len) && (result == I2C_OK)) {
i2c->IICDS = addr[i];
ReadWriteByte();
result = WaitForXfer();
ReadWriteByte ();
result = WaitForXfer ();
i++;
}
i2c->IICDS = chip;
/* resend START */
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP;
ReadWriteByte();
result = WaitForXfer();
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA |
I2C_START_STOP;
ReadWriteByte ();
result = WaitForXfer ();
i = 0;
while ((i < data_len) && (result == I2C_OK)) {
/* disable ACK for final READ */
if (i == data_len - 1)
i2c->IICCON &= ~0x80;
ReadWriteByte();
result = WaitForXfer();
ReadWriteByte ();
result = WaitForXfer ();
data[i] = i2c->IICDS;
i++;
}
@ -324,16 +321,16 @@ int i2c_transfer(unsigned char cmd_type,
i2c->IICDS = chip;
/* send START */
i2c->IICSTAT |= I2C_START_STOP;
result = WaitForXfer();
result = WaitForXfer ();
if (IsACK()) {
if (IsACK ()) {
i = 0;
while ((i < data_len) && (result == I2C_OK)) {
/* disable ACK for final READ */
if (i == data_len - 1)
i2c->IICCON &= ~0x80;
ReadWriteByte();
result = WaitForXfer();
ReadWriteByte ();
result = WaitForXfer ();
data[i] = i2c->IICDS;
i++;
}
@ -344,11 +341,11 @@ int i2c_transfer(unsigned char cmd_type,
/* send STOP */
i2c->IICSTAT = I2C_MODE_MR | I2C_TXRX_ENA;
ReadWriteByte();
ReadWriteByte ();
break;
default:
printf( "i2c_transfer: bad call\n" );
printf ("i2c_transfer: bad call\n");
result = I2C_NOK;
break;
}
@ -367,7 +364,7 @@ int i2c_probe (uchar chip)
* address was <ACK>ed (i.e. there was a chip at that address which
* drove the data line low).
*/
return(i2c_transfer (I2C_READ, chip << 1, 0, 0, buf, 1) != I2C_OK);
return (i2c_transfer (I2C_READ, chip << 1, 0, 0, buf, 1) != I2C_OK);
}
int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
@ -375,19 +372,18 @@ int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
uchar xaddr[4];
int ret;
if ( alen > 4 ) {
if (alen > 4) {
printf ("I2C read: addr len %d not supported\n", alen);
return 1;
}
if ( alen > 0 ) {
if (alen > 0) {
xaddr[0] = (addr >> 24) & 0xFF;
xaddr[1] = (addr >> 16) & 0xFF;
xaddr[2] = (addr >> 8) & 0xFF;
xaddr[3] = addr & 0xFF;
}
#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
/*
* EEPROM chips that implement "address overflow" are ones
@ -400,11 +396,13 @@ int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
* still be one byte because the extra address bits are
* hidden in the chip address.
*/
if( alen > 0 )
if (alen > 0)
chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
#endif
if( (ret = i2c_transfer(I2C_READ, chip<<1, &xaddr[4-alen], alen, buffer, len )) != 0) {
printf( "I2c read: failed %d\n", ret);
if ((ret =
i2c_transfer (I2C_READ, chip << 1, &xaddr[4 - alen], alen,
buffer, len)) != 0) {
printf ("I2c read: failed %d\n", ret);
return 1;
}
return 0;
@ -414,18 +412,17 @@ int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
{
uchar xaddr[4];
if ( alen > 4 ) {
if (alen > 4) {
printf ("I2C write: addr len %d not supported\n", alen);
return 1;
}
if ( alen > 0 ) {
if (alen > 0) {
xaddr[0] = (addr >> 24) & 0xFF;
xaddr[1] = (addr >> 16) & 0xFF;
xaddr[2] = (addr >> 8) & 0xFF;
xaddr[3] = addr & 0xFF;
}
#ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW
/*
* EEPROM chips that implement "address overflow" are ones
@ -438,12 +435,13 @@ int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
* still be one byte because the extra address bits are
* hidden in the chip address.
*/
if( alen > 0 )
if (alen > 0)
chip |= ((addr >> (alen * 8)) & CFG_I2C_EEPROM_ADDR_OVERFLOW);
#endif
return (i2c_transfer(I2C_WRITE, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
return (i2c_transfer
(I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer,
len) != 0);
}
#endif /* CONFIG_HARD_I2C */
#endif /* CONFIG_DRIVER_S3C24X0_I2C */

@ -46,6 +46,9 @@ int miiphy_info(unsigned char addr, unsigned int *oui, unsigned char *model,
int miiphy_reset(unsigned char addr);
int miiphy_speed(unsigned char addr);
int miiphy_duplex(unsigned char addr);
#ifdef CFG_FAULT_ECHO_LINK_DOWN
int miiphy_link(unsigned char addr);
#endif
/* phy seed setup */

@ -65,6 +65,10 @@
#include "bootp.h"
#include "tftp.h"
#include "rarp.h"
#ifdef CONFIG_STATUS_LED
#include <status_led.h>
#include <miiphy.h>
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NET)
@ -361,6 +365,18 @@ restart:
break;
}
#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
#if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED)
/*
* Echo the inverted link state to the fault LED.
*/
if(miiphy_link(CFG_FAULT_MII_ADDR)) {
status_led_set (STATUS_LED_RED, STATUS_LED_OFF);
} else {
status_led_set (STATUS_LED_RED, STATUS_LED_ON);
}
#endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */
#endif /* CONFIG_MII, ... */
/*
* Main packet reception loop. Loop receiving packets until
@ -398,6 +414,18 @@ restart:
if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) {
thand_f *x;
#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
#if defined(CFG_FAULT_ECHO_LINK_DOWN) && defined(CONFIG_STATUS_LED) && defined(STATUS_LED_RED)
/*
* Echo the inverted link state to the fault LED.
*/
if(miiphy_link(CFG_FAULT_MII_ADDR)) {
status_led_set (STATUS_LED_RED, STATUS_LED_OFF);
} else {
status_led_set (STATUS_LED_RED, STATUS_LED_ON);
}
#endif /* CFG_FAULT_ECHO_LINK_DOWN, ... */
#endif /* CONFIG_MII, ... */
x = timeHandler;
timeHandler = (thand_f *)0;
(*x)();

Loading…
Cancel
Save