net: macb: add support for faster clk rates
[oweals/u-boot.git] / drivers / net / ftgmac100.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Faraday FTGMAC100 Ethernet
4  *
5  * (C) Copyright 2009 Faraday Technology
6  * Po-Yu Chuang <ratbert@faraday-tech.com>
7  *
8  * (C) Copyright 2010 Andes Technology
9  * Macpaul Lin <macpaul@andestech.com>
10  *
11  * Copyright (C) 2018, IBM Corporation.
12  */
13
14 #include <clk.h>
15 #include <dm.h>
16 #include <miiphy.h>
17 #include <net.h>
18 #include <wait_bit.h>
19 #include <linux/io.h>
20 #include <linux/iopoll.h>
21
22 #include "ftgmac100.h"
23
24 /* Min frame ethernet frame size without FCS */
25 #define ETH_ZLEN                        60
26
27 /* Receive Buffer Size Register - HW default is 0x640 */
28 #define FTGMAC100_RBSR_DEFAULT          0x640
29
30 /* PKTBUFSTX/PKTBUFSRX must both be power of 2 */
31 #define PKTBUFSTX       4       /* must be power of 2 */
32
33 /* Timeout for transmit */
34 #define FTGMAC100_TX_TIMEOUT_MS         1000
35
36 /* Timeout for a mdio read/write operation */
37 #define FTGMAC100_MDIO_TIMEOUT_USEC     10000
38
39 /*
40  * MDC clock cycle threshold
41  *
42  * 20us * 100 = 2ms > (1 / 2.5Mhz) * 0x34
43  */
44 #define MDC_CYCTHR                      0x34
45
46 /*
47  * ftgmac100 model variants
48  */
49 enum ftgmac100_model {
50         FTGMAC100_MODEL_FARADAY,
51         FTGMAC100_MODEL_ASPEED,
52 };
53
54 /**
55  * struct ftgmac100_data - private data for the FTGMAC100 driver
56  *
57  * @iobase: The base address of the hardware registers
58  * @txdes: The array of transmit descriptors
59  * @rxdes: The array of receive descriptors
60  * @tx_index: Transmit descriptor index in @txdes
61  * @rx_index: Receive descriptor index in @rxdes
62  * @phy_addr: The PHY interface address to use
63  * @phydev: The PHY device backing the MAC
64  * @bus: The mdio bus
65  * @phy_mode: The mode of the PHY interface (rgmii, rmii, ...)
66  * @max_speed: Maximum speed of Ethernet connection supported by MAC
67  * @clks: The bulk of clocks assigned to the device in the DT
68  * @rxdes0_edorr_mask: The bit number identifying the end of the RX ring buffer
69  * @txdes0_edotr_mask: The bit number identifying the end of the TX ring buffer
70  */
71 struct ftgmac100_data {
72         struct ftgmac100 *iobase;
73
74         struct ftgmac100_txdes txdes[PKTBUFSTX];
75         struct ftgmac100_rxdes rxdes[PKTBUFSRX];
76         int tx_index;
77         int rx_index;
78
79         u32 phy_addr;
80         struct phy_device *phydev;
81         struct mii_dev *bus;
82         u32 phy_mode;
83         u32 max_speed;
84
85         struct clk_bulk clks;
86
87         /* End of RX/TX ring buffer bits. Depend on model */
88         u32 rxdes0_edorr_mask;
89         u32 txdes0_edotr_mask;
90 };
91
92 /*
93  * struct mii_bus functions
94  */
95 static int ftgmac100_mdio_read(struct mii_dev *bus, int phy_addr, int dev_addr,
96                                int reg_addr)
97 {
98         struct ftgmac100_data *priv = bus->priv;
99         struct ftgmac100 *ftgmac100 = priv->iobase;
100         int phycr;
101         int data;
102         int ret;
103
104         phycr = FTGMAC100_PHYCR_MDC_CYCTHR(MDC_CYCTHR) |
105                 FTGMAC100_PHYCR_PHYAD(phy_addr) |
106                 FTGMAC100_PHYCR_REGAD(reg_addr) |
107                 FTGMAC100_PHYCR_MIIRD;
108         writel(phycr, &ftgmac100->phycr);
109
110         ret = readl_poll_timeout(&ftgmac100->phycr, phycr,
111                                  !(phycr & FTGMAC100_PHYCR_MIIRD),
112                                  FTGMAC100_MDIO_TIMEOUT_USEC);
113         if (ret) {
114                 pr_err("%s: mdio read failed (phy:%d reg:%x)\n",
115                        priv->phydev->dev->name, phy_addr, reg_addr);
116                 return ret;
117         }
118
119         data = readl(&ftgmac100->phydata);
120
121         return FTGMAC100_PHYDATA_MIIRDATA(data);
122 }
123
124 static int ftgmac100_mdio_write(struct mii_dev *bus, int phy_addr, int dev_addr,
125                                 int reg_addr, u16 value)
126 {
127         struct ftgmac100_data *priv = bus->priv;
128         struct ftgmac100 *ftgmac100 = priv->iobase;
129         int phycr;
130         int data;
131         int ret;
132
133         phycr = FTGMAC100_PHYCR_MDC_CYCTHR(MDC_CYCTHR) |
134                 FTGMAC100_PHYCR_PHYAD(phy_addr) |
135                 FTGMAC100_PHYCR_REGAD(reg_addr) |
136                 FTGMAC100_PHYCR_MIIWR;
137         data = FTGMAC100_PHYDATA_MIIWDATA(value);
138
139         writel(data, &ftgmac100->phydata);
140         writel(phycr, &ftgmac100->phycr);
141
142         ret = readl_poll_timeout(&ftgmac100->phycr, phycr,
143                                  !(phycr & FTGMAC100_PHYCR_MIIWR),
144                                  FTGMAC100_MDIO_TIMEOUT_USEC);
145         if (ret) {
146                 pr_err("%s: mdio write failed (phy:%d reg:%x)\n",
147                        priv->phydev->dev->name, phy_addr, reg_addr);
148         }
149
150         return ret;
151 }
152
153 static int ftgmac100_mdio_init(struct udevice *dev)
154 {
155         struct ftgmac100_data *priv = dev_get_priv(dev);
156         struct mii_dev *bus;
157         int ret;
158
159         bus = mdio_alloc();
160         if (!bus)
161                 return -ENOMEM;
162
163         bus->read  = ftgmac100_mdio_read;
164         bus->write = ftgmac100_mdio_write;
165         bus->priv  = priv;
166
167         ret = mdio_register_seq(bus, dev->seq);
168         if (ret) {
169                 free(bus);
170                 return ret;
171         }
172
173         priv->bus = bus;
174
175         return 0;
176 }
177
178 static int ftgmac100_phy_adjust_link(struct ftgmac100_data *priv)
179 {
180         struct ftgmac100 *ftgmac100 = priv->iobase;
181         struct phy_device *phydev = priv->phydev;
182         u32 maccr;
183
184         if (!phydev->link) {
185                 dev_err(phydev->dev, "No link\n");
186                 return -EREMOTEIO;
187         }
188
189         /* read MAC control register and clear related bits */
190         maccr = readl(&ftgmac100->maccr) &
191                 ~(FTGMAC100_MACCR_GIGA_MODE |
192                   FTGMAC100_MACCR_FAST_MODE |
193                   FTGMAC100_MACCR_FULLDUP);
194
195         if (phy_interface_is_rgmii(phydev) && phydev->speed == 1000)
196                 maccr |= FTGMAC100_MACCR_GIGA_MODE;
197
198         if (phydev->speed == 100)
199                 maccr |= FTGMAC100_MACCR_FAST_MODE;
200
201         if (phydev->duplex)
202                 maccr |= FTGMAC100_MACCR_FULLDUP;
203
204         /* update MII config into maccr */
205         writel(maccr, &ftgmac100->maccr);
206
207         return 0;
208 }
209
210 static int ftgmac100_phy_init(struct udevice *dev)
211 {
212         struct ftgmac100_data *priv = dev_get_priv(dev);
213         struct phy_device *phydev;
214         int ret;
215
216         phydev = phy_connect(priv->bus, priv->phy_addr, dev, priv->phy_mode);
217         if (!phydev)
218                 return -ENODEV;
219
220         phydev->supported &= PHY_GBIT_FEATURES;
221         if (priv->max_speed) {
222                 ret = phy_set_supported(phydev, priv->max_speed);
223                 if (ret)
224                         return ret;
225         }
226         phydev->advertising = phydev->supported;
227         priv->phydev = phydev;
228         phy_config(phydev);
229
230         return 0;
231 }
232
233 /*
234  * Reset MAC
235  */
236 static void ftgmac100_reset(struct ftgmac100_data *priv)
237 {
238         struct ftgmac100 *ftgmac100 = priv->iobase;
239
240         debug("%s()\n", __func__);
241
242         setbits_le32(&ftgmac100->maccr, FTGMAC100_MACCR_SW_RST);
243
244         while (readl(&ftgmac100->maccr) & FTGMAC100_MACCR_SW_RST)
245                 ;
246 }
247
248 /*
249  * Set MAC address
250  */
251 static int ftgmac100_set_mac(struct ftgmac100_data *priv,
252                              const unsigned char *mac)
253 {
254         struct ftgmac100 *ftgmac100 = priv->iobase;
255         unsigned int maddr = mac[0] << 8 | mac[1];
256         unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
257
258         debug("%s(%x %x)\n", __func__, maddr, laddr);
259
260         writel(maddr, &ftgmac100->mac_madr);
261         writel(laddr, &ftgmac100->mac_ladr);
262
263         return 0;
264 }
265
266 /*
267  * disable transmitter, receiver
268  */
269 static void ftgmac100_stop(struct udevice *dev)
270 {
271         struct ftgmac100_data *priv = dev_get_priv(dev);
272         struct ftgmac100 *ftgmac100 = priv->iobase;
273
274         debug("%s()\n", __func__);
275
276         writel(0, &ftgmac100->maccr);
277
278         phy_shutdown(priv->phydev);
279 }
280
281 static int ftgmac100_start(struct udevice *dev)
282 {
283         struct eth_pdata *plat = dev_get_platdata(dev);
284         struct ftgmac100_data *priv = dev_get_priv(dev);
285         struct ftgmac100 *ftgmac100 = priv->iobase;
286         struct phy_device *phydev = priv->phydev;
287         unsigned int maccr;
288         ulong start, end;
289         int ret;
290         int i;
291
292         debug("%s()\n", __func__);
293
294         ftgmac100_reset(priv);
295
296         /* set the ethernet address */
297         ftgmac100_set_mac(priv, plat->enetaddr);
298
299         /* disable all interrupts */
300         writel(0, &ftgmac100->ier);
301
302         /* initialize descriptors */
303         priv->tx_index = 0;
304         priv->rx_index = 0;
305
306         for (i = 0; i < PKTBUFSTX; i++) {
307                 priv->txdes[i].txdes3 = 0;
308                 priv->txdes[i].txdes0 = 0;
309         }
310         priv->txdes[PKTBUFSTX - 1].txdes0 = priv->txdes0_edotr_mask;
311
312         start = (ulong)&priv->txdes[0];
313         end = start + roundup(sizeof(priv->txdes), ARCH_DMA_MINALIGN);
314         flush_dcache_range(start, end);
315
316         for (i = 0; i < PKTBUFSRX; i++) {
317                 priv->rxdes[i].rxdes3 = (unsigned int)net_rx_packets[i];
318                 priv->rxdes[i].rxdes0 = 0;
319         }
320         priv->rxdes[PKTBUFSRX - 1].rxdes0 = priv->rxdes0_edorr_mask;
321
322         start = (ulong)&priv->rxdes[0];
323         end = start + roundup(sizeof(priv->rxdes), ARCH_DMA_MINALIGN);
324         flush_dcache_range(start, end);
325
326         /* transmit ring */
327         writel((u32)priv->txdes, &ftgmac100->txr_badr);
328
329         /* receive ring */
330         writel((u32)priv->rxdes, &ftgmac100->rxr_badr);
331
332         /* poll receive descriptor automatically */
333         writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);
334
335         /* config receive buffer size register */
336         writel(FTGMAC100_RBSR_SIZE(FTGMAC100_RBSR_DEFAULT), &ftgmac100->rbsr);
337
338         /* enable transmitter, receiver */
339         maccr = FTGMAC100_MACCR_TXMAC_EN |
340                 FTGMAC100_MACCR_RXMAC_EN |
341                 FTGMAC100_MACCR_TXDMA_EN |
342                 FTGMAC100_MACCR_RXDMA_EN |
343                 FTGMAC100_MACCR_CRC_APD |
344                 FTGMAC100_MACCR_FULLDUP |
345                 FTGMAC100_MACCR_RX_RUNT |
346                 FTGMAC100_MACCR_RX_BROADPKT;
347
348         writel(maccr, &ftgmac100->maccr);
349
350         ret = phy_startup(phydev);
351         if (ret) {
352                 dev_err(phydev->dev, "Could not start PHY\n");
353                 return ret;
354         }
355
356         ret = ftgmac100_phy_adjust_link(priv);
357         if (ret) {
358                 dev_err(phydev->dev,  "Could not adjust link\n");
359                 return ret;
360         }
361
362         printf("%s: link up, %d Mbps %s-duplex mac:%pM\n", phydev->dev->name,
363                phydev->speed, phydev->duplex ? "full" : "half", plat->enetaddr);
364
365         return 0;
366 }
367
368 static int ftgmac100_free_pkt(struct udevice *dev, uchar *packet, int length)
369 {
370         struct ftgmac100_data *priv = dev_get_priv(dev);
371         struct ftgmac100_rxdes *curr_des = &priv->rxdes[priv->rx_index];
372         ulong des_start = (ulong)curr_des;
373         ulong des_end = des_start +
374                 roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
375
376         /* Release buffer to DMA and flush descriptor */
377         curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
378         flush_dcache_range(des_start, des_end);
379
380         /* Move to next descriptor */
381         priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
382
383         return 0;
384 }
385
386 /*
387  * Get a data block via Ethernet
388  */
389 static int ftgmac100_recv(struct udevice *dev, int flags, uchar **packetp)
390 {
391         struct ftgmac100_data *priv = dev_get_priv(dev);
392         struct ftgmac100_rxdes *curr_des = &priv->rxdes[priv->rx_index];
393         unsigned short rxlen;
394         ulong des_start = (ulong)curr_des;
395         ulong des_end = des_start +
396                 roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
397         ulong data_start = curr_des->rxdes3;
398         ulong data_end;
399
400         invalidate_dcache_range(des_start, des_end);
401
402         if (!(curr_des->rxdes0 & FTGMAC100_RXDES0_RXPKT_RDY))
403                 return -EAGAIN;
404
405         if (curr_des->rxdes0 & (FTGMAC100_RXDES0_RX_ERR |
406                                 FTGMAC100_RXDES0_CRC_ERR |
407                                 FTGMAC100_RXDES0_FTL |
408                                 FTGMAC100_RXDES0_RUNT |
409                                 FTGMAC100_RXDES0_RX_ODD_NB)) {
410                 return -EAGAIN;
411         }
412
413         rxlen = FTGMAC100_RXDES0_VDBC(curr_des->rxdes0);
414
415         debug("%s(): RX buffer %d, %x received\n",
416                __func__, priv->rx_index, rxlen);
417
418         /* Invalidate received data */
419         data_end = data_start + roundup(rxlen, ARCH_DMA_MINALIGN);
420         invalidate_dcache_range(data_start, data_end);
421         *packetp = (uchar *)data_start;
422
423         return rxlen;
424 }
425
426 static u32 ftgmac100_read_txdesc(const void *desc)
427 {
428         const struct ftgmac100_txdes *txdes = desc;
429         ulong des_start = (ulong)txdes;
430         ulong des_end = des_start + roundup(sizeof(*txdes), ARCH_DMA_MINALIGN);
431
432         invalidate_dcache_range(des_start, des_end);
433
434         return txdes->txdes0;
435 }
436
437 BUILD_WAIT_FOR_BIT(ftgmac100_txdone, u32, ftgmac100_read_txdesc)
438
439 /*
440  * Send a data block via Ethernet
441  */
442 static int ftgmac100_send(struct udevice *dev, void *packet, int length)
443 {
444         struct ftgmac100_data *priv = dev_get_priv(dev);
445         struct ftgmac100 *ftgmac100 = priv->iobase;
446         struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index];
447         ulong des_start = (ulong)curr_des;
448         ulong des_end = des_start +
449                 roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
450         ulong data_start;
451         ulong data_end;
452         int rc;
453
454         invalidate_dcache_range(des_start, des_end);
455
456         if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
457                 dev_err(dev, "no TX descriptor available\n");
458                 return -EPERM;
459         }
460
461         debug("%s(%x, %x)\n", __func__, (int)packet, length);
462
463         length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
464
465         curr_des->txdes3 = (unsigned int)packet;
466
467         /* Flush data to be sent */
468         data_start = curr_des->txdes3;
469         data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
470         flush_dcache_range(data_start, data_end);
471
472         /* Only one segment on TXBUF */
473         curr_des->txdes0 &= priv->txdes0_edotr_mask;
474         curr_des->txdes0 |= FTGMAC100_TXDES0_FTS |
475                             FTGMAC100_TXDES0_LTS |
476                             FTGMAC100_TXDES0_TXBUF_SIZE(length) |
477                             FTGMAC100_TXDES0_TXDMA_OWN ;
478
479         /* Flush modified buffer descriptor */
480         flush_dcache_range(des_start, des_end);
481
482         /* Start transmit */
483         writel(1, &ftgmac100->txpd);
484
485         rc = wait_for_bit_ftgmac100_txdone(curr_des,
486                                            FTGMAC100_TXDES0_TXDMA_OWN, false,
487                                            FTGMAC100_TX_TIMEOUT_MS, true);
488         if (rc)
489                 return rc;
490
491         debug("%s(): packet sent\n", __func__);
492
493         /* Move to next descriptor */
494         priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX;
495
496         return 0;
497 }
498
499 static int ftgmac100_write_hwaddr(struct udevice *dev)
500 {
501         struct eth_pdata *pdata = dev_get_platdata(dev);
502         struct ftgmac100_data *priv = dev_get_priv(dev);
503
504         return ftgmac100_set_mac(priv, pdata->enetaddr);
505 }
506
507 static int ftgmac100_ofdata_to_platdata(struct udevice *dev)
508 {
509         struct eth_pdata *pdata = dev_get_platdata(dev);
510         struct ftgmac100_data *priv = dev_get_priv(dev);
511         const char *phy_mode;
512
513         pdata->iobase = devfdt_get_addr(dev);
514         pdata->phy_interface = -1;
515         phy_mode = dev_read_string(dev, "phy-mode");
516         if (phy_mode)
517                 pdata->phy_interface = phy_get_interface_by_name(phy_mode);
518         if (pdata->phy_interface == -1) {
519                 dev_err(dev, "Invalid PHY interface '%s'\n", phy_mode);
520                 return -EINVAL;
521         }
522
523         pdata->max_speed = dev_read_u32_default(dev, "max-speed", 0);
524
525         if (dev_get_driver_data(dev) == FTGMAC100_MODEL_ASPEED) {
526                 priv->rxdes0_edorr_mask = BIT(30);
527                 priv->txdes0_edotr_mask = BIT(30);
528         } else {
529                 priv->rxdes0_edorr_mask = BIT(15);
530                 priv->txdes0_edotr_mask = BIT(15);
531         }
532
533         return clk_get_bulk(dev, &priv->clks);
534 }
535
536 static int ftgmac100_probe(struct udevice *dev)
537 {
538         struct eth_pdata *pdata = dev_get_platdata(dev);
539         struct ftgmac100_data *priv = dev_get_priv(dev);
540         int ret;
541
542         priv->iobase = (struct ftgmac100 *)pdata->iobase;
543         priv->phy_mode = pdata->phy_interface;
544         priv->max_speed = pdata->max_speed;
545         priv->phy_addr = 0;
546
547         ret = clk_enable_bulk(&priv->clks);
548         if (ret)
549                 goto out;
550
551         ret = ftgmac100_mdio_init(dev);
552         if (ret) {
553                 dev_err(dev, "Failed to initialize mdiobus: %d\n", ret);
554                 goto out;
555         }
556
557         ret = ftgmac100_phy_init(dev);
558         if (ret) {
559                 dev_err(dev, "Failed to initialize PHY: %d\n", ret);
560                 goto out;
561         }
562
563 out:
564         if (ret)
565                 clk_release_bulk(&priv->clks);
566
567         return ret;
568 }
569
570 static int ftgmac100_remove(struct udevice *dev)
571 {
572         struct ftgmac100_data *priv = dev_get_priv(dev);
573
574         free(priv->phydev);
575         mdio_unregister(priv->bus);
576         mdio_free(priv->bus);
577         clk_release_bulk(&priv->clks);
578
579         return 0;
580 }
581
582 static const struct eth_ops ftgmac100_ops = {
583         .start  = ftgmac100_start,
584         .send   = ftgmac100_send,
585         .recv   = ftgmac100_recv,
586         .stop   = ftgmac100_stop,
587         .free_pkt = ftgmac100_free_pkt,
588         .write_hwaddr = ftgmac100_write_hwaddr,
589 };
590
591 static const struct udevice_id ftgmac100_ids[] = {
592         { .compatible = "faraday,ftgmac100",  .data = FTGMAC100_MODEL_FARADAY },
593         { .compatible = "aspeed,ast2500-mac", .data = FTGMAC100_MODEL_ASPEED  },
594         { }
595 };
596
597 U_BOOT_DRIVER(ftgmac100) = {
598         .name   = "ftgmac100",
599         .id     = UCLASS_ETH,
600         .of_match = ftgmac100_ids,
601         .ofdata_to_platdata = ftgmac100_ofdata_to_platdata,
602         .probe  = ftgmac100_probe,
603         .remove = ftgmac100_remove,
604         .ops    = &ftgmac100_ops,
605         .priv_auto_alloc_size = sizeof(struct ftgmac100_data),
606         .platdata_auto_alloc_size = sizeof(struct eth_pdata),
607         .flags  = DM_FLAG_ALLOC_PRIV_DMA,
608 };