[U-Boot] [PATCH 1/3] phy: Add phy driver support for xilinx PCS/PMA core

Michal Simek michal.simek at xilinx.com
Tue Apr 26 08:13:47 CEST 2016


On 26.4.2016 00:36, Joe Hershberger wrote:
> On Mon, Feb 15, 2016 at 3:54 AM, Michal Simek <michal.simek at xilinx.com> wrote:
>> From: Siva Durga Prasad Paladugu <siva.durga.paladugu at xilinx.com>
>>
>> Add phy driver support for xilinx PCS/PMA core
>>
>> Signed-off-by: Siva Durga Prasad Paladugu <sivadur at xilinx.com>
>> Signed-off-by: Kedareswara rao Appana <appanad at xilinx.com>
>> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
>> ---
>>
>>  drivers/net/phy/Makefile     |   1 +
>>  drivers/net/phy/phy.c        |   3 +
>>  drivers/net/phy/xilinx_phy.c | 144 +++++++++++++++++++++++++++++++++++++++++++
>>  include/phy.h                |   1 +
>>  4 files changed, 149 insertions(+)
>>  create mode 100644 drivers/net/phy/xilinx_phy.c
>>
>> diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
>> index 9e4d4927e676..1e299b97b961 100644
>> --- a/drivers/net/phy/Makefile
>> +++ b/drivers/net/phy/Makefile
>> @@ -25,4 +25,5 @@ obj-$(CONFIG_PHY_REALTEK) += realtek.o
>>  obj-$(CONFIG_PHY_SMSC) += smsc.o
>>  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
>> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
>> index 17866a244b3a..23c82bb36e93 100644
>> --- a/drivers/net/phy/phy.c
>> +++ b/drivers/net/phy/phy.c
>> @@ -503,6 +503,9 @@ int phy_init(void)
>>  #ifdef CONFIG_PHY_VITESSE
>>         phy_vitesse_init();
>>  #endif
>> +#ifdef CONFIG_PHY_XILINX
>> +       phy_xilinx_init();
>> +#endif
>>
>>         return 0;
>>  }
>> diff --git a/drivers/net/phy/xilinx_phy.c b/drivers/net/phy/xilinx_phy.c
>> new file mode 100644
>> index 000000000000..f3eaf2e97ced
>> --- /dev/null
>> +++ b/drivers/net/phy/xilinx_phy.c
>> @@ -0,0 +1,144 @@
>> +/*
>> + * Xilinx PCS/PMA Core phy driver
>> + *
>> + * Copyright (C) 2015 - 2016 Xilinx, Inc.
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <config.h>
>> +#include <common.h>
>> +#include <phy.h>
>> +#include <dm.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +#define MII_PHY_STATUS_SPD_MASK                0x0C00
>> +#define MII_PHY_STATUS_FULLDUPLEX      0x1000
>> +#define MII_PHY_STATUS_1000            0x0800
>> +#define MII_PHY_STATUS_100             0x0400
> 
> Use the BIT() macro where appropriate.
> 
>> +#define XPCSPMA_PHY_CTRL_ISOLATE_DISABLE 0xFBFF
>> +
>> +/* Mask used for ID comparisons */
>> +#define XILINX_PHY_ID_MASK             0xfffffff0
>> +
>> +/* Known PHY IDs */
>> +#define XILINX_PHY_ID                  0x01740c00
>> +
>> +/* struct phy_device dev_flags definitions */
>> +#define XAE_PHY_TYPE_MII               0
>> +#define XAE_PHY_TYPE_GMII              1
>> +#define XAE_PHY_TYPE_RGMII_1_3         2
>> +#define XAE_PHY_TYPE_RGMII_2_0         3
>> +#define XAE_PHY_TYPE_SGMII             4
>> +#define XAE_PHY_TYPE_1000BASE_X                5
>> +
>> +static int xilinxphy_startup(struct phy_device *phydev)
>> +{
>> +       int err;
>> +       int status = 0;
>> +
>> +       debug("%s\n", __func__);
>> +       /* Update the link, but return if there
>> +        * was an error
>> +        */
>> +       err = genphy_update_link(phydev);
>> +       if (err)
>> +               return err;
>> +
>> +       if (AUTONEG_ENABLE == phydev->autoneg) {
>> +               status = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
>> +               status = status & MII_PHY_STATUS_SPD_MASK;
>> +
>> +               if (status & MII_PHY_STATUS_FULLDUPLEX)
>> +                       phydev->duplex = DUPLEX_FULL;
>> +               else
>> +                       phydev->duplex = DUPLEX_HALF;
>> +
>> +               switch (status) {
>> +               case MII_PHY_STATUS_1000:
>> +                       phydev->speed = SPEED_1000;
>> +                       break;
>> +
>> +               case MII_PHY_STATUS_100:
>> +                       phydev->speed = SPEED_100;
>> +                       break;
>> +
>> +               default:
>> +                       phydev->speed = SPEED_10;
>> +                       break;
>> +               }
>> +       } else {
>> +               int bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
>> +
>> +               if (bmcr < 0)
>> +                       return bmcr;
>> +
>> +               if (bmcr & BMCR_FULLDPLX)
>> +                       phydev->duplex = DUPLEX_FULL;
>> +               else
>> +                       phydev->duplex = DUPLEX_HALF;
>> +
>> +               if (bmcr & BMCR_SPEED1000)
>> +                       phydev->speed = SPEED_1000;
>> +               else if (bmcr & BMCR_SPEED100)
>> +                       phydev->speed = SPEED_100;
>> +               else
>> +                       phydev->speed = SPEED_10;
>> +       }
>> +
>> +       /*
>> +        * For 1000BASE-X Phy Mode the speed/duplex will always be
>> +        * 1000Mbps/fullduplex
>> +        */
>> +       if (phydev->flags == XAE_PHY_TYPE_1000BASE_X) {
>> +               phydev->duplex = DUPLEX_FULL;
>> +               phydev->speed = SPEED_1000;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int xilinxphy_of_init(struct phy_device *phydev)
>> +{
>> +       struct udevice *dev = (struct udevice *)&phydev->dev;
>> +       u32 phytype;
>> +
>> +       debug("%s\n", __func__);
>> +       phytype = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "phy-type", -1);
> 
> Is there a bindings document that can be included to describe this?

It should be added.

Siva: Can you please look at it?

Thanks,
Michal




More information about the U-Boot mailing list