aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin Schulz2018-10-31 05:20:39 -0500
committerJoe Hershberger2018-11-05 10:41:59 -0600
commit05bbd676a7579545bc9c0b7ec590793bd33d2024 (patch)
tree228a6d7f746bc94533006120bf858697b4c51cab /drivers
parentb5bca65e19ff63efbed8056b2651cec25192277a (diff)
downloadu-boot-05bbd676a7579545bc9c0b7ec590793bd33d2024.tar.gz
u-boot-05bbd676a7579545bc9c0b7ec590793bd33d2024.tar.xz
u-boot-05bbd676a7579545bc9c0b7ec590793bd33d2024.zip
net: phy: mscc: add support for VSC8574 PHY
The VSC8574 PHY is a 4-port PHY that is 10/100/1000BASE-T, 100BASE-FX, 1000BASE-X and triple-speed copper SFP capable, can communicate with the MAC via SGMII, QSGMII or 1000BASE-X, supports WOL, downshifting and can set the blinking pattern of each of its 4 LEDs, supports SyncE as well as HP Auto-MDIX detection. This adds support for 10/100/1000BASE-T and SGMII/QSGMII link with the MAC. The VSC8574 has also an internal Intel 8051 microcontroller whose firmware needs to be patched when the PHY is reset. If the 8051's firmware has the expected CRC, its patching can be skipped. The microcontroller can be accessed from any port of the PHY, though the CRC function can only be done through the PHY that is the base PHY of the package (internal address 0) due to a limitation of the firmware. The GPIO register bank is a set of registers that are common to all PHYs in the package. So any modification in any register of this bank affects all PHYs of the package. Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com> Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/phy/mscc.c420
1 files changed, 420 insertions, 0 deletions
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c
index c1b73c6348..72bbda5469 100644
--- a/drivers/net/phy/mscc.c
+++ b/drivers/net/phy/mscc.c
@@ -19,6 +19,7 @@
19#define PHY_ID_VSC8531 0x00070570 19#define PHY_ID_VSC8531 0x00070570
20#define PHY_ID_VSC8540 0x00070760 20#define PHY_ID_VSC8540 0x00070760
21#define PHY_ID_VSC8541 0x00070770 21#define PHY_ID_VSC8541 0x00070770
22#define PHY_ID_VSC8574 0x000704a0
22#define PHY_ID_VSC8584 0x000707c0 23#define PHY_ID_VSC8584 0x000707c0
23 24
24/* Microsemi VSC85xx PHY Register Pages */ 25/* Microsemi VSC85xx PHY Register Pages */
@@ -40,6 +41,9 @@
40#define MSCC_PHY_EXT_CNTL_STATUS 22 41#define MSCC_PHY_EXT_CNTL_STATUS 22
41#define SMI_BROADCAST_WR_EN BIT(0) 42#define SMI_BROADCAST_WR_EN BIT(0)
42 43
44/* Std Page Register 24 */
45#define MSCC_PHY_EXT_PHY_CNTL_2 24
46
43/* Std Page Register 28 - PHY AUX Control/Status */ 47/* Std Page Register 28 - PHY AUX Control/Status */
44#define MIIM_AUX_CNTRL_STAT_REG 28 48#define MIIM_AUX_CNTRL_STAT_REG 28
45#define MIIM_AUX_CNTRL_STAT_ACTIPHY_TO (0x0004) 49#define MIIM_AUX_CNTRL_STAT_ACTIPHY_TO (0x0004)
@@ -127,12 +131,15 @@
127#define DW8051_CLK_EN BIT(4) 131#define DW8051_CLK_EN BIT(4)
128#define MICRO_CLK_EN BIT(3) 132#define MICRO_CLK_EN BIT(3)
129#define MICRO_CLK_DIVIDE(x) ((x) >> 1) 133#define MICRO_CLK_DIVIDE(x) ((x) >> 1)
134#define MSCC_DW8051_VLD_MASK 0xf1ff
130 135
131/* Extended page GPIO register 09G */ 136/* Extended page GPIO register 09G */
132#define MSCC_TRAP_ROM_ADDR(x) ((x) * 2 + 1) 137#define MSCC_TRAP_ROM_ADDR(x) ((x) * 2 + 1)
138#define MSCC_TRAP_ROM_ADDR_SERDES_INIT 0x3eb7
133 139
134/* Extended page GPIO register 10G */ 140/* Extended page GPIO register 10G */
135#define MSCC_PATCH_RAM_ADDR(x) (((x) + 1) * 2) 141#define MSCC_PATCH_RAM_ADDR(x) (((x) + 1) * 2)
142#define MSCC_PATCH_RAM_ADDR_SERDES_INIT 0x4012
136 143
137/* Extended page GPIO register 11G */ 144/* Extended page GPIO register 11G */
138#define MSCC_INT_MEM_ADDR 11 145#define MSCC_INT_MEM_ADDR 11
@@ -166,7 +173,9 @@
166#define PROC_CMD_SGMII_MAC (BIT(5) | BIT(4)) 173#define PROC_CMD_SGMII_MAC (BIT(5) | BIT(4))
167#define PROC_CMD_QSGMII_MAC BIT(5) 174#define PROC_CMD_QSGMII_MAC BIT(5)
168#define PROC_CMD_NO_MAC_CONF (0x00 << 4) 175#define PROC_CMD_NO_MAC_CONF (0x00 << 4)
176#define PROC_CMD_1588_DEFAULT_INIT BIT(4)
169#define PROC_CMD_NOP GENMASK(3, 0) 177#define PROC_CMD_NOP GENMASK(3, 0)
178#define PROC_CMD_PHY_INIT (BIT(3) | BIT(1))
170#define PROC_CMD_CRC16 BIT(3) 179#define PROC_CMD_CRC16 BIT(3)
171#define PROC_CMD_FIBER_MEDIA_CONF BIT(0) 180#define PROC_CMD_FIBER_MEDIA_CONF BIT(0)
172#define PROC_CMD_MCB_ACCESS_MAC_CONF (0x0000 << 0) 181#define PROC_CMD_MCB_ACCESS_MAC_CONF (0x0000 << 0)
@@ -184,6 +193,10 @@
184#define MSCC_PHY_TEST_PAGE_8 8 193#define MSCC_PHY_TEST_PAGE_8 8
185#define TR_CLK_DISABLE BIT(15) 194#define TR_CLK_DISABLE BIT(15)
186 195
196#define MSCC_PHY_TEST_PAGE_9 9
197#define MSCC_PHY_TEST_PAGE_20 20
198#define MSCC_PHY_TEST_PAGE_24 24
199
187/* Token Ring Page 0x52B5 Registers */ 200/* Token Ring Page 0x52B5 Registers */
188#define MSCC_PHY_REG_TR_ADDR_16 16 201#define MSCC_PHY_REG_TR_ADDR_16 16
189#define MSCC_PHY_REG_TR_DATA_17 17 202#define MSCC_PHY_REG_TR_DATA_17 17
@@ -225,6 +238,9 @@
225#define VSC8584_REVB 0x0001 238#define VSC8584_REVB 0x0001
226#define MSCC_DEV_REV_MASK GENMASK(3, 0) 239#define MSCC_DEV_REV_MASK GENMASK(3, 0)
227 240
241#define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000
242#define MSCC_VSC8574_REVB_INT8051_FW_CRC 0x29e8
243
228#define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800 244#define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800
229#define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48 245#define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48
230 246
@@ -373,6 +389,147 @@ static int vsc8584_micro_assert_reset(struct mii_dev *bus, int phy)
373 return 0; 389 return 0;
374} 390}
375 391
392static const u8 fw_patch_vsc8574[] = {
393 0x46, 0x4a, 0x02, 0x43, 0x37, 0x02, 0x46, 0x26, 0x02, 0x46, 0x77, 0x02,
394 0x45, 0x60, 0x02, 0x45, 0xaf, 0xed, 0xff, 0xe5, 0xfc, 0x54, 0x38, 0x64,
395 0x20, 0x70, 0x08, 0x65, 0xff, 0x70, 0x04, 0xed, 0x44, 0x80, 0xff, 0x22,
396 0x8f, 0x19, 0x7b, 0xbb, 0x7d, 0x0e, 0x7f, 0x04, 0x12, 0x3d, 0xd7, 0xef,
397 0x4e, 0x60, 0x03, 0x02, 0x41, 0xf9, 0xe4, 0xf5, 0x1a, 0x74, 0x01, 0x7e,
398 0x00, 0xa8, 0x1a, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8,
399 0xf9, 0xff, 0xef, 0x55, 0x19, 0x70, 0x03, 0x02, 0x41, 0xed, 0x85, 0x1a,
400 0xfb, 0x7b, 0xbb, 0xe4, 0xfd, 0xff, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60,
401 0x03, 0x02, 0x41, 0xed, 0xe5, 0x1a, 0x54, 0x02, 0x75, 0x1d, 0x00, 0x25,
402 0xe0, 0x25, 0xe0, 0xf5, 0x1c, 0xe4, 0x78, 0xc5, 0xf6, 0xd2, 0x0a, 0x12,
403 0x41, 0xfa, 0x7b, 0xff, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef,
404 0x4e, 0x60, 0x03, 0x02, 0x41, 0xe7, 0xc2, 0x0a, 0x74, 0xc7, 0x25, 0x1a,
405 0xf9, 0x74, 0xe7, 0x25, 0x1a, 0xf8, 0xe6, 0x27, 0xf5, 0x1b, 0xe5, 0x1d,
406 0x24, 0x5b, 0x12, 0x45, 0xea, 0x12, 0x3e, 0xda, 0x7b, 0xfc, 0x7d, 0x11,
407 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0x78, 0xcc, 0xef, 0xf6, 0x78, 0xc1, 0xe6,
408 0xfe, 0xef, 0xd3, 0x9e, 0x40, 0x06, 0x78, 0xcc, 0xe6, 0x78, 0xc1, 0xf6,
409 0x12, 0x41, 0xfa, 0x7b, 0xec, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7,
410 0x78, 0xcb, 0xef, 0xf6, 0xbf, 0x07, 0x06, 0x78, 0xc3, 0x76, 0x1a, 0x80,
411 0x1f, 0x78, 0xc5, 0xe6, 0xff, 0x60, 0x0f, 0xc3, 0xe5, 0x1b, 0x9f, 0xff,
412 0x78, 0xcb, 0xe6, 0x85, 0x1b, 0xf0, 0xa4, 0x2f, 0x80, 0x07, 0x78, 0xcb,
413 0xe6, 0x85, 0x1b, 0xf0, 0xa4, 0x78, 0xc3, 0xf6, 0xe4, 0x78, 0xc2, 0xf6,
414 0x78, 0xc2, 0xe6, 0xff, 0xc3, 0x08, 0x96, 0x40, 0x03, 0x02, 0x41, 0xd1,
415 0xef, 0x54, 0x03, 0x60, 0x33, 0x14, 0x60, 0x46, 0x24, 0xfe, 0x60, 0x42,
416 0x04, 0x70, 0x4b, 0xef, 0x24, 0x02, 0xff, 0xe4, 0x33, 0xfe, 0xef, 0x78,
417 0x02, 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0xd8, 0xf8, 0xff, 0xe5, 0x1d,
418 0x24, 0x5c, 0xcd, 0xe5, 0x1c, 0x34, 0xf0, 0xcd, 0x2f, 0xff, 0xed, 0x3e,
419 0xfe, 0x12, 0x46, 0x0d, 0x7d, 0x11, 0x80, 0x0b, 0x78, 0xc2, 0xe6, 0x70,
420 0x04, 0x7d, 0x11, 0x80, 0x02, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3e, 0x9a,
421 0x8e, 0x1e, 0x8f, 0x1f, 0x80, 0x03, 0xe5, 0x1e, 0xff, 0x78, 0xc5, 0xe6,
422 0x06, 0x24, 0xcd, 0xf8, 0xa6, 0x07, 0x78, 0xc2, 0x06, 0xe6, 0xb4, 0x1a,
423 0x0a, 0xe5, 0x1d, 0x24, 0x5c, 0x12, 0x45, 0xea, 0x12, 0x3e, 0xda, 0x78,
424 0xc5, 0xe6, 0x65, 0x1b, 0x70, 0x82, 0x75, 0xdb, 0x20, 0x75, 0xdb, 0x28,
425 0x12, 0x46, 0x02, 0x12, 0x46, 0x02, 0xe5, 0x1a, 0x12, 0x45, 0xf5, 0xe5,
426 0x1a, 0xc3, 0x13, 0x12, 0x45, 0xf5, 0x78, 0xc5, 0x16, 0xe6, 0x24, 0xcd,
427 0xf8, 0xe6, 0xff, 0x7e, 0x08, 0x1e, 0xef, 0xa8, 0x06, 0x08, 0x80, 0x02,
428 0xc3, 0x13, 0xd8, 0xfc, 0xfd, 0xc4, 0x33, 0x54, 0xe0, 0xf5, 0xdb, 0xef,
429 0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x13, 0xd8, 0xfc, 0xfd, 0xc4, 0x33,
430 0x54, 0xe0, 0x44, 0x08, 0xf5, 0xdb, 0xee, 0x70, 0xd8, 0x78, 0xc5, 0xe6,
431 0x70, 0xc8, 0x75, 0xdb, 0x10, 0x02, 0x40, 0xfd, 0x78, 0xc2, 0xe6, 0xc3,
432 0x94, 0x17, 0x50, 0x0e, 0xe5, 0x1d, 0x24, 0x62, 0x12, 0x42, 0x08, 0xe5,
433 0x1d, 0x24, 0x5c, 0x12, 0x42, 0x08, 0x20, 0x0a, 0x03, 0x02, 0x40, 0x76,
434 0x05, 0x1a, 0xe5, 0x1a, 0xc3, 0x94, 0x04, 0x50, 0x03, 0x02, 0x40, 0x3a,
435 0x22, 0xe5, 0x1d, 0x24, 0x5c, 0xff, 0xe5, 0x1c, 0x34, 0xf0, 0xfe, 0x12,
436 0x46, 0x0d, 0x22, 0xff, 0xe5, 0x1c, 0x34, 0xf0, 0xfe, 0x12, 0x46, 0x0d,
437 0x22, 0xe4, 0xf5, 0x19, 0x12, 0x46, 0x43, 0x20, 0xe7, 0x1e, 0x7b, 0xfe,
438 0x12, 0x42, 0xf9, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, 0xc0, 0x07,
439 0x7b, 0x54, 0x12, 0x42, 0xf9, 0xd0, 0xe0, 0x4f, 0xff, 0x74, 0x2a, 0x25,
440 0x19, 0xf8, 0xa6, 0x07, 0x12, 0x46, 0x43, 0x20, 0xe7, 0x03, 0x02, 0x42,
441 0xdf, 0x54, 0x03, 0x64, 0x03, 0x70, 0x03, 0x02, 0x42, 0xcf, 0x7b, 0xcb,
442 0x12, 0x43, 0x2c, 0x8f, 0xfb, 0x7b, 0x30, 0x7d, 0x03, 0xe4, 0xff, 0x12,
443 0x3d, 0xd7, 0xc3, 0xef, 0x94, 0x02, 0xee, 0x94, 0x00, 0x50, 0x2a, 0x12,
444 0x42, 0xec, 0xef, 0x4e, 0x70, 0x23, 0x12, 0x43, 0x04, 0x60, 0x0a, 0x12,
445 0x43, 0x12, 0x70, 0x0c, 0x12, 0x43, 0x1f, 0x70, 0x07, 0x12, 0x46, 0x39,
446 0x7b, 0x03, 0x80, 0x07, 0x12, 0x46, 0x39, 0x12, 0x46, 0x43, 0xfb, 0x7a,
447 0x00, 0x7d, 0x54, 0x80, 0x3e, 0x12, 0x42, 0xec, 0xef, 0x4e, 0x70, 0x24,
448 0x12, 0x43, 0x04, 0x60, 0x0a, 0x12, 0x43, 0x12, 0x70, 0x0f, 0x12, 0x43,
449 0x1f, 0x70, 0x0a, 0x12, 0x46, 0x39, 0xe4, 0xfb, 0xfa, 0x7d, 0xee, 0x80,
450 0x1e, 0x12, 0x46, 0x39, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x80, 0x13,
451 0x12, 0x46, 0x39, 0x12, 0x46, 0x43, 0x54, 0x40, 0xfe, 0xc4, 0x13, 0x13,
452 0x54, 0x03, 0xfb, 0x7a, 0x00, 0x7d, 0xee, 0x12, 0x38, 0xbd, 0x7b, 0xff,
453 0x12, 0x43, 0x2c, 0xef, 0x4e, 0x70, 0x07, 0x74, 0x2a, 0x25, 0x19, 0xf8,
454 0xe4, 0xf6, 0x05, 0x19, 0xe5, 0x19, 0xc3, 0x94, 0x02, 0x50, 0x03, 0x02,
455 0x42, 0x15, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd, 0x7b, 0x20, 0x7f, 0x04,
456 0x12, 0x3d, 0xd7, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd, 0x7f, 0x04, 0x12,
457 0x3d, 0xd7, 0x22, 0x7b, 0x22, 0x7d, 0x18, 0x7f, 0x06, 0x12, 0x3d, 0xd7,
458 0xef, 0x64, 0x01, 0x4e, 0x22, 0x7d, 0x1c, 0xe4, 0xff, 0x12, 0x3e, 0x9a,
459 0xef, 0x54, 0x1b, 0x64, 0x0a, 0x22, 0x7b, 0xcc, 0x7d, 0x10, 0xff, 0x12,
460 0x3d, 0xd7, 0xef, 0x64, 0x01, 0x4e, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd,
461 0x7f, 0x04, 0x12, 0x3d, 0xd7, 0x22, 0xd2, 0x08, 0x75, 0xfb, 0x03, 0xab,
462 0x7e, 0xaa, 0x7d, 0x7d, 0x19, 0x7f, 0x03, 0x12, 0x3e, 0xda, 0xe5, 0x7e,
463 0x54, 0x0f, 0x24, 0xf3, 0x60, 0x03, 0x02, 0x43, 0xe9, 0x12, 0x46, 0x5a,
464 0x12, 0x46, 0x61, 0xd8, 0xfb, 0xff, 0x20, 0xe2, 0x35, 0x13, 0x92, 0x0c,
465 0xef, 0xa2, 0xe1, 0x92, 0x0b, 0x30, 0x0c, 0x2a, 0xe4, 0xf5, 0x10, 0x7b,
466 0xfe, 0x12, 0x43, 0xff, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, 0xc0,
467 0x07, 0x7b, 0x54, 0x12, 0x43, 0xff, 0xd0, 0xe0, 0x4f, 0xff, 0x74, 0x2a,
468 0x25, 0x10, 0xf8, 0xa6, 0x07, 0x05, 0x10, 0xe5, 0x10, 0xc3, 0x94, 0x02,
469 0x40, 0xd9, 0x12, 0x46, 0x5a, 0x12, 0x46, 0x61, 0xd8, 0xfb, 0x54, 0x05,
470 0x64, 0x04, 0x70, 0x27, 0x78, 0xc4, 0xe6, 0x78, 0xc6, 0xf6, 0xe5, 0x7d,
471 0xff, 0x33, 0x95, 0xe0, 0xef, 0x54, 0x0f, 0x78, 0xc4, 0xf6, 0x12, 0x44,
472 0x0a, 0x20, 0x0c, 0x0c, 0x12, 0x46, 0x5a, 0x12, 0x46, 0x61, 0xd8, 0xfb,
473 0x13, 0x92, 0x0d, 0x22, 0xc2, 0x0d, 0x22, 0x12, 0x46, 0x5a, 0x12, 0x46,
474 0x61, 0xd8, 0xfb, 0x54, 0x05, 0x64, 0x05, 0x70, 0x1e, 0x78, 0xc4, 0x7d,
475 0xb8, 0x12, 0x43, 0xf5, 0x78, 0xc1, 0x7d, 0x74, 0x12, 0x43, 0xf5, 0xe4,
476 0x78, 0xc1, 0xf6, 0x22, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x7f, 0x92,
477 0x12, 0x38, 0xbd, 0x22, 0xe6, 0xfb, 0x7a, 0x00, 0x7f, 0x92, 0x12, 0x38,
478 0xbd, 0x22, 0xe5, 0x10, 0x24, 0x17, 0xfd, 0x7f, 0x04, 0x12, 0x3d, 0xd7,
479 0x22, 0x78, 0xc1, 0xe6, 0xfb, 0x7a, 0x00, 0x7d, 0x74, 0x7f, 0x92, 0x12,
480 0x38, 0xbd, 0xe4, 0x78, 0xc1, 0xf6, 0xf5, 0x11, 0x74, 0x01, 0x7e, 0x00,
481 0xa8, 0x11, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9,
482 0xff, 0x78, 0xc4, 0xe6, 0xfd, 0xef, 0x5d, 0x60, 0x44, 0x85, 0x11, 0xfb,
483 0xe5, 0x11, 0x54, 0x02, 0x25, 0xe0, 0x25, 0xe0, 0xfe, 0xe4, 0x24, 0x5b,
484 0xfb, 0xee, 0x12, 0x45, 0xed, 0x12, 0x3e, 0xda, 0x7b, 0x40, 0x7d, 0x11,
485 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0x74, 0xc7, 0x25, 0x11, 0xf8, 0xa6, 0x07,
486 0x7b, 0x11, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60,
487 0x09, 0x74, 0xe7, 0x25, 0x11, 0xf8, 0x76, 0x04, 0x80, 0x07, 0x74, 0xe7,
488 0x25, 0x11, 0xf8, 0x76, 0x0a, 0x05, 0x11, 0xe5, 0x11, 0xc3, 0x94, 0x04,
489 0x40, 0x9a, 0x78, 0xc6, 0xe6, 0x70, 0x15, 0x78, 0xc4, 0xe6, 0x60, 0x10,
490 0x75, 0xd9, 0x38, 0x75, 0xdb, 0x10, 0x7d, 0xfe, 0x12, 0x44, 0xb8, 0x7d,
491 0x76, 0x12, 0x44, 0xb8, 0x79, 0xc6, 0xe7, 0x78, 0xc4, 0x66, 0xff, 0x60,
492 0x03, 0x12, 0x40, 0x25, 0x78, 0xc4, 0xe6, 0x70, 0x09, 0xfb, 0xfa, 0x7d,
493 0xfe, 0x7f, 0x8e, 0x12, 0x38, 0xbd, 0x22, 0x7b, 0x01, 0x7a, 0x00, 0x7f,
494 0x8e, 0x12, 0x38, 0xbd, 0x22, 0xe4, 0xf5, 0xfb, 0x7d, 0x1c, 0xe4, 0xff,
495 0x12, 0x3e, 0x9a, 0xad, 0x07, 0xac, 0x06, 0xec, 0x54, 0xc0, 0xff, 0xed,
496 0x54, 0x3f, 0x4f, 0xf5, 0x20, 0x30, 0x06, 0x2c, 0x30, 0x01, 0x08, 0xa2,
497 0x04, 0x72, 0x03, 0x92, 0x07, 0x80, 0x21, 0x30, 0x04, 0x06, 0x7b, 0xcc,
498 0x7d, 0x11, 0x80, 0x0d, 0x30, 0x03, 0x06, 0x7b, 0xcc, 0x7d, 0x10, 0x80,
499 0x04, 0x7b, 0x66, 0x7d, 0x16, 0xe4, 0xff, 0x12, 0x3d, 0xd7, 0xee, 0x4f,
500 0x24, 0xff, 0x92, 0x07, 0xaf, 0xfb, 0x74, 0x26, 0x2f, 0xf8, 0xe6, 0xff,
501 0xa6, 0x20, 0x20, 0x07, 0x39, 0x8f, 0x20, 0x30, 0x07, 0x34, 0x30, 0x00,
502 0x31, 0x20, 0x04, 0x2e, 0x20, 0x03, 0x2b, 0xe4, 0xf5, 0xff, 0x75, 0xfc,
503 0xc2, 0xe5, 0xfc, 0x30, 0xe0, 0xfb, 0xaf, 0xfe, 0xef, 0x20, 0xe3, 0x1a,
504 0xae, 0xfd, 0x44, 0x08, 0xf5, 0xfe, 0x75, 0xfc, 0x80, 0xe5, 0xfc, 0x30,
505 0xe0, 0xfb, 0x8f, 0xfe, 0x8e, 0xfd, 0x75, 0xfc, 0x80, 0xe5, 0xfc, 0x30,
506 0xe0, 0xfb, 0x05, 0xfb, 0xaf, 0xfb, 0xef, 0xc3, 0x94, 0x04, 0x50, 0x03,
507 0x02, 0x44, 0xc5, 0xe4, 0xf5, 0xfb, 0x22, 0xe5, 0x7e, 0x54, 0x0f, 0x64,
508 0x01, 0x70, 0x23, 0xe5, 0x7e, 0x30, 0xe4, 0x1e, 0x90, 0x47, 0xd0, 0xe0,
509 0x44, 0x02, 0xf0, 0x54, 0xfb, 0xf0, 0x90, 0x47, 0xd4, 0xe0, 0x44, 0x04,
510 0xf0, 0x7b, 0x03, 0x7d, 0x5b, 0x7f, 0x5d, 0x12, 0x36, 0x29, 0x7b, 0x0e,
511 0x80, 0x1c, 0x90, 0x47, 0xd0, 0xe0, 0x54, 0xfd, 0xf0, 0x44, 0x04, 0xf0,
512 0x90, 0x47, 0xd4, 0xe0, 0x54, 0xfb, 0xf0, 0x7b, 0x02, 0x7d, 0x5b, 0x7f,
513 0x5d, 0x12, 0x36, 0x29, 0x7b, 0x06, 0x7d, 0x60, 0x7f, 0x63, 0x12, 0x36,
514 0x29, 0x22, 0xe5, 0x7e, 0x30, 0xe5, 0x35, 0x30, 0xe4, 0x0b, 0x7b, 0x02,
515 0x7d, 0x33, 0x7f, 0x35, 0x12, 0x36, 0x29, 0x80, 0x10, 0x7b, 0x01, 0x7d,
516 0x33, 0x7f, 0x35, 0x12, 0x36, 0x29, 0x90, 0x47, 0xd2, 0xe0, 0x44, 0x04,
517 0xf0, 0x90, 0x47, 0xd2, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x47, 0xd1, 0xe0,
518 0x44, 0x10, 0xf0, 0x7b, 0x05, 0x7d, 0x84, 0x7f, 0x86, 0x12, 0x36, 0x29,
519 0x22, 0xfb, 0xe5, 0x1c, 0x34, 0xf0, 0xfa, 0x7d, 0x10, 0x7f, 0x07, 0x22,
520 0x54, 0x01, 0xc4, 0x33, 0x54, 0xe0, 0xf5, 0xdb, 0x44, 0x08, 0xf5, 0xdb,
521 0x22, 0xf5, 0xdb, 0x75, 0xdb, 0x08, 0xf5, 0xdb, 0x75, 0xdb, 0x08, 0x22,
522 0xab, 0x07, 0xaa, 0x06, 0x7d, 0x10, 0x7f, 0x07, 0x12, 0x3e, 0xda, 0x7b,
523 0xff, 0x7d, 0x10, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60, 0xf3,
524 0x22, 0x12, 0x44, 0xc2, 0x30, 0x0c, 0x03, 0x12, 0x42, 0x12, 0x78, 0xc4,
525 0xe6, 0xff, 0x60, 0x03, 0x12, 0x40, 0x25, 0x22, 0xe5, 0x19, 0x24, 0x17,
526 0x54, 0x1f, 0x44, 0x80, 0xff, 0x22, 0x74, 0x2a, 0x25, 0x19, 0xf8, 0xe6,
527 0x22, 0x12, 0x46, 0x72, 0x12, 0x46, 0x68, 0x90, 0x47, 0xfa, 0xe0, 0x54,
528 0xf8, 0x44, 0x02, 0xf0, 0x22, 0xe5, 0x7e, 0xae, 0x7d, 0x78, 0x04, 0x22,
529 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0x22, 0xe4, 0x78, 0xc4, 0xf6, 0xc2,
530 0x0d, 0x78, 0xc1, 0xf6, 0x22, 0xc2, 0x0c, 0xc2, 0x0b, 0x22, 0x22,
531};
532
376static const u8 fw_patch_vsc8584[] = { 533static const u8 fw_patch_vsc8584[] = {
377 0xe8, 0x59, 0x02, 0xe8, 0x12, 0x02, 0xe8, 0x42, 0x02, 0xe8, 0x5a, 0x02, 534 0xe8, 0x59, 0x02, 0xe8, 0x12, 0x02, 0xe8, 0x42, 0x02, 0xe8, 0x5a, 0x02,
378 0xe8, 0x5b, 0x02, 0xe8, 0x5c, 0xe5, 0x69, 0x54, 0x0f, 0x24, 0xf7, 0x60, 535 0xe8, 0x5b, 0x02, 0xe8, 0x5c, 0xe5, 0x69, 0x54, 0x0f, 0x24, 0xf7, 0x60,
@@ -451,6 +608,247 @@ static int vsc8584_patch_fw(struct mii_dev *bus, int phy, const u8 *fw_patch,
451 return 0; 608 return 0;
452} 609}
453 610
611static bool vsc8574_is_serdes_init(struct mii_dev *bus, int phy)
612{
613 u16 reg;
614 bool ret;
615
616 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
617 MSCC_PHY_PAGE_GPIO);
618
619 reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(1));
620 if (reg != MSCC_TRAP_ROM_ADDR_SERDES_INIT) {
621 ret = false;
622 goto out;
623 }
624
625 reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(1));
626 if (reg != MSCC_PATCH_RAM_ADDR_SERDES_INIT) {
627 ret = false;
628 goto out;
629 }
630
631 reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
632 if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
633 ret = false;
634 goto out;
635 }
636
637 reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS);
638 if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
639 MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
640 ret = false;
641 goto out;
642 }
643
644 ret = true;
645
646out:
647 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
648 MSCC_PHY_PAGE_GPIO);
649
650 return ret;
651}
652
653static int vsc8574_config_pre_init(struct phy_device *phydev)
654{
655 struct mii_dev *bus = phydev->bus;
656 u16 crc, reg, phy0, addr;
657 bool serdes_init;
658 int ret;
659
660 phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
661 MSCC_PHY_PAGE_EXT1);
662 addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
663 addr >>= PHY_CNTL_4_ADDR_POS;
664
665 reg = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_ACTIPHY_CNTL);
666 if (reg & PHY_ADDR_REVERSED)
667 phy0 = phydev->addr + addr;
668 else
669 phy0 = phydev->addr - addr;
670
671 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
672 MSCC_PHY_PAGE_STD);
673
674 /* all writes below are broadcasted to all PHYs in the same package */
675 reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
676 reg |= SMI_BROADCAST_WR_EN;
677 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
678
679 /*
680 * The below register writes are tweaking analog and electrical
681 * configuration that were determined through characterization by PHY
682 * engineers. These don't mean anything more than "these are the best
683 * values".
684 */
685 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
686
687 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
688 MSCC_PHY_PAGE_TEST);
689
690 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_20, 0x4320);
691 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_24, 0x0c00);
692 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_9, 0x18ca);
693 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_5, 0x1b20);
694
695 reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
696 reg |= TR_CLK_DISABLE;
697 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
698
699 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
700 MSCC_PHY_PAGE_TR);
701
702 vsc8584_csr_write(bus, phy0, 0x0fae, 0x000401bd);
703 vsc8584_csr_write(bus, phy0, 0x0fac, 0x000f000f);
704 vsc8584_csr_write(bus, phy0, 0x17a0, 0x00a0f147);
705 vsc8584_csr_write(bus, phy0, 0x0fe4, 0x00052f54);
706 vsc8584_csr_write(bus, phy0, 0x1792, 0x0027303d);
707 vsc8584_csr_write(bus, phy0, 0x07fe, 0x00000704);
708 vsc8584_csr_write(bus, phy0, 0x0fe0, 0x00060150);
709 vsc8584_csr_write(bus, phy0, 0x0f82, 0x0012b00a);
710 vsc8584_csr_write(bus, phy0, 0x0f80, 0x00000d74);
711 vsc8584_csr_write(bus, phy0, 0x02e0, 0x00000012);
712 vsc8584_csr_write(bus, phy0, 0x03a2, 0x00050208);
713 vsc8584_csr_write(bus, phy0, 0x03b2, 0x00009186);
714 vsc8584_csr_write(bus, phy0, 0x0fb0, 0x000e3700);
715 vsc8584_csr_write(bus, phy0, 0x1688, 0x00049f81);
716 vsc8584_csr_write(bus, phy0, 0x0fd2, 0x0000ffff);
717 vsc8584_csr_write(bus, phy0, 0x168a, 0x00039fa2);
718 vsc8584_csr_write(bus, phy0, 0x1690, 0x0020640b);
719 vsc8584_csr_write(bus, phy0, 0x0258, 0x00002220);
720 vsc8584_csr_write(bus, phy0, 0x025a, 0x00002a20);
721 vsc8584_csr_write(bus, phy0, 0x025c, 0x00003060);
722 vsc8584_csr_write(bus, phy0, 0x025e, 0x00003fa0);
723 vsc8584_csr_write(bus, phy0, 0x03a6, 0x0000e0f0);
724 vsc8584_csr_write(bus, phy0, 0x0f92, 0x00001489);
725 vsc8584_csr_write(bus, phy0, 0x16a2, 0x00007000);
726 vsc8584_csr_write(bus, phy0, 0x16a6, 0x00071448);
727 vsc8584_csr_write(bus, phy0, 0x16a0, 0x00eeffdd);
728 vsc8584_csr_write(bus, phy0, 0x0fe8, 0x0091b06c);
729 vsc8584_csr_write(bus, phy0, 0x0fea, 0x00041600);
730 vsc8584_csr_write(bus, phy0, 0x16b0, 0x00eeff00);
731 vsc8584_csr_write(bus, phy0, 0x16b2, 0x00007000);
732 vsc8584_csr_write(bus, phy0, 0x16b4, 0x00000814);
733 vsc8584_csr_write(bus, phy0, 0x0f90, 0x00688980);
734 vsc8584_csr_write(bus, phy0, 0x03a4, 0x0000d8f0);
735 vsc8584_csr_write(bus, phy0, 0x0fc0, 0x00000400);
736 vsc8584_csr_write(bus, phy0, 0x07fa, 0x0050100f);
737 vsc8584_csr_write(bus, phy0, 0x0796, 0x00000003);
738 vsc8584_csr_write(bus, phy0, 0x07f8, 0x00c3ff98);
739 vsc8584_csr_write(bus, phy0, 0x0fa4, 0x0018292a);
740 vsc8584_csr_write(bus, phy0, 0x168c, 0x00d2c46f);
741 vsc8584_csr_write(bus, phy0, 0x17a2, 0x00000620);
742 vsc8584_csr_write(bus, phy0, 0x16a4, 0x0013132f);
743 vsc8584_csr_write(bus, phy0, 0x16a8, 0x00000000);
744 vsc8584_csr_write(bus, phy0, 0x0ffc, 0x00c0a028);
745 vsc8584_csr_write(bus, phy0, 0x0fec, 0x00901c09);
746 vsc8584_csr_write(bus, phy0, 0x0fee, 0x0004a6a1);
747 vsc8584_csr_write(bus, phy0, 0x0ffe, 0x00b01807);
748
749 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
750 MSCC_PHY_PAGE_EXT2);
751
752 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
753
754 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
755 MSCC_PHY_PAGE_TR);
756
757 vsc8584_csr_write(bus, phy0, 0x0486, 0x0008a518);
758 vsc8584_csr_write(bus, phy0, 0x0488, 0x006dc696);
759 vsc8584_csr_write(bus, phy0, 0x048a, 0x00000912);
760 vsc8584_csr_write(bus, phy0, 0x048e, 0x00000db6);
761 vsc8584_csr_write(bus, phy0, 0x049c, 0x00596596);
762 vsc8584_csr_write(bus, phy0, 0x049e, 0x00000514);
763 vsc8584_csr_write(bus, phy0, 0x04a2, 0x00410280);
764 vsc8584_csr_write(bus, phy0, 0x04a4, 0x00000000);
765 vsc8584_csr_write(bus, phy0, 0x04a6, 0x00000000);
766 vsc8584_csr_write(bus, phy0, 0x04a8, 0x00000000);
767 vsc8584_csr_write(bus, phy0, 0x04aa, 0x00000000);
768 vsc8584_csr_write(bus, phy0, 0x04ae, 0x007df7dd);
769 vsc8584_csr_write(bus, phy0, 0x04b0, 0x006d95d4);
770 vsc8584_csr_write(bus, phy0, 0x04b2, 0x00492410);
771
772 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
773 MSCC_PHY_PAGE_TEST);
774
775 reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
776 reg &= ~TR_CLK_DISABLE;
777 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
778
779 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
780 MSCC_PHY_PAGE_STD);
781
782 /* end of write broadcasting */
783 reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
784 reg &= ~SMI_BROADCAST_WR_EN;
785 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
786
787 ret = vsc8584_get_fw_crc(bus, phy0,
788 MSCC_VSC8574_REVB_INT8051_FW_START_ADDR, &crc,
789 fw_patch_vsc8574,
790 ARRAY_SIZE(fw_patch_vsc8574));
791 if (ret)
792 goto out;
793
794 if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
795 serdes_init = vsc8574_is_serdes_init(bus, phy0);
796
797 if (!serdes_init) {
798 ret = vsc8584_micro_assert_reset(bus, phy0);
799 if (ret) {
800 pr_err("failed to assert reset of micro\n");
801 return ret;
802 }
803 }
804 } else {
805 pr_debug("FW CRC is not the expected one, patching FW\n");
806
807 serdes_init = false;
808
809 if (vsc8584_patch_fw(bus, phy0, fw_patch_vsc8574,
810 ARRAY_SIZE(fw_patch_vsc8574)))
811 pr_warn("failed to patch FW, expect non-optimal device\n");
812 }
813
814 if (!serdes_init) {
815 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
816 MSCC_PHY_PAGE_GPIO);
817
818 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(1),
819 MSCC_TRAP_ROM_ADDR_SERDES_INIT);
820 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(1),
821 MSCC_PATCH_RAM_ADDR_SERDES_INIT);
822
823 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
824 EN_PATCH_RAM_TRAP_ADDR(1));
825
826 vsc8584_micro_deassert_reset(bus, phy0, false);
827
828 ret = vsc8584_get_fw_crc(bus, phy0,
829 MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
830 &crc, fw_patch_vsc8574,
831 ARRAY_SIZE(fw_patch_vsc8574));
832 if (ret)
833 goto out;
834
835 if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
836 pr_warn("FW CRC after patching is not the expected one, expect non-optimal device\n");
837 }
838
839 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
840 MSCC_PHY_PAGE_GPIO);
841
842 ret = vsc8584_cmd(bus, phy0, PROC_CMD_1588_DEFAULT_INIT |
843 PROC_CMD_PHY_INIT);
844
845out:
846 bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
847 MSCC_PHY_PAGE_STD);
848
849 return ret;
850}
851
454static int vsc8584_config_pre_init(struct phy_device *phydev) 852static int vsc8584_config_pre_init(struct phy_device *phydev)
455{ 853{
456 struct mii_dev *bus = phydev->bus; 854 struct mii_dev *bus = phydev->bus;
@@ -1010,6 +1408,17 @@ static int vsc8584_config_init(struct phy_device *phydev)
1010 return genphy_config(phydev); 1408 return genphy_config(phydev);
1011} 1409}
1012 1410
1411static struct vsc85xx_priv vsc8574_priv = {
1412 .config_pre = vsc8574_config_pre_init,
1413};
1414
1415static int vsc8574_config(struct phy_device *phydev)
1416{
1417 phydev->priv = &vsc8574_priv;
1418
1419 return vsc8584_config_init(phydev);
1420}
1421
1013static struct vsc85xx_priv vsc8584_priv = { 1422static struct vsc85xx_priv vsc8584_priv = {
1014 .config_pre = vsc8584_config_pre_init, 1423 .config_pre = vsc8584_config_pre_init,
1015}; 1424};
@@ -1061,6 +1470,16 @@ static struct phy_driver VSC8541_driver = {
1061 .shutdown = &genphy_shutdown, 1470 .shutdown = &genphy_shutdown,
1062}; 1471};
1063 1472
1473static struct phy_driver VSC8574_driver = {
1474 .name = "Microsemi VSC8574",
1475 .uid = PHY_ID_VSC8574,
1476 .mask = 0x000ffff0,
1477 .features = PHY_GBIT_FEATURES,
1478 .config = &vsc8574_config,
1479 .startup = &mscc_startup,
1480 .shutdown = &genphy_shutdown,
1481};
1482
1064static struct phy_driver VSC8584_driver = { 1483static struct phy_driver VSC8584_driver = {
1065 .name = "Microsemi VSC8584", 1484 .name = "Microsemi VSC8584",
1066 .uid = PHY_ID_VSC8584, 1485 .uid = PHY_ID_VSC8584,
@@ -1077,6 +1496,7 @@ int phy_mscc_init(void)
1077 phy_register(&VSC8531_driver); 1496 phy_register(&VSC8531_driver);
1078 phy_register(&VSC8540_driver); 1497 phy_register(&VSC8540_driver);
1079 phy_register(&VSC8541_driver); 1498 phy_register(&VSC8541_driver);
1499 phy_register(&VSC8574_driver);
1080 phy_register(&VSC8584_driver); 1500 phy_register(&VSC8584_driver);
1081 1501
1082 return 0; 1502 return 0;