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