Repository navigation
J713: hold the memory and fabric floor for GPU work, not whenever GFX is powered - #582
Merged
erykwieliczko merged 6 commits intoNov 4, 2026
Conversation
Contributor
Author
|
cc @DjDeveloperr - what do you think of this clpc-gpu messaging mechanism? |
The power work treats a reading of less than 0.1 W across the P-CPU, E-CPU and GPU rails as a firmware reset image: it reports -ENODATA, retains the minimum CPU and GPU ceilings and fails the hwmon rails with -EAGAIN. An idle J713 reads below that once its GPU idles at a low performance state (P-CPU 40-55 mW, E-CPU 9 mW, GPU 27 mW): the ceilings then sat at the minimum while idle, the CPUs ran at 900 MHz, and the GPU budget climbed back one state at a time once work arrived. A reset image reads zero on both CPU rails, which the running reader cannot. Reject only that. Signed-off-by: Erik Bourget <erik@ebourget.net>
The firmware runs at the state the three Globals selectors publish, busy or idle, and the host published the thermal ceiling: on the J713 the GPU sat at S9 (1470 MHz, 1000 mV) with nothing to draw. Its rail drew 1.06 W idle and 1.25 W for a 60 fps desktop, against 68-90 mW for the same desktop at S1-S3. Request a state from the GPU's busy share of each 20 ms window, between S3 and the thermal and user ceiling, which still bound it: the top state when a window was at least 70% busy, one step up at 40%, and down on a utilization averaged over about four windows, one step under 25% and to S3 under 10%. Busy time runs from publication to drain. An idle engine polls once more per window until it is back at S3. S3 draws no more than S1 on a desktop load and runs at 2.4 times its clock; S4 and up cost several times as much. The accounting is policy::Governor, which the host policy test runs directly: publication to drain, busy spans carried across windows, flights dropped by recovery without a drain, the idle re-arm back to S3, and thermal and user ceilings, including those below S3. Paired on the J713, on battery with the backlight at half (idle 5 x 60 s, three 60 Hz scenes 3 x 30 s each, the glmark2 suite 3 times): idle draw 7.32 -> 6.06 W, the GPU rail 1.09 W -> 27 mW. The 60 Hz build scene stays at S3 with no missed frame, and the glmark2 score is 574 -> 573. Signed-off-by: Erik Bourget <erik@ebourget.net> [eryk: don't re-arm the idle poll on a failed engine: its poll returns before service_power(), so the demand never decays, and an engine that failed while idle above S3 re-armed its poll every 20 ms until reboot once anything kicked it; the host test's call-site check follows] Signed-off-by: Eryk Wieliczko <eryk@wieliczko.ninja> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
T8132's G16 firmware keeps GFX powered while the GPU idles, as T6040's does for its whole lifetime, so the GFX power state says nothing about GPU work. Let a T8132 GPU driver take the CLPC's host input, as on T6040 and T8140: accept the T8132 CLPC as a provider, and allocate the input at probe. The T8132 floor still follows the GFX power state; a later change makes it follow the reported work. Signed-off-by: Erik Bourget <erik@ebourget.net>
The G16 firmware keeps GFX powered while the GPU idles, so a host performance controller cannot tell GPU work from its power state. Take the DT-selected CLPC's input (apple,clpc) at probe, as G17 does, and report whether work is in flight. Polling retires finished work before it publishes, so reporting after each publication pass sees work start and drain; a fail-stop, which empties the flights without another pass, reports from fail_flights(). Only changes are reported. The handle is taken before the PMP vote, so a CLPC that has not probed yet defers the GPU before anything is set up, with the reason recorded; any other error is reported. The floor is a performance aid: without apple,clpc, or in a kernel built without the CLPC, the GPU runs without one, with a warning in the latter case. Kconfig keeps a CLPC that is built reachable from the GPU driver. Signed-off-by: Erik Bourget <erik@ebourget.net>
The J713 enables the PMC and its CLPC. Point the GPU at that CLPC with apple,clpc, so the GPU driver reports its work there. The link stays on the J713: the other T8132 boards leave the PMC disabled, and a GPU linked to a CLPC that never probes would wait for it. Signed-off-by: Erik Bourget <erik@ebourget.net>
The T8132 CLPC votes the qualified M5/F3 floor (DCS 5, fabric 3) whenever GFX is powered. The G16 firmware keeps GFX powered while the GPU idles, so on a J713 the DRAM controller and the fabric stay at their top states the whole time the system is awake, also at an idle desktop. Take the GPU's share of the floor from the work the GPU driver reports instead, as on T6040: the floor is held while work is in flight, and released HOLD_MS after the last of it retires. CPU demand is unchanged. Continuous rendering, such as video playback or animations, keeps work coming more often than HOLD_MS and holds the floor as before; the saving is at a desktop where nothing redraws. On a J713: - at an idle desktop the floor is released about 90% of the time, and system power drops by about 0.45 W, from 6.3 to 5.9 W on the same boot; - under glmark2 the floor is held while the GPU works and the score is unchanged. With the floor released outright it drops by about 45%, so GPU work does need it; - video playback holds the floor throughout, as before; - suspend-to-idle and resume are unaffected. The GPU's floor now depends on the J713 device tree linking the GPU to the CLPC (apple,clpc): without that link nothing reports GPU work and it gets no floor. The J713 device tree is built and shipped with its kernel. It keeps apple,gpu-power-state on the T8132 CLPC for older kernels; it is no longer used. A KUnit case covers the T8132 input gate. Signed-off-by: Erik Bourget <erik@ebourget.net> [eryk: follow the change in the host model, tools/asahi/clpc-gpu-demand-tests.py, which failed to build: extract apple_clpc_gpu_input_demand(), aim the omit-host-demand mutation at its call, model T8132 on reported work, and move the read-error check (bf86f72) to T8140, the table that still reads the GFX power state] Signed-off-by: Eryk Wieliczko <eryk@wieliczko.ninja> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
|
Merging with a test fix and a conflict resolved. This comment is from Claude Opus 5.5, working for Eryk, not from Eryk himself. Rebased onto integration/aurora Changes
OpenThe question to DjDeveloperr about the CLPC-GPU messaging is still unanswered. Testing
🤖 Written by Claude Opus 5.5 (in Claude Code) for Eryk. |
erykwieliczko
force-pushed
the
j713/g16-memory-floor
branch
from
November 4, 2026 09:39
94a2535 to
ab308ac
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On the J713 (MacBook Air 13" M4) the DRAM controller (DCS) and the SoC fabric run at their top states the whole time the system is awake, also at an idle desktop.
The T8132 CLPC votes the qualified M5/F3 floor (DCS 5, fabric 3) whenever the GFX power domain is on. The G16 firmware keeps GFX powered while the GPU idles, so that floor is never released.
Releasing it outright at an idle desktop cuts system power from 6.3 to 5.9 W on the same boot, with the 3.8 V SoC rail going from 1.93 to 1.55 W. The display is unaffected. But the floor is needed for GPU work: released outright, glmark2 drops from about 520 to 289.
Fix
T6040 has the same problem, with firmware that keeps GFX powered for its whole lifetime, and the CLPC already solves it there with a host input: the GPU driver reports its work through
apple_clpc_gpu_set_active(), and that report, not the power state, drives the GPU's floor. This series uses the same path for T8132:soc: apple: clpc: Let the T8132 GPU driver report its work: accept the T8132 CLPC as a GPU-demand provider and allocate its input at probe. The floor still follows GFX power.drm/asahi: g16: Report work in flight to the CLPC: take the DT-selected CLPC's input (apple,clpc) at probe, as G17 does, and report whether work is in flight after each publication pass. Polling retires before it publishes, so the report sees work start and drain; a fail-stop reports fromfail_flights(). Only changes are reported.apple,clpc, or in a kernel built without the CLPC, the GPU runs without it (with a warning in the latter case). Kconfig keeps a CLPC that is built reachable from the GPU driver.arm64: dts: apple: t8132-j713: Link the GPU to its CLPC:apple,clpcon the J713 GPU node. The other T8132 boards leave the PMC disabled and get no link, so their GPU never waits for a CLPC that doesn't probe.soc: apple: clpc: Hold the T8132 GPU floor for reported GPU work: the T8132 table drops the GFX power-state rule and uses the reported work, as on T6040. The floor is held while work is in flight and released HOLD_MS after the last of it retires. CPU demand is unchanged. KUnit case for the T8132 input gate.Each commit builds and leaves a working system: the reports exist from commit 2, arrive from commit 3 and are used from commit 4.
apple,gpu-power-statestays on the T8132 CLPC node for older kernels; nothing reads it for T8132 any more.Testing
On a J713, running our J713 tree with integration's
clpc.cand this series on top (integration/auroraalone doesn't bring up the J713 display yet):Continuous rendering such as video or animations keeps work coming more often than HOLD_MS, so it holds the floor as before. The saving is at a desktop where nothing redraws, which is most of the time on a laptop.
apple-clpc-gpusuite, now 5 cases, passes under arm64 QEMU with lockdep.CHECK_DTBSshows no new warnings for the J713 DTB, anddt_binding_checkpasses forapple,agx.yaml.--strict: clean, except three "externs should be avoided in .c files" warnings ing16/glue.c. Those follow the file's existing pattern for its Rust-called helpers.Not covered
This series was developed and tested by Claude (Anthropic), working with me on the J713.