Skip to content

drm/asahi: bridge PMP lifetime effort to G17 power ceiling - #1666

Draft
RyanTheTide wants to merge 20 commits into
integration/aurorafrom
parity-idx/g17-pmp-gpu-ceiling
Draft

RyanTheTide wants to merge 20 commits into
integration/aurorafrom
parity-idx/g17-pmp-gpu-ceiling

Conversation

@RyanTheTide

Copy link
Copy Markdown
Contributor

Summary:

  • expose the bounded PMP lifetime-effort report through its existing provider
  • link T8140 G17P to that report and map Q8.24 effort to the native percent ceiling
  • publish the scaled live PPM target on the firmware cadence and restore the captured native policy when the source is absent

Tests:

  • arm64 release-config Image, modules, and t8140-j700.dtb build
  • arm64 QEMU KUnit: apple-pmp-report 13/13, asahi_g17_idle_hold 6/6
  • complete host-test controls (133/133 across the full run and the targeted historical-control rerun)

Read the bounded Q8.24 lifetime-servo effort array from the existing PMP report owner and select its effective final entry. Keep absent, stopped, zero-count and malformed reports explicit, with KUnit coverage for the count contract.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Document the bounded lifetime-servo report array and the T8140 G17P consumer phandle.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Give the T8140 G17P driver an explicit phandle to the provider that owns the lifetime-servo report aperture.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Convert the bounded PMP Q8.24 effort to the native integer ceiling, publish a scaled live PPM target in firmware order, and restore the captured native words when the source is absent. Sample only on the PMP cadence while work is active.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Keep the T8140 GPU node's sleep entry (apple,pmp-report-entry) next to the
report link, and the M5 governor, waiter note and DVFS/request-word helpers
next to the GPU effort reader.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
The firmware polls the PPM target words only while it runs, and the PMP
report is stopped across the sleep. Skip the ceiling update while the GPU
firmware is stopped; the first pass after the wake samples again.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
The M5 firmware session builds its own Firmware state; give it the same
empty ceiling as the G17P session so the driver builds with both.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
@RyanTheTide

Copy link
Copy Markdown
Contributor Author

Neo (T8140) test of 50851a0 merged onto integration/aurora 2b4523c, on a one-shot kernel with an aura b12 trial: the kernel booted clean (Enforcing, 0 failed units, 0 kernel errors, 0 AVC). The first read of /sys/kernel/debug/apple-pmp-report/* then froze the machine with nothing logged, and the watchdog reset it. The only MMIO read this adds to the status file is the GPU effort count at report + 0xc000. On T8140 that word is not readable in the mapped report aperture. With the GPU link in the DT, the bridge makes the same read on the first busy pass, so I didn't boot that variant.

Baseline on the same Neo (7.3.0-aurora-fleet64, glmark2 terrain off-screen, 600 s): hottest GPU sensor peak 107.7 C, mean 107.6 C after 90 s; FPS 689 → 597.

Draft until the effort array's mapping is confirmed.

The lifetime-servo effort array is part of the PMP runtime shared allocation, not the sparse PTD MMIO aperture. Retain the firmware-requested coherent buffer, export aligned word reads through the PMP owner, and make debugfs use that safe path.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Move the lifetime-servo report contract from the sparse PTD aperture to the PMP runtime provider. Require T8140 AGX to name that provider and document that the shared allocation has no DT reg.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Point the T8140 GPU at the PMP firmware provider that owns the coherent lifetime-servo report instead of the sparse PTD report aperture.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Link G17 to the PMP supplier and sample the owner-managed coherent effort report. Provider absence, zero count, invalid data, free and failure continue to withdraw the ceiling and restore firmware-native state.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Pass the underlying device through the public AsRef path when creating the PMP supplier link from the G17 platform probe.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Use the G17 probe platform device when creating the PMP supplier link; the DRM wrapper does not expose the raw platform pointer.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Inline the T8112/T8140 coherent-effort capability check in the report probe so its independently extracted host harness does not depend on a file-local status helper.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Provide a no-Rust fallback for standalone C host extraction of the PMP bridge. Real APPLE_PMP builds depend on Rust and continue to bind the strong owner-managed reader.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
@RyanTheTide

Copy link
Copy Markdown
Contributor Author

Tested 2dea50f on a J700 (T8140), merged onto integration/aurora 028d762. Each arm was a one-shot boot that changed only the DTB. A deletes the GPU's apple,pmp property; B keeps the DTB as built.

The new read is safe. With both DTBs, cat on the pmp-report debugfs file returns at once, and 300 s and 600 s glmark2 runs read it every 2 s without a hang.

The ceiling never engages, though:

  • The firmware never requests the 0xe400 buffer. Across two boots and 15 minutes of GPU load, dmesg never prints PMP coherent report buffer ready, so report_addr stays None and apple_pmp_gpu_effort() can only return -EAGAIN. Only host-initiated GET_IOVA_TABLE and MALLOC requests reach the driver, and none of them is 0xe400 bytes. In m1n1's proxyclient/m1n1/fw/pmp.py, the host allocates the shared memory itself and passes its DVA to the PMP, and the status words sit at +0xc000 of that host buffer. The effort words most likely live in a buffer the host has to supply and announce, which pmp.rs doesn't do yet.
  • The debugfs file always prints gpu_effort: unavailable (-19). CONFIG_APPLE_PMP_REPORT=y with CONFIG_APPLE_PMP=m makes IS_REACHABLE(CONFIG_APPLE_PMP) false in pmp-report.c, so it calls the -ENODEV stub. drm/asahi is a module, so the bridge itself does reach the real function.

Results (glmark2 terrain off-screen, hottest GPU sensor Tg0L):

arm load peak mean after 90 s FPS first -> last (mean)
A (no link) 300 s 107.7 C 107.63 C 691 -> 617 (640)
B (link) 600 s 107.7 C 107.59 C 675 -> 590 (612)
fleet kernel, no #1666 600 s 107.7 C 107.60 C 689 -> 597 (618)

B behaves the same as A and the fleet kernel. The target was about 105.5 C.

B with the GPU -> PMP device link: s2r 3/3 and s2idle 2/2 resumed with Wi-Fi, NVMe, display, input and Touch ID intact, 0 kernel errors and 0 AVC. Each s2r wake re-enumerated the dock's USB3 hub under a different vendor ID. The device set stayed the same and the change has nothing to do with this PR. Host tests 292/292, dcp 88/88.

RyanTheTide and others added 5 commits November 13, 2026 10:03
The T8140 firmware never asks for its runtime report buffer, so the GPU
effort reader never found one and always returned -EAGAIN. Set the
memory up the way m1n1 (proxyclient/m1n1/fw/pmp.py) does: allocate 64 KiB
of coherent memory, send its DVA in a Configure message (type 0x10 in
bits 56:44) once the endpoint is up, and take the firmware's type 0x20
answer as the buffer being ready. The GPU effort is read from its +0xc000
status area.

Only T8140 opts in. Other SoCs keep their message flow unchanged.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
APPLE_PMP_REPORT is built in while APPLE_PMP may be a module, so the
report debugfs file resolved apple_pmp_gpu_effort() to its -ENODEV stub
and never showed the effort. The PMP driver now registers its reader with
the report driver once bound and withdraws it before unbind, outside its
own lock.

DRM_ASAHI reads the same effort for the G17 power ceiling, so it may not
be built in while APPLE_PMP is a module.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Log when the PMP GPU effort engages or releases the power ceiling, and
when the ceiling moves by 5% or more since the last message, with the
effort word and the native power target.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
The production bridge harness links pmp-export.c on the host. Stub the
report driver's reader registration and check that register hands over
apple_pmp_gpu_effort(), that a foreign unregister keeps it, and that the
owner's unregister withdraws it.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
Both 25G83 hosts allocate exactly 0xe400 bytes only after the PMP sends its Ready word. Move the T8140 allocation and Configure reply into that message path, and publish the report only after Configure Ack. The retained sleep keeps the allocation and endpoint, so resume still requires no re-handshake.

Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@aurorasilicon.org>
@RyanTheTide

Copy link
Copy Markdown
Contributor Author

J700 (T8140) test of 628168a (kernel 7.3.0-aurora-ntherm3 = integration e661192 + this branch at f51d963), one-shot boot:

  • The Configure message sent after endpoint start (0x00010100bfde0000, type 0x10 in bits 56:44, DVA 0x100bfde0000) crashes the PMP firmware immediately: exception from EL1t, PC = 0, ESR 0x86000006, with the message in x0. The PMP report reads running: 0 afterwards. No GPU load was run on that boot.
  • Mailbox history before the crash: the firmware's own startup sequence (GET_IOVA_TABLE and so on), then the Configure.
  • On production kernels the PMP endpoint never sends a type 0 (Ready) message, which would log as an unknown message. If that holds on 35665a0's kernel, Configure is never sent and the bridge stays inert. 35665a0 has not been booted yet.
  • ad4def5 (reader registered with the built-in report driver) and f51d963 (harness): host tests 293/293, apple-dcp 88/88 on integration e661192 + this branch.
  • Production fleet64 afterwards: PMP running, report running: 1.

@RyanTheTide

Copy link
Copy Markdown
Contributor Author

35665a0 is safe on the J700 (T8140) but will not engage. It sends Configure only in reply to a Ready (bits 55:48 == 0), and this firmware never sends one: pmp.rs logs any unhandled opcode as "Got unknown message", and no Neo boot has logged that (production, ntherm2, ntherm3). In the ntherm3 mailbox history, the firmware's first word on endpoint 0x20 is GET_IOVA_TABLE (0x0010000000000000). An unsolicited Configure takes the firmware to PC 0.

So the v2 firmware does not use the Ready/Configure report buffer, and the effort has to come from wherever v2 publishes it. That's still open. Keeping this as a draft until it's found. ad4def5, ab01216 and f51d963 don't depend on it.

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.

1 participant