Re: [PATCH 1/2] clk: mediatek: mt7988: keep combo-lane U3 PHY ref clock enabled
From: AngeloGioacchino Del Regno
Date: Mon Sep 21 2026 - 06:25:59 EST
On 9/19/26 13:47, Frank Wunderlich wrote:
From: Mihai Ordean <research@xxxxxxxxxxxxxxx>
CLK_INFRA_USB_PIPE is the reference clock of xphyu3port0, the U3/PCIe
combo serdes. On MT7988 that lane is shared between ssusb0's SuperSpeed
side and pcie2, but only the consumer that claims the PHY holds the gate.
On the BPI-R4 Pro, ssusb0 is configured USB2-only (u3p-dis-msk=1) and
pcie2 claims the lane for the CN13/CN15 M.2 slot, so pcie2 is the sole
holder. u3p-dis-msk does not remove ssusb0's SuperSpeed root hub: that is
decided by xhci_has_one_roothub(), which keys off usb3_rhub.num_ports
from the xHCI capability registers, so bus 2 is registered and live
regardless. When the M.2 slot is empty, pcie2 fails link training (-110)
and its error path calls phy_power_off()/phy_exit(), which gates this
clock - and sspxtp_sel with it, as nothing else consumes it. The still
registered SuperSpeed root hub is then left polling a serdes whose PHY
reference clock has just stopped,
I'm not sure why said clock cannot be assigned to the USB controller as well
as the PCIe PHY to keep the refcount high, avoiding to gate it?
Cheers,
Angelo
and asserts the shared SSUSB interrupt
outside the xHCI event ring; xhci_irq() reads USBSTS with EINT clear and
returns IRQ_NONE, so the core disables the line ("nobody cared") and the
next USB teardown blocks forever in xhci_disable_slot().
Boot logs show the storm threshold being crossed 86-107 ms after the
pcie2 probe failure, while the earlier combo-mux switch to PCIe mode
(~550 ms before) causes no trouble, pointing at the clock gating rather
than the mux as the trigger.
Mark the gate CLK_IS_CRITICAL so the combo lane keeps its reference clock.
Only port 0's gate is affected; ssusb1 uses CLK_INFRA_USB_PIPE_CK_P1.
Signed-off-by: Mihai Ordean <research@xxxxxxxxxxxxxxx>
Signed-off-by: Frank Wunderlich <frank-w@xxxxxxxxxxxxxxx>
---
drivers/clk/mediatek/clk-mt7988-infracfg.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/mediatek/clk-mt7988-infracfg.c b/drivers/clk/mediatek/clk-mt7988-infracfg.c
index 13ffa9d88e24..a8cbcb64d90f 100644
--- a/drivers/clk/mediatek/clk-mt7988-infracfg.c
+++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c
@@ -225,7 +225,17 @@ static const struct mtk_gate infra_clks[] = {
CLK_IS_CRITICAL),
GATE_INFRA3_FLAGS(CLK_INFRA_USB_FRMCNT_CK_P1, "infra_usb_frmcnt_ck_p1", "usb_frmcnt_p1_sel",
9, CLK_IS_CRITICAL),
- GATE_INFRA3(CLK_INFRA_USB_PIPE, "infra_usb_pipe", "sspxtp_sel", 10),
+ /*
+ * Reference clock of the U3/PCIe combo serdes (xphyu3port0). The lane
+ * is shared between ssusb0 and pcie2, but only the PHY consumer that
+ * claims it holds this gate. On boards where pcie2 owns the lane, a
+ * failed pcie2 probe (e.g. empty M.2 slot) calls phy_exit() and gates
+ * this clock while ssusb0 still has a live SuperSpeed root hub on the
+ * same PHY, which wedges the shared SSUSB interrupt. CCF cannot model
+ * the cross-IP sharing, so keep the gate on.
+ */
+ GATE_INFRA3_FLAGS(CLK_INFRA_USB_PIPE, "infra_usb_pipe", "sspxtp_sel", 10,
+ CLK_IS_CRITICAL),
GATE_INFRA3(CLK_INFRA_USB_PIPE_CK_P1, "infra_usb_pipe_ck_p1", "usb_phy_sel", 11),
GATE_INFRA3(CLK_INFRA_USB_UTMI, "infra_usb_utmi", "top_xtal", 12),
GATE_INFRA3(CLK_INFRA_USB_UTMI_CK_P1, "infra_usb_utmi_ck_p1", "top_xtal", 13),