2 * Copyright (C) 2009 BuS Elektronik GmbH & Co. KG
3 * Jens Scharsig (esw@bus-elektronik.de)
6 * Author : Hamid Ikdoumi (Atmel)
8 * See file CREDITS for list of people who contributed to this
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 #ifndef CONFIG_AT91_LEGACY
30 #include <asm/arch/hardware.h>
31 #include <asm/arch/at91_emac.h>
32 #include <asm/arch/at91_pmc.h>
33 #include <asm/arch/at91_pio.h>
35 /* remove next 5 lines, if all RM9200 boards convert to at91 arch */
36 #include <asm/arch-at91/at91rm9200.h>
37 #include <asm/arch-at91/hardware.h>
38 #include <asm/arch-at91/at91_emac.h>
39 #include <asm/arch-at91/at91_pmc.h>
40 #include <asm/arch-at91/at91_pio.h>
46 #include <linux/mii.h>
51 #if (CONFIG_SYS_RX_ETH_BUFFER > 1024)
52 #error AT91 EMAC supports max 1024 RX buffers. \
53 Please decrease the CONFIG_SYS_RX_ETH_BUFFER value
56 #ifndef CONFIG_DRIVER_AT91EMAC_PHYADDR
57 #define CONFIG_DRIVER_AT91EMAC_PHYADDR 0
60 /* MDIO clock must not exceed 2.5 MHz, so enable MCK divider */
61 #if (AT91C_MASTER_CLOCK > 80000000)
62 #define HCLK_DIV AT91_EMAC_CFG_MCLK_64
63 #elif (AT91C_MASTER_CLOCK > 40000000)
64 #define HCLK_DIV AT91_EMAC_CFG_MCLK_32
65 #elif (AT91C_MASTER_CLOCK > 20000000)
66 #define HCLK_DIV AT91_EMAC_CFG_MCLK_16
68 #define HCLK_DIV AT91_EMAC_CFG_MCLK_8
72 #define DEBUG_AT91EMAC(...) printf(__VA_ARGS__);
74 #define DEBUG_AT91EMAC(...)
78 #define DEBUG_AT91PHY(...) printf(__VA_ARGS__);
80 #define DEBUG_AT91PHY(...)
83 #ifndef CONFIG_DRIVER_AT91EMAC_QUIET
84 #define VERBOSEP(...) printf(__VA_ARGS__);
89 #define RBF_ADDR 0xfffffffc
90 #define RBF_OWNER (1<<0)
91 #define RBF_WRAP (1<<1)
92 #define RBF_BROADCAST (1<<31)
93 #define RBF_MULTICAST (1<<30)
94 #define RBF_UNICAST (1<<29)
95 #define RBF_EXTERNAL (1<<28)
96 #define RBF_UNKOWN (1<<27)
97 #define RBF_SIZE 0x07ff
98 #define RBF_LOCAL4 (1<<26)
99 #define RBF_LOCAL3 (1<<25)
100 #define RBF_LOCAL2 (1<<24)
101 #define RBF_LOCAL1 (1<<23)
103 #define RBF_FRAMEMAX CONFIG_SYS_RX_ETH_BUFFER
104 #define RBF_FRAMELEN 0x600
107 unsigned long addr
, size
;
111 rbf_t rbfdt
[RBF_FRAMEMAX
];
112 unsigned long rbindex
;
115 void at91emac_EnableMDIO(at91_emac_t
*at91mac
)
117 /* Mac CTRL reg set for MDIO enable */
118 writel(readl(&at91mac
->ctl
) | AT91_EMAC_CTL_MPE
, &at91mac
->ctl
);
121 void at91emac_DisableMDIO(at91_emac_t
*at91mac
)
123 /* Mac CTRL reg set for MDIO disable */
124 writel(readl(&at91mac
->ctl
) & ~AT91_EMAC_CTL_MPE
, &at91mac
->ctl
);
127 int at91emac_read(at91_emac_t
*at91mac
, unsigned char addr
,
128 unsigned char reg
, unsigned short *value
)
130 unsigned long netstat
;
131 at91emac_EnableMDIO(at91mac
);
133 writel(AT91_EMAC_MAN_HIGH
| AT91_EMAC_MAN_RW_R
|
134 AT91_EMAC_MAN_REGA(reg
) | AT91_EMAC_MAN_CODE_802_3
|
135 AT91_EMAC_MAN_PHYA(addr
),
139 netstat
= readl(&at91mac
->sr
);
140 DEBUG_AT91PHY("poll SR %08lx\n", netstat
);
141 } while (!(netstat
& AT91_EMAC_SR_IDLE
));
143 *value
= readl(&at91mac
->man
) & AT91_EMAC_MAN_DATA_MASK
;
145 at91emac_DisableMDIO(at91mac
);
147 DEBUG_AT91PHY("AT91PHY read %x REG(%d)=%x\n", at91mac
, reg
, *value
)
152 int at91emac_write(at91_emac_t
*at91mac
, unsigned char addr
,
153 unsigned char reg
, unsigned short value
)
155 unsigned long netstat
;
156 DEBUG_AT91PHY("AT91PHY write %x REG(%d)=%x\n", at91mac
, reg
, &value
)
158 at91emac_EnableMDIO(at91mac
);
160 writel(AT91_EMAC_MAN_HIGH
| AT91_EMAC_MAN_RW_W
|
161 AT91_EMAC_MAN_REGA(reg
) | AT91_EMAC_MAN_CODE_802_3
|
162 AT91_EMAC_MAN_PHYA(addr
) | (value
& AT91_EMAC_MAN_DATA_MASK
),
166 netstat
= readl(&at91mac
->sr
);
167 DEBUG_AT91PHY("poll SR %08lx\n", netstat
);
168 } while (!(netstat
& AT91_EMAC_SR_IDLE
));
170 at91emac_DisableMDIO(at91mac
);
175 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
177 at91_emac_t
*get_emacbase_by_name(const char *devname
)
179 struct eth_device
*netdev
;
181 netdev
= eth_get_dev_by_name(devname
);
182 return (at91_emac_t
*) netdev
->iobase
;
185 int at91emac_mii_read(const char *devname
, unsigned char addr
,
186 unsigned char reg
, unsigned short *value
)
190 emac
= get_emacbase_by_name(devname
);
191 at91emac_read(emac
, addr
, reg
, value
);
196 int at91emac_mii_write(const char *devname
, unsigned char addr
,
197 unsigned char reg
, unsigned short value
)
201 emac
= get_emacbase_by_name(devname
);
202 at91emac_write(emac
, addr
, reg
, value
);
208 static int at91emac_phy_reset(struct eth_device
*netdev
)
214 emac
= (at91_emac_t
*) netdev
->iobase
;
216 adv
= ADVERTISE_CSMA
| ADVERTISE_ALL
;
217 at91emac_write(emac
, CONFIG_DRIVER_AT91EMAC_PHYADDR
,
219 VERBOSEP("%s: Starting autonegotiation...\n", netdev
->name
);
220 at91emac_write(emac
, CONFIG_DRIVER_AT91EMAC_PHYADDR
, MII_BMCR
,
221 (BMCR_ANENABLE
| BMCR_ANRESTART
));
223 for (i
= 0; i
< 30000; i
++) {
224 at91emac_read(emac
, CONFIG_DRIVER_AT91EMAC_PHYADDR
,
226 if (status
& BMSR_ANEGCOMPLETE
)
231 if (status
& BMSR_ANEGCOMPLETE
) {
232 VERBOSEP("%s: Autonegotiation complete\n", netdev
->name
);
234 printf("%s: Autonegotiation timed out (status=0x%04x)\n",
235 netdev
->name
, status
);
241 static int at91emac_phy_init(struct eth_device
*netdev
)
243 u16 phy_id
, status
, adv
, lpa
;
244 int media
, speed
, duplex
;
248 emac
= (at91_emac_t
*) netdev
->iobase
;
250 /* Check if the PHY is up to snuff... */
251 at91emac_read(emac
, CONFIG_DRIVER_AT91EMAC_PHYADDR
,
252 MII_PHYSID1
, &phy_id
);
253 if (phy_id
== 0xffff) {
254 printf("%s: No PHY present\n", netdev
->name
);
258 at91emac_read(emac
, CONFIG_DRIVER_AT91EMAC_PHYADDR
,
261 if (!(status
& BMSR_LSTATUS
)) {
262 /* Try to re-negotiate if we don't have link already. */
263 if (at91emac_phy_reset(netdev
))
266 for (i
= 0; i
< 100000 / 100; i
++) {
267 at91emac_read(emac
, CONFIG_DRIVER_AT91EMAC_PHYADDR
,
269 if (status
& BMSR_LSTATUS
)
274 if (!(status
& BMSR_LSTATUS
)) {
275 VERBOSEP("%s: link down\n", netdev
->name
);
278 at91emac_read(emac
, CONFIG_DRIVER_AT91EMAC_PHYADDR
,
279 MII_ADVERTISE
, &adv
);
280 at91emac_read(emac
, CONFIG_DRIVER_AT91EMAC_PHYADDR
,
282 media
= mii_nway_result(lpa
& adv
);
283 speed
= (media
& (ADVERTISE_100FULL
| ADVERTISE_100HALF
)
285 duplex
= (media
& ADVERTISE_FULL
) ? 1 : 0;
286 VERBOSEP("%s: link up, %sMbps %s-duplex\n",
288 speed
? "100" : "10",
289 duplex
? "full" : "half");
294 int at91emac_UpdateLinkSpeed(at91_emac_t
*emac
)
296 unsigned short stat1
;
298 at91emac_read(emac
, CONFIG_DRIVER_AT91EMAC_PHYADDR
, MII_BMSR
, &stat1
);
300 if (!(stat1
& BMSR_LSTATUS
)) /* link status up? */
303 if (stat1
& BMSR_100FULL
) {
304 /*set Emac for 100BaseTX and Full Duplex */
305 writel(readl(&emac
->cfg
) |
306 AT91_EMAC_CFG_SPD
| AT91_EMAC_CFG_FD
,
311 if (stat1
& BMSR_10FULL
) {
312 /*set MII for 10BaseT and Full Duplex */
313 writel((readl(&emac
->cfg
) &
314 ~(AT91_EMAC_CFG_SPD
| AT91_EMAC_CFG_FD
)
315 ) | AT91_EMAC_CFG_FD
,
320 if (stat1
& BMSR_100HALF
) {
321 /*set MII for 100BaseTX and Half Duplex */
322 writel((readl(&emac
->cfg
) &
323 ~(AT91_EMAC_CFG_SPD
| AT91_EMAC_CFG_FD
)
324 ) | AT91_EMAC_CFG_SPD
,
329 if (stat1
& BMSR_10HALF
) {
330 /*set MII for 10BaseT and Half Duplex */
331 writel((readl(&emac
->cfg
) &
332 ~(AT91_EMAC_CFG_SPD
| AT91_EMAC_CFG_FD
)),
339 static int at91emac_init(struct eth_device
*netdev
, bd_t
*bd
)
345 at91_pio_t
*pio
= (at91_pio_t
*) AT91_PIO_BASE
;
346 at91_pmc_t
*pmc
= (at91_pmc_t
*) AT91_PMC_BASE
;
348 emac
= (at91_emac_t
*) netdev
->iobase
;
349 dev
= (emac_device
*) netdev
->priv
;
351 /* PIO Disable Register */
352 value
= AT91_PMX_AA_EMDIO
| AT91_PMX_AA_EMDC
|
353 AT91_PMX_AA_ERXER
| AT91_PMX_AA_ERX1
|
354 AT91_PMX_AA_ERX0
| AT91_PMX_AA_ECRS
|
355 AT91_PMX_AA_ETX1
| AT91_PMX_AA_ETX0
|
356 AT91_PMX_AA_ETXEN
| AT91_PMX_AA_EREFCK
;
358 writel(value
, &pio
->pioa
.pdr
);
359 writel(value
, &pio
->pioa
.asr
);
362 value
= AT91_PMX_BA_ERXCK
;
364 value
= AT91_PMX_BA_ERXCK
| AT91_PMX_BA_ECOL
|
365 AT91_PMX_BA_ERXDV
| AT91_PMX_BA_ERX3
|
366 AT91_PMX_BA_ERX2
| AT91_PMX_BA_ETXER
|
367 AT91_PMX_BA_ETX3
| AT91_PMX_BA_ETX2
;
369 writel(value
, &pio
->piob
.pdr
);
370 writel(value
, &pio
->piob
.bsr
);
372 writel(1 << AT91_ID_EMAC
, &pmc
->pcer
);
373 writel(readl(&emac
->ctl
) | AT91_EMAC_CTL_CSR
, &emac
->ctl
);
375 /* Init Ethernet buffers */
376 for (i
= 0; i
< RBF_FRAMEMAX
; i
++) {
377 dev
->rbfdt
[i
].addr
= (unsigned long) NetRxPackets
[i
];
378 dev
->rbfdt
[i
].size
= 0;
380 dev
->rbfdt
[RBF_FRAMEMAX
- 1].addr
|= RBF_WRAP
;
382 writel((u32
) &(dev
->rbfdt
[0]), &emac
->rbqp
);
384 writel(readl(&emac
->rsr
) &
385 ~(AT91_EMAC_RSR_OVR
| AT91_EMAC_RSR_REC
| AT91_EMAC_RSR_BNA
),
388 value
= AT91_EMAC_CFG_CAF
| AT91_EMAC_CFG_NBC
|
391 value
|= AT91_EMAC_CFG_RMII
;
393 writel(value
, &emac
->cfg
);
395 writel(readl(&emac
->ctl
) | AT91_EMAC_CTL_TE
| AT91_EMAC_CTL_RE
,
398 if (!at91emac_phy_init(netdev
)) {
399 at91emac_UpdateLinkSpeed(emac
);
405 static void at91emac_halt(struct eth_device
*netdev
)
409 emac
= (at91_emac_t
*) netdev
->iobase
;
410 writel(readl(&emac
->ctl
) & ~(AT91_EMAC_CTL_TE
| AT91_EMAC_CTL_RE
),
412 DEBUG_AT91EMAC("halt MAC\n");
415 static int at91emac_send(struct eth_device
*netdev
, volatile void *packet
,
420 emac
= (at91_emac_t
*) netdev
->iobase
;
422 while (!(readl(&emac
->tsr
) & AT91_EMAC_TSR_BNQ
))
424 writel((u32
) packet
, &emac
->tar
);
425 writel(AT91_EMAC_TCR_LEN(length
), &emac
->tcr
);
426 while (AT91_EMAC_TCR_LEN(readl(&emac
->tcr
)))
428 DEBUG_AT91EMAC("Send %d \n", length
);
429 writel(readl(&emac
->tsr
) | AT91_EMAC_TSR_COMP
, &emac
->tsr
);
433 static int at91emac_recv(struct eth_device
*netdev
)
440 emac
= (at91_emac_t
*) netdev
->iobase
;
441 dev
= (emac_device
*) netdev
->priv
;
443 rbfp
= &dev
->rbfdt
[dev
->rbindex
];
444 while (rbfp
->addr
& RBF_OWNER
) {
445 size
= rbfp
->size
& RBF_SIZE
;
446 NetReceive(NetRxPackets
[dev
->rbindex
], size
);
448 DEBUG_AT91EMAC("Recv[%d]: %d bytes @ %x \n",
449 dev
->rbindex
, size
, rbfp
->addr
);
451 rbfp
->addr
&= ~RBF_OWNER
;
453 if (dev
->rbindex
< (RBF_FRAMEMAX
-1))
458 rbfp
= &(dev
->rbfdt
[dev
->rbindex
]);
459 if (!(rbfp
->addr
& RBF_OWNER
))
460 writel(readl(&emac
->rsr
) | AT91_EMAC_RSR_REC
,
464 if (readl(&emac
->isr
) & AT91_EMAC_IxR_RBNA
) {
465 /* EMAC silicon bug 41.3.1 workaround 1 */
466 writel(readl(&emac
->ctl
) & ~AT91_EMAC_CTL_RE
, &emac
->ctl
);
467 writel(readl(&emac
->ctl
) | AT91_EMAC_CTL_RE
, &emac
->ctl
);
469 printf("%s: reset receiver (EMAC dead lock bug)\n",
475 static int at91emac_write_hwaddr(struct eth_device
*netdev
)
479 at91_pmc_t
*pmc
= (at91_pmc_t
*) AT91_PMC_BASE
;
480 emac
= (at91_emac_t
*) netdev
->iobase
;
481 dev
= (emac_device
*) netdev
->priv
;
483 writel(1 << AT91_ID_EMAC
, &pmc
->pcer
);
484 DEBUG_AT91EMAC("init MAC-ADDR %x%x \n",
485 cpu_to_le16(*((u16
*)(netdev
->enetaddr
+ 4))),
486 cpu_to_le32(*((u32
*)netdev
->enetaddr
)));
487 writel(cpu_to_le32(*((u32
*)netdev
->enetaddr
)), &emac
->sa2l
);
488 writel(cpu_to_le16(*((u16
*)(netdev
->enetaddr
+ 4))), &emac
->sa2h
);
489 DEBUG_AT91EMAC("init MAC-ADDR %x%x \n",
490 readl(&emac
->sa2h
), readl(&emac
->sa2l
));
494 int at91emac_register(bd_t
*bis
, unsigned long iobase
)
497 emac_device
*emacfix
;
498 struct eth_device
*dev
;
501 iobase
= AT91_EMAC_BASE
;
502 emac
= malloc(sizeof(*emac
)+512);
505 dev
= malloc(sizeof(*dev
));
510 /* alignment as per Errata (64 bytes) is insufficient! */
511 emacfix
= (emac_device
*) (((unsigned long) emac
+ 0x1ff) & 0xFFFFFE00);
512 memset(emacfix
, 0, sizeof(emac_device
));
514 memset(dev
, 0, sizeof(*dev
));
515 sprintf(dev
->name
, "emac");
516 dev
->iobase
= iobase
;
518 dev
->init
= at91emac_init
;
519 dev
->halt
= at91emac_halt
;
520 dev
->send
= at91emac_send
;
521 dev
->recv
= at91emac_recv
;
522 dev
->write_hwaddr
= at91emac_write_hwaddr
;
526 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
527 miiphy_register(dev
->name
, at91emac_mii_read
, at91emac_mii_write
);