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>

Reply via email to