diff mbox series

[v1,1/6] net: mv88e61xx: Add support for checking addressing mode

Message ID 20210317141410.32152-2-lukma@denx.de
State Accepted
Delegated to: Ramon Fried
Headers show
Series Provide support for mv88e6020 Marvell switch | expand

Commit Message

Lukasz Majewski March 17, 2021, 2:14 p.m. UTC
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(+)

Comments

Ramon Fried May 8, 2021, 6:25 a.m. UTC | #1
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>
Lukasz Majewski May 28, 2021, 11:49 a.m. UTC | #2
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 mbox series

Patch

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