public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Quentin Schulz <quentin.schulz@bootlin.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 3/3] net: phy: mscc: add support for VSC8574 PHY
Date: Fri, 14 Sep 2018 14:48:33 +0200	[thread overview]
Message-ID: <20180914124833.24906-4-quentin.schulz@bootlin.com> (raw)
In-Reply-To: <20180914124833.24906-1-quentin.schulz@bootlin.com>

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>
---
 drivers/net/phy/mscc.c | 413 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 413 insertions(+)

diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c
index b9dfcadd85..2d510c8715 100644
--- a/drivers/net/phy/mscc.c
+++ b/drivers/net/phy/mscc.c
@@ -19,6 +19,7 @@
 #define PHY_ID_VSC8531                  0x00070570
 #define PHY_ID_VSC8540                  0x00070760
 #define PHY_ID_VSC8541                  0x00070770
+#define PHY_ID_VSC8574			0x000704a0
 #define PHY_ID_VSC8584                  0x000707c0
 
 /* Microsemi VSC85xx PHY Register Pages */
@@ -40,6 +41,9 @@
 #define MSCC_PHY_EXT_CNTL_STATUS          22
 #define SMI_BROADCAST_WR_EN              0x0001
 
+/* Std Page Register 24 */
+#define MSCC_PHY_EXT_PHY_CNTL_2           24
+
 /* Std Page Register 28 - PHY AUX Control/Status */
 #define MIIM_AUX_CNTRL_STAT_REG		28
 #define MIIM_AUX_CNTRL_STAT_ACTIPHY_TO	(0x0004)
@@ -127,6 +131,7 @@
 #define DW8051_CLK_EN			0x0010
 #define MICRO_CLK_EN			0x0008
 #define MICRO_CLK_DIVIDE(x)		((x) >> 1)
+#define MSCC_DW8051_VLD_MASK		0xf1ff
 
 /* Extended page GPIO register 09G */
 #define MSCC_TRAP_ROM_ADDR(x)		((x) * 2 + 1)
@@ -166,7 +171,9 @@
 #define PROC_CMD_SGMII_MAC		  0x0030
 #define PROC_CMD_QSGMII_MAC		  0x0020
 #define PROC_CMD_NO_MAC_CONF		  0x0000
+#define PROC_CMD_1588_DEFAULT_INIT	  0x0010
 #define PROC_CMD_NOP			  0x000f
+#define PROC_CMD_PHY_INIT		  0x000a
 #define PROC_CMD_CRC16			  0x0008
 #define PROC_CMD_FIBER_MEDIA_CONF	  0x0001
 #define PROC_CMD_MCB_ACCESS_MAC_CONF	  0x0000
@@ -181,6 +188,9 @@
 /* Test Registers */
 #define MSCC_PHY_TEST_PAGE_5		5
 #define MSCC_PHY_TEST_PAGE_8		8
+#define MSCC_PHY_TEST_PAGE_9		9
+#define MSCC_PHY_TEST_PAGE_20		20
+#define MSCC_PHY_TEST_PAGE_24		24
 
 /* Token Ring Page 0x52B5 Registers */
 #define MSCC_PHY_REG_TR_ADDR_16		16
@@ -223,6 +233,9 @@
 #define VSC8584_REVB		0x0001
 #define MSCC_DEV_REV_MASK	GENMASK(3, 0)
 
+#define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000
+#define MSCC_VSC8574_REVB_INT8051_FW_CRC	0x29e8
+
 #define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR	0xe800
 #define MSCC_VSC8584_REVB_INT8051_FW_CRC	0xfb48
 
@@ -370,6 +383,147 @@ static int vsc8584_micro_assert_reset(struct mii_dev *bus, int phy)
 	return 0;
 }
 
+static const u8 fw_patch_vsc8574[] = {
+	0x46, 0x4a, 0x02, 0x43, 0x37, 0x02, 0x46, 0x26, 0x02, 0x46, 0x77, 0x02,
+	0x45, 0x60, 0x02, 0x45, 0xaf, 0xed, 0xff, 0xe5, 0xfc, 0x54, 0x38, 0x64,
+	0x20, 0x70, 0x08, 0x65, 0xff, 0x70, 0x04, 0xed, 0x44, 0x80, 0xff, 0x22,
+	0x8f, 0x19, 0x7b, 0xbb, 0x7d, 0x0e, 0x7f, 0x04, 0x12, 0x3d, 0xd7, 0xef,
+	0x4e, 0x60, 0x03, 0x02, 0x41, 0xf9, 0xe4, 0xf5, 0x1a, 0x74, 0x01, 0x7e,
+	0x00, 0xa8, 0x1a, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8,
+	0xf9, 0xff, 0xef, 0x55, 0x19, 0x70, 0x03, 0x02, 0x41, 0xed, 0x85, 0x1a,
+	0xfb, 0x7b, 0xbb, 0xe4, 0xfd, 0xff, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60,
+	0x03, 0x02, 0x41, 0xed, 0xe5, 0x1a, 0x54, 0x02, 0x75, 0x1d, 0x00, 0x25,
+	0xe0, 0x25, 0xe0, 0xf5, 0x1c, 0xe4, 0x78, 0xc5, 0xf6, 0xd2, 0x0a, 0x12,
+	0x41, 0xfa, 0x7b, 0xff, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef,
+	0x4e, 0x60, 0x03, 0x02, 0x41, 0xe7, 0xc2, 0x0a, 0x74, 0xc7, 0x25, 0x1a,
+	0xf9, 0x74, 0xe7, 0x25, 0x1a, 0xf8, 0xe6, 0x27, 0xf5, 0x1b, 0xe5, 0x1d,
+	0x24, 0x5b, 0x12, 0x45, 0xea, 0x12, 0x3e, 0xda, 0x7b, 0xfc, 0x7d, 0x11,
+	0x7f, 0x07, 0x12, 0x3d, 0xd7, 0x78, 0xcc, 0xef, 0xf6, 0x78, 0xc1, 0xe6,
+	0xfe, 0xef, 0xd3, 0x9e, 0x40, 0x06, 0x78, 0xcc, 0xe6, 0x78, 0xc1, 0xf6,
+	0x12, 0x41, 0xfa, 0x7b, 0xec, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7,
+	0x78, 0xcb, 0xef, 0xf6, 0xbf, 0x07, 0x06, 0x78, 0xc3, 0x76, 0x1a, 0x80,
+	0x1f, 0x78, 0xc5, 0xe6, 0xff, 0x60, 0x0f, 0xc3, 0xe5, 0x1b, 0x9f, 0xff,
+	0x78, 0xcb, 0xe6, 0x85, 0x1b, 0xf0, 0xa4, 0x2f, 0x80, 0x07, 0x78, 0xcb,
+	0xe6, 0x85, 0x1b, 0xf0, 0xa4, 0x78, 0xc3, 0xf6, 0xe4, 0x78, 0xc2, 0xf6,
+	0x78, 0xc2, 0xe6, 0xff, 0xc3, 0x08, 0x96, 0x40, 0x03, 0x02, 0x41, 0xd1,
+	0xef, 0x54, 0x03, 0x60, 0x33, 0x14, 0x60, 0x46, 0x24, 0xfe, 0x60, 0x42,
+	0x04, 0x70, 0x4b, 0xef, 0x24, 0x02, 0xff, 0xe4, 0x33, 0xfe, 0xef, 0x78,
+	0x02, 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0xd8, 0xf8, 0xff, 0xe5, 0x1d,
+	0x24, 0x5c, 0xcd, 0xe5, 0x1c, 0x34, 0xf0, 0xcd, 0x2f, 0xff, 0xed, 0x3e,
+	0xfe, 0x12, 0x46, 0x0d, 0x7d, 0x11, 0x80, 0x0b, 0x78, 0xc2, 0xe6, 0x70,
+	0x04, 0x7d, 0x11, 0x80, 0x02, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3e, 0x9a,
+	0x8e, 0x1e, 0x8f, 0x1f, 0x80, 0x03, 0xe5, 0x1e, 0xff, 0x78, 0xc5, 0xe6,
+	0x06, 0x24, 0xcd, 0xf8, 0xa6, 0x07, 0x78, 0xc2, 0x06, 0xe6, 0xb4, 0x1a,
+	0x0a, 0xe5, 0x1d, 0x24, 0x5c, 0x12, 0x45, 0xea, 0x12, 0x3e, 0xda, 0x78,
+	0xc5, 0xe6, 0x65, 0x1b, 0x70, 0x82, 0x75, 0xdb, 0x20, 0x75, 0xdb, 0x28,
+	0x12, 0x46, 0x02, 0x12, 0x46, 0x02, 0xe5, 0x1a, 0x12, 0x45, 0xf5, 0xe5,
+	0x1a, 0xc3, 0x13, 0x12, 0x45, 0xf5, 0x78, 0xc5, 0x16, 0xe6, 0x24, 0xcd,
+	0xf8, 0xe6, 0xff, 0x7e, 0x08, 0x1e, 0xef, 0xa8, 0x06, 0x08, 0x80, 0x02,
+	0xc3, 0x13, 0xd8, 0xfc, 0xfd, 0xc4, 0x33, 0x54, 0xe0, 0xf5, 0xdb, 0xef,
+	0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x13, 0xd8, 0xfc, 0xfd, 0xc4, 0x33,
+	0x54, 0xe0, 0x44, 0x08, 0xf5, 0xdb, 0xee, 0x70, 0xd8, 0x78, 0xc5, 0xe6,
+	0x70, 0xc8, 0x75, 0xdb, 0x10, 0x02, 0x40, 0xfd, 0x78, 0xc2, 0xe6, 0xc3,
+	0x94, 0x17, 0x50, 0x0e, 0xe5, 0x1d, 0x24, 0x62, 0x12, 0x42, 0x08, 0xe5,
+	0x1d, 0x24, 0x5c, 0x12, 0x42, 0x08, 0x20, 0x0a, 0x03, 0x02, 0x40, 0x76,
+	0x05, 0x1a, 0xe5, 0x1a, 0xc3, 0x94, 0x04, 0x50, 0x03, 0x02, 0x40, 0x3a,
+	0x22, 0xe5, 0x1d, 0x24, 0x5c, 0xff, 0xe5, 0x1c, 0x34, 0xf0, 0xfe, 0x12,
+	0x46, 0x0d, 0x22, 0xff, 0xe5, 0x1c, 0x34, 0xf0, 0xfe, 0x12, 0x46, 0x0d,
+	0x22, 0xe4, 0xf5, 0x19, 0x12, 0x46, 0x43, 0x20, 0xe7, 0x1e, 0x7b, 0xfe,
+	0x12, 0x42, 0xf9, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, 0xc0, 0x07,
+	0x7b, 0x54, 0x12, 0x42, 0xf9, 0xd0, 0xe0, 0x4f, 0xff, 0x74, 0x2a, 0x25,
+	0x19, 0xf8, 0xa6, 0x07, 0x12, 0x46, 0x43, 0x20, 0xe7, 0x03, 0x02, 0x42,
+	0xdf, 0x54, 0x03, 0x64, 0x03, 0x70, 0x03, 0x02, 0x42, 0xcf, 0x7b, 0xcb,
+	0x12, 0x43, 0x2c, 0x8f, 0xfb, 0x7b, 0x30, 0x7d, 0x03, 0xe4, 0xff, 0x12,
+	0x3d, 0xd7, 0xc3, 0xef, 0x94, 0x02, 0xee, 0x94, 0x00, 0x50, 0x2a, 0x12,
+	0x42, 0xec, 0xef, 0x4e, 0x70, 0x23, 0x12, 0x43, 0x04, 0x60, 0x0a, 0x12,
+	0x43, 0x12, 0x70, 0x0c, 0x12, 0x43, 0x1f, 0x70, 0x07, 0x12, 0x46, 0x39,
+	0x7b, 0x03, 0x80, 0x07, 0x12, 0x46, 0x39, 0x12, 0x46, 0x43, 0xfb, 0x7a,
+	0x00, 0x7d, 0x54, 0x80, 0x3e, 0x12, 0x42, 0xec, 0xef, 0x4e, 0x70, 0x24,
+	0x12, 0x43, 0x04, 0x60, 0x0a, 0x12, 0x43, 0x12, 0x70, 0x0f, 0x12, 0x43,
+	0x1f, 0x70, 0x0a, 0x12, 0x46, 0x39, 0xe4, 0xfb, 0xfa, 0x7d, 0xee, 0x80,
+	0x1e, 0x12, 0x46, 0x39, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x80, 0x13,
+	0x12, 0x46, 0x39, 0x12, 0x46, 0x43, 0x54, 0x40, 0xfe, 0xc4, 0x13, 0x13,
+	0x54, 0x03, 0xfb, 0x7a, 0x00, 0x7d, 0xee, 0x12, 0x38, 0xbd, 0x7b, 0xff,
+	0x12, 0x43, 0x2c, 0xef, 0x4e, 0x70, 0x07, 0x74, 0x2a, 0x25, 0x19, 0xf8,
+	0xe4, 0xf6, 0x05, 0x19, 0xe5, 0x19, 0xc3, 0x94, 0x02, 0x50, 0x03, 0x02,
+	0x42, 0x15, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd, 0x7b, 0x20, 0x7f, 0x04,
+	0x12, 0x3d, 0xd7, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd, 0x7f, 0x04, 0x12,
+	0x3d, 0xd7, 0x22, 0x7b, 0x22, 0x7d, 0x18, 0x7f, 0x06, 0x12, 0x3d, 0xd7,
+	0xef, 0x64, 0x01, 0x4e, 0x22, 0x7d, 0x1c, 0xe4, 0xff, 0x12, 0x3e, 0x9a,
+	0xef, 0x54, 0x1b, 0x64, 0x0a, 0x22, 0x7b, 0xcc, 0x7d, 0x10, 0xff, 0x12,
+	0x3d, 0xd7, 0xef, 0x64, 0x01, 0x4e, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd,
+	0x7f, 0x04, 0x12, 0x3d, 0xd7, 0x22, 0xd2, 0x08, 0x75, 0xfb, 0x03, 0xab,
+	0x7e, 0xaa, 0x7d, 0x7d, 0x19, 0x7f, 0x03, 0x12, 0x3e, 0xda, 0xe5, 0x7e,
+	0x54, 0x0f, 0x24, 0xf3, 0x60, 0x03, 0x02, 0x43, 0xe9, 0x12, 0x46, 0x5a,
+	0x12, 0x46, 0x61, 0xd8, 0xfb, 0xff, 0x20, 0xe2, 0x35, 0x13, 0x92, 0x0c,
+	0xef, 0xa2, 0xe1, 0x92, 0x0b, 0x30, 0x0c, 0x2a, 0xe4, 0xf5, 0x10, 0x7b,
+	0xfe, 0x12, 0x43, 0xff, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, 0xc0,
+	0x07, 0x7b, 0x54, 0x12, 0x43, 0xff, 0xd0, 0xe0, 0x4f, 0xff, 0x74, 0x2a,
+	0x25, 0x10, 0xf8, 0xa6, 0x07, 0x05, 0x10, 0xe5, 0x10, 0xc3, 0x94, 0x02,
+	0x40, 0xd9, 0x12, 0x46, 0x5a, 0x12, 0x46, 0x61, 0xd8, 0xfb, 0x54, 0x05,
+	0x64, 0x04, 0x70, 0x27, 0x78, 0xc4, 0xe6, 0x78, 0xc6, 0xf6, 0xe5, 0x7d,
+	0xff, 0x33, 0x95, 0xe0, 0xef, 0x54, 0x0f, 0x78, 0xc4, 0xf6, 0x12, 0x44,
+	0x0a, 0x20, 0x0c, 0x0c, 0x12, 0x46, 0x5a, 0x12, 0x46, 0x61, 0xd8, 0xfb,
+	0x13, 0x92, 0x0d, 0x22, 0xc2, 0x0d, 0x22, 0x12, 0x46, 0x5a, 0x12, 0x46,
+	0x61, 0xd8, 0xfb, 0x54, 0x05, 0x64, 0x05, 0x70, 0x1e, 0x78, 0xc4, 0x7d,
+	0xb8, 0x12, 0x43, 0xf5, 0x78, 0xc1, 0x7d, 0x74, 0x12, 0x43, 0xf5, 0xe4,
+	0x78, 0xc1, 0xf6, 0x22, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x7f, 0x92,
+	0x12, 0x38, 0xbd, 0x22, 0xe6, 0xfb, 0x7a, 0x00, 0x7f, 0x92, 0x12, 0x38,
+	0xbd, 0x22, 0xe5, 0x10, 0x24, 0x17, 0xfd, 0x7f, 0x04, 0x12, 0x3d, 0xd7,
+	0x22, 0x78, 0xc1, 0xe6, 0xfb, 0x7a, 0x00, 0x7d, 0x74, 0x7f, 0x92, 0x12,
+	0x38, 0xbd, 0xe4, 0x78, 0xc1, 0xf6, 0xf5, 0x11, 0x74, 0x01, 0x7e, 0x00,
+	0xa8, 0x11, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9,
+	0xff, 0x78, 0xc4, 0xe6, 0xfd, 0xef, 0x5d, 0x60, 0x44, 0x85, 0x11, 0xfb,
+	0xe5, 0x11, 0x54, 0x02, 0x25, 0xe0, 0x25, 0xe0, 0xfe, 0xe4, 0x24, 0x5b,
+	0xfb, 0xee, 0x12, 0x45, 0xed, 0x12, 0x3e, 0xda, 0x7b, 0x40, 0x7d, 0x11,
+	0x7f, 0x07, 0x12, 0x3d, 0xd7, 0x74, 0xc7, 0x25, 0x11, 0xf8, 0xa6, 0x07,
+	0x7b, 0x11, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60,
+	0x09, 0x74, 0xe7, 0x25, 0x11, 0xf8, 0x76, 0x04, 0x80, 0x07, 0x74, 0xe7,
+	0x25, 0x11, 0xf8, 0x76, 0x0a, 0x05, 0x11, 0xe5, 0x11, 0xc3, 0x94, 0x04,
+	0x40, 0x9a, 0x78, 0xc6, 0xe6, 0x70, 0x15, 0x78, 0xc4, 0xe6, 0x60, 0x10,
+	0x75, 0xd9, 0x38, 0x75, 0xdb, 0x10, 0x7d, 0xfe, 0x12, 0x44, 0xb8, 0x7d,
+	0x76, 0x12, 0x44, 0xb8, 0x79, 0xc6, 0xe7, 0x78, 0xc4, 0x66, 0xff, 0x60,
+	0x03, 0x12, 0x40, 0x25, 0x78, 0xc4, 0xe6, 0x70, 0x09, 0xfb, 0xfa, 0x7d,
+	0xfe, 0x7f, 0x8e, 0x12, 0x38, 0xbd, 0x22, 0x7b, 0x01, 0x7a, 0x00, 0x7f,
+	0x8e, 0x12, 0x38, 0xbd, 0x22, 0xe4, 0xf5, 0xfb, 0x7d, 0x1c, 0xe4, 0xff,
+	0x12, 0x3e, 0x9a, 0xad, 0x07, 0xac, 0x06, 0xec, 0x54, 0xc0, 0xff, 0xed,
+	0x54, 0x3f, 0x4f, 0xf5, 0x20, 0x30, 0x06, 0x2c, 0x30, 0x01, 0x08, 0xa2,
+	0x04, 0x72, 0x03, 0x92, 0x07, 0x80, 0x21, 0x30, 0x04, 0x06, 0x7b, 0xcc,
+	0x7d, 0x11, 0x80, 0x0d, 0x30, 0x03, 0x06, 0x7b, 0xcc, 0x7d, 0x10, 0x80,
+	0x04, 0x7b, 0x66, 0x7d, 0x16, 0xe4, 0xff, 0x12, 0x3d, 0xd7, 0xee, 0x4f,
+	0x24, 0xff, 0x92, 0x07, 0xaf, 0xfb, 0x74, 0x26, 0x2f, 0xf8, 0xe6, 0xff,
+	0xa6, 0x20, 0x20, 0x07, 0x39, 0x8f, 0x20, 0x30, 0x07, 0x34, 0x30, 0x00,
+	0x31, 0x20, 0x04, 0x2e, 0x20, 0x03, 0x2b, 0xe4, 0xf5, 0xff, 0x75, 0xfc,
+	0xc2, 0xe5, 0xfc, 0x30, 0xe0, 0xfb, 0xaf, 0xfe, 0xef, 0x20, 0xe3, 0x1a,
+	0xae, 0xfd, 0x44, 0x08, 0xf5, 0xfe, 0x75, 0xfc, 0x80, 0xe5, 0xfc, 0x30,
+	0xe0, 0xfb, 0x8f, 0xfe, 0x8e, 0xfd, 0x75, 0xfc, 0x80, 0xe5, 0xfc, 0x30,
+	0xe0, 0xfb, 0x05, 0xfb, 0xaf, 0xfb, 0xef, 0xc3, 0x94, 0x04, 0x50, 0x03,
+	0x02, 0x44, 0xc5, 0xe4, 0xf5, 0xfb, 0x22, 0xe5, 0x7e, 0x54, 0x0f, 0x64,
+	0x01, 0x70, 0x23, 0xe5, 0x7e, 0x30, 0xe4, 0x1e, 0x90, 0x47, 0xd0, 0xe0,
+	0x44, 0x02, 0xf0, 0x54, 0xfb, 0xf0, 0x90, 0x47, 0xd4, 0xe0, 0x44, 0x04,
+	0xf0, 0x7b, 0x03, 0x7d, 0x5b, 0x7f, 0x5d, 0x12, 0x36, 0x29, 0x7b, 0x0e,
+	0x80, 0x1c, 0x90, 0x47, 0xd0, 0xe0, 0x54, 0xfd, 0xf0, 0x44, 0x04, 0xf0,
+	0x90, 0x47, 0xd4, 0xe0, 0x54, 0xfb, 0xf0, 0x7b, 0x02, 0x7d, 0x5b, 0x7f,
+	0x5d, 0x12, 0x36, 0x29, 0x7b, 0x06, 0x7d, 0x60, 0x7f, 0x63, 0x12, 0x36,
+	0x29, 0x22, 0xe5, 0x7e, 0x30, 0xe5, 0x35, 0x30, 0xe4, 0x0b, 0x7b, 0x02,
+	0x7d, 0x33, 0x7f, 0x35, 0x12, 0x36, 0x29, 0x80, 0x10, 0x7b, 0x01, 0x7d,
+	0x33, 0x7f, 0x35, 0x12, 0x36, 0x29, 0x90, 0x47, 0xd2, 0xe0, 0x44, 0x04,
+	0xf0, 0x90, 0x47, 0xd2, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x47, 0xd1, 0xe0,
+	0x44, 0x10, 0xf0, 0x7b, 0x05, 0x7d, 0x84, 0x7f, 0x86, 0x12, 0x36, 0x29,
+	0x22, 0xfb, 0xe5, 0x1c, 0x34, 0xf0, 0xfa, 0x7d, 0x10, 0x7f, 0x07, 0x22,
+	0x54, 0x01, 0xc4, 0x33, 0x54, 0xe0, 0xf5, 0xdb, 0x44, 0x08, 0xf5, 0xdb,
+	0x22, 0xf5, 0xdb, 0x75, 0xdb, 0x08, 0xf5, 0xdb, 0x75, 0xdb, 0x08, 0x22,
+	0xab, 0x07, 0xaa, 0x06, 0x7d, 0x10, 0x7f, 0x07, 0x12, 0x3e, 0xda, 0x7b,
+	0xff, 0x7d, 0x10, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60, 0xf3,
+	0x22, 0x12, 0x44, 0xc2, 0x30, 0x0c, 0x03, 0x12, 0x42, 0x12, 0x78, 0xc4,
+	0xe6, 0xff, 0x60, 0x03, 0x12, 0x40, 0x25, 0x22, 0xe5, 0x19, 0x24, 0x17,
+	0x54, 0x1f, 0x44, 0x80, 0xff, 0x22, 0x74, 0x2a, 0x25, 0x19, 0xf8, 0xe6,
+	0x22, 0x12, 0x46, 0x72, 0x12, 0x46, 0x68, 0x90, 0x47, 0xfa, 0xe0, 0x54,
+	0xf8, 0x44, 0x02, 0xf0, 0x22, 0xe5, 0x7e, 0xae, 0x7d, 0x78, 0x04, 0x22,
+	0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0x22, 0xe4, 0x78, 0xc4, 0xf6, 0xc2,
+	0x0d, 0x78, 0xc1, 0xf6, 0x22, 0xc2, 0x0c, 0xc2, 0x0b, 0x22, 0x22,
+};
+
 static const u8 fw_patch_vsc8584[] = {
 	0xe8, 0x59, 0x02, 0xe8, 0x12, 0x02, 0xe8, 0x42, 0x02, 0xe8, 0x5a, 0x02,
 	0xe8, 0x5b, 0x02, 0xe8, 0x5c, 0xe5, 0x69, 0x54, 0x0f, 0x24, 0xf7, 0x60,
@@ -448,6 +602,243 @@ static int vsc8584_patch_fw(struct mii_dev *bus, int phy, const u8 *fw_patch,
 	return 0;
 }
 
+static bool vsc8574_is_serdes_init(struct mii_dev *bus, int phy)
+{
+	u16 reg;
+	bool ret;
+
+	bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+		   MSCC_PHY_PAGE_GPIO);
+
+	reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(1));
+	if (reg != 0x3eb7) {
+		ret = false;
+		goto out;
+	}
+
+	reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(1));
+	if (reg != 0x4012) {
+		ret = false;
+		goto out;
+	}
+
+	reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
+	if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
+		ret = false;
+		goto out;
+	}
+
+	reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS);
+	if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM |  DW8051_CLK_EN |
+	     MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
+		ret = false;
+		goto out;
+	}
+
+	ret = true;
+
+out:
+	bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+		   MSCC_PHY_PAGE_GPIO);
+
+	return ret;
+}
+
+static int vsc8574_config_pre_init(struct phy_device *phydev)
+{
+	struct mii_dev *bus = phydev->bus;
+	u16 crc, reg, phy0, addr;
+	bool serdes_init;
+	int ret;
+
+	phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+		  MSCC_PHY_PAGE_EXT1);
+	addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
+	addr >>= PHY_CNTL_4_ADDR_POS;
+
+	reg = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_ACTIPHY_CNTL);
+	if (reg & PHY_ADDR_REVERSED)
+		phy0 = phydev->addr + addr;
+	else
+		phy0 = phydev->addr - addr;
+
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+		   MSCC_PHY_PAGE_STD);
+
+	reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
+	reg |= SMI_BROADCAST_WR_EN;
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
+
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+		   MSCC_PHY_PAGE_TEST);
+
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_20, 0x4320);
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_24, 0x0c00);
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_9, 0x18ca);
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_5, 0x1b20);
+
+	reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
+	reg |= 0x8000;
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
+
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+		   MSCC_PHY_PAGE_TR);
+
+	vsc8584_csr_write(bus, phy0, 0x8fae, 0x000401bd);
+	vsc8584_csr_write(bus, phy0, 0x8fac, 0x000f000f);
+	vsc8584_csr_write(bus, phy0, 0x97a0, 0x00a0f147);
+	vsc8584_csr_write(bus, phy0, 0x8fe4, 0x00052f54);
+	vsc8584_csr_write(bus, phy0, 0x9792, 0x0027303d);
+	vsc8584_csr_write(bus, phy0, 0x87fe, 0x00000704);
+	vsc8584_csr_write(bus, phy0, 0x8fe0, 0x00060150);
+	vsc8584_csr_write(bus, phy0, 0x8f82, 0x0012b00a);
+	vsc8584_csr_write(bus, phy0, 0x8f80, 0x00000d74);
+	vsc8584_csr_write(bus, phy0, 0x82e0, 0x00000012);
+	vsc8584_csr_write(bus, phy0, 0x83a2, 0x00050208);
+	vsc8584_csr_write(bus, phy0, 0x83b2, 0x00009186);
+	vsc8584_csr_write(bus, phy0, 0x8fb0, 0x000e3700);
+	vsc8584_csr_write(bus, phy0, 0x9688, 0x00049f81);
+	vsc8584_csr_write(bus, phy0, 0x8fd2, 0x0000ffff);
+	vsc8584_csr_write(bus, phy0, 0x968a, 0x00039fa2);
+	vsc8584_csr_write(bus, phy0, 0x9690, 0x0020640b);
+	vsc8584_csr_write(bus, phy0, 0x8258, 0x00002220);
+	vsc8584_csr_write(bus, phy0, 0x825a, 0x00002a20);
+	vsc8584_csr_write(bus, phy0, 0x825c, 0x00003060);
+	vsc8584_csr_write(bus, phy0, 0x825e, 0x00003fa0);
+	vsc8584_csr_write(bus, phy0, 0x83a6, 0x0000e0f0);
+	vsc8584_csr_write(bus, phy0, 0x8f92, 0x00001489);
+	vsc8584_csr_write(bus, phy0, 0x96a2, 0x00007000);
+	vsc8584_csr_write(bus, phy0, 0x96a6, 0x00071448);
+	vsc8584_csr_write(bus, phy0, 0x96a0, 0x00eeffdd);
+	vsc8584_csr_write(bus, phy0, 0x8fe8, 0x0091b06c);
+	vsc8584_csr_write(bus, phy0, 0x8fea, 0x00041600);
+	vsc8584_csr_write(bus, phy0, 0x96b0, 0x00eeff00);
+	vsc8584_csr_write(bus, phy0, 0x96b2, 0x00007000);
+	vsc8584_csr_write(bus, phy0, 0x96b4, 0x00000814);
+	vsc8584_csr_write(bus, phy0, 0x8f90, 0x00688980);
+	vsc8584_csr_write(bus, phy0, 0x83a4, 0x0000d8f0);
+	vsc8584_csr_write(bus, phy0, 0x8fc0, 0x00000400);
+	vsc8584_csr_write(bus, phy0, 0x87fa, 0x0050100f);
+	vsc8584_csr_write(bus, phy0, 0x8796, 0x00000003);
+	vsc8584_csr_write(bus, phy0, 0x87f8, 0x00c3ff98);
+	vsc8584_csr_write(bus, phy0, 0x8fa4, 0x0018292a);
+	vsc8584_csr_write(bus, phy0, 0x968c, 0x00d2c46f);
+	vsc8584_csr_write(bus, phy0, 0x97a2, 0x00000620);
+	vsc8584_csr_write(bus, phy0, 0x96a4, 0x0013132f);
+	vsc8584_csr_write(bus, phy0, 0x96a8, 0x00000000);
+	vsc8584_csr_write(bus, phy0, 0x8ffc, 0x00c0a028);
+	vsc8584_csr_write(bus, phy0, 0x8fec, 0x00901c09);
+	vsc8584_csr_write(bus, phy0, 0x8fee, 0x0004a6a1);
+	vsc8584_csr_write(bus, phy0, 0x8ffe, 0x00b01807);
+
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+			MSCC_PHY_PAGE_EXT2);
+
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
+
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+		   MSCC_PHY_PAGE_TR);
+
+	vsc8584_csr_write(bus, phy0, 0x8486, 0x0008a518);
+	vsc8584_csr_write(bus, phy0, 0x8488, 0x006dc696);
+	vsc8584_csr_write(bus, phy0, 0x848a, 0x00000912);
+	vsc8584_csr_write(bus, phy0, 0x848e, 0x00000db6);
+	vsc8584_csr_write(bus, phy0, 0x849c, 0x00596596);
+	vsc8584_csr_write(bus, phy0, 0x849e, 0x00000514);
+	vsc8584_csr_write(bus, phy0, 0x84a2, 0x00410280);
+	vsc8584_csr_write(bus, phy0, 0x84a4, 0x00000000);
+	vsc8584_csr_write(bus, phy0, 0x84a6, 0x00000000);
+	vsc8584_csr_write(bus, phy0, 0x84a8, 0x00000000);
+	vsc8584_csr_write(bus, phy0, 0x84aa, 0x00000000);
+	vsc8584_csr_write(bus, phy0, 0x84ae, 0x007df7dd);
+	vsc8584_csr_write(bus, phy0, 0x84b0, 0x006d95d4);
+	vsc8584_csr_write(bus, phy0, 0x84b2, 0x00492410);
+
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+		   MSCC_PHY_PAGE_TEST);
+
+	reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
+	reg &= ~0x8000;
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
+
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+			MSCC_PHY_PAGE_STD);
+
+	reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
+	reg &= ~SMI_BROADCAST_WR_EN;
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+	// Add one byte to size for the one added by the patch_fw function
+	ret = vsc8584_get_fw_crc(bus, phy0,
+				 MSCC_VSC8574_REVB_INT8051_FW_START_ADDR, &crc,
+				 fw_patch_vsc8574,
+				 ARRAY_SIZE(fw_patch_vsc8574));
+	if (ret)
+		goto out;
+
+	if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
+		serdes_init = vsc8574_is_serdes_init(bus, phy0);
+
+		if (!serdes_init) {
+			ret = vsc8584_micro_assert_reset(bus, phy0);
+			if (ret) {
+				pr_err("failed to assert reset of micro\n");
+				return ret;
+			}
+		}
+	} else {
+		pr_debug("FW CRC is not the expected one, patching FW\n");
+
+		serdes_init = false;
+
+		if (vsc8584_patch_fw(bus, phy0, fw_patch_vsc8574,
+				     ARRAY_SIZE(fw_patch_vsc8574)))
+			pr_warn("failed to patch FW, expect non-optimal device\n");
+	}
+
+	if (!serdes_init) {
+		bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+				MSCC_PHY_PAGE_GPIO);
+
+		bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(1),
+			   0x3eb7);
+		bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(1),
+			   0x4012);
+
+		bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
+				EN_PATCH_RAM_TRAP_ADDR(1));
+
+		vsc8584_micro_deassert_reset(bus, phy0, false);
+
+		/* Add one byte to size for the one added by the patch_fw
+		 * function
+		 */
+		ret = vsc8584_get_fw_crc(bus, phy0,
+					 MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
+					 &crc, fw_patch_vsc8574,
+					 ARRAY_SIZE(fw_patch_vsc8574));
+		if (ret)
+			goto out;
+
+		if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
+			pr_warn("FW CRC after patching is not the expected one, expect non-optimal device\n");
+	}
+
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+		   MSCC_PHY_PAGE_GPIO);
+
+	ret = vsc8584_cmd(bus, phy0, PROC_CMD_1588_DEFAULT_INIT |
+			  PROC_CMD_PHY_INIT);
+
+out:
+	bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+			MSCC_PHY_PAGE_STD);
+
+	return ret;
+}
+
 static int vsc8584_config_pre_init(struct phy_device *phydev)
 {
 	struct mii_dev *bus = phydev->bus;
@@ -999,6 +1390,17 @@ static int vsc8584_config_init(struct phy_device *phydev)
 	return genphy_config(phydev);
 }
 
+static struct vsc85xx_priv vsc8574_priv = {
+	.config_pre = vsc8574_config_pre_init,
+};
+
+static int vsc8574_config(struct phy_device *phydev)
+{
+	phydev->priv = &vsc8574_priv;
+
+	return vsc8584_config_init(phydev);
+}
+
 static struct vsc85xx_priv vsc8584_priv = {
 	.config_pre = vsc8584_config_pre_init,
 };
@@ -1050,6 +1452,16 @@ static struct phy_driver VSC8541_driver = {
 	.shutdown = &genphy_shutdown,
 };
 
+static struct phy_driver VSC8574_driver = {
+	.name = "Microsemi VSC8574",
+	.uid = PHY_ID_VSC8574,
+	.mask = 0x000ffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &vsc8574_config,
+	.startup = &mscc_startup,
+	.shutdown = &genphy_shutdown,
+};
+
 static struct phy_driver VSC8584_driver = {
 	.name = "Microsemi VSC8584",
 	.uid = PHY_ID_VSC8584,
@@ -1066,6 +1478,7 @@ int phy_mscc_init(void)
 	phy_register(&VSC8531_driver);
 	phy_register(&VSC8540_driver);
 	phy_register(&VSC8541_driver);
+	phy_register(&VSC8574_driver);
 	phy_register(&VSC8584_driver);
 
 	return 0;
-- 
2.17.1

  parent reply	other threads:[~2018-09-14 12:48 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-14 12:48 [U-Boot] [PATCH 0/3] add support for VSC8584 and VSC8574 Microsemi PHYs Quentin Schulz
2018-09-14 12:48 ` [U-Boot] [PATCH 1/3] net: phy: mscc: add support for VSC8584 PHY Quentin Schulz
2018-10-22 21:52   ` Joe Hershberger
2018-10-31  8:20     ` Quentin Schulz
2018-09-14 12:48 ` [U-Boot] [PATCH 2/3] net: phy: mscc: factorize part of config function for VSC8584 Quentin Schulz
2018-10-22 22:11   ` Joe Hershberger
2018-09-14 12:48 ` Quentin Schulz [this message]
2018-10-22 22:25   ` [U-Boot] [PATCH 3/3] net: phy: mscc: add support for VSC8574 PHY Joe Hershberger
2018-10-30 15:54     ` Quentin Schulz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180914124833.24906-4-quentin.schulz@bootlin.com \
    --to=quentin.schulz@bootlin.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox