Skip to content

lemp12: USB-C port never exceeds USB 2.0 speeds, USB-C direct to a display doesnt work #675

Description

@mattwollf
  • Model: lemp12
  • BIOS version: 2025-07-24_c242738
  • EC version: 2025-07-24_c242738
  • OS: Gentoo Linux
  • Kernel: 6.18.42

Generated with LLM assistance but read by a human

The USB-C port never operates above USB 2.0 speeds, and DisplayPort
alt-mode never engages. USB-C power delivery works normally.

The cause looks like a devicetree omission rather than anything in the silicon: no
rpl variant enables tcss_usb3_port1, so the FSP-S UPD UsbTcPortEn stays 0 and
FSP-S never brings the Type-C port up. All 7 adl boards enable it; 0 of 12 rpl
boards do.

See also #472 and #497 ?

Steps to reproduce

  1. Plug a USB 3.x device in directly or through a USB-C hub.
  2. Observe at 480 Mbps; no SuperSpeed companion device appears.
  3. Plug in a DisplayPort sink.
  4. Observe no display and no kernel events.

Expected behavior

USB 3.0 devices operate at USB 3 speeds

Actual behavior

A USB-C capable display plugged directly into the port stays black. ethernet via USB-C dock and flash drives never break USB 2.0 speed

Same drive, four placements — Kingston HyperX Fury 3.0 (0951:16a5):

Placement Device Root hub Speed
Laptop Type-A 4-2 bus 4, PCH SuperSpeed 5000 Mbps
USB-C dock A (VIA Labs 2109:2822) 3-3.2 bus 3, PCH USB2 480 Mbps
USB-C dock B, "USB 3.1" port (Genesys 05e3:0610) 3-3.1 bus 3, PCH USB2 480 Mbps
On J_TYPEC1 with no hub in the path 3-3 bus 3, PCH USB2 480 Mbps

Docks A and B are the same product but different silicon — VIA Labs vs Genesys Logic
hub, ASIX AX88179A vs AX88179B ethernet — so this is not one dock's quirk. Neither
dock's SuperSpeed hub face ever appears; a USB 3 hub enumerates as two logical devices,
and the SuperSpeed one cannot exist while the host never brings the lanes up.

usb 3-3: new high-speed USB device number 14 using xhci_hcd
usb 3-3: Product: HyperX Fury 3.0
/sys/bus/usb/devices/3-3/speed = 480

lsusb -t at that moment — note both SuperSpeed root hubs are empty while the drive
sits on the 480M root:

Bus 002.Port 001: Dev 001, Class=root_hub, xhci_hcd/1p, 20000M/x2    <- TCSS root hub, EMPTY
Bus 003.Port 001: Dev 001, Class=root_hub, xhci_hcd/12p, 480M
    |__ Port 003: Dev 014, Class=Mass Storage, usb-storage, 480M     <- the drive
Bus 004.Port 001: Dev 001, Class=root_hub, xhci_hcd/4p, 10000M       <- PCH SS, EMPTY

So the laptop's PCH SuperSpeed stack and the drive are both fine, and the hub is not
involved — the fault is isolated to the TCSS Type-C path.

Additional info

Root cause

soc/intel/alderlake/fsp_params.c, fill_fsps_tcss_params():

s_cfg->UsbTcPortEn = 0;
for (int i = 0; i < MAX_TYPE_C_PORTS; i++) {
    if (is_dev_enabled(tcss_port_arr[i]))   // DEV_PTR(tcss_usb3_portN)
        s_cfg->UsbTcPortEn |= BIT(i);
}

UsbTcPortEn is derived entirely from whether the devicetree device
tcss_usb3_port1 is enabled, and appears nowhere else in the file.

soc/intel/alderlake/chipset.cb declares tcss_root_hub off and
tcss_usb3_port1 off. mainboard/system76/rpl/devicetree.cb has no TCSS section.
lemp12's overridetree enables tcss_xhci, tcss_ports[0] and tcss_dma0, but never
tcss_usb3_port1 — same on branches system76, system76-25.03, system76-26.03,
tcss-det and main.

So the bit stays clear, and the SuperSpeed lanes stay off while the USB 2.0 pair —
which routes to the PCH, not the TCSS — keeps working.

Port identity, for anyone reproducing this

A hub on the Type-C port appears on the PCH xHCI, because
usb2_ports[2] = USB2_PORT_TYPE_C # J_TYPEC1. Only the SuperSpeed lanes route via
tcss_usb3_port1. PCH SS03 showing "not attached" is by design —
usb3_ports[2] is deliberately unregistered — and is not the symptom. SS01 on the
TCSS root hub is the port that matters.

Scope — all rpl boards

Boards enabling tcss_usb3_port1:

Platform Boards
tgl-u darp7, galp5, lemp10
adl darp8, galp6, gaze17-3050, gaze17-3060-b, lemp11, oryp10, oryp9
rpl none of the 12
mtl darp10, darp11, lemp13
meer9 meer9

rpl is the only generation missing it, and the same split holds for
pmc_gpe0_dw0/1/2. The rpl/ directory looks to have been created fresh rather
than carried over from adl/.

Independently, starlabs/starbook/variants/rpl ships these blocks on a board that
selects the identical SoC and PCH pairSOC_INTEL_RAPTORLAKE +
SOC_INTEL_ALDERLAKE_PCH_P, the same as lemp12, plus the same
SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES — so it compiles the same
soc/intel/alderlake code and passes the same UsbTcPortEn UPD to the same FSP. Its
devicetree includes the same
dfp[0].power_gpio = ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E4); its Type-C is on
usb2_port1 rather than usb2_port3. It also selects DRIVERS_INTEL_USB4_RETIMER,
one of the two Kconfig selects missing from system76/rpl.

Probably the same as #472 and #497 — and those two boards test the theory

If the cause is what I think, then on any rpl board a Type-C connector should work
iff its SuperSpeed pairs are assigned to a PCH usb3_ports[] entry, and fail if
they depend on TCSS. Both reported boards have two Type-C connectors, so each is a
control against itself:

Board Connector (devicetree comment) PCH usb3_ports Predicted Reported
oryp11 (#472) usb2_ports[1] "J_TYPEC1: USB-C Thunderbolt (Right)" none → TCSS fails "USB-C port on right side … detects USB 3.2 Gen 2x1 device as USB 2.0"
oryp11 usb2_ports[2] "J_TYPEC2: USB-C 3.2 Gen 2 (Back)" [2], [3] works not reported broken
darp9 (#497) usb2_ports[5] "J_TYPEC2 (Thunderbolt)" none → TCSS fails "usb3 devices not detected on thunderbolt port"
darp9 usb2_ports[2] "J_TYPEC1 (USB-C)" [1], [2] works "the adjacent port functions normally"
lemp12 (this report) usb2_ports[2] "J_TYPEC1", the only Type-C none → TCSS fails 480 Mbps, measured above

The split falls exactly along "does this connector depend on TCSS", within the same
machine. On oryp11 the reporter identifies the bad port by physical side, and right
is precisely the connector the devicetree labels Thunderbolt.

Other details in #497 fit as well:

  • Monitors over the dock keep workingrpl does enable tcss_dma0, so the
    Thunderbolt/PCIe tunnel and DP tunnelling are up; only the TCSS USB port is off.
  • The dock authenticates fine — again the TBT link, not the USB3 path.
  • A motherboard replacement changed nothing — expected, if the setting is in
    firmware and identical on every unit.

On #497's needs-repro label: I see it unchanged on the current release
(2025-07-24_c242738), and it's checkable without hardware — no rpl overridetree on
any branch of system76/coreboot enables tcss_usb3_port1.

Prior art

CB:82058"soc/intel/alderlake:
Set UsbTcPortEn based on tcss_port[x]"
— described this exact coupling:

UsbTcPortEn is configured based on pointers to tcss_usb3_port1, which is part of
the ACPI driver. This is illogical, as the port might need to be enabled, and the
ACPI not needed or included.

Verified+1 and Code-Review+1 before being abandoned as "Not needed". Had it landed,
every affected board would work as-is — all four rpl boards with a TCSS-backed
Type-C (darp9, galp7, lemp12, oryp11) already set tcss_ports[0]. The reason they
don't work is precisely the coupling that change called illogical.

Note on the tcss-det branch

These devicetree blocks also look like a prerequisite for that branch to have any
effect on rpl. tcss_get_port_info() builds its port list by walking
PMC → generic 0 → generic <port> and calling intel_pmc_mux_conn_get_ports(),
guarded by CONFIG(DRIVERS_INTEL_PMC). No rpl board has that device path or that
Kconfig, so the list comes back empty and tcss_configure() has nothing to act on,
even with ENABLE_TCSS_{DISPLAY,USB}_DETECTION selected.

Those two Kconfigs also look orthogonal to this bug — they're absent on adl, where
DP-alt works. The lemp11 bring-up commit
(CB:65384) says as much: it lists
"DisplayPort output over USB-C" under Working and "Detection of devices in TBT
slot on boot" under Not working.

Suggested fix

Mirror lemp11's overridetree:

  1. tcss_xhcidrivers/usb/acpitcss_root_hub ontcss_usb3_port1 on
    — this is the part that sets UsbTcPortEn
  2. tcss_dma0chip drivers/intel/usb4/retimer,
    dfp[0].power_gpio = ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E4)
  3. xhci → per-port drivers/usb/acpi descriptors
  4. pmc hiddenchip drivers/intel/pmc_mux + pmc_mux/conn,
    use usb2_port3 as usb2_port, use tcss_usb3_port1 as usb3_port

Plus, in mainboard/system76/rpl/Kconfig — currently missing and required, as adl
already has both:

	select DRIVERS_INTEL_PMC
	select DRIVERS_INTEL_USB4_RETIMER

pmc_mux/Makefile.mk gates mux.c on CONFIG_DRIVERS_INTEL_PMC; without these the
chip entries don't link.

What I have and haven't verified

Verified:

  • Builds and links on c242738, the release this machine runs.
  • The change reaches the image, not just generated source: extracting
    fallback/ramstage from the built ROM and reading the devicetree out of the binary
    shows tcss_usb3_port1 .enabled = 0 in a stock build and 1 in a patched build,
    with all 20 USB devices otherwise identical. Footprint +2189 B ramstage,
    +768 B romstage, identical CBFS file set, FSP and payload untouched.
  • The OS half already works on unpatched firmware — see the SSDT overlay under
    "Ruled out".

Not verified — I have not flashed this. lemp12's SPI flash is a WSON-8
MX25L25673G (U41). It's leadless, so a SOIC-8 clip has nothing to grip, and I have
no external programmer. Without a recovery path a bad flash is unrecoverable on this
machine, so I've deliberately stopped short of testing it. I can't claim the change
fixes the runtime behaviour — only that the mechanism is present and the patch does
what it should up to the point of flashing.

Happy to run any diagnostics you suggest (dmesg, cbmem -1, lsusb -t,
lspci -vvv, acpidump), share the patch, send it to Gerrit, or test a firmware
build if one is provided.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions