3 * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 * Designware ethernet IP driver for u-boot
31 #include <linux/err.h>
33 #include "designware.h"
35 static int configure_phy(struct eth_device
*dev
);
37 static void tx_descs_init(struct eth_device
*dev
)
39 struct dw_eth_dev
*priv
= dev
->priv
;
40 struct eth_dma_regs
*dma_p
= priv
->dma_regs_p
;
41 struct dmamacdescr
*desc_table_p
= &priv
->tx_mac_descrtable
[0];
42 char *txbuffs
= &priv
->txbuffs
[0];
43 struct dmamacdescr
*desc_p
;
46 for (idx
= 0; idx
< CONFIG_TX_DESCR_NUM
; idx
++) {
47 desc_p
= &desc_table_p
[idx
];
48 desc_p
->dmamac_addr
= &txbuffs
[idx
* CONFIG_ETH_BUFSIZE
];
49 desc_p
->dmamac_next
= &desc_table_p
[idx
+ 1];
51 #if defined(CONFIG_DW_ALTDESCRIPTOR)
52 desc_p
->txrx_status
&= ~(DESC_TXSTS_TXINT
| DESC_TXSTS_TXLAST
|
53 DESC_TXSTS_TXFIRST
| DESC_TXSTS_TXCRCDIS
| \
54 DESC_TXSTS_TXCHECKINSCTRL
| \
55 DESC_TXSTS_TXRINGEND
| DESC_TXSTS_TXPADDIS
);
57 desc_p
->txrx_status
|= DESC_TXSTS_TXCHAIN
;
58 desc_p
->dmamac_cntl
= 0;
59 desc_p
->txrx_status
&= ~(DESC_TXSTS_MSK
| DESC_TXSTS_OWNBYDMA
);
61 desc_p
->dmamac_cntl
= DESC_TXCTRL_TXCHAIN
;
62 desc_p
->txrx_status
= 0;
66 /* Correcting the last pointer of the chain */
67 desc_p
->dmamac_next
= &desc_table_p
[0];
69 writel((ulong
)&desc_table_p
[0], &dma_p
->txdesclistaddr
);
72 static void rx_descs_init(struct eth_device
*dev
)
74 struct dw_eth_dev
*priv
= dev
->priv
;
75 struct eth_dma_regs
*dma_p
= priv
->dma_regs_p
;
76 struct dmamacdescr
*desc_table_p
= &priv
->rx_mac_descrtable
[0];
77 char *rxbuffs
= &priv
->rxbuffs
[0];
78 struct dmamacdescr
*desc_p
;
81 for (idx
= 0; idx
< CONFIG_RX_DESCR_NUM
; idx
++) {
82 desc_p
= &desc_table_p
[idx
];
83 desc_p
->dmamac_addr
= &rxbuffs
[idx
* CONFIG_ETH_BUFSIZE
];
84 desc_p
->dmamac_next
= &desc_table_p
[idx
+ 1];
87 (MAC_MAX_FRAME_SZ
& DESC_RXCTRL_SIZE1MASK
) | \
90 desc_p
->txrx_status
= DESC_RXSTS_OWNBYDMA
;
93 /* Correcting the last pointer of the chain */
94 desc_p
->dmamac_next
= &desc_table_p
[0];
96 writel((ulong
)&desc_table_p
[0], &dma_p
->rxdesclistaddr
);
99 static void descs_init(struct eth_device
*dev
)
105 static int mac_reset(struct eth_device
*dev
)
107 struct dw_eth_dev
*priv
= dev
->priv
;
108 struct eth_mac_regs
*mac_p
= priv
->mac_regs_p
;
109 struct eth_dma_regs
*dma_p
= priv
->dma_regs_p
;
112 int timeout
= CONFIG_MACRESET_TIMEOUT
;
114 writel(DMAMAC_SRST
, &dma_p
->busmode
);
115 writel(MII_PORTSELECT
, &mac_p
->conf
);
117 start
= get_timer(0);
118 while (get_timer(start
) < timeout
) {
119 if (!(readl(&dma_p
->busmode
) & DMAMAC_SRST
))
122 /* Try again after 10usec */
129 static int dw_write_hwaddr(struct eth_device
*dev
)
131 struct dw_eth_dev
*priv
= dev
->priv
;
132 struct eth_mac_regs
*mac_p
= priv
->mac_regs_p
;
133 u32 macid_lo
, macid_hi
;
134 u8
*mac_id
= &dev
->enetaddr
[0];
136 macid_lo
= mac_id
[0] + (mac_id
[1] << 8) + \
137 (mac_id
[2] << 16) + (mac_id
[3] << 24);
138 macid_hi
= mac_id
[4] + (mac_id
[5] << 8);
140 writel(macid_hi
, &mac_p
->macaddr0hi
);
141 writel(macid_lo
, &mac_p
->macaddr0lo
);
146 static int dw_eth_init(struct eth_device
*dev
, bd_t
*bis
)
148 struct dw_eth_dev
*priv
= dev
->priv
;
149 struct eth_mac_regs
*mac_p
= priv
->mac_regs_p
;
150 struct eth_dma_regs
*dma_p
= priv
->dma_regs_p
;
153 if (priv
->phy_configured
!= 1)
156 /* Reset ethernet hardware */
157 if (mac_reset(dev
) < 0)
160 /* Resore the HW MAC address as it has been lost during MAC reset */
161 dw_write_hwaddr(dev
);
163 writel(FIXEDBURST
| PRIORXTX_41
| BURST_16
,
166 writel(FLUSHTXFIFO
| readl(&dma_p
->opmode
), &dma_p
->opmode
);
167 writel(STOREFORWARD
| TXSECONDFRAME
, &dma_p
->opmode
);
169 conf
= FRAMEBURSTENABLE
| DISABLERXOWN
;
171 if (priv
->speed
!= SPEED_1000M
)
172 conf
|= MII_PORTSELECT
;
174 if ((priv
->interface
!= PHY_INTERFACE_MODE_MII
) &&
175 (priv
->interface
!= PHY_INTERFACE_MODE_GMII
)) {
177 if (priv
->speed
== SPEED_100M
)
181 if (priv
->duplex
== FULL_DUPLEX
)
182 conf
|= FULLDPLXMODE
;
184 writel(conf
, &mac_p
->conf
);
189 * Start/Enable xfer at dma as well as mac level
191 writel(readl(&dma_p
->opmode
) | RXSTART
, &dma_p
->opmode
);
192 writel(readl(&dma_p
->opmode
) | TXSTART
, &dma_p
->opmode
);
194 writel(readl(&mac_p
->conf
) | RXENABLE
| TXENABLE
, &mac_p
->conf
);
199 static int dw_eth_send(struct eth_device
*dev
, void *packet
, int length
)
201 struct dw_eth_dev
*priv
= dev
->priv
;
202 struct eth_dma_regs
*dma_p
= priv
->dma_regs_p
;
203 u32 desc_num
= priv
->tx_currdescnum
;
204 struct dmamacdescr
*desc_p
= &priv
->tx_mac_descrtable
[desc_num
];
206 /* Check if the descriptor is owned by CPU */
207 if (desc_p
->txrx_status
& DESC_TXSTS_OWNBYDMA
) {
208 printf("CPU not owner of tx frame\n");
212 memcpy((void *)desc_p
->dmamac_addr
, packet
, length
);
214 #if defined(CONFIG_DW_ALTDESCRIPTOR)
215 desc_p
->txrx_status
|= DESC_TXSTS_TXFIRST
| DESC_TXSTS_TXLAST
;
216 desc_p
->dmamac_cntl
|= (length
<< DESC_TXCTRL_SIZE1SHFT
) & \
217 DESC_TXCTRL_SIZE1MASK
;
219 desc_p
->txrx_status
&= ~(DESC_TXSTS_MSK
);
220 desc_p
->txrx_status
|= DESC_TXSTS_OWNBYDMA
;
222 desc_p
->dmamac_cntl
|= ((length
<< DESC_TXCTRL_SIZE1SHFT
) & \
223 DESC_TXCTRL_SIZE1MASK
) | DESC_TXCTRL_TXLAST
| \
226 desc_p
->txrx_status
= DESC_TXSTS_OWNBYDMA
;
229 /* Test the wrap-around condition. */
230 if (++desc_num
>= CONFIG_TX_DESCR_NUM
)
233 priv
->tx_currdescnum
= desc_num
;
235 /* Start the transmission */
236 writel(POLL_DATA
, &dma_p
->txpolldemand
);
241 static int dw_eth_recv(struct eth_device
*dev
)
243 struct dw_eth_dev
*priv
= dev
->priv
;
244 u32 desc_num
= priv
->rx_currdescnum
;
245 struct dmamacdescr
*desc_p
= &priv
->rx_mac_descrtable
[desc_num
];
247 u32 status
= desc_p
->txrx_status
;
250 /* Check if the owner is the CPU */
251 if (!(status
& DESC_RXSTS_OWNBYDMA
)) {
253 length
= (status
& DESC_RXSTS_FRMLENMSK
) >> \
254 DESC_RXSTS_FRMLENSHFT
;
256 NetReceive(desc_p
->dmamac_addr
, length
);
259 * Make the current descriptor valid again and go to
262 desc_p
->txrx_status
|= DESC_RXSTS_OWNBYDMA
;
264 /* Test the wrap-around condition. */
265 if (++desc_num
>= CONFIG_RX_DESCR_NUM
)
269 priv
->rx_currdescnum
= desc_num
;
274 static void dw_eth_halt(struct eth_device
*dev
)
276 struct dw_eth_dev
*priv
= dev
->priv
;
279 priv
->tx_currdescnum
= priv
->rx_currdescnum
= 0;
282 static int eth_mdio_read(struct eth_device
*dev
, u8 addr
, u8 reg
, u16
*val
)
284 struct dw_eth_dev
*priv
= dev
->priv
;
285 struct eth_mac_regs
*mac_p
= priv
->mac_regs_p
;
288 int timeout
= CONFIG_MDIO_TIMEOUT
;
290 miiaddr
= ((addr
<< MIIADDRSHIFT
) & MII_ADDRMSK
) | \
291 ((reg
<< MIIREGSHIFT
) & MII_REGMSK
);
293 writel(miiaddr
| MII_CLKRANGE_150_250M
| MII_BUSY
, &mac_p
->miiaddr
);
295 start
= get_timer(0);
296 while (get_timer(start
) < timeout
) {
297 if (!(readl(&mac_p
->miiaddr
) & MII_BUSY
)) {
298 *val
= readl(&mac_p
->miidata
);
302 /* Try again after 10usec */
309 static int eth_mdio_write(struct eth_device
*dev
, u8 addr
, u8 reg
, u16 val
)
311 struct dw_eth_dev
*priv
= dev
->priv
;
312 struct eth_mac_regs
*mac_p
= priv
->mac_regs_p
;
315 int ret
= -1, timeout
= CONFIG_MDIO_TIMEOUT
;
318 writel(val
, &mac_p
->miidata
);
319 miiaddr
= ((addr
<< MIIADDRSHIFT
) & MII_ADDRMSK
) | \
320 ((reg
<< MIIREGSHIFT
) & MII_REGMSK
) | MII_WRITE
;
322 writel(miiaddr
| MII_CLKRANGE_150_250M
| MII_BUSY
, &mac_p
->miiaddr
);
324 start
= get_timer(0);
325 while (get_timer(start
) < timeout
) {
326 if (!(readl(&mac_p
->miiaddr
) & MII_BUSY
)) {
331 /* Try again after 10usec */
335 /* Needed as a fix for ST-Phy */
336 eth_mdio_read(dev
, addr
, reg
, &value
);
341 #if defined(CONFIG_DW_SEARCH_PHY)
342 static int find_phy(struct eth_device
*dev
)
348 eth_mdio_read(dev
, phy_addr
, MII_BMCR
, &ctrl
);
349 oldctrl
= ctrl
& BMCR_ANENABLE
;
351 ctrl
^= BMCR_ANENABLE
;
352 eth_mdio_write(dev
, phy_addr
, MII_BMCR
, ctrl
);
353 eth_mdio_read(dev
, phy_addr
, MII_BMCR
, &ctrl
);
354 ctrl
&= BMCR_ANENABLE
;
356 if (ctrl
== oldctrl
) {
359 ctrl
^= BMCR_ANENABLE
;
360 eth_mdio_write(dev
, phy_addr
, MII_BMCR
, ctrl
);
364 } while (phy_addr
< 32);
370 static int dw_reset_phy(struct eth_device
*dev
)
372 struct dw_eth_dev
*priv
= dev
->priv
;
375 int timeout
= CONFIG_PHYRESET_TIMEOUT
;
376 u32 phy_addr
= priv
->address
;
378 eth_mdio_write(dev
, phy_addr
, MII_BMCR
, BMCR_RESET
);
380 start
= get_timer(0);
381 while (get_timer(start
) < timeout
) {
382 eth_mdio_read(dev
, phy_addr
, MII_BMCR
, &ctrl
);
383 if (!(ctrl
& BMCR_RESET
))
386 /* Try again after 10usec */
390 if (get_timer(start
) >= CONFIG_PHYRESET_TIMEOUT
)
393 #ifdef CONFIG_PHY_RESET_DELAY
394 udelay(CONFIG_PHY_RESET_DELAY
);
399 static int configure_phy(struct eth_device
*dev
)
401 struct dw_eth_dev
*priv
= dev
->priv
;
404 #if defined(CONFIG_DW_AUTONEG)
413 #if defined(CONFIG_DW_SEARCH_PHY)
414 phy_addr
= find_phy(dev
);
416 priv
->address
= phy_addr
;
420 phy_addr
= priv
->address
;
422 if (dw_reset_phy(dev
) < 0)
425 #if defined(CONFIG_DW_AUTONEG)
426 /* Set Auto-Neg Advertisement capabilities to 10/100 half/full */
427 eth_mdio_write(dev
, phy_addr
, MII_ADVERTISE
, 0x1E1);
429 bmcr
= BMCR_ANENABLE
| BMCR_ANRESTART
;
431 bmcr
= BMCR_SPEED100
| BMCR_FULLDPLX
;
433 #if defined(CONFIG_DW_SPEED10M)
434 bmcr
&= ~BMCR_SPEED100
;
436 #if defined(CONFIG_DW_DUPLEXHALF)
437 bmcr
&= ~BMCR_FULLDPLX
;
440 if (eth_mdio_write(dev
, phy_addr
, MII_BMCR
, bmcr
) < 0)
443 /* Read the phy status register and populate priv structure */
444 #if defined(CONFIG_DW_AUTONEG)
445 timeout
= CONFIG_AUTONEG_TIMEOUT
;
446 start
= get_timer(0);
448 while (get_timer(start
) < timeout
) {
449 eth_mdio_read(dev
, phy_addr
, MII_BMSR
, &bmsr
);
450 if (bmsr
& BMSR_ANEGCOMPLETE
)
453 /* Try again after 10usec */
457 eth_mdio_read(dev
, phy_addr
, MII_LPA
, &anlpar
);
458 eth_mdio_read(dev
, phy_addr
, MII_STAT1000
, &btsr
);
460 if (bmsr
& BMSR_ANEGCOMPLETE
) {
461 if (btsr
& PHY_1000BTSR_1000FD
) {
462 priv
->speed
= SPEED_1000M
;
463 bmcr
|= BMCR_SPEED1000
;
464 priv
->duplex
= FULL_DUPLEX
;
465 bmcr
|= BMCR_FULLDPLX
;
466 } else if (btsr
& PHY_1000BTSR_1000HD
) {
467 priv
->speed
= SPEED_1000M
;
468 bmcr
|= BMCR_SPEED1000
;
469 priv
->duplex
= HALF_DUPLEX
;
470 bmcr
&= ~BMCR_FULLDPLX
;
471 } else if (anlpar
& LPA_100FULL
) {
472 priv
->speed
= SPEED_100M
;
473 bmcr
|= BMCR_SPEED100
;
474 priv
->duplex
= FULL_DUPLEX
;
475 bmcr
|= BMCR_FULLDPLX
;
476 } else if (anlpar
& LPA_100HALF
) {
477 priv
->speed
= SPEED_100M
;
478 bmcr
|= BMCR_SPEED100
;
479 priv
->duplex
= HALF_DUPLEX
;
480 bmcr
&= ~BMCR_FULLDPLX
;
481 } else if (anlpar
& LPA_10FULL
) {
482 priv
->speed
= SPEED_10M
;
483 bmcr
&= ~BMCR_SPEED100
;
484 priv
->duplex
= FULL_DUPLEX
;
485 bmcr
|= BMCR_FULLDPLX
;
487 priv
->speed
= SPEED_10M
;
488 bmcr
&= ~BMCR_SPEED100
;
489 priv
->duplex
= HALF_DUPLEX
;
490 bmcr
&= ~BMCR_FULLDPLX
;
492 if (eth_mdio_write(dev
, phy_addr
, MII_BMCR
, bmcr
) < 0)
497 if (eth_mdio_read(dev
, phy_addr
, MII_BMCR
, &ctrl
) < 0)
500 if (ctrl
& BMCR_FULLDPLX
)
501 priv
->duplex
= FULL_DUPLEX
;
503 priv
->duplex
= HALF_DUPLEX
;
505 if (ctrl
& BMCR_SPEED1000
)
506 priv
->speed
= SPEED_1000M
;
507 else if (ctrl
& BMCR_SPEED100
)
508 priv
->speed
= SPEED_100M
;
510 priv
->speed
= SPEED_10M
;
512 priv
->phy_configured
= 1;
517 #if defined(CONFIG_MII)
518 static int dw_mii_read(const char *devname
, u8 addr
, u8 reg
, u16
*val
)
520 struct eth_device
*dev
;
522 dev
= eth_get_dev_by_name(devname
);
524 eth_mdio_read(dev
, addr
, reg
, val
);
529 static int dw_mii_write(const char *devname
, u8 addr
, u8 reg
, u16 val
)
531 struct eth_device
*dev
;
533 dev
= eth_get_dev_by_name(devname
);
535 eth_mdio_write(dev
, addr
, reg
, val
);
541 int designware_initialize(u32 id
, ulong base_addr
, u32 phy_addr
, u32 interface
)
543 struct eth_device
*dev
;
544 struct dw_eth_dev
*priv
;
546 dev
= (struct eth_device
*) malloc(sizeof(struct eth_device
));
551 * Since the priv structure contains the descriptors which need a strict
552 * buswidth alignment, memalign is used to allocate memory
554 priv
= (struct dw_eth_dev
*) memalign(16, sizeof(struct dw_eth_dev
));
560 memset(dev
, 0, sizeof(struct eth_device
));
561 memset(priv
, 0, sizeof(struct dw_eth_dev
));
563 sprintf(dev
->name
, "mii%d", id
);
564 dev
->iobase
= (int)base_addr
;
567 eth_getenv_enetaddr_by_index("eth", id
, &dev
->enetaddr
[0]);
570 priv
->mac_regs_p
= (struct eth_mac_regs
*)base_addr
;
571 priv
->dma_regs_p
= (struct eth_dma_regs
*)(base_addr
+
573 priv
->address
= phy_addr
;
574 priv
->phy_configured
= 0;
575 priv
->interface
= interface
;
577 if (mac_reset(dev
) < 0)
582 dev
->init
= dw_eth_init
;
583 dev
->send
= dw_eth_send
;
584 dev
->recv
= dw_eth_recv
;
585 dev
->halt
= dw_eth_halt
;
586 dev
->write_hwaddr
= dw_write_hwaddr
;
590 #if defined(CONFIG_MII)
591 miiphy_register(dev
->name
, dw_mii_read
, dw_mii_write
);