|
@@ -1008,6 +1008,25 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+static void cpsw_phy_addr_update(struct cpsw_priv *priv)
|
|
|
+{
|
|
|
+ struct cpsw_platform_data *data = &priv->data;
|
|
|
+ u16 alive = mdio_regs->alive & GENMASK(15, 0);
|
|
|
+ int active = data->active_slave;
|
|
|
+ int new_addr = ffs(alive) - 1;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If there is only one phy alive and its address does not match
|
|
|
+ * that of active slave, then phy address can safely be updated.
|
|
|
+ */
|
|
|
+ if (hweight16(alive) == 1 &&
|
|
|
+ data->slave_data[active].phy_addr != new_addr) {
|
|
|
+ printf("Updated phy address for CPSW#%d, old: %d, new: %d\n",
|
|
|
+ active, data->slave_data[active].phy_addr, new_addr);
|
|
|
+ data->slave_data[active].phy_addr = new_addr;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
int _cpsw_register(struct cpsw_priv *priv)
|
|
|
{
|
|
|
struct cpsw_slave *slave;
|
|
@@ -1034,6 +1053,9 @@ int _cpsw_register(struct cpsw_priv *priv)
|
|
|
}
|
|
|
|
|
|
cpsw_mdio_init(priv->dev->name, data->mdio_base, data->mdio_div);
|
|
|
+
|
|
|
+ cpsw_phy_addr_update(priv);
|
|
|
+
|
|
|
priv->bus = miiphy_get_dev_by_name(priv->dev->name);
|
|
|
for_active_slave(slave, priv)
|
|
|
cpsw_phy_init(priv, slave);
|
|
@@ -1458,6 +1480,13 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+int cpsw_get_slave_phy_addr(struct udevice *dev, int slave)
|
|
|
+{
|
|
|
+ struct cpsw_priv *priv = dev_get_priv(dev);
|
|
|
+ struct cpsw_platform_data *data = &priv->data;
|
|
|
+
|
|
|
+ return data->slave_data[slave].phy_addr;
|
|
|
+}
|
|
|
|
|
|
static const struct udevice_id cpsw_eth_ids[] = {
|
|
|
{ .compatible = "ti,cpsw" },
|