]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
Xilinx: ARM: Clean-up of ethernet code.
authorAndrei Simion <andreis@xilinx.com>
Thu, 22 Dec 2011 23:04:24 +0000 (15:04 -0800)
committerJohn Linn <john.linn@xilinx.com>
Wed, 18 Jan 2012 00:36:29 +0000 (16:36 -0800)
MAC/PHY driver has been cleaned up and commented thoroughly. Uneeded
code has been removed.

board/xilinx/dfe/xgmac.c

index ea73bda94d7ddc7e8cb52b8d92818b88f924839e..198ee03eed6c4806fe46b7e6ccd3a864add043c0 100644 (file)
@@ -15,6 +15,8 @@ int Xgmac_make_rxbuff_mem(XEmacPss * EmacPssInstancePtr, void *rx_buf_start,
 int Xgmac_next_rx_buf(XEmacPss * EmacPssInstancePtr);
 int Xgmac_phy_mgmt_idle(XEmacPss * EmacPssInstancePtr);
 
+void set_eth_advertise(XEmacPss * EmacPssInstancePtr, int link_speed);
+
 /*************************** Constant Definitions ***************************/
 
 #define EMACPSS_DEVICE_ID   0
@@ -181,31 +183,21 @@ int eth_init(bd_t * bis)
                          XEMACPSS_TXQBASE_OFFSET,
                          EmacPssInstancePtr->TxBdRing.BaseBdAddr);
 
-       /* MAC Setup */
        /*
-        *  Following is the setup for Network Configuration register.
-        *  Bit 0:  Set for 100 Mbps operation.
-        *  Bit 1:  Set for Full Duplex mode.
-        *  Bit 4:  Set to allow Copy all frames.
-        *  Bit 10: Set for Gigabit.
-        *  Bit 17: Set for FCS removal.
-        *  Bits 20-18: Set with value binary 010 to divide pclk by 32
-        *              (pclk up to 80 MHz)
+        * Setup the ethernet.
         */
+       printf("Trying to set up GEM link...\n");
+
+       /*************************** MAC Setup ***************************/
+       tmp = (2 << 18);        /* MDC clock division (32 for up to 80MHz) */
+       tmp |= (1 << 17);       /* set for FCS removal */
+       tmp |= (1 << 10);       /* enable gigabit */
+       tmp |= (1 << 4);        /* copy all frames */
+       tmp |= (1 << 1);        /* enable full duplex */
+
        XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,
-                         XEMACPSS_NWCFG_OFFSET, 0x000A0413);
+                         XEMACPSS_NWCFG_OFFSET, tmp);
 
-       /*
-        * Following is the setup for DMA Configuration register.
-        * Bits 4-0: To set AHB fixed burst length for DMA data operations ->
-        *           Set with binary 00100 to use INCR4 AHB bursts.
-        * Bits 9-8: Receiver packet buffer memory size ->
-        *       Set with binary 11 to Use full configured addressable space (8 Kb)
-        * Bit 10  : Transmitter packet buffer memory size ->
-        *       Set with binary 1 to Use full configured addressable space (4 Kb)
-        * Bits 23-16 : DMA receive buffer size in AHB system memory ->
-        *   Set with binary 00011000 to use 1536 byte (1*max length frame/buffer).
-        */
        XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,
                          XEMACPSS_DMACR_OFFSET, 0x00180704);
 
@@ -213,79 +205,70 @@ int eth_init(bd_t * bis)
        XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,
                          XEMACPSS_IDR_OFFSET, 0xFFFFFFFF);
 
-       /*
-        * Following is the setup for Network Control register.
-        * Bit 2:  Set to enable Receive operation.
-        * Bit 3:  Set to enable Transmitt operation.
-        * Bit 4:  Set to enable MDIO operation.
-        */
+       /* MDIO, Rx and Tx enable */
        tmp =
            XEmacPss_ReadReg(EmacPssInstancePtr->Config.BaseAddress,
                             XEMACPSS_NWCTRL_OFFSET);
-       /*MDIO, Rx and Tx enable */
        tmp |=
            XEMACPSS_NWCTRL_MDEN_MASK | XEMACPSS_NWCTRL_RXEN_MASK |
            XEMACPSS_NWCTRL_TXEN_MASK;
        XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,
                          XEMACPSS_NWCTRL_OFFSET, tmp);
 
-       /* PHY Setup */
-
-#ifdef CONFIG_EP107
-       /* "add delay to RGMII rx interface" */
-       phy_wr(EmacPssInstancePtr, 20, 0xc93);
-#else
-       phy_wr(EmacPssInstancePtr, 22, 2);      /* page 2 */
-
-       /* rx clock transition when data stable */
-       phy_wr(EmacPssInstancePtr, 21, 0x3030);
+       /*************************** PHY Setup ***************************/
 
        phy_wr(EmacPssInstancePtr, 22, 0);      /* page 0 */
-#endif
 
-       /* link speed advertisement for autonegotiation */
+       /* Auto-negotiation advertisement register */
        tmp = phy_rd(EmacPssInstancePtr, 4);
-       tmp |= 0xd80;           /* enable 100Mbps */
-       tmp |= 0x60;            /* enable 10 Mbps */
+       tmp |= (1 << 11);       /* asymmetric pause */
+       tmp |= (1 << 10);       /* MAC pause implemented */
        phy_wr(EmacPssInstancePtr, 4, tmp);
 
-       /* enable gigabit advertisement */
-       tmp = phy_rd(EmacPssInstancePtr, 9);
-       tmp |= 0x0300;
-       phy_wr(EmacPssInstancePtr, 9, tmp);
-
        /* Copper specific control register 1 */
-       phy_wr(EmacPssInstancePtr, 22, 0);
        tmp = phy_rd(EmacPssInstancePtr, 16);
        tmp |= (7 << 12);       /* max number of gigabit attempts */
        tmp |= (1 << 11);       /* enable downshift */
        phy_wr(EmacPssInstancePtr, 16, tmp);
 
-       /* enable autonegotiation, set 100Mbps, full-duplex, restart aneg */
+#ifdef CONFIG_EP107
+       /* "add delay to RGMII rx interface" */
+       phy_wr(EmacPssInstancePtr, 20, 0xc93);
+#else
+       phy_wr(EmacPssInstancePtr, 22, 2);      /* page 2 */
+       tmp = phy_rd(EmacPssInstancePtr, 21);
+       tmp |= (1 << 5);        /* RGMII receive timing transition when data stable */
+       tmp |= (1 << 4);        /* RGMII transmit clock internally delayed */
+       phy_wr(EmacPssInstancePtr, 21, tmp);
+       phy_wr(EmacPssInstancePtr, 22, 0);      /* page 0 */
+#endif
+
+       /* Control register */
        tmp = phy_rd(EmacPssInstancePtr, 0);
-       phy_wr(EmacPssInstancePtr, 0, 0x3300 | (tmp & 0x1F));
+       tmp |= (1 << 12);       /* auto-negotiation enable */
+       tmp |= (1 << 8);        /* enable full duplex */
+       phy_wr(EmacPssInstancePtr, 0, tmp);
 
+       /***** Try to establish a link at the highest speed possible  *****/
+       set_eth_advertise(EmacPssInstancePtr, 1000);
        phy_rst(EmacPssInstancePtr);
 
-       puts("\nWaiting for PHY to complete autonegotiation.");
+       /* Attempt auto-negotiation */
+       puts("Waiting for PHY to complete auto-negotiation...\n");
        tmp = 0; /* delay counter */
        while (!(phy_rd(EmacPssInstancePtr, 1) & (1 << 5))) {
                udelay(10000);
                tmp++;
                if (tmp > 1000) { /* stalled if no link after 10 seconds */
-                       printf("***Error: Auto-negotiation stalled...\n");
+                       puts("***Error: Auto-negotiation stalled...\n");
                        return -1;
                }
        }
 
-       puts("\nPHY claims autonegotiation complete...\n");
-
        /* Check if the link is up */
-       phy_wr(EmacPssInstancePtr, 22, 0);
        tmp = phy_rd(EmacPssInstancePtr, 17);
        if (  ((tmp >> 10) & 1) ) {
                /* Check for an auto-negotiation error */
-               phy_wr(EmacPssInstancePtr, 22, 0);
                tmp = phy_rd(EmacPssInstancePtr, 19);
                if ( (tmp >> 15) & 1 ) {
                        puts("***Error: Auto-negotiation error is present.\n");
@@ -296,8 +279,7 @@ int eth_init(bd_t * bis)
                return -1;
        }
 
-       /* Determine link speed */
-       phy_wr(EmacPssInstancePtr, 22, 0);
+       /********************** Determine link speed **********************/
        tmp = phy_rd(EmacPssInstancePtr, 17);
        if ( ((tmp >> 14) & 3) == 2)            /* 1000Mbps */
                link_speed = 1000;
@@ -306,7 +288,7 @@ int eth_init(bd_t * bis)
        else                                    /* 10Mbps */
                link_speed = 10;
 
-       /* MAC Setup */
+       /*************************** MAC Setup ***************************/
        tmp = XEmacPss_ReadReg(EmacPssInstancePtr->Config.BaseAddress,
                          XEMACPSS_NWCFG_OFFSET);
        if (link_speed == 10)
@@ -320,7 +302,7 @@ int eth_init(bd_t * bis)
        XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,
                          XEMACPSS_NWCFG_OFFSET, tmp);
 
-       /* GEM0_CLK Setup */
+       /************************* GEM0_CLK Setup *************************/
        /* SLCR unlock */
        Out32(0xF8000008, 0xDF0D);
 
@@ -338,7 +320,7 @@ int eth_init(bd_t * bis)
        /* SLCR lock */
        Out32(0xF8000008, 0x767B);
 
-       printf("GEM link speed is %dMbps!\n", link_speed);
+       printf("Link is now at %dMbps!\n", link_speed);
 
        ethstate.initialized = 1;
        return 0;
@@ -608,3 +590,51 @@ int Xgmac_next_rx_buf(XEmacPss * EmacPssInstancePtr)
 
        return 0;
 }
+
+void set_eth_advertise(XEmacPss * EmacPssInstancePtr, int link_speed) {
+
+       int tmp;
+
+       /* MAC setup */
+       tmp = XEmacPss_ReadReg(EmacPssInstancePtr->Config.BaseAddress,
+                         XEMACPSS_NWCFG_OFFSET);
+       if (link_speed == 10)
+               tmp &= ~(1 << 0);       /* enable 10Mbps */
+       else if (link_speed == 100)
+               tmp |= (1 << 0);        /* enable 100Mbps */
+       XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,
+                         XEMACPSS_NWCFG_OFFSET, tmp);
+
+       phy_wr(EmacPssInstancePtr, 22, 0);      /* page 0 */
+
+       /* Auto-negotiation advertisement register */
+       tmp = phy_rd(EmacPssInstancePtr, 4);
+       if (link_speed >= 100) {
+               tmp |= (1 << 8);        /* advertise 100Mbps F */
+               tmp |= (1 << 7);        /* advertise 100Mbps H */
+       } else {
+               tmp &= ~(1 << 8);       /* advertise 100Mbps F */
+               tmp &= ~(1 << 7);       /* advertise 100Mbps H */
+       }
+       if (link_speed >= 10) {
+               tmp |= (1 << 6);        /* advertise 10Mbps F */
+               tmp |= (1 << 5);        /* advertise 10Mbps H */
+       } else {
+               tmp &= ~(1 << 6);       /* advertise 10Mbps F */
+               tmp &= ~(1 << 5);       /* advertise 10Mbps H */
+       }
+       phy_wr(EmacPssInstancePtr, 4, tmp);
+
+       /* 1000BASE-T control register */
+       tmp = phy_rd(EmacPssInstancePtr, 9);
+       if (link_speed == 1000) {
+               tmp |= (1 << 9);        /* advertise 1000Mbps F */
+               tmp |= (1 << 8);        /* advertise 1000Mbps H */
+       } else {
+               tmp &= ~(1 << 9);       /* advertise 1000Mbps F */
+               tmp &= ~(1 << 8);       /* advertise 1000Mbps H */
+       }
+       phy_wr(EmacPssInstancePtr, 9, tmp);
+
+}
+