mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-09-19 21:01:51 +02:00
When bringing in the series 'arm: dts: am62-beagleplay: Fix Beagleplay Ethernet"' I failed to notice that b4 noticed it was based on next and so took that as the base commit and merged that part of next to master. This reverts commit c8ffd1356d42223cbb8c86280a083cc3c93e6426, reversing changes made to 2ee6f3a5f7550de3599faef9704e166e5dcace35. Reported-by: Jonas Karlman <jonas@kwiboo.se> Signed-off-by: Tom Rini <trini@konsulko.com>
134 lines
2.7 KiB
C
134 lines
2.7 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Xilinx PCS/PMA Core phy driver
|
|
*
|
|
* Copyright (C) 2015 - 2016 Xilinx, Inc.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <common.h>
|
|
#include <log.h>
|
|
#include <phy.h>
|
|
#include <dm.h>
|
|
|
|
#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)
|
|
{
|
|
ofnode node;
|
|
|
|
debug("%s\n", __func__);
|
|
node = phy_get_ofnode(phydev);
|
|
if (!ofnode_valid(node))
|
|
return -EINVAL;
|
|
|
|
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;
|
|
}
|
|
|
|
U_BOOT_PHY_DRIVER(xilinxphy) = {
|
|
.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,
|
|
};
|