[U-Boot] [PATCH 1/2] Add-MSCC-Phys-VSC8530-VSC8531-VSC8540-VSC8541

Joe Hershberger joe.hershberger at gmail.com
Tue Nov 29 22:18:16 CET 2016


On Thu, Nov 17, 2016 at 6:09 PM, John Haechten
<john.haechten at microsemi.com> wrote:
> From 452bf05d5e3add67f2dded5537da4bb5d0527e70 Mon Sep 17 00:00:00 2001
> From: John Haechten <john.haechten at 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.haechten at microsemi.com> Signed-off-by:John Haechten
> <john.haechten at microsemi.com>; Reviewed-by:Howard Hicks
> <howard.hicks at microsemi.com>; Series-to:u-boot;phy; Cc:Allan Nielsen
> <Allan.Nielsen at microsemi.com>; Tested-by:Howard Hicks
> <Howard.Hicks at 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

It seems your commit message is malformed and patman did not strip the
way it should have. White space issues?

> Signed-off-by: John Haechten <john.haechten at 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;

This is a bit of a peculiar pattern. Usually a "_MASK" register is a
mask _of_ the field, not of all _but_ the field. And then in a case
like this I would expect it to be reg_val17 &=
~MSCC_PHY_TR_LINKDETCTRL_MASK;

Also, all of this would be much cleaner to read if it used
bitfield_replace() or bitfield_replace_by_mask() from
include/bitfield.h

> +     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);

Where you need to specify a magic value for something like a gain,
please include a comment about what real-world value it represents and
maybe the equation used to compute the constant.

> +     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) {

Does it make sense to consolidate these cases? Seems like a lot of
duplicated code with only a few values different. I haven't gone
through the exercise to see if it's cleaner, but I suspect it is.

> +     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");

Why the "printf: "? Same for other phys.

> +
> +     genphy_config_aneg(phydev);

Seems you should return this function's return code. Same for other phys.

> +
> +     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

Why not add this to Kconfig instead?

> CONFIG_PHY_NATSEMI
> CONFIG_PHY_REALTEK
> CONFIG_PHY_RESET
> --
> 1.9.1
>
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot


More information about the U-Boot mailing list