[PATCH 0/4] Fix up QUSB2 PHY description for MSM8996/SM61[12]5

Konrad Dybcio konrad.dybcio at oss.qualcomm.com
Thu Sep 3 07:18:52 PDT 2026


On 6/10/26 3:20 PM, Dmitry Baryshkov wrote:
> On Wed, Jun 10, 2026 at 03:13:01PM +0200, Konrad Dybcio wrote:
>> On 6/10/26 3:03 PM, Dmitry Baryshkov wrote:
>>> On Wed, Jun 10, 2026 at 02:49:31PM +0200, Konrad Dybcio wrote:
>>>> On 6/10/26 2:04 PM, Konrad Dybcio wrote:
>>>>> The MSM8996 QUSB2PHY was not being guaranteed a power source.
>>>>> The SM6125's QUSB2PHY was believed to be idential as the 96 one. It
>>>>> wasn't. This series tackles that, freeing us of some dt checker
>>>>> errors about vdd-supply not found on MSM8996 boards.

[...]

>> reg   96   pro
>> 0x80 0xF8  0xD0 [!] QUSB2PHY_PORT_TUNE1
>> 0x84 0xB3  0xB3
>> 0x88 0x83  0x83
>> 0x8C 0xC0  0xC0
>> 0x90 none  0x02 [!] QUSB2PHY_PORT_TUNE5
>> 0x08 0x30  0x30
>> 0x0C 0x79  0x79
>> 0x10 0x21  0x21
>> 0x9C 0x14  0x14
>> 0x1C 0x9F  0x9F
>> 0x18 0x00  0x00
>>
>> apparently this is indeed SoC-specific (via docs) but also apparently
>> may not be very important (although should be fixed regardless as
>> some designs may rely on this)
> 
> Would you send a patch, please?

So the tuning differences may be taken care of through a separate table,
or by adding support for overriding parameters for the QUSB2PHYv1 (8996
-class) devices. Currently the overrides only really work as intended
for V2/V3 (SDM845-class) PHYs as the register layout changed majorly.

I think the real right solution here is to fix the overrides.
dt-bindings clearly created by an LLM :)


I implemented some of it, but I currently don't have the time
for finishing it up - feel free to take it further. It would also
help adjust the specific OnePlus init sequence that was originally
used for every SM6115 device (patch 2)

I also discovered that the interrupt mask is wrong for V1 PHYs.
At this point maybe it'd be easier to split off the v1 support to
a separate driver? Anyway, up to you.

I'll resend this series as-is as it fixes actual issues.

Konrad

commit 792eeeb5d43428cedc72c5778f664a33c4cf2b30
Author: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
Date:   Thu Sep 3 16:10:36 2026 +0200

    [WIP] qusb2phy v1 overrides/tuning/fixups
    
    Assisted-by: LLM

diff --git a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
index 39e796cd5dc6..13a5c08fdb8e 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
@@ -169,6 +169,22 @@ properties:
     maximum: 3
     default: 0
 
+  qcom,man-sqrx-dis-value:
+    description:
+      It is a 1 bit value that enables manual squelch receiver disable.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 1
+    default: 0
+
+  qcom,squelch-eop-delay-value:
+    description:
+      It is a 2 bit value that specifies the squelch end-of-packet delay.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 3
+    default: 0
+
 required:
   - compatible
   - reg
@@ -182,10 +198,17 @@ required:
 allOf:
   - if:
       not:
-        properties:
-          compatible:
-            contains:
-              const: qcom,qusb2-v2-phy
+        anyOf:
+          - properties:
+              compatible:
+                contains:
+                  const: qcom,qusb2-v2-phy
+          - properties:
+              compatible:
+                contains:
+                  enum:
+                    - qcom,msm8996-qusb2-phy
     then:
       properties:
         qcom,imp-res-offset-value: false
@@ -196,6 +219,19 @@ allOf:
         qcom,preemphasis-width: false
         qcom,hsdisc-trim-value: false
 
+  - if:
+      not:
+        properties:
+          compatible:
+            contains:
+              enum:
+                - qcom,msm8996-qusb2-phy
+    then:
+      properties:
+        qcom,man-sqrx-dis-value: false
+        qcom,squelch-eop-delay-value: false
+
   # On MSM8996, VDD is supplied via the MX power domain
   - if:
       properties:
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index c34d847b123c..a9435b6e1637 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -51,7 +51,22 @@
 
 #define PHY_CLK_SCHEME_SEL		BIT(0)
 
+/* V1 (MSM8996) register fields */
+
+/* QUSB2PHY_PORT_TUNE2 register bits */
+#define UTM_HSTX_TRIM_V1		GENMASK(7, 4)
+
+/* QUSB2PHY_PORT_TUNE4 register bits */
+#define SQUELCH_EOP_DLY_V1		GENMASK(7, 6)
+#define MAN_SQRX_DIS_V1			BIT(4)
+#define PREEMPH_WIDTH_HALF_BIT_V1	BIT(3)
+#define PREEMPHASIS_EN_MASK_V1		GENMASK(2, 0)
+
+/* V2/V3 (SDM845) register fields */
 /* QUSB2PHY_INTR_CTRL register bits */
+
+// v1: 4-chg 3-dmse_high 2-dmse 1-dpse_high 0-dpse
+// v3: 4- dmse_high 3-dpse_high 2-chg_det 1-dmse_intr 0-dpse_intr
 #define DMSE_INTR_HIGH_SEL			BIT(4)
 #define DPSE_INTR_HIGH_SEL			BIT(3)
 #define CHG_DET_INTR_EN				BIT(2)
@@ -443,14 +458,17 @@ struct override_param {
 	u8 value;
 };
 
-/*struct override_params - structure holding qusb2 v2 phy overriding params
+/**
+ * struct override_params - structure holding QUSB2 PHY override parameters
  * @imp_res_offset: rescode offset to be updated in IMP_CTRL1 register
- * @hstx_trim: HSTX_TRIM to be updated in TUNE1 register
- * @preemphasis: Amplitude Pre-Emphasis to be updated in TUNE1 register
- * @preemphasis_width: half/full-width Pre-Emphasis updated via TUNE1
- * @bias_ctrl: bias ctrl to be updated in BIAS_CONTROL_2 register
- * @charge_ctrl: charge ctrl to be updated in CHG_CTRL2 register
- * @hsdisc_trim: disconnect threshold to be updated in TUNE2 register
+ * @hstx_trim: High-Speed TX trim
+ * @preemphasis: Amplitude Pre-Emphasis
+ * @preemphasis_width: Pre-Emphasis width (half/full)
+ * @bias_ctrl: bias control value
+ * @charge_ctrl: charge control value
+ * @hsdisc_trim: High-Speed disconnect threshold
+ * @man_sqrx_dis: manual squelch receiver disable
+ * @squelch_eop_delay: squelch end-of-packet delay
  */
 struct override_params {
 	struct override_param imp_res_offset;
@@ -460,6 +478,9 @@ struct override_params {
 	struct override_param bias_ctrl;
 	struct override_param charge_ctrl;
 	struct override_param hsdisc_trim;
+
+	struct override_param man_sqrx_dis;
+	struct override_param squelch_eop_delay;
 };
 
 /**
@@ -558,11 +579,48 @@ void qcom_qusb2_phy_configure(void __iomem *base,
 	}
 }
 
-/*
- * Update board specific PHY tuning override values if specified from
- * device tree.
- */
-static void qusb2_phy_override_phy_params(struct qusb2_phy *qphy)
+static void qusb2_v1_phy_override_phy_params(struct qusb2_phy *qphy)
+{
+	const struct qusb2_phy_cfg *cfg = qphy->cfg;
+	struct override_params *or = &qphy->overrides;
+
+	if (or->hstx_trim.override) {
+		qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
+				 FIELD_PREP(UTM_HSTX_TRIM_V1, or->hstx_trim.value),
+				 UTM_HSTX_TRIM_V1);
+	}
+
+	if (or->squelch_eop_delay.override) {
+		qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE4],
+				 FIELD_PREP(SQUELCH_EOP_DLY_V1, or->squelch_eop_delay.value),
+				 SQUELCH_EOP_DLY_V1);
+	}
+
+	if (or->man_sqrx_dis.override) {
+		qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE4],
+				 FIELD_PREP(MAN_SQRX_DIS_V1, or->man_sqrx_dis.value),
+				 MAN_SQRX_DIS_V1);
+	}
+
+	if (or->preemphasis.override) {
+		qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE4],
+				 FIELD_PREP(PREEMPHASIS_EN_MASK_V1, or->preemphasis.value),
+				 PREEMPHASIS_EN_MASK_V1);
+	}
+
+	if (or->preemphasis_width.override) {
+		if (or->preemphasis_width.value == QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT)
+			qusb2_setbits(qphy->base,
+				      cfg->regs[QUSB2PHY_PORT_TUNE4],
+				      PREEMPH_WIDTH_HALF_BIT_V1);
+		else
+			qusb2_clrbits(qphy->base,
+				      cfg->regs[QUSB2PHY_PORT_TUNE4],
+				      PREEMPH_WIDTH_HALF_BIT_V1);
+	}
+}
+
+static void qusb2_v3_phy_override_phy_params(struct qusb2_phy *qphy)
 {
 	const struct qusb2_phy_cfg *cfg = qphy->cfg;
 	struct override_params *or = &qphy->overrides;
@@ -840,7 +898,10 @@ static int qusb2_phy_init(struct phy *phy)
 				 cfg->tbl_num);
 
 	/* Override board specific PHY tuning values */
-	qusb2_phy_override_phy_params(qphy);
+	if (true /* TODO: */)
+		qusb2_v3_phy_override_phy_params(qphy);
+	else
+		qusb2_v1_phy_override_phy_params(qphy);
 
 	/* Set efuse value for tuning the PHY */
 	qusb2_phy_set_tune2_param(qphy);
@@ -1136,6 +1197,18 @@ static int qusb2_phy_probe(struct platform_device *pdev)
 		or->hsdisc_trim.override = true;
 	}
 
+	if (!of_property_read_u32(dev->of_node, "qcom,man-sqrx-dis-value",
+				  &value)) {
+		or->man_sqrx_dis.value = (u8)value;
+		or->man_sqrx_dis.override = true;
+	}
+
+	if (!of_property_read_u32(dev->of_node,
+				  "qcom,squelch-eop-delay-value", &value)) {
+		or->squelch_eop_delay.value = (u8)value;
+		or->squelch_eop_delay.override = true;
+	}
+
 	dev_set_drvdata(dev, qphy);
 
 	/*




More information about the linux-phy mailing list