* [PATCH v2] accel/rocket: request the core clocks by name
@ 2026-07-29 13:07 ` Igor Paunovic
0 siblings, 0 replies; 9+ messages in thread
From: Igor Paunovic @ 2026-07-29 13:07 UTC (permalink / raw)
To: Tomeu Vizoso
Cc: Oded Gabbay, dri-devel, linux-kernel, linux-rockchip, Jiaxing Hu,
Heiko Stuebner, Igor Paunovic
rocket_core_init() hands core->clks to devm_clk_bulk_get() without ever
setting the .id members. The rocket_core array is allocated with
devm_kcalloc() in rocket_device_init(), and rocket_probe() only fills in
.rdev, .dev and .index, so all four clk_bulk_data entries are requested
with a NULL con_id (unlike core->resets, whose ids are set a few lines
above).
clk_get(dev, NULL) ends up in of_clk_get_hw(np, 0, NULL), and
of_parse_clkspec() only consults "clock-names" when a name was passed,
so the index stays 0 for all four entries. Every entry therefore ends up
holding a handle to the *first* clock of the DT "clocks" property, i.e.
ACLK_NPUn. Nothing fails: probe succeeds and the driver believes it owns
four different clocks.
The consequence is that rocket_device_runtime_resume() prepares and
enables the AXI clock four times, while hclk, pclk and - most
importantly - the NPU compute clock ("npu", SCMI_CLK_NPU on RK3588) are
never prepared or enabled by this driver at all. The NPU still works
only because the Rockchip power-domain driver sets GENPD_FLAG_PM_CLK and
its attach_dev() callback walks the device node with of_clk_get() and
adds every clock to the pm_clk list, so genpd happens to keep the
remaining clocks running. The bug is therefore latent today, but it
means the driver holds no reference to the clock that actually feeds the
NPU, which stands in the way of any future frequency scaling
(OPP/devfreq) work.
Found on an Orange Pi 5 Plus (RK3588) by reading the live clock tree:
/sys/kernel/debug/clk/clk_summary shows four "fdab0000.npu" consumer
handles on aclk_npu0 (and likewise on aclk_npu1/aclk_npu2 for the other
two cores), while hclk_npu0, pclk_npu_root and scmi_clk_npu have no
"fdab0000.npu" consumer at all - their only consumers are the
"npu@fdab0000" handles created by the power-domain driver via
of_clk_get().
Set the ids explicitly, in the order mandated by the binding
(Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml):
aclk, hclk, npu, pclk. After the change the driver holds one handle per
distinct clock and clk_bulk_prepare_enable() covers all four.
Note that this is a user-visible tightening for out-of-tree DTs: the
old NULL-id requests resolved by index and succeeded no matter what
"clock-names" contained, while the named requests fail probe with
-ENOENT when one of the four names is missing. That is the right
outcome for in-tree users - the binding requires exactly these four
clock-names and rk3588-base.dtsi carries them on all three cores - but
a DT that relied on the permissive lookup goes from silently running on
the wrong clock handles to not probing at all, so record the change
here where git log will find it.
Fixes: ed98261b4168 ("accel/rocket: Add a new driver for Rockchip's NPU")
Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
Reviewed-by: Jiaxing Hu <gahing@gahingwoo.com>
---
v2:
- document that resolving by name is a behaviour change for DTs that
do not carry all four clock-names (Jiaxing Hu)
- collect Jiaxing's Reviewed-by
v1: https://lore.kernel.org/linux-rockchip/20260729092939.118779-1-royalnet026@gmail.com/
The same four id assignments are board-tested on RK3576 (ROCK 4D) as
part of Jiaxing's RK3576 enablement series (v2 6/8), so the change has
been exercised on two SoCs between us.
Verified on RK3588 (Orange Pi 5 Plus): after the change clk_summary
shows one consumer handle per clock instead of four handles on aclk, the
NPU still powers up and down cleanly through runtime PM, and a
MobileNetV1 inference run via the Teflon TFLite delegate produces
bit-identical output tensors to the unpatched driver.
drivers/accel/rocket/rocket_core.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
index b3b2fa9..5dd260b 100644
--- a/drivers/accel/rocket/rocket_core.c
+++ b/drivers/accel/rocket/rocket_core.c
@@ -28,6 +28,10 @@ int rocket_core_init(struct rocket_core *core)
if (err)
return dev_err_probe(dev, err, "failed to get resets for core %d\n", core->index);
+ core->clks[0].id = "aclk";
+ core->clks[1].id = "hclk";
+ core->clks[2].id = "npu";
+ core->clks[3].id = "pclk";
err = devm_clk_bulk_get(dev, ARRAY_SIZE(core->clks), core->clks);
if (err)
return dev_err_probe(dev, err, "failed to get clocks for core %d\n", core->index);
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2] accel/rocket: request the core clocks by name
@ 2026-07-29 13:07 ` Igor Paunovic
0 siblings, 0 replies; 9+ messages in thread
From: Igor Paunovic @ 2026-07-29 13:07 UTC (permalink / raw)
To: Tomeu Vizoso
Cc: Oded Gabbay, dri-devel, linux-kernel, linux-rockchip, Jiaxing Hu,
Heiko Stuebner, Igor Paunovic
rocket_core_init() hands core->clks to devm_clk_bulk_get() without ever
setting the .id members. The rocket_core array is allocated with
devm_kcalloc() in rocket_device_init(), and rocket_probe() only fills in
.rdev, .dev and .index, so all four clk_bulk_data entries are requested
with a NULL con_id (unlike core->resets, whose ids are set a few lines
above).
clk_get(dev, NULL) ends up in of_clk_get_hw(np, 0, NULL), and
of_parse_clkspec() only consults "clock-names" when a name was passed,
so the index stays 0 for all four entries. Every entry therefore ends up
holding a handle to the *first* clock of the DT "clocks" property, i.e.
ACLK_NPUn. Nothing fails: probe succeeds and the driver believes it owns
four different clocks.
The consequence is that rocket_device_runtime_resume() prepares and
enables the AXI clock four times, while hclk, pclk and - most
importantly - the NPU compute clock ("npu", SCMI_CLK_NPU on RK3588) are
never prepared or enabled by this driver at all. The NPU still works
only because the Rockchip power-domain driver sets GENPD_FLAG_PM_CLK and
its attach_dev() callback walks the device node with of_clk_get() and
adds every clock to the pm_clk list, so genpd happens to keep the
remaining clocks running. The bug is therefore latent today, but it
means the driver holds no reference to the clock that actually feeds the
NPU, which stands in the way of any future frequency scaling
(OPP/devfreq) work.
Found on an Orange Pi 5 Plus (RK3588) by reading the live clock tree:
/sys/kernel/debug/clk/clk_summary shows four "fdab0000.npu" consumer
handles on aclk_npu0 (and likewise on aclk_npu1/aclk_npu2 for the other
two cores), while hclk_npu0, pclk_npu_root and scmi_clk_npu have no
"fdab0000.npu" consumer at all - their only consumers are the
"npu@fdab0000" handles created by the power-domain driver via
of_clk_get().
Set the ids explicitly, in the order mandated by the binding
(Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml):
aclk, hclk, npu, pclk. After the change the driver holds one handle per
distinct clock and clk_bulk_prepare_enable() covers all four.
Note that this is a user-visible tightening for out-of-tree DTs: the
old NULL-id requests resolved by index and succeeded no matter what
"clock-names" contained, while the named requests fail probe with
-ENOENT when one of the four names is missing. That is the right
outcome for in-tree users - the binding requires exactly these four
clock-names and rk3588-base.dtsi carries them on all three cores - but
a DT that relied on the permissive lookup goes from silently running on
the wrong clock handles to not probing at all, so record the change
here where git log will find it.
Fixes: ed98261b4168 ("accel/rocket: Add a new driver for Rockchip's NPU")
Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
Reviewed-by: Jiaxing Hu <gahing@gahingwoo.com>
---
v2:
- document that resolving by name is a behaviour change for DTs that
do not carry all four clock-names (Jiaxing Hu)
- collect Jiaxing's Reviewed-by
v1: https://lore.kernel.org/linux-rockchip/20260729092939.118779-1-royalnet026@gmail.com/
The same four id assignments are board-tested on RK3576 (ROCK 4D) as
part of Jiaxing's RK3576 enablement series (v2 6/8), so the change has
been exercised on two SoCs between us.
Verified on RK3588 (Orange Pi 5 Plus): after the change clk_summary
shows one consumer handle per clock instead of four handles on aclk, the
NPU still powers up and down cleanly through runtime PM, and a
MobileNetV1 inference run via the Teflon TFLite delegate produces
bit-identical output tensors to the unpatched driver.
drivers/accel/rocket/rocket_core.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
index b3b2fa9..5dd260b 100644
--- a/drivers/accel/rocket/rocket_core.c
+++ b/drivers/accel/rocket/rocket_core.c
@@ -28,6 +28,10 @@ int rocket_core_init(struct rocket_core *core)
if (err)
return dev_err_probe(dev, err, "failed to get resets for core %d\n", core->index);
+ core->clks[0].id = "aclk";
+ core->clks[1].id = "hclk";
+ core->clks[2].id = "npu";
+ core->clks[3].id = "pclk";
err = devm_clk_bulk_get(dev, ARRAY_SIZE(core->clks), core->clks);
if (err)
return dev_err_probe(dev, err, "failed to get clocks for core %d\n", core->index);
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2] accel/rocket: request the core clocks by name
2026-07-29 13:07 ` Igor Paunovic
(?)
@ 2026-07-29 13:22 ` sashiko-bot
-1 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-07-29 13:22 UTC (permalink / raw)
To: Igor Paunovic; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [Critical] If `rocket_device_init` fails during the first core's probe, the global `rdev` pointer is left as an `ERR_PTR` rather than being reset to `NULL`, causing a kernel panic on subsequent probes.
- [High] The driver leaks the shared `rdev` and `rdev->cores` structures upon probe deferral or failure.
- [High] The driver incorrectly uses `rdev->num_cores` both as a count of active cores and as the boundary index, causing state corruption and resource leaks upon out-of-order unbind.
--
--- Patch [1]: [PATCH v2] accel/rocket: request the core clocks by name ---
commit 4687ac2abf99b6ec4120f9d98c0f4148fc2a6b97
Author: Igor Paunovic <royalnet026@gmail.com>
accel/rocket: request the core clocks by name
This commit fixes clock initialization by setting the proper names for the
"aclk", "hclk", "npu", and "pclk" clocks before requesting them. Previously,
all four clocks defaulted to index 0, which meant only the AXI clock was
controlled by the driver.
> diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
> index b3b2fa9ba645a..5dd260bacbff6 100644
> --- a/drivers/accel/rocket/rocket_core.c
> +++ b/drivers/accel/rocket/rocket_core.c
> @@ -28,6 +28,10 @@ int rocket_core_init(struct rocket_core *core)
> if (err)
> return dev_err_probe(dev, err, "failed to get resets for core %d\n", core->index);
>
> + core->clks[0].id = "aclk";
> + core->clks[1].id = "hclk";
> + core->clks[2].id = "npu";
> + core->clks[3].id = "pclk";
> err = devm_clk_bulk_get(dev, ARRAY_SIZE(core->clks), core->clks);
> if (err)
> return dev_err_probe(dev, err, "failed to get clocks for core %d\n", core->index);
[Severity: High]
This isn't a bug introduced by this patch, but this devm_clk_bulk_get() call
can defer probe. If rocket_core_init() fails here, I noticed a potential
memory leak in the cleanup path.
In drivers/accel/rocket/rocket_device.c:rocket_device_init(), the rdev
structure is allocated via devres attached to the static drm_dev device:
drivers/accel/rocket/rocket_device.c:rocket_device_init() {
...
rdev = devm_drm_dev_alloc(dev, rocket_drm_driver, struct rocket_device, ddev);
...
}
However, if probe fails, drivers/accel/rocket/rocket_drv.c:rocket_probe()
abandons it without freeing the devres:
drivers/accel/rocket/rocket_drv.c:rocket_probe() {
...
if (rdev->num_cores == 0) {
rocket_device_fini(rdev);
rdev = NULL;
}
...
}
Since drm_dev is never unbound while the module is loaded, does this leak
the rdev and rdev->cores structures on every probe deferral?
[Severity: Critical]
This is a pre-existing issue, but looking at the error handling in
drivers/accel/rocket/rocket_drv.c:rocket_probe():
drivers/accel/rocket/rocket_drv.c:rocket_probe() {
...
if (rdev == NULL) {
/* First core probing, initialize DRM device. */
rdev = rocket_device_init(drm_dev, &rocket_drm_driver);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to initialize rocket device\n");
return PTR_ERR(rdev);
}
}
unsigned int core = rdev->num_cores;
...
}
If rocket_device_init() returns an error, rdev is left holding an ERR_PTR
instead of being reset to NULL. Will a subsequent probe attempt try to
dereference the poisoned rdev pointer when evaluating rdev->num_cores?
[Severity: High]
This is a pre-existing issue, but does the driver mishandle out-of-order
unbinds?
In drivers/accel/rocket/rocket_drv.c:find_core_for_dev(), num_cores is used
as a strict upper bound:
drivers/accel/rocket/rocket_drv.c:find_core_for_dev() {
...
for (unsigned int core = 0; core < rdev->num_cores; core++) {
if (dev == rdev->cores[core].dev)
return core;
}
...
}
If an earlier core is unbound, num_cores is decremented. If a higher-indexed
core is then unbound, find_core_for_dev() won't search far enough to find it.
Furthermore, if another core is then bound, rocket_probe() inserts it using
num_cores as the index:
drivers/accel/rocket/rocket_drv.c:rocket_probe() {
...
rdev->cores[core].rdev = rdev;
rdev->cores[core].dev = &pdev->dev;
...
}
Could this overwrite an active higher-indexed core that was never properly
cleaned up?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260729130743.128876-1-royalnet026@gmail.com?part=1
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] accel/rocket: request the core clocks by name
2026-07-29 13:07 ` Igor Paunovic
@ 2026-08-02 13:13 ` Sidong Yang
-1 siblings, 0 replies; 9+ messages in thread
From: Sidong Yang @ 2026-08-02 13:13 UTC (permalink / raw)
To: Tomeu Vizoso, Igor Paunovic
Cc: ogabbay, dri-devel, linux-kernel, linux-rockchip, gahing, heiko,
Sidong Yang
On Wed, Jul 29, 2026 at 03:07:43PM +0200, Igor Paunovic wrote:
> Found on an Orange Pi 5 Plus (RK3588) by reading the live clock tree:
I see the same thing on a Radxa ROCK 5B+ (RK3588), and the patch fixes
it here as well.
Before, clk_summary has the four rocket handles piled up on the AXI
clock, with no driver consumer at all on the other three:
aclk_npu0 4x fdab0000.npu 1x npu@fdab0000
hclk_npu0 - 1x npu@fdab0000
pclk_npu_root - 3x npu@fdXX0000
scmi_clk_npu - 3x npu@fdXX0000
After the patch every clock has exactly one fdXX0000.npu consumer, and
scmi_clk_npu picks up driver handles for all three cores.
No regressions here:
- 90 runtime PM suspend/resume cycles over the three cores: no
power-domain ack failures, no SErrors, nothing logged at all.
scmi_clk_npu stays at its boot rate and returns to enable_cnt 0
when the cores go idle.
- Five MobileNetV2 subgraphs through the Teflon TFLite delegate still
match the CPU reference (max diff 1). I could not measure any change
in inference time either way, though run-to-run spread on this box is
around 10%, so that only rules out a large regression.
Tested on v7.2-rc3.
Tested-by: Sidong Yang <sidong.yang@furiosa.ai>
Thanks,
Sidong
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] accel/rocket: request the core clocks by name
@ 2026-08-02 13:13 ` Sidong Yang
0 siblings, 0 replies; 9+ messages in thread
From: Sidong Yang @ 2026-08-02 13:13 UTC (permalink / raw)
To: Tomeu Vizoso, Igor Paunovic
Cc: ogabbay, dri-devel, linux-kernel, linux-rockchip, gahing, heiko,
Sidong Yang
On Wed, Jul 29, 2026 at 03:07:43PM +0200, Igor Paunovic wrote:
> Found on an Orange Pi 5 Plus (RK3588) by reading the live clock tree:
I see the same thing on a Radxa ROCK 5B+ (RK3588), and the patch fixes
it here as well.
Before, clk_summary has the four rocket handles piled up on the AXI
clock, with no driver consumer at all on the other three:
aclk_npu0 4x fdab0000.npu 1x npu@fdab0000
hclk_npu0 - 1x npu@fdab0000
pclk_npu_root - 3x npu@fdXX0000
scmi_clk_npu - 3x npu@fdXX0000
After the patch every clock has exactly one fdXX0000.npu consumer, and
scmi_clk_npu picks up driver handles for all three cores.
No regressions here:
- 90 runtime PM suspend/resume cycles over the three cores: no
power-domain ack failures, no SErrors, nothing logged at all.
scmi_clk_npu stays at its boot rate and returns to enable_cnt 0
when the cores go idle.
- Five MobileNetV2 subgraphs through the Teflon TFLite delegate still
match the CPU reference (max diff 1). I could not measure any change
in inference time either way, though run-to-run spread on this box is
around 10%, so that only rules out a large regression.
Tested on v7.2-rc3.
Tested-by: Sidong Yang <sidong.yang@furiosa.ai>
Thanks,
Sidong
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] accel/rocket: request the core clocks by name
2026-07-29 13:07 ` Igor Paunovic
@ 2026-08-05 18:43 ` Diederik de Haas
-1 siblings, 0 replies; 9+ messages in thread
From: Diederik de Haas @ 2026-08-05 18:43 UTC (permalink / raw)
To: Igor Paunovic, Tomeu Vizoso
Cc: Oded Gabbay, dri-devel, linux-kernel, linux-rockchip, Jiaxing Hu,
Heiko Stuebner
Hi Igor,
On Wed Jul 29, 2026 at 3:07 PM CEST, Igor Paunovic wrote:
> rocket_core_init() hands core->clks to devm_clk_bulk_get() without ever
> setting the .id members. The rocket_core array is allocated with
> devm_kcalloc() in rocket_device_init(), and rocket_probe() only fills in
> .rdev, .dev and .index, so all four clk_bulk_data entries are requested
> with a NULL con_id (unlike core->resets, whose ids are set a few lines
> above).
>
> clk_get(dev, NULL) ends up in of_clk_get_hw(np, 0, NULL), and
> of_parse_clkspec() only consults "clock-names" when a name was passed,
> so the index stays 0 for all four entries. Every entry therefore ends up
> holding a handle to the *first* clock of the DT "clocks" property, i.e.
> ACLK_NPUn. Nothing fails: probe succeeds and the driver believes it owns
> four different clocks.
>
> The consequence is that rocket_device_runtime_resume() prepares and
> enables the AXI clock four times, while hclk, pclk and - most
> importantly - the NPU compute clock ("npu", SCMI_CLK_NPU on RK3588) are
> never prepared or enabled by this driver at all. The NPU still works
> only because the Rockchip power-domain driver sets GENPD_FLAG_PM_CLK and
> its attach_dev() callback walks the device node with of_clk_get() and
> adds every clock to the pm_clk list, so genpd happens to keep the
> remaining clocks running. The bug is therefore latent today, but it
> means the driver holds no reference to the clock that actually feeds the
> NPU, which stands in the way of any future frequency scaling
> (OPP/devfreq) work.
>
> Found on an Orange Pi 5 Plus (RK3588) by reading the live clock tree:
> /sys/kernel/debug/clk/clk_summary shows four "fdab0000.npu" consumer
> handles on aclk_npu0 (and likewise on aclk_npu1/aclk_npu2 for the other
> two cores), while hclk_npu0, pclk_npu_root and scmi_clk_npu have no
> "fdab0000.npu" consumer at all - their only consumers are the
> "npu@fdab0000" handles created by the power-domain driver via
> of_clk_get().
I have confirmed both the 'old' situation and the 'new' one on both my
NanoPC-T6 LTS and NanoPC-T6 Plus (both RK3588), so feel free to add
Tested-by: Diederik de Haas <diederik@cknow-tech.com> # NanoPC-T6 LTS, NanoPC-T6 Plus
Cheers,
Diederik
>
> Set the ids explicitly, in the order mandated by the binding
> (Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml):
> aclk, hclk, npu, pclk. After the change the driver holds one handle per
> distinct clock and clk_bulk_prepare_enable() covers all four.
>
> Note that this is a user-visible tightening for out-of-tree DTs: the
> old NULL-id requests resolved by index and succeeded no matter what
> "clock-names" contained, while the named requests fail probe with
> -ENOENT when one of the four names is missing. That is the right
> outcome for in-tree users - the binding requires exactly these four
> clock-names and rk3588-base.dtsi carries them on all three cores - but
> a DT that relied on the permissive lookup goes from silently running on
> the wrong clock handles to not probing at all, so record the change
> here where git log will find it.
>
> Fixes: ed98261b4168 ("accel/rocket: Add a new driver for Rockchip's NPU")
> Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
> Reviewed-by: Jiaxing Hu <gahing@gahingwoo.com>
> ---
> v2:
> - document that resolving by name is a behaviour change for DTs that
> do not carry all four clock-names (Jiaxing Hu)
> - collect Jiaxing's Reviewed-by
> v1: https://lore.kernel.org/linux-rockchip/20260729092939.118779-1-royalnet026@gmail.com/
>
> The same four id assignments are board-tested on RK3576 (ROCK 4D) as
> part of Jiaxing's RK3576 enablement series (v2 6/8), so the change has
> been exercised on two SoCs between us.
>
> Verified on RK3588 (Orange Pi 5 Plus): after the change clk_summary
> shows one consumer handle per clock instead of four handles on aclk, the
> NPU still powers up and down cleanly through runtime PM, and a
> MobileNetV1 inference run via the Teflon TFLite delegate produces
> bit-identical output tensors to the unpatched driver.
>
> drivers/accel/rocket/rocket_core.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
> index b3b2fa9..5dd260b 100644
> --- a/drivers/accel/rocket/rocket_core.c
> +++ b/drivers/accel/rocket/rocket_core.c
> @@ -28,6 +28,10 @@ int rocket_core_init(struct rocket_core *core)
> if (err)
> return dev_err_probe(dev, err, "failed to get resets for core %d\n", core->index);
>
> + core->clks[0].id = "aclk";
> + core->clks[1].id = "hclk";
> + core->clks[2].id = "npu";
> + core->clks[3].id = "pclk";
> err = devm_clk_bulk_get(dev, ARRAY_SIZE(core->clks), core->clks);
> if (err)
> return dev_err_probe(dev, err, "failed to get clocks for core %d\n", core->index);
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] accel/rocket: request the core clocks by name
@ 2026-08-05 18:43 ` Diederik de Haas
0 siblings, 0 replies; 9+ messages in thread
From: Diederik de Haas @ 2026-08-05 18:43 UTC (permalink / raw)
To: Igor Paunovic, Tomeu Vizoso
Cc: Oded Gabbay, dri-devel, linux-kernel, linux-rockchip, Jiaxing Hu,
Heiko Stuebner
Hi Igor,
On Wed Jul 29, 2026 at 3:07 PM CEST, Igor Paunovic wrote:
> rocket_core_init() hands core->clks to devm_clk_bulk_get() without ever
> setting the .id members. The rocket_core array is allocated with
> devm_kcalloc() in rocket_device_init(), and rocket_probe() only fills in
> .rdev, .dev and .index, so all four clk_bulk_data entries are requested
> with a NULL con_id (unlike core->resets, whose ids are set a few lines
> above).
>
> clk_get(dev, NULL) ends up in of_clk_get_hw(np, 0, NULL), and
> of_parse_clkspec() only consults "clock-names" when a name was passed,
> so the index stays 0 for all four entries. Every entry therefore ends up
> holding a handle to the *first* clock of the DT "clocks" property, i.e.
> ACLK_NPUn. Nothing fails: probe succeeds and the driver believes it owns
> four different clocks.
>
> The consequence is that rocket_device_runtime_resume() prepares and
> enables the AXI clock four times, while hclk, pclk and - most
> importantly - the NPU compute clock ("npu", SCMI_CLK_NPU on RK3588) are
> never prepared or enabled by this driver at all. The NPU still works
> only because the Rockchip power-domain driver sets GENPD_FLAG_PM_CLK and
> its attach_dev() callback walks the device node with of_clk_get() and
> adds every clock to the pm_clk list, so genpd happens to keep the
> remaining clocks running. The bug is therefore latent today, but it
> means the driver holds no reference to the clock that actually feeds the
> NPU, which stands in the way of any future frequency scaling
> (OPP/devfreq) work.
>
> Found on an Orange Pi 5 Plus (RK3588) by reading the live clock tree:
> /sys/kernel/debug/clk/clk_summary shows four "fdab0000.npu" consumer
> handles on aclk_npu0 (and likewise on aclk_npu1/aclk_npu2 for the other
> two cores), while hclk_npu0, pclk_npu_root and scmi_clk_npu have no
> "fdab0000.npu" consumer at all - their only consumers are the
> "npu@fdab0000" handles created by the power-domain driver via
> of_clk_get().
I have confirmed both the 'old' situation and the 'new' one on both my
NanoPC-T6 LTS and NanoPC-T6 Plus (both RK3588), so feel free to add
Tested-by: Diederik de Haas <diederik@cknow-tech.com> # NanoPC-T6 LTS, NanoPC-T6 Plus
Cheers,
Diederik
>
> Set the ids explicitly, in the order mandated by the binding
> (Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml):
> aclk, hclk, npu, pclk. After the change the driver holds one handle per
> distinct clock and clk_bulk_prepare_enable() covers all four.
>
> Note that this is a user-visible tightening for out-of-tree DTs: the
> old NULL-id requests resolved by index and succeeded no matter what
> "clock-names" contained, while the named requests fail probe with
> -ENOENT when one of the four names is missing. That is the right
> outcome for in-tree users - the binding requires exactly these four
> clock-names and rk3588-base.dtsi carries them on all three cores - but
> a DT that relied on the permissive lookup goes from silently running on
> the wrong clock handles to not probing at all, so record the change
> here where git log will find it.
>
> Fixes: ed98261b4168 ("accel/rocket: Add a new driver for Rockchip's NPU")
> Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
> Reviewed-by: Jiaxing Hu <gahing@gahingwoo.com>
> ---
> v2:
> - document that resolving by name is a behaviour change for DTs that
> do not carry all four clock-names (Jiaxing Hu)
> - collect Jiaxing's Reviewed-by
> v1: https://lore.kernel.org/linux-rockchip/20260729092939.118779-1-royalnet026@gmail.com/
>
> The same four id assignments are board-tested on RK3576 (ROCK 4D) as
> part of Jiaxing's RK3576 enablement series (v2 6/8), so the change has
> been exercised on two SoCs between us.
>
> Verified on RK3588 (Orange Pi 5 Plus): after the change clk_summary
> shows one consumer handle per clock instead of four handles on aclk, the
> NPU still powers up and down cleanly through runtime PM, and a
> MobileNetV1 inference run via the Teflon TFLite delegate produces
> bit-identical output tensors to the unpatched driver.
>
> drivers/accel/rocket/rocket_core.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
> index b3b2fa9..5dd260b 100644
> --- a/drivers/accel/rocket/rocket_core.c
> +++ b/drivers/accel/rocket/rocket_core.c
> @@ -28,6 +28,10 @@ int rocket_core_init(struct rocket_core *core)
> if (err)
> return dev_err_probe(dev, err, "failed to get resets for core %d\n", core->index);
>
> + core->clks[0].id = "aclk";
> + core->clks[1].id = "hclk";
> + core->clks[2].id = "npu";
> + core->clks[3].id = "pclk";
> err = devm_clk_bulk_get(dev, ARRAY_SIZE(core->clks), core->clks);
> if (err)
> return dev_err_probe(dev, err, "failed to get clocks for core %d\n", core->index);
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] accel/rocket: request the core clocks by name
2026-07-29 13:07 ` Igor Paunovic
@ 2026-08-05 21:15 ` Sebastian Reichel
-1 siblings, 0 replies; 9+ messages in thread
From: Sebastian Reichel @ 2026-08-05 21:15 UTC (permalink / raw)
To: Igor Paunovic
Cc: Tomeu Vizoso, Oded Gabbay, dri-devel, linux-kernel,
linux-rockchip, Jiaxing Hu, Heiko Stuebner
[-- Attachment #1.1: Type: text/plain, Size: 4776 bytes --]
Hi,
On Wed, Jul 29, 2026 at 03:07:43PM +0200, Igor Paunovic wrote:
> rocket_core_init() hands core->clks to devm_clk_bulk_get() without ever
> setting the .id members. The rocket_core array is allocated with
> devm_kcalloc() in rocket_device_init(), and rocket_probe() only fills in
> .rdev, .dev and .index, so all four clk_bulk_data entries are requested
> with a NULL con_id (unlike core->resets, whose ids are set a few lines
> above).
>
> clk_get(dev, NULL) ends up in of_clk_get_hw(np, 0, NULL), and
> of_parse_clkspec() only consults "clock-names" when a name was passed,
> so the index stays 0 for all four entries. Every entry therefore ends up
> holding a handle to the *first* clock of the DT "clocks" property, i.e.
> ACLK_NPUn. Nothing fails: probe succeeds and the driver believes it owns
> four different clocks.
>
> The consequence is that rocket_device_runtime_resume() prepares and
> enables the AXI clock four times, while hclk, pclk and - most
> importantly - the NPU compute clock ("npu", SCMI_CLK_NPU on RK3588) are
> never prepared or enabled by this driver at all. The NPU still works
> only because the Rockchip power-domain driver sets GENPD_FLAG_PM_CLK and
> its attach_dev() callback walks the device node with of_clk_get() and
> adds every clock to the pm_clk list, so genpd happens to keep the
> remaining clocks running. The bug is therefore latent today, but it
> means the driver holds no reference to the clock that actually feeds the
> NPU, which stands in the way of any future frequency scaling
> (OPP/devfreq) work.
>
> Found on an Orange Pi 5 Plus (RK3588) by reading the live clock tree:
> /sys/kernel/debug/clk/clk_summary shows four "fdab0000.npu" consumer
> handles on aclk_npu0 (and likewise on aclk_npu1/aclk_npu2 for the other
> two cores), while hclk_npu0, pclk_npu_root and scmi_clk_npu have no
> "fdab0000.npu" consumer at all - their only consumers are the
> "npu@fdab0000" handles created by the power-domain driver via
> of_clk_get().
>
> Set the ids explicitly, in the order mandated by the binding
> (Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml):
> aclk, hclk, npu, pclk. After the change the driver holds one handle per
> distinct clock and clk_bulk_prepare_enable() covers all four.
>
> Note that this is a user-visible tightening for out-of-tree DTs: the
> old NULL-id requests resolved by index and succeeded no matter what
> "clock-names" contained, while the named requests fail probe with
> -ENOENT when one of the four names is missing. That is the right
> outcome for in-tree users - the binding requires exactly these four
> clock-names and rk3588-base.dtsi carries them on all three cores - but
> a DT that relied on the permissive lookup goes from silently running on
> the wrong clock handles to not probing at all, so record the change
> here where git log will find it.
>
> Fixes: ed98261b4168 ("accel/rocket: Add a new driver for Rockchip's NPU")
> Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
> Reviewed-by: Jiaxing Hu <gahing@gahingwoo.com>
> ---
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
-- Sebastian
> v2:
> - document that resolving by name is a behaviour change for DTs that
> do not carry all four clock-names (Jiaxing Hu)
> - collect Jiaxing's Reviewed-by
> v1: https://lore.kernel.org/linux-rockchip/20260729092939.118779-1-royalnet026@gmail.com/
>
> The same four id assignments are board-tested on RK3576 (ROCK 4D) as
> part of Jiaxing's RK3576 enablement series (v2 6/8), so the change has
> been exercised on two SoCs between us.
>
> Verified on RK3588 (Orange Pi 5 Plus): after the change clk_summary
> shows one consumer handle per clock instead of four handles on aclk, the
> NPU still powers up and down cleanly through runtime PM, and a
> MobileNetV1 inference run via the Teflon TFLite delegate produces
> bit-identical output tensors to the unpatched driver.
>
> drivers/accel/rocket/rocket_core.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
> index b3b2fa9..5dd260b 100644
> --- a/drivers/accel/rocket/rocket_core.c
> +++ b/drivers/accel/rocket/rocket_core.c
> @@ -28,6 +28,10 @@ int rocket_core_init(struct rocket_core *core)
> if (err)
> return dev_err_probe(dev, err, "failed to get resets for core %d\n", core->index);
>
> + core->clks[0].id = "aclk";
> + core->clks[1].id = "hclk";
> + core->clks[2].id = "npu";
> + core->clks[3].id = "pclk";
> err = devm_clk_bulk_get(dev, ARRAY_SIZE(core->clks), core->clks);
> if (err)
> return dev_err_probe(dev, err, "failed to get clocks for core %d\n", core->index);
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 170 bytes --]
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] accel/rocket: request the core clocks by name
@ 2026-08-05 21:15 ` Sebastian Reichel
0 siblings, 0 replies; 9+ messages in thread
From: Sebastian Reichel @ 2026-08-05 21:15 UTC (permalink / raw)
To: Igor Paunovic
Cc: Tomeu Vizoso, Oded Gabbay, dri-devel, linux-kernel,
linux-rockchip, Jiaxing Hu, Heiko Stuebner
[-- Attachment #1: Type: text/plain, Size: 4776 bytes --]
Hi,
On Wed, Jul 29, 2026 at 03:07:43PM +0200, Igor Paunovic wrote:
> rocket_core_init() hands core->clks to devm_clk_bulk_get() without ever
> setting the .id members. The rocket_core array is allocated with
> devm_kcalloc() in rocket_device_init(), and rocket_probe() only fills in
> .rdev, .dev and .index, so all four clk_bulk_data entries are requested
> with a NULL con_id (unlike core->resets, whose ids are set a few lines
> above).
>
> clk_get(dev, NULL) ends up in of_clk_get_hw(np, 0, NULL), and
> of_parse_clkspec() only consults "clock-names" when a name was passed,
> so the index stays 0 for all four entries. Every entry therefore ends up
> holding a handle to the *first* clock of the DT "clocks" property, i.e.
> ACLK_NPUn. Nothing fails: probe succeeds and the driver believes it owns
> four different clocks.
>
> The consequence is that rocket_device_runtime_resume() prepares and
> enables the AXI clock four times, while hclk, pclk and - most
> importantly - the NPU compute clock ("npu", SCMI_CLK_NPU on RK3588) are
> never prepared or enabled by this driver at all. The NPU still works
> only because the Rockchip power-domain driver sets GENPD_FLAG_PM_CLK and
> its attach_dev() callback walks the device node with of_clk_get() and
> adds every clock to the pm_clk list, so genpd happens to keep the
> remaining clocks running. The bug is therefore latent today, but it
> means the driver holds no reference to the clock that actually feeds the
> NPU, which stands in the way of any future frequency scaling
> (OPP/devfreq) work.
>
> Found on an Orange Pi 5 Plus (RK3588) by reading the live clock tree:
> /sys/kernel/debug/clk/clk_summary shows four "fdab0000.npu" consumer
> handles on aclk_npu0 (and likewise on aclk_npu1/aclk_npu2 for the other
> two cores), while hclk_npu0, pclk_npu_root and scmi_clk_npu have no
> "fdab0000.npu" consumer at all - their only consumers are the
> "npu@fdab0000" handles created by the power-domain driver via
> of_clk_get().
>
> Set the ids explicitly, in the order mandated by the binding
> (Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml):
> aclk, hclk, npu, pclk. After the change the driver holds one handle per
> distinct clock and clk_bulk_prepare_enable() covers all four.
>
> Note that this is a user-visible tightening for out-of-tree DTs: the
> old NULL-id requests resolved by index and succeeded no matter what
> "clock-names" contained, while the named requests fail probe with
> -ENOENT when one of the four names is missing. That is the right
> outcome for in-tree users - the binding requires exactly these four
> clock-names and rk3588-base.dtsi carries them on all three cores - but
> a DT that relied on the permissive lookup goes from silently running on
> the wrong clock handles to not probing at all, so record the change
> here where git log will find it.
>
> Fixes: ed98261b4168 ("accel/rocket: Add a new driver for Rockchip's NPU")
> Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
> Reviewed-by: Jiaxing Hu <gahing@gahingwoo.com>
> ---
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
-- Sebastian
> v2:
> - document that resolving by name is a behaviour change for DTs that
> do not carry all four clock-names (Jiaxing Hu)
> - collect Jiaxing's Reviewed-by
> v1: https://lore.kernel.org/linux-rockchip/20260729092939.118779-1-royalnet026@gmail.com/
>
> The same four id assignments are board-tested on RK3576 (ROCK 4D) as
> part of Jiaxing's RK3576 enablement series (v2 6/8), so the change has
> been exercised on two SoCs between us.
>
> Verified on RK3588 (Orange Pi 5 Plus): after the change clk_summary
> shows one consumer handle per clock instead of four handles on aclk, the
> NPU still powers up and down cleanly through runtime PM, and a
> MobileNetV1 inference run via the Teflon TFLite delegate produces
> bit-identical output tensors to the unpatched driver.
>
> drivers/accel/rocket/rocket_core.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
> index b3b2fa9..5dd260b 100644
> --- a/drivers/accel/rocket/rocket_core.c
> +++ b/drivers/accel/rocket/rocket_core.c
> @@ -28,6 +28,10 @@ int rocket_core_init(struct rocket_core *core)
> if (err)
> return dev_err_probe(dev, err, "failed to get resets for core %d\n", core->index);
>
> + core->clks[0].id = "aclk";
> + core->clks[1].id = "hclk";
> + core->clks[2].id = "npu";
> + core->clks[3].id = "pclk";
> err = devm_clk_bulk_get(dev, ARRAY_SIZE(core->clks), core->clks);
> if (err)
> return dev_err_probe(dev, err, "failed to get clocks for core %d\n", core->index);
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-08-05 21:15 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-29 13:07 [PATCH v2] accel/rocket: request the core clocks by name Igor Paunovic
2026-07-29 13:07 ` Igor Paunovic
2026-07-29 13:22 ` sashiko-bot
2026-08-02 13:13 ` Sidong Yang
2026-08-02 13:13 ` Sidong Yang
2026-08-05 18:43 ` Diederik de Haas
2026-08-05 18:43 ` Diederik de Haas
2026-08-05 21:15 ` Sebastian Reichel
2026-08-05 21:15 ` Sebastian Reichel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.