diff options
author | Quentin Schulz <quentin.schulz@bootlin.com> | 2020-06-23 17:30:11 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-06-25 00:33:16 +0300 |
commit | ab2bf933935710ac545f94e49d16b5eab01f846f (patch) | |
tree | af2c9b6578139a92998cb906a25003334e7c8007 /drivers/net/phy/mscc/mscc_main.c | |
parent | 4c8c5dc57ae8226ceb7e72fb7a5cfa8e743c0a2b (diff) | |
download | linux-ab2bf933935710ac545f94e49d16b5eab01f846f.tar.xz |
net: phy: mscc: 1588 block initialization
This patch adds the first parts of the 1588 support in the MSCC PHY,
with registers definition and the 1588 block initialization.
Those PHYs are distributed in hardware packages containing multiple
times the PHY. The VSC8584 for example is composed of 4 PHYs. With
hardware packages, parts of the logic is usually common and one of the
PHY has to be used for some parts of the initialization. Following this
logic, the 1588 blocks of those PHYs are shared between two PHYs and
accessing the registers has to be done using the "base" PHY of the
group. This is handled thanks to helpers in the PTP code (and locks).
We also need the MDIO bus lock while performing a single read or write
to the 1588 registers as the read/write are composed of multiple MDIO
transactions (and we don't want other threads updating the page).
Co-developed-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/mscc/mscc_main.c')
-rw-r--r-- | drivers/net/phy/mscc/mscc_main.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c index 052a0def6e83..ea004712540f 100644 --- a/drivers/net/phy/mscc/mscc_main.c +++ b/drivers/net/phy/mscc/mscc_main.c @@ -1299,10 +1299,26 @@ static void vsc8584_get_base_addr(struct phy_device *phydev) __phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD); mutex_unlock(&phydev->mdio.bus->mdio_lock); - if (val & PHY_ADDR_REVERSED) + /* In the package, there are two pairs of PHYs (PHY0 + PHY2 and + * PHY1 + PHY3). The first PHY of each pair (PHY0 and PHY1) is + * the base PHY for timestamping operations. + */ + vsc8531->ts_base_addr = phydev->mdio.addr; + vsc8531->ts_base_phy = addr; + + if (val & PHY_ADDR_REVERSED) { vsc8531->base_addr = phydev->mdio.addr + addr; - else + if (addr > 1) { + vsc8531->ts_base_addr += 2; + vsc8531->ts_base_phy += 2; + } + } else { vsc8531->base_addr = phydev->mdio.addr - addr; + if (addr > 1) { + vsc8531->ts_base_addr -= 2; + vsc8531->ts_base_phy -= 2; + } + } vsc8531->addr = addr; } @@ -1418,6 +1434,10 @@ static int vsc8584_config_init(struct phy_device *phydev) if (ret) return ret; + ret = vsc8584_ptp_init(phydev); + if (ret) + goto err; + phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD); val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1); @@ -1999,6 +2019,7 @@ static int vsc8584_probe(struct phy_device *phydev) u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY, VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY, VSC8531_DUPLEX_COLLISION}; + int ret; if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) { dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n"); @@ -2024,6 +2045,10 @@ static int vsc8584_probe(struct phy_device *phydev) if (!vsc8531->stats) return -ENOMEM; + ret = vsc8584_ptp_probe(phydev); + if (ret) + return ret; + return vsc85xx_dt_led_modes_get(phydev, default_mode); } @@ -2403,6 +2428,7 @@ static struct phy_driver vsc85xx_driver[] = { .get_sset_count = &vsc85xx_get_sset_count, .get_strings = &vsc85xx_get_strings, .get_stats = &vsc85xx_get_stats, + .link_change_notify = &vsc85xx_link_change_notify, } }; |