2024-04-03 13:48:15

by Gregor Herburger

[permalink] [raw]
Subject: [PATCH] net: phy: marvell-88q2xxx: add support for Rev B1 and B2

Different revisions of the Marvell 88q2xxx phy needs different init
sequences.

Add init sequence for Rev B1 and Rev B2. Rev B2 init sequence skips one
register write.

Signed-off-by: Gregor Herburger <[email protected]>
---
Hi,

as discussed when adding support for Marvell 88Q2220 Revision B0 [1],
newer revisions need different init sequences. So add support for Rev B1
and B2 with this patch.

[1] https://lore.kernel.org/netdev/20240216205302.GC3873@debian/

Best regards
Gregor
---
drivers/net/phy/marvell-88q2xxx.c | 86 +++++++++++++++++++++++++++++++++++++--
1 file changed, 83 insertions(+), 3 deletions(-)

diff --git a/drivers/net/phy/marvell-88q2xxx.c b/drivers/net/phy/marvell-88q2xxx.c
index 6b4bd9883304..c4c916eb3195 100644
--- a/drivers/net/phy/marvell-88q2xxx.c
+++ b/drivers/net/phy/marvell-88q2xxx.c
@@ -12,6 +12,8 @@
#include <linux/hwmon.h>

#define PHY_ID_88Q2220_REVB0 (MARVELL_PHY_ID_88Q2220 | 0x1)
+#define PHY_ID_88Q2220_REVB1 (MARVELL_PHY_ID_88Q2220 | 0x2)
+#define PHY_ID_88Q2220_REVB2 (MARVELL_PHY_ID_88Q2220 | 0x3)

#define MDIO_MMD_AN_MV_STAT 32769
#define MDIO_MMD_AN_MV_STAT_ANEG 0x0100
@@ -129,6 +131,43 @@ static const struct mmd_val mv88q222x_revb0_init_seq1[] = {
{ MDIO_MMD_PCS, 0xfe05, 0x755c },
};

+static const struct mmd_val mv88q222x_revb1_init_seq0[] = {
+ { MDIO_MMD_PCS, 0xFFE4, 0x0007 },
+ { MDIO_MMD_AN, MDIO_AN_T1_CTRL, 0x0 },
+ { MDIO_MMD_PCS, 0xFFE3, 0x7000 },
+ { MDIO_MMD_PMAPMD, MDIO_CTRL1, 0x0840 },
+};
+
+static const struct mmd_val mv88q222x_revb1_init_seq1[] = {
+ { MDIO_MMD_PCS, 0xFE07, 0x125A },
+ { MDIO_MMD_PCS, 0xFE09, 0x1288 },
+ { MDIO_MMD_PCS, 0xFE08, 0x2588 },
+ { MDIO_MMD_PCS, 0xFE72, 0x042C },
+ { MDIO_MMD_PCS, 0xFFE4, 0x0071 },
+ { MDIO_MMD_PCS, 0xFFE4, 0x0001 },
+ { MDIO_MMD_PCS, 0xFE1B, 0x0048 },
+ { MDIO_MMD_PMAPMD, 0x0000, 0x0000 },
+ { MDIO_MMD_PCS, 0x0000, 0x0000 },
+ { MDIO_MMD_PCS, 0xFFDB, 0xFC10 },
+ { MDIO_MMD_PCS, 0xFE1B, 0x58 },
+ { MDIO_MMD_PCS, 0xFCAD, 0x030C },
+ { MDIO_MMD_PCS, 0x8032, 0x6001 },
+ { MDIO_MMD_PCS, 0xFDFF, 0x05A5 },
+ { MDIO_MMD_PCS, 0xFDEC, 0xDBAF },
+ { MDIO_MMD_PCS, 0xFCAB, 0x1054 },
+ { MDIO_MMD_PCS, 0xFCAC, 0x1483 },
+ { MDIO_MMD_PCS, 0x8033, 0xC801 },
+ { MDIO_MMD_AN, 0x8032, 0x2020 },
+ { MDIO_MMD_AN, 0x8031, 0xA28 },
+ { MDIO_MMD_AN, 0x8031, 0xC28 },
+ { MDIO_MMD_PCS, 0xFBBA, 0x0CB2 },
+ { MDIO_MMD_PCS, 0xFBBB, 0x0C4A },
+ { MDIO_MMD_PCS, 0xFE5F, 0xE8 },
+ { MDIO_MMD_PCS, 0xFE05, 0x755C },
+ { MDIO_MMD_PCS, 0xFA20, 0x002A },
+ { MDIO_MMD_PCS, 0xFE11, 0x1105 },
+};
+
static int mv88q2xxx_soft_reset(struct phy_device *phydev)
{
int ret;
@@ -712,6 +751,46 @@ static int mv88q222x_revb0_config_init(struct phy_device *phydev)
return mv88q2xxx_config_init(phydev);
}

+static int mv88q222x_revb1_revb2_config_init(struct phy_device *phydev)
+{
+ bool is_rev_b2 = phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] == PHY_ID_88Q2220_REVB2;
+ int ret, i;
+
+ for (i = 0; i < ARRAY_SIZE(mv88q222x_revb1_init_seq0); i++) {
+ /* Rev B2 init sequence differs compared to Rev B1. As noted in Marvell API:
+ * Remove the instruction to enable TXDAC setting overwrite bit for Rev B2.
+ */
+ if (is_rev_b2 && mv88q222x_revb1_init_seq1[i].regnum == 0xffe3)
+ continue;
+
+ ret = phy_write_mmd(phydev, mv88q222x_revb1_init_seq0[i].devad,
+ mv88q222x_revb1_init_seq0[i].regnum,
+ mv88q222x_revb1_init_seq0[i].val);
+ if (ret < 0)
+ return ret;
+ }
+
+ usleep_range(3000, 5000);
+
+ for (i = 0; i < ARRAY_SIZE(mv88q222x_revb1_init_seq1); i++) {
+ ret = phy_write_mmd(phydev, mv88q222x_revb1_init_seq1[i].devad,
+ mv88q222x_revb1_init_seq1[i].regnum,
+ mv88q222x_revb1_init_seq1[i].val);
+ if (ret < 0)
+ return ret;
+ }
+
+ return mv88q2xxx_config_init(phydev);
+}
+
+static int mv88q222x_config_init(struct phy_device *phydev)
+{
+ if (phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] == PHY_ID_88Q2220_REVB0)
+ return mv88q222x_revb0_config_init(phydev);
+ else
+ return mv88q222x_revb1_revb2_config_init(phydev);
+}
+
static int mv88q222x_cable_test_start(struct phy_device *phydev)
{
int ret;
@@ -810,14 +889,15 @@ static struct phy_driver mv88q2xxx_driver[] = {
.get_sqi_max = mv88q2xxx_get_sqi_max,
},
{
- PHY_ID_MATCH_EXACT(PHY_ID_88Q2220_REVB0),
+ .phy_id = MARVELL_PHY_ID_88Q2220,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "mv88q2220",
.flags = PHY_POLL_CABLE_TEST,
.probe = mv88q2xxx_probe,
.get_features = mv88q2xxx_get_features,
.config_aneg = mv88q2xxx_config_aneg,
.aneg_done = genphy_c45_aneg_done,
- .config_init = mv88q222x_revb0_config_init,
+ .config_init = mv88q222x_config_init,
.read_status = mv88q2xxx_read_status,
.soft_reset = mv88q222x_soft_reset,
.config_intr = mv88q2xxx_config_intr,
@@ -836,7 +916,7 @@ module_phy_driver(mv88q2xxx_driver);

static struct mdio_device_id __maybe_unused mv88q2xxx_tbl[] = {
{ MARVELL_PHY_ID_88Q2110, MARVELL_PHY_ID_MASK },
- { PHY_ID_MATCH_EXACT(PHY_ID_88Q2220_REVB0), },
+ { MARVELL_PHY_ID_88Q2220, MARVELL_PHY_ID_MASK },
{ /*sentinel*/ }
};
MODULE_DEVICE_TABLE(mdio, mv88q2xxx_tbl);

---
base-commit: 1fdad13606e104ff103ca19d2d660830cb36d43e
change-id: 20240403-mv88q222x-revb1-b2-init-9961d2cf1d27

Best regards,
--
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
https://www.tq-group.com/



2024-04-03 14:00:12

by Russell King (Oracle)

[permalink] [raw]
Subject: Re: [PATCH] net: phy: marvell-88q2xxx: add support for Rev B1 and B2

On Wed, Apr 03, 2024 at 03:45:22PM +0200, Gregor Herburger wrote:
> +static int mv88q222x_revb1_revb2_config_init(struct phy_device *phydev)
> +{
> + bool is_rev_b2 = phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] == PHY_ID_88Q2220_REVB2;
> + int ret, i;
> +
> + for (i = 0; i < ARRAY_SIZE(mv88q222x_revb1_init_seq0); i++) {
> + /* Rev B2 init sequence differs compared to Rev B1. As noted in Marvell API:
> + * Remove the instruction to enable TXDAC setting overwrite bit for Rev B2.
> + */
> + if (is_rev_b2 && mv88q222x_revb1_init_seq1[i].regnum == 0xffe3)
> + continue;
> +
> + ret = phy_write_mmd(phydev, mv88q222x_revb1_init_seq0[i].devad,
> + mv88q222x_revb1_init_seq0[i].regnum,
> + mv88q222x_revb1_init_seq0[i].val);
> + if (ret < 0)
> + return ret;
> + }
> +
> + usleep_range(3000, 5000);
> +
> + for (i = 0; i < ARRAY_SIZE(mv88q222x_revb1_init_seq1); i++) {
> + ret = phy_write_mmd(phydev, mv88q222x_revb1_init_seq1[i].devad,
> + mv88q222x_revb1_init_seq1[i].regnum,
> + mv88q222x_revb1_init_seq1[i].val);
> + if (ret < 0)
> + return ret;
> + }

I think a helper would be useful to write these sequences, rather than
writing the same code several times:

static int mv88q2xxx_write_mmd_vals(struct phy_device *phydev,
const struct mmd_val *vals, size_t len)
{
int ret;

for (; len; vals++, len--) {
ret = phy_write_mmd(phydev, vals->devad, vals->regnum,
vals->val);
if (ret < 0)
return ret;
}

return 0;
}

--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

2024-04-04 14:07:09

by Gregor Herburger

[permalink] [raw]
Subject: Re: Re: [PATCH] net: phy: marvell-88q2xxx: add support for Rev B1 and B2

Hi Russell,

On Wed, Apr 03, 2024 at 02:59:37PM +0100, Russell King (Oracle) wrote:
> I think a helper would be useful to write these sequences, rather than
> writing the same code several times:

Ok. Will add it to the next version.

>
> static int mv88q2xxx_write_mmd_vals(struct phy_device *phydev,
> const struct mmd_val *vals, size_t len)
> {
> int ret;
>
> for (; len; vals++, len--) {
> ret = phy_write_mmd(phydev, vals->devad, vals->regnum,
> vals->val);
> if (ret < 0)
> return ret;
> }
>
> return 0;
> }
>
> --
> RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
> FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

--
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
https://www.tq-group.com/