Skip to content

soc: apple: clpc: raise the T8140 fabric floor for GPU work - #226

Merged
maralcbr merged 9 commits into
integration/aurorafrom
neo/t8140-clpc-fabric-floor-20261025
Oct 26, 2026
Merged

maralcbr merged 9 commits into
integration/aurorafrom
neo/t8140-clpc-fabric-floor-20261025

Conversation

@DjDeveloperr

@DjDeveloperr DjDeveloperr commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

On Neo (T8140) the CLPC table never raised the SoC fabric. Busy CPU clusters only lifted the DCS, and graphics load lifted nothing. The GPU firmware takes up and completes every command over the fabric, so at fabric state 0 its per-command work ran slowly. This was the fixed firmware cost behind most of the light-workload gap to macOS, which holds the fabric at its top states while such work streams.

Fix

Set gpu_demand for T8140, as T8132 already does, and give the fabric a top-quartile state. While GPU work streams, the floor is DCS 4 and fabric 3:

  • Streaming: graphics counts as streaming once it has stayed powered for 64 ms without a break. Frame-paced loads such as video playback power it up and down with every frame and don't count.
  • Heavy rendering: while the PMP votes the DCS below the floor's state, which it does under sustained heavy rendering, the floor is released for 1 s.

An idle desktop leaves the fabric at state 0 (checked on Neo). The in-tree t8140.dtsi already provides apple,gpu-power-state. The power, thermal and light-row comparison is in the PR discussion.

The change is data-only: no type changes. The rebuilt core's BTF is byte-identical to the previous one.

Measurements (Neo, same GPU driver and Mesa; gpubench µs per submission)

Workload fabric 0 (before) this change macOS
compute, depth 1 158.9 108.2 111.3
compute, depth 64 19.3 14.7 14.0
compute, 16 processes 25.6 17.9 23.7
render, depth 1 149.9 137.3 239.0
render, depth 32 42.7 29.7 26.8
render, 8 queues 58.2 41.0 35.7
queue-to-queue handoff 42.2 31.9 19.5

Other measurements:

  • With this change, results match a forced fabric-3 vote within run-to-run noise, so the CLPC sampling adds no measurable latency.
  • Fabric 2 recovers about 80% of the gain.
  • A forced DCS 4 adds nothing over the CPU-driven DCS vote.
  • Heavy ALU work is unchanged.

Testing on Neo

  • Booted the rebuilt perf core with the existing modules and initramfs.
  • The floor follows GPU activity and is released at idle.
  • 10k cross-queue order/data iterations, slow-producer pressure and mixed stress passed.
  • No new GPU faults; the desktop stayed alive.

Commits

  1. dt-bindings: accept apple,t8132-clpc for the PMC voter child.
  2. Eryk Wieliczko's "retain qualified T8132 memory floors", carried unchanged. It adds the gpu_demand mechanism (sampling the graphics power state) and the T8132 table that uses it.
  3. keep CPU floors without a graphics power state. apple,gpu-power-state is optional in the binding. A controller that follows GPU demand now falls back to CPU-driven floors when the property is absent, instead of failing probe. Probe errors in that block go through dev_err_probe().
  4. raise the T8140 fabric floor for GPU work.
  5. count graphics power state read failures. A failed read still counts as powered, but is counted in the debugfs status and warned about once.
  6. hold the T8140 GPU floor only while GPU work streams.
  7. release the T8140 GPU floor while the PMP limits the DCS.

Base

The measurements above were taken on Neo with the 7.3 kernel. This branch builds cleanly on 7.2.11 with the Neo config; a Neo boot test of the 7.2.11 build follows.

@greptile-apps

greptile-apps Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The change affects CLPC performance floors on T8132 and T8140 devices.

Preserve CPU-only operation when apple,gpu-power-state is absent before merging.

Findings

  1. P1 Optional property now blocks probe ▶
  2. P2 New compatible lacks a binding ▶

Summary

Adds GPU power-state sampling to clpc.c and raises T8140 memory and fabric floors during GPU activity.

  • GPU activity now raises the CLPC floor on both rails.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  CPU[CPU load and frequency] --> Table[Per-chip floor table]
  GPU[GPU actual power state] --> Active{Powered or read failed?}
  Active -->|Yes| Top[Request top table states]
  Table --> Demand[Combine rail demand]
  Top --> Demand
  Demand --> Hold[Keep demand briefly after activity stops]
  Hold --> PMC[Update PMC floors]
Loading

Reviews (1) · Last reviewed commit: "soc: apple: clpc: raise the T8140 fabric..." · Reviewed by Greptile

Comment thread drivers/soc/apple/clpc.c Outdated
Comment on lines +363 to +364
if (!gpu)
return dev_err_probe(dev, -EINVAL, "missing graphics power state\n");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Optional property now blocks probe

apple_clpc_probe() now rejects a missing apple,gpu-power-state, but the existing binding makes that property optional. A valid T8140 device tree without it previously provided CPU-driven floors; it now loses the entire driver, not just GPU demand. Keep CPU-only operation when the property is absent.

Knowledge Base Used: ARM64 and Aurora platform support

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 791fa7c: the property is optional again. Without it the controller leaves the GPU out and CPU demand alone sets the floors, instead of failing probe.

Comment thread drivers/soc/apple/clpc.c Resolved
@DjDeveloperr
DjDeveloperr force-pushed the neo/t8140-clpc-fabric-floor-20261025 branch from f3451cb to 452aea0 Compare October 25, 2026 22:31
DjDeveloperr and others added 2 commits October 25, 2026 18:33
The T8132 host performance controller is a PMC voter agent like the T8140
one, with its own CPU and GPU floors. Accept its compatible for the voter
child node.

Signed-off-by: DjDeveloperr <hey@djdev.me>
Select the known active memory floors for CPU and GPU demand without
inventing intermediate frequency-to-memory mappings.

Source-commit: 551311604a7a12b73eab15d1d60b6c92c68386b7
Source-snapshot: 9ffa1fbed1e052d9706ad3e13c8663bc8ffe3d8d
Assisted-by: LLM
(cherry picked from commit c26dfe7)
Signed-off-by: DjDeveloperr <hey@djdev.me>
@DjDeveloperr
DjDeveloperr force-pushed the neo/t8140-clpc-fabric-floor-20261025 branch from 452aea0 to 1e54678 Compare October 25, 2026 22:34

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Greptile has paused reviews on this repository — it used its 100 free open-source review credits for this billing period. Reviews resume automatically on November 21. To continue before then, an organization admin can keep reviews running past the free credits — those bill as normal usage.

@chriskearney chriskearney left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Source review at 1e5467868c874c3a6f37ff3592c11397725f6621: the optional-phandle fallback preserves CPU-only operation, and suspend/remove still cancel sampling and restore the saved floors. I found no correctness blocker in those changed paths.

One release qualification gap: the PMC cooling path caps DCS, not the SoC fabric vote. This patch can therefore keep fabric state 3 requested during thermal pressure. The 32 ms hold also means repeated GPU activity during scrolling/video can retain the high floors between frames; static idle alone does not measure that cost.

Please include a same-build Neo/base comparison for sustained GPU temperatures/throttling and light-use power before release. This is an unmeasured side-effect risk, not a reproduced thermal failure. The T8132 table is dormant without a matching DT node, and an M3 boot will not qualify these new floor settings.

Validation here: source review of CLPC, PMC cooling and the binding/DT changes. CI is green; I have not independently built or boot-tested this head.

@maralcbr maralcbr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed at 1e54678 (source only; no build or boot on my side).

The code looks right: the ps_gfx test matches PS_ACTUAL/PS_ACTIVE in pmgr-pwrstate, the offset and node lifetime are handled correctly, and a missing apple,gpu-power-state now falls back to CPU-only floors.

Gate before merge: battery. While the GPU power state is on, every rail goes to its top state (DCS 4, fabric 3). The 32 ms HOLD_MS can bridge the gaps between frames, so video playback, scrolling or a light browse may hold the floor the whole time, not just GPU-bound work. The measurements here are submission latency plus "idle desktop stays at fabric 0". Could you add, on Neo with and without this change:

  • package/system watts and floor residency (status in debugfs) during 1080p video playback and a few minutes of light browsing;
  • the same for a CPU-only load that reaches the top quartile, since that now raises the fabric too.

Small things:

  • A failed regmap_read forces the top floors every sample with no trace; update_errors only counts PMC update failures. Keep the conservative fallback but count or warn once on read failures.
  • Probe errors from the new block would read better through dev_err_probe().
  • While a GPU-held vote exists, sampling uses the non-deferrable work every 4 ms. That's probably fine; worth keeping in mind for the power numbers.
  • apple,t8132-clpc has no DT consumer yet, so the T8132 table is inert here. Fine, just confirming that's intended.

Also, the PR body says the 7.2.11 Neo boot test is still to come. Please post that, ideally as one run on the exact base with #227 and #228 applied too: #228 changes cluster utilisation, #227 changes how DVFS follows it, and this PR samples both.

The binding makes apple,gpu-power-state optional, but a controller whose
table follows GPU demand refused to probe without it, so a device tree
that omits the property lost its CPU-driven floors as well. Without the
property, leave the GPU out and let CPU demand alone set the floors.

Report the remaining errors in that block through dev_err_probe().

Signed-off-by: DjDeveloperr <hey@djdev.me>
The T8140 table never raised the SoC fabric: busy CPU clusters only
lifted the DCS, and graphics load lifted nothing. The GPU firmware takes
up and completes every command over the fabric, so with the fabric at
state 0 each command's firmware work ran slowly, and light GPU work fell
well behind macOS, which holds the fabric at its top states while such
work streams.

Hold DCS 4 and fabric 3 while the graphics power state is on, as T8132
already does with its own top states. The firmware powers the GPU off
when it is idle, so the floor follows GPU activity and drops HOLD_MS
after the last work; an idle desktop leaves the fabric at state 0. A
cluster in its top frequency quartile now also raises the fabric.

Measured on Neo against the same driver and userspace (gpubench, us per
submission, fabric 0 -> 3):

  compute, depth 1          158.9 -> 108.2
  compute, depth 64          19.3 ->  14.7
  compute, 16 processes      25.6 ->  17.9
  render, depth 1           149.9 -> 137.3
  render, depth 32           42.7 ->  29.7
  render, 8 queues           58.2 ->  41.0
  queue-to-queue handoff     42.2 ->  31.9

Fabric 2 recovers about 80% of that; a forced DCS 4 adds nothing over
the CPU-driven DCS vote. Heavy ALU work is unchanged.

(cherry picked from commit d69f14f)
Signed-off-by: DjDeveloperr <hey@djdev.me>
A failed read of the graphics power state holds the GPU floor, so that a
running graphics consumer is never starved, but nothing recorded that it
happened: update_errors counts only PMC floor updates. Count the failures
in debugfs and warn once, keeping the conservative fallback.

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

Copy link
Copy Markdown
Collaborator Author

Thanks both. Code changes are in 0a51fbe:

  • Read failures. A failed regmap_read of the graphics power state still holds the GPU floor (the conservative fallback), but now increments gpu read errors in the debugfs status line and warns once (new commit "count graphics power state read failures").
  • Probe errors. The two errors in the new probe block go through dev_err_probe() (folded into the CPU-floor fallback commit).
  • T8132. Yes, the table is intentionally inert here: no in-tree DT carries apple,t8132-clpc yet. It comes with Eryk's commit and is documented by the binding commit.
  • Sampling cadence. Noted. While a GPU-held vote exists, sampling uses the non-deferrable 4 ms work. I'll report it alongside the power numbers.

On the release gates (battery and thermal), I agree these are unmeasured side effects so far. A same-build comparison on Neo is under way, run as one 7.2.11 boot with #226, #227 and #228 applied, plus a base without them where you asked for a comparison. It covers:

I'll post the results here. If the fabric hold costs measurably under thermal pressure or between frames, I'll bound it (for example, yield the fabric floor while the PMC DCS cooling state is non-zero) rather than ship it as is.

@maralcbr maralcbr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Follow-up at 0a51fbe (source only).

Thanks, the interdiff covers everything from my earlier review: read failures are counted in status and warned once while keeping the conservative floor, and the probe errors go through dev_err_probe(). No further code comments.

From my side this is ready to merge once the combined 7.2.11 Neo run lands with the power and floor-residency numbers (1080p video, light browsing, CPU-only top quartile) and the thermal comparison. Your plan to bound the fabric hold under DCS cooling pressure, if it turns out to cost something, sounds right.

@chriskearney

Copy link
Copy Markdown

At 0a51fbe5e63f915f22d34df347b4850d7bda122c, the new GPU-read error counter and warn-once address the observability part of my earlier feedback while retaining the conservative floor on a read error. The missing-phandle path still keeps CPU-only demand; a present invalid provider remains an explicit probe failure.

The native aarch64 build completed with the same frozen M3 regression configuration as a separate integration control. I independently verified the actual artifact hash, embedded config and AArch64 Rust Asahi module. CLPC/PMC/AIC are built in, both native M3 GPU backends are enabled, and the resolved configuration differs from control only in the release label. The built Image contains the newly added read-error warning/counter strings; control does not. Build b1025-170652-6ff7, release 7.2.11-lab0a51fbe5-cf4c, artifact SHA256 1ad37c2f478eccca0d0eedd56d3af8fc0f2fb9d4f4904509aa008103ce8ddf43.

This is build/source coverage, with no new physical boot result. M3 cannot exercise the new T8140 fabric-floor behavior or establish its performance, sustained thermals or light-use power. Those Neo-specific measurements remain distinct from this regression build; this is not release approval.

@DjDeveloperr

Copy link
Copy Markdown
Collaborator Author

The combined 7.2.11 Neo run is done.

Setup

leg system W, floor / none DCS vote residency, floor / none fabric vote, floor / none max °C, floor / none
idle, 40 s 3.593 / 3.597 state 0: 98% / 97% 0: 100% / 0: 100% 49.5 / 50.7
1080p30 H.264 in Firefox, 60 s 5.264 / 4.887 (+0.38 W) state 4: 73% / 15% 3: 100% / 0: 100% 69.8 / 67.0
light browsing, 60 s 4.171 / 4.011 (+0.16 W) state 4: 24% / 2% 3: 48% / 0: 100% 52.6 / 51.4
single-thread CPU, top quartile, 40 s 7.008 / 6.867 state 4: 100% / 100% 3: 100% / 0: 100% 83.2 / 82.6
render.heavy d4, 90 s sustained 11.544 / 11.403 state 4: 100% / mostly 0 3: 100% / 0: 100% 89.9 / 88.6
  • Idle: no cost.
  • Video: the floor is held for the whole leg, because WebRender and the compositor keep graphics powered. That is where it costs most, +0.38 W.
  • Sustained GPU: over the 90 s, render.heavy d4 went from 567.6 to 665.6 µs per submit with the floor, against 564.0 to 654.1 without. The floor ends 1.8% slower and 1.3 °C hotter. These are single runs, but idle matched within 4 mW.

The video and sustained-GPU results are the costs the bounding we discussed should remove. Next I'll look at holding the floor for GPU demand rather than for graphics being powered, and dropping it under sustained heavy load and DCS cooling pressure.

@maralcbr maralcbr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the combined run at 0a51fbe. It answers the question clearly.

The floor is free at idle but costs +0.38 W (about 8%) on 1080p video, where it is held for the whole leg, and +0.16 W on light browsing. Sustained GPU is no better with it (end-of-run submit time 1.8% slower, 1.3 °C hotter; single runs, so indicative only). Holding it whenever graphics is powered is too broad, so I'd hold this as is and wait for the rework you described: hold the floor for GPU demand rather than graphics being powered, and drop it under sustained heavy load or DCS cooling pressure.

When that lands, the same table (idle, video, light browsing, CPU top quartile, sustained GPU), plus the light-submit latency rows, would be the evidence to merge on. Video and light browsing should end up close to the no-floor numbers.

@DjDeveloperr

Copy link
Copy Markdown
Collaborator Author

Agreed. I'll rework the floor so it is held for GPU demand rather than whenever graphics is powered, and released under sustained heavy load or DCS cooling pressure. Then I'll rerun the same table on the same base, plus the light-submit latency rows, and post here when it's ready.

The T8140 GPU floor was held whenever graphics was powered. On J700 that
costs 0.38 W (about 8%) during 1080p video playback in Firefox and
0.16 W during light browsing, where the floor gains nothing.

The firmware powers graphics off a few milliseconds after the GPU idles.
Sampled every millisecond, 1080p video powered graphics for 56% of the
time and light browsing for 34%, but never for more than 63 ms at a
time, while light compute and render submission streams kept it powered
throughout.

Count graphics as GPU demand only once it has stayed powered for 64 ms,
with no sample finding it off and no gap in sampling long enough to have
missed that, and sample on time while it is powered. A failed read still
counts as powered. The debugfs status shows how long graphics has been
powered.

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

Under sustained heavy rendering on J700, the GPU floor ended 1.8%
slower and 1.3 C hotter than no floor over 90 s, for 0.14 W more.

The PMP, voter agent 0, votes the DCS to its top state for streams of
light GPU submissions: it did for every millisecond sample of light
compute and render streams. Under heavy rendering it lowers the DCS,
to state 3 for 62% of the samples, to stay within the GPU's power
budget. The floor then only overrides that and takes headroom from the
GPU. macOS also lets the fabric drop for heavy GPU work.

While GPU work streams, read the PMP's floor word. When it votes the
DCS below the GPU floor's state, release the GPU floor and keep it
released for 1 s after the PMP last did so. The debugfs status shows
when that was.

Measured on J700 with both changes, one boot each on battery, against
no GPU floor and the floor held whenever graphics is powered:

                               no floor   powered   this
  1080p video, W                 4.903     5.151    4.975
  light browsing, W              3.971     4.085    3.970
  render.heavy d4 at 90 s, us    659.5     671.1    656.8
  compute.light d1, us           373.7     320.5    319.3
  render.light d2, us             87.2      65.6     66.6

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

Copy link
Copy Markdown
Collaborator Author

The rework is pushed as two commits on top of 0a51fbe:

  • e011255, "hold the T8140 GPU floor only while GPU work streams". I sampled the graphics power state every millisecond on Neo:
    • 1080p video kept graphics powered 56% of the time and light browsing 34%, but never for more than 63 ms at a time. The firmware powers graphics off a few milliseconds after the GPU idles, so frame-paced loads power it up and down with every frame.
    • Light compute and render submission streams kept it powered throughout.
    • So graphics now counts as GPU demand only after staying powered for 64 ms, with no sample finding it off and no sampling gap long enough to have missed that. CLPC samples on time while graphics is powered.
  • 6a48de3, "release the T8140 GPU floor while the PMP limits the DCS". I read each PMC agent's floor every millisecond:
    • The GPU agent never votes.
    • The PMP (agent 0) votes the DCS to state 4 for streams of light submissions: in every sample.
    • Under sustained heavy rendering, the PMP votes state 3 in 62% of samples, holding the GPU to its power budget. The floor then only overrode that.
    • So while GPU work streams and the PMP votes the DCS below the floor's state, the floor is released, and it stays released for 1 s after the PMP last did so.

J700 maps no thermal zone to the DCS cooling device (see the comment in t8140-j700.dts), so DCS cooling pressure never occurs there. The PMP's own DCS vote is the signal that does.

Same table, same base (19f4965 + #226 + #227 979d4f1 + #228). One boot per kernel, all in one session, on battery. "No floor" reverts b0d4633, "powered" is 0a51fbe, and "rework" is this head.

leg no floor powered rework fabric vote residency (no floor / powered / rework)
idle, 40 s 3.569 W 3.505 W 3.541 W 0: 100% / 100% / 100%
1080p video, 60 s 4.903 W 5.151 W 4.975 W 3: 0% / 100% / 21%
light browsing, 60 s 3.971 W 4.085 W 3.970 W 3: 0% / 51% / 2%
single-thread CPU top quartile, 40 s 6.738 W 6.955 W 6.948 W 3: 0% / 100% / 100% (the CPU table's top-quartile rule, unchanged)
render.heavy d4, 90 s 11.283 W 11.425 W 11.347 W 3: 0% / 100% / 5%
render.heavy d4 at the end of 90 s 659.5 µs, 88.8 °C 671.1 µs, 90.3 °C 656.8 µs, 88.7 °C

Light-submit rows, µs per submit, median of three rounds. This base has integration/aurora's own asahi driver, and the system level cache is off until #235.

row no floor powered rework
compute.light d1 373.7 320.5 319.3
compute.light d2 190.7 166.0 165.8
render.light d2 87.2 65.6 66.6
render.light d32 67.8 61.4 61.8

Summary:

  • Video: the floor's cost drops from +0.25 W to +0.07 W.
  • Light browsing: the cost is gone.
  • Sustained heavy rendering: matches no floor in power, end-of-run speed and temperature.
  • Light submissions: keep the floor's 13–25% gain. render.light d2 is 1.5% above the powered floor, with overlapping round ranges (66.5–67.2 against 65.6–66.7).

The rest of video's remaining 21% fabric residency is runs where graphics stayed powered for at least 64 ms. The single-thread CPU leg is the CPU table's top-quartile rule, which this rework doesn't change.

@maralcbr maralcbr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed at 6a48de3 (source only), with your table from the same base.

This is a big improvement. Gating the floor on 64 ms of continuous graphics power, and backing off while the PMP lowers the DCS, takes video from +0.25 W to +0.07 W, removes the browsing cost, brings heavy rendering close to no floor (+64 mW in this run), and keeps the 13–25% light-submit gains. Two things before merge, then some data.

1. The CPU-side fabric raise. b0d4633 also changed the T8140 CPU table: a cluster busy in its top frequency quartile now raises the fabric to 3 (SOC map {0,0,0,0} → {0,0,0,3}). That costs +0.21 W on the single-thread CPU leg (6.738 → 6.948 W), and no CPU benefit has been measured. Zeroing the table isn't the fix, because the GPU floor reads the same top entry (map[rail][APPLE_CLPC_LEVELS - 1]). Could you split the GPU target from the CPU map, then either show a CPU benefit (a memory-bound workload, completion time plus energy) or leave the CPU map's fabric at 0 as before?

2. T8132 scope. The new streaming gate and back-off sit on the shared gpu_pmgr path, so they also apply to apple_clpc_hw_t8132, which has gpu_demand from Eryk's carried commit. That table has no DT consumer yet, so nothing changes today, but it quietly changes behaviour that was qualified separately: bursts under 64 ms would lose the T8132 floor. Please gate the sustain/back-off logic per SoC (T8140 only) unless it's been measured on T8132.

Data, not blocking:

  • Short off gaps. Samples land every 4 ms (jiffies-rounded), and the gap reset only fires beyond about 8 ms, so off intervals shorter than the sample period go unseen and count as continuously powered. 1080p30 came out fine at 21% residency, but 60 fps or 4K60 video, an external display (mode and refresh), and the CONFIG_HZ you ran would show whether higher frame rates pin the floor again.
  • Mixed load. CPU requests survive the back-off, and release goes through the existing 32 ms hold, so a CPU-plus-GPU load can still hold DCS 4 and fabric 3. One mixed leg (e.g. a heavy render with a busy P-core) would cover it.
  • Noise. With one boot per kernel, video's remaining +0.07 W is about the same size as the 64 mW idle spread between kernels, so it's "small", not yet "measured".

Minor: debugfs prints pmp limited 0 ms ago both for "never" and "just now". And a failed read is taken as powered, but it still goes through the sustain gate and back-off, so the "cannot starve" wording in the comment overstates it a little.

The GPU floor used the top entry of each rail's CPU table, so raising
the fabric for GPU work also raised it for a CPU cluster in its top
frequency quartile. On J700 that costs 0.21 W during a single-thread
load (6.738 -> 6.948 W), and no CPU benefit has been measured.

Give each SoC a GPU target separate from its CPU table. T8140 keeps DCS 4
and fabric 3 for streaming GPU work, and its CPU table no longer touches
the fabric, as before the GPU floor. T8132's GPU target is its CPU
table's top entry, so it is unchanged.

Signed-off-by: DjDeveloperr <hey@djdev.me>
The 64 ms streaming gate and the PMP back-off were measured on T8140 but
sat on the shared graphics path, so they also changed T8132. That SoC
had no DT consumer yet, but it would have lost its floor for bursts under
64 ms, against what was qualified there.

Make the time graphics must stay powered a per-SoC parameter: 64 ms on
T8140, and 0 on T8132, which keeps that SoC's floor whenever graphics is
powered, as before. The PMP back-off was already T8140 only.

The debugfs status now says "never" when the PMP has not limited the DCS,
rather than 0 ms ago. The comment no longer says a failed read cannot
starve a graphics consumer: a failed read counts as powered, so read
errors alone do not end a stream that is already under way.

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

Copy link
Copy Markdown
Collaborator Author

Both points addressed, plus the two minor ones:

  • b7db2f2, "give the GPU floor its own states". Each SoC now has a GPU target separate from its CPU table. On T8140 the GPU target stays DCS 4 / fabric 3. The CPU table's fabric is back to {0, 0, 0, 0}, as before the floor. I'm not claiming a CPU benefit, so a single-thread load costs what the "no floor" column measured (6.738 W, with the CPU fabric vote at 0 for the whole leg). T8132's GPU target is its CPU table's top entry, so it is unchanged. The GPU demand now combines with CPU demand through max() rather than replacing it, which gives the same result for both tables.
  • 682b924, "limit the GPU streaming gate to T8140". The time graphics must stay powered is now a per-SoC gpu_sustain_ms: 64 on T8140, 0 on T8132. Zero keeps T8132's floor whenever graphics is powered, as qualified. The PMP back-off was already T8140 only (pmp_backoff).
  • The debugfs status prints "pmp limited never" when the PMP hasn't limited the DCS.
  • The comment now says a failed read counts as powered, so read errors alone don't end a stream that is already under way. It no longer says that cannot starve a consumer.

Both build with W=1, and checkpatch --strict is clean. On T8140 the GPU paths behave exactly as in the table above, so I didn't re-measure.

On the data points: I'll add a 60 fps / 4K60 video leg, an external display, and a mixed heavy render with a busy P-core to the next run, with alternating boots so the remaining video cost can be called measured rather than small. Neo runs CONFIG_HZ=1000, so the jiffy rounding there is 1 ms.

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.

4 participants