Files
openwrt/target/linux/generic/backport-6.18/785-v7.0-10-net-pcs-pcs-mtk-lynxi-deprecate-mediatek-pnswap.patch
T
Daniel Golle 18cbd83a14 generic: 6.18: import updated standalone PCS handling
Import pending series introducing support for standalone PCS drivers.

This has previously already been used by the airoha target, and is
also the base for the closer-to-upstream patches for MediaTek MT7988
10G SerDes support.

In order to not having to diverge from upstream also backport series
for standardized handling for PHY and PCS SerDes pair polarity.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-04-21 18:42:45 +01:00

124 lines
4.0 KiB
Diff

From 8871389da15165198c3407584d40e7295bceaca5 Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Mon, 19 Jan 2026 11:12:20 +0200
Subject: [PATCH 3/3] net: pcs: pcs-mtk-lynxi: deprecate "mediatek,pnswap"
Prefer the new "rx-polarity" and "tx-polarity" properties, which in this
case have the advantage that polarity inversion can be specified per
direction (and per protocol, although this isn't useful here).
We use the vendor specific ones as fallback if the standard description
doesn't exist.
Daniel, referring to the Mediatek SDK, clarifies that the combined
SGMII_PN_SWAP_TX_RX register field should be split like this: bit 0 is
TX and bit 1 is RX:
https://lore.kernel.org/linux-phy/aSW--slbJWpXK0nv@makrotopia.org/
Suggested-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260119091220.1493761-6-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/pcs/Kconfig | 1 +
drivers/net/pcs/pcs-mtk-lynxi.c | 50 +++++++++++++++++++++++++++++----
2 files changed, 45 insertions(+), 6 deletions(-)
--- a/drivers/net/pcs/Kconfig
+++ b/drivers/net/pcs/Kconfig
@@ -20,6 +20,7 @@ config PCS_LYNX
config PCS_MTK_LYNXI
tristate
+ select PHY_COMMON_PROPS
select REGMAP
help
This module provides helpers to phylink for managing the LynxI PCS
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -11,6 +11,7 @@
#include <linux/mdio.h>
#include <linux/of.h>
#include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/phy/phy-common-props.h>
#include <linux/phylink.h>
#include <linux/regmap.h>
@@ -62,8 +63,9 @@
/* Register to QPHY wrapper control */
#define SGMSYS_QPHY_WRAP_CTRL 0xec
-#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
-#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
+#define SGMII_PN_SWAP_RX BIT(1)
+#define SGMII_PN_SWAP_TX BIT(0)
+
/* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated
* data
@@ -119,6 +121,42 @@ static void mtk_pcs_lynxi_get_state(stru
FIELD_GET(SGMII_LPA, adv));
}
+static int mtk_pcs_config_polarity(struct mtk_pcs_lynxi *mpcs,
+ phy_interface_t interface)
+{
+ struct fwnode_handle *fwnode = mpcs->fwnode, *pcs_fwnode;
+ unsigned int pol, default_pol = PHY_POL_NORMAL;
+ unsigned int val = 0;
+ int ret;
+
+ if (fwnode_property_read_bool(fwnode, "mediatek,pnswap"))
+ default_pol = PHY_POL_INVERT;
+
+ pcs_fwnode = fwnode_get_named_child_node(fwnode, "pcs");
+
+ ret = phy_get_rx_polarity(pcs_fwnode, phy_modes(interface),
+ BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT),
+ default_pol, &pol);
+ if (ret) {
+ fwnode_handle_put(pcs_fwnode);
+ return ret;
+ }
+ if (pol == PHY_POL_INVERT)
+ val |= SGMII_PN_SWAP_RX;
+
+ ret = phy_get_tx_polarity(pcs_fwnode, phy_modes(interface),
+ BIT(PHY_POL_NORMAL) | BIT(PHY_POL_INVERT),
+ default_pol, &pol);
+ fwnode_handle_put(pcs_fwnode);
+ if (ret)
+ return ret;
+ if (pol == PHY_POL_INVERT)
+ val |= SGMII_PN_SWAP_TX;
+
+ return regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
+ SGMII_PN_SWAP_RX | SGMII_PN_SWAP_TX, val);
+}
+
static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
phy_interface_t interface,
const unsigned long *advertising,
@@ -128,6 +166,7 @@ static int mtk_pcs_lynxi_config(struct p
bool mode_changed = false, changed;
unsigned int rgc3, sgm_mode, bmcr;
int advertise, link_timer;
+ int ret;
advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
advertising);
@@ -167,10 +206,9 @@ static int mtk_pcs_lynxi_config(struct p
regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0,
SGMII_SW_RESET);
- if (fwnode_property_read_bool(mpcs->fwnode, "mediatek,pnswap"))
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
- SGMII_PN_SWAP_MASK,
- SGMII_PN_SWAP_TX_RX);
+ ret = mtk_pcs_config_polarity(mpcs, interface);
+ if (ret)
+ return ret;
if (interface == PHY_INTERFACE_MODE_2500BASEX)
rgc3 = SGMII_PHY_SPEED_3_125G;