[RFC] accel/rocket: DVFS on RK3588 - a hardware constraint, and some numbers

Igor Paunovic royalnet026 at gmail.com
Wed Aug 19 05:59:30 PDT 2026


Hi Jonas,

I promised to determine empirically which clock the NPU PVTPLL needs.
I ran that today. The answer is not what either of us expected, and it
comes with two corrections to my previous mail, so those first.

Correction 1: I wrote that only core 0 requests PCLK_NPU_ROOT in the
mainline DT. That is wrong - all three rknn-core nodes request it as
their "pclk" (my grep had truncated the clocks list; verified since in
the tree and in the live FDT). The hazard window is unchanged in
practice - the gate still closes whenever all three cores are
runtime-suspended, which is the normal idle state - but the sentence
as I wrote it was false.

Correction 2: my inferred failure mechanism ("the GRF write cannot
land, the mux still switches, the ring is left unconfigured and the
failure appears later as a power-on ack timeout") understated reality
considerably. Measured today:

Test module, on the same v2.12 firmware discussed earlier: acquire the
clocks via the core DT node, verify all three cores runtime-suspended,
then issue one clk_set_rate(scmi npu clk, 600 MHz - a PVTPLL-path
rate). Serial console at loglevel 8, captured by a recorder on a
second machine, so the last lines survive whatever happens. Three
arms, one variable:

  held during set_rate          outcome
  pclk_npu_root                 SoC resets, U-Boot 0.58 s after the call
  pclk + hclk (the PD pair)     identical, 0.58 s
  nothing (control)             identical, 0.58 s

No oops, no SError trace, nothing on the console after the set_rate
marker in any arm - the SoC dies at firmware level and the reset
latency is constant to the millisecond across all three. Bus clocks
are simply irrelevant to this failure: my open question ("does the
ring also need hclk_npu_root?") turns out to be the wrong question.
No root clock makes a domain-off set_rate safe.

The explanation most consistent with the data is that the NPU GRF (or
the PVTPLL block behind it) sits inside the NPU power island, so the
EL3 write to 0xfd5a2000 with the island off is fatal regardless of any
bus clock state. I cannot rule out that the firmware dies elsewhere in
that path, but the clock-independence is measured, not inferred.

The counterpart run closes the loop: same module, same set_rate to a
PVTPLL rate (1 GHz), with the cores resumed first - completes cleanly,
and the GRF readback then matches the firmware table exactly (ring
length 12 for 1 GHz in CON0_H, cal_cnt 0x18 in CON1, 0x40000 gating
interval in CON2). So the sequence we discussed is confirmed live in
the registers, and the domain state is the single discriminating
variable.

For the series the consequence is now sharp: every path that can issue
an SCMI set_rate - governor, sysfs, cooling, OPP init - must guarantee
the domain is powered first. The hold-all guard stays ordered before
the devfreq patch, and your pm_runtime_suspended() check in
config_clks() guards the OPP-initiated paths for exactly the same
reason. On mainline as-is the NPU exposure is theoretical only because
nothing scales the clock yet.

One small ask: we tried to read a ring frequency counter in the NPU
GRF (candidate offset +0x24) to publish measured ring frequency vs
voltage; it reads zero with the ring demonstrably running, so the
candidate is wrong. If you happen to know the OSC counter offset in
the GPU GRF from your experiments, the pointer would save a TRM dig -
if not, no matter.

Regards,
Igor



More information about the Linux-rockchip mailing list