summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRemy Bohmer <linux@bohmer.net>2008-06-03 15:26:24 +0200
committerBen Warren <biggerbadderben@gmail.com>2008-06-04 23:47:31 -0700
commitfbcb7ece0ea1e364180f1cf963e0fa0ce7f6560d (patch)
tree90372be6e1a16b1d74f678651831a63d311d4453
parentacba31847fad9ae40708cc2c9f3a634ec35f3416 (diff)
downloadu-boot-imx-fbcb7ece0ea1e364180f1cf963e0fa0ce7f6560d.zip
u-boot-imx-fbcb7ece0ea1e364180f1cf963e0fa0ce7f6560d.tar.gz
u-boot-imx-fbcb7ece0ea1e364180f1cf963e0fa0ce7f6560d.tar.bz2
DM9000: Improve eth_reset() routine
According to the application notes of the DM9000 v1.22 chapter 5.2 bullet 2, the reset procedure must be done twice to properly reset the DM9000 by means of software. This errata is not needed anymore for the DM9000A, but it does not bother it. This change has been tested with DM9000A, DM9000E, DM9000EP. Signed-off-by: Remy Bohmer <linux@bohmer.net> Signed-off-by: Ben Warren <biggerbadderben@gmail.com>
-rw-r--r--drivers/net/dm9000x.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c
index c6c24dd..5b00e95 100644
--- a/drivers/net/dm9000x.c
+++ b/drivers/net/dm9000x.c
@@ -45,6 +45,8 @@ v1.2 03/18/2003 Weilun Huang <weilun_huang@davicom.com.tw>:
- Adapt eth_send such that it matches the DM9000*
application notes. Needed to make it work properly
for DM9000A.
+ - Adapted reset procedure to match DM9000 application
+ notes (i.e. double reset)
These changes are tested with DM9000{A,EP,E} together
with a 200MHz Atmel AT91SAM92161 core
@@ -362,9 +364,35 @@ identify_nic(void)
static void
dm9000_reset(void)
{
- DM9000_DBG("resetting\n");
- DM9000_iow(DM9000_NCR, NCR_RST);
- udelay(1000); /* delay 1ms */
+ DM9000_DBG("resetting DM9000\n");
+
+ /* Reset DM9000,
+ see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */
+
+ /* DEBUG: Make all GPIO pins outputs */
+ DM9000_iow(DM9000_GPCR, 0x0F);
+ /* Step 1: Power internal PHY by writing 0 to GPIO0 pin */
+ DM9000_iow(DM9000_GPR, 0);
+ /* Step 2: Software reset */
+ DM9000_iow(DM9000_NCR, 3);
+
+ do {
+ DM9000_DBG("resetting the DM9000, 1st reset\n");
+ udelay(25); /* Wait at least 20 us */
+ } while (DM9000_ior(DM9000_NCR) & 1);
+
+ DM9000_iow(DM9000_NCR, 0);
+ DM9000_iow(DM9000_NCR, 3); /* Issue a second reset */
+
+ do {
+ DM9000_DBG("resetting the DM9000, 2nd reset\n");
+ udelay(25); /* Wait at least 20 us */
+ } while (DM9000_ior(DM9000_NCR) & 1);
+
+ /* Check whether the ethernet controller is present */
+ if ((DM9000_ior(DM9000_PIDL) != 0x0) ||
+ (DM9000_ior(DM9000_PIDH) != 0x90))
+ printf("ERROR: resetting DM9000 -> not responding\n");
}
/* Initilize dm9000 board