On 10/20/26 11:16, Neil Armstrong wrote:
On 10/13/26 19:08, Balaji Selvanathan wrote:
The TypeC port-select mux was always programmed with SW_PORTSELECT_MUX
set and SW_PORTSELECT_VAL left clear, regardless of which way the
USB-C cable was inserted. On a board where the cable goes in reversed,
the SuperSpeed/DP lanes end up routed to the wrong side of the
connector, so USB3/DP never comes up correctly.

Cable orientation is reported by a GPIO on the qcom,pmic-glink node
("orientation-gpios"), and is now sampled each time the PHY is
enabled to check for the orientation.

Taken from Linux commit 815891eee668 ("phy: qcom-qmp-combo: Introduce
orientation variable").

Tested on QCS6490 RB3 Gen2 board.

Signed-off-by: Balaji Selvanathan <[email protected]>
---
Changes in v2:
- Instead of reading the orientation at probe, read it only during the PHY init
- Updated the commit message to better explain why this change is required
- Link to v1: 
https://lore.kernel.org/u-boot/20260724-kodiak_ss_orientation-v1-1-d9d8fd271...@oss.qualcomm.com/
---
  drivers/phy/qcom/phy-qcom-qmp-combo.c | 26 ++++++++++++++++++++++++++
  1 file changed, 26 insertions(+)

diff --git a/drivers/phy/qcom/phy-qcom-qmp-combo.c 
b/drivers/phy/qcom/phy-qcom-qmp-combo.c
index 0d63e482ee4..65141489d51 100644
--- a/drivers/phy/qcom/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qcom/phy-qcom-qmp-combo.c
@@ -7,10 +7,12 @@
  #include <dm.h>
  #include <dm/device_compat.h>
  #include <dm/devres.h>
+#include <dm/ofnode.h>
  #include <generic-phy.h>
  #include <reset.h>
  #include <power/regulator.h>
  #include <asm/io.h>
+#include <asm-generic/gpio.h>
  #include <linux/bitops.h>
  #include <linux/compat.h>
  #include <linux/delay.h>
@@ -39,6 +41,7 @@
  #define DP_MODE                                 BIT(1) /* enables DP mode */
  /* QPHY_V3_DP_COM_TYPEC_CTRL register bits */
+#define SW_PORTSELECT_VAL                       BIT(0)
  #define SW_PORTSELECT_MUX                       BIT(1)
  /* PHY slot identifiers for device tree phandle arguments */
@@ -283,6 +286,27 @@ static int qmp_combo_com_exit(struct qmp_combo *qmp)
      return 0;
  }
+static bool qmp_combo_read_orientation(void)
+{
+    ofnode node;
+    struct gpio_desc desc;
+    int ret, val;
+
+    node = ofnode_by_compatible(ofnode_null(), "qcom,pmic-glink");
+    if (!ofnode_valid(node))
+        return false;
+
+    ret = gpio_request_by_name_nodev(node, "orientation-gpios", 0,
+                     &desc, GPIOD_IS_IN);
+    if (ret)
+        return false;

So yes it will work with single-usb platforms, but will severely break
the other platforms with multiple controllers (X1, ...).

The real way to fix this is by following the graph to the pmic-glink,
not the simplest but not the hardest, and there's all the required functions
to do that in dm/ofnode_graph.h

The path is:
qmp-combo/port0 -> redriver/port@1 -> redriver/port@0 -> connector@0/port@0

get the connector reg and use this as index of the orientation-gpios.

As a simpler alternative, you could try to get the orientation using the
PORTSELECT_RAW field from the TYPEC_STATUS register, or enable the Hardware
PORTSELECT by setting SW_PORTSELECT_MUX to 0 and enabling HW_PORTSELECT_SEL.

We don't use those in Linux since we need the orientation info across Linux
subsystems (UCSI, PHY, DP, USB, ...) but from Uboot we can enable the HW
select or get the value from the TYPEC_STATUS.

Neil


Neil

+
+    val = dm_gpio_get_value(&desc);
+    dm_gpio_free(desc.dev, &desc);
+
+    return val > 0;
+}
+
  static int qmp_combo_com_init(struct qmp_combo *qmp)
  {
      void __iomem *com = qmp->com;
@@ -333,6 +357,8 @@ static int qmp_combo_com_init(struct qmp_combo *qmp)
               SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET);
      val = SW_PORTSELECT_MUX;
+    if (qmp_combo_read_orientation())
+        val |= SW_PORTSELECT_VAL;
      writel(val, com + QPHY_V3_DP_COM_TYPEC_CTRL);
      writel(USB3_MODE | DP_MODE, com + QPHY_V3_DP_COM_PHY_MODE_CTRL);

---
base-commit: fed92546960a92177d67c0b8d7b22385f50fed29
change-id: 20261013-ss-orientation-d85a156e806a

Best regards,


Reply via email to