Commit e2597be5bcb90030fdc116e7c5810bdef7fd9e0d
Committed by
Tom Rini
1 parent
4495680735
Exists in
smarc_8mq_lf_v2020.04
and in
11 other branches
drivers: net: cpsw: add support to update phy address
On some boards using TI CPSW, it may be possible that PHY address was not latched correctly, and the actual address that the phy responds on is different from that set in device-tree. For example, see this problem report on beaglebone black: https://groups.google.com/d/msg/beagleboard/9mctrG26Mc8/1FuI_i5KW10J Add support to check for this condition and use the detected phy address when its safe to do so. Also, add a public API that exposes the phy address of a given slave. This can be used to update device-tree that is passed to Linux kernel. Signed-off-by: Sekhar Nori <nsekhar@ti.com> Reviewed-by: Tom Rini <trini@konsulko.com>
Showing 2 changed files with 30 additions and 0 deletions Side-by-side Diff
drivers/net/cpsw.c
... | ... | @@ -1008,6 +1008,25 @@ |
1008 | 1008 | return 1; |
1009 | 1009 | } |
1010 | 1010 | |
1011 | +static void cpsw_phy_addr_update(struct cpsw_priv *priv) | |
1012 | +{ | |
1013 | + struct cpsw_platform_data *data = &priv->data; | |
1014 | + u16 alive = mdio_regs->alive & GENMASK(15, 0); | |
1015 | + int active = data->active_slave; | |
1016 | + int new_addr = ffs(alive) - 1; | |
1017 | + | |
1018 | + /* | |
1019 | + * If there is only one phy alive and its address does not match | |
1020 | + * that of active slave, then phy address can safely be updated. | |
1021 | + */ | |
1022 | + if (hweight16(alive) == 1 && | |
1023 | + data->slave_data[active].phy_addr != new_addr) { | |
1024 | + printf("Updated phy address for CPSW#%d, old: %d, new: %d\n", | |
1025 | + active, data->slave_data[active].phy_addr, new_addr); | |
1026 | + data->slave_data[active].phy_addr = new_addr; | |
1027 | + } | |
1028 | +} | |
1029 | + | |
1011 | 1030 | int _cpsw_register(struct cpsw_priv *priv) |
1012 | 1031 | { |
1013 | 1032 | struct cpsw_slave *slave; |
... | ... | @@ -1034,6 +1053,9 @@ |
1034 | 1053 | } |
1035 | 1054 | |
1036 | 1055 | cpsw_mdio_init(priv->dev->name, data->mdio_base, data->mdio_div); |
1056 | + | |
1057 | + cpsw_phy_addr_update(priv); | |
1058 | + | |
1037 | 1059 | priv->bus = miiphy_get_dev_by_name(priv->dev->name); |
1038 | 1060 | for_active_slave(slave, priv) |
1039 | 1061 | cpsw_phy_init(priv, slave); |
... | ... | @@ -1458,6 +1480,13 @@ |
1458 | 1480 | return 0; |
1459 | 1481 | } |
1460 | 1482 | |
1483 | +int cpsw_get_slave_phy_addr(struct udevice *dev, int slave) | |
1484 | +{ | |
1485 | + struct cpsw_priv *priv = dev_get_priv(dev); | |
1486 | + struct cpsw_platform_data *data = &priv->data; | |
1487 | + | |
1488 | + return data->slave_data[slave].phy_addr; | |
1489 | +} | |
1461 | 1490 | |
1462 | 1491 | static const struct udevice_id cpsw_eth_ids[] = { |
1463 | 1492 | { .compatible = "ti,cpsw" }, |
include/cpsw.h