Skip to content

usb: typec: tipd: Restore J716c dock startup - #1272

Closed
erikwb wants to merge 264 commits into
ewb/j716c-public-usb4-thunderboltfrom
ewb/j716c-public-usb4-typec
Closed

erikwb wants to merge 264 commits into
ewb/j716c-public-usb4-thunderboltfrom
ewb/j716c-public-usb4-typec

Conversation

@erikwb

@erikwb erikwb commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Superseded by #1323, which carries the inherited-connection reset, startup recovery and teardown fixes with the original authorship and trailers. The remaining USB4/display PRs now name #1323 as their prerequisite rather than stacking on this PR. Closing this duplicate submission; the branch remains available.

Created with GPT-6 Astra in Codex.

funkzy and others added 30 commits November 4, 2026 20:33
apple,port-index has an enum but no type, so dtschema cannot decode the
cell and every combo PHY node fails with "b'\x00\x00\x00\x02' is not one
of [1, 2]" and a core-schema type error, whatever port it names. Give it
the uint32 type.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
Add apple,t6050-dwc3, the T6050 (J775D) DWC3 on bare metal. It uses the
shared tunable table, extended with the tables Diljit Singh's T6050 USB
support applies, in the same order: the T6040 tables plus CIO (the Apple
region from 0xcd20, after the fixed CIO values), bulk fabric and AUSBC
debug (the optional drd-bulk and drd-ausbc regions).

It is host-only, like T6040. The USB2 port reset follows the root hub's
start (a no-op without a PHY reset op), and a USB3 PHY failure is fatal,
as on T8132.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
The PIPE lock that starts the USB3 handoff is acknowledged only while
the combo PHY's dummy PIPE PHY is enabled (pipehandler
NONSELECTED_OVERRIDE bit 15), as on the earlier ATC PHYs (T8122,
T8140), and the bit resets to clear with the controller's domain.
Without it the lock timed out, the PHY faulted and rear port 2 had no
USB at all.

Enable it before the controller leaves reset. Each PIPE-switch step
returns its own code, and every fault of the PHY is logged with its
reason (the pipehandler registers for PIPE faults); dwc3-apple logs a
fatal USB3 PHY failure.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
A USB3 PIPE switch can fail before the mux moves, with the PIPE still on
its dummy producer. The PHY then faulted and lost USB2 with it.

Leave the port on USB2 in that case, as four DisplayPort lanes do.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
Add the T6050 SMC consumer profile, described pcIO GPIO outputs, power-supply identity sizing, and charging policy. Preserve the newer shared SRAM accessor and metadata serialization.

Source snapshot: t6050-gpu ee68abb105200e99636a5edfc647a5cfc1d89954
Integration base: 9cbdd07

Signed-off-by: Dj <hey@djdev.me>
Signed-off-by: Erik Bourget <erik@ebourget.net>
The combo PHY refused any apple,port-index other than 1 or 2, the two ports a
guest description produced. Nothing else in the driver reads the index: the
firmware buffer, banks and sequences are port-agnostic. Validate it against
the board's port set instead: 1 to 5, with 0 (the port that carries the boot
loader's debug link) still excluded, here and in the binding.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
The T6050 profile (Aurora's t6050/smc) registers input, power and hwmon
only, so a T6050 kernel that owns the machine (J775D on bare metal) had
no SMC restart or power-off and no RTC: poweroff halted Linux and left
the machine on.

Add macsmc-reboot and macsmc-rtc to the T6050 profile as cells that are
registered only where the device tree has their child node, the rule
the pcIO outputs and the second GPIO bank already follow; those two
blocks become one table and one helper. A T6050 device tree without
reboot or rtc children registers exactly what it did,
and other SMCs are unchanged (same cells in the same order; the
registration failure messages now name the cell).

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
apple,soc-die-keys adds a "SoC die <key>" channel per listed key for the
macsmc_soc_die zone, and apple,discover-temperatures refuses to run once
any temperature channel exists, so a machine that discovers its
temperatures (T8142, J775D) could not have the zone: the probe failed
with -EINVAL.

With discovery, a listed key now adds no channel; the channel discovery
creates for it (labelled with the key) is marked for the zone instead.
Machines that set only one of the two properties are unchanged.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
Expose the PMU's power-on policy byte as the ac_power_mode attribute
Asahi's downstream driver had, with a third mode. The byte has two
policy bits: bit 0 keeps the machine off when power returns after a loss,
bit 5 keeps it off when power is connected. Asahi's driver wrote the whole
byte (0x02 restore, 0x03 off), which clears bit 5: on machines whose PMU
powers on at connect that write means "always", the opposite of "off".
Change only the two bits and leave the rest to the PMU:

  off      bit 0 and bit 5 set
  restore  bit 5 set, bit 0 clear
  always   bit 5 clear (bit 0 set)

The pm_setting cell is optional; the attribute appears only with it.
The binding takes it as a fifth cell, as the t600x/t602x device trees
already list it.

Based on Asahi's ac_power_mode (marcan).

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
signal.c calls apple_afp_enabled() while sizing the signal frame, behind
a runtime check, but the function is only declared with
CONFIG_ARM64_APPLE_X86_FP, so a kernel built without it fails to
compile. Report AFP as disabled when it is not built.

Developed with Claude Code.

Signed-off-by: Erik Bourget <erik@ebourget.net>
Without CONFIG_OF_DYNAMIC, of_node_put() is a static inline no-op, so
bindgen emits no binding for it and Rust users such as the AOP driver
fail to build. Wrap it in a helper in that case.

Developed with Claude Code.

Signed-off-by: Erik Bourget <erik@ebourget.net>
Add the T6050 SoC in its two-die M5 Ultra form, and the Mac Studio board
that uses it: the device tree for Linux running on the hardware, as the
boot loader hands it over (the loader fills the tunables and calibration
the nodes name).

Every T6050 is made of the same die, so the SoC description is split as
for the M3 Max and Ultra (t6031-base, -die0, -dieX):

- t6050-base.dtsi: the nodes common to every size, die 0's bus and the
  CPU node template;
- t6050-die0.dtsi: the blocks used on die 0 only, among them the
  interrupt controller that serves both dies;
- t6050-dieX.dtsi: the per-die template, included once for each die,
  with each die's blocks at the die stride and its interrupts on its
  own die of the AIC;
- t6050-ultra.dtsi: the two dies, their CPUs (five cores in each
  cluster) and the blocks so far described for the two-die part only:
  the video decoders, the memory cache controllers, the display
  subsystem, die 1's ATC0 and its DisplayPort PHY;
- t6050-j775d.dts: the board, its USB-C ports and their PD controllers,
  the HDMI port, PCIe, audio, the boot NOR and the fans.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
[erik: dropped references to private files from a comment]
Signed-off-by: Erik Bourget <erik@ebourget.net>
Build t6050-j775d.dtb, the Mac Studio with the M5 Ultra (J775D, T6050),
with the other Apple device trees.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
T6050's coprocessors (ANS among them) use the ASC v4 mailbox.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
Add the J775D board and its T6050 (M5 Ultra) SoC.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
T6050's AIC3 is the T8122 one with two dies, so it takes the T8122 fallback
and, like T6031's, four interrupt cells (the second is the die).

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
T6050's watchdog is compatible with T8103's.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
Add apple,t6050-dart, the DART of the T6050 (M5 Ultra) PCIe ports and
display co-processors, with the t8110 fallback like the other recent
SoCs.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
T6050's boot NOR sits behind a QSPIMC controller with the same P and C
apertures (C at P + 0x800) as T8140's. Describe it as
"apple,t6050-qspi", "apple,t8140-qspi" so the driver's T8140 policy (data
reads anywhere, programs and erases only inside the nvram partition)
applies without a driver change.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
The PMU's info-pm_setting byte (0x2001, as on T6030) holds the power-on
policy: bit 0 keeps the machine off when power returns after a loss, bit 5
keeps it off when power is connected. Hand it to the SMC reboot node as the
pm_setting cell so macsmc-reboot's ac_power_mode can read and set it.
Written 0x03 ("always") from Linux on the Studio, a wall-power cycle after
a Linux shutdown powered it on by itself.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
The T6050 (M5 Ultra) SART keeps SARTv3's entries but moves the address
and size arrays, so it is not compatible with apple,t6000-sart and has
no fallback.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
The SART that filters the T6050 (M5 Ultra) ANS's DMA keeps SARTv3's
entry format (config, page address and size, 4 KiB units) but moves the
address and size arrays from 0x40/0x80 to 0x60/0xc0. Read on J775D before
Linux started: the config words at 0x00+4i and seven live entries whose
addresses at 0x60+4i and sizes at 0xc0+4i name ANS's MMIO and two DRAM
ranges.

Let the v3 ops carry the array offsets, so v3 and v4 share one
implementation, and match apple,t6050-sart with the v4 offsets. There is
no v3 fallback compatible: a v3 driver would read the wrong registers.
Log the number of entries the boot loader left (protected) at debug
level.

v2 and v3 SARTs keep their offsets.

Testing: on J775D, every boot since protects the seven entries the boot
loader left, and ANS's NVMe runs behind it (Linux boots from and writes
to its NVMe partition).

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
Add apple,t6050-nvme-ans2: T6040's three-region layout (nvme, ans,
nvmmu) and power domains. The T6050 ANS is adopted running and never
reset through PMGR, so it requires no reset.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
Add apple,t6050-nvme-ans2 for the M5 Ultra's ANS when Linux runs on the
hardware. Its layout is T6040's, as the ADT
and the registers read before Linux started show: a 64 KiB "nvme" block,
a separate NVMMU and linear submission queues. The controller reports
254 queue entries (CAP.MQES 0xfd); the profile uses T6040's 64. FUA
writes are not shown durable here, so the profile flushes instead
(NVME_QUIRK_BROKEN_FUA).

The boot loader leaves ANS's firmware running and the controller shut
down (CC.EN 0, CSTS.RDY 0). The driver adopts that session, and, like
every post-M4 ANS without cold_reset, never resets it through PMGR, so
the profile sets reset_optional, a hardware-profile flag that takes the
controller reset as optional, and the binding requires no reset for it.
Every other profile still requires its reset.

Testing: on J775D, every boot since 2026-10-30 adopts ANS's running
firmware and enables the controller with this profile; Linux runs from
its NVMe root partition (ext4) through daily builds and reboots without
an NVMe error.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
The boot loader leaves the T6050 ANS's firmware running with the
controller disabled and, as on T8132 and T8140, adds apple,rtkit-handoff
to the node so the kernel adopts that RTKit session instead of starting
the co-processor again. The T6050 profile relies on that adoption. Allow
the property on apple,t6050-nvme-ans2.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
…oader

Add apple,t6050-pcie, a T6050 (M5 Ultra) PCIe host whose root ports the
boot loader powered, trained and left running. Each such port is marked
apple,link-trained-by-bootloader and named by its port<n>, phy<n> and
intr2axi<n> register ranges and its port<n> interrupt; the host's local
MSI map starts at apple,msi-vector-base. The OS adopts the trained state
and never resets, retrains or changes the port's power: reset-gpios,
pwren-gpios and power-domains are not allowed on it.

Also name nonposted-mmio, which these hosts take.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
The two non-T6050 defaults added for the T6050 hosts (the fixed reg-names
list with at most 10 regions, and reset-gpios on every root port) were
written as an if with only an else. dtschema's meta-schema requires a
then wherever there is an if, so dt_binding_check reports "'then' is a
dependency of 'if'" for both. State the same conditions as "not T6050,
then".

No change in what the binding accepts.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
On the M5 Ultra (T6050, J775D) running Linux on the hardware, the boot
loader brings up the internal PCIe host's ports itself: it powers the
shared PHY, trains each port's link and leaves it up, with the endpoint
idle. Port 2 carries the onboard RTL8127 Ethernet controller and port 3
the ASM3142 xHCI behind the rear USB-A ports. Repeating the reset and
training sequence from Linux is not needed and not known to be safe on
this SoC.

Add apple,t6050-pcie, a host whose root ports marked
apple,link-trained-by-bootloader are adopted as they are: no reset, no
tunable replay, no clock or power change and no retraining. Every
resource comes from the DT by the port's index (port<n>, phy<n>,
intr2axi<n>, interrupt port<n>, the iommu-map entry for the endpoint's
RID). Before the first PCIe register write the driver checks that the
link is up and not retraining at Gen3 x1, that the boot loader numbered
the root port's buses (primary 0, one secondary), that the endpoint on
it is device 0 function 0 with DMA and MSI off and a well-formed
capability list, and that the port's RID table holds no valid entry. A
port that fails a check is left alone and the others are still adopted.
Then the endpoint's RID is routed to its SID, the host's MSI map is set
up from apple,msi-vector-base, and only the adopted root ports and the
endpoint behind each are enumerated. The links cannot be recovered by a
user reset or removal, since the boot loader owns them.

No other SoC sets adopt_link.

Testing: on J775D, every boot adopts port 2 (RTL8127, DHCP and SSH over
it on every boot) and port 3 (ASM3142, a USB keyboard and mouse driving
the desktop session).

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Erik Bourget <erik@ebourget.net>
A driver's work item that rescans or resets part of a bus takes the
rescan/remove lock. When the device is being removed, the remover holds
that lock while it cancels the work, so a worker that blocks on the lock
deadlocks against its own cancellation.

Add pci_trylock_rescan_remove(), which takes the rescan/remove lock only
if it is free. A worker that cannot get it returns and retries later,
and the remover's cancellation completes.

Signed-off-by: Dj <hey@djdev.me>
Signed-off-by: Erik Bourget <erik@ebourget.net>
…uences

An adopted T6050 port is left as the boot loader trained it, but an
endpoint that has to come back on a retrained link (the N1 on port 0,
after its ROM boot) needs the host to take the port down and bring it
up again. Add the sequences for that, on the port's own register blocks
(port<n>, phy<n> and intr2axi<n>) and the root port's config space:

- Disable: wait for the link to leave L1 and go idle, assert the
  port's PERST# through its handshake, then stop the lane clocks and
  the port's application clock.
- Enable: the port reset table, which also clears the RID2SID and MSI
  map tables, the port's tunables, then the application clock and the
  PERST# release handshake, until the port is ready and its link idle.
- Configure: with the root complex's read-only registers opened, its
  tunables and the per-rate shadow tunables, then a Gen3 x1 link
  (target speed, link width and capability) and a directed speed
  change; Intr2AXI enabled.
- Train: the lane's reference clocks, the endpoint's PERST# released
  through its pad, the LTSSM started, then the 100 ms wait after link
  up.

The tunables are the lists the boot loader copies onto the root port
node, groups of (offset, 4, mask, value); a list it did not copy is
skipped. The root-port reset that runs the sequences follows; until
then they are marked __maybe_unused.

Developed with Claude Code.

Co-developed-by: Dj <hey@djdev.me>
Signed-off-by: Dj <hey@djdev.me>
Signed-off-by: Erik Bourget <erik@ebourget.net>
erikwb and others added 10 commits November 8, 2026 21:01
Distinguish the coprocessor-driven T6050 GPU from its raw disabled
inventory node with the G17 family fallback. Describe both mailboxes,
the six reserved memory regions and loader-filled power data.

Accept the existing mini-LED panel compatible and the named boot
framebuffer reservation supplied to the display subsystem.

Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
Include integration/aurora at 8c4b5c5, including the merged display
audio updates, before testing the complete J716c desktop and USB4 stack.

Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
Supply the one-die GPU resource layout, GFX/GFX1 mailboxes, six memory
reservations and fourteen operating points with four cluster voltage
lanes. Put its existing PMGR resources under the GPU aperture and replace
the raw disabled GPU inventory nodes. Keep the J716c inventory on its
existing SoC bus so loader path lookups are unambiguous.

Connect the internal DCP to its bandwidth scratch, clocks and mini-LED
panel, with display scanout through disp0 SID 0. Reuse the existing DCP,
DART, mailbox and PMC definitions.

The GPU, its power states and mailboxes, memory reservations and internal
display remain disabled until the loader validates and fills the handoff.

Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
Describe the ASCWrap v6 compatible for the physical GPU aperture shared
by J775D and J716c, distinct from the existing T6050 alias profiles.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
The existing T6050 profiles validate alias addresses and reject the physical
GFX/GFX1 resources used on J716c. Add the shared J775D/J716c profile for
0x2302600000 and 0x2302e00000, including their vector-base registers.
Reuse the ASCWrap v6 transport and retain all existing address profiles.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
Developed with Claude Code.

Signed-off-by: Erik Bourget <erik@ebourget.net>
Retain the PCIe DART inventory guards where native tunnel DARTs already provide the resources.

Developed with Claude Code.

Signed-off-by: Erik Bourget <erik@ebourget.net>
Provide the four USB4 DisplayPort tunnel pixel-clock gates and clock-source
switches, unwind failed starts, and park idle clocks in USB4 mode. Accept
port index zero when its controller has handed the port to the host.

Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
T6050 can report a busy crossbar connection after selecting a valid
output. Log that status while retaining the selected route, so an active
USB4 DisplayPort tunnel can complete its display setup.

Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
Route four DP IN adapters through the T6050 display fabric, assign each
dock stream its own processor, and manage the PHY clocks and crossbar
link around activation. Handle firmware-27 tunnel attributes, resource
calls, drive settings, HPD events and paired high-bandwidth modes.

Stop a firmware-27 display pair before the single-pipe profile guard so
DPMS and cable removal release its route. Bind deferred HPD events to
their attachment and drain delivery before route retirement or reassignment.
Describe T6050 four-adapter tunnel routing in the display binding.

Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
@erikwb
erikwb force-pushed the ewb/j716c-public-usb4-thunderbolt branch from 3a3515a to 597d90d Compare November 9, 2026 02:48
@erikwb
erikwb force-pushed the ewb/j716c-public-usb4-typec branch from c335baf to 0c929dd Compare November 9, 2026 02:48
@erikwb erikwb changed the title usb: typec: tipd: Restore J716c dock USB across boot usb: typec: tipd: Restore J716c dock startup Nov 9, 2026
@erikwb
erikwb marked this pull request as ready for review November 9, 2026 03:59
T6050 assigns each display tunnel to a processor before userspace can
modeset it. Narrowing possible_crtcs to that processor after registration
changes advertised encoder capabilities and breaks clients that cache
them, especially when reconnecting a dock changes tunnel allocation.

Expose one connector for each eligible physical port and display processor
pair, with a single fixed CRTC mask. Publish each attachment on the
connector for its assigned processor, independently of the DP IN ordinal.
Keep the tunnel slot for ownership tracking, adopt already active routes
during DRM initialization, and clear route references during DRM unbind.
Leave the existing topology on earlier platforms unchanged.

Exercise connector identity across all ports and DP IN ordinals, reversed
boot ownership, retirement and unbind with KUnit coverage.

Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
Map all four T6050 DP IN adapters, forward their HPD interrupts to the
display driver, and apply the host link, TMU and DP OUT policies needed
for USB4 display tunneling. Preserve the existing M4 handshake policy.

Wait 100 ms for a T6050 request generation to settle before handing it to
DCP. Retired transient requests must not occupy the second display
processor during dock discovery. Block delayed IRQ handlers and polling
from reading registers after powered retirement.

Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
Reinitialize an inherited J716c boot-port USB2 connection before its
first connect notification, after suppliers and the Type-C port exist.
Limit the operation to the board property and normal host operation;
exclude the debug bridge modes. Allow SN201202x up to five seconds to
wake so a connected dock can restore its USB hub after boot.

Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
An attached J716c dock can leave DISC running beyond the default one-second command timeout. Probe then attempts LOCK while DISC still owns the command register, receives EBUSY, and abandons the port even though a later reprobe works.

Allow five seconds for DISC to acknowledge, matching the surrounding startup operations. Keep the automatic CC restore delay and the post-command application-mode check unchanged.

Developed with Claude Code.

Signed-off-by: Erik Bourget <erik@ebourget.net>
An empty SN201202x port can take 1.6 seconds to acknowledge LDCM at startup. Allow five seconds so a command still running is not treated as a failed mitigation change.

Removing mitigation can start a new measurement after a valid dry snapshot. Preserve that result while the new measurement is in progress, as the existing entry path does for a published result. Re-enabling mitigation immediately can hold the detector in the measuring state and permanently suppress a later dock attachment.

Keep failures and liquid results mitigated. Exercise the dry-to-measuring transition from every previous state and the failed re-read path in KUnit.

Developed with Claude Code.

Signed-off-by: Erik Bourget <erik@ebourget.net>
Reset recovery can invalidate the detector after tipd_remove cancels its work but before cd321x_remove drains resume work. Disable delayed work permanently at removal so this late producer cannot restart it after driver resources are released.

Exercise the production stop and invalidate callbacks in KUnit. The regression test runs the callback after cancellation on the old implementation and passes when work is disabled.

Developed with Claude Code.

Signed-off-by: Erik Bourget <erik@ebourget.net>
@erikwb
erikwb force-pushed the ewb/j716c-public-usb4-typec branch from 0f76176 to f2010ce Compare November 9, 2026 04:53
@erikwb
erikwb force-pushed the ewb/j716c-public-usb4-thunderbolt branch from 597d90d to 0881b67 Compare November 9, 2026 04:53

@DjDeveloperr DjDeveloperr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes a visible problem on the M5 Pro. Same-day A/B on the same rig. The baseline kernel's tipd code is identical to #1271's head, and so are its SPMI and Type-C core. Its log on both PD controllers:

sn201202x 1-0a: connector contaminant state unavailable: -110
sn201202x 1-0a: liquid-detection status unavailable: -16   (x2)
sn201202x 2-0c: connector contaminant state unavailable: -110
sn201202x 2-0c: liquid-detection status unavailable: -16   (x2)

With this PR there are none of these. Both ports register, and the debug bridge (ATC0, DbMa) keeps working. sn201202x-pm passes 36/36 in KUnit, including sn201202x_dbma_held_test with DEBUG_FS.

Setup. 14-inch M5 Pro (J714sAP, T6050, macOS 27.0 firmware). RAM boot through aura of #1273's head (the whole stack on ewb/j716c-usb4-public-base), plus our M5 Pro GPU commit, plus #1308. #1308 is needed because the base doesn't build t6050-j714s.dtb; see there. The kit DT is the J714s one compiled on this tree. Modules: nvme, display, smc, input, gpu and usb4 (mux-apple-display-crossbar, phy-apple-dptx, atc-t6050-dp, dwc3-apple, sn201202x, thunderbolt, thunderbolt_apple). No display or dock was attached. ATC0 carries the debug link.

Whole-stack result on J714s.

  • Boots to a shell with no oops, WARN or BUG.
  • 2ab000000.phy and 383000000.phy -> apple-t6050-dp-phy (phys .0-.5); 2aa280000.usb and 382280000.usb -> dwc3-apple. typec port0 and port1 register (device/sink, no partner). The debug port is left alone and the KIS link stayed up throughout.
  • Internal panel: display-subsystem -> apple-drm, card1-eDP-1 connected and enabled at 3024x1890. GPU: card0 and renderD128.
  • ATC2 router mailbox 381108000 binds and thunderbolt_apple loads. 381ac0000.acio stays deferred because J714s has no board ports/DROM yet.

KUnit on the same tree (ARM64 QEMU, panic_on_warn=1, PROVE_LOCKING, DEBUG_OBJECTS_WORK): 356 tests, 354 passed, 2 skipped by design.

@erikwb
erikwb force-pushed the ewb/j716c-public-usb4-thunderbolt branch from 0881b67 to 9eb9bc2 Compare November 9, 2026 14:40
@erikwb erikwb closed this Nov 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants