[RFC] accel/rocket: DVFS on RK3588 - a hardware constraint, and some numbers
Jonas Karlman
jonas at kwiboo.se
Wed Aug 19 02:40:08 PDT 2026
Hi Igor,
On 8/19/2026 7:52 AM, Igor Paunovic wrote:
> Hi Jonas,
>
> On 8/18/2026 2:30 PM, Jonas Karlman wrote:
>> Looking closer at my old commits, it was the PCLK_GPU_ROOT that was
>> needed for e.g. RK3576 and RK3528. This clock is not described in RK3588
>> clock tree so it never gets disabled by Linux clock framework.
>>
>> I suspect similarly one of the NPU root clocks is what drives the NPU
>> PVTPLL and thus always must be kept enabled when PVTPLL mode is used.
>
> Thank you - the PCLK_GPU_ROOT observation was the missing piece. I went
> through the firmware my board actually runs and can now name the clock
> for the NPU case.
>
> First a correction to what I told Nicolas earlier: my BL31 is not the
> vendor blob. The boot banner reports v2.12.0-9-gd5c68fd92, which is the
> edk2-rk3588 project's TF-A branch: upstream v2.12.0 plus nine feature
> commits (SCMI voltage domain, eMMC clock, TRNG, ...). The only one of
> those touching rk3588_clk.c adds an eMMC clock; the NPU set_rate/PVTPLL
> path is unmodified mainline v2.12. So Nicolas and I are effectively
> running the same clock code, and the firmware-difference caveat from my
> earlier mail mostly evaporates.
>
> What clk_npu_set_rate() in plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c
> does:
>
> - The rate table gives every OPP from 300 MHz up a ring length > 0, so
> they all take the PVTPLL path; 200 MHz has length 0 and takes the
> normal GPLL divider path. The 200 MHz suspend rate we both converged
> on is therefore safe by construction on this SoC.
>
> - For a PVTPLL rate the firmware programs ring_sel/length/calibration
> (cal cnt = 24, T = 1 us, i.e. a 24 MHz reference) into NPU GRF at
> 0xfd5a2000 (NPU_PVTPLL_CON0..2), and only then flips the mux in CRU
> CLKSEL_CON(74) to the PVTPLL path.
>
> The Linux side is where the NPU differs from your GPU case: the NPU
> root clocks are fully described in clk-rk3588.c. pclk_npu_root is a
> gateable composite (CLKGATE_CON(29) bit 4) and NPU GRF hangs off it
> (pclk_npu_grf, CLK_IGNORE_UNUSED). In the mainline DT only core 0
> (fdab0000) requests PCLK_NPU_ROOT as its "pclk"; cores 1/2 only hold
> their aclk/hclk. So whenever core 0 is runtime-suspended, pclk_npu_root
> has no user left and gets gated.
>
> An SCMI set_rate to a PVTPLL rate issued in that state programs a GRF
> whose bus clock is off, while the mux write still lands because the CRU
> is always clocked - leaving clk_npu_dsu0 parked on a ring that was
> never configured. That matches the empirical failure in my RFC exactly:
> the sysfs min_freq write while suspended, followed by the power-domain
> power-on ack timeout. (I have not put a scope on the APB bus, so "the
> GRF write cannot land" is inferred from the failure signature plus the
> gate state, not observed directly.)
Ideally the SCMI firmware code should probably be updated to ensure any
required root clock is ungated, and possible also hide some related
clocks from OS. I am not even sure this is feasible option and this may
diverge too much from vendor blobs and may not be backward compatible.
>
> For the series this reinforces the hold-all guard: resuming all cores -
> core 0 in particular - around every rate change keeps pclk_npu_root
> enabled for the duration of the SCMI call, closing the window for the
> sysfs, governor and cooling paths alike. Your .config_clks() +
> pm_runtime_suspended() check covers the OPP-initiated paths; I will
> reference it and your branch in the cover letter.
I played around with Nicolas patches and created a more updated
config_clks() variant that tries to use the clocks configured for opp
instead of keeping track of the clock, see [2]. Have not done any
runtime testing of that, but wanted to share the link anyway :-)
If I remember correctly for the GPU path on RK3576, keeping the 'bus'
clock enabled at all times helped ensure any root clock was enabled
while GRF is accessed. I cannot remember that I had any issues with GPU
GRF access for PD and sysfs governor paths. The config_clks() helped
ensure set_rate never was called during GPU probe or when governor was
changed. Maybe I missed testing some other paths :-)
[2] https://github.com/Kwiboo/linux-rockchip/commits/next-20260803-rk-hdmi-v6/
>
> One open point where your GPU experience may help: besides the GRF
> programming interface, do you know whether the ring/monitor logic also
> depends on hclk_npu_root, or is the 24 MHz calibration reference
> (xin24m, always on) the only other input? If you never had to find out,
> I will determine it empirically by holding only pclk and cycling rates.
I do not know, and never looked too deep into it, with the root clk
enabled everything seemed to work great, so I was happy enough with that
and just moved on to next thing :-)
Regards,
Jonas
>
> Regards,
> Igor
More information about the Linux-rockchip
mailing list