dm9000 remove dead external phy support, gpio fix
dm9000 has code to detect and initialize external phy parts, but later
on in the code the part is forced to use the internal phy
unconditionally. Remove the unused/untested code.
change the GPIO initialization so that only the GPIO used as an
internal phy reset (hardwired in the chip) is set as an output. The
remaining GPIO need to be handled by board specific code to prevent
possible drive conflicts. Set as inputs for safety.
replace a few magic numbers with defines
Signed-off-by: Andrew Dyer <adyer@righthandtech.com>
Signed-off-by: Ben Warren <biggerbadderben@gmail.com>
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c
index e7365fe..3a61b80 100644
--- a/drivers/net/dm9000x.c
+++ b/drivers/net/dm9000x.c
@@ -55,8 +55,7 @@
These changes are tested with DM9000{A,EP,E} together
with a 200MHz Atmel AT91SAM92161 core
-TODO: Homerun NIC and longrun NIC are not functional, only internal at the
- moment.
+TODO: external MII is not functional, only internal at the moment.
*/
#include <common.h>
@@ -68,9 +67,6 @@
/* Board/System/Debug information/definition ---------------- */
-#define DM9801_NOISE_FLOOR 0x08
-#define DM9802_NOISE_FLOOR 0x05
-
/* #define CONFIG_DM9000_DEBUG */
#ifdef CONFIG_DM9000_DEBUG
@@ -90,13 +86,6 @@
#define DM9000_DMP_PACKET(func,packet,length)
#endif
-enum DM9000_PHY_mode { DM9000_10MHD = 0, DM9000_100MHD =
- 1, DM9000_10MFD = 4, DM9000_100MFD = 5, DM9000_AUTO =
- 8, DM9000_1M_HPNA = 0x10
-};
-enum DM9000_NIC_TYPE { FASTETHER_NIC = 0, HOMERUN_NIC = 1, LONGRUN_NIC = 2
-};
-
/* Structure/enum declaration ------------------------------- */
typedef struct board_info {
u32 runt_length_counter; /* counter: RX length < 64byte */
@@ -109,7 +98,6 @@
u16 dbug_cnt;
u8 phy_addr;
u8 device_wait_reset; /* device state */
- u8 nic_type; /* NIC type */
unsigned char srom[128];
void (*outblk)(volatile void *data_ptr, int count);
void (*inblk)(void *data_ptr, int count);
@@ -117,10 +105,6 @@
} board_info_t;
static board_info_t dm9000_info;
-/* For module input parameter */
-static int media_mode = DM9000_AUTO;
-static u8 nfloor = 0;
-
/* function declaration ------------------------------------- */
int eth_init(bd_t * bd);
int eth_send(volatile void *, int);
@@ -258,114 +242,6 @@
CONFIG_DM9000_BASE, id_val);
return -1;
}
-}
-
-/* Set PHY operationg mode
-*/
-static void
-set_PHY_mode(void)
-{
- u16 phy_reg4 = 0x01e1, phy_reg0 = 0x1000;
- if (!(media_mode & DM9000_AUTO)) {
- switch (media_mode) {
- case DM9000_10MHD:
- phy_reg4 = 0x21;
- phy_reg0 = 0x0000;
- break;
- case DM9000_10MFD:
- phy_reg4 = 0x41;
- phy_reg0 = 0x1100;
- break;
- case DM9000_100MHD:
- phy_reg4 = 0x81;
- phy_reg0 = 0x2000;
- break;
- case DM9000_100MFD:
- phy_reg4 = 0x101;
- phy_reg0 = 0x3100;
- break;
- }
- phy_write(4, phy_reg4); /* Set PHY media mode */
- phy_write(0, phy_reg0); /* Tmp */
- }
- DM9000_iow(DM9000_GPCR, 0x01); /* Let GPIO0 output */
- DM9000_iow(DM9000_GPR, 0x00); /* Enable PHY */
-}
-
-/*
- Init HomeRun DM9801
-*/
-static void
-program_dm9801(u16 HPNA_rev)
-{
- __u16 reg16, reg17, reg24, reg25;
- if (!nfloor)
- nfloor = DM9801_NOISE_FLOOR;
- reg16 = phy_read(16);
- reg17 = phy_read(17);
- reg24 = phy_read(24);
- reg25 = phy_read(25);
- switch (HPNA_rev) {
- case 0xb900: /* DM9801 E3 */
- reg16 |= 0x1000;
- reg25 = ((reg24 + nfloor) & 0x00ff) | 0xf000;
- break;
- case 0xb901: /* DM9801 E4 */
- reg25 = ((reg24 + nfloor) & 0x00ff) | 0xc200;
- reg17 = (reg17 & 0xfff0) + nfloor + 3;
- break;
- case 0xb902: /* DM9801 E5 */
- case 0xb903: /* DM9801 E6 */
- default:
- reg16 |= 0x1000;
- reg25 = ((reg24 + nfloor - 3) & 0x00ff) | 0xc200;
- reg17 = (reg17 & 0xfff0) + nfloor;
- }
- phy_write(16, reg16);
- phy_write(17, reg17);
- phy_write(25, reg25);
-}
-
-/*
- Init LongRun DM9802
-*/
-static void
-program_dm9802(void)
-{
- __u16 reg25;
- if (!nfloor)
- nfloor = DM9802_NOISE_FLOOR;
- reg25 = phy_read(25);
- reg25 = (reg25 & 0xff00) + nfloor;
- phy_write(25, reg25);
-}
-
-/* Identify NIC type
-*/
-static void
-identify_nic(void)
-{
- struct board_info *db = &dm9000_info;
- u16 phy_reg3;
- DM9000_iow(DM9000_NCR, NCR_EXT_PHY);
- phy_reg3 = phy_read(3);
- switch (phy_reg3 & 0xfff0) {
- case 0xb900:
- if (phy_read(31) == 0x4404) {
- db->nic_type = HOMERUN_NIC;
- program_dm9801(phy_reg3);
- DM9000_DBG("found homerun NIC\n");
- } else {
- db->nic_type = LONGRUN_NIC;
- DM9000_DBG("found longrun NIC\n");
- program_dm9802();
- }
- break;
- default:
- db->nic_type = FASTETHER_NIC;
- break;
- }
- DM9000_iow(DM9000_NCR, 0);
}
/* General Purpose dm9000 reset routine */
@@ -377,12 +253,12 @@
/* Reset DM9000,
see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */
- /* DEBUG: Make all GPIO pins outputs */
- DM9000_iow(DM9000_GPCR, 0x0F);
+ /* DEBUG: Make all GPIO0 outputs, all others inputs */
+ DM9000_iow(DM9000_GPCR, GPCR_GPIO0_OUT);
/* 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);
+ DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));
do {
DM9000_DBG("resetting the DM9000, 1st reset\n");
@@ -390,7 +266,7 @@
} while (DM9000_ior(DM9000_NCR) & 1);
DM9000_iow(DM9000_NCR, 0);
- DM9000_iow(DM9000_NCR, 3); /* Issue a second reset */
+ DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); /* Issue a second reset */
do {
DM9000_DBG("resetting the DM9000, 2nd reset\n");
@@ -416,7 +292,9 @@
/* RESET device */
dm9000_reset();
- dm9000_probe();
+
+ if (dm9000_probe() < 0)
+ return -1;
/* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */
io_mode = DM9000_ior(DM9000_ISR) >> 6;
@@ -449,21 +327,12 @@
break;
}
- /* NIC Type: FASTETHER, HOMERUN, LONGRUN */
- identify_nic();
-
- /* GPIO0 on pre-activate PHY */
- DM9000_iow(DM9000_GPR, 0x00); /*REG_1F bit0 activate phyxcer */
-
- /* Set PHY */
- set_PHY_mode();
-
- /* Program operating register, only intern phy supported by now */
+ /* Program operating register, only internal phy supported */
DM9000_iow(DM9000_NCR, 0x0);
/* TX Polling clear */
DM9000_iow(DM9000_TCR, 0);
/* Less 3Kb, 200us */
- DM9000_iow(DM9000_BPTR, 0x3f);
+ DM9000_iow(DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US);
/* Flow Control : High/Low Water */
DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));
/* SH FIXME: This looks strange! Flow Control */
@@ -473,10 +342,10 @@
/* clear TX status */
DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
/* Clear interrupt status */
- DM9000_iow(DM9000_ISR, 0x0f);
+ DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);
/* Set Node address */
-#ifndef CONFIG_AT91SAM9261EK
+#if !defined(CONFIG_AT91SAM9261EK)
for (i = 0; i < 6; i++)
((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);
#endif
@@ -498,7 +367,9 @@
printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", bd->bi_enetaddr[0],
bd->bi_enetaddr[1], bd->bi_enetaddr[2], bd->bi_enetaddr[3],
bd->bi_enetaddr[4], bd->bi_enetaddr[5]);
- for (i = 0, oft = 0x10; i < 6; i++, oft++)
+
+ /* fill device MAC address registers */
+ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
DM9000_iow(oft, bd->bi_enetaddr[i]);
for (i = 0, oft = 0x16; i < 8; i++, oft++)
DM9000_iow(oft, 0xff);
diff --git a/drivers/net/dm9000x.h b/drivers/net/dm9000x.h
index f47ff8c..0d123e2 100644
--- a/drivers/net/dm9000x.h
+++ b/drivers/net/dm9000x.h
@@ -66,6 +66,8 @@
#define NCR_FCOL (1<<4)
#define NCR_FDX (1<<3)
#define NCR_LBK (3<<1)
+#define NCR_LBK_INT_MAC (1<<1)
+#define NCR_LBK_INT_PHY (2<<1)
#define NCR_RST (1<<0)
#define NSR_SPEED (1<<7)
@@ -107,13 +109,32 @@
#define RSR_CE (1<<1)
#define RSR_FOE (1<<0)
+#define EPCR_EPOS_PHY (1<<3)
+#define EPCR_EPOS_EE (0<<3)
+#define EPCR_ERPRR (1<<2)
+#define EPCR_ERPRW (1<<1)
+#define EPCR_ERRE (1<<0)
+
#define FCTR_HWOT(ot) (( ot & 0xf ) << 4 )
#define FCTR_LWOT(ot) ( ot & 0xf )
+#define BPTR_BPHW(x) ((x) << 4)
+#define BPTR_JPT_200US (0x07)
+#define BPTR_JPT_600US (0x0f)
+
#define IMR_PAR (1<<7)
#define IMR_ROOM (1<<3)
#define IMR_ROM (1<<2)
#define IMR_PTM (1<<1)
#define IMR_PRM (1<<0)
+#define ISR_ROOS (1<<3)
+#define ISR_ROS (1<<2)
+#define ISR_PTS (1<<1)
+#define ISR_PRS (1<<0)
+
+#define GPCR_GPIO0_OUT (1<<0)
+
+#define GPR_PHY_PWROFF (1<<0)
+
#endif