[PATCH 06/10] phy: qcom-ipq806x-usb: fix the PHY_PARAM_CTRL1 field masks
From: Dmitry Baryshkov
Date: Mon Aug 10 2026 - 07:45:51 EST
Each of the PHY_PARAM_CTRL1 field masks extends one bit below its
documented field: TX_FULL_SWING [26:20] is coded as GENMASK(26, 19),
TX_DEEMPH_6DB [19:14] as GENMASK(19, 13), TX_DEEMPH_3_5DB [13:8] as
GENMASK(13, 7) and LOS_BIAS [7:3] as GENMASK(7, 2). Also, the field
described as LOS_BIAS in reality is called LOS_LEVEL. FIELD_PREP against
these masks places every value one bit short of its field, so the
programmed swing/de-emphasis/LOS parameters land shifted and the
neighbouring fields are corrupted; the masked write-readback in the SS
PHY init reports 'write: ... to QSCRATCH: 4 FAILED'.
Align the masks with the documented field positions.
Fixes: ef19b117b834 ("phy: qualcomm: add qcom ipq806x dwc usb phy driver")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxxxxxxxx>
---
drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
index cf77e0a66e20..3d3e9d6da298 100644
--- a/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
@@ -68,15 +68,17 @@
#define SSPHY_MPLL_VALUE 0
/* QSCRATCH PHY_PARAM_CTRL1 fields */
-#define PHY_PARAM_CTRL1_TX_FULL_SWING_MASK GENMASK(26, 19)
-#define PHY_PARAM_CTRL1_TX_DEEMPH_6DB_MASK GENMASK(19, 13)
-#define PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB_MASK GENMASK(13, 7)
-#define PHY_PARAM_CTRL1_LOS_BIAS_MASK GENMASK(7, 2)
+#define PHY_PARAM_CTRL1_TX_FULL_SWING_MASK GENMASK(26, 20)
+#define PHY_PARAM_CTRL1_TX_DEEMPH_6DB_MASK GENMASK(19, 14)
+#define PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB_MASK GENMASK(13, 8)
+#define PHY_PARAM_CTRL1_LOS_LEVEL_MASK GENMASK(7, 3)
+#define PHY_PARAM_CTRL1_LOS_BIAS_MASK GENMASK(2, 0)
#define PHY_PARAM_CTRL1_MASK \
(PHY_PARAM_CTRL1_TX_FULL_SWING_MASK | \
PHY_PARAM_CTRL1_TX_DEEMPH_6DB_MASK | \
PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB_MASK | \
+ PHY_PARAM_CTRL1_LOS_LEVEL_MASK | \
PHY_PARAM_CTRL1_LOS_BIAS_MASK)
#define PHY_PARAM_CTRL1_TX_FULL_SWING(x) \
@@ -85,6 +87,8 @@
FIELD_PREP(PHY_PARAM_CTRL1_TX_DEEMPH_6DB_MASK, (x))
#define PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB(x) \
FIELD_PREP(PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB_MASK, x)
+#define PHY_PARAM_CTRL1_LOS_LEVEL(x) \
+ FIELD_PREP(PHY_PARAM_CTRL1_LOS_LEVEL_MASK, (x))
#define PHY_PARAM_CTRL1_LOS_BIAS(x) \
FIELD_PREP(PHY_PARAM_CTRL1_LOS_BIAS_MASK, (x))
@@ -436,7 +440,8 @@ static int qcom_ipq806x_usb_ss_phy_init(struct phy *phy)
data |= PHY_PARAM_CTRL1_TX_FULL_SWING(0x6e) |
PHY_PARAM_CTRL1_TX_DEEMPH_6DB(0x20) |
PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB(phy_dwc3->tx_deamp_3_5db) |
- PHY_PARAM_CTRL1_LOS_BIAS(0x9);
+ PHY_PARAM_CTRL1_LOS_LEVEL(0x9) |
+ PHY_PARAM_CTRL1_LOS_BIAS(0x0);
usb_phy_write_readback(phy_dwc3, SSUSB_PHY_PARAM_CTRL_1,
PHY_PARAM_CTRL1_MASK, data);
--
2.47.3