Skip to content

drm/asahi: add the T6041 25G83 profile captured on the J616C (stacked on #525) - #916

Closed
AxxzyWasTaken wants to merge 18 commits into
aurora-silicon:integration/aurorafrom
AxxzyWasTaken:t6041-25g83-profile
Closed

AxxzyWasTaken wants to merge 18 commits into
aurora-silicon:integration/aurorafrom
AxxzyWasTaken:t6041-25g83-profile

Conversation

@AxxzyWasTaken

@AxxzyWasTaken AxxzyWasTaken commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #525, so #525 should go in first. Two commits are new: drm/asahi: add the T6041 25G83 profile captured on the J616C and tools/asahi: model the configuration of a firmware build. The commits under them are #525 as of c048e0eb6bc8. The merge commit brings the branch up to integration/aurora with the conflict resolutions from #525 at 3d0938d8da13, so the tree is #525 at that commit, plus these two commits, plus the base.

#525 admits the M4 Max only with its 25F84 GPU firmware, on 40 cores. A 32-core J616C booting through a macOS 26.6.2 stub loads a T6041 image of 25G83, which #525 refuses. This admits that image as a second T6041 build:

  • A firmware build can now carry the SoC configuration it was measured with. Once the build is identified from its loaded TEXT, that configuration replaces the probed one. 25F84 names none and keeps Bring up T6041/J616c GPU, protected audio and HEVC #525's static profile.
  • The 25G83 configuration (hw/t6041_25g83.rs) is the one this J616C runs with:
    • 32 of 40 cores
    • operand banks for all 40 slots
    • four-cluster deflake and TA mode 1
    • a compute pool of 96 blocks (21 hangs this firmware on grids of more than ten workgroups)
    • the captured register map (six MCC instances)
  • Its hardware data, power configuration, region C and AON table are the contents captured on this unit (hw/t6041_captured.rs), with only the runtime words written over them. The GPU isn't started unless the chip ID, core count, register map and content hashes match the capture.

The commit message has the details and the reasons for each value.

Testing

  • On the merged tree:
    • The driver builds against 7.3 as a module, and the KUnit build compiles. The KUnit tests weren't run.
    • The J614s, J616s and J616C device trees build.
    • The G17 host tests pass (25 of 25). g17-firmware-selection-tests now also checks that a build's configuration follows the identified image.
    • aop-bootargs-tests and t604x-cpu-order-tests pass.
  • run-host-tests.py refuses to start on this tree, because three tests from Bring up T6041/J616c GPU, protected audio and HEVC #525 aren't registered with it (aop-bootargs, g17-t6041-initdata, t604x-cpu-order). I ran the G17 set from a temporary copy that lists them.
  • Not run on the merged tree:
  • This branch hasn't been booted. An earlier 7.3 build of the same profile booted once on a 32-core J616C, with aura#68 and arm64: dts: apple: t6041-j616c: describe the GPU (stacked on #914) #917. The firmware started. On the same stack, Hyprland ran on the G17 driver with Mesa aurora-wip, vkmark on Wayland kept the fragment engine busy (checked in fdinfo), and Sober (x86, through FEX) reached Roblox's home screen, with no recoveries in about 2.5 minutes. No game has been played on it yet. That build had two local changes that aren't in this PR: a 96-block render pool, and the larger clustering metadata sizes described below. I didn't try it without them.
  • The same 25G83 profile and captured contents have been this J616C's GPU driver since late October, on a 7.2 port of the G17 driver: desktop, GL and Vulkan apps and games, Flatpak and x86 apps through FEX.

On current integration/aurora: with the base merged in, T6041 25G83 also picks up upstream's 25G83 partial renders, ray traversal, segment limits and its 44-block render pool. On 7.2 this unit needed 96 render blocks (22 hung it). On 7.2 it also needed bigger clustering metadata with four clusters, or clustered tiling outgrew it on heavy geometry and the firmware killed the render as no-progress (reason 0). This PR has neither change yet. In the 7.3 boot, metadata 3 and 4 were 0x2800 and the larger of 0x800 and the partial-render size, and metadata 1 was 0x44 per block of tiles.

Needs

Follow-up: the captured contents include this unit's binned operating points, power limit and leakage coefficients. That's only because the device tree it booted with had no GPU tables. With the loader filling the tables, the builders could produce those values instead of the capture.

astaff and others added 15 commits October 28, 2026 17:11
Reuse the existing SoC and PMGR descriptions as the shared T604x base.
The J616s compiled tree keeps every node and property unchanged.

Assisted-by: LLM
Describe the Max CPU, OPP and register-window differences on the shared
base. Preserve the qualified J616c node and property values.

Assisted-by: LLM
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Move identical register-window constructors into a family helper.
The T6040 and T6041 initialization-data checks retain their exact values.

Assisted-by: LLM
Select a static 25F84 profile and admit the normalized loaded image
measured in three qualification boots. Remove exploratory overrides
and unknown-image admission from the support path.

Assisted-by: LLM
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Keep the reason-0 and cancellation handling scoped to 25F84, with
serial rendering explicitly opt-in. Concurrent-render firmware restarts
and complete recovery remain unresolved.

Assisted-by: LLM
Add gated 26.5.2 firmware acceptance and headerless powerlog parsing
for the T6041 display controller.

Assisted-by: LLM
Wait for the flip notification before completing commit cleanup so
framebuffer ownership follows scanout completion.

Assisted-by: LLM
Give bootarg access width its own hardware setting and patch through
one aligned buffer. Preserve surrounding bytes and verify changed words.
Synthetic MMIO checks cover malformed tables, bounds and failed readback.

Assisted-by: LLM
Describe the six amplifiers and headphone jack in the J616c board
DT. Stop playback when the protection lease is lost.

Assisted-by: LLM
Limit admission to the qualified J616c machine and firmware layout.
Apply the capability per device without allocating or changing the
shared variant descriptor.

Assisted-by: LLM
Register the watchdog against its platform device and apply the
configured nowayout policy.

Assisted-by: LLM
Build the production initialization objects with their soft-float types
and compare constants with explicit capture inputs. Keep T6040 per-chip
calibration validation separate; include no captures or local defaults.

Assisted-by: LLM
m1n1 compares DT CPUs with its physical MPIDR enumeration. Appending the Max cores to the Pro topology put CPU 9 out of order and stopped boot before kernel entry.

Define the full family topology in hardware order and remove the extra cores from J616s. Check the compiled DTB order for both SoCs.

Assisted-by: LLM
Keep all shared firmware profiles at TA 0x1c890 = 0 and enable mode 1
only in T6041's admitted 25F84 build. Pass that device/build policy
through RenderArgs without changing register ordering, merge-buffer
writes, fragment programs or serial-render admission.

Add KUnit coverage for the policy boundary and constructor output,
including SCS array shape and unchanged fragment/G17P arrays.

Motivated by AxxzyWasTaken's separate J616C/25G83 implementation results:
aurora-silicon#525 (comment)
Those results do not validate this branch or its 25F84 firmware; the
cluster merge-buffer explanation remains a hypothesis.

Validation: patch application/reversal, whitespace and source-scope checks.
Not yet compiled, KUnit-executed or hardware-tested. Keep the existing
asahi.t6041_serial_render=1 workaround pending the concurrent-render test
matrix documented in the PR.
The 32-core M4 Max in the J616C boots through a macOS 26.6.2 stub (iBoot
mBoot-18000.161.10), which loads a T6041 image of the 25G83 GPU firmware
the M4 Pro runs. Its loaded TEXT (0x60000 bytes, GKTS and ECAP records
at 0x59839 and 0x5991c, DATA 0x138000) normalizes to sha256
aa113ed62079bcfdeef0f86c2a8d7eae9f907b03be28ccf298c943951d0effc5.
T6041 admits only its 25F84 image, on 40 cores, so this unit's GPU is
refused.

Admit that image as a second T6041 build. A firmware build can now name
the SoC configuration it was measured with; once the build is
identified, that configuration replaces the probed one. The 25F84 build
names none and keeps its static profile; T6040 and T8140 only gain the
empty fields. Built on the host from the driver sources, the T6041
25F84 hardware data, power configuration and region C, and the T6040
builder output, are byte-identical before and after this change.

The 25G83 configuration (hw/t6041_25g83.rs) is the one the J616C has
run with on this firmware:
- 4 clusters with 32 enabled cores (core mask 0xf6_fdbf6fdb), which
  the probe requires.
- Operand-state banks for all 40 core slots (0x80000 bytes), as for
  25F84; the enabled slots run to 39. With banks for the 32 enabled
  cores only (0x68000 bytes, followed by the queue context), a compute
  load beside rendering hit reason-0 recoveries in 5 of 5 runs, and in
  0 of 4 with 40 banks.
- Four-cluster deflake and TA mode 1, as for 25F84. Clustered tiling
  hangs this GPU until the cluster buffers are sized for four clusters.
- A compute pool of 96 blocks, which the J616C has run with since
  23 Oct 2026; 21 blocks hang its firmware on grids of more than ten
  workgroups.
- The captured register map: six memory controller instances in slot 3
  (apple,sgx-active-mcc-bit-vector 0x3f, 32 MiB apart), which moves
  every window after it 0x30000 further than on the M4 Pro, and no
  reserved slots.

Its hardware data, power configuration, region C and AON table are
applied, not built: the contents built on this unit and captured from
it on 25 Oct 2026 (hw/t6041_captured.rs), with only the runtime words
written over them (completion-ring descriptors and QoS pointer;
configuration-status pointer, AON pointer and random word). They equal
what the 25G83 builders write for the M4 Pro except for the chip ID,
the core count, the register map, four GPU cluster temperature sources,
a second sensor-mask word, and the values below.

Some captured values exist only because the device tree the J616C boots
with has no GPU operating-point, CS or AFR tables and none of the
calibration properties the T6040 builder reads (apple,perf-map-a/b,
apple,perf-relative-a/b, apple,max-power-mw, the leakage coefficients):
this unit's binned operating points in the performance, CS and AFR
tables, its 110586 mW power limit and the coefficient derived from it,
and the four clusters' leakage coefficients. With those tables in its
device tree, the builders could produce them instead.

The GPU is not started if the captured contents do not fit: it must
have the captured 32 cores, the captured chip ID and register map must
equal the configuration's (with no reserved slots), and the FNV-1a 64
hashes of the hardware data and power configuration without their
runtime words, and of region C, must equal the capture's. On the host,
the written contents hash to those values, and the checks refuse
another chip ID, the 25F84 and T6040 register windows, a missing or
duplicated window and reserved slots.

Not run on hardware: the J616C has run these contents on this firmware
only with the 7.2 port of the G17 driver.
Bring the branch up to the current base. The conflicts are in the aurora-silicon#525
commits underneath, so they take the resolutions from aurora-silicon#525 at 3d0938d:
the tree is aurora-silicon#525 at that commit, the 25G83 profile and this base.
firmware_variant() now also returns the SoC configuration a build was
measured with, so the selection test no longer compiled. Give its model
of Build the field, and check that the configuration follows the
identified image, and that a build without one and a fixed variant keep
the probed configuration.
t6040.dtsi keeps aurora-silicon#525's split. The base dropped dma-noncoherent from a node
that moved to t604x.dtsi, so that removal goes there.
@RyanTheTide

Copy link
Copy Markdown
Contributor

Merge train (MTL, 06/11): can't take this one. None of its 16 non-merge commits carry a Signed-off-by: (14 are Artyom Astafurov's, 2 are yours), and a sign-off from each commit's author is a hard requirement. It also no longer merges into integration/aurora: most of the astaff commits it carries already landed through #525 and #958. Could you rebase it onto integration/aurora so it only contains the 25G83 profile and the tools/asahi model, with your sign-off on each commit? I'll gate it again then.

@AxxzyWasTaken

Copy link
Copy Markdown
Contributor Author

Replaced by #1050: rebased onto integration/aurora with only the two commits, both signed off.

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