[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