phy: zynqmp: keep SERDES scrambler and 8b/10b enabled for USB

USB Gen1 requires scrambling and 8b/10b encoding to be performed in the
physical layer. Do not bypass PHY-side scrambler or encoder/decoder for
USB operation, as mandated by the USB 3.x specification.

Scrambler and 8b/10b bypass remain restricted to SATA and SGMII
modes, where encoding is handled in the controller.

Fixes: 4a33bea003 ("phy: zynqmp: Add PHY driver for the Xilinx ZynqMP Gigabit Transceiver")
Cc: stable@vger.kernel.org
Signed-off-by: Nava kishore Manne <nava.kishore.manne@amd.com>
Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Acked-by: Michal Simek <michal.simek@amd.com>
Link: https://patch.msgid.link/20260627155229.2791113-4-radhey.shyam.pandey@amd.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Nava kishore Manne
2026-07-22 20:52:59 +05:30
committed by Vinod Koul
parent 21e0749f93
commit 7eb61caf45
+29 -10
View File
@@ -502,15 +502,30 @@ static void xpsgtr_lane_set_protocol(struct xpsgtr_phy *gtr_phy)
}
}
/* Bypass (de)scrambler and 8b/10b decoder and encoder. */
static void xpsgtr_bypass_scrambler_8b10b(struct xpsgtr_phy *gtr_phy)
/**
* xpsgtr_bypass_scrambler_8b10b - Configure scrambler/encoder behavior
* @gtr_phy: pointer to lane context
* @bypass: true to enable scrambler/encoder bypass (SATA/SGMII),
* false to disable scrambler/encoder bypass (USB3)
*
* Uses RMW to preserve reserved and unrelated register fields.
*/
static void xpsgtr_bypass_scrambler_8b10b(struct xpsgtr_phy *gtr_phy,
bool bypass)
{
xpsgtr_clr_set_phy(gtr_phy, L0_TM_DIG_6,
L0_TM_DIS_DESCRAMBLE_DECODER,
L0_TM_DIS_DESCRAMBLE_DECODER);
xpsgtr_clr_set_phy(gtr_phy, L0_TX_DIG_61,
L0_TM_DISABLE_SCRAMBLE_ENCODER,
L0_TM_DISABLE_SCRAMBLE_ENCODER);
if (bypass) {
xpsgtr_clr_set_phy(gtr_phy, L0_TM_DIG_6,
L0_TM_DIS_DESCRAMBLE_DECODER,
L0_TM_DIS_DESCRAMBLE_DECODER);
xpsgtr_clr_set_phy(gtr_phy, L0_TX_DIG_61,
L0_TM_DISABLE_SCRAMBLE_ENCODER,
L0_TM_DISABLE_SCRAMBLE_ENCODER);
} else {
xpsgtr_clr_set_phy(gtr_phy, L0_TM_DIG_6,
L0_TM_DIS_DESCRAMBLE_DECODER, 0);
xpsgtr_clr_set_phy(gtr_phy, L0_TX_DIG_61,
L0_TM_DISABLE_SCRAMBLE_ENCODER, 0);
}
}
/* DP-specific initialization. */
@@ -531,7 +546,7 @@ static void xpsgtr_phy_init_sata(struct xpsgtr_phy *gtr_phy)
{
struct xpsgtr_dev *gtr_dev = gtr_phy->dev;
xpsgtr_bypass_scrambler_8b10b(gtr_phy);
xpsgtr_bypass_scrambler_8b10b(gtr_phy, true);
writel(gtr_phy->lane, gtr_dev->siou + SATA_CONTROL_OFFSET);
}
@@ -547,7 +562,7 @@ static void xpsgtr_phy_init_sgmii(struct xpsgtr_phy *gtr_phy)
xpsgtr_clr_set(gtr_dev, TX_PROT_BUS_WIDTH, mask, val);
xpsgtr_clr_set(gtr_dev, RX_PROT_BUS_WIDTH, mask, val);
xpsgtr_bypass_scrambler_8b10b(gtr_phy);
xpsgtr_bypass_scrambler_8b10b(gtr_phy, true);
}
/* Configure TX de-emphasis and margining for DP. */
@@ -708,6 +723,10 @@ static int xpsgtr_phy_init(struct phy *phy)
case ICM_PROTOCOL_SGMII:
xpsgtr_phy_init_sgmii(gtr_phy);
break;
case ICM_PROTOCOL_USB:
xpsgtr_bypass_scrambler_8b10b(gtr_phy, false);
break;
}
goto out;