Port from tsec.c file to add support for m88e1011s, m88e1111s, m88e1118, m88e1121r, m88e1145, m88e1149s.
Signed-off-by: Mingkai Hu <mingkai...@freescale.com> --- drivers/net/fsl_phy.c | 299 +++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/fsl_phy.h | 36 ++++++ 2 files changed, 335 insertions(+), 0 deletions(-) diff --git a/drivers/net/fsl_phy.c b/drivers/net/fsl_phy.c index 7c22666..ad9d65e 100644 --- a/drivers/net/fsl_phy.c +++ b/drivers/net/fsl_phy.c @@ -457,6 +457,245 @@ static int bcm5482_startup(struct mii_info *mii_info) return 0; } +/* Marvell 88E1011S */ +static int m88e1011s_config(struct mii_info *mii_info) +{ + /* Reset and configure the PHY */ + tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET); + + tsec_phy_write(mii_info, 0, 0x1d, 0x1f); + tsec_phy_write(mii_info, 0, 0x1e, 0x200c); + tsec_phy_write(mii_info, 0, 0x1d, 0x5); + tsec_phy_write(mii_info, 0, 0x1e, 0); + tsec_phy_write(mii_info, 0, 0x1e, 0x100); + tsec_phy_write(mii_info, 0, MII_CTRL1000, MII_CTRL1000_INIT); + tsec_phy_write(mii_info, 0, MII_ADVERTISE, MII_ADVERTISE_INIT); + + tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET); + tsec_phy_write(mii_info, 0, MII_BMCR, MII_BMCR_INIT); + + return 0; +} + +/* Parse the 88E1011's status register for speed and duplex + * information + */ +static uint m88e1011s_parse_status(struct mii_info *mii_info) +{ + unsigned int speed; + unsigned int mii_reg; + + mii_reg = tsec_phy_read(mii_info, 0, MIIM_88E1011_PHY_STATUS); + + if ((mii_reg & MIIM_88E1011_PHYSTAT_LINK) && + !(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) { + int i = 0; + + puts("Waiting for PHY realtime link"); + while (!(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) { + /* Timeout reached ? */ + if (i > PHY_AUTONEGOTIATE_TIMEOUT) { + puts(" TIMEOUT !\n"); + mii_info->link = 0; + break; + } + + if ((i++ % 1000) == 0) { + putc('.'); + } + udelay(1000); + mii_reg = tsec_phy_read(mii_info, 0, + MIIM_88E1011_PHY_STATUS); + } + puts(" done\n"); + udelay(500000); /* another 500 ms (results in faster booting) */ + } else { + if (mii_reg & MIIM_88E1011_PHYSTAT_LINK) + mii_info->link = 1; + else + mii_info->link = 0; + } + + if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + + speed = mii_reg & MIIM_88E1011_PHYSTAT_SPEED; + + switch (speed) { + case MIIM_88E1011_PHYSTAT_GBIT: + mii_info->speed = SPEED_1000; + break; + case MIIM_88E1011_PHYSTAT_100: + mii_info->speed = SPEED_100; + break; + default: + mii_info->speed = SPEED_10; + break; + } + + return 0; +} + +static int m88e1011s_startup(struct mii_info *mii_info) +{ + genphy_update_link(mii_info); + m88e1011s_parse_status(mii_info); + + return 0; +} + +/* Marvell 88E1111S */ +static int m88e1111s_config(struct mii_info *mii_info) +{ + int reg; + + /* Reset and configure the PHY */ + tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET); + + if (mii_info->flags & TSEC_REDUCED) { + reg = tsec_phy_read(mii_info, 0, 0x1b); + reg = (reg & 0xfff0) | 0xb; + tsec_phy_write(mii_info, 0, 0x1b, reg); + } else { + tsec_phy_write(mii_info, 0, 0x1b, 0x1f); + } + + tsec_phy_write(mii_info, 0, 0x14, 0x0cd2); + tsec_phy_write(mii_info, 0, MII_CTRL1000, MII_CTRL1000_INIT); + tsec_phy_write(mii_info, 0, MII_ADVERTISE, MII_ADVERTISE_INIT); + tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET); + tsec_phy_write(mii_info, 0, MII_BMCR, MII_BMCR_INIT); + + return 0; +} + +/* Marvell 88E1118 */ +static int m88e1118_config(struct mii_info *mii_info) +{ + /* Reset and configure the PHY */ + tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET); + /* Change Page Number */ + tsec_phy_write(mii_info, 0, 0x16, 0x0002); + /* Delay RGMII TX and RX */ + tsec_phy_write(mii_info, 0, 0x15, 0x1070); + /* Change Page Number */ + tsec_phy_write(mii_info, 0, 0x16, 0x0003); + /* Adjust LED control */ + tsec_phy_write(mii_info, 0, 0x10, 0x021e); + /* Change Page Number */ + tsec_phy_write(mii_info, 0, 0x16, 0x0000); + + tsec_phy_write(mii_info, 0, MII_CTRL1000, MII_CTRL1000_INIT); + tsec_phy_write(mii_info, 0, MII_ADVERTISE, MII_ADVERTISE_INIT); + tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET); + tsec_phy_write(mii_info, 0, MII_BMCR, MII_BMCR_INIT); + + return 0; +} + +static int m88e1118_startup(struct mii_info *mii_info) +{ + /* Change Page Number */ + tsec_phy_write(mii_info, 0, 0x16, 0x0000); + + genphy_update_link(mii_info); + m88e1011s_parse_status(mii_info); + + return 0; +} + +/* Marvell 88E1121R */ +static int m88e1121_config(struct mii_info *mii_info) +{ + int pg; + + /* Reset and configure the PHY */ + tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET); + tsec_phy_write(mii_info, 0, MII_CTRL1000, MII_CTRL1000_INIT); + tsec_phy_write(mii_info, 0, MII_ADVERTISE, MII_ADVERTISE_INIT); + + /* Switch the page to access the led register */ + pg = tsec_phy_read(mii_info, 0, MIIM_88E1121_PHY_PAGE); + tsec_phy_write(mii_info, 0, MIIM_88E1121_PHY_PAGE, + MIIM_88E1121_PHY_LED_PAGE); + /* Configure leds */ + tsec_phy_write(mii_info, 0, MIIM_88E1121_PHY_LED_CTRL, + MIIM_88E1121_PHY_LED_DEF); + /* Restore the page pointer */ + tsec_phy_write(mii_info, 0, MIIM_88E1121_PHY_PAGE, pg); + + tsec_phy_write(mii_info, 0, MII_BMCR, MII_BMCR_INIT); + /* Disable IRQs and de-assert interrupt */ + tsec_phy_write(mii_info, 0, MIIM_88E1121_PHY_IRQ_EN, 0); + tsec_phy_read(mii_info, 0, MIIM_88E1121_PHY_IRQ_STATUS); + + return 0; +} + +/* Marvell 88E1145 */ +static int m88e1145_config(struct mii_info *mii_info) +{ + int reg; + + /* Reset and configure the PHY */ + tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET); + + /* Errata E0, E1 */ + tsec_phy_write(mii_info, 0, 29, 0x001b); + tsec_phy_write(mii_info, 0, 30, 0x418f); + tsec_phy_write(mii_info, 0, 29, 0x0016); + tsec_phy_write(mii_info, 0, 30, 0xa2da); + + tsec_phy_write(mii_info, 0, MII_CTRL1000, MII_CTRL1000_INIT); + tsec_phy_write(mii_info, 0, MII_ADVERTISE, MII_ADVERTISE_INIT); + + tsec_phy_write(mii_info, 0, MIIM_88E1011_PHY_SCR, + MIIM_88E1011_PHY_MDI_X_AUTO); + + reg = tsec_phy_read(mii_info, 0, MIIM_88E1145_PHY_EXT_CR); + if (mii_info->flags & TSEC_REDUCED) + reg |= MIIM_M88E1145_RGMII_RX_DELAY | + MIIM_M88E1145_RGMII_TX_DELAY; + tsec_phy_write(mii_info, 0, MIIM_88E1145_PHY_EXT_CR, reg); + + tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET); + tsec_phy_write(mii_info, 0, MII_BMCR, MII_BMCR_INIT); + + return 0; +} + +static int m88e1145_startup(struct mii_info *mii_info) +{ + genphy_update_link(mii_info); + tsec_phy_write(mii_info, 0, MIIM_88E1111_PHY_LED_CONTROL, + MIIM_88E1111_PHY_LED_DIRECT); + m88e1011s_parse_status(mii_info); + + return 0; +} + +/* Marvell 88E1149S */ +static int m88e1149_config(struct mii_info *mii_info) +{ + /* Reset and configure the PHY */ + tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET); + + tsec_phy_write(mii_info, 0, 0x1d, 0x1f); + tsec_phy_write(mii_info, 0, 0x1e, 0x200c); + tsec_phy_write(mii_info, 0, 0x1d, 0x5); + tsec_phy_write(mii_info, 0, 0x1e, 0x0); + tsec_phy_write(mii_info, 0, 0x1e, 0x100); + + tsec_phy_write(mii_info, 0, MII_CTRL1000, MII_CTRL1000_INIT); + tsec_phy_write(mii_info, 0, MII_ADVERTISE, MII_ADVERTISE_INIT); + tsec_phy_write(mii_info, 0, MII_BMCR, BMCR_RESET); + tsec_phy_write(mii_info, 0, MII_BMCR, MII_BMCR_INIT); + + return 0; +} + /* Vitesse VSC8211 */ static int vsc8211_config(struct mii_info *mii_info) { @@ -601,6 +840,60 @@ static struct phy_info phy_info_BCM5482S = { &genphy_shutdown, }; +static struct phy_info phy_info_M88E1011S = { + "Marvell 88E1011S", + 0x1410c60, + 0xffffff0, + &m88e1011s_config, + &m88e1011s_startup, + &genphy_shutdown, +}; + +static struct phy_info phy_info_M88E1111S = { + "Marvell 88E1111S", + 0x1410cc0, + 0xffffff0, + &m88e1111s_config, + &m88e1011s_startup, + &genphy_shutdown, +}; + +static struct phy_info phy_info_M88E1118 = { + "Marvell 88E1118", + 0x1410e10, + 0xffffff0, + &m88e1118_config, + &m88e1118_startup, + &genphy_shutdown, +}; + +static struct phy_info phy_info_M88E1121R = { + "Marvell 88E1121R", + 0x1410cb0, + 0xffffff0, + &m88e1121_config, + &genphy_startup, + &genphy_shutdown, +}; + +static struct phy_info phy_info_M88E1145 = { + "Marvell 88E1145", + 0x1410cd0, + 0xffffff0, + &m88e1145_config, + &m88e1145_startup, + &genphy_shutdown, +}; + +static struct phy_info phy_info_M88E1149S = { + "Marvell 88E1149S", + 0x1410ca0, + 0xffffff0, + &m88e1149_config, + &m88e1011s_startup, + &genphy_shutdown, +}; + static struct phy_info phy_info_VSC8211 = { "Vitesse VSC8211", 0xfc4b0, @@ -668,6 +961,12 @@ static struct phy_info *phy_info[] = { &phy_info_BCM5461S, &phy_info_BCM5464S, &phy_info_BCM5482S, + &phy_info_M88E1011S, + &phy_info_M88E1111S, + &phy_info_M88E1118, + &phy_info_M88E1121R, + &phy_info_M88E1145, + &phy_info_M88E1149S, &phy_info_VSC8211, &phy_info_VSC8221, &phy_info_VSC8244, diff --git a/drivers/net/fsl_phy.h b/drivers/net/fsl_phy.h index 340527c..5e6d236 100644 --- a/drivers/net/fsl_phy.h +++ b/drivers/net/fsl_phy.h @@ -134,6 +134,42 @@ #define MIIM_CIS8201_EXT_CON1 0x17 #define MIIM_CIS8201_EXTCON1_INIT 0x0000 +/* 88E1011 PHY Status Register */ +#define MIIM_88E1011_PHY_STATUS 0x11 +#define MIIM_88E1011_PHYSTAT_SPEED 0xc000 +#define MIIM_88E1011_PHYSTAT_GBIT 0x8000 +#define MIIM_88E1011_PHYSTAT_100 0x4000 +#define MIIM_88E1011_PHYSTAT_DUPLEX 0x2000 +#define MIIM_88E1011_PHYSTAT_SPDDONE 0x0800 +#define MIIM_88E1011_PHYSTAT_LINK 0x0400 + +#define MIIM_88E1011_PHY_SCR 0x10 +#define MIIM_88E1011_PHY_MDI_X_AUTO 0x0060 + +/* 88E1111 PHY LED Control Register */ +#define MIIM_88E1111_PHY_LED_CONTROL 24 +#define MIIM_88E1111_PHY_LED_DIRECT 0x4100 +#define MIIM_88E1111_PHY_LED_COMBINE 0x411C + +/* 88E1121 PHY LED Control Register */ +#define MIIM_88E1121_PHY_LED_CTRL 16 +#define MIIM_88E1121_PHY_LED_PAGE 3 +#define MIIM_88E1121_PHY_LED_DEF 0x0030 + +/* 88E1121 PHY IRQ Enable/Status Register */ +#define MIIM_88E1121_PHY_IRQ_EN 18 +#define MIIM_88E1121_PHY_IRQ_STATUS 19 + +#define MIIM_88E1121_PHY_PAGE 22 + +/* 88E1145 Extended PHY Specific Control Register */ +#define MIIM_88E1145_PHY_EXT_CR 20 +#define MIIM_M88E1145_RGMII_RX_DELAY 0x0080 +#define MIIM_M88E1145_RGMII_TX_DELAY 0x0002 + +#define MIIM_88E1145_PHY_PAGE 29 +#define MIIM_88E1145_PHY_CAL_OV 30 + /* Entry for Vitesse VSC8244 regs starts here */ /* Vitesse VSC8244 Auxiliary Control/Status Register */ #define MIIM_VSC8244_AUX_CONSTAT 0x1c -- 1.6.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot