]> Git Repo - J-u-boot.git/blob - drivers/net/zynq_gem.c
net: zynq_gem: Use ulong instead of u32 data type
[J-u-boot.git] / drivers / net / zynq_gem.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2011 Michal Simek
4  *
5  * Michal SIMEK <[email protected]>
6  *
7  * Based on Xilinx gmac driver:
8  * (C) Copyright 2011 Xilinx
9  */
10
11 #include <clk.h>
12 #include <common.h>
13 #include <cpu_func.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 <dm/device_compat.h>
29 #include <linux/err.h>
30 #include <linux/errno.h>
31
32 /* Bit/mask specification */
33 #define ZYNQ_GEM_PHYMNTNC_OP_MASK       0x40020000 /* operation mask bits */
34 #define ZYNQ_GEM_PHYMNTNC_OP_R_MASK     0x20000000 /* read operation */
35 #define ZYNQ_GEM_PHYMNTNC_OP_W_MASK     0x10000000 /* write operation */
36 #define ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK      23 /* Shift bits for PHYAD */
37 #define ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK      18 /* Shift bits for PHREG */
38
39 #define ZYNQ_GEM_RXBUF_EOF_MASK         0x00008000 /* End of frame. */
40 #define ZYNQ_GEM_RXBUF_SOF_MASK         0x00004000 /* Start of frame. */
41 #define ZYNQ_GEM_RXBUF_LEN_MASK         0x00003FFF /* Mask for length field */
42
43 #define ZYNQ_GEM_RXBUF_WRAP_MASK        0x00000002 /* Wrap bit, last BD */
44 #define ZYNQ_GEM_RXBUF_NEW_MASK         0x00000001 /* Used bit.. */
45 #define ZYNQ_GEM_RXBUF_ADD_MASK         0xFFFFFFFC /* Mask for address */
46
47 /* Wrap bit, last descriptor */
48 #define ZYNQ_GEM_TXBUF_WRAP_MASK        0x40000000
49 #define ZYNQ_GEM_TXBUF_LAST_MASK        0x00008000 /* Last buffer */
50 #define ZYNQ_GEM_TXBUF_USED_MASK        0x80000000 /* Used by Hw */
51
52 #define ZYNQ_GEM_NWCTRL_TXEN_MASK       0x00000008 /* Enable transmit */
53 #define ZYNQ_GEM_NWCTRL_RXEN_MASK       0x00000004 /* Enable receive */
54 #define ZYNQ_GEM_NWCTRL_MDEN_MASK       0x00000010 /* Enable MDIO port */
55 #define ZYNQ_GEM_NWCTRL_STARTTX_MASK    0x00000200 /* Start tx (tx_go) */
56
57 #define ZYNQ_GEM_NWCFG_SPEED100         0x00000001 /* 100 Mbps operation */
58 #define ZYNQ_GEM_NWCFG_SPEED1000        0x00000400 /* 1Gbps operation */
59 #define ZYNQ_GEM_NWCFG_FDEN             0x00000002 /* Full Duplex mode */
60 #define ZYNQ_GEM_NWCFG_FSREM            0x00020000 /* FCS removal */
61 #define ZYNQ_GEM_NWCFG_SGMII_ENBL       0x08000000 /* SGMII Enable */
62 #define ZYNQ_GEM_NWCFG_PCS_SEL          0x00000800 /* PCS select */
63 #ifdef CONFIG_ARM64
64 #define ZYNQ_GEM_NWCFG_MDCCLKDIV        0x00100000 /* Div pclk by 64, max 160MHz */
65 #else
66 #define ZYNQ_GEM_NWCFG_MDCCLKDIV        0x000c0000 /* Div pclk by 48, max 120MHz */
67 #endif
68
69 #ifdef CONFIG_ARM64
70 # define ZYNQ_GEM_DBUS_WIDTH    (1 << 21) /* 64 bit bus */
71 #else
72 # define ZYNQ_GEM_DBUS_WIDTH    (0 << 21) /* 32 bit bus */
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 /* PHY management idle */
81
82 #define ZYNQ_GEM_DMACR_BLENGTH          0x00000004 /* INCR4 AHB bursts */
83 /* Use full configured addressable space (8 Kb) */
84 #define ZYNQ_GEM_DMACR_RXSIZE           0x00000300
85 /* Use full configured addressable space (4 Kb) */
86 #define ZYNQ_GEM_DMACR_TXSIZE           0x00000400
87 /* Set with binary 00011000 to use 1536 byte(1*max length frame/buffer) */
88 #define ZYNQ_GEM_DMACR_RXBUF            0x00180000
89
90 #if defined(CONFIG_PHYS_64BIT)
91 # define ZYNQ_GEM_DMA_BUS_WIDTH         BIT(30) /* 64 bit bus */
92 #else
93 # define ZYNQ_GEM_DMA_BUS_WIDTH         (0 << 30) /* 32 bit bus */
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 /* Tx done mask */
103
104 #define ZYNQ_GEM_PCS_CTL_ANEG_ENBL      0x1000
105
106 #define ZYNQ_GEM_DCFG_DBG6_DMA_64B      BIT(23)
107
108 /* Use MII register 1 (MII status register) to detect PHY */
109 #define PHY_DETECT_REG  1
110
111 /* Mask used to verify certain PHY features (or register contents)
112  * in the register above:
113  *  0x1000: 10Mbps full duplex support
114  *  0x0800: 10Mbps half duplex support
115  *  0x0008: Auto-negotiation support
116  */
117 #define PHY_DETECT_MASK 0x1808
118
119 /* TX BD status masks */
120 #define ZYNQ_GEM_TXBUF_FRMLEN_MASK      0x000007ff
121 #define ZYNQ_GEM_TXBUF_EXHAUSTED        0x08000000
122 #define ZYNQ_GEM_TXBUF_UNDERRUN         0x10000000
123
124 /* Clock frequencies for different speeds */
125 #define ZYNQ_GEM_FREQUENCY_10   2500000UL
126 #define ZYNQ_GEM_FREQUENCY_100  25000000UL
127 #define ZYNQ_GEM_FREQUENCY_1000 125000000UL
128
129 /* Device registers */
130 struct zynq_gem_regs {
131         u32 nwctrl; /* 0x0 - Network Control reg */
132         u32 nwcfg; /* 0x4 - Network Config reg */
133         u32 nwsr; /* 0x8 - Network Status reg */
134         u32 reserved1;
135         u32 dmacr; /* 0x10 - DMA Control reg */
136         u32 txsr; /* 0x14 - TX Status reg */
137         u32 rxqbase; /* 0x18 - RX Q Base address reg */
138         u32 txqbase; /* 0x1c - TX Q Base address reg */
139         u32 rxsr; /* 0x20 - RX Status reg */
140         u32 reserved2[2];
141         u32 idr; /* 0x2c - Interrupt Disable reg */
142         u32 reserved3;
143         u32 phymntnc; /* 0x34 - Phy Maintaince reg */
144         u32 reserved4[18];
145         u32 hashl; /* 0x80 - Hash Low address reg */
146         u32 hashh; /* 0x84 - Hash High address reg */
147 #define LADDR_LOW       0
148 #define LADDR_HIGH      1
149         u32 laddr[4][LADDR_HIGH + 1]; /* 0x8c - Specific1 addr low/high reg */
150         u32 match[4]; /* 0xa8 - Type ID1 Match reg */
151         u32 reserved6[18];
152 #define STAT_SIZE       44
153         u32 stat[STAT_SIZE]; /* 0x100 - Octects transmitted Low reg */
154         u32 reserved9[20];
155         u32 pcscntrl;
156         u32 rserved12[36];
157         u32 dcfg6; /* 0x294 Design config reg6 */
158         u32 reserved7[106];
159         u32 transmit_q1_ptr; /* 0x440 - Transmit priority queue 1 */
160         u32 reserved8[15];
161         u32 receive_q1_ptr; /* 0x480 - Receive priority queue 1 */
162         u32 reserved10[17];
163         u32 upper_txqbase; /* 0x4C8 - Upper tx_q base addr */
164         u32 reserved11[2];
165         u32 upper_rxqbase; /* 0x4D4 - Upper rx_q base addr */
166 };
167
168 /* BD descriptors */
169 struct emac_bd {
170         u32 addr; /* Next descriptor pointer */
171         u32 status;
172 #if defined(CONFIG_PHYS_64BIT)
173         u32 addr_hi;
174         u32 reserved;
175 #endif
176 };
177
178 /* Reduce amount of BUFs if you have limited amount of memory */
179 #define RX_BUF 32
180 /* Page table entries are set to 1MB, or multiples of 1MB
181  * (not < 1MB). driver uses less bd's so use 1MB bdspace.
182  */
183 #define BD_SPACE        0x100000
184 /* BD separation space */
185 #define BD_SEPRN_SPACE  (RX_BUF * sizeof(struct emac_bd))
186
187 /* Setup the first free TX descriptor */
188 #define TX_FREE_DESC    2
189
190 /* Initialized, rxbd_current, rx_first_buf must be 0 after init */
191 struct zynq_gem_priv {
192         struct emac_bd *tx_bd;
193         struct emac_bd *rx_bd;
194         char *rxbuffers;
195         u32 rxbd_current;
196         u32 rx_first_buf;
197         int phyaddr;
198         int init;
199         struct zynq_gem_regs *iobase;
200         phy_interface_t interface;
201         struct phy_device *phydev;
202         ofnode phy_of_node;
203         struct mii_dev *bus;
204         struct clk clk;
205         u32 max_speed;
206         bool int_pcs;
207         bool dma_64bit;
208 };
209
210 static int phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
211                         u32 op, u16 *data)
212 {
213         u32 mgtcr;
214         struct zynq_gem_regs *regs = priv->iobase;
215         int err;
216
217         err = wait_for_bit_le32(&regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
218                                 true, 20000, false);
219         if (err)
220                 return err;
221
222         /* Construct mgtcr mask for the operation */
223         mgtcr = ZYNQ_GEM_PHYMNTNC_OP_MASK | op |
224                 (phy_addr << ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK) |
225                 (regnum << ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK) | *data;
226
227         /* Write mgtcr and wait for completion */
228         writel(mgtcr, &regs->phymntnc);
229
230         err = wait_for_bit_le32(&regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
231                                 true, 20000, false);
232         if (err)
233                 return err;
234
235         if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK)
236                 *data = readl(&regs->phymntnc);
237
238         return 0;
239 }
240
241 static int phyread(struct zynq_gem_priv *priv, u32 phy_addr,
242                    u32 regnum, u16 *val)
243 {
244         int ret;
245
246         ret = phy_setup_op(priv, phy_addr, regnum,
247                            ZYNQ_GEM_PHYMNTNC_OP_R_MASK, val);
248
249         if (!ret)
250                 debug("%s: phy_addr %d, regnum 0x%x, val 0x%x\n", __func__,
251                       phy_addr, regnum, *val);
252
253         return ret;
254 }
255
256 static int phywrite(struct zynq_gem_priv *priv, u32 phy_addr,
257                     u32 regnum, u16 data)
258 {
259         debug("%s: phy_addr %d, regnum 0x%x, data 0x%x\n", __func__, phy_addr,
260               regnum, data);
261
262         return phy_setup_op(priv, phy_addr, regnum,
263                             ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data);
264 }
265
266 static int zynq_gem_setup_mac(struct udevice *dev)
267 {
268         u32 i, macaddrlow, macaddrhigh;
269         struct eth_pdata *pdata = dev_get_platdata(dev);
270         struct zynq_gem_priv *priv = dev_get_priv(dev);
271         struct zynq_gem_regs *regs = priv->iobase;
272
273         /* Set the MAC bits [31:0] in BOT */
274         macaddrlow = pdata->enetaddr[0];
275         macaddrlow |= pdata->enetaddr[1] << 8;
276         macaddrlow |= pdata->enetaddr[2] << 16;
277         macaddrlow |= pdata->enetaddr[3] << 24;
278
279         /* Set MAC bits [47:32] in TOP */
280         macaddrhigh = pdata->enetaddr[4];
281         macaddrhigh |= pdata->enetaddr[5] << 8;
282
283         for (i = 0; i < 4; i++) {
284                 writel(0, &regs->laddr[i][LADDR_LOW]);
285                 writel(0, &regs->laddr[i][LADDR_HIGH]);
286                 /* Do not use MATCHx register */
287                 writel(0, &regs->match[i]);
288         }
289
290         writel(macaddrlow, &regs->laddr[0][LADDR_LOW]);
291         writel(macaddrhigh, &regs->laddr[0][LADDR_HIGH]);
292
293         return 0;
294 }
295
296 static int zynq_phy_init(struct udevice *dev)
297 {
298         int ret;
299         struct zynq_gem_priv *priv = dev_get_priv(dev);
300         struct zynq_gem_regs *regs = priv->iobase;
301         const u32 supported = SUPPORTED_10baseT_Half |
302                         SUPPORTED_10baseT_Full |
303                         SUPPORTED_100baseT_Half |
304                         SUPPORTED_100baseT_Full |
305                         SUPPORTED_1000baseT_Half |
306                         SUPPORTED_1000baseT_Full;
307
308         /* Enable only MDIO bus */
309         writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, &regs->nwctrl);
310
311         priv->phydev = phy_connect(priv->bus, priv->phyaddr, dev,
312                                    priv->interface);
313         if (!priv->phydev)
314                 return -ENODEV;
315
316         if (priv->max_speed) {
317                 ret = phy_set_supported(priv->phydev, priv->max_speed);
318                 if (ret)
319                         return ret;
320         }
321
322         priv->phydev->supported &= supported | ADVERTISED_Pause |
323                                   ADVERTISED_Asym_Pause;
324
325         priv->phydev->advertising = priv->phydev->supported;
326         priv->phydev->node = priv->phy_of_node;
327
328         return phy_config(priv->phydev);
329 }
330
331 static int zynq_gem_init(struct udevice *dev)
332 {
333         u32 i, nwconfig;
334         int ret;
335         unsigned long clk_rate = 0;
336         struct zynq_gem_priv *priv = dev_get_priv(dev);
337         struct zynq_gem_regs *regs = priv->iobase;
338         struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC];
339         struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2];
340
341         if (readl(&regs->dcfg6) & ZYNQ_GEM_DCFG_DBG6_DMA_64B)
342                 priv->dma_64bit = true;
343         else
344                 priv->dma_64bit = false;
345
346 #if defined(CONFIG_PHYS_64BIT)
347         if (!priv->dma_64bit) {
348                 printf("ERR: %s: Using 64-bit DMA but HW doesn't support it\n",
349                        __func__);
350                 return -EINVAL;
351         }
352 #else
353         if (priv->dma_64bit)
354                 debug("WARN: %s: Not using 64-bit dma even HW supports it\n",
355                       __func__);
356 #endif
357
358         if (!priv->init) {
359                 /* Disable all interrupts */
360                 writel(0xFFFFFFFF, &regs->idr);
361
362                 /* Disable the receiver & transmitter */
363                 writel(0, &regs->nwctrl);
364                 writel(0, &regs->txsr);
365                 writel(0, &regs->rxsr);
366                 writel(0, &regs->phymntnc);
367
368                 /* Clear the Hash registers for the mac address
369                  * pointed by AddressPtr
370                  */
371                 writel(0x0, &regs->hashl);
372                 /* Write bits [63:32] in TOP */
373                 writel(0x0, &regs->hashh);
374
375                 /* Clear all counters */
376                 for (i = 0; i < STAT_SIZE; i++)
377                         readl(&regs->stat[i]);
378
379                 /* Setup RxBD space */
380                 memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));
381
382                 for (i = 0; i < RX_BUF; i++) {
383                         priv->rx_bd[i].status = 0xF0000000;
384                         priv->rx_bd[i].addr =
385                                         (lower_32_bits((ulong)(priv->rxbuffers)
386                                                         + (i * PKTSIZE_ALIGN)));
387 #if defined(CONFIG_PHYS_64BIT)
388                         priv->rx_bd[i].addr_hi =
389                                         (upper_32_bits((ulong)(priv->rxbuffers)
390                                                         + (i * PKTSIZE_ALIGN)));
391 #endif
392         }
393                 /* WRAP bit to last BD */
394                 priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
395                 /* Write RxBDs to IP */
396                 writel(lower_32_bits((ulong)priv->rx_bd), &regs->rxqbase);
397 #if defined(CONFIG_PHYS_64BIT)
398                 writel(upper_32_bits((ulong)priv->rx_bd), &regs->upper_rxqbase);
399 #endif
400
401                 /* Setup for DMA Configuration register */
402                 writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
403
404                 /* Setup for Network Control register, MDIO, Rx and Tx enable */
405                 setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK);
406
407                 /* Disable the second priority queue */
408                 dummy_tx_bd->addr = 0;
409 #if defined(CONFIG_PHYS_64BIT)
410                 dummy_tx_bd->addr_hi = 0;
411 #endif
412                 dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
413                                 ZYNQ_GEM_TXBUF_LAST_MASK|
414                                 ZYNQ_GEM_TXBUF_USED_MASK;
415
416                 dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
417                                 ZYNQ_GEM_RXBUF_NEW_MASK;
418 #if defined(CONFIG_PHYS_64BIT)
419                 dummy_rx_bd->addr_hi = 0;
420 #endif
421                 dummy_rx_bd->status = 0;
422
423                 writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
424                 writel((ulong)dummy_rx_bd, &regs->receive_q1_ptr);
425
426                 priv->init++;
427         }
428
429         ret = phy_startup(priv->phydev);
430         if (ret)
431                 return ret;
432
433         if (!priv->phydev->link) {
434                 printf("%s: No link.\n", priv->phydev->dev->name);
435                 return -1;
436         }
437
438         nwconfig = ZYNQ_GEM_NWCFG_INIT;
439
440         /*
441          * Set SGMII enable PCS selection only if internal PCS/PMA
442          * core is used and interface is SGMII.
443          */
444         if (priv->interface == PHY_INTERFACE_MODE_SGMII &&
445             priv->int_pcs) {
446                 nwconfig |= ZYNQ_GEM_NWCFG_SGMII_ENBL |
447                             ZYNQ_GEM_NWCFG_PCS_SEL;
448 #ifdef CONFIG_ARM64
449                 writel(readl(&regs->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL,
450                        &regs->pcscntrl);
451 #endif
452         }
453
454         switch (priv->phydev->speed) {
455         case SPEED_1000:
456                 writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED1000,
457                        &regs->nwcfg);
458                 clk_rate = ZYNQ_GEM_FREQUENCY_1000;
459                 break;
460         case SPEED_100:
461                 writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED100,
462                        &regs->nwcfg);
463                 clk_rate = ZYNQ_GEM_FREQUENCY_100;
464                 break;
465         case SPEED_10:
466                 clk_rate = ZYNQ_GEM_FREQUENCY_10;
467                 break;
468         }
469
470         ret = clk_set_rate(&priv->clk, clk_rate);
471         if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) {
472                 dev_err(dev, "failed to set tx clock rate\n");
473                 return ret;
474         }
475
476         ret = clk_enable(&priv->clk);
477         if (ret && ret != -ENOSYS) {
478                 dev_err(dev, "failed to enable tx clock\n");
479                 return ret;
480         }
481
482         setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
483                                         ZYNQ_GEM_NWCTRL_TXEN_MASK);
484
485         return 0;
486 }
487
488 static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
489 {
490         dma_addr_t addr;
491         u32 size;
492         struct zynq_gem_priv *priv = dev_get_priv(dev);
493         struct zynq_gem_regs *regs = priv->iobase;
494         struct emac_bd *current_bd = &priv->tx_bd[1];
495
496         /* Setup Tx BD */
497         memset(priv->tx_bd, 0, sizeof(struct emac_bd));
498
499         priv->tx_bd->addr = lower_32_bits((ulong)ptr);
500 #if defined(CONFIG_PHYS_64BIT)
501         priv->tx_bd->addr_hi = upper_32_bits((ulong)ptr);
502 #endif
503         priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) |
504                                ZYNQ_GEM_TXBUF_LAST_MASK;
505         /* Dummy descriptor to mark it as the last in descriptor chain */
506         current_bd->addr = 0x0;
507 #if defined(CONFIG_PHYS_64BIT)
508         current_bd->addr_hi = 0x0;
509 #endif
510         current_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK |
511                              ZYNQ_GEM_TXBUF_LAST_MASK|
512                              ZYNQ_GEM_TXBUF_USED_MASK;
513
514         /* setup BD */
515         writel(lower_32_bits((ulong)priv->tx_bd), &regs->txqbase);
516 #if defined(CONFIG_PHYS_64BIT)
517         writel(upper_32_bits((ulong)priv->tx_bd), &regs->upper_txqbase);
518 #endif
519
520         addr = (ulong) ptr;
521         addr &= ~(ARCH_DMA_MINALIGN - 1);
522         size = roundup(len, ARCH_DMA_MINALIGN);
523         flush_dcache_range(addr, addr + size);
524         barrier();
525
526         /* Start transmit */
527         setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK);
528
529         /* Read TX BD status */
530         if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED)
531                 printf("TX buffers exhausted in mid frame\n");
532
533         return wait_for_bit_le32(&regs->txsr, ZYNQ_GEM_TSR_DONE,
534                                  true, 20000, true);
535 }
536
537 /* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */
538 static int zynq_gem_recv(struct udevice *dev, int flags, uchar **packetp)
539 {
540         int frame_len;
541         dma_addr_t addr;
542         struct zynq_gem_priv *priv = dev_get_priv(dev);
543         struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current];
544
545         if (!(current_bd->addr & ZYNQ_GEM_RXBUF_NEW_MASK))
546                 return -1;
547
548         if (!(current_bd->status &
549                         (ZYNQ_GEM_RXBUF_SOF_MASK | ZYNQ_GEM_RXBUF_EOF_MASK))) {
550                 printf("GEM: SOF or EOF not set for last buffer received!\n");
551                 return -1;
552         }
553
554         frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK;
555         if (!frame_len) {
556                 printf("%s: Zero size packet?\n", __func__);
557                 return -1;
558         }
559
560 #if defined(CONFIG_PHYS_64BIT)
561         addr = (dma_addr_t)((current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK)
562                       | ((dma_addr_t)current_bd->addr_hi << 32));
563 #else
564         addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK;
565 #endif
566         addr &= ~(ARCH_DMA_MINALIGN - 1);
567
568         *packetp = (uchar *)(uintptr_t)addr;
569
570         invalidate_dcache_range(addr, addr + roundup(PKTSIZE_ALIGN, ARCH_DMA_MINALIGN));
571         barrier();
572
573         return frame_len;
574 }
575
576 static int zynq_gem_free_pkt(struct udevice *dev, uchar *packet, int length)
577 {
578         struct zynq_gem_priv *priv = dev_get_priv(dev);
579         struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current];
580         struct emac_bd *first_bd;
581
582         if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) {
583                 priv->rx_first_buf = priv->rxbd_current;
584         } else {
585                 current_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK;
586                 current_bd->status = 0xF0000000; /* FIXME */
587         }
588
589         if (current_bd->status & ZYNQ_GEM_RXBUF_EOF_MASK) {
590                 first_bd = &priv->rx_bd[priv->rx_first_buf];
591                 first_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK;
592                 first_bd->status = 0xF0000000;
593         }
594
595         if ((++priv->rxbd_current) >= RX_BUF)
596                 priv->rxbd_current = 0;
597
598         return 0;
599 }
600
601 static void zynq_gem_halt(struct udevice *dev)
602 {
603         struct zynq_gem_priv *priv = dev_get_priv(dev);
604         struct zynq_gem_regs *regs = priv->iobase;
605
606         clrsetbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
607                                                 ZYNQ_GEM_NWCTRL_TXEN_MASK, 0);
608 }
609
610 __weak int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
611 {
612         return -ENOSYS;
613 }
614
615 static int zynq_gem_read_rom_mac(struct udevice *dev)
616 {
617         struct eth_pdata *pdata = dev_get_platdata(dev);
618
619         if (!pdata)
620                 return -ENOSYS;
621
622         return zynq_board_read_rom_ethaddr(pdata->enetaddr);
623 }
624
625 static int zynq_gem_miiphy_read(struct mii_dev *bus, int addr,
626                                 int devad, int reg)
627 {
628         struct zynq_gem_priv *priv = bus->priv;
629         int ret;
630         u16 val = 0;
631
632         ret = phyread(priv, addr, reg, &val);
633         debug("%s 0x%x, 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val, ret);
634         return val;
635 }
636
637 static int zynq_gem_miiphy_write(struct mii_dev *bus, int addr, int devad,
638                                  int reg, u16 value)
639 {
640         struct zynq_gem_priv *priv = bus->priv;
641
642         debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, value);
643         return phywrite(priv, addr, reg, value);
644 }
645
646 static int zynq_gem_probe(struct udevice *dev)
647 {
648         void *bd_space;
649         struct zynq_gem_priv *priv = dev_get_priv(dev);
650         int ret;
651
652         /* Align rxbuffers to ARCH_DMA_MINALIGN */
653         priv->rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN);
654         if (!priv->rxbuffers)
655                 return -ENOMEM;
656
657         memset(priv->rxbuffers, 0, RX_BUF * PKTSIZE_ALIGN);
658         ulong addr = (ulong)priv->rxbuffers;
659         flush_dcache_range(addr, addr + roundup(RX_BUF * PKTSIZE_ALIGN, ARCH_DMA_MINALIGN));
660         barrier();
661
662         /* Align bd_space to MMU_SECTION_SHIFT */
663         bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE);
664         if (!bd_space)
665                 return -ENOMEM;
666
667         mmu_set_region_dcache_behaviour((phys_addr_t)bd_space,
668                                         BD_SPACE, DCACHE_OFF);
669
670         /* Initialize the bd spaces for tx and rx bd's */
671         priv->tx_bd = (struct emac_bd *)bd_space;
672         priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE);
673
674         ret = clk_get_by_name(dev, "tx_clk", &priv->clk);
675         if (ret < 0) {
676                 dev_err(dev, "failed to get clock\n");
677                 return -EINVAL;
678         }
679
680         priv->bus = mdio_alloc();
681         priv->bus->read = zynq_gem_miiphy_read;
682         priv->bus->write = zynq_gem_miiphy_write;
683         priv->bus->priv = priv;
684
685         ret = mdio_register_seq(priv->bus, dev->seq);
686         if (ret)
687                 return ret;
688
689         return zynq_phy_init(dev);
690 }
691
692 static int zynq_gem_remove(struct udevice *dev)
693 {
694         struct zynq_gem_priv *priv = dev_get_priv(dev);
695
696         free(priv->phydev);
697         mdio_unregister(priv->bus);
698         mdio_free(priv->bus);
699
700         return 0;
701 }
702
703 static const struct eth_ops zynq_gem_ops = {
704         .start                  = zynq_gem_init,
705         .send                   = zynq_gem_send,
706         .recv                   = zynq_gem_recv,
707         .free_pkt               = zynq_gem_free_pkt,
708         .stop                   = zynq_gem_halt,
709         .write_hwaddr           = zynq_gem_setup_mac,
710         .read_rom_hwaddr        = zynq_gem_read_rom_mac,
711 };
712
713 static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
714 {
715         struct eth_pdata *pdata = dev_get_platdata(dev);
716         struct zynq_gem_priv *priv = dev_get_priv(dev);
717         struct ofnode_phandle_args phandle_args;
718         const char *phy_mode;
719
720         pdata->iobase = (phys_addr_t)dev_read_addr(dev);
721         priv->iobase = (struct zynq_gem_regs *)pdata->iobase;
722         /* Hardcode for now */
723         priv->phyaddr = -1;
724
725         if (!dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
726                                         &phandle_args)) {
727                 debug("phy-handle does exist %s\n", dev->name);
728                 priv->phyaddr = ofnode_read_u32_default(phandle_args.node,
729                                                         "reg", -1);
730                 priv->phy_of_node = phandle_args.node;
731                 priv->max_speed = ofnode_read_u32_default(phandle_args.node,
732                                                           "max-speed",
733                                                           SPEED_1000);
734         }
735
736         phy_mode = dev_read_prop(dev, "phy-mode", NULL);
737         if (phy_mode)
738                 pdata->phy_interface = phy_get_interface_by_name(phy_mode);
739         if (pdata->phy_interface == -1) {
740                 debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
741                 return -EINVAL;
742         }
743         priv->interface = pdata->phy_interface;
744
745         priv->int_pcs = dev_read_bool(dev, "is-internal-pcspma");
746
747         printf("ZYNQ GEM: %lx, phyaddr %x, interface %s\n", (ulong)priv->iobase,
748                priv->phyaddr, phy_string_for_interface(priv->interface));
749
750         return 0;
751 }
752
753 static const struct udevice_id zynq_gem_ids[] = {
754         { .compatible = "cdns,versal-gem" },
755         { .compatible = "cdns,zynqmp-gem" },
756         { .compatible = "cdns,zynq-gem" },
757         { .compatible = "cdns,gem" },
758         { }
759 };
760
761 U_BOOT_DRIVER(zynq_gem) = {
762         .name   = "zynq_gem",
763         .id     = UCLASS_ETH,
764         .of_match = zynq_gem_ids,
765         .ofdata_to_platdata = zynq_gem_ofdata_to_platdata,
766         .probe  = zynq_gem_probe,
767         .remove = zynq_gem_remove,
768         .ops    = &zynq_gem_ops,
769         .priv_auto_alloc_size = sizeof(struct zynq_gem_priv),
770         .platdata_auto_alloc_size = sizeof(struct eth_pdata),
771 };
This page took 0.079811 seconds and 4 git commands to generate.