dm: core: Create a new header file for 'compat' features
[platform/kernel/u-boot.git] / drivers / net / ti / am65-cpsw-nuss.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Texas Instruments K3 AM65 Ethernet Switch SubSystem Driver
4  *
5  * Copyright (C) 2019, Texas Instruments, Incorporated
6  *
7  */
8
9 #include <common.h>
10 #include <malloc.h>
11 #include <asm/io.h>
12 #include <asm/processor.h>
13 #include <clk.h>
14 #include <dm.h>
15 #include <dm/device_compat.h>
16 #include <dm/lists.h>
17 #include <dma-uclass.h>
18 #include <dm/of_access.h>
19 #include <miiphy.h>
20 #include <net.h>
21 #include <phy.h>
22 #include <power-domain.h>
23 #include <linux/soc/ti/ti-udma.h>
24
25 #include "cpsw_mdio.h"
26
27 #define AM65_CPSW_CPSWNU_MAX_PORTS 2
28
29 #define AM65_CPSW_SS_BASE               0x0
30 #define AM65_CPSW_SGMII_BASE    0x100
31 #define AM65_CPSW_MDIO_BASE     0xf00
32 #define AM65_CPSW_XGMII_BASE    0x2100
33 #define AM65_CPSW_CPSW_NU_BASE  0x20000
34 #define AM65_CPSW_CPSW_NU_ALE_BASE 0x1e000
35
36 #define AM65_CPSW_CPSW_NU_PORTS_OFFSET  0x1000
37 #define AM65_CPSW_CPSW_NU_PORT_MACSL_OFFSET     0x330
38
39 #define AM65_CPSW_MDIO_BUS_FREQ_DEF 1000000
40
41 #define AM65_CPSW_CTL_REG                       0x4
42 #define AM65_CPSW_STAT_PORT_EN_REG      0x14
43 #define AM65_CPSW_PTYPE_REG             0x18
44
45 #define AM65_CPSW_CTL_REG_P0_ENABLE                     BIT(2)
46 #define AM65_CPSW_CTL_REG_P0_TX_CRC_REMOVE              BIT(13)
47 #define AM65_CPSW_CTL_REG_P0_RX_PAD                     BIT(14)
48
49 #define AM65_CPSW_P0_FLOW_ID_REG                        0x8
50 #define AM65_CPSW_PN_RX_MAXLEN_REG              0x24
51 #define AM65_CPSW_PN_REG_SA_L                   0x308
52 #define AM65_CPSW_PN_REG_SA_H                   0x30c
53
54 #define AM65_CPSW_ALE_CTL_REG                   0x8
55 #define AM65_CPSW_ALE_CTL_REG_ENABLE            BIT(31)
56 #define AM65_CPSW_ALE_CTL_REG_RESET_TBL         BIT(30)
57 #define AM65_CPSW_ALE_CTL_REG_BYPASS            BIT(4)
58 #define AM65_CPSW_ALE_PN_CTL_REG(x)             (0x40 + (x) * 4)
59 #define AM65_CPSW_ALE_PN_CTL_REG_MODE_FORWARD   0x3
60 #define AM65_CPSW_ALE_PN_CTL_REG_MAC_ONLY       BIT(11)
61
62 #define AM65_CPSW_MACSL_CTL_REG                 0x0
63 #define AM65_CPSW_MACSL_CTL_REG_IFCTL_A         BIT(15)
64 #define AM65_CPSW_MACSL_CTL_REG_GIG             BIT(7)
65 #define AM65_CPSW_MACSL_CTL_REG_GMII_EN         BIT(5)
66 #define AM65_CPSW_MACSL_CTL_REG_LOOPBACK        BIT(1)
67 #define AM65_CPSW_MACSL_CTL_REG_FULL_DUPLEX     BIT(0)
68 #define AM65_CPSW_MACSL_RESET_REG               0x8
69 #define AM65_CPSW_MACSL_RESET_REG_RESET         BIT(0)
70 #define AM65_CPSW_MACSL_STATUS_REG              0x4
71 #define AM65_CPSW_MACSL_RESET_REG_PN_IDLE       BIT(31)
72 #define AM65_CPSW_MACSL_RESET_REG_PN_E_IDLE     BIT(30)
73 #define AM65_CPSW_MACSL_RESET_REG_PN_P_IDLE     BIT(29)
74 #define AM65_CPSW_MACSL_RESET_REG_PN_TX_IDLE    BIT(28)
75 #define AM65_CPSW_MACSL_RESET_REG_IDLE_MASK \
76         (AM65_CPSW_MACSL_RESET_REG_PN_IDLE | \
77          AM65_CPSW_MACSL_RESET_REG_PN_E_IDLE | \
78          AM65_CPSW_MACSL_RESET_REG_PN_P_IDLE | \
79          AM65_CPSW_MACSL_RESET_REG_PN_TX_IDLE)
80
81 #define AM65_CPSW_CPPI_PKT_TYPE                 0x7
82
83 struct am65_cpsw_port {
84         fdt_addr_t      port_base;
85         fdt_addr_t      macsl_base;
86         bool            disabled;
87         u32             mac_control;
88 };
89
90 struct am65_cpsw_common {
91         struct udevice          *dev;
92         fdt_addr_t              ss_base;
93         fdt_addr_t              cpsw_base;
94         fdt_addr_t              mdio_base;
95         fdt_addr_t              ale_base;
96         fdt_addr_t              gmii_sel;
97         fdt_addr_t              mac_efuse;
98
99         struct clk              fclk;
100         struct power_domain     pwrdmn;
101
102         u32                     port_num;
103         struct am65_cpsw_port   ports[AM65_CPSW_CPSWNU_MAX_PORTS];
104
105         struct mii_dev          *bus;
106         u32                     bus_freq;
107
108         struct dma              dma_tx;
109         struct dma              dma_rx;
110         u32                     rx_next;
111         u32                     rx_pend;
112         bool                    started;
113 };
114
115 struct am65_cpsw_priv {
116         struct udevice          *dev;
117         struct am65_cpsw_common *cpsw_common;
118         u32                     port_id;
119
120         struct phy_device       *phydev;
121         bool                    has_phy;
122         ofnode                  phy_node;
123         u32                     phy_addr;
124 };
125
126 #ifdef PKTSIZE_ALIGN
127 #define UDMA_RX_BUF_SIZE PKTSIZE_ALIGN
128 #else
129 #define UDMA_RX_BUF_SIZE ALIGN(1522, ARCH_DMA_MINALIGN)
130 #endif
131
132 #ifdef PKTBUFSRX
133 #define UDMA_RX_DESC_NUM PKTBUFSRX
134 #else
135 #define UDMA_RX_DESC_NUM 4
136 #endif
137
138 #define mac_hi(mac)     (((mac)[0] << 0) | ((mac)[1] << 8) |    \
139                          ((mac)[2] << 16) | ((mac)[3] << 24))
140 #define mac_lo(mac)     (((mac)[4] << 0) | ((mac)[5] << 8))
141
142 static void am65_cpsw_set_sl_mac(struct am65_cpsw_port *slave,
143                                  unsigned char *addr)
144 {
145         writel(mac_hi(addr),
146                slave->port_base + AM65_CPSW_PN_REG_SA_H);
147         writel(mac_lo(addr),
148                slave->port_base + AM65_CPSW_PN_REG_SA_L);
149 }
150
151 int am65_cpsw_macsl_reset(struct am65_cpsw_port *slave)
152 {
153         u32 i = 100;
154
155         /* Set the soft reset bit */
156         writel(AM65_CPSW_MACSL_RESET_REG_RESET,
157                slave->macsl_base + AM65_CPSW_MACSL_RESET_REG);
158
159         while ((readl(slave->macsl_base + AM65_CPSW_MACSL_RESET_REG) &
160                 AM65_CPSW_MACSL_RESET_REG_RESET) && i--)
161                 cpu_relax();
162
163         /* Timeout on the reset */
164         return i;
165 }
166
167 static int am65_cpsw_macsl_wait_for_idle(struct am65_cpsw_port *slave)
168 {
169         u32 i = 100;
170
171         while ((readl(slave->macsl_base + AM65_CPSW_MACSL_STATUS_REG) &
172                 AM65_CPSW_MACSL_RESET_REG_IDLE_MASK) && i--)
173                 cpu_relax();
174
175         return i;
176 }
177
178 static int am65_cpsw_update_link(struct am65_cpsw_priv *priv)
179 {
180         struct am65_cpsw_common *common = priv->cpsw_common;
181         struct am65_cpsw_port *port = &common->ports[priv->port_id];
182         struct phy_device *phy = priv->phydev;
183         u32 mac_control = 0;
184
185         if (phy->link) { /* link up */
186                 mac_control = /*AM65_CPSW_MACSL_CTL_REG_LOOPBACK |*/
187                               AM65_CPSW_MACSL_CTL_REG_GMII_EN;
188                 if (phy->speed == 1000)
189                         mac_control |= AM65_CPSW_MACSL_CTL_REG_GIG;
190                 if (phy->duplex == DUPLEX_FULL)
191                         mac_control |= AM65_CPSW_MACSL_CTL_REG_FULL_DUPLEX;
192                 if (phy->speed == 100)
193                         mac_control |= AM65_CPSW_MACSL_CTL_REG_IFCTL_A;
194         }
195
196         if (mac_control == port->mac_control)
197                 goto out;
198
199         if (mac_control) {
200                 printf("link up on port %d, speed %d, %s duplex\n",
201                        priv->port_id, phy->speed,
202                        (phy->duplex == DUPLEX_FULL) ? "full" : "half");
203         } else {
204                 printf("link down on port %d\n", priv->port_id);
205         }
206
207         writel(mac_control, port->macsl_base + AM65_CPSW_MACSL_CTL_REG);
208         port->mac_control = mac_control;
209
210 out:
211         return phy->link;
212 }
213
214 #define AM65_GMII_SEL_MODE_MII          0
215 #define AM65_GMII_SEL_MODE_RMII         1
216 #define AM65_GMII_SEL_MODE_RGMII        2
217
218 #define AM65_GMII_SEL_RGMII_IDMODE      BIT(4)
219
220 static void am65_cpsw_gmii_sel_k3(struct am65_cpsw_priv *priv,
221                                   phy_interface_t phy_mode, int slave)
222 {
223         struct am65_cpsw_common *common = priv->cpsw_common;
224         u32 reg;
225         u32 mode = 0;
226         bool rgmii_id = false;
227
228         reg = readl(common->gmii_sel);
229
230         dev_dbg(common->dev, "old gmii_sel: %08x\n", reg);
231
232         switch (phy_mode) {
233         case PHY_INTERFACE_MODE_RMII:
234                 mode = AM65_GMII_SEL_MODE_RMII;
235                 break;
236
237         case PHY_INTERFACE_MODE_RGMII:
238         case PHY_INTERFACE_MODE_RGMII_RXID:
239                 mode = AM65_GMII_SEL_MODE_RGMII;
240                 break;
241
242         case PHY_INTERFACE_MODE_RGMII_ID:
243         case PHY_INTERFACE_MODE_RGMII_TXID:
244                 mode = AM65_GMII_SEL_MODE_RGMII;
245                 rgmii_id = true;
246                 break;
247
248         default:
249                 dev_warn(common->dev,
250                          "Unsupported PHY mode: %u. Defaulting to MII.\n",
251                          phy_mode);
252                 /* fallthrough */
253         case PHY_INTERFACE_MODE_MII:
254                 mode = AM65_GMII_SEL_MODE_MII;
255                 break;
256         };
257
258         if (rgmii_id)
259                 mode |= AM65_GMII_SEL_RGMII_IDMODE;
260
261         reg = mode;
262         dev_dbg(common->dev, "gmii_sel PHY mode: %u, new gmii_sel: %08x\n",
263                 phy_mode, reg);
264         writel(reg, common->gmii_sel);
265
266         reg = readl(common->gmii_sel);
267         if (reg != mode)
268                 dev_err(common->dev,
269                         "gmii_sel PHY mode NOT SET!: requested: %08x, gmii_sel: %08x\n",
270                         mode, reg);
271 }
272
273 static int am65_cpsw_start(struct udevice *dev)
274 {
275         struct eth_pdata *pdata = dev_get_platdata(dev);
276         struct am65_cpsw_priv *priv = dev_get_priv(dev);
277         struct am65_cpsw_common *common = priv->cpsw_common;
278         struct am65_cpsw_port *port = &common->ports[priv->port_id];
279         struct am65_cpsw_port *port0 = &common->ports[0];
280         struct ti_udma_drv_chan_cfg_data *dma_rx_cfg_data;
281         int ret, i;
282
283         ret = power_domain_on(&common->pwrdmn);
284         if (ret) {
285                 dev_err(dev, "power_domain_on() failed %d\n", ret);
286                 goto out;
287         }
288
289         ret = clk_enable(&common->fclk);
290         if (ret) {
291                 dev_err(dev, "clk enabled failed %d\n", ret);
292                 goto err_off_pwrdm;
293         }
294
295         common->rx_next = 0;
296         common->rx_pend = 0;
297         ret = dma_get_by_name(common->dev, "tx0", &common->dma_tx);
298         if (ret) {
299                 dev_err(dev, "TX dma get failed %d\n", ret);
300                 goto err_off_clk;
301         }
302         ret = dma_get_by_name(common->dev, "rx", &common->dma_rx);
303         if (ret) {
304                 dev_err(dev, "RX dma get failed %d\n", ret);
305                 goto err_free_tx;
306         }
307
308         for (i = 0; i < UDMA_RX_DESC_NUM; i++) {
309                 ret = dma_prepare_rcv_buf(&common->dma_rx,
310                                           net_rx_packets[i],
311                                           UDMA_RX_BUF_SIZE);
312                 if (ret) {
313                         dev_err(dev, "RX dma add buf failed %d\n", ret);
314                         goto err_free_tx;
315                 }
316         }
317
318         ret = dma_enable(&common->dma_tx);
319         if (ret) {
320                 dev_err(dev, "TX dma_enable failed %d\n", ret);
321                 goto err_free_rx;
322         }
323         ret = dma_enable(&common->dma_rx);
324         if (ret) {
325                 dev_err(dev, "RX dma_enable failed %d\n", ret);
326                 goto err_dis_tx;
327         }
328
329         /* Control register */
330         writel(AM65_CPSW_CTL_REG_P0_ENABLE |
331                AM65_CPSW_CTL_REG_P0_TX_CRC_REMOVE |
332                AM65_CPSW_CTL_REG_P0_RX_PAD,
333                common->cpsw_base + AM65_CPSW_CTL_REG);
334
335         /* disable priority elevation */
336         writel(0, common->cpsw_base + AM65_CPSW_PTYPE_REG);
337
338         /* enable statistics */
339         writel(BIT(0) | BIT(priv->port_id),
340                common->cpsw_base + AM65_CPSW_STAT_PORT_EN_REG);
341
342         /* Port 0  length register */
343         writel(PKTSIZE_ALIGN, port0->port_base + AM65_CPSW_PN_RX_MAXLEN_REG);
344
345         /* set base flow_id */
346         dma_get_cfg(&common->dma_rx, 0, (void **)&dma_rx_cfg_data);
347         writel(dma_rx_cfg_data->flow_id_base,
348                port0->port_base + AM65_CPSW_P0_FLOW_ID_REG);
349         dev_info(dev, "K3 CPSW: rflow_id_base: %u\n",
350                  dma_rx_cfg_data->flow_id_base);
351
352         /* Reset and enable the ALE */
353         writel(AM65_CPSW_ALE_CTL_REG_ENABLE | AM65_CPSW_ALE_CTL_REG_RESET_TBL |
354                AM65_CPSW_ALE_CTL_REG_BYPASS,
355                common->ale_base + AM65_CPSW_ALE_CTL_REG);
356
357         /* port 0 put into forward mode */
358         writel(AM65_CPSW_ALE_PN_CTL_REG_MODE_FORWARD,
359                common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(0));
360
361         /* PORT x configuration */
362
363         /* Port x Max length register */
364         writel(PKTSIZE_ALIGN, port->port_base + AM65_CPSW_PN_RX_MAXLEN_REG);
365
366         /* Port x set mac */
367         am65_cpsw_set_sl_mac(port, pdata->enetaddr);
368
369         /* Port x ALE: mac_only, Forwarding */
370         writel(AM65_CPSW_ALE_PN_CTL_REG_MAC_ONLY |
371                AM65_CPSW_ALE_PN_CTL_REG_MODE_FORWARD,
372                common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(priv->port_id));
373
374         port->mac_control = 0;
375         if (!am65_cpsw_macsl_reset(port)) {
376                 dev_err(dev, "mac_sl reset failed\n");
377                 ret = -EFAULT;
378                 goto err_dis_rx;
379         }
380
381         ret = phy_startup(priv->phydev);
382         if (ret) {
383                 dev_err(dev, "phy_startup failed\n");
384                 goto err_dis_rx;
385         }
386
387         ret = am65_cpsw_update_link(priv);
388         if (!ret) {
389                 ret = -ENODEV;
390                 goto err_phy_shutdown;
391         }
392
393         common->started = true;
394
395         return 0;
396
397 err_phy_shutdown:
398         phy_shutdown(priv->phydev);
399 err_dis_rx:
400         /* disable ports */
401         writel(0, common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(priv->port_id));
402         writel(0, common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(0));
403         if (!am65_cpsw_macsl_wait_for_idle(port))
404                 dev_err(dev, "mac_sl idle timeout\n");
405         writel(0, port->macsl_base + AM65_CPSW_MACSL_CTL_REG);
406         writel(0, common->ale_base + AM65_CPSW_ALE_CTL_REG);
407         writel(0, common->cpsw_base + AM65_CPSW_CTL_REG);
408
409         dma_disable(&common->dma_rx);
410 err_dis_tx:
411         dma_disable(&common->dma_tx);
412 err_free_rx:
413         dma_free(&common->dma_rx);
414 err_free_tx:
415         dma_free(&common->dma_tx);
416 err_off_clk:
417         clk_disable(&common->fclk);
418 err_off_pwrdm:
419         power_domain_off(&common->pwrdmn);
420 out:
421         dev_err(dev, "%s end error\n", __func__);
422
423         return ret;
424 }
425
426 static int am65_cpsw_send(struct udevice *dev, void *packet, int length)
427 {
428         struct am65_cpsw_priv *priv = dev_get_priv(dev);
429         struct am65_cpsw_common *common = priv->cpsw_common;
430         struct ti_udma_drv_packet_data packet_data;
431         int ret;
432
433         packet_data.pkt_type = AM65_CPSW_CPPI_PKT_TYPE;
434         packet_data.dest_tag = priv->port_id;
435         ret = dma_send(&common->dma_tx, packet, length, &packet_data);
436         if (ret) {
437                 dev_err(dev, "TX dma_send failed %d\n", ret);
438                 return ret;
439         }
440
441         return 0;
442 }
443
444 static int am65_cpsw_recv(struct udevice *dev, int flags, uchar **packetp)
445 {
446         struct am65_cpsw_priv *priv = dev_get_priv(dev);
447         struct am65_cpsw_common *common = priv->cpsw_common;
448
449         /* try to receive a new packet */
450         return dma_receive(&common->dma_rx, (void **)packetp, NULL);
451 }
452
453 static int am65_cpsw_free_pkt(struct udevice *dev, uchar *packet, int length)
454 {
455         struct am65_cpsw_priv *priv = dev_get_priv(dev);
456         struct am65_cpsw_common *common = priv->cpsw_common;
457         int ret;
458
459         if (length > 0) {
460                 u32 pkt = common->rx_next % UDMA_RX_DESC_NUM;
461
462                 ret = dma_prepare_rcv_buf(&common->dma_rx,
463                                           net_rx_packets[pkt],
464                                           UDMA_RX_BUF_SIZE);
465                 if (ret)
466                         dev_err(dev, "RX dma free_pkt failed %d\n", ret);
467                 common->rx_next++;
468         }
469
470         return 0;
471 }
472
473 static void am65_cpsw_stop(struct udevice *dev)
474 {
475         struct am65_cpsw_priv *priv = dev_get_priv(dev);
476         struct am65_cpsw_common *common = priv->cpsw_common;
477         struct am65_cpsw_port *port = &common->ports[priv->port_id];
478
479         if (!common->started)
480                 return;
481
482         phy_shutdown(priv->phydev);
483
484         writel(0, common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(priv->port_id));
485         writel(0, common->ale_base + AM65_CPSW_ALE_PN_CTL_REG(0));
486         if (!am65_cpsw_macsl_wait_for_idle(port))
487                 dev_err(dev, "mac_sl idle timeout\n");
488         writel(0, port->macsl_base + AM65_CPSW_MACSL_CTL_REG);
489         writel(0, common->ale_base + AM65_CPSW_ALE_CTL_REG);
490         writel(0, common->cpsw_base + AM65_CPSW_CTL_REG);
491
492         dma_disable(&common->dma_tx);
493         dma_free(&common->dma_tx);
494
495         dma_disable(&common->dma_rx);
496         dma_free(&common->dma_rx);
497
498         common->started = false;
499 }
500
501 static int am65_cpsw_read_rom_hwaddr(struct udevice *dev)
502 {
503         struct am65_cpsw_priv *priv = dev_get_priv(dev);
504         struct am65_cpsw_common *common = priv->cpsw_common;
505         struct eth_pdata *pdata = dev_get_platdata(dev);
506         u32 mac_hi, mac_lo;
507
508         if (common->mac_efuse == FDT_ADDR_T_NONE)
509                 return -1;
510
511         mac_lo = readl(common->mac_efuse);
512         mac_hi = readl(common->mac_efuse + 4);
513         pdata->enetaddr[0] = (mac_hi >> 8) & 0xff;
514         pdata->enetaddr[1] = mac_hi & 0xff;
515         pdata->enetaddr[2] = (mac_lo >> 24) & 0xff;
516         pdata->enetaddr[3] = (mac_lo >> 16) & 0xff;
517         pdata->enetaddr[4] = (mac_lo >> 8) & 0xff;
518         pdata->enetaddr[5] = mac_lo & 0xff;
519
520         return 0;
521 }
522
523 static const struct eth_ops am65_cpsw_ops = {
524         .start          = am65_cpsw_start,
525         .send           = am65_cpsw_send,
526         .recv           = am65_cpsw_recv,
527         .free_pkt       = am65_cpsw_free_pkt,
528         .stop           = am65_cpsw_stop,
529         .read_rom_hwaddr = am65_cpsw_read_rom_hwaddr,
530 };
531
532 static int am65_cpsw_mdio_init(struct udevice *dev)
533 {
534         struct am65_cpsw_priv *priv = dev_get_priv(dev);
535         struct am65_cpsw_common *cpsw_common = priv->cpsw_common;
536
537         if (!priv->has_phy || cpsw_common->bus)
538                 return 0;
539
540         cpsw_common->bus = cpsw_mdio_init(dev->name,
541                                           cpsw_common->mdio_base,
542                                           cpsw_common->bus_freq,
543                                           clk_get_rate(&cpsw_common->fclk));
544         if (!cpsw_common->bus)
545                 return -EFAULT;
546
547         return 0;
548 }
549
550 static int am65_cpsw_phy_init(struct udevice *dev)
551 {
552         struct am65_cpsw_priv *priv = dev_get_priv(dev);
553         struct am65_cpsw_common *cpsw_common = priv->cpsw_common;
554         struct eth_pdata *pdata = dev_get_platdata(dev);
555         struct phy_device *phydev;
556         u32 supported = PHY_GBIT_FEATURES;
557         int ret;
558
559         phydev = phy_connect(cpsw_common->bus,
560                              priv->phy_addr,
561                              priv->dev,
562                              pdata->phy_interface);
563
564         if (!phydev) {
565                 dev_err(dev, "phy_connect() failed\n");
566                 return -ENODEV;
567         }
568
569         phydev->supported &= supported;
570         if (pdata->max_speed) {
571                 ret = phy_set_supported(phydev, pdata->max_speed);
572                 if (ret)
573                         return ret;
574         }
575         phydev->advertising = phydev->supported;
576
577         if (ofnode_valid(priv->phy_node))
578                 phydev->node = priv->phy_node;
579
580         priv->phydev = phydev;
581         ret = phy_config(phydev);
582         if (ret < 0)
583                 pr_err("phy_config() failed: %d", ret);
584
585         return ret;
586 }
587
588 static int am65_cpsw_ofdata_parse_phy(struct udevice *dev, ofnode port_np)
589 {
590         struct eth_pdata *pdata = dev_get_platdata(dev);
591         struct am65_cpsw_priv *priv = dev_get_priv(dev);
592         struct ofnode_phandle_args out_args;
593         const char *phy_mode;
594         int ret = 0;
595
596         phy_mode = ofnode_read_string(port_np, "phy-mode");
597         if (phy_mode) {
598                 pdata->phy_interface =
599                                 phy_get_interface_by_name(phy_mode);
600                 if (pdata->phy_interface == -1) {
601                         dev_err(dev, "Invalid PHY mode '%s', port %u\n",
602                                 phy_mode, priv->port_id);
603                         ret = -EINVAL;
604                         goto out;
605                 }
606         }
607
608         ofnode_read_u32(port_np, "max-speed", (u32 *)&pdata->max_speed);
609         if (pdata->max_speed)
610                 dev_err(dev, "Port %u speed froced to %uMbit\n",
611                         priv->port_id, pdata->max_speed);
612
613         priv->has_phy  = true;
614         ret = ofnode_parse_phandle_with_args(port_np, "phy-handle",
615                                              NULL, 0, 0, &out_args);
616         if (ret) {
617                 dev_err(dev, "can't parse phy-handle port %u (%d)\n",
618                         priv->port_id, ret);
619                 priv->has_phy  = false;
620                 ret = 0;
621         }
622
623         priv->phy_node = out_args.node;
624         if (priv->has_phy) {
625                 ret = ofnode_read_u32(priv->phy_node, "reg", &priv->phy_addr);
626                 if (ret) {
627                         dev_err(dev, "failed to get phy_addr port %u (%d)\n",
628                                 priv->port_id, ret);
629                         goto out;
630                 }
631         }
632
633 out:
634         return ret;
635 }
636
637 static int am65_cpsw_probe_cpsw(struct udevice *dev)
638 {
639         struct am65_cpsw_priv *priv = dev_get_priv(dev);
640         struct eth_pdata *pdata = dev_get_platdata(dev);
641         struct am65_cpsw_common *cpsw_common;
642         ofnode ports_np, node;
643         int ret, i;
644
645         priv->dev = dev;
646
647         cpsw_common = calloc(1, sizeof(*priv->cpsw_common));
648         if (!cpsw_common)
649                 return -ENOMEM;
650         priv->cpsw_common = cpsw_common;
651
652         cpsw_common->dev = dev;
653         cpsw_common->ss_base = dev_read_addr(dev);
654         if (cpsw_common->ss_base == FDT_ADDR_T_NONE)
655                 return -EINVAL;
656         cpsw_common->mac_efuse = devfdt_get_addr_name(dev, "mac_efuse");
657         /* no err check - optional */
658
659         ret = power_domain_get_by_index(dev, &cpsw_common->pwrdmn, 0);
660         if (ret) {
661                 dev_err(dev, "failed to get pwrdmn: %d\n", ret);
662                 return ret;
663         }
664
665         ret = clk_get_by_name(dev, "fck", &cpsw_common->fclk);
666         if (ret) {
667                 power_domain_free(&cpsw_common->pwrdmn);
668                 dev_err(dev, "failed to get clock %d\n", ret);
669                 return ret;
670         }
671
672         cpsw_common->cpsw_base = cpsw_common->ss_base + AM65_CPSW_CPSW_NU_BASE;
673         cpsw_common->ale_base = cpsw_common->cpsw_base +
674                                 AM65_CPSW_CPSW_NU_ALE_BASE;
675         cpsw_common->mdio_base = cpsw_common->ss_base + AM65_CPSW_MDIO_BASE;
676
677         ports_np = dev_read_subnode(dev, "ports");
678         if (!ofnode_valid(ports_np)) {
679                 ret = -ENOENT;
680                 goto out;
681         }
682
683         ofnode_for_each_subnode(node, ports_np) {
684                 const char *node_name;
685                 u32 port_id;
686                 bool disabled;
687
688                 node_name = ofnode_get_name(node);
689
690                 disabled = !ofnode_is_available(node);
691
692                 ret = ofnode_read_u32(node, "reg", &port_id);
693                 if (ret) {
694                         dev_err(dev, "%s: failed to get port_id (%d)\n",
695                                 node_name, ret);
696                         goto out;
697                 }
698
699                 if (port_id >= AM65_CPSW_CPSWNU_MAX_PORTS) {
700                         dev_err(dev, "%s: invalid port_id (%d)\n",
701                                 node_name, port_id);
702                         ret = -EINVAL;
703                         goto out;
704                 }
705                 cpsw_common->port_num++;
706
707                 if (!port_id)
708                         continue;
709
710                 priv->port_id = port_id;
711                 cpsw_common->ports[port_id].disabled = disabled;
712                 if (disabled)
713                         continue;
714
715                 ret = am65_cpsw_ofdata_parse_phy(dev, node);
716                 if (ret)
717                         goto out;
718         }
719
720         for (i = 0; i < AM65_CPSW_CPSWNU_MAX_PORTS; i++) {
721                 struct am65_cpsw_port *port = &cpsw_common->ports[i];
722
723                 port->port_base = cpsw_common->cpsw_base +
724                                   AM65_CPSW_CPSW_NU_PORTS_OFFSET +
725                                   (i * AM65_CPSW_CPSW_NU_PORTS_OFFSET);
726                 port->macsl_base = port->port_base +
727                                    AM65_CPSW_CPSW_NU_PORT_MACSL_OFFSET;
728         }
729
730         node = dev_read_subnode(dev, "cpsw-phy-sel");
731         if (!ofnode_valid(node)) {
732                 dev_err(dev, "can't find cpsw-phy-sel\n");
733                 ret = -ENOENT;
734                 goto out;
735         }
736
737         cpsw_common->gmii_sel = ofnode_get_addr(node);
738         if (cpsw_common->gmii_sel == FDT_ADDR_T_NONE) {
739                 dev_err(dev, "failed to get gmii_sel base\n");
740                 goto out;
741         }
742
743         node = dev_read_subnode(dev, "mdio");
744         if (!ofnode_valid(node)) {
745                 dev_err(dev, "can't find mdio\n");
746                 ret = -ENOENT;
747                 goto out;
748         }
749
750         cpsw_common->bus_freq =
751                         dev_read_u32_default(dev, "bus_freq",
752                                              AM65_CPSW_MDIO_BUS_FREQ_DEF);
753
754         am65_cpsw_gmii_sel_k3(priv, pdata->phy_interface, priv->port_id);
755
756         ret = am65_cpsw_mdio_init(dev);
757         if (ret)
758                 goto out;
759
760         ret = am65_cpsw_phy_init(dev);
761         if (ret)
762                 goto out;
763
764         dev_info(dev, "K3 CPSW: nuss_ver: 0x%08X cpsw_ver: 0x%08X ale_ver: 0x%08X Ports:%u mdio_freq:%u\n",
765                  readl(cpsw_common->ss_base),
766                  readl(cpsw_common->cpsw_base),
767                  readl(cpsw_common->ale_base),
768                  cpsw_common->port_num,
769                  cpsw_common->bus_freq);
770
771 out:
772         clk_free(&cpsw_common->fclk);
773         power_domain_free(&cpsw_common->pwrdmn);
774         return ret;
775 }
776
777 static const struct udevice_id am65_cpsw_nuss_ids[] = {
778         { .compatible = "ti,am654-cpsw-nuss" },
779         { .compatible = "ti,j721e-cpsw-nuss" },
780         { }
781 };
782
783 U_BOOT_DRIVER(am65_cpsw_nuss_slave) = {
784         .name   = "am65_cpsw_nuss_slave",
785         .id     = UCLASS_ETH,
786         .of_match = am65_cpsw_nuss_ids,
787         .probe  = am65_cpsw_probe_cpsw,
788         .ops    = &am65_cpsw_ops,
789         .priv_auto_alloc_size = sizeof(struct am65_cpsw_priv),
790         .platdata_auto_alloc_size = sizeof(struct eth_pdata),
791         .flags = DM_FLAG_ALLOC_PRIV_DMA,
792 };