summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSriram <srk@ti.com>2009-06-18 01:53:03 +0530
committerJustin Waters <justin.waters@timesys.com>2009-10-21 16:46:34 -0400
commita74b88e542841397d176621d157da3d576a24c2f (patch)
tree9ddf0456ffcaa877db9332344d4ab4786ee7bce2
parentdce76597be2aa1fc3148d2294d519527a613a786 (diff)
EMAC driver: Implement GPIO driven PHY reset.
-rw-r--r--board/omap3/omap3517evm/omap3517evm.c33
-rw-r--r--board/omap3/omap3517evm/omap3517evm.h6
-rw-r--r--drivers/net/ticpgmac.c100
-rw-r--r--include/asm-arm/arch-omap3/mux.h1
-rw-r--r--include/asm-arm/arch-omap3/ticpgmac.h17
5 files changed, 147 insertions, 10 deletions
diff --git a/board/omap3/omap3517evm/omap3517evm.c b/board/omap3/omap3517evm/omap3517evm.c
index bf304e33e3..0f8dc744ae 100644
--- a/board/omap3/omap3517evm/omap3517evm.c
+++ b/board/omap3/omap3517evm/omap3517evm.c
@@ -65,7 +65,8 @@ int misc_init_r(void)
#endif
#if defined(CONFIG_CMD_NET)
- //setup_net_chip();
+ /* Drive the PHY reset thru GPIO 30 */
+ setup_net_chip();
if (!eth_hw_init()) {
printf("error:Ethernet init failed\n");
}
@@ -95,6 +96,7 @@ void set_muxconf_regs(void)
*****************************************************************************/
static void setup_net_chip(void)
{
+ #if 0
gpio_t *gpio3_base = (gpio_t *)OMAP34XX_GPIO3_BASE;
gpmc_csx_t *gpmc_cs6_base = (gpmc_csx_t *)GPMC_CONFIG_CS6_BASE;
ctrl_t *ctrl_base = (ctrl_t *)OMAP34XX_CTRL_BASE;
@@ -125,4 +127,33 @@ static void setup_net_chip(void)
writel(GPIO0, &gpio3_base->cleardataout);
udelay(1);
writel(GPIO0, &gpio3_base->setdataout);
+ #else
+ volatile unsigned int ctr;
+
+ gpio_t *gpio1_base = (gpio_t *)OMAP34XX_GPIO1_BASE;
+ ctrl_t *ctrl_base = (ctrl_t *)OMAP34XX_CTRL_BASE;
+
+
+ /* Make GPIO 30 as output pin */
+ writel(readl(&gpio1_base->oe) & ~(GPIO30), &gpio1_base->oe);
+
+ /* Now send a pulse on the GPIO pin */
+ printf("Driving GPIO 30 low \n");
+ writel(GPIO30, &gpio1_base->cleardataout);
+ ctr = 0;
+ do{
+ udelay(1000);
+ ctr++;
+ }while (ctr <300);
+
+ printf("Driving GPIO 30 high \n");
+ writel(GPIO30, &gpio1_base->setdataout);
+ ctr =0;
+ /* allow the PHY to stabilize and settle down */
+ do{
+ udelay(1000);
+ ctr++;
+ }while (ctr <300);
+
+ #endif
}
diff --git a/board/omap3/omap3517evm/omap3517evm.h b/board/omap3/omap3517evm/omap3517evm.h
index 65276b8b9b..074d4ffd45 100644
--- a/board/omap3/omap3517evm/omap3517evm.h
+++ b/board/omap3/omap3517evm/omap3517evm.h
@@ -287,6 +287,8 @@ static void setup_net_chip(void);
MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)) /*SYS_32K*/\
MUX_VAL(CP(SYS_CLKREQ), (IEN | PTD | DIS | M0)) /*SYS_CLKREQ*/\
MUX_VAL(CP(SYS_NIRQ), (IEN | PTU | EN | M0)) /*SYS_nIRQ*/\
+ MUX_VAL(CP(SYS_NRESWARM), (IDIS | PTU | DIS | M4)) /*SYS_nRESWARM */\
+ /* GPIO 30 */\
MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M4)) /*GPIO_2*/\
/* - PEN_IRQ */\
MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M4)) /*GPIO_3 */\
@@ -337,8 +339,8 @@ static void setup_net_chip(void);
MUX_VAL(CP(CCDC_DATA5), (IEN | PTD | EN | M0)) /*ccdc_data5*/\
MUX_VAL(CP(CCDC_DATA6), (IEN | PTD | EN | M0)) /*ccdc_data6*/\
MUX_VAL(CP(CCDC_DATA7), (IEN | PTD | EN | M0)) /*ccdc_data7*/\
- MUX_VAL(CP(RMII_MDIO_DATA), (PTD | M0)) /*rmii_mdio_data*/\
- MUX_VAL(CP(RMII_MDIO_CLK), (PTD | M0)) /*rmii_mdio_clk*/\
+ MUX_VAL(CP(RMII_MDIO_DATA), (IEN | M0)) /*rmii_mdio_data*/\
+ MUX_VAL(CP(RMII_MDIO_CLK), (M0)) /*rmii_mdio_clk*/\
MUX_VAL(CP(RMII_RXD0) , (IEN | PTD | M0)) /*rmii_rxd0*/\
MUX_VAL(CP(RMII_RXD1), (IEN | PTD | M0)) /*rmii_rxd1*/\
MUX_VAL(CP(RMII_CRS_DV), (IEN | PTD | M0)) /*rmii_crs_dv*/\
diff --git a/drivers/net/ticpgmac.c b/drivers/net/ticpgmac.c
index 350fb9bed7..eeff23b1f1 100644
--- a/drivers/net/ticpgmac.c
+++ b/drivers/net/ticpgmac.c
@@ -268,26 +268,44 @@ STATIC int gen_is_phy_connected(int phy_addr)
STATIC int gen_get_link_status(int phy_addr)
{
- u_int16_t tmp;
+ u_int16_t tmp,lpa_val,val;
if (cpgmac_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)
&& (tmp & 0x04)) {
+ //printf("Phy %d MII_Status Reg=0x%x \n",phy_addr,tmp);
+ //printf("MACCTRL 0x%x\n",adap_emac->MACCONTROL);
+ cpgmac_eth_phy_read(phy_addr,MII_CTRL_REG,&val);
+ //printf("Phy CTRL=0x%x \n",val);
+
+ cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG,&val);
+ // printf("Phy ANEG ADV=0x%x \n",val);
+
+ cpgmac_eth_phy_read(phy_addr,ANEG_LPA_REG,&lpa_val);
+ //printf("Phy ANEG LPA=0x%x \n",lpa_val);
+
/* Speed doesn't matter, there is no setting for it in EMAC. */
- if (tmp & GEN_PHY_STATUS_FD_MASK) {
+ //if (tmp & GEN_PHY_STATUS_FD_MASK) {
+ if (lpa_val & (GEN_PHY_ANEG_100DUP | GEN_PHY_ANEG_10DUP ) ) {
/* set EMAC for Full Duplex */
+ // printf("Set MACCTRL for full duplex \n");
adap_emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE |
EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
} else {
/*set EMAC for Half Duplex */
adap_emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
+ // printf("Set MACCTRL for HALF duplex \n");
}
#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
- if(tmp & GEN_PHY_STATUS_SPEED100_MASK) {
+ //if(tmp & GEN_PHY_STATUS_SPEED100_MASK) {
+ if (lpa_val & (GEN_PHY_ANEG_100DUP | GEN_PHY_ANEG_100TX ) ) {
adap_emac->MACCONTROL |= EMAC_MACCONTROL_RMIISPEED_100;
+ // printf("Set maccontrol for RMII 100 - 0x%x\n",adap_emac->MACCONTROL);
+
} else {
adap_emac->MACCONTROL &= ~EMAC_MACCONTROL_RMIISPEED_100;
+ printf("Set maccontrol for RMII 10 - 0x%x\n",adap_emac->MACCONTROL);
}
#endif
@@ -299,20 +317,62 @@ STATIC int gen_get_link_status(int phy_addr)
STATIC int gen_auto_negotiate(int phy_addr)
{
- u_int16_t tmp;
+ u_int16_t tmp,val;
+ unsigned long cntr =0;
if (!cpgmac_eth_phy_read(phy_addr, PHY_BMCR, &tmp))
return(0);
+ printf("read BMCR 0x%x\n",tmp);
+
+ val = tmp | GEN_PHY_CTRL_DUP | GEN_PHY_CTRL_ENA_ANEG | GEN_PHY_CTRL_SPD_SEL ;
+ cpgmac_eth_phy_write(phy_addr, PHY_BMCR, val);
+ cpgmac_eth_phy_read(phy_addr, PHY_BMCR, &val);
+ printf("BMCR set to 0x%X \n",val);
+
+ cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG, &val);
+ printf("read ANEG 0x%x \n",val);
+ val |= ( GEN_PHY_ANEG_100DUP | GEN_PHY_ANEG_100TX | GEN_PHY_ANEG_10DUP | GEN_PHY_ANEG_10TX );
+ printf("writing back 0x%x \n",val);
+ cpgmac_eth_phy_write(phy_addr, ANEG_ADVERTISE_REG, val);
+ cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG, &val);
+ printf("ANEG ADVT set to 0x%x \n", val);
+
+
+ printf("Restart Auto-negn \n");
+ cpgmac_eth_phy_read(phy_addr, PHY_BMCR, &tmp);
+
/* Restart Auto_negotiation */
- tmp |= PHY_BMCR_AUTON;
+ tmp |= PHY_BMCR_RST_NEG;
+ printf("writing bk 0x%x to BMCR for anegn \n",tmp);
cpgmac_eth_phy_write(phy_addr, PHY_BMCR, tmp);
/*check AutoNegotiate complete */
- udelay (10000);
+ //udelay (10000);
+ do{
+ udelay(40000);
+ cntr++;
+ }while(cntr < 150 );
+
if (!cpgmac_eth_phy_read(phy_addr, PHY_BMSR, &tmp))
return(0);
+ printf("BMSR after negn 0x%X\n",tmp);
+ cpgmac_eth_phy_read(phy_addr,MII_CTRL_REG,&val);
+ printf("Phy CTRL=0x%x \n",val);
+
+ cpgmac_eth_phy_read(phy_addr,ANEG_ADVERTISE_REG,&val);
+ printf("Phy ANEG ADV=0x%x \n",val);
+
+ cpgmac_eth_phy_read(phy_addr,ANEG_LPA_REG,&val);
+ printf("Phy ANEG LPA=0x%x \n",val);
+
+ cpgmac_eth_phy_read(phy_addr,ANEG_EXP_REG,&val);
+ printf("Phy ANEG eXP=0x%x \n",val);
+
+ cpgmac_eth_phy_read(phy_addr,SPL_VEND_REG,&val);
+ printf("Phy SPL VEND =0x%x \n",val);
+
if (!(tmp & PHY_BMSR_AUTN_COMP))
return(0);
@@ -324,16 +384,20 @@ STATIC int gen_auto_negotiate(int phy_addr)
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
STATIC int cpgmac_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
{
+ printf("MII Phy read \n");
return(cpgmac_eth_phy_read(addr, reg, value) ? 0 : 1);
}
STATIC int cpgmac_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value)
{
+
+ printf("MII Phy write \n");
return(cpgmac_eth_phy_write(addr, reg, value) ? 0 : 1);
}
int cpgmac_eth_miiphy_initialize(bd_t *bis)
{
+ printf("MIIPHY initialize \n");
miiphy_register(phy.name, cpgmac_mii_phy_read, cpgmac_mii_phy_write);
return(1);
@@ -399,6 +463,28 @@ STATIC int cpgmac_eth_hw_init(void)
printf("Ethernet PHY: %s\n", phy.name);
+ /* Override HW configuration value that were latched */
+ cpgmac_eth_phy_read(active_phy_addr, SPL_VEND_REG, &tmp);
+ printf("read HW config for PHY 0x%x\n",tmp);
+// tmp |= (1 << 14) | ( 7 << 5) ;
+ tmp = 0x60e0;
+ printf("Program HW config as 0x%x \n",tmp);
+ cpgmac_eth_phy_write(active_phy_addr,SPL_VEND_REG,tmp);
+
+ /* Soft reset the PHY */
+ cpgmac_eth_phy_write(active_phy_addr, PHY_BMCR, (1 << 15));
+
+ active_phy_addr = 0;
+
+ do
+ {
+ cpgmac_eth_phy_read(active_phy_addr, PHY_BMCR , &tmp);
+
+ }while (tmp & (1 << 15));
+
+
+
+
return(1);
}
@@ -505,7 +591,7 @@ STATIC int cpgmac_eth_open(void)
clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);
- if (!phy.get_link_status(active_phy_addr))
+ if (!phy.auto_negotiate(active_phy_addr))
return(0);
/* Start receive process */
diff --git a/include/asm-arm/arch-omap3/mux.h b/include/asm-arm/arch-omap3/mux.h
index d94eb2d231..3e4a2ee742 100644
--- a/include/asm-arm/arch-omap3/mux.h
+++ b/include/asm-arm/arch-omap3/mux.h
@@ -284,6 +284,7 @@
#define CONTROL_PADCONF_SYS_32K 0x0A04
#define CONTROL_PADCONF_SYS_CLKREQ 0x0A06
#define CONTROL_PADCONF_SYS_NIRQ 0x01E0
+#define CONTROL_PADCONF_SYS_NRESWARM 0x0A08
#define CONTROL_PADCONF_SYS_BOOT0 0x0A0A
#define CONTROL_PADCONF_SYS_BOOT1 0x0A0C
#define CONTROL_PADCONF_SYS_BOOT2 0x0A0E
diff --git a/include/asm-arm/arch-omap3/ticpgmac.h b/include/asm-arm/arch-omap3/ticpgmac.h
index 10ec187224..2a7c886e04 100644
--- a/include/asm-arm/arch-omap3/ticpgmac.h
+++ b/include/asm-arm/arch-omap3/ticpgmac.h
@@ -81,7 +81,12 @@
#define EMAC_TEARDOWN_VALUE 0xfffffffc
/* MII Status Register */
+#define MII_CTRL_REG 0
#define MII_STATUS_REG 1
+#define ANEG_ADVERTISE_REG 4
+#define ANEG_LPA_REG 5
+#define ANEG_EXP_REG 6
+#define SPL_VEND_REG 18
/* Number of statistics registers */
#define EMAC_NUM_STATS 36
@@ -339,4 +344,16 @@ typedef struct
#define GEN_PHY_STATUS_SPEED100_MASK ((1 << 13) | (1 << 14))
#define GEN_PHY_STATUS_FD_MASK ((1 << 11) | (1 << 13))
+#define GEN_PHY_ANEG_100DUP (1 << 8)
+#define GEN_PHY_ANEG_100TX (1 << 7)
+#define GEN_PHY_ANEG_10DUP (1 << 6)
+#define GEN_PHY_ANEG_10TX (1 << 5)
+
+#define GEN_PHY_CTRL_RST_ANEG (1 << 9)
+#define GEN_PHY_CTRL_DUP (1 << 8)
+#define GEN_PHY_CTRL_ENA_ANEG (1 << 12)
+#define GEN_PHY_CTRL_SPD_SEL (1 << 13)
+
+
+
#endif /* _TI_CPGMAC_H_ */