Message ID | 20210317141410.32152-2-lukma@denx.de |
---|---|
State | Accepted |
Delegated to: | Ramon Fried |
Headers | show |
Series | Provide support for mv88e6020 Marvell switch | expand |
On Wed, Mar 17, 2021 at 4:14 PM Lukasz Majewski <lukma@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 <lukma@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.dev@gmail.com>
Hi Joe, Tom, > On Wed, Mar 17, 2021 at 4:14 PM Lukasz Majewski <lukma@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 <lukma@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.dev@gmail.com> Could this patch series be pulled to u-boot-net tree (or directly to -master branch) ? Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
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
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 <lukma@denx.de> --- drivers/net/phy/mv88e61xx.c | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)