>From 452bf05d5e3add67f2dded5537da4bb5d0527e70 Mon Sep 17 00:00:00 2001 From: John Haechten <john.haech...@microsemi.com> Date: Mon, 14 Nov 2016 08:44:02 -0800 Subject: [PATCH 1/2] Add-MSCC-Phys-VSC8530-VSC8531-VSC8540-VSC8541 (C) Copyright 2016 Microsemi Corporation, MIT License (MIT) Author:John Haechten <john.haech...@microsemi.com> Signed-off-by:John Haechten <john.haech...@microsemi.com>; Reviewed-by:Howard Hicks <howard.hi...@microsemi.com>; Series-to:u-boot;phy; Cc:Allan Nielsen <allan.niel...@microsemi.com>; Tested-by:Howard Hicks <howard.hi...@microsemi.com> Series-name:Add-Support-for-MSCC-PHY-VSC8530-VSC8531-VSC8540-VSC8541 Cover-letter: Add u-boot support for MSCC 1G Phy family: VSC8530/VSC8531/VSC8540/VSC8541 END Series-notes: Tested using BeagleBoneBlack, bb.org-overlays, v2016.11-rc3, with 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch applied END
Signed-off-by: John Haechten <john.haech...@microsemi.com> --- drivers/net/phy/Makefile | 1 + drivers/net/phy/mscc.c | 462 ++++++++++++++++++++++++++++++++++++ drivers/net/phy/phy.c | 3 + include/config_phylib_all_drivers.h | 1 + include/configs/am335x_evm.h | 3 + include/phy.h | 1 + scripts/config_whitelist.txt | 1 + 7 files changed, 472 insertions(+) create mode 100644 drivers/net/phy/mscc.c diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 1e299b9..d372971 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -27,3 +27,4 @@ obj-$(CONFIG_PHY_TERANETICS) += teranetics.o obj-$(CONFIG_PHY_TI) += ti.o obj-$(CONFIG_PHY_XILINX) += xilinx_phy.o obj-$(CONFIG_PHY_VITESSE) += vitesse.o +obj-$(CONFIG_PHY_MSCC) += mscc.o diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c new file mode 100644 index 0000000..e6d8fcd --- /dev/null +++ b/drivers/net/phy/mscc.c @@ -0,0 +1,462 @@ +/* + * Driver for Microsemi VSC85xx PHYs + * + * Author: John Haechten + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Microsemi Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include <miiphy.h> + +/* Note: To include this PHY Driver file, #define CONFIG_PHY_MSCC */ + +/* Microsemi PHY ID's */ +#define PHY_ID_VSC8530 0x00070560 +#define PHY_ID_VSC8531 0x00070570 +#define PHY_ID_VSC8540 0x00070760 +#define PHY_ID_VSC8541 0x00070770 + +/* Microsemi VSC85xx PHY Register Pages */ +#define MSCC_EXT_PAGE_ACCESS 31 /* Page Access Register */ +#define MSCC_PHY_PAGE_STD 0x0000 /* Standard registers */ +#define MSCC_PHY_PAGE_EXT1 0x0001 /* Extended registers - page 1 */ +#define MSCC_PHY_PAGE_EXT2 0x0002 /* Extended registers - page 2 */ +#define MSCC_PHY_PAGE_EXT3 0x0003 /* Extended registers - page 3 */ +#define MSCC_PHY_PAGE_EXT4 0x0004 /* Extended registers - page 4 */ +#define MSCC_PHY_PAGE_GPIO 0x0010 /* GPIO registers */ +#define MSCC_PHY_PAGE_TEST 0x2A30 /* TEST Page registers */ +#define MSCC_PHY_PAGE_TR 0x52B5 /* Token Ring Page registers */ + +/* MSCC PHY Auxiliary Control/Status Register */ +#define MIIM_AUX_CNTRL_STAT_REG 0x1c +#define MIIM_AUX_CNTRL_STAT_ACTIPHY_TO 0x0004 +#define MIIM_AUX_CNTRL_STAT_F_DUPLEX 0x0020 +#define MIIM_AUX_CNTRL_STAT_SPEED_MASK 0x0018 +#define MIIM_AUX_CNTRL_STAT_SPEED_POS (3) +#define MIIM_AUX_CNTRL_STAT_SPEED_10M (0x0) +#define MIIM_AUX_CNTRL_STAT_SPEED_100M (0x1) +#define MIIM_AUX_CNTRL_STAT_SPEED_1000M (0x2) + +#define MSCC_PHY_EXT_PHY_CNTL_1 23 +#define MAC_IF_SELECTION_MASK 0x1800 +#define MAC_IF_SELECTION_GMII 0 +#define MAC_IF_SELECTION_RMII 1 +#define MAC_IF_SELECTION_RGMII 2 +#define MAC_IF_SELECTION_POS 11 +# +/* Extended Page 2 Registers */ +#define MSCC_PHY_RGMII_CNTL 20 +#define VSC_FAST_LINK_FAIL2_ENA_MASK 0x8000 +#define RGMII_RX_CLK_OUT_POS 11 +#define RGMII_RX_CLK_OUT_DIS 1 +#define RGMII_RX_CLK_DELAY_POS 4 +#define RGMII_RX_CLK_DELAY_MASK 0x0070 +#define RGMII_TX_CLK_DELAY_POS 0 +#define RGMII_TX_CLK_DELAY_MASK 0x0007 + +#define MSCC_PHY_WOL_MAC_CONTROL 27 +#define EDGE_RATE_CNTL_POS 5 +#define EDGE_RATE_CNTL_MASK 0x00E0 + +/* Token Ring Registers */ +#define MSCC_PHY_REG_TR_ADDR_16 16 +#define MSCC_PHY_REG_TR_DATA_17 17 +#define MSCC_PHY_REG_TR_DATA_18 18 + +/* Token Ring Registers */ +#define MSCC_PHY_TR_LINKDETCTRL_POS 3 +#define MSCC_PHY_TR_LINKDETCTRL_MASK 0xffe7 +#define MSCC_PHY_TR_VGATHRESH100_POS 0 +#define MSCC_PHY_TR_VGATHRESH100_MASK 0xff80 +#define MSCC_PHY_TR_VGAGAIN10_U_POS 0 +#define MSCC_PHY_TR_VGAGAIN10_U_MASK 0xfffe +#define MSCC_PHY_TR_VGAGAIN10_L_POS 12 +#define MSCC_PHY_TR_VGAGAIN10_L_MASK 0x0fff + + +#define MSCC_PHY_RESET_TIMEOUT (100) +#define MSCC_PHY_MICRO_TIMEOUT (500) + + +/**< RGMII/GMII Clock Delay (Skew) Options */ +enum vsc_phy_rgmii_skew { + VSC_PHY_RGMII_DELAY_200_PS, + VSC_PHY_RGMII_DELAY_800_PS, + VSC_PHY_RGMII_DELAY_1100_PS, + VSC_PHY_RGMII_DELAY_1700_PS, + VSC_PHY_RGMII_DELAY_2000_PS, + VSC_PHY_RGMII_DELAY_2300_PS, + VSC_PHY_RGMII_DELAY_2600_PS, + VSC_PHY_RGMII_DELAY_3400_PS +}; + +/**< MAC i/f Clock Edge Rage Control (Slew), See Reg27E2 */ +enum vsc_phy_clk_slew { + VSC_PHY_CLK_SLEW_RATE_0, + VSC_PHY_CLK_SLEW_RATE_1, + VSC_PHY_CLK_SLEW_RATE_2, + VSC_PHY_CLK_SLEW_RATE_3, + VSC_PHY_CLK_SLEW_RATE_4, + VSC_PHY_CLK_SLEW_RATE_5, + VSC_PHY_CLK_SLEW_RATE_6, + VSC_PHY_CLK_SLEW_RATE_7 +}; + + +static int mscc_vsc8531_vsc8541_init_scripts(struct phy_device *phydev) +{ + u16 reg_val17; + u16 reg_val18; + + /* Set to Access Token Ring Registers */ + phy_write(phydev, MDIO_DEVAD_NONE, + MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR); + + /* Update LinkDetectCtrl */ + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0xA7F8); + reg_val17 = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17); + reg_val17 &= MSCC_PHY_TR_LINKDETCTRL_MASK; + reg_val17 |= (3 << MSCC_PHY_TR_LINKDETCTRL_POS); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val17); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0x87F8); + + /* Update VgaThresh100 */ + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0xAFA4); + reg_val18 = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18); + reg_val18 &= MSCC_PHY_TR_VGATHRESH100_MASK; + reg_val18 |= (24 << MSCC_PHY_TR_VGATHRESH100_POS); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val18); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0x8FA4); + + /* Update VgaGain10 */ + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0xAF92); + reg_val18 = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18); + reg_val17 = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17); + reg_val18 &= MSCC_PHY_TR_VGAGAIN10_U_MASK; + reg_val18 |= 0 << MSCC_PHY_TR_VGAGAIN10_U_POS; + reg_val17 &= MSCC_PHY_TR_VGAGAIN10_L_MASK; + reg_val17 |= (1 << MSCC_PHY_TR_VGAGAIN10_L_POS); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val18); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val17); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0x8F92); + + /* Set back to Access Standard Page Registers */ + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_STD); + + return 0; +} + +static int mscc_parse_status(struct phy_device *phydev) +{ + u16 speed; + u16 mii_reg; + + mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_AUX_CNTRL_STAT_REG); + + if (mii_reg & MIIM_AUX_CNTRL_STAT_F_DUPLEX) + phydev->duplex = DUPLEX_FULL; + else + phydev->duplex = DUPLEX_HALF; + + speed = mii_reg & MIIM_AUX_CNTRL_STAT_SPEED_MASK; + speed = speed >> MIIM_AUX_CNTRL_STAT_SPEED_POS; + + switch (speed) { + case MIIM_AUX_CNTRL_STAT_SPEED_1000M: + phydev->speed = SPEED_1000; + break; + case MIIM_AUX_CNTRL_STAT_SPEED_100M: + phydev->speed = SPEED_100; + break; + case MIIM_AUX_CNTRL_STAT_SPEED_10M: + phydev->speed = SPEED_10; + break; + default: + phydev->speed = SPEED_10; + break; + } + + return 0; +} + +static int mscc_startup(struct phy_device *phydev) +{ + int ret; + + ret = genphy_update_link(phydev); + if (ret) + return ret; + return mscc_parse_status(phydev); +} + +static int mscc_phy_soft_reset(struct phy_device *phydev) +{ + int rc = 0; + u16 timeout = MSCC_PHY_RESET_TIMEOUT; + u16 reg_val = 0; + + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_STD); + + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); + reg_val |= BMCR_RESET; + phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, reg_val); + + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); + + while ((reg_val & BMCR_RESET) && (timeout > 0)) { + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); + timeout--; + udelay(1000); /* 1 ms */ + } + + if (timeout == 0) + rc = -ETIME; + + return rc; +} + +static int vsc8531_vsc8541_mac_config(struct phy_device *phydev) +{ + u16 reg_val = 0; + + /* For VSC8530/31 the only MAC modes are RMII/RGMII. */ + /* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */ + /* Setup MAC Configuration */ + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_STD); + + switch (phydev->interface) { + case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_GMII: + /* Set Reg23.12:11=0 */ + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, + MSCC_PHY_EXT_PHY_CNTL_1); + reg_val &= ~(MAC_IF_SELECTION_MASK); + reg_val |= MAC_IF_SELECTION_GMII << MAC_IF_SELECTION_POS; + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_1, + reg_val); + + /* Set Reg20E2.11=1 */ + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_EXT2); + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, + MSCC_PHY_RGMII_CNTL); + reg_val &= ~(0x1 << RGMII_RX_CLK_OUT_POS); + reg_val |= (0x1 << RGMII_RX_CLK_OUT_POS); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL, + reg_val); + printf("PHY 8531 config = (G)MII\n"); + break; + + case PHY_INTERFACE_MODE_RMII: + /* Set Reg23.12:11=1 */ + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, + MSCC_PHY_EXT_PHY_CNTL_1); + reg_val &= ~(MAC_IF_SELECTION_MASK); + reg_val |= MAC_IF_SELECTION_RMII << MAC_IF_SELECTION_POS; + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_1, + reg_val); + + /* Clear Reg20E2.11=0 */ + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_EXT2); + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, + MSCC_PHY_RGMII_CNTL); + reg_val &= ~(0x1 << RGMII_RX_CLK_OUT_POS); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL, + reg_val); + printf("PHY 8531 config = RMII\n"); + break; + + case PHY_INTERFACE_MODE_RGMII: + /* Set Reg23.12:11=2 */ + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, + MSCC_PHY_EXT_PHY_CNTL_1); + reg_val &= ~(MAC_IF_SELECTION_MASK); + reg_val |= MAC_IF_SELECTION_RGMII << MAC_IF_SELECTION_POS; + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_1, + reg_val); + + /* Clear Reg20E2.11=0 */ + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_EXT2); + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, + MSCC_PHY_RGMII_CNTL); + reg_val &= ~(0x1 << RGMII_RX_CLK_OUT_POS); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL, + reg_val); + printf("PHY 8531 config = RGMII\n"); + break; + + default: + return -EINVAL; + } + + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_STD); + return 0; +} + +static int vsc8531_config(struct phy_device *phydev) +{ + enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS; + enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS; + enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4; + u16 reg_val; + + /* For VSC8530/31 and VSC8540/41 the init scripts are the same */ + mscc_vsc8531_vsc8541_init_scripts(phydev); + + /* For VSC8530/31 the only MAC modes are RMII/RGMII. */ + switch (phydev->interface) { + case PHY_INTERFACE_MODE_RMII: + case PHY_INTERFACE_MODE_RGMII: + vsc8531_vsc8541_mac_config(phydev); + mscc_phy_soft_reset(phydev); + break; + default: + printf("PHY 8531 MAC i/f config Error: mac i/f = 0x%x\n", + phydev->interface); + return -EINVAL; + } + + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_EXT2); + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL); + reg_val &= ~(RGMII_RX_CLK_DELAY_MASK | RGMII_TX_CLK_DELAY_MASK); + reg_val |= (rx_clk_skew << RGMII_RX_CLK_DELAY_POS) | + (tx_clk_skew << RGMII_TX_CLK_DELAY_POS); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL, reg_val); + + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL); + reg_val &= ~(EDGE_RATE_CNTL_MASK); + reg_val |= edge_rate << EDGE_RATE_CNTL_POS; + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_STD); + + printf("printf: PHY VSC8530/31 MAC i/f config done - going to ANEG\n"); + + genphy_config_aneg(phydev); + + return 0; +} + +static int vsc8541_config(struct phy_device *phydev) +{ + enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS; + enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS; + enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4; + u16 reg_val; + + /* For VSC8530/31 and VSC8540/41 the init scripts are the same */ + mscc_vsc8531_vsc8541_init_scripts(phydev); + + /* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */ + switch (phydev->interface) { + case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_GMII: + case PHY_INTERFACE_MODE_RMII: + case PHY_INTERFACE_MODE_RGMII: + vsc8531_vsc8541_mac_config(phydev); + mscc_phy_soft_reset(phydev); + break; + default: + printf("PHY 8541 MAC i/f config Error: mac i/f = 0x%x\n", + phydev->interface); + return -EINVAL; + } + + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_EXT2); + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL); + reg_val &= ~(RGMII_RX_CLK_DELAY_MASK | RGMII_TX_CLK_DELAY_MASK); + reg_val |= (rx_clk_skew << RGMII_RX_CLK_DELAY_POS) | + (tx_clk_skew << RGMII_TX_CLK_DELAY_POS); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL, reg_val); + + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL); + reg_val &= ~(EDGE_RATE_CNTL_MASK); + reg_val |= edge_rate << EDGE_RATE_CNTL_POS; + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val); + phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS, + MSCC_PHY_PAGE_STD); + + printf("printf: PHY VSC8540/41 MAC i/f config done - going to ANEG\n"); + + genphy_config_aneg(phydev); + + return 0; +} + +static struct phy_driver VSC8530_driver = { + .name = "Microsemi VSC8530", + .uid = PHY_ID_VSC8530, + .mask = 0x000ffff0, + .features = PHY_BASIC_FEATURES, + .config = &vsc8531_config, + .startup = &mscc_startup, + .shutdown = &genphy_shutdown, +}; + +static struct phy_driver VSC8531_driver = { + .name = "Microsemi VSC8531", + .uid = PHY_ID_VSC8531, + .mask = 0x000ffff0, + .features = PHY_GBIT_FEATURES, + .config = &vsc8531_config, + .startup = &mscc_startup, + .shutdown = &genphy_shutdown, +}; + +static struct phy_driver VSC8540_driver = { + .name = "Microsemi VSC8540", + .uid = PHY_ID_VSC8540, + .mask = 0x000ffff0, + .features = PHY_BASIC_FEATURES, + .config = &vsc8541_config, + .startup = &mscc_startup, + .shutdown = &genphy_shutdown, +}; + +static struct phy_driver VSC8541_driver = { + .name = "Microsemi VSC8541", + .uid = PHY_ID_VSC8541, + .mask = 0x000ffff0, + .features = PHY_GBIT_FEATURES, + .config = &vsc8541_config, + .startup = &mscc_startup, + .shutdown = &genphy_shutdown, +}; + +int phy_mscc_init(void) +{ + phy_register(&VSC8530_driver); + phy_register(&VSC8531_driver); + phy_register(&VSC8540_driver); + phy_register(&VSC8541_driver); + + return 0; +} diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 80bdfb6..539abee 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -512,6 +512,9 @@ int phy_init(void) #ifdef CONFIG_PHY_XILINX phy_xilinx_init(); #endif +#ifdef CONFIG_PHY_MSCC + phy_mscc_init(); +#endif return 0; } diff --git a/include/config_phylib_all_drivers.h b/include/config_phylib_all_drivers.h index 12828c6..d2965ed 100644 --- a/include/config_phylib_all_drivers.h +++ b/include/config_phylib_all_drivers.h @@ -14,6 +14,7 @@ #ifdef CONFIG_PHYLIB +#define CONFIG_PHY_MSCC #define CONFIG_PHY_VITESSE #define CONFIG_PHY_MARVELL #define CONFIG_PHY_MICREL diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index ec70b72..694e249 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -433,6 +433,9 @@ #define CONFIG_PHY_SMSC /* Enable Atheros phy driver */ #define CONFIG_PHY_ATHEROS +/* Enable MSCC phy driver */ +#define CONFIG_PHY_MSCC + /* * NOR Size = 16 MiB diff --git a/include/phy.h b/include/phy.h index 268d9a1..5477496 100644 --- a/include/phy.h +++ b/include/phy.h @@ -266,6 +266,7 @@ int phy_teranetics_init(void); int phy_ti_init(void); int phy_vitesse_init(void); int phy_xilinx_init(void); +int phy_mscc_init(void); int board_phy_config(struct phy_device *phydev); int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id); diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index d476367..cb38b49 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -3553,6 +3553,7 @@ CONFIG_PHY_MICREL CONFIG_PHY_MICREL_KSZ9021 CONFIG_PHY_MICREL_KSZ9031 CONFIG_PHY_MODE_NEED_CHANGE +CONFIG_PHY_MSCC CONFIG_PHY_NATSEMI CONFIG_PHY_REALTEK CONFIG_PHY_RESET -- 1.9.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot