Skip to content

soc: apple: clpc: take GPU activity reports from the G17 driver (stacked on #244) - #270

Open
DjDeveloperr wants to merge 5 commits into
integration/aurorafrom
neo/clpc-gpu-activity-20261028
Open

DjDeveloperr wants to merge 5 commits into
integration/aurorafrom
neo/clpc-gpu-activity-20261028

Conversation

@DjDeveloperr

@DjDeveloperr DjDeveloperr commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #244 (which is stacked on #229). The G17 side reports from port.rs and the direct publication path, and both come from #229. Once #229 and #244 land, this goes onto integration/aurora unchanged.

This adds the GPU activity input that the T8140 dense-light GPU floor (next PR, mirroring aurora-silicon/linux#563) counts submissions through. omacom doesn't have it yet. On its own it changes no floor and no behaviour, because the T8140 device tree doesn't link the GPU to its CLPC until the next PR.

What it carries

  1. dt-bindings: gpu: apple,agx: add the apple,clpc link: the phandle from the GPU to its CLPC. The binding has additionalProperties: false, so the device tree can't name the CLPC without it.

  2. soc: apple: clpc: take GPU activity reports from the GPU driver: apple_clpc_gpu_get(), apple_clpc_gpu_set_active() and apple_clpc_gpu_put(), declared in include/linux/soc/apple/clpc.h. The T8140 CLPC offers the input.

    • A report records whether the GPU has work and when that last changed, and counts the reports (sequence).
    • It takes only the input's own spinlock, so the submission path can make it in atomic context.
    • The input is a separate refcounted allocation, so a GPU that lets go after the CLPC is removed never touches freed memory.
    • A mutex orders the GPU's drvdata lookup against CLPC removal, and a device link orders the CLPC before the GPU. A GPU that names a CLPC which hasn't probed yet defers.
    • debugfs shows the input (host_gpu: active … request_ns … sequence …).
    • New KUnit suite apple-clpc-gpu: reference lifetime, and a put after the CLPC has gone.
  3. drm/asahi: g17: report GPU activity to the CLPC: G17 reports:

    • every submission, with or without the device mutex;
    • each change of full firmware effort;
    • an inactive GPU once both firmware processors have stopped.

    A small C shim keeps struct device opaque across the FFI boundary, like the existing sync shims. Without the DT link, every report is a no-op.

Scope

This is Ryan Murray's input from aurora-silicon/linux (32f7efe, 07a2cd1, 61a2fec, 7ab7775, fa12ae8), cut down to what Neo needs. No T6040 code. Left out:

The API, the request lifetime and the G17 call sites match aurora, so later aurora changes still apply here.

Testing

  • Host build at the head of the stack, with the shipped linux-aurora config plus asahi.config (CLPC built in, asahi a module, Rust 1.85.0, private bindgen):
    • drivers/soc/apple/ and drivers/gpu/drm/asahi/ compile and asahi.o links;
    • asahi_core.o calls the three shims, and clpc.o exports the three functions;
    • no new Rust warnings.
  • tools/aurora-ci/compile-check.py --per-commit (W=1, shipped config): pass, 0 new W=1 warnings at each of the 3 commits. That job skips Rust, so it never selects g17/clpc.o; in the Rust-enabled build both clpc.c and g17/clpc.c are W=1-clean.
  • tools/aurora-ci/check-commits.py: all commits signed off. checkpatch only asks whether MAINTAINERS needs updating for the two new files, which the existing globs already cover.
  • tools/aurora-ci/dt-check.py over this stack plus the next PR: pass, 0 new problems in any class; the binding is checked.
  • KUnit apple-clpc-gpu (arm64 QEMU, 16K pages): 2/2 at this head (3/3 with the next PR).
  • Kernel CI (dispatched, because stacked PRs don't trigger it): green at 139d67f95e75: run 40799680459. package, KUnit (omacom's aurora.kunitconfig), boot, host tests and the CI self-test pass. A dispatched run skips commits, compile and device trees, so those three were run locally (results above).

Note: tools/aurora-ci/aurora.kunitconfig doesn't enable CONFIG_APPLE_CLPC, so CI's KUnit job doesn't run the new suite yet. I left that config alone to keep this PR to the driver; enabling it needs CONFIG_CPU_FREQ=y, CONFIG_MFD_SYSCON=y and CONFIG_APPLE_CLPC=y.

The SoC's host performance controller (CLPC) raises the floors of the
memory controller and the fabric for GPU work. To tell GPU work apart
from the GPU merely being powered, it needs to know when the GPU driver
submits work. Describe the phandle that names that controller.

Signed-off-by: DjDeveloperr <hey@djdev.me>
The T8140 CLPC sees GPU work only through the graphics power state, which
the firmware turns off a few milliseconds after the GPU idles. Light
submissions a few milliseconds apart power graphics up and down between
them, so from that state alone the CLPC cannot tell them from a load paced
by frames.

Add an input the GPU driver reports its activity through. The GPU names its
CLPC with an "apple,clpc" phandle and takes the input with
apple_clpc_gpu_get(). apple_clpc_gpu_set_active() records whether the GPU
has work and when that last changed, and counts the reports;
apple_clpc_gpu_put() clears the input and lets it go. A report takes only
the input's own spinlock, so a submission path can make it in atomic
context.

The input has a lifetime of its own: the CLPC and the GPU each hold a
reference, so a GPU that lets go after the CLPC went away never touches
freed memory. A mutex orders the GPU's lookup of the CLPC's drvdata against
the CLPC's removal, and a device link orders the CLPC before the GPU. A GPU
that names a CLPC which has not probed yet defers its probe.

The T8140 CLPC offers the input. Nothing uses it for a floor yet; debugfs
shows it. A KUnit suite covers its reference lifetime, including a put by
the GPU after the CLPC is gone.

This is the input Ryan Murray added to aurora-silicon/linux for T6040
(32f7efe, 07a2cd1, 7ab7775), offered here on T8140 and
without the T6040 demand policy or the sampler wake on a cold publication
that only that policy uses.

Signed-off-by: DjDeveloperr <hey@djdev.me>
Take the activity input of the CLPC that the device tree links the GPU to,
when it links one, and report to it:

 - every submission, at publication, with or without the device mutex;
 - each change of full firmware effort, which is withdrawn after the GPU
   has been continuously idle;
 - an inactive GPU once both firmware processors have stopped, so that a
   slow shutdown does not end the activity while firmware can still
   consume work.

A report only takes the input's own spinlock. A device tree without the
link leaves the input unset and every report a no-op; one that names a
CLPC which has not probed yet defers the GPU's probe. A small C shim keeps
struct device opaque across the FFI boundary, as the existing sync shims
do.

This is the G17 side of the input Ryan Murray added to aurora-silicon/linux
(32f7efe, 61a2fec, fa12ae8), without the read-only power view
of the firmware reports.

Signed-off-by: DjDeveloperr <hey@djdev.me>
…ity-20261028

Pick up #229's restored DRM module owner (6c66b41) through #244. No conflicts.

Signed-off-by: DjDeveloperr <hey@djdev.me>
DjDeveloperr added a commit that referenced this pull request Oct 29, 2026
…se-light-20261028

Pick up #229's restored DRM module owner (6c66b41) through #244 and #270. No conflicts.

Signed-off-by: DjDeveloperr <hey@djdev.me>
@DjDeveloperr
DjDeveloperr changed the base branch from neo/g17-aurora-merged-20261027 to integration/aurora October 29, 2026 03:11
@DjDeveloperr

Copy link
Copy Markdown
Collaborator Author

Retargeted to integration/aurora: its base, #244, has merged. The diff now shows only this PR's three commits. #271 stays stacked on this branch.

Bring the branch up to date with integration/aurora at 7e4fc9f, now that its
base, #244, has merged. No conflicts.

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

@scottjones scottjones left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does what it says, and we found nothing that hurts on its own. Both things it was stacked on are in: #229 and #244 are ancestors of integration/aurora, so it needs nothing more from them, and it merges clean onto 8970439 and 919b433. The "stacked on #244" in the title and the first paragraph of the body are out of date now.

We checked the "no floor, no behaviour" claim. Nothing in clpc.c's sampling reads the input, only the debugfs line does, and no device tree at this head has apple,clpc. So apple_clpc_gpu_get() hands back NULL and every report returns straight away. What's left is one small allocation in the T8140 CLPC's probe, a host_gpu: debugfs line that stays at 0, and effort_full cleared at Firmware drop (g17/mod.rs:651), after both processors have stopped. Other SoCs get no input, and G15 never calls this. The shipped config resolves to CLPC built in and asahi a module, as the body says.

Against aurora-silicon#563's tree the cut matches the Scope section: no wake in set_active, no T6041, no last_submission_ns. The G17 call sites are the same.

One thing to settle before #271 counts on it. sequence counts reports, not submissions, and the two differ, which matters when #271 sets its threshold at 2 per sample:

  • Device-mutex compute isn't reported when effort is already full. ComputeHost::note_submission (g17/runtime.rs:1405) only calls apply_shared_effort, which reports just on an effort change. compute_direct also returns before it counts anything for packets with input sources or a context that has seen render (runtime.rs:1790, the count is at :1804). So the body's "every submission, with or without the device mutex" isn't quite true. Compute in a render context mostly goes uncounted.
  • A render that tries the direct path and falls back reports twice, at port.rs:459 and mod.rs:698. A cold one reports three times with the effort change at mod.rs:719.
  • An idle clear reports twice with no submission (mod.rs:736, then :719 through apply_effort(0)).

The compute gap is in aurora-silicon too (same note_submission at its runtime.rs:1405), and #271's comment at clpc.c:443 calls this "every submission the GPU driver published". We haven't measured how much it moves the dense floor. Reporting from ComputeHost is one line, and either that or a note that #271 knowingly counts reports would do. We don't think it should hold this PR up on its own.

Smaller things, all of which only bite once #271 adds the DT link:

  • With apple,clpc present, DRM_ASAHI=y and APPLE_CLPC=m gets the stub in clpc.h and -ENODEV, so no GPU. Kconfig allows that today. Not the shipped config, but depends on APPLE_CLPC || !APPLE_CLPC on DRM_ASAHI would close it.
  • apple_clpc_gpu_get() runs after Bridge::enable (mod.rs:1327 vs :1338), so a defer now unwinds a bridge it just enabled and retries the UAT and coprocessor setup. Until now only ENOMEM reached that path. Taking the input at the top of boot() avoids the question.
  • A linked CLPC that never binds defers the GPU forever and logs nothing (clpc.c:215, :230). A second holder of the input gets -EPROBE_DEFER too, through the refcount check at clpc.c:223. A dev_err_probe() would make either one findable.

Also, #271 no longer applies once this lands. It conflicts with #263 in clpc.c (apple_clpc_sample), and its commit message says this tree doesn't have the floor release counters, which it now does. That rebase should keep the counting.

The new KUnit suite isn't in aurora.kunitconfig, as you noted, so CI doesn't run it. We'd add it as a follow-up.

We read this and checked merges but didn't build it. We'd like a Neo boot on this head showing the input stays at 0 before it merges.

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