1
2
3
4
5
6
7
8#include <config.h>
9#include <common.h>
10#include <dm.h>
11#include <net.h>
12#include <malloc.h>
13#include <asm/io.h>
14#include <phy.h>
15#include <miiphy.h>
16#include <wait_bit.h>
17
18DECLARE_GLOBAL_DATA_PTR;
19
20
21#define XAE_EMMC_LINKSPEED_MASK 0xC0000000
22#define XAE_EMMC_LINKSPD_10 0x00000000
23#define XAE_EMMC_LINKSPD_100 0x40000000
24#define XAE_EMMC_LINKSPD_1000 0x80000000
25
26
27#define XAE_INT_RXRJECT_MASK 0x00000008
28#define XAE_INT_MGTRDY_MASK 0x00000080
29
30
31#define XAE_RCW1_RX_MASK 0x10000000
32
33
34#define XAE_TC_TX_MASK 0x10000000
35
36#define XAE_UAW1_UNICASTADDR_MASK 0x0000FFFF
37
38
39#define XAE_MDIO_MC_MDIOEN_MASK 0x00000040
40
41
42#define XAE_MDIO_MCR_PHYAD_MASK 0x1F000000
43#define XAE_MDIO_MCR_PHYAD_SHIFT 24
44#define XAE_MDIO_MCR_REGAD_MASK 0x001F0000
45#define XAE_MDIO_MCR_REGAD_SHIFT 16
46#define XAE_MDIO_MCR_OP_READ_MASK 0x00008000
47#define XAE_MDIO_MCR_OP_WRITE_MASK 0x00004000
48#define XAE_MDIO_MCR_INITIATE_MASK 0x00000800
49#define XAE_MDIO_MCR_READY_MASK 0x00000080
50
51#define XAE_MDIO_DIV_DFT 29
52
53#define XAXIDMA_BD_STS_ACTUAL_LEN_MASK 0x007FFFFF
54
55
56
57#define XAXIDMA_CR_RUNSTOP_MASK 0x00000001
58#define XAXIDMA_CR_RESET_MASK 0x00000004
59
60
61#define XAXIDMA_HALTED_MASK 0x00000001
62
63
64#define XAXIDMA_IRQ_IOC_MASK 0x00001000
65#define XAXIDMA_IRQ_DELAY_MASK 0x00002000
66#define XAXIDMA_IRQ_ALL_MASK 0x00007000
67
68
69#define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000
70#define XAXIDMA_BD_CTRL_TXEOF_MASK 0x04000000
71
72#define DMAALIGN 128
73
74static u8 rxframe[PKTSIZE_ALIGN] __attribute((aligned(DMAALIGN)));
75
76
77struct axidma_reg {
78 u32 control;
79 u32 status;
80 u32 current;
81 u32 current_hi;
82 u32 tail;
83 u32 tail_hi;
84};
85
86
87struct axidma_priv {
88 struct axidma_reg *dmatx;
89 struct axidma_reg *dmarx;
90 int phyaddr;
91 struct axi_regs *iobase;
92 phy_interface_t interface;
93 struct phy_device *phydev;
94 struct mii_dev *bus;
95 u8 eth_hasnobuf;
96 int phy_of_handle;
97};
98
99
100struct axidma_bd {
101 u32 next;
102 u32 reserved1;
103 u32 phys;
104 u32 reserved2;
105 u32 reserved3;
106 u32 reserved4;
107 u32 cntrl;
108 u32 status;
109 u32 app0;
110 u32 app1;
111 u32 app2;
112 u32 app3;
113 u32 app4;
114 u32 sw_id_offset;
115 u32 reserved5;
116 u32 reserved6;
117};
118
119
120static struct axidma_bd tx_bd __attribute((aligned(DMAALIGN)));
121static struct axidma_bd rx_bd __attribute((aligned(DMAALIGN)));
122
123struct axi_regs {
124 u32 reserved[3];
125 u32 is;
126 u32 reserved2;
127 u32 ie;
128 u32 reserved3[251];
129 u32 rcw1;
130 u32 tc;
131 u32 reserved4;
132 u32 emmc;
133 u32 reserved5[59];
134 u32 mdio_mc;
135 u32 mdio_mcr;
136 u32 mdio_mwd;
137 u32 mdio_mrd;
138 u32 reserved6[124];
139 u32 uaw0;
140 u32 uaw1;
141};
142
143
144#define PHY_DETECT_REG 1
145
146
147
148
149
150
151
152
153#define PHY_DETECT_MASK 0x1808
154
155static inline int mdio_wait(struct axi_regs *regs)
156{
157 u32 timeout = 200;
158
159
160 while (timeout && (!(readl(®s->mdio_mcr)
161 & XAE_MDIO_MCR_READY_MASK))) {
162 timeout--;
163 udelay(1);
164 }
165 if (!timeout) {
166 printf("%s: Timeout\n", __func__);
167 return 1;
168 }
169 return 0;
170}
171
172
173
174
175
176
177
178
179static inline void axienet_dma_write(struct axidma_bd *bd, u32 *desc)
180{
181#if defined(CONFIG_PHYS_64BIT)
182 writeq(bd, desc);
183#else
184 writel((u32)bd, desc);
185#endif
186}
187
188static u32 phyread(struct axidma_priv *priv, u32 phyaddress, u32 registernum,
189 u16 *val)
190{
191 struct axi_regs *regs = priv->iobase;
192 u32 mdioctrlreg = 0;
193
194 if (mdio_wait(regs))
195 return 1;
196
197 mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) &
198 XAE_MDIO_MCR_PHYAD_MASK) |
199 ((registernum << XAE_MDIO_MCR_REGAD_SHIFT)
200 & XAE_MDIO_MCR_REGAD_MASK) |
201 XAE_MDIO_MCR_INITIATE_MASK |
202 XAE_MDIO_MCR_OP_READ_MASK;
203
204 writel(mdioctrlreg, ®s->mdio_mcr);
205
206 if (mdio_wait(regs))
207 return 1;
208
209
210 *val = readl(®s->mdio_mrd);
211 return 0;
212}
213
214static u32 phywrite(struct axidma_priv *priv, u32 phyaddress, u32 registernum,
215 u32 data)
216{
217 struct axi_regs *regs = priv->iobase;
218 u32 mdioctrlreg = 0;
219
220 if (mdio_wait(regs))
221 return 1;
222
223 mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) &
224 XAE_MDIO_MCR_PHYAD_MASK) |
225 ((registernum << XAE_MDIO_MCR_REGAD_SHIFT)
226 & XAE_MDIO_MCR_REGAD_MASK) |
227 XAE_MDIO_MCR_INITIATE_MASK |
228 XAE_MDIO_MCR_OP_WRITE_MASK;
229
230
231 writel(data, ®s->mdio_mwd);
232
233 writel(mdioctrlreg, ®s->mdio_mcr);
234
235 if (mdio_wait(regs))
236 return 1;
237
238 return 0;
239}
240
241static int axiemac_phy_init(struct udevice *dev)
242{
243 u16 phyreg;
244 u32 i, ret;
245 struct axidma_priv *priv = dev_get_priv(dev);
246 struct axi_regs *regs = priv->iobase;
247 struct phy_device *phydev;
248
249 u32 supported = SUPPORTED_10baseT_Half |
250 SUPPORTED_10baseT_Full |
251 SUPPORTED_100baseT_Half |
252 SUPPORTED_100baseT_Full |
253 SUPPORTED_1000baseT_Half |
254 SUPPORTED_1000baseT_Full;
255
256
257 writel(XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK, ®s->mdio_mc);
258
259 if (priv->phyaddr == -1) {
260
261 for (i = 31; i >= 0; i--) {
262 ret = phyread(priv, i, PHY_DETECT_REG, &phyreg);
263 if (!ret && (phyreg != 0xFFFF) &&
264 ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
265
266 priv->phyaddr = i;
267 debug("axiemac: Found valid phy address, %x\n",
268 i);
269 break;
270 }
271 }
272 }
273
274
275 phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface);
276
277 phydev->supported &= supported;
278 phydev->advertising = phydev->supported;
279 priv->phydev = phydev;
280 if (priv->phy_of_handle)
281 priv->phydev->node = offset_to_ofnode(priv->phy_of_handle);
282 phy_config(phydev);
283
284 return 0;
285}
286
287
288static int setup_phy(struct udevice *dev)
289{
290 u16 temp;
291 u32 speed, emmc_reg, ret;
292 struct axidma_priv *priv = dev_get_priv(dev);
293 struct axi_regs *regs = priv->iobase;
294 struct phy_device *phydev = priv->phydev;
295
296 if (priv->interface == PHY_INTERFACE_MODE_SGMII) {
297
298
299
300
301
302 ret = phyread(priv, priv->phyaddr, MII_BMCR, &temp);
303 if (ret)
304 return 0;
305 if (temp & BMCR_ISOLATE) {
306 temp &= ~BMCR_ISOLATE;
307 ret = phywrite(priv, priv->phyaddr, MII_BMCR, temp);
308 if (ret)
309 return 0;
310 }
311 }
312
313 if (phy_startup(phydev)) {
314 printf("axiemac: could not initialize PHY %s\n",
315 phydev->dev->name);
316 return 0;
317 }
318 if (!phydev->link) {
319 printf("%s: No link.\n", phydev->dev->name);
320 return 0;
321 }
322
323 switch (phydev->speed) {
324 case 1000:
325 speed = XAE_EMMC_LINKSPD_1000;
326 break;
327 case 100:
328 speed = XAE_EMMC_LINKSPD_100;
329 break;
330 case 10:
331 speed = XAE_EMMC_LINKSPD_10;
332 break;
333 default:
334 return 0;
335 }
336
337
338 emmc_reg = readl(®s->emmc);
339 emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK;
340 emmc_reg |= speed;
341
342
343 writel(emmc_reg, ®s->emmc);
344
345
346
347
348
349
350 udelay(1);
351
352 return 1;
353}
354
355
356static void axiemac_stop(struct udevice *dev)
357{
358 struct axidma_priv *priv = dev_get_priv(dev);
359 u32 temp;
360
361
362 temp = readl(&priv->dmatx->control);
363 temp &= ~XAXIDMA_CR_RUNSTOP_MASK;
364 writel(temp, &priv->dmatx->control);
365
366 temp = readl(&priv->dmarx->control);
367 temp &= ~XAXIDMA_CR_RUNSTOP_MASK;
368 writel(temp, &priv->dmarx->control);
369
370 debug("axiemac: Halted\n");
371}
372
373static int axi_ethernet_init(struct axidma_priv *priv)
374{
375 struct axi_regs *regs = priv->iobase;
376 int err;
377
378
379
380
381
382
383
384
385
386
387 if (!priv->eth_hasnobuf) {
388 err = wait_for_bit_le32(®s->is, XAE_INT_MGTRDY_MASK,
389 true, 200, false);
390 if (err) {
391 printf("%s: Timeout\n", __func__);
392 return 1;
393 }
394
395
396
397
398
399 writel(0, ®s->ie);
400 }
401
402
403 writel(readl(®s->rcw1) & ~XAE_RCW1_RX_MASK, ®s->rcw1);
404
405
406
407
408
409 if (!priv->eth_hasnobuf) {
410
411 writel(XAE_INT_RXRJECT_MASK, ®s->is);
412 }
413
414
415
416 writel(XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK, ®s->mdio_mc);
417
418 debug("axiemac: InitHw done\n");
419 return 0;
420}
421
422static int axiemac_write_hwaddr(struct udevice *dev)
423{
424 struct eth_pdata *pdata = dev_get_platdata(dev);
425 struct axidma_priv *priv = dev_get_priv(dev);
426 struct axi_regs *regs = priv->iobase;
427
428
429 int val = ((pdata->enetaddr[3] << 24) | (pdata->enetaddr[2] << 16) |
430 (pdata->enetaddr[1] << 8) | (pdata->enetaddr[0]));
431 writel(val, ®s->uaw0);
432
433 val = (pdata->enetaddr[5] << 8) | pdata->enetaddr[4];
434 val |= readl(®s->uaw1) & ~XAE_UAW1_UNICASTADDR_MASK;
435 writel(val, ®s->uaw1);
436 return 0;
437}
438
439
440static void axi_dma_init(struct axidma_priv *priv)
441{
442 u32 timeout = 500;
443
444
445 writel(XAXIDMA_CR_RESET_MASK, &priv->dmatx->control);
446 writel(XAXIDMA_CR_RESET_MASK, &priv->dmarx->control);
447
448
449 while (timeout--) {
450
451
452 if (!((readl(&priv->dmatx->control) |
453 readl(&priv->dmarx->control))
454 & XAXIDMA_CR_RESET_MASK)) {
455 break;
456 }
457 }
458 if (!timeout)
459 printf("%s: Timeout\n", __func__);
460}
461
462static int axiemac_start(struct udevice *dev)
463{
464 struct axidma_priv *priv = dev_get_priv(dev);
465 struct axi_regs *regs = priv->iobase;
466 u32 temp;
467
468 debug("axiemac: Init started\n");
469
470
471
472
473
474
475 axi_dma_init(priv);
476
477
478 if (axi_ethernet_init(priv))
479 return -1;
480
481
482 temp = readl(&priv->dmarx->control);
483 temp &= ~XAXIDMA_IRQ_ALL_MASK;
484 writel(temp, &priv->dmarx->control);
485
486
487 axienet_dma_write(&rx_bd, &priv->dmarx->current);
488
489
490 memset(&rx_bd, 0, sizeof(rx_bd));
491 rx_bd.next = (u32)&rx_bd;
492 rx_bd.phys = (u32)&rxframe;
493 rx_bd.cntrl = sizeof(rxframe);
494
495 flush_cache((u32)&rx_bd, sizeof(rx_bd));
496
497
498
499 flush_cache((u32)&rxframe, sizeof(rxframe));
500
501
502 temp = readl(&priv->dmarx->control);
503 temp |= XAXIDMA_CR_RUNSTOP_MASK;
504 writel(temp, &priv->dmarx->control);
505
506
507 axienet_dma_write(&rx_bd, &priv->dmarx->tail);
508
509
510 writel(XAE_TC_TX_MASK, ®s->tc);
511
512 writel(XAE_RCW1_RX_MASK, ®s->rcw1);
513
514
515 if (!setup_phy(dev)) {
516 axiemac_stop(dev);
517 return -1;
518 }
519
520 debug("axiemac: Init complete\n");
521 return 0;
522}
523
524static int axiemac_send(struct udevice *dev, void *ptr, int len)
525{
526 struct axidma_priv *priv = dev_get_priv(dev);
527 u32 timeout;
528
529 if (len > PKTSIZE_ALIGN)
530 len = PKTSIZE_ALIGN;
531
532
533 flush_cache((u32)ptr, len);
534
535
536 memset(&tx_bd, 0, sizeof(tx_bd));
537
538 tx_bd.next = (u32)&tx_bd;
539 tx_bd.phys = (u32)ptr;
540
541 tx_bd.cntrl = len | XAXIDMA_BD_CTRL_TXSOF_MASK |
542 XAXIDMA_BD_CTRL_TXEOF_MASK;
543
544
545 flush_cache((u32)&tx_bd, sizeof(tx_bd));
546
547 if (readl(&priv->dmatx->status) & XAXIDMA_HALTED_MASK) {
548 u32 temp;
549 axienet_dma_write(&tx_bd, &priv->dmatx->current);
550
551 temp = readl(&priv->dmatx->control);
552 temp |= XAXIDMA_CR_RUNSTOP_MASK;
553 writel(temp, &priv->dmatx->control);
554 }
555
556
557 axienet_dma_write(&tx_bd, &priv->dmatx->tail);
558
559
560 debug("axiemac: Waiting for tx to be done\n");
561 timeout = 200;
562 while (timeout && (!(readl(&priv->dmatx->status) &
563 (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK)))) {
564 timeout--;
565 udelay(1);
566 }
567 if (!timeout) {
568 printf("%s: Timeout\n", __func__);
569 return 1;
570 }
571
572 debug("axiemac: Sending complete\n");
573 return 0;
574}
575
576static int isrxready(struct axidma_priv *priv)
577{
578 u32 status;
579
580
581 status = readl(&priv->dmarx->status);
582
583
584 writel(status & XAXIDMA_IRQ_ALL_MASK, &priv->dmarx->status);
585
586
587
588
589
590 if ((status & (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK)))
591 return 1;
592
593 return 0;
594}
595
596static int axiemac_recv(struct udevice *dev, int flags, uchar **packetp)
597{
598 u32 length;
599 struct axidma_priv *priv = dev_get_priv(dev);
600 u32 temp;
601
602
603 if (!isrxready(priv))
604 return -1;
605
606 debug("axiemac: RX data ready\n");
607
608
609 temp = readl(&priv->dmarx->control);
610 temp &= ~XAXIDMA_IRQ_ALL_MASK;
611 writel(temp, &priv->dmarx->control);
612 if (!priv->eth_hasnobuf)
613 length = rx_bd.app4 & 0xFFFF;
614 else
615 length = rx_bd.status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;
616
617#ifdef DEBUG
618 print_buffer(&rxframe, &rxframe[0], 1, length, 16);
619#endif
620
621 *packetp = rxframe;
622 return length;
623}
624
625static int axiemac_free_pkt(struct udevice *dev, uchar *packet, int length)
626{
627 struct axidma_priv *priv = dev_get_priv(dev);
628
629#ifdef DEBUG
630
631 memset(rxframe, 0, sizeof(rxframe));
632#endif
633
634
635 memset(&rx_bd, 0, sizeof(rx_bd));
636 rx_bd.next = (u32)&rx_bd;
637 rx_bd.phys = (u32)&rxframe;
638 rx_bd.cntrl = sizeof(rxframe);
639
640
641 flush_cache((u32)&rx_bd, sizeof(rx_bd));
642
643
644
645 flush_cache((u32)&rxframe, sizeof(rxframe));
646
647
648 axienet_dma_write(&rx_bd, &priv->dmarx->tail);
649
650 debug("axiemac: RX completed, framelength = %d\n", length);
651
652 return 0;
653}
654
655static int axiemac_miiphy_read(struct mii_dev *bus, int addr,
656 int devad, int reg)
657{
658 int ret;
659 u16 value;
660
661 ret = phyread(bus->priv, addr, reg, &value);
662 debug("axiemac: Read MII 0x%x, 0x%x, 0x%x, %d\n", addr, reg,
663 value, ret);
664 return value;
665}
666
667static int axiemac_miiphy_write(struct mii_dev *bus, int addr, int devad,
668 int reg, u16 value)
669{
670 debug("axiemac: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, value);
671 return phywrite(bus->priv, addr, reg, value);
672}
673
674static int axi_emac_probe(struct udevice *dev)
675{
676 struct axidma_priv *priv = dev_get_priv(dev);
677 int ret;
678
679 priv->bus = mdio_alloc();
680 priv->bus->read = axiemac_miiphy_read;
681 priv->bus->write = axiemac_miiphy_write;
682 priv->bus->priv = priv;
683
684 ret = mdio_register_seq(priv->bus, dev->seq);
685 if (ret)
686 return ret;
687
688 axiemac_phy_init(dev);
689
690 return 0;
691}
692
693static int axi_emac_remove(struct udevice *dev)
694{
695 struct axidma_priv *priv = dev_get_priv(dev);
696
697 free(priv->phydev);
698 mdio_unregister(priv->bus);
699 mdio_free(priv->bus);
700
701 return 0;
702}
703
704static const struct eth_ops axi_emac_ops = {
705 .start = axiemac_start,
706 .send = axiemac_send,
707 .recv = axiemac_recv,
708 .free_pkt = axiemac_free_pkt,
709 .stop = axiemac_stop,
710 .write_hwaddr = axiemac_write_hwaddr,
711};
712
713static int axi_emac_ofdata_to_platdata(struct udevice *dev)
714{
715 struct eth_pdata *pdata = dev_get_platdata(dev);
716 struct axidma_priv *priv = dev_get_priv(dev);
717 int node = dev_of_offset(dev);
718 int offset = 0;
719 const char *phy_mode;
720
721 pdata->iobase = (phys_addr_t)devfdt_get_addr(dev);
722 priv->iobase = (struct axi_regs *)pdata->iobase;
723
724 offset = fdtdec_lookup_phandle(gd->fdt_blob, node,
725 "axistream-connected");
726 if (offset <= 0) {
727 printf("%s: axistream is not found\n", __func__);
728 return -EINVAL;
729 }
730 priv->dmatx = (struct axidma_reg *)fdtdec_get_addr(gd->fdt_blob,
731 offset, "reg");
732 if (!priv->dmatx) {
733 printf("%s: axi_dma register space not found\n", __func__);
734 return -EINVAL;
735 }
736
737 priv->dmarx = (struct axidma_reg *)((u32)priv->dmatx + 0x30);
738
739 priv->phyaddr = -1;
740
741 offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "phy-handle");
742 if (offset > 0) {
743 priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
744 priv->phy_of_handle = offset;
745 }
746
747 phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL);
748 if (phy_mode)
749 pdata->phy_interface = phy_get_interface_by_name(phy_mode);
750 if (pdata->phy_interface == -1) {
751 printf("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
752 return -EINVAL;
753 }
754 priv->interface = pdata->phy_interface;
755
756 priv->eth_hasnobuf = fdtdec_get_bool(gd->fdt_blob, node,
757 "xlnx,eth-hasnobuf");
758
759 printf("AXI EMAC: %lx, phyaddr %d, interface %s\n", (ulong)priv->iobase,
760 priv->phyaddr, phy_string_for_interface(priv->interface));
761
762 return 0;
763}
764
765static const struct udevice_id axi_emac_ids[] = {
766 { .compatible = "xlnx,axi-ethernet-1.00.a" },
767 { }
768};
769
770U_BOOT_DRIVER(axi_emac) = {
771 .name = "axi_emac",
772 .id = UCLASS_ETH,
773 .of_match = axi_emac_ids,
774 .ofdata_to_platdata = axi_emac_ofdata_to_platdata,
775 .probe = axi_emac_probe,
776 .remove = axi_emac_remove,
777 .ops = &axi_emac_ops,
778 .priv_auto_alloc_size = sizeof(struct axidma_priv),
779 .platdata_auto_alloc_size = sizeof(struct eth_pdata),
780};
781