[U-Boot] [PATCH] powerpc/t104xrdb: Add l2switch external PHYs configuration

Codrin Ciubotariu codrin.ciubotariu at freescale.com
Mon Mar 17 13:12:18 CET 2014


T1040rdb has 2 VSC8514 quad PHYs attached to 8 ports from a
layer 2 switch. The PHYs Serdes Auto-negotiation must be enabled
in order to have link between internal PHYs and external PHYs.

Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu at freescale.com>
Cc: York Sun <yorksun at freescale.com>
---
 board/freescale/t104xrdb/eth.c | 115 +++++++++++++++++++++++++++++++++++++++++
 include/configs/T1040RDB.h     |   2 +
 2 files changed, 117 insertions(+)

diff --git a/board/freescale/t104xrdb/eth.c b/board/freescale/t104xrdb/eth.c
index 0188fd4..93b758d 100644
--- a/board/freescale/t104xrdb/eth.c
+++ b/board/freescale/t104xrdb/eth.c
@@ -14,12 +14,101 @@
 
 #include "../common/fman.h"
 
+#define PHY_ID_VSC8514			0x00070670
+
+#define PHY_ID_REG1			0x02
+#define PHY_ID_REG2			0x03
+
+#define PHY_EXT_PAGE_ACCESS_EXTENDED3	0x3
+#define PHY_EXT_PAGE_ACCESS_GENERAL	0x10
+#define MIIM_VSC8514_MAC_SERDES_CON	0x10
+#define MIIM_VSC8514_MAC_SERDES_ANEG	0x80
+
+/* Vitesse VSC8514 control register */
+#define MIIM_VSC8514_GENERAL18		0x12
+#define MIIM_VSC8514_GENERAL19		0x13
+#define MIIM_VSC8514_GENERAL23		0x17
+
+/* Vitesse VSC8514 general purpose register 18 */
+#define MIIM_VSC8514_18G_QSGMII		0x80e0
+#define MIIM_VSC8514_18G_CMDSTAT	0x8000
+
+#ifdef CONFIG_T1040RDB
+static int vsc8514_config(struct mii_dev *bus, int phy_addr,
+		phy_interface_t interface)
+{
+	int i;
+	u32 val;
+	int timeout = 1000000;
+
+	/* this is a quad PHY, so we must initialize 4 PHYs
+	 * starting with phy_addr */
+	for (i = phy_addr; i < phy_addr + 4; i++) {
+		/* configure register to access 19G */
+		bus->write(bus, i, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
+			  PHY_EXT_PAGE_ACCESS_GENERAL);
+
+		val = bus->read(bus, i, MDIO_DEVAD_NONE,
+				MIIM_VSC8514_GENERAL19);
+		if (interface == PHY_INTERFACE_MODE_QSGMII) {
+			/* set bit 15:14 to '01' for QSGMII mode */
+			val = (val & 0x3fff) | (1 << 14);
+			bus->write(bus, i, MDIO_DEVAD_NONE,
+				  MIIM_VSC8514_GENERAL19, val);
+			/* Enable 4 ports MAC QSGMII */
+			bus->write(bus, i, MDIO_DEVAD_NONE,
+				MIIM_VSC8514_GENERAL18,
+				MIIM_VSC8514_18G_QSGMII);
+		}
+
+		val = bus->read(bus, i, MDIO_DEVAD_NONE,
+				MIIM_VSC8514_GENERAL18);
+		/* When bit 15 is cleared the command has completed */
+		while ((val & MIIM_VSC8514_18G_CMDSTAT) && timeout--)
+			val = bus->read(bus, i, MDIO_DEVAD_NONE,
+					MIIM_VSC8514_GENERAL18);
+
+		if (0 == timeout) {
+			printf("PHY 8514 config failed\n");
+			return -1;
+		}
+
+		bus->write(bus, i, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
+
+		/* configure register to access 23 */
+		val = bus->read(bus, i, MDIO_DEVAD_NONE,
+				MIIM_VSC8514_GENERAL23);
+		/* set bits 10:8 to '000' */
+		val = (val & 0xf8ff);
+		bus->write(bus, i, MDIO_DEVAD_NONE,
+				MIIM_VSC8514_GENERAL23, val);
+
+		/* Enable Serdes Auto-negotiation */
+		bus->write(bus, i, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
+				PHY_EXT_PAGE_ACCESS_EXTENDED3);
+		val = bus->read(bus, i, MDIO_DEVAD_NONE,
+				MIIM_VSC8514_MAC_SERDES_CON);
+		val = val | MIIM_VSC8514_MAC_SERDES_ANEG;
+		bus->write(bus, i, MDIO_DEVAD_NONE, MIIM_VSC8514_MAC_SERDES_CON,
+				val);
+		bus->write(bus, i, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
+	}
+
+	return 0;
+}
+#endif
+
 int board_eth_init(bd_t *bis)
 {
 #ifdef CONFIG_FMAN_ENET
 	struct memac_mdio_info memac_mdio_info;
 	unsigned int i;
 	int phy_addr = 0;
+#ifdef CONFIG_T1040RDB
+	struct mii_dev *bus;
+	u32 val;
+#endif
+
 	printf("Initializing Fman\n");
 
 	memac_mdio_info.regs =
@@ -66,6 +155,32 @@ int board_eth_init(bd_t *bis)
 	}
 
 	cpu_eth_init(bis);
+
+#ifdef CONFIG_T1040RDB
+	bus = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME);
+
+	/* if there are VSC8514 quad PHYs over QSGMII, configure them
+	 * these are l2switch PHYs and they are not associated
+	 * with ethernet interfaces*/
+	val = 0xFFFF & bus->read(bus, CONFIG_SYS_FM1_QSGMII11_PHY_ADDR,
+			MDIO_DEVAD_NONE, PHY_ID_REG1);
+	val <<= 16;
+	val += 0xFFFF & bus->read(bus, CONFIG_SYS_FM1_QSGMII11_PHY_ADDR,
+			MDIO_DEVAD_NONE, PHY_ID_REG2);
+	if (val == PHY_ID_VSC8514)
+		vsc8514_config(bus, CONFIG_SYS_FM1_QSGMII11_PHY_ADDR,
+			       PHY_INTERFACE_MODE_QSGMII);
+
+	val = 0xFFFF & bus->read(bus, CONFIG_SYS_FM1_QSGMII21_PHY_ADDR,
+			MDIO_DEVAD_NONE, PHY_ID_REG1);
+	val <<= 16;
+	val += 0xFFFF & bus->read(bus, CONFIG_SYS_FM1_QSGMII21_PHY_ADDR,
+			MDIO_DEVAD_NONE, PHY_ID_REG2);
+	if (val == PHY_ID_VSC8514)
+		vsc8514_config(bus, CONFIG_SYS_FM1_QSGMII21_PHY_ADDR,
+			       PHY_INTERFACE_MODE_QSGMII);
+#endif
+
 #endif
 
 	return pci_eth_init(bis);
diff --git a/include/configs/T1040RDB.h b/include/configs/T1040RDB.h
index 395845b..af9d073 100644
--- a/include/configs/T1040RDB.h
+++ b/include/configs/T1040RDB.h
@@ -544,6 +544,8 @@
 #endif
 
 #ifdef CONFIG_FMAN_ENET
+#define CONFIG_SYS_FM1_QSGMII11_PHY_ADDR	0x04
+#define CONFIG_SYS_FM1_QSGMII21_PHY_ADDR	0x08
 #define CONFIG_SYS_SGMII1_PHY_ADDR		0x03
 #define CONFIG_SYS_RGMII1_PHY_ADDR		0x01
 #define CONFIG_SYS_RGMII2_PHY_ADDR		0x02
-- 
1.7.11.7




More information about the U-Boot mailing list