[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