Skip to content

drm/asahi: add the T6041 25G83 profile captured on the J616C - #1050

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

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

Conversation

@AxxzyWasTaken

Copy link
Copy Markdown
Contributor

Replaces #916, rebased onto integration/aurora as asked there: now that #525 and #958 are in, this carries only two commits, both signed off.

  • drm/asahi: add the T6041 25G83 profile captured on the J616C
  • tools/asahi: model the configuration of a firmware build

integration/aurora 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 is refused. 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 its 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.

Changes from #916 in the rebase

  • Gpu::new no longer selects the compute program or pool, because integration/aurora moved that, so only the configuration swap stays.
  • t6041_25g83.rs gains alternate_core_masks: None.
  • The TA mode test keeps integration/aurora's compute and firmware-area checks, on the 25F84 entry.

Testing

  • On this tree:
    • The driver builds against 7.3 as a module, and it also builds with CONFIG_KUNIT=y. The KUnit tests weren't run.
    • The G17 host tests pass, 29 of 29, through run-host-tests.py --only g17.
    • aop-bootargs-tests and t604x-cpu-order-tests pass.
  • This exact tree hasn't been booted, and Bring up T6041/J616c GPU, protected audio and HEVC #525's host harness wasn't rerun.
  • An earlier 7.3 build of the same profile booted once on a 32-core J616C. The firmware started, Hyprland ran on the G17 driver with Mesa aurora-wip, vkmark kept the fragment engine busy, and Sober (x86, through FEX) reached Roblox's home screen, with no recoveries in about 2.5 minutes. That build had two local changes that aren't in this PR: a 96-block render pool, and larger clustering metadata sizes.
  • 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.

Known gap: on integration/aurora, T6041 25G83 also picks up the 25G83 partial renders, ray traversal, segment limits and the 44-block render pool. On 7.2 this unit needed 96 render blocks (22 hung it). 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.

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 through aura#68, the builders could produce those values instead of the capture.

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.

Signed-off-by: AxxzyWasTaken <axxzytte@gmail.com>
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.

Signed-off-by: AxxzyWasTaken <axxzytte@gmail.com>

@RyanTheTide RyanTheTide 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.

t6041_captured.rs and the profile it encodes come from Gravity Linux code. Please credit the original authors (Cody Ho, Niklas Sheth): keep their copyright lines and their Signed-off-by from the original commits (Co-developed-by plus their own sign-off, or authorship of the commit), and use SPDX GPL-2.0-only for derived files. The values also look specific to a single unit; it would help to show which fields vary per machine and read those from the ADT instead.

@AxxzyWasTaken

Copy link
Copy Markdown
Contributor Author

@RyanTheTide thanks, done in #1373. The commits had to be rewritten, so it replaces this PR, rebased onto current integration/aurora (7b7c237, 226a65c).

Credit for Cody Ho and Niklas Sheth. The profile was built by Gravity Linux's M4 GPU encoders (g16_fw.rs, g16_platform.rs, g16_power.rs):

  • Niklas Sheth: the commit carries Co-developed-by: Niklas Sheth <hi@niklassheth.com> and Signed-off-by: Niklas Sheth <hi@niklassheth.com>, copied from his 3a2ad76 ("drm/asahi: wire M4 GPU into the T8132 desktop platform"), which added the bootloader power limit.
  • Cody Ho: his original commit has no Signed-off-by, neither GravityLinux bd25d19 ("drm/asahi: add asynchronous M4 GPU prototype driver") nor 778088823509, which it was cherry-picked from. So I haven't added one for him. He is credited by name in the commit message, with links to both commits. His sign-off appears only on later Gravity commits such as ed2c67a9f6d4, which this profile doesn't come from. If he wants to add his Signed-off-by or Co-developed-by, I'll add it.
  • The commit message also credits Jonathan Goyvaerts' T6040 values in those encoders.

Copyright and SPDX. t6041_captured.rs is gone. The derived file is now hw/t6041_25g83.rs, with // SPDX-License-Identifier: GPL-2.0-only and Gravity's own line, // Copyright The Gravity Linux Contributors, plus the links.

Per-unit values and the ADT. The capture is no longer applied. The 32-core configuration runs the 25G83 builders, like the 40-core one from #1345. The values that vary per unit (the binned operating points with one voltage per cluster, and the CS and AFR tables) now come from the device tree, which the loader fills from the ADT perf-states, cs-perf-states and afr-perf-states (aura#68). On the host, the builders fed this J616C's ADT values give the same FNV-1a hashes as the capture for the hardware data, power configuration and region C (runtime words excluded). That is checked in g17-t6041-initdata-tests.

These stay static, because the driver has no ADT source for them on T6041:

  • The selector ladders: the per-voltage-step OPP indices of this unit, and the M4 Pro's relative ladders.
  • The 110586 mW limit (the M4 Pro's 69116 mW per 20 cores, scaled to 32) and the leakage coefficients. These are M4 Pro values, not measurements of this unit, and they are not in the ADT.
  • The AON rows. They do come from the ADT's aon-ptd ptd_data_table, but the loader doesn't publish them.
  • Five power-configuration words. One is +0x9ec, which is -1000 / power limit.

I didn't add new property names.

When the 25G83 image is listed for both core layouts, the selector picks the configuration that matches the probed cores.

Testing

  • run-host-tests.py --only g17: 30/30 pass, including the new hash and selection checks.
  • The new const checks were compiled with rustc and hold.
  • rustfmt is clean on the changes. checkpatch reports no errors.
  • Not compile-tested in a kernel tree (no room for a Rust tree build in the build VM). KUnit was not run, and nothing was booted.

@AxxzyWasTaken

Copy link
Copy Markdown
Contributor Author

Superseded by #1373 (rewritten for the requested credits, rebased onto current integration/aurora).

niteria pushed a commit to niteria/linux that referenced this pull request Nov 9, 2026
The macOS 26.6.2 boot firmware (iBoot mBoot-18000.161.10) loads the
25G83 GPU firmware on the M4 Max as well. integration/aurora admits
only 25F84 there, so a 40-core J614c booting through a 26.6.2 stub has
no GPU (linux#1332).

A firmware build can now carry the SoC configuration it runs with. Once
the build is identified, that configuration replaces the probed one.
This is the mechanism linux#1050 proposes, so its 32-core profile can
build on it.

T6041 gains a 25G83 build. Its configuration is the 40-core 25F84
profile with two changes:
- the 25G83 variant, with the four-cluster tiler values (TA mode 1)
  that 25F84 uses on this machine and aurora-silicon#1050 uses for 25G83;
- the 25G83 register map. It has the same 25 windows (slot 3 holds the
  40-core part's eight memory controllers), laid out the way 25G83
  lays them out on the M4 Pro: from +0x200000, each window followed by
  a 16K guard page, with no reserved slots. This rule reproduces both
  known 25G83 maps, the M4 Pro's (four controllers) and aurora-silicon#1050's 32-core
  M4 Max map (six). A compile-time check holds the M4 Pro's map and
  the new one to the rule, and the new one to 25F84's windows.

The rest comes from the 25F84 profile: 40 cores in four clusters, the
operand-state and deflake layouts, the 160-block compute pool, the
hardware data and power words, and region C. The core count check
stays, so a 32-core part is refused with this configuration.

The build admits one loaded image: the only T6041 25G83 image measured
so far (sha256 aa113ed6...effc5, measured on aurora-silicon#1050's 32-core J616C).
iBoot fills part of the loaded TEXT for each Mac (three J616s loaded
three different T6040 images), so a 40-core Mac most likely loads a
different one. If so, its "unsupported GPU firmware build" line gives
the sha256 to add.

KUnit tests cover the identities of both T6041 builds, the 25G83
configuration, and the render policy of both builds. The host model of
the build selector now returns the build's configuration, and the T6041
initdata host test also builds the 25G83 objects.

Not run on hardware.

Link: aurora-silicon#1332
Link: aurora-silicon#1050
Signed-off-by: Diljit Singh <hey@djdev.me>
RyanTheTide pushed a commit that referenced this pull request Nov 10, 2026
The 32-core M4 Max in the J616C boots through a macOS 26.6.2 stub (iBoot
mBoot-18000.161.10) and loads the T6041 25G83 image that "drm/asahi: run
the 25G83 build on the 40-core M4 Max" admits. That build runs the
40-core configuration, whose core check refuses this GPU.

Admit the image a second time, with a 32-core configuration
(hw/t6041_25g83.rs). When builds share an image, the selector now takes
the one whose configuration matches the probed clusters and enabled
cores, else the first one, so a 40-core part runs as before and another
layout is still refused by the core check. The GPU ID is read before the
build is selected for this. T6040 and T8140 are unchanged.

The configuration:
- 4 clusters with 32 enabled cores. Operand-state banks for all 40 core
  slots: the enabled slots run to 39 (core mask 0xf6_fdbf6fdb), and with
  banks for the 32 enabled cores only, 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 the 40-core 25G83 build.
- 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 40-core 25G83 register map with six memory controllers in slot 3
  (ADT active-mcc-bit-vector 0x3f), laid out by the same rule. A
  compile-time check holds it to that rule and to the 40-core windows.

What varies between units comes from the device tree, as on the 40-core
part: the boot loader fills the operating points with one voltage per
cluster (from the ADT perf-states tables) and the CS and AFR tables (from
cs-perf-states and afr-perf-states), and the 25G83 builders turn them
into the performance, CS and AFR tables of the hardware data. The
previous version of this change applied contents captured on this unit,
binned operating points included, because its device tree had no GPU
tables at the time.

The rest is static, because the driver has no source for it on T6041:
- The selector ladders: the highest and lowest of this unit's operating
  points at each of its 11 core voltages (state 5 of ladder B is OPP 5,
  where the 40-core profile has OPP 6), and the M4 Pro's relative
  ladders.
- The power limit, 110586 mW (the M4 Pro's 69116 mW for 20 cores, scaled
  to 32), and the M4 Pro's leakage coefficients for four clusters.
  Neither is in the ADT, and neither is a measurement of this unit.
- The AON rows of the four GPU clusters and the SoC, from the ADT's
  aon-ptd ptd_data_table, which the loader does not publish.
- Five power configuration words: -1000 / power limit at +0x9ec, the
  second temperature-sensor mask word at +0x3b5c, the temperature sources
  of clusters 2 and 3 at +0x6328 and +0x632c, and 5 at +0x6360.

Built on the host from the J616C's ADT operating points, the hardware
data, power configuration and region C hash (FNV-1a 64 without the
runtime words) to those of the contents this unit has run with since
October 2026, dumped on 25 Oct 2026.

Those contents, and so the static values above, were built by the M4 GPU
encoders of Gravity Linux (g16_fw.rs, g16_platform.rs, g16_power.rs),
with Jonathan Goyvaerts' T6040 values. Based on work by Cody Ho, who
wrote the encoders (GravityLinux bd25d19, cherry-picked from
778088823509, which carries no Signed-off-by), and Niklas Sheth, who
added the bootloader power limit (GravityLinux 3a2ad76).

Not run on hardware, and not built in a kernel tree: the host tests
compile the build selector, the configuration's constants with the 25G83
builders, and its compile-time checks.

Link: GravityLinux/linux@bd25d19
Link: GravityLinux/linux@3a2ad76
Link: #1050
Co-developed-by: Niklas Sheth <hi@niklassheth.com>
Signed-off-by: Niklas Sheth <hi@niklassheth.com>
Signed-off-by: AxxzyWasTaken <axxzytte@gmail.com>
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.

2 participants