1
2
3
4
5
6
7
8
9
10
11
12#include <common.h>
13#include <dm.h>
14#include <net.h>
15#include <netdev.h>
16#include <config.h>
17#include <console.h>
18#include <malloc.h>
19#include <asm/io.h>
20#include <phy.h>
21#include <miiphy.h>
22#include <watchdog.h>
23#include <asm/system.h>
24#include <asm/arch/hardware.h>
25#include <asm/arch/sys_proto.h>
26#include <asm-generic/errno.h>
27
28DECLARE_GLOBAL_DATA_PTR;
29
30
31#define ZYNQ_GEM_PHYMNTNC_OP_MASK 0x40020000
32#define ZYNQ_GEM_PHYMNTNC_OP_R_MASK 0x20000000
33#define ZYNQ_GEM_PHYMNTNC_OP_W_MASK 0x10000000
34#define ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK 23
35#define ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK 18
36
37#define ZYNQ_GEM_RXBUF_EOF_MASK 0x00008000
38#define ZYNQ_GEM_RXBUF_SOF_MASK 0x00004000
39#define ZYNQ_GEM_RXBUF_LEN_MASK 0x00003FFF
40
41#define ZYNQ_GEM_RXBUF_WRAP_MASK 0x00000002
42#define ZYNQ_GEM_RXBUF_NEW_MASK 0x00000001
43#define ZYNQ_GEM_RXBUF_ADD_MASK 0xFFFFFFFC
44
45
46#define ZYNQ_GEM_TXBUF_WRAP_MASK 0x40000000
47#define ZYNQ_GEM_TXBUF_LAST_MASK 0x00008000
48#define ZYNQ_GEM_TXBUF_USED_MASK 0x80000000
49
50#define ZYNQ_GEM_NWCTRL_TXEN_MASK 0x00000008
51#define ZYNQ_GEM_NWCTRL_RXEN_MASK 0x00000004
52#define ZYNQ_GEM_NWCTRL_MDEN_MASK 0x00000010
53#define ZYNQ_GEM_NWCTRL_STARTTX_MASK 0x00000200
54
55#define ZYNQ_GEM_NWCFG_SPEED100 0x000000001
56#define ZYNQ_GEM_NWCFG_SPEED1000 0x000000400
57#define ZYNQ_GEM_NWCFG_FDEN 0x000000002
58#define ZYNQ_GEM_NWCFG_FSREM 0x000020000
59#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x0000c0000
60
61#ifdef CONFIG_ARM64
62# define ZYNQ_GEM_DBUS_WIDTH (1 << 21)
63#else
64# define ZYNQ_GEM_DBUS_WIDTH (0 << 21)
65#endif
66
67#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_DBUS_WIDTH | \
68 ZYNQ_GEM_NWCFG_FDEN | \
69 ZYNQ_GEM_NWCFG_FSREM | \
70 ZYNQ_GEM_NWCFG_MDCCLKDIV)
71
72#define ZYNQ_GEM_NWSR_MDIOIDLE_MASK 0x00000004
73
74#define ZYNQ_GEM_DMACR_BLENGTH 0x00000004
75
76#define ZYNQ_GEM_DMACR_RXSIZE 0x00000300
77
78#define ZYNQ_GEM_DMACR_TXSIZE 0x00000400
79
80#define ZYNQ_GEM_DMACR_RXBUF 0x00180000
81
82#define ZYNQ_GEM_DMACR_INIT (ZYNQ_GEM_DMACR_BLENGTH | \
83 ZYNQ_GEM_DMACR_RXSIZE | \
84 ZYNQ_GEM_DMACR_TXSIZE | \
85 ZYNQ_GEM_DMACR_RXBUF)
86
87#define ZYNQ_GEM_TSR_DONE 0x00000020
88
89
90#define PHY_DETECT_REG 1
91
92
93
94
95
96
97
98#define PHY_DETECT_MASK 0x1808
99
100
101#define ZYNQ_GEM_TXBUF_FRMLEN_MASK 0x000007ff
102#define ZYNQ_GEM_TXBUF_EXHAUSTED 0x08000000
103#define ZYNQ_GEM_TXBUF_UNDERRUN 0x10000000
104
105
106#define ZYNQ_GEM_FREQUENCY_10 2500000UL
107#define ZYNQ_GEM_FREQUENCY_100 25000000UL
108#define ZYNQ_GEM_FREQUENCY_1000 125000000UL
109
110
111struct zynq_gem_regs {
112 u32 nwctrl;
113 u32 nwcfg;
114 u32 nwsr;
115 u32 reserved1;
116 u32 dmacr;
117 u32 txsr;
118 u32 rxqbase;
119 u32 txqbase;
120 u32 rxsr;
121 u32 reserved2[2];
122 u32 idr;
123 u32 reserved3;
124 u32 phymntnc;
125 u32 reserved4[18];
126 u32 hashl;
127 u32 hashh;
128#define LADDR_LOW 0
129#define LADDR_HIGH 1
130 u32 laddr[4][LADDR_HIGH + 1];
131 u32 match[4];
132 u32 reserved6[18];
133#define STAT_SIZE 44
134 u32 stat[STAT_SIZE];
135 u32 reserved7[164];
136 u32 transmit_q1_ptr;
137 u32 reserved8[15];
138 u32 receive_q1_ptr;
139};
140
141
142struct emac_bd {
143 u32 addr;
144 u32 status;
145};
146
147#define RX_BUF 32
148
149
150
151#define BD_SPACE 0x100000
152
153#define BD_SEPRN_SPACE (RX_BUF * sizeof(struct emac_bd))
154
155
156#define TX_FREE_DESC 2
157
158
159struct zynq_gem_priv {
160 struct emac_bd *tx_bd;
161 struct emac_bd *rx_bd;
162 char *rxbuffers;
163 u32 rxbd_current;
164 u32 rx_first_buf;
165 int phyaddr;
166 u32 emio;
167 int init;
168 struct zynq_gem_regs *iobase;
169 phy_interface_t interface;
170 struct phy_device *phydev;
171 struct mii_dev *bus;
172};
173
174static inline int mdio_wait(struct zynq_gem_regs *regs)
175{
176 u32 timeout = 20000;
177
178
179 while (--timeout) {
180 if (readl(®s->nwsr) & ZYNQ_GEM_NWSR_MDIOIDLE_MASK)
181 break;
182 WATCHDOG_RESET();
183 }
184
185 if (!timeout) {
186 printf("%s: Timeout\n", __func__);
187 return 1;
188 }
189
190 return 0;
191}
192
193static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
194 u32 op, u16 *data)
195{
196 u32 mgtcr;
197 struct zynq_gem_regs *regs = priv->iobase;
198
199 if (mdio_wait(regs))
200 return 1;
201
202
203 mgtcr = ZYNQ_GEM_PHYMNTNC_OP_MASK | op |
204 (phy_addr << ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK) |
205 (regnum << ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK) | *data;
206
207
208 writel(mgtcr, ®s->phymntnc);
209
210 if (mdio_wait(regs))
211 return 1;
212
213 if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK)
214 *data = readl(®s->phymntnc);
215
216 return 0;
217}
218
219static u32 phyread(struct zynq_gem_priv *priv, u32 phy_addr,
220 u32 regnum, u16 *val)
221{
222 u32 ret;
223
224 ret = phy_setup_op(priv, phy_addr, regnum,
225 ZYNQ_GEM_PHYMNTNC_OP_R_MASK, val);
226
227 if (!ret)
228 debug("%s: phy_addr %d, regnum 0x%x, val 0x%x\n", __func__,
229 phy_addr, regnum, *val);
230
231 return ret;
232}
233
234static u32 phywrite(struct zynq_gem_priv *priv, u32 phy_addr,
235 u32 regnum, u16 data)
236{
237 debug("%s: phy_addr %d, regnum 0x%x, data 0x%x\n", __func__, phy_addr,
238 regnum, data);
239
240 return phy_setup_op(priv, phy_addr, regnum,
241 ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data);
242}
243
244static int phy_detection(struct udevice *dev)
245{
246 int i;
247 u16 phyreg;
248 struct zynq_gem_priv *priv = dev->priv;
249
250 if (priv->phyaddr != -1) {
251 phyread(priv, priv->phyaddr, PHY_DETECT_REG, &phyreg);
252 if ((phyreg != 0xFFFF) &&
253 ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
254
255 debug("Default phy address %d is valid\n",
256 priv->phyaddr);
257 return 0;
258 } else {
259 debug("PHY address is not setup correctly %d\n",
260 priv->phyaddr);
261 priv->phyaddr = -1;
262 }
263 }
264
265 debug("detecting phy address\n");
266 if (priv->phyaddr == -1) {
267
268 for (i = 31; i >= 0; i--) {
269 phyread(priv, i, PHY_DETECT_REG, &phyreg);
270 if ((phyreg != 0xFFFF) &&
271 ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
272
273 priv->phyaddr = i;
274 debug("Found valid phy address, %d\n", i);
275 return 0;
276 }
277 }
278 }
279 printf("PHY is not detected\n");
280 return -1;
281}
282
283static int zynq_gem_setup_mac(struct udevice *dev)
284{
285 u32 i, macaddrlow, macaddrhigh;
286 struct eth_pdata *pdata = dev_get_platdata(dev);
287 struct zynq_gem_priv *priv = dev_get_priv(dev);
288 struct zynq_gem_regs *regs = priv->iobase;
289
290
291 macaddrlow = pdata->enetaddr[0];
292 macaddrlow |= pdata->enetaddr[1] << 8;
293 macaddrlow |= pdata->enetaddr[2] << 16;
294 macaddrlow |= pdata->enetaddr[3] << 24;
295
296
297 macaddrhigh = pdata->enetaddr[4];
298 macaddrhigh |= pdata->enetaddr[5] << 8;
299
300 for (i = 0; i < 4; i++) {
301 writel(0, ®s->laddr[i][LADDR_LOW]);
302 writel(0, ®s->laddr[i][LADDR_HIGH]);
303
304 writel(0, ®s->match[i]);
305 }
306
307 writel(macaddrlow, ®s->laddr[0][LADDR_LOW]);
308 writel(macaddrhigh, ®s->laddr[0][LADDR_HIGH]);
309
310 return 0;
311}
312
313static int zynq_phy_init(struct udevice *dev)
314{
315 int ret;
316 struct zynq_gem_priv *priv = dev_get_priv(dev);
317 struct zynq_gem_regs *regs = priv->iobase;
318 const u32 supported = SUPPORTED_10baseT_Half |
319 SUPPORTED_10baseT_Full |
320 SUPPORTED_100baseT_Half |
321 SUPPORTED_100baseT_Full |
322 SUPPORTED_1000baseT_Half |
323 SUPPORTED_1000baseT_Full;
324
325
326 writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, ®s->nwctrl);
327
328 ret = phy_detection(dev);
329 if (ret) {
330 printf("GEM PHY init failed\n");
331 return ret;
332 }
333
334 priv->phydev = phy_connect(priv->bus, priv->phyaddr, dev,
335 priv->interface);
336 if (!priv->phydev)
337 return -ENODEV;
338
339 priv->phydev->supported = supported | ADVERTISED_Pause |
340 ADVERTISED_Asym_Pause;
341 priv->phydev->advertising = priv->phydev->supported;
342 phy_config(priv->phydev);
343
344 return 0;
345}
346
347static int zynq_gem_init(struct udevice *dev)
348{
349 u32 i;
350 unsigned long clk_rate = 0;
351 struct zynq_gem_priv *priv = dev_get_priv(dev);
352 struct zynq_gem_regs *regs = priv->iobase;
353 struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC];
354 struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2];
355
356 if (!priv->init) {
357
358 writel(0xFFFFFFFF, ®s->idr);
359
360
361 writel(0, ®s->nwctrl);
362 writel(0, ®s->txsr);
363 writel(0, ®s->rxsr);
364 writel(0, ®s->phymntnc);
365
366
367
368
369 writel(0x0, ®s->hashl);
370
371 writel(0x0, ®s->hashh);
372
373
374 for (i = 0; i < STAT_SIZE; i++)
375 readl(®s->stat[i]);
376
377
378 memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));
379
380 for (i = 0; i < RX_BUF; i++) {
381 priv->rx_bd[i].status = 0xF0000000;
382 priv->rx_bd[i].addr =
383 ((ulong)(priv->rxbuffers) +
384 (i * PKTSIZE_ALIGN));
385 }
386
387 priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
388
389 writel((ulong)priv->rx_bd, ®s->rxqbase);
390
391
392 writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr);
393
394
395 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK);
396
397
398 dummy_tx_bd->addr = 0;
399 dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
400 ZYNQ_GEM_TXBUF_LAST_MASK|
401 ZYNQ_GEM_TXBUF_USED_MASK;
402
403 dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
404 ZYNQ_GEM_RXBUF_NEW_MASK;
405 dummy_rx_bd->status = 0;
406 flush_dcache_range((ulong)&dummy_tx_bd, (ulong)&dummy_tx_bd +
407 sizeof(dummy_tx_bd));
408 flush_dcache_range((ulong)&dummy_rx_bd, (ulong)&dummy_rx_bd +
409 sizeof(dummy_rx_bd));
410
411 writel((ulong)dummy_tx_bd, ®s->transmit_q1_ptr);
412 writel((ulong)dummy_rx_bd, ®s->receive_q1_ptr);
413
414 priv->init++;
415 }
416
417 phy_startup(priv->phydev);
418
419 if (!priv->phydev->link) {
420 printf("%s: No link.\n", priv->phydev->dev->name);
421 return -1;
422 }
423
424 switch (priv->phydev->speed) {
425 case SPEED_1000:
426 writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000,
427 ®s->nwcfg);
428 clk_rate = ZYNQ_GEM_FREQUENCY_1000;
429 break;
430 case SPEED_100:
431 writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100,
432 ®s->nwcfg);
433 clk_rate = ZYNQ_GEM_FREQUENCY_100;
434 break;
435 case SPEED_10:
436 clk_rate = ZYNQ_GEM_FREQUENCY_10;
437 break;
438 }
439
440
441 if (!priv->emio)
442 zynq_slcr_gem_clk_setup((ulong)priv->iobase !=
443 ZYNQ_GEM_BASEADDR0, clk_rate);
444
445 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
446 ZYNQ_GEM_NWCTRL_TXEN_MASK);
447
448 return 0;
449}
450
451static int wait_for_bit(const char *func, u32 *reg, const u32 mask,
452 bool set, unsigned int timeout)
453{
454 u32 val;
455 unsigned long start = get_timer(0);
456
457 while (1) {
458 val = readl(reg);
459
460 if (!set)
461 val = ~val;
462
463 if ((val & mask) == mask)
464 return 0;
465
466 if (get_timer(start) > timeout)
467 break;
468
469 if (ctrlc()) {
470 puts("Abort\n");
471 return -EINTR;
472 }
473
474 udelay(1);
475 }
476
477 debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n",
478 func, reg, mask, set);
479
480 return -ETIMEDOUT;
481}
482
483static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
484{
485 u32 addr, size;
486 struct zynq_gem_priv *priv = dev_get_priv(dev);
487 struct zynq_gem_regs *regs = priv->iobase;
488 struct emac_bd *current_bd = &priv->tx_bd[1];
489
490
491 memset(priv->tx_bd, 0, sizeof(struct emac_bd));
492
493 priv->tx_bd->addr = (ulong)ptr;
494 priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) |
495 ZYNQ_GEM_TXBUF_LAST_MASK;
496
497 current_bd->addr = 0x0;
498 current_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
499 ZYNQ_GEM_TXBUF_LAST_MASK|
500 ZYNQ_GEM_TXBUF_USED_MASK;
501
502
503 writel((ulong)priv->tx_bd, ®s->txqbase);
504
505 addr = (ulong) ptr;
506 addr &= ~(ARCH_DMA_MINALIGN - 1);
507 size = roundup(len, ARCH_DMA_MINALIGN);
508 flush_dcache_range(addr, addr + size);
509
510 addr = (ulong)priv->rxbuffers;
511 addr &= ~(ARCH_DMA_MINALIGN - 1);
512 size = roundup((RX_BUF * PKTSIZE_ALIGN), ARCH_DMA_MINALIGN);
513 flush_dcache_range(addr, addr + size);
514 barrier();
515
516
517 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK);
518
519
520 if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED)
521 printf("TX buffers exhausted in mid frame\n");
522
523 return wait_for_bit(__func__, ®s->txsr, ZYNQ_GEM_TSR_DONE,
524 true, 20000);
525}
526
527
528static int zynq_gem_recv(struct udevice *dev, int flags, uchar **packetp)
529{
530 int frame_len;
531 u32 addr;
532 struct zynq_gem_priv *priv = dev_get_priv(dev);
533 struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current];
534
535 if (!(current_bd->addr & ZYNQ_GEM_RXBUF_NEW_MASK))
536 return -1;
537
538 if (!(current_bd->status &
539 (ZYNQ_GEM_RXBUF_SOF_MASK | ZYNQ_GEM_RXBUF_EOF_MASK))) {
540 printf("GEM: SOF or EOF not set for last buffer received!\n");
541 return -1;
542 }
543
544 frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK;
545 if (!frame_len) {
546 printf("%s: Zero size packet?\n", __func__);
547 return -1;
548 }
549
550 addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK;
551 addr &= ~(ARCH_DMA_MINALIGN - 1);
552 *packetp = (uchar *)(uintptr_t)addr;
553
554 return frame_len;
555}
556
557static int zynq_gem_free_pkt(struct udevice *dev, uchar *packet, int length)
558{
559 struct zynq_gem_priv *priv = dev_get_priv(dev);
560 struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current];
561 struct emac_bd *first_bd;
562
563 if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) {
564 priv->rx_first_buf = priv->rxbd_current;
565 } else {
566 current_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK;
567 current_bd->status = 0xF0000000;
568 }
569
570 if (current_bd->status & ZYNQ_GEM_RXBUF_EOF_MASK) {
571 first_bd = &priv->rx_bd[priv->rx_first_buf];
572 first_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK;
573 first_bd->status = 0xF0000000;
574 }
575
576 if ((++priv->rxbd_current) >= RX_BUF)
577 priv->rxbd_current = 0;
578
579 return 0;
580}
581
582static void zynq_gem_halt(struct udevice *dev)
583{
584 struct zynq_gem_priv *priv = dev_get_priv(dev);
585 struct zynq_gem_regs *regs = priv->iobase;
586
587 clrsetbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
588 ZYNQ_GEM_NWCTRL_TXEN_MASK, 0);
589}
590
591static int zynq_gem_miiphy_read(struct mii_dev *bus, int addr,
592 int devad, int reg)
593{
594 struct zynq_gem_priv *priv = bus->priv;
595 int ret;
596 u16 val;
597
598 ret = phyread(priv, addr, reg, &val);
599 debug("%s 0x%x, 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val, ret);
600 return val;
601}
602
603static int zynq_gem_miiphy_write(struct mii_dev *bus, int addr, int devad,
604 int reg, u16 value)
605{
606 struct zynq_gem_priv *priv = bus->priv;
607
608 debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, value);
609 return phywrite(priv, addr, reg, value);
610}
611
612static int zynq_gem_probe(struct udevice *dev)
613{
614 void *bd_space;
615 struct zynq_gem_priv *priv = dev_get_priv(dev);
616 int ret;
617
618
619 priv->rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN);
620 memset(priv->rxbuffers, 0, RX_BUF * PKTSIZE_ALIGN);
621
622
623 bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE);
624 mmu_set_region_dcache_behaviour((phys_addr_t)bd_space,
625 BD_SPACE, DCACHE_OFF);
626
627
628 priv->tx_bd = (struct emac_bd *)bd_space;
629 priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE);
630
631 priv->bus = mdio_alloc();
632 priv->bus->read = zynq_gem_miiphy_read;
633 priv->bus->write = zynq_gem_miiphy_write;
634 priv->bus->priv = priv;
635 strcpy(priv->bus->name, "gem");
636
637 ret = mdio_register(priv->bus);
638 if (ret)
639 return ret;
640
641 zynq_phy_init(dev);
642
643 return 0;
644}
645
646static int zynq_gem_remove(struct udevice *dev)
647{
648 struct zynq_gem_priv *priv = dev_get_priv(dev);
649
650 free(priv->phydev);
651 mdio_unregister(priv->bus);
652 mdio_free(priv->bus);
653
654 return 0;
655}
656
657static const struct eth_ops zynq_gem_ops = {
658 .start = zynq_gem_init,
659 .send = zynq_gem_send,
660 .recv = zynq_gem_recv,
661 .free_pkt = zynq_gem_free_pkt,
662 .stop = zynq_gem_halt,
663 .write_hwaddr = zynq_gem_setup_mac,
664};
665
666static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
667{
668 struct eth_pdata *pdata = dev_get_platdata(dev);
669 struct zynq_gem_priv *priv = dev_get_priv(dev);
670 int offset = 0;
671 const char *phy_mode;
672
673 pdata->iobase = (phys_addr_t)dev_get_addr(dev);
674 priv->iobase = (struct zynq_gem_regs *)pdata->iobase;
675
676 priv->emio = 0;
677 priv->phyaddr = -1;
678
679 offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
680 "phy-handle");
681 if (offset > 0)
682 priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
683
684 phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
685 if (phy_mode)
686 pdata->phy_interface = phy_get_interface_by_name(phy_mode);
687 if (pdata->phy_interface == -1) {
688 debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
689 return -EINVAL;
690 }
691 priv->interface = pdata->phy_interface;
692
693 printf("ZYNQ GEM: %lx, phyaddr %d, interface %s\n", (ulong)priv->iobase,
694 priv->phyaddr, phy_string_for_interface(priv->interface));
695
696 return 0;
697}
698
699static const struct udevice_id zynq_gem_ids[] = {
700 { .compatible = "cdns,zynqmp-gem" },
701 { .compatible = "cdns,zynq-gem" },
702 { .compatible = "cdns,gem" },
703 { }
704};
705
706U_BOOT_DRIVER(zynq_gem) = {
707 .name = "zynq_gem",
708 .id = UCLASS_ETH,
709 .of_match = zynq_gem_ids,
710 .ofdata_to_platdata = zynq_gem_ofdata_to_platdata,
711 .probe = zynq_gem_probe,
712 .remove = zynq_gem_remove,
713 .ops = &zynq_gem_ops,
714 .priv_auto_alloc_size = sizeof(struct zynq_gem_priv),
715 .platdata_auto_alloc_size = sizeof(struct eth_pdata),
716};
717