
Hi John,
I have some additional comments beyond Alexey's.
On Wed, Dec 7, 2016 at 11:11 AM, John Haechten john.haechten@microsemi.com wrote:
From 127c5fb9ef390cad5cf58e446110a696cf111345 Mon Sep 17 00:00:00 2001 From: John Haechten john.haechten@microsemi.com Date: Wed, 7 Dec 2016 07:51:37 -0800 Subject: [PATCH] Adding MSCC PHY-VSC8530-VSC8531-VSC8540-VSC8541
(C) Copyright 2016 Microsemi Corporation, MIT License (MIT) Author:John Haechten john.haechten@microsemi.com Reviewed-by:Howard Hicks howard.hicks@microsemi.com Reviewed-by:Joe Hershberger joe.hershberger@ni.com
You should not add a "Reviewed-by:" tag just because I gave feedback. The meaning of a Reviewed-by: tag is that it is reviewed and acceptable in the eyes of that reviewer. The reviewer will reply with the Reviewed-by: tag when they approve. If they reply to your patch and there is no need for a new version, then there is nothing further that you need to do. If you do get a Reviewed-by: that someone replies, but some other reviewer or custodian asks for a change that means a new version, then you need to add any Reviewed-by: or Tested-by: tags that people sent (unless the change is so drastic as to invalidate the review or test).
Also, all tags should be followed by a space before the name of the person or other content. Perhaps this is why patman isn't handling your tags properly.
Tested-by:Howard Hicks howard.hicks@microsemi.com Version:1
In the future, you should not specify a version until it is version 2.
Prefix:None Signed-off-by: John Haechten john.haechten@microsemi.com
drivers/net/phy/Makefile | 1 + drivers/net/phy/mscc.c | 480 ++++++++++++++++++++++++++++++++++++ drivers/net/phy/phy.c | 3 + include/config_phylib_all_drivers.h | 1 + include/configs/am335x_evm.h | 3 + include/phy.h | 1 + 6 files changed, 489 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..e63bd43 --- /dev/null +++ b/drivers/net/phy/mscc.c @@ -0,0 +1,480 @@ +/*
- 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> +#include <bitfield.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 */ +/* Std Page Register 28 - PHY AUX Control/Status */ +#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) +/* Std Page Register 23 - Extended PHY CTRL_1 */ +#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 +#define MAC_IF_SELECTION_WIDTH 2 +/* Extended Page 2 Register 20E2 */ +#define MSCC_PHY_RGMII_CNTL 20 +#define VSC_FAST_LINK_FAIL2_ENA_MASK 0x8000 +#define RX_CLK_OUT_MASK 0x0800 +#define RX_CLK_OUT_POS 11 +#define RX_CLK_OUT_WIDTH 1 +#define RX_CLK_OUT_NORMAL 0 +#define RX_CLK_OUT_DISABLE 1 +#define RGMII_RX_CLK_DELAY_POS 4 +#define RGMII_RX_CLK_DELAY_WIDTH 3 +#define RGMII_RX_CLK_DELAY_MASK 0x0070 +#define RGMII_TX_CLK_DELAY_POS 0 +#define RGMII_TX_CLK_DELAY_WIDTH 3 +#define RGMII_TX_CLK_DELAY_MASK 0x0007 +/* Extended Page 2 Register 27E2 */ +#define MSCC_PHY_WOL_MAC_CONTROL 27 +#define EDGE_RATE_CNTL_POS 5 +#define EDGE_RATE_CNTL_WIDTH 3 +#define EDGE_RATE_CNTL_MASK 0x00E0 +#define RMII_CLK_OUT_ENABLE_POS 4 +#define RMII_CLK_OUT_ENABLE_WIDTH 1 +#define RMII_CLK_OUT_ENABLE_MASK 0x10 +/* Token Ring Page 0x52B5 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_WIDTH 2 +#define MSCC_PHY_TR_LINKDETCTRL_MASK 0x18 +#define MSCC_PHY_TR_VGATHRESH100_POS 0 +#define MSCC_PHY_TR_VGATHRESH100_WIDTH 7 +#define MSCC_PHY_TR_VGATHRESH100_MASK 0x7f +#define MSCC_PHY_TR_VGAGAIN10_U_POS 0 +#define MSCC_PHY_TR_VGAGAIN10_U_WIDTH 1 +#define MSCC_PHY_TR_VGAGAIN10_U_MASK 0x01 +#define MSCC_PHY_TR_VGAGAIN10_L_POS 12 +#define MSCC_PHY_TR_VGAGAIN10_L_WIDTH 4 +#define MSCC_PHY_TR_VGAGAIN10_L_MASK 0xf000 +/* General Timeout Values */ +#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 default to optimized values */
/* Determined during Silicon Validation Testing */
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 = bitfield_replace(reg_val17, MSCC_PHY_TR_LINKDETCTRL_POS,
MSCC_PHY_TR_LINKDETCTRL_WIDTH, 3);
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 defaults to optimized values */
/* Determined during Silicon Validation Testing */
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 = bitfield_replace(reg_val18, MSCC_PHY_TR_VGATHRESH100_POS,
MSCC_PHY_TR_VGATHRESH100_WIDTH, 24);
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 defaults to optimized values */
/* Determined during Silicon Validation Testing */
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 = bitfield_replace(reg_val18, MSCC_PHY_TR_VGAGAIN10_U_POS,
MSCC_PHY_TR_VGAGAIN10_U_WIDTH, 0);
reg_val17 = bitfield_replace(reg_val17, MSCC_PHY_TR_VGAGAIN10_L_POS,
MSCC_PHY_TR_VGAGAIN10_L_WIDTH, 1);
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;
Please use the ubiquitous 'retval' for this variable name.
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;
Same here, use retval.
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) {
printf("MSCC PHY Soft_Reset Error: mac i/f = 0x%x\n",
phydev->interface);
rc = -ETIME;
}
return rc;
+}
+static int vsc8531_vsc8541_mac_config(struct phy_device *phydev) +{
int rc = 0;
This variable is never used. Just return 0 at the end.
u16 reg_val = 0;
u16 mac_if = 0;
u16 rx_clk_out = 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 */
switch (phydev->interface) {
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_GMII:
/* Set Reg23.12:11=0 */
mac_if = MAC_IF_SELECTION_GMII;
/* Set Reg20E2.11=1 */
rx_clk_out = RX_CLK_OUT_DISABLE;
break;
case PHY_INTERFACE_MODE_RMII:
/* Set Reg23.12:11=1 */
mac_if = MAC_IF_SELECTION_RMII;
/* Set Reg20E2.11=0 */
rx_clk_out = RX_CLK_OUT_NORMAL;
break;
case PHY_INTERFACE_MODE_RGMII:
/* Set Reg23.12:11=2 */
mac_if = MAC_IF_SELECTION_RGMII;
/* Set Reg20E2.11=0 */
rx_clk_out = RX_CLK_OUT_NORMAL;
break;
default:
printf("MSCC PHY - INVALID MAC i/f Config: mac i/f = 0x%x\n",
phydev->interface);
return -EINVAL;
}
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
/* Read Reg23 */
reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
MSCC_PHY_EXT_PHY_CNTL_1);
/* Set MAC i/f bits Reg23.12:11 */
reg_val = bitfield_replace(reg_val, MAC_IF_SELECTION_POS,
MAC_IF_SELECTION_WIDTH, mac_if);
/* Update Reg23.12:11 */
phy_write(phydev, MDIO_DEVAD_NONE,
MSCC_PHY_EXT_PHY_CNTL_1, reg_val);
/* Setup ExtPg_2 Register Access */
phy_write(phydev, MDIO_DEVAD_NONE,
MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXT2);
/* Read Reg20E2 */
reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
MSCC_PHY_RGMII_CNTL);
reg_val = bitfield_replace(reg_val, RX_CLK_OUT_POS,
RX_CLK_OUT_WIDTH, rx_clk_out);
/* Update Reg20E2.11 */
phy_write(phydev, MDIO_DEVAD_NONE,
MSCC_PHY_RGMII_CNTL, reg_val);
/* Before leaving - Change back to Std Page Register Access */
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
return rc;
+}
+static int vsc8531_config(struct phy_device *phydev) +{
u16 reg_val;
u16 rmii_clk_out;
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;
/* 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 8530/31 MAC i/f Config Error: mac i/f = 0x%x\n",
phydev->interface);
return -EINVAL;
}
/* Default RMII Clk Output to 0=OFF/1=ON */
rmii_clk_out = 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);
/* Reg20E2 - Update RGMII RX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
/* Reg20E2 - Update RGMII TX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
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);
/* Reg27E2 - Update Clk Slew Rate. */
reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
EDGE_RATE_CNTL_WIDTH, edge_rate);
/* Reg27E2 - Update RMII Clk Out. */
reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
/* Update Reg27E2 */
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);
return genphy_config_aneg(phydev);
+}
+static int vsc8541_config(struct phy_device *phydev) +{
u16 reg_val;
u16 rmii_clk_out;
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;
/* 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;
}
/* Default RMII Clk Output to 0=OFF/1=ON */
rmii_clk_out = 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);
/* Reg20E2 - Update RGMII RX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
/* Reg20E2 - Update RGMII TX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
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);
/* Reg27E2 - Update Clk Slew Rate. */
reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
EDGE_RATE_CNTL_WIDTH, edge_rate);
/* Reg27E2 - Update RMII Clk Out. */
reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
/* Update Reg27E2 */
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);
return genphy_config_aneg(phydev);
+}
+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..8db6574 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); -- 1.9.1
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot