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