Skip to content

arm64: dts: apple: t6050: Build the other T6050 Max boards again - #1308

Closed
DjDeveloperr wants to merge 156 commits into
ewb/j716c-public-usb4-dtfrom
djdev/t6050-max-dt-guards
Closed

DjDeveloperr wants to merge 156 commits into
ewb/j716c-public-usb4-dtfrom
djdev/t6050-max-dt-guards

Conversation

@DjDeveloperr

Copy link
Copy Markdown
Contributor

Follow-up to the USB4 display stack (#1268..#1273).

Problem. In ewb/j716c-usb4-public-base, and so at every layer up to #1273's head, nine T6050 DTBs fail to build: j714c, j714s, j716s, j775c, j873s, k114c, k114s, k116c and k116s. Only j716c and j775d build:

ERROR (duplicate_label): /soc/iommu@384000000: Duplicate label 'apciec2_dart' on /soc/iommu@384000000 and /pcie-tunnel-2/iommu@384000000
ERROR (duplicate_label): /soc/spmi@28a1a8000: Duplicate label 'nub_spmi_a1' on /soc/spmi@28a1a8000 and /soc@200000000/spmi@28a1a8000

Cause. The prerequisite merge (70eb31b) brings in t6050-max.dtsi's nub-spmi-a1 and ATC2 PCIe-tunnel DART, which every board including that file gets. But t6050-peripherals.dtsi skips its inventory copies only #ifndef T6050_J716C. integration/aurora and #1276 alone build all of these boards.

Change. t6050-max.dtsi defines T6050_MAX_DTSI, and the two inventory copies are skipped on every board with it. J716c and J775D DTBs are byte-identical before and after; all 11 T6050 DTBs build. The J714sAP ADT has nub-spmi-a1, acio2, apciec2 and dart-apciec2, so the max.dtsi nodes describe real hardware there.

Tested on the 14-inch M5 Pro (J714s). RAM boot of #1273's head plus this commit (and our M5 Pro GPU commit). The kit DT is built on this tree's t6050-j714s.dts. It boots to a shell with:

  • NVMe, the internal panel (eDP-1 3024x1890 through the DCP), GPU (G17S firmware up, renderD128) and SMC working;
  • both combo PHYs and dwc3 controllers bound, and both sn201202x ports registered;
  • no oops or warnings.

With this, J714s also gets max.dtsi's ATC2 router (acio2, its DART, NHI and mailbox) and PCIe tunnel 2 enabled. The mailbox binds; 381ac0000.acio stays in deferred probe because only J716c's board file supplies ports and apple,thunderbolt-drom. dt-validate reports the same 4 lines for those properties on the non-J716c max boards; J716c reports none. A J714s board description of its right port would fill them in. If you'd rather keep the router disabled on boards that don't describe it yet, I can add that here.

🤖 Generated with Claude Code

funkzy and others added 30 commits November 4, 2026 18:55
The M5 Ultra's lpdptx PHY has the T602x bank layout: core plus dptx, with
the PLL command at dptx+0x100c. Its PLL calibration, clocking, rate
programming, AUX impedance calibration and PHY power follow the newer
blocks. The T6020 sequence replays captured register words, and
on this PHY it would program the wrong fields. Give T6050 its own
sequence:

- activate: core power for PLL, AUX and PHY (1 us apart); source select
  from the crossbar's ufp endpoint; the board's PLL calibration
  (DCOCFG split across 0x2240[2:1] and [6:4], DTCVREG, DTCCAL, DCDADJ,
  DLFCFG, optional RODCOROLEAKCOMP) and fixed settings; PLL setup with
  the pixel-clock driver selected by pclkdrv-select and single-ended
  clock out; lanes released; AUX up; impedance calibration, with its
  result copied into 0x4228.
- link reconfiguration, as the DCP brackets it: PHY down, PLL down, lane
  count, rate, then PLL up and PHY up. A per-rate PLL record gives the
  divider and analog fields for 1.62 to 8.1 Gbit/s. PLL commands wait
  100 us, then check the acknowledgment (0x1014[0]) and the lock
  (0x1008[3]) separately.
- deactivate: the reverse.

Every write is a field update.

Signed-off-by: Jeff Queisser <funkzy@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
[erik: dropped the bring-up debugfs interface]
Signed-off-by: Erik Bourget <erik@ebourget.net>
A DockChannel UART drains only while a debug USB host reads it. On a
board that boots unattended with nothing attached, its TX FIFO stays
full. apple,tx-never-wait tells the driver not to wait for room.

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>
…r-wait

The DockChannel console drains only while a debug USB host reads the
channel. With none attached, as on an M5 Ultra Mac Studio (J775D) that
boots unattended, the TX FIFO stays full: the write loops spun up to
10000 reads of TX_FREE per character and every close waited for output
that could not drain, so boot and every console write stalled.

With apple,tx-never-wait, console writes (the driver's and the early
console's) send what TX_FREE says fits and drop the rest, tty output is
sent from the drain timer and dropped after two ticks without room, a
close does not wait, and tx_empty reports empty. Without the property,
every other DockChannel Mac's driver and early console behave as
before.

Testing: J775D boots unattended to its login with nothing reading the
channel (the property set), and with a reader attached the console
carries the whole boot log.

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 co-processor whose crashlog endpoint was never discovered or started,
such as a DCP adopted from the bootloader, requests the crashlog buffer
only when it crashes and writes the log after receiving it. The header
read right after mapping the buffer then fails, and the report was
dropped without a word: on T6050 all three DCPs crashed this way within
8 s, display swaps stopped completing and the compositor froze, with
nothing in the log but "Message to undiscovered endpoint 0x01".

Report such a crash and poll the buffer until the log is written, then
dump it. Only do this when APPLE_RTKIT_EP_CRASHLOG is not in
rtk->endpoints. On a started crashlog endpoint the first message without
a buffer is the normal boot-time buffer request, not a crash; treating it
as one reported a crash for every other co-processor at boot (SMC, NVMe,
PMP and the DP PHY on T6050). That path stays as it was: map the buffer
and return silently.

Nothing else changes: the consumer is not told, as before.

Signed-off-by: Diljit Singh <hey@djdev.me>
Signed-off-by: Erik Bourget <erik@ebourget.net>
In a session that went through the handshake, the crashlog handler
takes the first message on the crashlog endpoint for the buffer request
that answers the endpoint's start: it sets the buffer up and returns.
That has been the rule since RTKit was added. Two later commits made
an inherited session's first message a crash report and kept the rule
for every other session:
commit e52b589 ("soc: apple: rtkit: recognise an initial crash log in adopted sessions")
commit 8a2875a ("soc: apple: rtkit: Only parse an initial crash log in inherited sessions")
The previous commit reads the log of such a report when it is written
after the report, but only in an inherited session, and without telling
the client.

The rule only holds when the endpoint was in the endpoint map and was
started. The external DCP on T6050 (dcpext0 on J775D) does not list the
crashlog endpoint in its map, so the endpoint is never started and the
co-processor is never asked for a buffer. Its firmware still reports a
crash there, naming a buffer of its own, in a session that went through
the handshake as well. That report was set up as a buffer and dropped:
the instance was never marked crashed and the DCP driver's crash
handling never ran. Presents stopped (a swap timed out 36 s later) and
every later modeset failed with -EINVAL until a reboot, with nothing in
the log but "Message to undiscovered endpoint 0x01".

Handle a crashlog message on an undiscovered endpoint as an inherited
session's report is handled, in any session: set up the buffer it names
and dump a valid log if there is one, then mark the instance crashed and
notify the client at once, with or without a readable log. A log that is
not written yet is still read once it is there, after the client has
been told. A buffer that could not be set up and a buffer that holds no
valid log yet are reported separately. Log when the endpoint map lacks
the crashlog endpoint.

A crashlog message still being handled may queue that late read, so
stopping and reinitializing flush the work queue before cancelling it.

A discovered endpoint is unchanged: its first message is still the
buffer request.

This builds on the inherited-session path those commits added, so a
backport needs them.

Testing: on J775D the map line appears for dcpext0 and for no other
co-processor. A crash caused on dcpext0, by an IOMFB call to a method
neither of its firmware tables has, was reported on the crashlog
endpoint 4.7 ms after the call, with the same buffer as a crash seen in
normal use. The instance was marked crashed and the DCP driver's crash
handling ran ("DCP has crashed", the connector then reported
disconnected).

Fixes: 9bd1d9a ("soc: apple: Add RTKit IPC library")
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 external DCP of T6050 (dcpext0 on J775D) writes its crashlog as a
container: a 'CLGH' header and a table of records (ID, offset), where
the record whose ID is the container's current ID holds this crash's
log. That record can be a container itself; on this DCP the buffer holds
one per co-processor and, inside, one per task. The log at the end is an
ordinary 'CLHE' crashlog with the usual sections.

RTKit looked for 'CLHE' at offset 0 only, so such a log was never valid:
the crash was reported "without a readable log" although the log was in
the buffer.

Follow the container to its log, through at most 8 levels and with
offsets that only move forward, both when checking that a log is there
and when dumping it. A log selected through a container is not complete
while bit 8 of its flags is set. Decode the 'Crl4' register frame, at
the offsets of Diljit Singh's T8140 DCP decoder. The DCP logs read on
J775D so far carry no register frame section, neither 'Crg8' nor
'Crl4', so this decoder has not run on a real log, only in the host
test below.

Container logs come from firmware that has just crashed, so the section
walk no longer trusts their sizes. A section header must fit in the log;
a section's size must cover its own 16-byte header and stay inside the
log; and a section is decoded only with at least the footer's 16-byte
header after it, since the decoders read up to the section's size from
16 bytes in. A zero size used to loop forever, and a size past the log,
or a mailbox section under 28 bytes, made the decoders read past the
copy. The version and message strings are bounded by the section's size
instead of a terminating NUL, and a buffer shorter than a log header is
refused.

A buffer that starts with 'CLHE' is checked as before, and a well-formed
log there is decoded exactly as before.

Testing: on J775D, the crash caused on dcpext0 as in the previous commit
now prints "Crashlog container: log 'RTAL' at 0x2000 (depth 2)", the
log's message naming the method the firmware could not find, and the
firmware's mailbox history (128 entries), whose last entry is that call.
The log was complete when the crash was reported. A buffer read back
after an earlier crash on the 27.2 firmware has the same layout (logs
for the root task, RTAL and one untagged task). These runs predate the
section bounds, which change nothing for a well-formed log. A host test,
tools/asahi/rtkit-crashlog-tests.py, builds this file with ASan and
UBSan and feeds it a log with the layout of that crash (two containers,
then RTAL's log with its eleven sections and footer) and malformed logs:
zero, oversized and footer-less sections, a truncated section header,
mailbox sections of 16 to 27 bytes, short, truncated and undecodable
'Crl4' sections, unterminated strings, short buffers and broken
containers. Each is decoded or refused without a loop or a read past the
log, and removing any one bound makes it fail. The buffer read back
after the earlier crash decodes the same with and without the bounds.

The container selection, the record layout, the incomplete flag and
the 'Crl4' offsets follow that decoder. Here they are in RTKit, so that
every client gets them.

Co-developed-by: Diljit Singh <hey@djdev.me>
Signed-off-by: Diljit Singh <hey@djdev.me>
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 (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>
Add the T6050 DisplayPort/USB combo PHY and four-clock display crossbar profile. Carry the current Type-C, USB2, USB3 PIPE sequencing, and teardown behavior from the published T6050 source.

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's USB2 PHY and digital banks are in the USB controller's
power domain. Let a combo PHY name it fourth, as "usb", so the PHY can
hold it on a port with no USB controller bound. The fixed DisplayPort
PHY keeps exactly three domains.

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 combo PHY's USB2 PHY and digital banks are in the USB controller's
power domain. Only a bound USB controller holds that domain, so on a
port with no controller (a DisplayPort-only port, as on J775D with Linux
on the hardware) the first Type-C mode switch wrote an unclocked bank
and took an SError.

A combo PHY node may now name that domain as a fourth power domain,
"usb". When it does, the PHY holds it from combo start to combo stop,
after the common domain on the way up and before it on the way down.
Nodes that name three domains probe and run exactly as before, and the
fixed DisplayPort PHY still takes exactly three.

Testing: on J775D (M5 Ultra), with the fourth domain named on each combo
port, Type-C mode switches and DisplayPort on the rear ports ran without
an SError on every boot since 2026-10-30.

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,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>
RyanTheTide and others added 20 commits November 9, 2026 11:46
When a display wakes up (DPMS on), the DCP reports its sink on the
audio interface instance it had and replaces that instance some 200 ms
later. PipeWire opens the PCM as soon as the jack turns on, the Open
goes to the old instance, the firmware answers it with a reply that
matches no call, and the Open times out a second later. PipeWire then
drops the output for good: on the J616s, with the Acer QG270 S3 on a
USB-C dock, every DPMS cycle left the display without an audio output
("playback open failed: Connection timed out").

Retry the Open once when the published instance changed while it ran.
The second Open goes to the new instance and is answered.

Signed-off-by: Ryan Murray <81541646+RyanTheTide@users.noreply.github.com>
Assisted-by: LLM
Combine integration/aurora with the published platform, Thunderbolt and
version-27 display series. Preserve newer controller variants and binding
constraints while applying the T6050 router initialization changes.

Reuse the existing public combo-PHY binding and its matrix tunable types;
do not resurrect the obsolete T6050-only schema. Keep one DockChannel
nonblocking-output property definition when combining the public series.

Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
With display audio on, every power-on of a display on a T6041 DCPEXT
logged "unable to match compact service" for its DCPAV video
interface, which endpoint 0x2b publishes cut to
"dispext0:dcpav-video-interface-". The video side runs through IOMFB:
take the interface with the no-op service the CEC interface already
uses.

Signed-off-by: Ryan Murray <81541646+RyanTheTide@users.noreply.github.com>
Assisted-by: LLM
…lt-on

drm/apple: display audio on by default, ELD names, J616s DCPEXT1 audio
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>
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>
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>
Wire both left USB-C ports, their USB and PCIe IOMMUs, router resources,
power domains and display routes. Enable external display processors and
four tunnel pixel-clock gates per port using the public hardware inventory.
Extend the display master's scanout list while retaining the internal
panel's DART first for the loader handoff.

Enable each required supply domain and the board-specific boot-port USB2
handover property. Each port routes two displays through independent
processors, with paired processors for high-bandwidth modes.

Developed with Claude Code.
Signed-off-by: Erik Bourget <erik@ebourget.net>
t6050-max.dtsi describes nub-spmi-a1 and ATC2's PCIe tunnel DART for
every board that includes it, but t6050-peripherals.dtsi skipped its
inventory copies of those two nodes only for J716c. J714c, J714s, J716s,
J775c, J873s and the K114/K116 boards got both and failed to build with
duplicate labels apciec2_dart and nub_spmi_a1.

Skip the inventory copies on every board with t6050-max.dtsi. J716c and
J775D build the same nodes as before.

Signed-off-by: Diljit Singh <hey@djdev.me>
@DjDeveloperr

Copy link
Copy Markdown
Contributor Author

Closing: no longer needed. This fixed the duplicate nub_spmi_a1/apciec2_dart labels that kept nine T6050 DTBs from building on the old ewb/j716c-usb4-public-base stack. #1323 rebases that stack onto integration/aurora and wraps everything it adds to t6050-max.dtsi in #ifdef T6050_J716C, so the other T6050 boards build exactly as before. A local apple-dt-check.sh run on #1323's head built all 137 Apple DTBs with no new warnings. erikwb's restacked #1273 now carries the J716c-only guards for the left-port PCIe DARTs itself.

🤖 Generated with Claude Code

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.

4 participants