blob: 64e860e324dcd956734890e7104c8fe303760325 [file] [log] [blame]
Tim Harveyc3cd7f12022-11-30 09:42:50 -08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2022
4 * Gateworks Corporation <www.gateworks.com>
5 * Tim Harvey <tharvey@gateworks.com>
6 *
7 * (C) Copyright 2015
8 * Elecsys Corporation <www.elecsyscorp.com>
9 * Kevin Smith <kevin.smith@elecsyscorp.com>
10 *
11 * Original driver:
12 * (C) Copyright 2009
13 * Marvell Semiconductor <www.marvell.com>
14 * Prafulla Wadaskar <prafulla@marvell.com>
15 */
16
17/*
18 * DSA driver for mv88e6xxx ethernet switches.
19 *
20 * This driver configures the mv88e6xxx for basic use as a DSA switch.
21 *
22 * This driver was adapted from drivers/net/phy/mv88e61xx and tested
23 * on the mv88e6176 via an SGMII interface.
24 */
25
26#include <common.h>
27#include <dm/device.h>
28#include <dm/device_compat.h>
29#include <dm/device-internal.h>
30#include <dm/lists.h>
31#include <dm/of_extra.h>
32#include <linux/delay.h>
33#include <miiphy.h>
34#include <net/dsa.h>
35
36/* Device addresses */
37#define DEVADDR_PHY(p) (p)
38#define DEVADDR_SERDES 0x0F
39
40/* SMI indirection registers for multichip addressing mode */
41#define SMI_CMD_REG 0x00
42#define SMI_DATA_REG 0x01
43
44/* Global registers */
45#define GLOBAL1_STATUS 0x00
46#define GLOBAL1_CTRL 0x04
47
48/* Global 2 registers */
49#define GLOBAL2_REG_PHY_CMD 0x18
50#define GLOBAL2_REG_PHY_DATA 0x19
51#define GLOBAL2_REG_SCRATCH 0x1A
52
53/* Port registers */
54#define PORT_REG_STATUS 0x00
55#define PORT_REG_PHYS_CTRL 0x01
56#define PORT_REG_SWITCH_ID 0x03
57#define PORT_REG_CTRL 0x04
58
59/* Phy registers */
60#define PHY_REG_PAGE 0x16
61
62/* Phy page numbers */
63#define PHY_PAGE_COPPER 0
64#define PHY_PAGE_SERDES 1
65
66/* Register fields */
67#define GLOBAL1_CTRL_SWRESET BIT(15)
68
69#define PORT_REG_STATUS_SPEED_SHIFT 8
70#define PORT_REG_STATUS_SPEED_10 0
71#define PORT_REG_STATUS_SPEED_100 1
72#define PORT_REG_STATUS_SPEED_1000 2
73
74#define PORT_REG_STATUS_CMODE_MASK 0xF
75#define PORT_REG_STATUS_CMODE_SGMII 0xa
76#define PORT_REG_STATUS_CMODE_1000BASE_X 0x9
77#define PORT_REG_STATUS_CMODE_100BASE_X 0x8
78#define PORT_REG_STATUS_CMODE_RGMII 0x7
79#define PORT_REG_STATUS_CMODE_RMII 0x5
80#define PORT_REG_STATUS_CMODE_RMII_PHY 0x4
81#define PORT_REG_STATUS_CMODE_GMII 0x3
82#define PORT_REG_STATUS_CMODE_MII 0x2
83#define PORT_REG_STATUS_CMODE_MIIPHY 0x1
84
85#define PORT_REG_PHYS_CTRL_RGMII_DELAY_RXCLK BIT(15)
86#define PORT_REG_PHYS_CTRL_RGMII_DELAY_TXCLK BIT(14)
87#define PORT_REG_PHYS_CTRL_PCS_AN_EN BIT(10)
88#define PORT_REG_PHYS_CTRL_PCS_AN_RST BIT(9)
89#define PORT_REG_PHYS_CTRL_FC_VALUE BIT(7)
90#define PORT_REG_PHYS_CTRL_FC_FORCE BIT(6)
91#define PORT_REG_PHYS_CTRL_LINK_VALUE BIT(5)
92#define PORT_REG_PHYS_CTRL_LINK_FORCE BIT(4)
93#define PORT_REG_PHYS_CTRL_DUPLEX_VALUE BIT(3)
94#define PORT_REG_PHYS_CTRL_DUPLEX_FORCE BIT(2)
95#define PORT_REG_PHYS_CTRL_SPD1000 BIT(1)
96#define PORT_REG_PHYS_CTRL_SPD100 BIT(0)
97#define PORT_REG_PHYS_CTRL_SPD_MASK (BIT(1) | BIT(0))
98
99#define PORT_REG_CTRL_PSTATE_SHIFT 0
100#define PORT_REG_CTRL_PSTATE_MASK 3
101
102/* Field values */
103#define PORT_REG_CTRL_PSTATE_DISABLED 0
104#define PORT_REG_CTRL_PSTATE_FORWARD 3
105
106/*
107 * Macros for building commands for indirect addressing modes. These are valid
108 * for both the indirect multichip addressing mode and the PHY indirection
109 * required for the writes to any PHY register.
110 */
111#define SMI_BUSY BIT(15)
112#define SMI_CMD_CLAUSE_22 BIT(12)
113#define SMI_CMD_CLAUSE_22_OP_READ (2 << 10)
114#define SMI_CMD_CLAUSE_22_OP_WRITE (1 << 10)
115#define SMI_CMD_ADDR_SHIFT 5
116#define SMI_CMD_ADDR_MASK 0x1f
117#define SMI_CMD_REG_SHIFT 0
118#define SMI_CMD_REG_MASK 0x1f
119#define SMI_CMD_READ(addr, reg) \
120 (SMI_BUSY | SMI_CMD_CLAUSE_22 | SMI_CMD_CLAUSE_22_OP_READ) | \
121 (((addr) & SMI_CMD_ADDR_MASK) << SMI_CMD_ADDR_SHIFT) | \
122 (((reg) & SMI_CMD_REG_MASK) << SMI_CMD_REG_SHIFT)
123#define SMI_CMD_WRITE(addr, reg) \
124 (SMI_BUSY | SMI_CMD_CLAUSE_22 | SMI_CMD_CLAUSE_22_OP_WRITE) | \
125 (((addr) & SMI_CMD_ADDR_MASK) << SMI_CMD_ADDR_SHIFT) | \
126 (((reg) & SMI_CMD_REG_MASK) << SMI_CMD_REG_SHIFT)
127
128/* ID register values for different switch models */
129#define PORT_SWITCH_ID_6020 0x0200
130#define PORT_SWITCH_ID_6070 0x0700
131#define PORT_SWITCH_ID_6071 0x0710
132#define PORT_SWITCH_ID_6096 0x0980
133#define PORT_SWITCH_ID_6097 0x0990
134#define PORT_SWITCH_ID_6172 0x1720
135#define PORT_SWITCH_ID_6176 0x1760
136#define PORT_SWITCH_ID_6220 0x2200
137#define PORT_SWITCH_ID_6240 0x2400
138#define PORT_SWITCH_ID_6250 0x2500
139#define PORT_SWITCH_ID_6320 0x1150
140#define PORT_SWITCH_ID_6352 0x3520
141
142struct mv88e6xxx_priv {
143 int smi_addr;
144 int id;
145 int port_count; /* Number of switch ports */
146 int port_reg_base; /* Base of the switch port registers */
147 u8 global1; /* Offset of Switch Global 1 registers */
148 u8 global2; /* Offset of Switch Global 2 registers */
149};
150
151/* Wait for the current SMI indirect command to complete */
152static int mv88e6xxx_smi_wait(struct udevice *dev, int smi_addr)
153{
154 int val;
155 u32 timeout = 100;
156
157 do {
158 val = dm_mdio_read(dev->parent, smi_addr, MDIO_DEVAD_NONE, SMI_CMD_REG);
159 if (val >= 0 && (val & SMI_BUSY) == 0)
160 return 0;
161
162 mdelay(1);
163 } while (--timeout);
164
165 dev_err(dev, "SMI busy timeout\n");
166 return -ETIMEDOUT;
167}
168
169/*
170 * The mv88e6xxx has three types of addresses: the smi bus address, the device
171 * address, and the register address. The smi bus address distinguishes it on
172 * the smi bus from other PHYs or switches. The device address determines
173 * which on-chip register set you are reading/writing (the various PHYs, their
174 * associated ports, or global configuration registers). The register address
175 * is the offset of the register you are reading/writing.
176 *
177 * When the mv88e6xxx is hardware configured to have address zero, it behaves in
178 * single-chip addressing mode, where it responds to all SMI addresses, using
179 * the smi address as its device address. This obviously only works when this
180 * is the only chip on the SMI bus. This allows the driver to access device
181 * registers without using indirection. When the chip is configured to a
182 * non-zero address, it only responds to that SMI address and requires indirect
183 * writes to access the different device addresses.
184 */
185static int mv88e6xxx_reg_read(struct udevice *dev, int addr, int reg)
186{
187 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
188 int smi_addr = priv->smi_addr;
189 int res;
190
191 /* In single-chip mode, the device can be addressed directly */
192 if (smi_addr == 0)
193 return dm_mdio_read(dev->parent, addr, MDIO_DEVAD_NONE, reg);
194
195 /* Wait for the bus to become free */
196 res = mv88e6xxx_smi_wait(dev, smi_addr);
197 if (res < 0)
198 return res;
199
200 /* Issue the read command */
201 res = dm_mdio_write(dev->parent, smi_addr, MDIO_DEVAD_NONE, SMI_CMD_REG,
202 SMI_CMD_READ(addr, reg));
203 if (res < 0)
204 return res;
205
206 /* Wait for the read command to complete */
207 res = mv88e6xxx_smi_wait(dev, smi_addr);
208 if (res < 0)
209 return res;
210
211 /* Read the data */
212 res = dm_mdio_read(dev->parent, smi_addr, MDIO_DEVAD_NONE, SMI_DATA_REG);
213 if (res < 0)
214 return res;
215
216 return res & 0xffff;
217}
218
219/* See the comment above mv88e6xxx_reg_read */
220static int mv88e6xxx_reg_write(struct udevice *dev, int addr, int reg, u16 val)
221{
222 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
223 int smi_addr = priv->smi_addr;
224 int res;
225
226 /* In single-chip mode, the device can be addressed directly */
227 if (smi_addr == 0)
228 return dm_mdio_write(dev->parent, addr, MDIO_DEVAD_NONE, reg, val);
229
230 /* Wait for the bus to become free */
231 res = mv88e6xxx_smi_wait(dev, smi_addr);
232 if (res < 0)
233 return res;
234
235 /* Set the data to write */
236 res = dm_mdio_write(dev->parent, smi_addr, MDIO_DEVAD_NONE,
237 SMI_DATA_REG, val);
238 if (res < 0)
239 return res;
240
241 /* Issue the write command */
242 res = dm_mdio_write(dev->parent, smi_addr, MDIO_DEVAD_NONE, SMI_CMD_REG,
243 SMI_CMD_WRITE(addr, reg));
244 if (res < 0)
245 return res;
246
247 /* Wait for the write command to complete */
248 res = mv88e6xxx_smi_wait(dev, smi_addr);
249 if (res < 0)
250 return res;
251
252 return 0;
253}
254
255static int mv88e6xxx_phy_wait(struct udevice *dev)
256{
257 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
258 int val;
259 u32 timeout = 100;
260
261 do {
262 val = mv88e6xxx_reg_read(dev, priv->global2, GLOBAL2_REG_PHY_CMD);
263 if (val >= 0 && (val & SMI_BUSY) == 0)
264 return 0;
265
266 mdelay(1);
267 } while (--timeout);
268
269 return -ETIMEDOUT;
270}
271
272static int mv88e6xxx_phy_read_indirect(struct udevice *dev, int phyad, int devad, int reg)
273{
274 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
275 int res;
276
277 /* Issue command to read */
278 res = mv88e6xxx_reg_write(dev, priv->global2,
279 GLOBAL2_REG_PHY_CMD,
280 SMI_CMD_READ(phyad, reg));
281
282 /* Wait for data to be read */
283 res = mv88e6xxx_phy_wait(dev);
284 if (res < 0)
285 return res;
286
287 /* Read retrieved data */
288 return mv88e6xxx_reg_read(dev, priv->global2,
289 GLOBAL2_REG_PHY_DATA);
290}
291
292static int mv88e6xxx_phy_write_indirect(struct udevice *dev, int phyad,
293 int devad, int reg, u16 data)
294{
295 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
296 int res;
297
298 /* Set the data to write */
299 res = mv88e6xxx_reg_write(dev, priv->global2,
300 GLOBAL2_REG_PHY_DATA, data);
301 if (res < 0)
302 return res;
303 /* Issue the write command */
304 res = mv88e6xxx_reg_write(dev, priv->global2,
305 GLOBAL2_REG_PHY_CMD,
306 SMI_CMD_WRITE(phyad, reg));
307 if (res < 0)
308 return res;
309
310 /* Wait for command to complete */
311 return mv88e6xxx_phy_wait(dev);
312}
313
314/* Wrapper function to make calls to phy_read_indirect simpler */
315static int mv88e6xxx_phy_read(struct udevice *dev, int phy, int reg)
316{
317 return mv88e6xxx_phy_read_indirect(dev, DEVADDR_PHY(phy),
318 MDIO_DEVAD_NONE, reg);
319}
320
321/* Wrapper function to make calls to phy_write_indirect simpler */
322static int mv88e6xxx_phy_write(struct udevice *dev, int phy, int reg, u16 val)
323{
324 return mv88e6xxx_phy_write_indirect(dev, DEVADDR_PHY(phy),
325 MDIO_DEVAD_NONE, reg, val);
326}
327
328static int mv88e6xxx_port_read(struct udevice *dev, u8 port, u8 reg)
329{
330 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
331
332 return mv88e6xxx_reg_read(dev, priv->port_reg_base + port, reg);
333}
334
335static int mv88e6xxx_port_write(struct udevice *dev, u8 port, u8 reg, u16 val)
336{
337 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
338
339 return mv88e6xxx_reg_write(dev, priv->port_reg_base + port, reg, val);
340}
341
342static int mv88e6xxx_set_page(struct udevice *dev, u8 phy, u8 page)
343{
344 return mv88e6xxx_phy_write(dev, phy, PHY_REG_PAGE, page);
345}
346
347static int mv88e6xxx_get_switch_id(struct udevice *dev)
348{
349 int res;
350
351 res = mv88e6xxx_port_read(dev, 0, PORT_REG_SWITCH_ID);
352 if (res < 0) {
353 dev_err(dev, "Failed to read switch ID: %d\n", res);
354 return res;
355 }
356 return res & 0xfff0;
357}
358
359static bool mv88e6xxx_6352_family(struct udevice *dev)
360{
361 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
362
363 switch (priv->id) {
364 case PORT_SWITCH_ID_6172:
365 case PORT_SWITCH_ID_6176:
366 case PORT_SWITCH_ID_6240:
367 case PORT_SWITCH_ID_6352:
368 return true;
369 }
370 return false;
371}
372
373static int mv88e6xxx_get_cmode(struct udevice *dev, u8 port)
374{
375 int res;
376
377 res = mv88e6xxx_port_read(dev, port, PORT_REG_STATUS);
378 if (res < 0)
379 return res;
380 return res & PORT_REG_STATUS_CMODE_MASK;
381}
382
383static int mv88e6xxx_switch_reset(struct udevice *dev)
384{
385 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
386 int time_ms;
387 int val;
388 u8 port;
389
390 /* Disable all ports */
391 for (port = 0; port < priv->port_count; port++) {
392 val = mv88e6xxx_port_read(dev, port, PORT_REG_CTRL);
393 if (val < 0)
394 return val;
395 val &= ~(PORT_REG_CTRL_PSTATE_MASK << PORT_REG_CTRL_PSTATE_SHIFT);
396 val |= (PORT_REG_CTRL_PSTATE_DISABLED << PORT_REG_CTRL_PSTATE_SHIFT);
397 val = mv88e6xxx_port_write(dev, port, PORT_REG_CTRL, val);
398 if (val < 0)
399 return val;
400 }
401
402 /* Wait 2 ms for queues to drain */
403 udelay(2000);
404
405 /* Reset switch */
406 val = mv88e6xxx_reg_read(dev, priv->global1, GLOBAL1_CTRL);
407 if (val < 0)
408 return val;
409 val |= GLOBAL1_CTRL_SWRESET;
410 val = mv88e6xxx_reg_write(dev, priv->global1, GLOBAL1_CTRL, val);
411 if (val < 0)
412 return val;
413
414 /* Wait up to 1 second for switch to reset complete */
415 for (time_ms = 1000; time_ms; time_ms--) {
416 val = mv88e6xxx_reg_read(dev, priv->global1, GLOBAL1_CTRL);
417 if (val >= 0 && ((val & GLOBAL1_CTRL_SWRESET) == 0))
418 break;
419 udelay(1000);
420 }
421 if (!time_ms)
422 return -ETIMEDOUT;
423
424 return 0;
425}
426
427static int mv88e6xxx_serdes_init(struct udevice *dev)
428{
429 int val;
430
431 val = mv88e6xxx_set_page(dev, DEVADDR_SERDES, PHY_PAGE_SERDES);
432 if (val < 0)
433 return val;
434
435 /* Power up serdes module */
436 val = mv88e6xxx_phy_read(dev, DEVADDR_SERDES, MII_BMCR);
437 if (val < 0)
438 return val;
439 val &= ~(BMCR_PDOWN);
440 val = mv88e6xxx_phy_write(dev, DEVADDR_SERDES, MII_BMCR, val);
441 if (val < 0)
442 return val;
443
444 return 0;
445}
446
447/*
448 * This function is used to pre-configure the required register
449 * offsets, so that the indirect register access to the PHY registers
450 * is possible. This is necessary to be able to read the PHY ID
451 * while driver probing or in get_phy_id(). The globalN register
452 * offsets must be initialized correctly for a detected switch,
453 * otherwise detection of the PHY ID won't work!
454 */
455static int mv88e6xxx_priv_reg_offs_pre_init(struct udevice *dev)
456{
457 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
458
459 /*
460 * Initial 'port_reg_base' value must be an offset of existing
461 * port register, then reading the ID should succeed. First, try
462 * to read via port registers with device address 0x10 (88E6096
463 * and compatible switches).
464 */
465 priv->port_reg_base = 0x10;
466 priv->id = mv88e6xxx_get_switch_id(dev);
467 if (priv->id != 0xfff0) {
468 priv->global1 = 0x1B;
469 priv->global2 = 0x1C;
470 return 0;
471 }
472
473 /*
474 * Now try via port registers with device address 0x08
475 * (88E6020 and compatible switches).
476 */
477 priv->port_reg_base = 0x08;
478 priv->id = mv88e6xxx_get_switch_id(dev);
479 if (priv->id != 0xfff0) {
480 priv->global1 = 0x0F;
481 priv->global2 = 0x07;
482 return 0;
483 }
484
485 dev_warn(dev, "%s Unknown ID 0x%x\n", __func__, priv->id);
486
487 return -ENODEV;
488}
489
490static int mv88e6xxx_mdio_read(struct udevice *dev, int addr, int devad, int reg)
491{
492 return mv88e6xxx_phy_read_indirect(dev->parent, DEVADDR_PHY(addr),
493 MDIO_DEVAD_NONE, reg);
494}
495
496static int mv88e6xxx_mdio_write(struct udevice *dev, int addr, int devad,
497 int reg, u16 val)
498{
499 return mv88e6xxx_phy_write_indirect(dev->parent, DEVADDR_PHY(addr),
500 MDIO_DEVAD_NONE, reg, val);
501}
502
503static const struct mdio_ops mv88e6xxx_mdio_ops = {
504 .read = mv88e6xxx_mdio_read,
505 .write = mv88e6xxx_mdio_write,
506};
507
508static int mv88e6xxx_mdio_bind(struct udevice *dev)
509{
510 char name[32];
511 static int num_devices;
512
513 sprintf(name, "mv88e6xxx-mdio-%d", num_devices++);
514 device_set_name(dev, name);
515
516 return 0;
517}
518
519U_BOOT_DRIVER(mv88e6xxx_mdio) = {
520 .name = "mv88e6xxx_mdio",
521 .id = UCLASS_MDIO,
522 .ops = &mv88e6xxx_mdio_ops,
523 .bind = mv88e6xxx_mdio_bind,
524 .plat_auto = sizeof(struct mdio_perdev_priv),
525};
526
527static int mv88e6xxx_port_probe(struct udevice *dev, int port, struct phy_device *phy)
528{
529 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
530 int supported;
531
532 switch (priv->id) {
533 case PORT_SWITCH_ID_6020:
534 case PORT_SWITCH_ID_6070:
535 case PORT_SWITCH_ID_6071:
536 supported = PHY_BASIC_FEATURES | SUPPORTED_MII;
537 break;
538 default:
539 supported = PHY_GBIT_FEATURES;
540 break;
541 }
542
543 phy->supported &= supported;
544 phy->advertising &= supported;
545
546 return phy_config(phy);
547}
548
549static int mv88e6xxx_port_enable(struct udevice *dev, int port, struct phy_device *phy)
550{
551 int val, ret;
552
553 dev_dbg(dev, "%s P%d phy:0x%08x %s\n", __func__, port,
554 phy->phy_id, phy_string_for_interface(phy->interface));
555
556 if (phy->phy_id == PHY_FIXED_ID) {
557 /* Physical Control register: Table 62 */
558 val = mv88e6xxx_port_read(dev, port, PORT_REG_PHYS_CTRL);
559
560 /* configure RGMII delays for fixed link */
561 switch (phy->interface) {
562 case PHY_INTERFACE_MODE_RGMII:
563 case PHY_INTERFACE_MODE_RGMII_ID:
564 case PHY_INTERFACE_MODE_RGMII_RXID:
565 case PHY_INTERFACE_MODE_RGMII_TXID:
566 dev_dbg(dev, "configure internal RGMII delays\n");
567
568 /* RGMII delays */
569 val &= ~(PORT_REG_PHYS_CTRL_RGMII_DELAY_RXCLK ||
570 PORT_REG_PHYS_CTRL_RGMII_DELAY_TXCLK);
571 if (phy->interface == PHY_INTERFACE_MODE_RGMII_ID ||
572 phy->interface == PHY_INTERFACE_MODE_RGMII_RXID)
573 val |= PORT_REG_PHYS_CTRL_RGMII_DELAY_RXCLK;
574 if (phy->interface == PHY_INTERFACE_MODE_RGMII_ID ||
575 phy->interface == PHY_INTERFACE_MODE_RGMII_TXID)
576 val |= PORT_REG_PHYS_CTRL_RGMII_DELAY_TXCLK;
577 break;
578 default:
579 break;
580 }
581
582 /* Force Link */
583 val |= PORT_REG_PHYS_CTRL_LINK_VALUE |
584 PORT_REG_PHYS_CTRL_LINK_FORCE;
585
586 ret = mv88e6xxx_port_write(dev, port, PORT_REG_PHYS_CTRL, val);
587 if (ret < 0)
588 return ret;
589
590 if (mv88e6xxx_6352_family(dev)) {
591 /* validate interface type */
592 dev_dbg(dev, "validate interface type\n");
593 val = mv88e6xxx_get_cmode(dev, port);
594 if (val < 0)
595 return val;
596 switch (phy->interface) {
597 case PHY_INTERFACE_MODE_RGMII:
598 case PHY_INTERFACE_MODE_RGMII_RXID:
599 case PHY_INTERFACE_MODE_RGMII_TXID:
600 case PHY_INTERFACE_MODE_RGMII_ID:
601 if (val != PORT_REG_STATUS_CMODE_RGMII)
602 goto mismatch;
603 break;
604 case PHY_INTERFACE_MODE_1000BASEX:
605 if (val != PORT_REG_STATUS_CMODE_1000BASE_X)
606 goto mismatch;
607 break;
608mismatch:
609 default:
610 dev_err(dev, "Mismatched PHY mode %s on port %d!\n",
611 phy_string_for_interface(phy->interface), port);
612 break;
613 }
614 }
615 }
616
617 /* enable port */
618 val = mv88e6xxx_port_read(dev, port, PORT_REG_CTRL);
619 if (val < 0)
620 return val;
621 val &= ~(PORT_REG_CTRL_PSTATE_MASK << PORT_REG_CTRL_PSTATE_SHIFT);
622 val |= (PORT_REG_CTRL_PSTATE_FORWARD << PORT_REG_CTRL_PSTATE_SHIFT);
623 val = mv88e6xxx_port_write(dev, port, PORT_REG_CTRL, val);
624 if (val < 0)
625 return val;
626
627 return phy_startup(phy);
628}
629
630static void mv88e6xxx_port_disable(struct udevice *dev, int port, struct phy_device *phy)
631{
632 int val;
633
634 dev_dbg(dev, "%s P%d phy:0x%08x %s\n", __func__, port,
635 phy->phy_id, phy_string_for_interface(phy->interface));
636
637 val = mv88e6xxx_port_read(dev, port, PORT_REG_CTRL);
638 val &= ~(PORT_REG_CTRL_PSTATE_MASK << PORT_REG_CTRL_PSTATE_SHIFT);
639 val |= (PORT_REG_CTRL_PSTATE_DISABLED << PORT_REG_CTRL_PSTATE_SHIFT);
640 mv88e6xxx_port_write(dev, port, PORT_REG_CTRL, val);
641}
642
643static const struct dsa_ops mv88e6xxx_dsa_ops = {
644 .port_probe = mv88e6xxx_port_probe,
645 .port_enable = mv88e6xxx_port_enable,
646 .port_disable = mv88e6xxx_port_disable,
647};
648
649/* bind and probe the switch mdios */
650static int mv88e6xxx_probe_mdio(struct udevice *dev)
651{
652 struct udevice *mdev;
653 const char *name;
654 ofnode node;
655 int ret;
656
657 /* bind phy ports of mdio child node to mv88e6xxx_mdio device */
658 node = dev_read_subnode(dev, "mdio");
659 if (!ofnode_valid(node))
660 return 0;
661
662 name = ofnode_get_name(node);
663 ret = device_bind_driver_to_node(dev,
664 "mv88e6xxx_mdio",
665 name, node, NULL);
666 if (ret) {
667 dev_err(dev, "failed to bind %s: %d\n", name, ret);
668 } else {
669 /* need to probe it as there is no compatible to do so */
670 ret = uclass_get_device_by_ofnode(UCLASS_MDIO, node, &mdev);
671 if (ret)
672 dev_err(dev, "failed to probe %s: %d\n", name, ret);
673 }
674
675 return ret;
676}
677
678static int mv88e6xxx_probe(struct udevice *dev)
679{
680 struct dsa_pdata *dsa_pdata = dev_get_uclass_plat(dev);
681 struct mv88e6xxx_priv *priv = dev_get_priv(dev);
682 int val, ret;
683
684 if (ofnode_valid(dev_ofnode(dev)) &&
685 !ofnode_is_enabled(dev_ofnode(dev))) {
686 dev_dbg(dev, "switch disabled\n");
687 return -ENODEV;
688 }
689
690 /* probe internal mdio bus */
691 ret = mv88e6xxx_probe_mdio(dev);
692 if (ret)
693 return ret;
694
695 ret = mv88e6xxx_priv_reg_offs_pre_init(dev);
696 if (ret)
697 return ret;
698
699 dev_dbg(dev, "ID=0x%x PORT_BASE=0x%02x GLOBAL1=0x%02x GLOBAL2=0x%02x\n",
700 priv->id, priv->port_reg_base, priv->global1, priv->global2);
701 switch (priv->id) {
702 case PORT_SWITCH_ID_6096:
703 case PORT_SWITCH_ID_6097:
704 case PORT_SWITCH_ID_6172:
705 case PORT_SWITCH_ID_6176:
706 case PORT_SWITCH_ID_6240:
707 case PORT_SWITCH_ID_6352:
708 priv->port_count = 11;
709 break;
710 case PORT_SWITCH_ID_6020:
711 case PORT_SWITCH_ID_6070:
712 case PORT_SWITCH_ID_6071:
713 case PORT_SWITCH_ID_6220:
714 case PORT_SWITCH_ID_6250:
715 case PORT_SWITCH_ID_6320:
716 priv->port_count = 7;
717 break;
718 default:
719 return -ENODEV;
720 }
721
722 ret = mv88e6xxx_switch_reset(dev);
723 if (ret < 0)
724 return ret;
725
726 if (mv88e6xxx_6352_family(dev)) {
727 val = mv88e6xxx_get_cmode(dev, dsa_pdata->cpu_port);
728 if (val < 0)
729 return val;
730 /* initialize serdes */
731 if (val == PORT_REG_STATUS_CMODE_100BASE_X ||
732 val == PORT_REG_STATUS_CMODE_1000BASE_X ||
733 val == PORT_REG_STATUS_CMODE_SGMII) {
734 ret = mv88e6xxx_serdes_init(dev);
735 if (ret < 0)
736 return ret;
737 }
738 }
739
740 return 0;
741}
742
743static const struct udevice_id mv88e6xxx_ids[] = {
744 { .compatible = "marvell,mv88e6085" },
745 { }
746};
747
748U_BOOT_DRIVER(mv88e6xxx) = {
749 .name = "mv88e6xxx",
750 .id = UCLASS_DSA,
751 .of_match = mv88e6xxx_ids,
752 .probe = mv88e6xxx_probe,
753 .ops = &mv88e6xxx_dsa_ops,
754 .priv_auto = sizeof(struct mv88e6xxx_priv),
755};