On Wed, Mar 17, 2021 at 4:14 PM Lukasz Majewski <lu...@denx.de> wrote: > > Some Marvell switch devices are dual chip ones, like mv88e6020, which > use direct MDIO addressing to access its ports' registers. Such approach > allows connecting two such devices in a single MDIO bus with simple > addressing scheme. > > Signed-off-by: Lukasz Majewski <lu...@denx.de> > --- > > drivers/net/phy/mv88e61xx.c | 42 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/drivers/net/phy/mv88e61xx.c b/drivers/net/phy/mv88e61xx.c > index 7eff37b24499..69a1dd8f1859 100644 > --- a/drivers/net/phy/mv88e61xx.c > +++ b/drivers/net/phy/mv88e61xx.c > @@ -202,6 +202,7 @@ struct mv88e61xx_phy_priv { > u8 phy_ctrl1_en_det_shift; /* 'EDet' bit field offset */ > u8 phy_ctrl1_en_det_width; /* Width of 'EDet' bit field */ > u8 phy_ctrl1_en_det_ctrl; /* 'EDet' control value */ > + u8 direct_access; /* Access switch device directly */ > }; > > static inline int smi_cmd(int cmd, int addr, int reg) > @@ -928,6 +929,40 @@ static int mv88e61xx_priv_reg_offs_pre_init(struct > phy_device *phydev) > return -ENODEV; > } > > +static int mv88e61xx_check_addressing(struct phy_device *phydev) > +{ > + if (!CONFIG_IS_ENABLED(OF_CONTROL)) > + return 0; > + > + /* > + * Some devices - like mv88e6020 are dual chip - i.e. two > + * such devices can be directly accessed via SMI bus. > + * The addressing depends on R0_LED/ADDR4 pin value duing > + * bootstrap. > + * > + * This means that there is no need for indirect access. > + */ > + struct mv88e61xx_phy_priv *priv = phydev->priv; > + > + /* > + * As this function is called very early and hence the phydev > + * is not yet initialized we use aliast and DTS to asses if > + * device shall be directly accessed or not. > + */ > + ofnode sw0; > + int ret; > + > + sw0 = ofnode_get_aliases_node("switch0"); > + if (!ofnode_valid(sw0)) > + return -ENODEV; > + > + ret = ofnode_device_is_compatible(sw0, "marvell,mv88e6020"); > + if (ret) > + priv->direct_access = 1; > + > + return 0; > +} > + > static int mv88e61xx_probe(struct phy_device *phydev) > { > struct mii_dev *smi_wrapper; > @@ -982,6 +1017,8 @@ static int mv88e61xx_probe(struct phy_device *phydev) > > phydev->priv = priv; > > + mv88e61xx_check_addressing(phydev); > + > res = mv88e61xx_priv_reg_offs_pre_init(phydev); > if (res < 0) > return res; > @@ -1197,6 +1234,11 @@ int get_phy_id(struct mii_dev *bus, int smi_addr, int > devad, u32 *phy_id) > temp_phy.priv = &temp_priv; > temp_mii.priv = &temp_phy; > > + mv88e61xx_check_addressing(&temp_phy); > + /* For direct access the phy address equals to smi_addr */ > + if (temp_priv.direct_access) > + temp_phy.addr = smi_addr; > + > /* > * get_phy_id() can be called by framework before mv88e61xx driver > * probing, in this case the global register offsets are not > -- > 2.20.1 >
Reviewed-by: Ramon Fried <rfried....@gmail.com>