Linux-PHY Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] phy: qcom: usb-hs: MSM8x60 vendor ULPI init
@ 2026-06-16 13:26 Herman van Hazendonk
  2026-06-16 13:26 ` [PATCH v3 1/2] dt-bindings: phy: qcom,usb-hs-phy: add qcom,hs-drv-slope Herman van Hazendonk
  2026-06-16 13:26 ` [PATCH v3 2/2] phy: qcom: usb-hs: program MSM8x60 vendor ULPI registers on power-on Herman van Hazendonk
  0 siblings, 2 replies; 4+ messages in thread
From: Herman van Hazendonk @ 2026-06-16 13:26 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Bjorn Andersson, Philipp Zabel, Nathan Chancellor,
	Nick Desaulniers, Bill Wendling, Justin Stitt
  Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, llvm,
	Herman van Hazendonk, konrad.dybcio, dmitry.baryshkov

v3 (this round):
 - Re-introduce a much smaller DT binding patch following Konrad's
   "do we have values for MTP/QRD" question and Dmitry's
   "qcom,hsdrvslope (or similarly named) property in DT" suggestion.
 - Survey of every MSM8x60-class downstream tree I could reach --
   Qualcomm reference (SURF/FFA/Fluid/Dragon/Fusion via
   board-msm8x60.c on android.googlesource.com), Samsung Galaxy S2
   family (Q1 / Celox / Dali / generic 8x60 MTP), Sony MSM8660
   (sony-kernel-msm8660), HTC MSM8660 ports
   (shooter / holiday / pyramid / doubleshot / shooter_u / ruby) and
   HP TouchPad -- shows that pre-emphasis, CDR auto-reset and SE1
   gating values are *identical* across every reference board.
   Only the 4-bit HS driver slope in reg 0x32 [3:0] varies.
 - Patch 1/2 adds a single qcom,hs-drv-slope DT property (u32,
   range 0..15) gated to the qcom,usb-hs-phy-msm8660 compatible.
 - Patch 2/2 hardcodes the three platform-wide writes in the driver
   behind the same compatible match, consumes qcom,hs-drv-slope for
   the board-specific bits, and leaves the silicon default in place
   when the property is absent -- which matches Qualcomm's own MTP,
   Samsung and Sony reference behaviour.
 - The bit-level meaning we *do* have comes from Code Aurora's
   downstream arch/arm/mach-msm/include/mach/msm_hsusb_hw.h, which
   Samsung and HP both shipped byte-for-byte identical.
 - Per Dmitry's request, both commit messages call out explicitly
   that there is no public Qualcomm documentation describing how the
   4-bit slope value maps to an actual slew rate / V/ns / %.  The
   field is an opaque hardware control; boards must copy the value
   from their vendor / downstream kernel as a measured-per-layout
   knob, not a derived one.

v2:
 - Dropped the original qcom,vendor-init-seq DT property entirely
   and folded all the vendor-register programming into the driver
   behind the qcom,usb-hs-phy-msm8660 compatible.
 - HS driver slope was hardcoded in v2.  v3 promotes that one
   varying value to a DT property as Dmitry requested.

Companion TouchPad DTS work (flipping the PHY compatible from
"qcom,usb-hs-phy-apq8064" to "qcom,usb-hs-phy-msm8660" and adding
qcom,hs-drv-slope = <5>) will be sent separately with the rest of
the apq8060-tenderloin DT series.

On-device validation (HP TouchPad / APQ8060):
 - Booted with v3 + the upcoming DTS hookup.  PHY driver bound,
   msm_hsusb HS link came up at high-speed.  No regression vs the v2
   hardcoded build.

Build / schema verification:
 - dt_binding_check DT_SCHEMA_FILES=.../qcom,usb-hs-phy.yaml: clean.
 - dtbs_check on qcom-apq8060-dragonboard.dtb and
   qcom-msm8960-cdp.dtb (the two existing in-tree usb-hs-phy
   consumers): clean.
 - drivers/phy/qualcomm/phy-qcom-usb-hs.o builds clean.
 - checkpatch.pl --strict: no warnings on either patch.

Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
---
Herman van Hazendonk (2):
      dt-bindings: phy: qcom,usb-hs-phy: add qcom,hs-drv-slope
      phy: qcom: usb-hs: program MSM8x60 vendor ULPI registers on power-on

 .../devicetree/bindings/phy/qcom,usb-hs-phy.yaml   | 89 +++++++++++++++-------
 drivers/phy/qualcomm/phy-qcom-usb-hs.c             | 68 +++++++++++++++++
 2 files changed, 131 insertions(+), 26 deletions(-)
---
base-commit: 944125b4c454b58d2fe6e35f1087a932b2050dff
change-id: 20260616-submit-phy-usb-hs-vendor-init-seq-ad39d29ccaf5

Best regards,
-- 
Herman van Hazendonk <github.com@herrie.org>


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3 1/2] dt-bindings: phy: qcom,usb-hs-phy: add qcom,hs-drv-slope
  2026-06-16 13:26 [PATCH v3 0/2] phy: qcom: usb-hs: MSM8x60 vendor ULPI init Herman van Hazendonk
@ 2026-06-16 13:26 ` Herman van Hazendonk
  2026-06-22  9:21   ` Krzysztof Kozlowski
  2026-06-16 13:26 ` [PATCH v3 2/2] phy: qcom: usb-hs: program MSM8x60 vendor ULPI registers on power-on Herman van Hazendonk
  1 sibling, 1 reply; 4+ messages in thread
From: Herman van Hazendonk @ 2026-06-16 13:26 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Bjorn Andersson, Philipp Zabel, Nathan Chancellor,
	Nick Desaulniers, Bill Wendling, Justin Stitt
  Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, llvm,
	Herman van Hazendonk, konrad.dybcio, dmitry.baryshkov

The MSM8x60 / APQ8060 PHY needs three vendor ULPI register tweaks for
stable USB operation: pre-emphasis level, CDR auto-reset and SE1
gating in registers 0x32 and 0x36.  A survey of MSM8x60-class
downstream board files (Qualcomm SURF/FFA/Fluid/Dragon, Samsung
Galaxy S2 family, Sony Xperia, HTC and HP TouchPad) shows that those
three values are identical across every reference board and can be
hardcoded in the driver behind the existing
qcom,usb-hs-phy-msm8660 compatible.

The only board-specific value is the 4-bit HS driver slope in bits
[3:0] of register 0x32:

  HP TouchPad                                  5
  HTC MSM8660 ports                            1
  Qualcomm / Samsung / Sony reference boards   0 (silicon default)

Add a qcom,hs-drv-slope property carrying that 4-bit value, valid
only on the qcom,usb-hs-phy-msm8660 variant.  When the property is
absent the driver leaves the silicon default in place, matching the
behaviour of the Qualcomm reference platform.

No public Qualcomm documentation describes how the 4-bit value maps
to an actual slew rate, V/ns or %; the bits are an opaque hardware
control whose meaning only Qualcomm knows.  The legal range (0..15)
comes from the field width in the downstream
arch/arm/mach-msm/include/mach/msm_hsusb_hw.h
(ULPI_HSDRVSLOPE_MASK == 0x0F).  Boards must therefore copy the
value from their downstream/vendor kernel; this is a measured /
tuned-per-layout knob, not a derived one.

Assisted-by: Claude:claude-opus-4-7 dt_binding_check checkpatch
Assisted-by: Sashiko:claude-opus-4-7
Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
---
 .../devicetree/bindings/phy/qcom,usb-hs-phy.yaml   | 89 +++++++++++++++-------
 1 file changed, 63 insertions(+), 26 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.yaml
index e03b516c698c..e605f5683f7d 100644
--- a/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,usb-hs-phy.yaml
@@ -9,32 +9,43 @@ title: Qualcomm's USB HS PHY
 maintainers:
   - Bjorn Andersson <bjorn.andersson@linaro.org>
 
-if:
-  properties:
-    compatible:
-      contains:
-        enum:
-          - qcom,usb-hs-phy-apq8064
-          - qcom,usb-hs-phy-msm8660
-          - qcom,usb-hs-phy-msm8960
-then:
-  properties:
-    resets:
-      maxItems: 1
-
-    reset-names:
-      const: por
-
-else:
-  properties:
-    resets:
-      minItems: 2
-      maxItems: 2
-
-    reset-names:
-      items:
-        - const: phy
-        - const: por
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,usb-hs-phy-apq8064
+              - qcom,usb-hs-phy-msm8660
+              - qcom,usb-hs-phy-msm8960
+    then:
+      properties:
+        resets:
+          maxItems: 1
+
+        reset-names:
+          const: por
+
+    else:
+      properties:
+        resets:
+          minItems: 2
+          maxItems: 2
+
+        reset-names:
+          items:
+            - const: phy
+            - const: por
+
+  - if:
+      not:
+        properties:
+          compatible:
+            contains:
+              const: qcom,usb-hs-phy-msm8660
+    then:
+      properties:
+        qcom,hs-drv-slope: false
 
 properties:
   compatible:
@@ -85,6 +96,15 @@ properties:
             the address is offset from the ULPI_EXT_VENDOR_SPECIFIC address
         - description: value
 
+  qcom,hs-drv-slope:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: >
+      4-bit HS driver slope written to bits [3:0] of ULPI vendor
+      register 0x32. Board-specific tuning value; absent means
+      leave silicon default. Only valid on qcom,usb-hs-phy-msm8660.
+    minimum: 0
+    maximum: 15
+
 required:
   - clocks
   - clock-names
@@ -114,3 +134,20 @@ examples:
         };
       };
     };
+
+  - |
+    usb-controller {
+      #reset-cells = <1>;
+
+      ulpi {
+        phy {
+          compatible = "qcom,usb-hs-phy-msm8660", "qcom,usb-hs-phy";
+          #phy-cells = <0>;
+          clocks = <&clk 0>, <&clk 1>;
+          clock-names = "ref", "sleep";
+          resets = <&otg 0>;
+          reset-names = "por";
+          qcom,hs-drv-slope = <5>;
+        };
+      };
+    };

-- 
2.43.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/2] phy: qcom: usb-hs: program MSM8x60 vendor ULPI registers on power-on
  2026-06-16 13:26 [PATCH v3 0/2] phy: qcom: usb-hs: MSM8x60 vendor ULPI init Herman van Hazendonk
  2026-06-16 13:26 ` [PATCH v3 1/2] dt-bindings: phy: qcom,usb-hs-phy: add qcom,hs-drv-slope Herman van Hazendonk
@ 2026-06-16 13:26 ` Herman van Hazendonk
  1 sibling, 0 replies; 4+ messages in thread
From: Herman van Hazendonk @ 2026-06-16 13:26 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Bjorn Andersson, Philipp Zabel, Nathan Chancellor,
	Nick Desaulniers, Bill Wendling, Justin Stitt
  Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, llvm,
	Herman van Hazendonk, konrad.dybcio, dmitry.baryshkov

The MSM8x60-class PHY needs three vendor-register tweaks for stable
USB operation, which the legacy msm_otg driver used to drive from
board platform data.  A survey of every MSM8x60-class downstream tree
(Qualcomm SURF/FFA/Fluid/Dragon, Samsung Galaxy S2 family, Sony
Xperia, HTC MSM8660 ports and HP TouchPad) shows that two of the
three settings are identical across every board:

  - reg 0x32 [5:4] = 11b: pre-emphasis level set to 20%
  - reg 0x36 bit 1 = 1, bit 2 = 1: CDR auto-reset and SE1 gating
    disabled (the legacy driver inverts these bits, so setting them
    disables the function)

Hardcode those two unconditionally behind the existing
qcom,usb-hs-phy-msm8660 compatible.  The bit-level documentation
comes from the Code Aurora downstream header
arch/arm/mach-msm/include/mach/msm_hsusb_hw.h, which Samsung and HP
both shipped byte-for-byte identical.

The third setting -- reg 0x32 [3:0] HS driver slope -- is genuinely
board-specific (HP TouchPad uses 5, HTC MSM8660 ports use 1, every
Qualcomm/Samsung/Sony reference board leaves the silicon default of
0) and is consumed from the new qcom,hs-drv-slope DT property.  When
the property is absent the silicon default is preserved.

No public Qualcomm documentation describes how the 4-bit slope value
maps to an actual slew rate, V/ns or %; the field is an opaque
hardware control whose semantics only Qualcomm knows.  Boards must
copy the value from their vendor / downstream kernel -- this is a
measured / tuned-per-layout knob, not a derived one.  We program the
4 bits verbatim and trust the silicon to do the right thing.

The writes live behind a runtime flag that only matches
"qcom,usb-hs-phy-msm8660" so the existing MSM8226/8916/8960/8974
consumers are untouched.  They are issued *after*
reset_control_reset() so the values survive the register restore the
reset performs.

Note: HTC MSM8660 vendor kernels additionally write 0x0C to reg 0x31.
The HP TouchPad webOS kernel does not touch that register and USB is
stable without it, so those bits are omitted here until documentation
is available to explain what they control.

Assisted-by: Claude:claude-opus-4-7 sparse smatch clang-analyzer coccinelle checkpatch
Assisted-by: Sashiko:claude-opus-4-7
Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
---
 drivers/phy/qualcomm/phy-qcom-usb-hs.c | 68 ++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hs.c b/drivers/phy/qualcomm/phy-qcom-usb-hs.c
index 98a18987f1be..a7649a09e82c 100644
--- a/drivers/phy/qualcomm/phy-qcom-usb-hs.c
+++ b/drivers/phy/qualcomm/phy-qcom-usb-hs.c
@@ -20,6 +20,14 @@
 # define ULPI_MISC_A_VBUSVLDEXTSEL	BIT(1)
 # define ULPI_MISC_A_VBUSVLDEXT		BIT(0)
 
+/* MSM8x60 vendor ULPI registers (raw addresses, not ULPI_EXT_VENDOR_SPECIFIC). */
+#define ULPI_MSM_CONFIG_REG3		0x32
+# define ULPI_MSM_HSDRVSLOPE_MASK	GENMASK(3, 0)
+# define ULPI_MSM_PRE_EMPHASIS_MASK	GENMASK(5, 4)
+# define ULPI_MSM_PRE_EMPHASIS_20PCT	(3 << 4)
+#define ULPI_MSM_DIGOUT_CTRL		0x36
+# define ULPI_MSM_CDR_AUTORESET		BIT(1)
+# define ULPI_MSM_SE1_GATE		BIT(2)
 
 struct ulpi_seq {
 	u8 addr;
@@ -37,6 +45,9 @@ struct qcom_usb_hs_phy {
 	struct ulpi_seq *init_seq;
 	struct extcon_dev *vbus_edev;
 	struct notifier_block vbus_notify;
+	bool msm8x60_init;
+	bool hs_drv_slope_present;
+	u8 hs_drv_slope;
 };
 
 static int qcom_usb_hs_phy_set_mode(struct phy *phy,
@@ -105,6 +116,41 @@ qcom_usb_hs_phy_vbus_notifier(struct notifier_block *nb, unsigned long event,
 	return ulpi_write(uphy->ulpi, addr, ULPI_MISC_A_VBUSVLDEXT);
 }
 
+/*
+ * RMW the vendor registers to preserve silicon reserved bits.
+ * In reg 0x36 the legacy semantics are inverted: setting
+ * CDR_AUTORESET / SE1_GATE *disables* those functions.
+ */
+static int qcom_usb_hs_phy_msm8x60_init(struct qcom_usb_hs_phy *uphy)
+{
+	struct ulpi *ulpi = uphy->ulpi;
+	int reg32, reg36, ret;
+
+	reg32 = ulpi_read(ulpi, ULPI_MSM_CONFIG_REG3);
+	if (reg32 < 0)
+		return reg32;
+
+	reg32 &= ~ULPI_MSM_PRE_EMPHASIS_MASK;
+	reg32 |= ULPI_MSM_PRE_EMPHASIS_20PCT;
+
+	if (uphy->hs_drv_slope_present) {
+		reg32 &= ~ULPI_MSM_HSDRVSLOPE_MASK;
+		reg32 |= uphy->hs_drv_slope & ULPI_MSM_HSDRVSLOPE_MASK;
+	}
+
+	ret = ulpi_write(ulpi, ULPI_MSM_CONFIG_REG3, reg32);
+	if (ret)
+		return ret;
+
+	reg36 = ulpi_read(ulpi, ULPI_MSM_DIGOUT_CTRL);
+	if (reg36 < 0)
+		return reg36;
+
+	reg36 |= ULPI_MSM_CDR_AUTORESET | ULPI_MSM_SE1_GATE;
+
+	return ulpi_write(ulpi, ULPI_MSM_DIGOUT_CTRL, reg36);
+}
+
 static int qcom_usb_hs_phy_power_on(struct phy *phy)
 {
 	struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy);
@@ -154,6 +200,12 @@ static int qcom_usb_hs_phy_power_on(struct phy *phy)
 			goto err_ulpi;
 	}
 
+	if (uphy->msm8x60_init) {
+		ret = qcom_usb_hs_phy_msm8x60_init(uphy);
+		if (ret)
+			goto err_ulpi;
+	}
+
 	if (uphy->vbus_edev) {
 		state = extcon_get_state(uphy->vbus_edev, EXTCON_USB);
 		/* setup initial state */
@@ -214,6 +266,22 @@ static int qcom_usb_hs_phy_probe(struct ulpi *ulpi)
 		return -ENOMEM;
 	ulpi_set_drvdata(ulpi, uphy);
 	uphy->ulpi = ulpi;
+	uphy->msm8x60_init = of_device_is_compatible(ulpi->dev.of_node,
+						     "qcom,usb-hs-phy-msm8660");
+
+	if (uphy->msm8x60_init) {
+		u32 slope;
+
+		if (!of_property_read_u32(ulpi->dev.of_node,
+					  "qcom,hs-drv-slope", &slope)) {
+			if (slope > ULPI_MSM_HSDRVSLOPE_MASK)
+				return dev_err_probe(&ulpi->dev, -EINVAL,
+						     "qcom,hs-drv-slope out of range (max %lu)\n",
+						     ULPI_MSM_HSDRVSLOPE_MASK);
+			uphy->hs_drv_slope = slope;
+			uphy->hs_drv_slope_present = true;
+		}
+	}
 
 	size = of_property_count_u8_elems(ulpi->dev.of_node, "qcom,init-seq");
 	if (size < 0)

-- 
2.43.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: phy: qcom,usb-hs-phy: add qcom,hs-drv-slope
  2026-06-16 13:26 ` [PATCH v3 1/2] dt-bindings: phy: qcom,usb-hs-phy: add qcom,hs-drv-slope Herman van Hazendonk
@ 2026-06-22  9:21   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 4+ messages in thread
From: Krzysztof Kozlowski @ 2026-06-22  9:21 UTC (permalink / raw)
  To: Herman van Hazendonk
  Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Bjorn Andersson, Philipp Zabel, Nathan Chancellor,
	Nick Desaulniers, Bill Wendling, Justin Stitt, linux-arm-msm,
	linux-phy, devicetree, linux-kernel, llvm, konrad.dybcio,
	dmitry.baryshkov

On Tue, Jun 16, 2026 at 03:26:53PM +0200, Herman van Hazendonk wrote:
> The MSM8x60 / APQ8060 PHY needs three vendor ULPI register tweaks for
> stable USB operation: pre-emphasis level, CDR auto-reset and SE1
> gating in registers 0x32 and 0x36.  A survey of MSM8x60-class
> downstream board files (Qualcomm SURF/FFA/Fluid/Dragon, Samsung
> Galaxy S2 family, Sony Xperia, HTC and HP TouchPad) shows that those
> three values are identical across every reference board and can be
> hardcoded in the driver behind the existing
> qcom,usb-hs-phy-msm8660 compatible.
> 
> The only board-specific value is the 4-bit HS driver slope in bits
> [3:0] of register 0x32:
> 
>   HP TouchPad                                  5
>   HTC MSM8660 ports                            1
>   Qualcomm / Samsung / Sony reference boards   0 (silicon default)
> 
> Add a qcom,hs-drv-slope property carrying that 4-bit value, valid
> only on the qcom,usb-hs-phy-msm8660 variant.  When the property is
> absent the driver leaves the silicon default in place, matching the
> behaviour of the Qualcomm reference platform.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-06-22  9:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-16 13:26 [PATCH v3 0/2] phy: qcom: usb-hs: MSM8x60 vendor ULPI init Herman van Hazendonk
2026-06-16 13:26 ` [PATCH v3 1/2] dt-bindings: phy: qcom,usb-hs-phy: add qcom,hs-drv-slope Herman van Hazendonk
2026-06-22  9:21   ` Krzysztof Kozlowski
2026-06-16 13:26 ` [PATCH v3 2/2] phy: qcom: usb-hs: program MSM8x60 vendor ULPI registers on power-on Herman van Hazendonk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox