Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v6 0/9] accel/rocket: RK3576 NPU (RKNN) enablement
@ 2026-08-06  6:34 Jiaxing Hu
  2026-08-06  6:34 ` [RFC PATCH v6 1/9] dt-bindings: npu: rockchip: add rockchip,rk3576-rknn-core Jiaxing Hu
                   ` (8 more replies)
  0 siblings, 9 replies; 13+ messages in thread
From: Jiaxing Hu @ 2026-08-06  6:34 UTC (permalink / raw)
  To: tomeu, heiko, robh, krzk+dt, conor+dt, joro, will, robin.murphy,
	ulfh, p.zabel, ogabbay, zhangqing
  Cc: royalnet026, alchark, chaoyi.chen, diederik, dri-devel,
	linux-rockchip, iommu, linux-pm, devicetree, linux-arm-kernel,
	linux-kernel, Jiaxing Hu

Based on Igor Paunovic's "[PATCH v2] accel/rocket: request the core
clocks by name", which is waiting on Tomeu and which v5 was carrying a
duplicate of:

  https://lore.kernel.org/linux-rockchip/20260729130743.128876-1-royalnet026@gmail.com/

That duplication was the coordination problem Igor raised on v5. Basing
on it rather than re-adding the same hunk removes it, and it makes the
patch split below fall out cleanly.

Tested on a Radxa ROCK 4D, on next-20260730.

Changes in v6
-------------

  * accel/rocket: the enablement is split in two, as Diederik de Haas
    asked for and Igor seconded with the observation that v5's 6/8 no
    longer applied on a tree carrying the clocks fix. 6/9 is preparation
    only, the soc_data plumbing and the bulk counts, with RK3588 keeping
    four clocks and two resets. 7/9 is the RK3576 enablement.

  * accel/rocket: poll_dying was a one-way latch. rocket_job_fini() set
    it and nothing cleared it, while struct rocket_core survives an
    unbind whenever another core stays bound, so a rebinding core would
    never retire anything through the poll again. rocket_job_init() now
    clears it. Found by Igor, who also explained why the ROCK 4D test
    could not have caught it: with one core enabled every unbind is the
    last one and the core array is reallocated.

  * accel/rocket: rocket_core_reset() still used ARRAY_SIZE(core->resets)
    after acquisition moved to soc->num_resets, so on RK3576 it walked a
    reset that was never acquired. Benign, since the reset core accepts a
    NULL rstc, but patch 5 has just made this path load bearing. Also
    from Igor. It is in 6/9 with the rest of the count changes.

  * accel/rocket: the two register writes in rocket_job_handle_irq() were
    outside job_lock while hw_submit() writes OPERATION_ENABLE inside it,
    so the completion's zero could land after a submit's one and stop a
    task that had just started. They are under the lock now. This is the
    only behaviour change 6/9 makes to RK3588.

  * accel/rocket: the poll work now skips its register writes when no job
    is in flight. Unlike an interrupt it has no hardware condition to
    ack, and with the job already retired by the interrupt path the
    device can have autosuspended underneath it.

  * accel/rocket: where both completion paths are live, a completion
    whose submit the other path has already retired no longer goes on to
    start a further task. v5 checked this only on the poll side, which
    left the mirror case open.

  * pmdomain/rockchip: dev_err_probe() for the reset acquisition, as
    Philipp Zabel asked.

Philipp, on the other half of that: every devm_reset_control_* variant
resolves against dev->of_node, and these resets are on the power-domain
child node rather than the PMU's own node, so the devm form would take
them from the wrong node. The clocks a few lines above use the same
of_*() and manual-put pattern for the same reason. Happy to add a
devm_add_action_or_reset() instead if you would rather the lifetime were
devres managed.

Igor, thank you for the RK3588 characterisation and for running the
per-core unbind and rebind. Everything in v6 that came from your review
is above. The completion path changed again, so it needs another look
rather than a carried tag.

Verified on hardware with every debug knob off: the NPU probes with the
two domain list and no attach failure, a convolution submitted after a
fresh resume is byte exact against the CPU reference, and unbind and
rebind is clean with no warning. Every patch in the series builds on its
own.

I have deliberately stopped quoting the "runs byte exact N times in a
row" figure I used in earlier cover letters. See below: that test could
not distinguish a recomputation from an untouched buffer, and it was
measuring the latter.

What is still wrong
-------------------

The failure is much narrower than I have been describing it, and most of
what I said about it in v3 through v5 was reading an artefact.

I had been reporting that a single convolution is byte exact, that
re-running the same one is byte exact every time, and that what fails is
loading a different configuration after it. The first part is true. The
rest was a stale buffer.

Every one of those "re-runs byte exact" measurements fed the same input
each time, so a correct recomputation and an output buffer that nothing
had touched since the first submit look identical. Feeding the same model
a different input and checksumming the output BO in place separates them:

  A(input X), first submit of the session   correct, crc32 20a556ae
  A(input Y), no reset in between           wrong,   crc32 20a556ae
  A(input Y), after a runtime resume        correct, crc32 dda67317

The third line moves the checksum, so it does see the block's writes. The
second does not move it, with the same configuration loaded and only the
input data different. The second submit does not write its output at all.

So the shape is: only the first submit after a reset computes. Everything
after it is a no-op that leaves the output buffer holding whatever was
there before. "A works, B fails, A works again" needs no configuration
story: A computes, B is a no-op and its freshly zeroed buffer reads back
as the zero point, and A again is a no-op returning A's old result.

That also settles the question Igor raised on v5, and not in favour of
what I claimed there. His alternative was that the block never stops
executing the resident configuration and writes to the previous task's
addresses, which would look the same from the failing job's own buffers.
With the watched buffer latched rather than followed, the resident job's
output is unchanged across the failing submit. It writes nothing anywhere.

Two corrections to the record, both mine:

  * v5 said the failing submit "computes byte exact from a buffer full of
    0xdeadbeef" after its regcmd was corrupted. It does not compute. The
    narrower statement survives, that a repeat submit does not re-read its
    regcmd, because it does not read anything.

  * v3 and v4 said the failing job "writes out a zero point surface" and I
    read that as the MAC producing nothing. Nothing was ever measured
    about the MAC. The buffer is simply never written, and a zeroed shmem
    page plus the +0x80 that teflon applies on readback is 128.

The ping-pong lead from the v3 thread stays retired, and so does the
configuration-load framing that replaced it. The question is now why the
block accepts exactly one task per reset. That is narrower than anything
I have had before, it matches the interrupt behaviour already in this
series, and it means the userspace side was never involved.

One incidental register fact, in case it means something to someone:
PC_BASE_ADDRESS reads back 0x00000000 immediately after being written, on
every submit.

I used Claude Opus 5 to trim this series out of my debugging tree and
generate the diffs.

Jiaxing Hu (9):
  dt-bindings: npu: rockchip: add rockchip,rk3576-rknn-core
  dt-bindings: power: rockchip: allow resets in a power domain node
  dt-bindings: iommu: rockchip: allow the RK3576 NPU MMU clock set
  pmdomain/rockchip: add optional per-domain power-on settle delay
  pmdomain/rockchip: cycle optional power-domain resets on power-on
  accel/rocket: select the per-core clock and reset counts from match data
  accel/rocket: add RK3576 NPU (RKNN) support
  arm64: dts: rockchip: rk3576: add NPU (RKNN) nodes
  arm64: dts: rockchip: rk3576-rock-4d: enable NPU

 .../devicetree/bindings/iommu/rockchip,iommu.yaml  |   8 ++
 .../bindings/npu/rockchip,rk3588-rknn-core.yaml    |  47 ++++++-
 .../bindings/power/rockchip,power-controller.yaml  |   8 ++
 arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts    |  10 ++
 arch/arm64/boot/dts/rockchip/rk3576.dtsi           |  80 ++++++++++-
 drivers/accel/rocket/rocket_core.c                 |  26 +++-
 drivers/accel/rocket/rocket_core.h                 |  20 ++-
 drivers/accel/rocket/rocket_device.c               |   4 +
 drivers/accel/rocket/rocket_drv.c                  |  22 ++-
 drivers/accel/rocket/rocket_job.c                  | 149 +++++++++++++++++++--
 drivers/pmdomain/rockchip/pm-domains.c             |  71 +++++++---
 11 files changed, 396 insertions(+), 49 deletions(-)

--
2.43.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-08-06 11:29 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-06  6:34 [RFC PATCH v6 0/9] accel/rocket: RK3576 NPU (RKNN) enablement Jiaxing Hu
2026-08-06  6:34 ` [RFC PATCH v6 1/9] dt-bindings: npu: rockchip: add rockchip,rk3576-rknn-core Jiaxing Hu
2026-08-06  6:34 ` [RFC PATCH v6 2/9] dt-bindings: power: rockchip: allow resets in a power domain node Jiaxing Hu
2026-08-06  6:34 ` [RFC PATCH v6 3/9] dt-bindings: iommu: rockchip: allow the RK3576 NPU MMU clock set Jiaxing Hu
2026-08-06  9:23   ` Diederik de Haas
2026-08-06  9:55     ` Jiaxing Hu
2026-08-06 11:29       ` Diederik de Haas
2026-08-06  6:34 ` [RFC PATCH v6 4/9] pmdomain/rockchip: add optional per-domain power-on settle delay Jiaxing Hu
2026-08-06  6:34 ` [RFC PATCH v6 5/9] pmdomain/rockchip: cycle optional power-domain resets on power-on Jiaxing Hu
2026-08-06  6:34 ` [RFC PATCH v6 6/9] accel/rocket: select the per-core clock and reset counts from match data Jiaxing Hu
2026-08-06  6:34 ` [RFC PATCH v6 7/9] accel/rocket: add RK3576 NPU (RKNN) support Jiaxing Hu
2026-08-06  6:34 ` [RFC PATCH v6 8/9] arm64: dts: rockchip: rk3576: add NPU (RKNN) nodes Jiaxing Hu
2026-08-06  6:34 ` [RFC PATCH v6 9/9] arm64: dts: rockchip: rk3576-rock-4d: enable NPU Jiaxing Hu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox