kernel/rv1106: HPMCU mailbox 100% VERIFIED + open NPU driver VERIFIED
MAILBOX (fully open A7<->RISC-V SCR1 round-trip, 5/5 exact echoes on c8a3):
- rockchip-mailbox.c: rv1106 has 1 shared IRQ, not 4/channel -> added
rv1106_drv_data{num_chans=1} + compatible (rk3368 fallback assumed 4 -> probe
failed 'IRQ index 1 not found').
- clk-rv1106.c: CLK_CORE_MCU (SCR1 core clock) marked CLK_IGNORE_UNUSED -
6.18's clk_disable_unused() was switching off the coprocessor clock so a
loaded firmware never ran (5.10 left it on).
- Open SCR1 echo firmware (scr1-echo/, 154B RV32IMC) + load/test scripts;
A2B_INTEN on the MCU side + CMD-then-DAT (DAT=doorbell) order. Loaded via the
proven hpmcu.rs SRAM path; do NOT kill warden-flared (dw-wdt). mailbox/VERIFIED.md.
NPU (open GPL rknpu 0.9.2 kernel driver on 6.18):
- DT fix: base npu node lacks interrupt-names, driver requests IRQ byname
'npu_irq' -> probe bailed -ENXIO. Added interrupt-names='npu_irq'.
- Verified: [drm] Initialized rknpu 0.9.2 on minor 1; /dev/dri/card1;
rknpu_version_test PASS (0.9.2 + hw version, full power/clock/reset path).
- Honest ceiling: open compute (regcmd compiler) is a from-scratch ~person-year
RE project, no RV1106 prior art; ship the driver, no blob. npu/VERIFIED.md.
DRIVER-PARITY + CAPABILITIES-AUDIT updated; dts snapshot refreshed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
54f961c6b6
commit
7e76553bd7
@@ -0,0 +1,137 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* rknpu_version_test.c -- standalone hardware smoke test for the RKNPU
|
||||
* kernel driver port (see PORT-PLAN.md / PORT-PROGRESS.md in this
|
||||
* directory).
|
||||
*
|
||||
* Opens a DRM node (tries /dev/dri/card0, then card1, then renderD128),
|
||||
* issues DRM_IOCTL_RKNPU_ACTION with RKNPU_GET_DRV_VERSION and then
|
||||
* RKNPU_GET_HW_VERSION, and prints the decoded results. This exercises the
|
||||
* full ioctl-dispatch -> power-get/put -> clock/reset path with zero
|
||||
* dependency on a regcmd buffer or the (closed) RKNN runtime -- see
|
||||
* OPEN-NPU-PLAN.md §1.4 Tier A and PORT-PLAN.md §3 step 5.
|
||||
*
|
||||
* Dependency-free beyond the UAPI header: build with
|
||||
* -I<kernel-tree>/include/uapi
|
||||
* so both <drm/drm.h> and <drm/rknpu_ioctl.h> (and the linux/types.h,
|
||||
* linux/ioctl.h they need) resolve entirely out of the kernel tree's own
|
||||
* include/uapi/ -- no libdrm, no target sysroot headers required.
|
||||
*
|
||||
* Cross-compile (see PORT-PROGRESS.md for the full recipe):
|
||||
*
|
||||
* export PATH="<flare-edge>/sdk/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin:/usr/bin:/bin"
|
||||
* arm-rockchip830-linux-uclibcgnueabihf-gcc \
|
||||
* -I<flare-edge>/research/linux-6.18.46/include/uapi \
|
||||
* -Wall -O2 -static -o rknpu_version_test rknpu_version_test.c
|
||||
*
|
||||
* (add -static if the target rootfs's libc version/ABI is in doubt; drop it
|
||||
* for a smaller dynamically-linked binary if the rootfs libc is known good.)
|
||||
*
|
||||
* Expected output on a working probe:
|
||||
*
|
||||
* opened /dev/dri/card0 (fd=3)
|
||||
* driver version: 0.9.2 (raw code 902)
|
||||
* hw version: 0x.... (raw)
|
||||
* PASS: /dev/dri/card0 answered both version-query ioctls -- probe,
|
||||
* power-get/put, and clock/reset all exercised.
|
||||
*
|
||||
* "0.9.2" is DRIVER_MAJOR/MINOR/PATCHLEVEL from the vendor source
|
||||
* (rknpu_drv.h) unmodified by this port -- a match confirms the ioctl
|
||||
* round-trip reached real driver code, not a stub. The hw version is a raw
|
||||
* value read directly off the NPU core's VERSION/VERSION_NUM registers
|
||||
* (rknpu_job.c:rknpu_get_hw_version()) -- any non-zero, non-0xffffffff
|
||||
* value is a plausible "the register block is alive" signal; there is no
|
||||
* published decode table for it beyond that (PORT-PLAN.md §3 step 5).
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <drm/rknpu_ioctl.h>
|
||||
|
||||
static const char *const candidates[] = {
|
||||
"/dev/dri/card0",
|
||||
"/dev/dri/card1",
|
||||
"/dev/dri/renderD128",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int do_action(int fd, __u32 flags, __u32 *value)
|
||||
{
|
||||
struct rknpu_action act;
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
act.flags = flags;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_RKNPU_ACTION, &act) < 0)
|
||||
return -errno;
|
||||
|
||||
*value = act.value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int fd = -1;
|
||||
const char *path = NULL;
|
||||
__u32 drv_version = 0;
|
||||
__u32 hw_version = 0;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* There may be several DRM cards (the VOP display registers card0, the
|
||||
* NPU registers its own). Try each candidate and keep the FIRST that
|
||||
* actually answers the RKNPU version ioctl -- opening successfully is not
|
||||
* enough (the display card opens fine but returns EINVAL). */
|
||||
for (i = 0; candidates[i] != NULL; i++) {
|
||||
int f = open(candidates[i], O_RDWR | O_CLOEXEC);
|
||||
if (f < 0) {
|
||||
fprintf(stderr, "open(%s): %s\n", candidates[i],
|
||||
strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if (do_action(f, RKNPU_GET_DRV_VERSION, &drv_version) == 0) {
|
||||
fd = f;
|
||||
path = candidates[i];
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "%s: not an rknpu node (version ioctl: %s)\n",
|
||||
candidates[i], strerror(errno));
|
||||
close(f);
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
fprintf(stderr,
|
||||
"FAIL: no DRM node answered the RKNPU version ioctl -- "
|
||||
"is CONFIG_ROCKCHIP_RKNPU probed? check "
|
||||
"`dmesg | grep -i rknpu` and `ls -la /dev/dri/`\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("opened %s (fd=%d)\n", path, fd);
|
||||
ret = 0;
|
||||
printf("driver version: %u.%u.%u (raw code %u)\n",
|
||||
RKNPU_GET_DRV_VERSION_MAJOR(drv_version),
|
||||
RKNPU_GET_DRV_VERSION_MINOR(drv_version),
|
||||
RKNPU_GET_DRV_VERSION_PATCHLEVEL(drv_version), drv_version);
|
||||
|
||||
ret = do_action(fd, RKNPU_GET_HW_VERSION, &hw_version);
|
||||
if (ret) {
|
||||
fprintf(stderr,
|
||||
"FAIL: DRM_IOCTL_RKNPU_ACTION(RKNPU_GET_HW_VERSION): %s\n",
|
||||
strerror(-ret));
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
printf("hw version: 0x%08x (raw)\n", hw_version);
|
||||
|
||||
printf("PASS: %s answered both version-query ioctls -- probe, "
|
||||
"power-get/put, and clock/reset all exercised.\n", path);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user