phy: Add phy driver support for xilinx PCS/PMA core
Add phy driver support for xilinx PCS/PMA core Signed-off-by: Siva Durga Prasad Paladugu <sivadur@xilinx.com> Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
This commit is contained in:
parent
563d8d9358
commit
ed6fad3e25
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
144
drivers/net/phy/xilinx_phy.c
Normal file
144
drivers/net/phy/xilinx_phy.c
Normal file
@ -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
|
||||
#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);
|
||||
if (phytype == XAE_PHY_TYPE_1000BASE_X)
|
||||
phydev->flags |= XAE_PHY_TYPE_1000BASE_X;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xilinxphy_config(struct phy_device *phydev)
|
||||
{
|
||||
int temp;
|
||||
|
||||
debug("%s\n", __func__);
|
||||
xilinxphy_of_init(phydev);
|
||||
temp = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
|
||||
temp &= XPCSPMA_PHY_CTRL_ISOLATE_DISABLE;
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct phy_driver xilinxphy_driver = {
|
||||
.uid = XILINX_PHY_ID,
|
||||
.mask = XILINX_PHY_ID_MASK,
|
||||
.name = "Xilinx PCS/PMA PHY",
|
||||
.features = PHY_GBIT_FEATURES,
|
||||
.config = &xilinxphy_config,
|
||||
.startup = &xilinxphy_startup,
|
||||
.shutdown = &genphy_shutdown,
|
||||
};
|
||||
|
||||
int phy_xilinx_init(void)
|
||||
{
|
||||
debug("%s\n", __func__);
|
||||
phy_register(&xilinxphy_driver);
|
||||
|
||||
return 0;
|
||||
}
|
@ -264,6 +264,7 @@ int phy_smsc_init(void);
|
||||
int phy_teranetics_init(void);
|
||||
int phy_ti_init(void);
|
||||
int phy_vitesse_init(void);
|
||||
int phy_xilinx_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);
|
||||
|
Loading…
Reference in New Issue
Block a user