USB4/Thunderbolt imported prerequisites - #1
Open
DjDeveloperr wants to merge 33 commits into
Open
DjDeveloperr wants to merge 33 commits into
DjDeveloperr wants to merge 33 commits into
Conversation
The Intel VID status register is actually 9 bytes long and doesn't contain the raw VDOs but only the upper 16bits for device mode and enter mode. Shift those two fields into place and reconstruct the cable discover mode VDO from the data status registers instead. Link: https://www.ti.com/lit/ug/slvubh2b/slvubh2b.pdf Fixes: 0b31c97 ("usb: typec: tipd: Read USB4, Thunderbolt and DisplayPort status for cd321x") Fixes: 82432bb ("usb: typec: tipd: Handle mode transitions for CD321x") Cc: stable@vger.kernel.org Signed-off-by: Sven Peter <sven@kernel.org>
Table F-10 of the USB Type-C Cable and Connector Specification R2.5 on page 412 defines bit 16 of the TBT3 Device Discover Mode VDO as 0 = TBT3 Adapter and 1 = TBT2 Legacy Adapter. Linux has those two swapped since their original introduction in commit ca469c2 ("usb: typec: Add definitions for Thunderbolt 3 Alternate Mode"). ChromiumOS EC's include/usb_pd_tbt.h has them the correct way around and references the USB Type-C ECN "Thunderbolt 3 Compatibility Updates" as fixing an error where they were originally swapped which is presumably where the wrong order originally came from. I've also confirmed the correct mapping with an Apple Thunderbolt 3 to Thunderbolt 2 adapter which does set bit 16 in that VDO. Swap the two values and update all users. Also rename the old defines so that no user accidentally ends up with an inverted value. No functional change. Link: https://usb.org/document-library/usb-type-cr-cable-and-connector-specification-release-25 Link: https://chromium.googlesource.com/chromiumos/platform/ec/+/db93814b6e73c8545d23714fe0674c10814d901a/include/usb_pd_tbt.h#90 Signed-off-by: Sven Peter <sven@kernel.org> --- I ran into this when bringing up thunderbolt for Apple Silicon SoCs and was very confused why the condition for "tbt2 adapter" vs "tbt3 adapter" seemed to be backwards. I think the qcom pmic_glink_altmode.c actually has a bug there that was hidden and/or caused by the wrong values: It used to always set TBT_ADAPTER_TBT3 which sounds plausible but actually claims to be a legacy TBT2 adapter on the wire. I don't have the hardware or know the intention there though. The other users look correct to me since they just pass the value through.
The CIO (USB4/Thunderbolt) blocks on Apple Silicon SoCs have a reset inside the power manager that has to be deasserted before their co-processor can be booted. On t8103 each port comes with a dedicated register page, represented as a standalone node. On t600x a single register shared by all ports of a die is located in the middle of the PMGR MMIO region instead, represented as a sub-node of the PMGR syscon. Signed-off-by: Sven Peter <sven@kernel.org>
Add a driver for the reset of the CIO (USB4/Thunderbolt) blocks on Apple Silicon SoCs which has to be deasserted before their co-processor can be booted. On t8103 each port comes with a dedicated register page while t600x uses a single register with one request bit per port shared by all ports of a die inside the PMGR MMIO region. Signed-off-by: Sven Peter <sven@kernel.org>
Add the reset controllers used to start the CIO (USB4/Thunderbolt) blocks on t8103 and t600x. On t8103 each port comes with a dedicated register page represented as a standalone node. On t600x a single register shared by all ports of a die is located in the middle of the PMGR MMIO region and represented as a sub-node of its syscon. Signed-off-by: Sven Peter <sven@kernel.org>
The USB4/Thunderbolt host routers on Apple Silicon SoCs require cable and mode details to be provided out-of-band by the Type-C port controller. Add a thunderbolt-switch property next to the existing orientation and mode switches which marks a node as handler of these notifications. Signed-off-by: Sven Peter <sven@kernel.org>
…dler For both Thunderbolt and DisplayPort atcphy_configure_pipehandler is reached with a request to switch to the DUMMY state (i.e. usb2 only). With the current code this breaks USB2 when all four SS lanes are used for DisplayPort AltMode because the -EINVAL is passed all the way back to the phy_set_mode() call which results in tearing down xhci and dwc3 again. Let's actually handle that case correctly and also drop the default from the switch such that we get a compiler warning if another pipehandler state is ever added and forgotten here. Reported-by: Paul Cristian <p4ulcristian@gmail.com> Closes: AsahiLinux#515 Fixes: 8e98ca1 ("phy: apple: Add Apple Type-C PHY") Cc: stable@vger.kernel.org Signed-off-by: Sven Peter <sven@kernel.org>
This sequence is already used in three places and we're about to add a fourth copy so let's factor it out to a helper. No functional change. Signed-off-by: Sven Peter <sven@kernel.org>
USB3 tunneled via USB4 requires dwc3's PIPE interface to be switched to the USB4 NHI which will take care of the tunneling. Add the required bringup sequence such that USB3 tunnels work once the USB4 NHI is upstream. Signed-off-by: Sven Peter <sven@kernel.org>
On Apple Silicon the USB4/Thunderbolt host router can only be brought up after a cable has been plugged in and requires the cable details known only to the Type-C port controller. Add a thunderbolt switch similar to the existing orientation and mode switches which Type-C port drivers can use to forward these details out-of-band. Unlike those switches only a single handler per connection is supported since the cable details always go to exactly one host router. Signed-off-by: Sven Peter <sven@kernel.org>
Look up the thunderbolt switch on Apple platforms and forward cable details whenever a Thunderbolt or USB4 connection comes up or disappears. Signed-off-by: Sven Peter <sven@kernel.org>
The Native Host Interface (NHI) provides the TX and RX rings used by the software connection manager on Apple Silicon SoCs. The NHI is part of the ACIO host router and is exposed to the main SoC bus while the ACIO co-processor is running. T6000 and T6020 use one DART stream for the TX and RX control rings and one shared by all other rings, which are used for XDomain connections. This likely improves the isolation of those host-to-host connections. The M3 generation uses a slightly insane set of 24 IOMMU entries. These are probably one DART stream for each TX and RX ring. Signed-off-by: Sven Peter <sven@kernel.org>
Each Type-C port with USB4/Thunderbolt support on Apple Silicon SoCs comes with a host router called ACIO. It contains a Cortex-M3 co-processor and the hardware blocks implementing the USB4 router. The co-processor exposes the NHI and its DART to the main SoC bus while it is running. ACIO can only be powered on after the Type-C PHY has been switched to USB4/Thunderbolt mode. The Type-C controller provides the cable information required to boot it through the thunderbolt-switch connection. Signed-off-by: Sven Peter <sven@kernel.org>
On Apple Silicon SoCs the DROM is provided by a device tree property. Try reading from that property first. Signed-off-by: Sven Peter <sven@kernel.org>
On Apple Silicon the host router's UID comes from the DROM provided by the device tree and is already known by the time tb_switch_set_uuid() runs. Skip reading it from the config space again in that case. For other USB4 hosts this only drops a duplicate read because tb_drom_host_read() has already filled in the UID from ROUTER_CS_7 before tb_switch_set_uuid() runs. Device routers keep reading it unconditionally. Signed-off-by: Sven Peter <sven@kernel.org>
The Apple NHI has one interrupt per ring and request_ring_irq picks it based on ring->hop which is still -1 at this point for rings allocated with an automatic HopID. Allocate the HopID first and release it again if the interrupt request fails. Signed-off-by: Sven Peter <sven@kernel.org>
The Apple NHI enables and disables ring interrupts differently. Add an optional tb_nhi_ops hook to override ring_interrupt_active which falls back to the standard USB4 method when it is not set. Signed-off-by: Sven Peter <sven@kernel.org>
The ring descriptor and options registers are laid out differently on the Apple NHI. Describe their offsets and strides with a tb_nhi_ring_layout struct that NHI drivers can override. Signed-off-by: Sven Peter <sven@kernel.org>
Masking ring interrupts works differently on the Apple NHI as well. Add an optional tb_nhi_ops hook for it which falls back to the standard USB4 NHI method when it is not set. Signed-off-by: Sven Peter <sven@kernel.org>
Signed-off-by: Sven Peter <sven@kernel.org>
Apple Silicon machines load and update the host router firmware with a separate, proprietary mechanism and have no DMA port. Add a quirk to skip its initialization. Signed-off-by: Sven Peter <sven@kernel.org>
The host routers on Apple Silicon do not implement USB3 bandwidth allocation registers: the CMR bit set in ADP_USB3_CS_2 by usb4_usb3_port_cm_request() is never acknowledged and every USB3 tunnel bringup fails there after the timeout: [ 49.259325] thunderbolt-apple-nhi 501f00000.nhi: 1:16: available bandwidth for new USB3 tunnel 18000/18000 Mb/s [ 49.265869] thunderbolt-apple-nhi 501f00000.nhi: 1:16: maximum required bandwidth for USB3 tunnel 9000 Mb/s [ 49.267894] thunderbolt-apple-nhi 501f00000.nhi: 0:4 <-> 1:16 (USB3): activating [ 49.269410] thunderbolt-apple-nhi 501f00000.nhi: 0:4 <-> 1:16 (USB3): allocating initial bandwidth 9000/9000 Mb/s [ 50.771764] thunderbolt-apple-nhi 501f00000.nhi: 1:16: USB3 tunnel activation failed, aborting Add a quirk to skip bandwidth allocation entirely but keep tracking the initial allocation in software for the consumed bandwidth calculation. Discovered tunnels book 90% of the maximum link rate instead of reading back an allocation that does not exist. This is only done for correctness and mirrors what tb_tunnel_alloc_usb3() does since on Apple Silicon there can never be any pre-existing tunnels. Signed-off-by: Sven Peter <sven@kernel.org>
The driver for the ACIO host router complex on Apple Silicon SoCs can be built as a module and needs tb_probe() and the domain functions to register its NHI with the software connection manager as well as tb_switch_find_vse_cap(), tb_cfg_write() and tb_port_unlock() to configure the cable details for its co-processor and to unlock the lane ports. Export these symbols in the USB4 namespace. Signed-off-by: Sven Peter <sven@kernel.org>
Not all USB4/TB implementations are based on a PCIe-attached controller. In order to make way for these, start off with moving the pci_device reference out of the main tb_nhi structure. Encapsulate the existing struct in a new tb_nhi_pci, that shall also house all properties that relate to the parent bus. Similarly, any other type of controller will be expected to contain tb_nhi as a member. Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Add a new file encapsulating most of the PCI NHI specifics (intentionally leaving some odd cookies behind to make the layering simpler). Most notably, separate out nhi_probe() to make it easier to register other types of NHIs. Also, fold in Intel Icelake (nhi_ops.c) support to contain all PCIe-related bits in pci.c. Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
…ng used Both Woody and Marek reported following crash: BUG: unable to handle page fault for address: fffffffffffffff8 Call Trace: <TASK> device_release+0x43/0x90 kobject_cleanup+0x3c/0x180 icm_probe+0x19c/0x550 [thunderbolt] nhi_probe+0x1a4/0x370 [thunderbolt] local_pci_probe+0x41/0x90 pci_call_probe+0x5b/0x1a0 ... This only triggers on the error path when icm_probe() fails and the domain structure is released, it tries to complete() uninitialized completion. Fix this by initializing the completion earlier. Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> Closes: https://lore.kernel.org/linux-usb/amdezCBiW4fd_DuB@mail-itl/ Reported-by: Woody Suwalski <terraluna977@gmail.com> Tested_by: Woody Suwalski <terraluna977@gmail.com> Closes: https://lore.kernel.org/linux-usb/62caf7f8-b403-d0dd-15bc-b31b56f71c28@gmail.com/ Fixes: f5cc545 ("thunderbolt: Wait for tb_domain_release() to complete when driver is removed") Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Add a driver for the ACIO host complex and USB Native Host Interface found on Apple Silicon SoCs. Signed-off-by: Sven Peter <sven@kernel.org>
Add the ACIO host router, NHI, DART and M3 mailbox nodes for both Type-C ports on t8103 and connect the host routers to the Type-C connectors. Signed-off-by: Sven Peter <sven@kernel.org>
Add the ACIO host router, NHI, DART and mailbox nodes for both Type-C ports on t8112 and connect the host routers to the Type-C connectors. Signed-off-by: Sven Peter <sven@kernel.org>
Add the ACIO host router, NHI, DART and mailbox nodes for the four ATC instances on each t600x and t602x die and connect the host routers to the Type-C connectors on the MacBook Pro (j314/j316 and j414/j416), Mac Studio (j375 and j475), Mac mini (j474) and Mac Pro (j180d) boards. Signed-off-by: Sven Peter <sven@kernel.org>
depends on "iommu: apple-dart: Support specifying the DMA aperture in the DT" series. Signed-off-by: Janne Grunau <j@jannau.net>
…removed We should not call nhi_shutdown() before the domain structure and the control channel rings are completely released. Otherwise we might release resources like the nhi->msix_ida that are still referenced in tb_domain_release(). For this reason wait for the tb_domain_release() to be completed before continuing to nhi_shutdown() and eventually releasing of the rest of the data structures. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
…ling Instead of the core driver programming fixed value for throttling let the service drivers to specify the interval if they need this. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
DjDeveloperr
pushed a commit
that referenced
this pull request
Sep 12, 2026
…mode list (#4) * usb: typec: tipd: fix partner identity use-after-free on CD321x cd321x_update_work() points desc.identity at st.partner_identity, where "st" is a stack local. typec_register_partner() stores that pointer in partner->identity rather than copying the structure, so once the work function returns the partner is left referencing a freed stack page. Any later read of the partner's PD identity then dereferences it. On a MacBook Pro (16-inch, M2 Max) reading /sys/class/typec/port0-partner/type as an unprivileged user is enough: Unable to handle kernel paging request at virtual address ffff800083a87d0c Internal error: Oops: 0000000096000007 [#1] SMP CPU: 10 UID: 1000 PID: 83017 Comm: cat pc : get_pd_product_type+0x54/0xa4 [typec] lr : type_show+0x14/0x3c [typec] get_pd_product_type() NULL-checks partner->identity and then reads id->id_header, which is the faulting access; the pointer is not NULL, just dangling. With VMAP_STACK the dead stack is unmapped, hence the vmalloc-range fault address. The driver already keeps a persistent copy in cd321x->cur_partner_identity, but only assigns it after registration. Fill it in first and register the partner against that instead. The generic tps6598x path already does the equivalent, pointing desc.identity at tps->partner_identity. Fixes: 82432bb ("usb: typec: tipd: Handle mode transitions for CD321x") Signed-off-by: Marcelo <marcelo@omarchy.org> * usb: typec: fix sysfs_emit_at() offset underflow on an empty mode list usb_mode_show() and usb_capability_show() build a space-separated list and then overwrite the trailing space with a newline: sysfs_emit_at(buf, len - 1, "\n"); When the partner or port advertises none of USB2/USB3/USB4 the loop body never runs, len stays 0, and the call is made with at == -1: invalid sysfs_emit_at: buf:00000000ffaad2a3 at:-1 WARNING: fs/sysfs/file.c:785 at sysfs_emit_at+0x54/0xd4, CPU#1: cat/892 sysfs_emit_at() rejects the negative offset, so the attribute also reads back empty rather than as a newline like every other list attribute. Seen on a MacBook Pro (16-inch, M2 Max), where one of the Type-C partners registered by the CD321x has no USB capability bits set, by reading /sys/class/typec/port1-partner/usb_mode Return a bare newline when nothing was written. Fixes: 2140a95 ("usb: typec: Add attribute file showing the USB Modes of the partner") Signed-off-by: Marcelo <marcelo@omarchy.org> --------- Signed-off-by: Marcelo <marcelo@omarchy.org> Co-authored-by: Marcelo <marcelo@omarchy.org>
DjDeveloperr
pushed a commit
that referenced
this pull request
Sep 12, 2026
cd321x_update_work() points desc.identity at st.partner_identity, where "st" is a stack local. typec_register_partner() stores that pointer in partner->identity rather than copying the structure, so once the work function returns the partner is left referencing a freed stack page. Any later read of the partner's PD identity then dereferences it. On a MacBook Pro (16-inch, M2 Max) reading /sys/class/typec/port0-partner/type as an unprivileged user is enough: Unable to handle kernel paging request at virtual address ffff800083a87d0c Internal error: Oops: 0000000096000007 [#1] SMP CPU: 10 UID: 1000 PID: 83017 Comm: cat pc : get_pd_product_type+0x54/0xa4 [typec] lr : type_show+0x14/0x3c [typec] get_pd_product_type() NULL-checks partner->identity and then reads id->id_header, which is the faulting access; the pointer is not NULL, just dangling. With VMAP_STACK the dead stack is unmapped, hence the vmalloc-range fault address. The driver already keeps a persistent copy in cd321x->cur_partner_identity, but only assigns it after registration. Fill it in first and register the partner against that instead. The generic tps6598x path already does the equivalent, pointing desc.identity at tps->partner_identity. Fixes: 82432bb ("usb: typec: tipd: Handle mode transitions for CD321x") Signed-off-by: Marcelo <marcelo@omarchy.org>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Imported prerequisites for the USB4/Thunderbolt work, split out as a base branch so the driver PR on top shows only our own commits.