Files
BFE Engineering 42fb386f60 docs: ASCII typography and style normalization across all repo text
Replace every em dash with real punctuation (rewrites, not hyphen swaps)
in docs, code comments, scripts, configs, and the port records; convert
en dashes, curly quotes, ellipsis glyphs, arrows, and section signs to
ASCII; drop machine-writing tell phrases from living docs. ADR titles
now use a colon. The M2 bring-up DTS model string carried an em dash
into the patch series and its record echoes; fixed at both, and the full
series re-verified to apply cleanly onto pristine 6.18.46. One comment
in freshness.h deliberately names the em dash glyph the UI renders as
the unknown mark; that is data, kept as prose naming it.

Verified: cargo tests (sim, config-lint, rs485-bridge), shellcheck,
both driver MC/DC harnesses, patches-apply.
2026-08-31 12:31:27 -06:00

138 lines
4.4 KiB
C

// 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 section 1.4 Tier A and PORT-PLAN.md section 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 section 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;
}