* [PATCH i-g-t v2 0/3] Add initial Panthor tests
@ 2025-09-12 18:19 Daniel Almeida
2025-09-12 18:19 ` [PATCH i-g-t v2 1/3] lib: add support for opening Panthor devices Daniel Almeida
` (3 more replies)
0 siblings, 4 replies; 15+ messages in thread
From: Daniel Almeida @ 2025-09-12 18:19 UTC (permalink / raw)
To: adrinael, arek, kamil.konieczny, juhapekka.heikkila,
bhanuprakash.modem, ashutosh.dixit, karthik.b.s, boris.brezillon,
liviu.dudau, steven.price, aliceryhl, jeffv
Cc: Daniel Almeida, intel-gfx, igt-dev, dri-devel
This series adds basic Panthor tests. In particular, these are being
used to test both Panthor[0] and Tyr[1], i.e.: the new Rust GPU driver
that implements Panthor's uAPI (i.e.: panthor_drm.h). Most of the
initial tests were chosen in order to have something to test Tyr with,
but this series lays the groundwork so that more interesting tests can
be added to test more of Panthor itself.
This work is being tested on a RockPi 5, featuring an rk3588 SoC and
Mali-G610 Valhall.
Note that there's a few (less than five?) remaining checkpatch.pl
comments about long lines. IMHO there's no way to format them better so
I hope we can live with this.
[0]: https://patchwork.freedesktop.org/patch/msgid/20240229162230.2634044-12-boris.brezillon@collabora.com
[1]: https://lore.kernel.org/dri-devel/aMLB0Vs0dJ_AkU4z@google.com/
Changes from v1:
- Rebased on top of the latest master
- Squashed patch 3 from v1 into patch 2.
- Switched to /* */ comments in headers
- Initialized padding fields to 0 as applicable in group_destroy and
vm_destroy
- Removed wrong assert(gpu_rev != 0)
- Changed indentation to use tabs
- Rework igt_panthor_mmap_bo to take an offset (so we don't call the
mmap_offset ioctl twice)
- Added igt_describe and docs to the functions igt_panthor.c
- Linked to the driver in the cover letter and patch 1.
- Improved the commit message for patch 1.
Link to v1: https://lore.kernel.org/dri-devel/20250828130402.2549948-1-daniel.almeida@collabora.com/
Daniel Almeida (3):
lib: add support for opening Panthor devices
panthor: add initial infrastructure
tests/panthor: add panthor tests
lib/drmtest.c | 1 +
lib/drmtest.h | 1 +
lib/igt_panthor.c | 229 ++++++++++++++++++++++++++++
lib/igt_panthor.h | 30 ++++
lib/meson.build | 1 +
meson.build | 8 +
tests/meson.build | 2 +
tests/panthor/meson.build | 15 ++
tests/panthor/panthor_gem.c | 66 ++++++++
tests/panthor/panthor_group.c | 276 ++++++++++++++++++++++++++++++++++
tests/panthor/panthor_query.c | 25 +++
tests/panthor/panthor_vm.c | 80 ++++++++++
12 files changed, 734 insertions(+)
create mode 100644 lib/igt_panthor.c
create mode 100644 lib/igt_panthor.h
create mode 100644 tests/panthor/meson.build
create mode 100644 tests/panthor/panthor_gem.c
create mode 100644 tests/panthor/panthor_group.c
create mode 100644 tests/panthor/panthor_query.c
create mode 100644 tests/panthor/panthor_vm.c
--
2.51.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH i-g-t v2 1/3] lib: add support for opening Panthor devices
2025-09-12 18:19 [PATCH i-g-t v2 0/3] Add initial Panthor tests Daniel Almeida
@ 2025-09-12 18:19 ` Daniel Almeida
2025-09-16 12:03 ` Kamil Konieczny
2025-09-12 18:19 ` [PATCH i-g-t v2 2/3] panthor: add initial infrastructure Daniel Almeida
` (2 subsequent siblings)
3 siblings, 1 reply; 15+ messages in thread
From: Daniel Almeida @ 2025-09-12 18:19 UTC (permalink / raw)
To: adrinael, arek, kamil.konieczny, juhapekka.heikkila,
bhanuprakash.modem, ashutosh.dixit, karthik.b.s, boris.brezillon,
liviu.dudau, steven.price, aliceryhl, jeffv
Cc: Daniel Almeida, intel-gfx, igt-dev, dri-devel
We will be adding tests for Panthor in a subsequent patch, so first add
the ability to open the device.
In particular, these will be used to test both Panthor[0] and Tyr[1],
i.e.: the new Rust GPU driver that implements Panthor's uAPI (i.e.:
panthor_drm.h).
This work is being tested on a RockPi 5, featuring an rk3588 SoC and
Mali-G610 Valhall.
[0]: https://patchwork.freedesktop.org/patch/msgid/20240229162230.2634044-12-boris.brezillon@collabora.com
[1]: https://lore.kernel.org/dri-devel/aMLB0Vs0dJ_AkU4z@google.com/
Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
---
lib/drmtest.c | 1 +
lib/drmtest.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/lib/drmtest.c b/lib/drmtest.c
index 551385867..ea37a886a 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -220,6 +220,7 @@ static const struct module {
{ DRIVER_INTEL, "i915", modprobe_i915 },
{ DRIVER_MSM, "msm" },
{ DRIVER_PANFROST, "panfrost" },
+ { DRIVER_PANTHOR, "panthor" },
{ DRIVER_V3D, "v3d" },
{ DRIVER_VC4, "vc4" },
{ DRIVER_VGEM, "vgem" },
diff --git a/lib/drmtest.h b/lib/drmtest.h
index a9542dde2..4c34ac311 100644
--- a/lib/drmtest.h
+++ b/lib/drmtest.h
@@ -56,6 +56,7 @@ int __get_drm_device_name(int fd, char *name, int name_size);
#define DRIVER_XE (1 << 7)
#define DRIVER_VMWGFX (1 << 8)
#define DRIVER_VKMS (1 << 9)
+#define DRIVER_PANTHOR (1 << 10)
/*
* Exclude DRVER_VGEM from DRIVER_ANY since if you run on a system
--
2.51.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH i-g-t v2 2/3] panthor: add initial infrastructure
2025-09-12 18:19 [PATCH i-g-t v2 0/3] Add initial Panthor tests Daniel Almeida
2025-09-12 18:19 ` [PATCH i-g-t v2 1/3] lib: add support for opening Panthor devices Daniel Almeida
@ 2025-09-12 18:19 ` Daniel Almeida
2025-09-16 12:12 ` Kamil Konieczny
2025-09-12 18:19 ` [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests Daniel Almeida
2025-09-15 14:40 ` [PATCH i-g-t v2 0/3] Add initial Panthor tests Steven Price
3 siblings, 1 reply; 15+ messages in thread
From: Daniel Almeida @ 2025-09-12 18:19 UTC (permalink / raw)
To: adrinael, arek, kamil.konieczny, juhapekka.heikkila,
bhanuprakash.modem, ashutosh.dixit, karthik.b.s, boris.brezillon,
liviu.dudau, steven.price, aliceryhl, jeffv
Cc: Daniel Almeida, intel-gfx, igt-dev, dri-devel
Add the necessary code needed to compile panthor tests as well as the
basic infrastructure that will be used by the Panthor tests themselves.
To make sure everything is in order, add a basic test in
panthor_query.c.
Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
---
lib/igt_panthor.c | 41 +++++++++++++++++++++++++++++++++++
lib/igt_panthor.h | 12 ++++++++++
lib/meson.build | 1 +
meson.build | 8 +++++++
tests/meson.build | 2 ++
tests/panthor/meson.build | 12 ++++++++++
tests/panthor/panthor_query.c | 25 +++++++++++++++++++++
7 files changed, 101 insertions(+)
create mode 100644 lib/igt_panthor.c
create mode 100644 lib/igt_panthor.h
create mode 100644 tests/panthor/meson.build
create mode 100644 tests/panthor/panthor_query.c
diff --git a/lib/igt_panthor.c b/lib/igt_panthor.c
new file mode 100644
index 000000000..0b690f796
--- /dev/null
+++ b/lib/igt_panthor.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
+
+#include "drmtest.h"
+#include "igt_panthor.h"
+#include "ioctl_wrappers.h"
+#include "panthor_drm.h"
+
+/**
+ * SECTION:igt_panthor
+ * @short_description: Panthor support library
+ * @title: Panthor
+ * @include: igt.h
+ *
+ * This library provides various auxiliary helper functions for writing Panthor
+ * tests.
+ */
+
+/**
+ * igt_panthor_query:
+ * @fd: device file descriptor
+ * @type: query type (e.g., DRM_PANTHOR_DEV_QUERY_GPU_INFO)
+ * @data: pointer to a struct to store the query result
+ * @size: size of the result struct
+ * @err: expected error code, or 0 for success
+ *
+ * Query GPU information.
+ */
+void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err)
+{
+ struct drm_panthor_dev_query query = {
+ .type = type,
+ .pointer = (uintptr_t)data,
+ .size = size,
+ };
+
+ if (err)
+ do_ioctl_err(fd, DRM_IOCTL_PANTHOR_DEV_QUERY, &query, err);
+ else
+ do_ioctl(fd, DRM_IOCTL_PANTHOR_DEV_QUERY, &query);
+}
diff --git a/lib/igt_panthor.h b/lib/igt_panthor.h
new file mode 100644
index 000000000..a99b7102d
--- /dev/null
+++ b/lib/igt_panthor.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: MIT */
+/* SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd. */
+
+#ifndef IGT_PANTHOR_H
+#define IGT_PANTHOR_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err);
+
+#endif /* IGT_PANTHOR_H */
diff --git a/lib/meson.build b/lib/meson.build
index f50a8d44b..4ccf3ee04 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -105,6 +105,7 @@ lib_sources = [
'igt_kmod.c',
'igt_ktap.c',
'igt_panfrost.c',
+ 'igt_panthor.c',
'igt_v3d.c',
'igt_vc4.c',
'igt_vmwgfx.c',
diff --git a/meson.build b/meson.build
index f7ae427b3..56ef8730e 100644
--- a/meson.build
+++ b/meson.build
@@ -288,6 +288,7 @@ libexecdir = join_paths(get_option('libexecdir'), 'igt-gpu-tools')
amdgpudir = join_paths(libexecdir, 'amdgpu')
msmdir = join_paths(libexecdir, 'msm')
panfrostdir = join_paths(libexecdir, 'panfrost')
+panthordir = join_paths(libexecdir, 'panthor')
v3ddir = join_paths(libexecdir, 'v3d')
vc4dir = join_paths(libexecdir, 'vc4')
vkmsdir = join_paths(libexecdir, 'vkms')
@@ -341,6 +342,12 @@ if get_option('use_rpath')
endforeach
panfrost_rpathdir = join_paths(panfrost_rpathdir, libdir)
+ panthor_rpathdir = '$ORIGIN'
+ foreach p : panthordir.split('/')
+ panthor_rpathdir = join_paths(panthor_rpathdir, '..')
+ endforeach
+ panthor_rpathdir = join_paths(panthor_rpathdir, libdir)
+
v3d_rpathdir = '$ORIGIN'
foreach p : v3ddir.split('/')
v3d_rpathdir = join_paths(v3d_rpathdir, '..')
@@ -370,6 +377,7 @@ else
amdgpudir_rpathdir = ''
msm_rpathdir = ''
panfrost_rpathdir = ''
+ panthor_rpathdir = ''
v3d_rpathdir = ''
vc4_rpathdir = ''
vkms_rpathdir = ''
diff --git a/tests/meson.build b/tests/meson.build
index a7b9375ed..0b61561a4 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -486,6 +486,8 @@ subdir('msm')
subdir('panfrost')
+subdir('panthor')
+
subdir('v3d')
subdir('vc4')
diff --git a/tests/panthor/meson.build b/tests/panthor/meson.build
new file mode 100644
index 000000000..ce13aebaa
--- /dev/null
+++ b/tests/panthor/meson.build
@@ -0,0 +1,12 @@
+panthor_progs = [
+ 'panthor_query'
+]
+
+foreach prog : panthor_progs
+ test_executables += executable(prog, prog + '.c',
+ dependencies : test_deps,
+ install_dir : panthordir,
+ install_rpath : panthor_rpathdir,
+ install : true)
+ test_list += join_paths('panthor', prog)
+endforeach
diff --git a/tests/panthor/panthor_query.c b/tests/panthor/panthor_query.c
new file mode 100644
index 000000000..7c1055763
--- /dev/null
+++ b/tests/panthor/panthor_query.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
+
+#include "igt.h"
+#include "igt_core.h"
+#include "igt_panthor.h"
+#include "panthor_drm.h"
+#include <stdint.h>
+
+igt_main {
+ int fd;
+
+ igt_fixture { fd = drm_open_driver(DRIVER_PANTHOR); }
+
+ igt_describe("Query GPU information from ROM.");
+ igt_subtest("query") {
+ struct drm_panthor_gpu_info gpu = {};
+
+ igt_panthor_query(fd, DRM_PANTHOR_DEV_QUERY_GPU_INFO, &gpu, sizeof(gpu), 0);
+
+ igt_assert(gpu.gpu_id != 0);
+ }
+
+ igt_fixture { drm_close_driver(fd); }
+}
--
2.51.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests
2025-09-12 18:19 [PATCH i-g-t v2 0/3] Add initial Panthor tests Daniel Almeida
2025-09-12 18:19 ` [PATCH i-g-t v2 1/3] lib: add support for opening Panthor devices Daniel Almeida
2025-09-12 18:19 ` [PATCH i-g-t v2 2/3] panthor: add initial infrastructure Daniel Almeida
@ 2025-09-12 18:19 ` Daniel Almeida
2025-09-16 12:15 ` Kamil Konieczny
` (2 more replies)
2025-09-15 14:40 ` [PATCH i-g-t v2 0/3] Add initial Panthor tests Steven Price
3 siblings, 3 replies; 15+ messages in thread
From: Daniel Almeida @ 2025-09-12 18:19 UTC (permalink / raw)
To: adrinael, arek, kamil.konieczny, juhapekka.heikkila,
bhanuprakash.modem, ashutosh.dixit, karthik.b.s, boris.brezillon,
liviu.dudau, steven.price, aliceryhl, jeffv
Cc: Daniel Almeida, intel-gfx, igt-dev, dri-devel
Add an initial test suit covering query device properties, allocating
memory, binding and unbinding VA ranges through VM_BIND and submitting a
simple piece of work through GROUP_SUBMIT.
Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
---
lib/igt_panthor.c | 188 +++++++++++++++++++++++
lib/igt_panthor.h | 18 +++
tests/panthor/meson.build | 5 +-
tests/panthor/panthor_gem.c | 66 ++++++++
tests/panthor/panthor_group.c | 276 ++++++++++++++++++++++++++++++++++
tests/panthor/panthor_vm.c | 80 ++++++++++
6 files changed, 632 insertions(+), 1 deletion(-)
create mode 100644 tests/panthor/panthor_gem.c
create mode 100644 tests/panthor/panthor_group.c
create mode 100644 tests/panthor/panthor_vm.c
diff --git a/lib/igt_panthor.c b/lib/igt_panthor.c
index 0b690f796..5d3b572b4 100644
--- a/lib/igt_panthor.c
+++ b/lib/igt_panthor.c
@@ -39,3 +39,191 @@ void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err)
else
do_ioctl(fd, DRM_IOCTL_PANTHOR_DEV_QUERY, &query);
}
+
+/**
+ * igt_panthor_vm_create:
+ * @fd: device file descriptor
+ * @vm_id: pointer to store the created VM ID
+ * @err: expected error code, or 0 for success
+ *
+ * Creates a VM.
+ */
+void igt_panthor_vm_create(int fd, uint32_t *vm_id, int err)
+{
+ struct drm_panthor_vm_create vm_create = {};
+
+ if (err) {
+ do_ioctl_err(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create, err);
+ } else {
+ do_ioctl(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create);
+ *vm_id = vm_create.id;
+ }
+}
+
+/**
+ * igt_panthor_vm_destroy:
+ * @fd: device file descriptor
+ * @vm_id: VM ID to destroy
+ * @err: expected error code, or 0 for success
+ *
+ * Destroys a VM.
+ */
+void igt_panthor_vm_destroy(int fd, uint32_t vm_id, int err)
+{
+ struct drm_panthor_vm_destroy vm_destroy = {
+ .id = vm_id,
+ };
+
+ if (err)
+ do_ioctl_err(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy, err);
+ else
+ do_ioctl(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy);
+}
+
+/**
+ * igt_panthor_vm_bind:
+ * @fd: device file descriptor
+ * @vm_id: VM ID to bind the buffer to
+ * @bo_handle: buffer object handle to bind
+ * @va: virtual address to bind at
+ * @size: size of the binding
+ * @flags: binding flags
+ * @err: expected error code, or 0 for success
+ *
+ * Bind a buffer object to a virtual address in the specified VM.
+ */
+void igt_panthor_vm_bind(int fd, uint32_t vm_id, uint32_t bo_handle,
+ uint64_t va, uint64_t size, uint32_t flags, int err)
+{
+ struct drm_panthor_vm_bind_op bind_op = {
+ .flags = flags,
+ .bo_handle = bo_handle,
+ .va = va,
+ .size = size,
+ };
+
+ struct drm_panthor_vm_bind vm_bind = {
+ .vm_id = vm_id,
+ .flags = 0,
+ .ops = DRM_PANTHOR_OBJ_ARRAY(1, &bind_op),
+ };
+
+ if (err)
+ do_ioctl_err(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind, err);
+ else
+ do_ioctl(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind);
+}
+
+/**
+ * igt_panthor_bo_create:
+ * @fd: device file descriptor
+ * @bo: pointer to panthor_bo structure to initialize
+ * @size: requested buffer size in bytes
+ * @flags: buffer object creation flags
+ * @err: expected error code, or 0 for success
+ *
+ * Creates a new buffer object
+ */
+void igt_panthor_bo_create(int fd, struct panthor_bo *bo,
+ uint64_t size, uint32_t flags, int err)
+{
+ struct drm_panthor_bo_create bo_create = {
+ .size = size,
+ .flags = flags,
+ };
+
+ if (err)
+ do_ioctl_err(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create, err);
+ else
+ do_ioctl(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create);
+
+ bo->handle = bo_create.handle;
+ bo->size = bo_create.size;
+ bo->offset = 0;
+ bo->map = NULL;
+}
+
+/**
+ * igt_panthor_bo_mmap_offset:
+ * @fd: device file descriptor
+ * @handle: buffer object handle
+ * @err: expected error code, or 0 for success
+ *
+ * Get the mmap offset for a buffer object.
+ *
+ * Returns: the mmap offset for the buffer object
+ */
+uint64_t igt_panthor_bo_mmap_offset(int fd, uint32_t handle, int err)
+{
+ struct drm_panthor_bo_mmap_offset bo_mmap_offset = {
+ .handle = handle,
+ };
+
+ if (err)
+ do_ioctl_err(fd, DRM_IOCTL_PANTHOR_BO_MMAP_OFFSET, &bo_mmap_offset, err);
+ else
+ do_ioctl(fd, DRM_IOCTL_PANTHOR_BO_MMAP_OFFSET, &bo_mmap_offset);
+
+ return bo_mmap_offset.offset;
+}
+
+/**
+ * igt_panthor_mmap_bo:
+ * @fd: device file descriptor
+ * @handle: buffer object handle
+ * @size: size of the buffer to map
+ * @prot: memory protection flags (e.g., PROT_READ | PROT_WRITE)
+ * @offset: mmap offset for the buffer object
+ *
+ * Map a buffer object into the process address space.
+ *
+ * Returns: pointer to the mapped memory, or NULL on failure
+ */
+void *igt_panthor_mmap_bo(int fd, uint32_t handle, uint64_t size,
+ unsigned int prot, uint64_t offset)
+{
+ void *ptr;
+
+ ptr = mmap(0, size, prot, MAP_SHARED, fd, offset);
+ if (ptr == MAP_FAILED)
+ return NULL;
+ return ptr;
+}
+
+/**
+ * igt_panthor_bo_create_mapped:
+ * @fd: device file descriptor
+ * @bo: pointer to panthor_bo structure to initialize
+ * @size: requested buffer size in bytes
+ * @flags: buffer object creation flags
+ * @err: expected error code, or 0 for success
+ *
+ * Create a new buffer object on the panthor device and map it into
+ * the process address space.
+ */
+void igt_panthor_bo_create_mapped(int fd, struct panthor_bo *bo, uint64_t size,
+ uint32_t flags, int err)
+{
+ igt_panthor_bo_create(fd, bo, size, flags, err);
+ bo->offset = igt_panthor_bo_mmap_offset(fd, bo->handle, err);
+ bo->map = igt_panthor_mmap_bo(fd, bo->handle, bo->size,
+ PROT_READ | PROT_WRITE, bo->offset);
+}
+
+/**
+ * igt_panthor_free_bo:
+ * @fd: panthor device file descriptor
+ * @bo: pointer to panthor_bo structure to free
+ *
+ * Free a buffer object and unmap it if it was mapped.
+ */
+void igt_panthor_free_bo(int fd, struct panthor_bo *bo)
+{
+ if (!bo)
+ return;
+
+ if (bo->map)
+ munmap(bo->map, bo->size);
+
+ gem_close(fd, bo->handle);
+}
diff --git a/lib/igt_panthor.h b/lib/igt_panthor.h
index a99b7102d..275ad54d6 100644
--- a/lib/igt_panthor.h
+++ b/lib/igt_panthor.h
@@ -7,6 +7,24 @@
#include <stddef.h>
#include <stdint.h>
+struct panthor_bo {
+ int handle;
+ uint64_t offset;
+ uint64_t size;
+ void *map;
+};
+
void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err);
+void igt_panthor_vm_create(int fd, uint32_t *vm_id, int err);
+void igt_panthor_vm_destroy(int fd, uint32_t vm_id, int err);
+void igt_panthor_vm_bind(int fd, uint32_t vm_id, uint32_t bo_handle,
+ uint64_t va, uint64_t size, uint32_t flags, int err);
+void igt_panthor_bo_create(int fd, struct panthor_bo *bo, uint64_t size, uint32_t flags, int err);
+uint64_t igt_panthor_bo_mmap_offset(int fd, uint32_t handle, int err);
+void igt_panthor_free_bo(int fd, struct panthor_bo *bo);
+void igt_panthor_bo_create_mapped(int fd, struct panthor_bo *bo, uint64_t size,
+ uint32_t flags, int err);
+void *igt_panthor_mmap_bo(int fd, uint32_t handle, uint64_t size,
+ unsigned int prot, uint64_t offset);
#endif /* IGT_PANTHOR_H */
diff --git a/tests/panthor/meson.build b/tests/panthor/meson.build
index ce13aebaa..42a46e993 100644
--- a/tests/panthor/meson.build
+++ b/tests/panthor/meson.build
@@ -1,5 +1,8 @@
panthor_progs = [
- 'panthor_query'
+ 'panthor_gem',
+ 'panthor_group',
+ 'panthor_query',
+ 'panthor_vm',
]
foreach prog : panthor_progs
diff --git a/tests/panthor/panthor_gem.c b/tests/panthor/panthor_gem.c
new file mode 100644
index 000000000..7e8e2084d
--- /dev/null
+++ b/tests/panthor/panthor_gem.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
+
+#include "igt.h"
+#include "igt_core.h"
+#include "igt_panthor.h"
+
+igt_main {
+ int fd;
+
+ igt_fixture { fd = drm_open_driver(DRIVER_PANTHOR); }
+
+ igt_describe("Create a buffer object");
+ igt_subtest("bo_create") {
+ struct panthor_bo bo;
+
+ igt_panthor_bo_create(fd, &bo, 4096, 0, 0);
+ igt_assert(bo.handle != 0);
+
+ igt_panthor_free_bo(fd, &bo);
+ }
+
+ igt_describe("Create a fake mmap offset for a buffer object");
+ igt_subtest("bo_mmap_offset") {
+ struct panthor_bo bo;
+ uint64_t mmap_offset;
+
+ igt_panthor_bo_create(fd, &bo, 4096, 0, 0);
+ igt_assert(bo.handle != 0);
+
+ mmap_offset = igt_panthor_bo_mmap_offset(fd, bo.handle, 0);
+ igt_assert(mmap_offset != 0);
+
+ igt_panthor_free_bo(fd, &bo);
+ }
+
+ igt_describe("Same as bo_mmap_offset but with an invalid handle");
+ igt_subtest("bo_mmap_offset_invalid_handle") {
+ struct panthor_bo bo;
+ uint64_t mmap_offset;
+
+ igt_panthor_bo_create(fd, &bo, 4096, 0, 0);
+ igt_assert(bo.handle != 0);
+
+ mmap_offset = igt_panthor_bo_mmap_offset(fd, 0xdeadbeef, ENOENT);
+ igt_assert(mmap_offset == 0);
+
+ igt_panthor_free_bo(fd, &bo);
+ }
+
+ igt_describe_f("Create a buffer object whose size is not page-aligned, and check "
+ "that the allocated size is rounded up to the next page size %lu.",
+ 8192UL);
+ igt_subtest("bo_create_round_size") {
+ struct panthor_bo bo;
+ uint64_t expected_size = 8192;
+
+ igt_panthor_bo_create(fd, &bo, 5000, 0, 0);
+ igt_assert(bo.handle != 0);
+ igt_assert(bo.size == expected_size);
+
+ igt_panthor_free_bo(fd, &bo);
+ }
+
+ igt_fixture { drm_close_driver(fd); }
+}
diff --git a/tests/panthor/panthor_group.c b/tests/panthor/panthor_group.c
new file mode 100644
index 000000000..0a3b746d8
--- /dev/null
+++ b/tests/panthor/panthor_group.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
+
+#include <stdint.h>
+#include <sys/mman.h>
+#include <endian.h> // For htole64
+#include <unistd.h>
+
+#include "drm.h"
+#include "igt.h"
+#include "igt_core.h"
+#include "igt_panthor.h"
+#include "panthor_drm.h"
+
+static void
+issue_store_multiple(u8 *command_stream, uint64_t kernel_va, uint32_t constant)
+{
+ uint64_t opcode, reg_num, mov48, store_multiple, flush;
+ uint64_t sr, src0, register_bitmap, offset;
+
+ // MOV48: Load the source register ([r68; r69]) with the kernel address
+ opcode = 0x1;
+ reg_num = 68;
+ mov48 = (opcode << 56) | (reg_num << 48) | kernel_va;
+ mov48 = htole64(mov48);
+ memcpy(&command_stream[0], &mov48, sizeof(mov48));
+
+ // MOV48: Load a known constant into r70
+ opcode = 0x1;
+ reg_num = 70;
+ mov48 = (opcode << 56) | (reg_num << 48) | constant;
+ mov48 = htole64(mov48);
+ memcpy(&command_stream[8], &mov48, sizeof(mov48));
+
+ // STORE_MULTIPLE: Store the first register to the address pointed to by [r68; r69]
+ opcode = 0x15; // STORE_MULTIPLE
+ sr = 70; // Starting from register r70
+ src0 = 68; // Address pointed to by [r68; r69]
+ register_bitmap = 1; // Store the first register
+ offset = 0; // Offset
+ store_multiple = (opcode << 56) | (sr << 48) | (src0 << 40) |
+ (register_bitmap << 16) | offset;
+ store_multiple = htole64(store_multiple);
+ memcpy(&command_stream[16], &store_multiple, sizeof(store_multiple));
+
+ opcode = 0x1;
+ reg_num = 68;
+ mov48 = (opcode << 56) | (reg_num << 48) | 0;
+ mov48 = htole64(mov48);
+ memcpy(&command_stream[24], &mov48, sizeof(mov48));
+
+ opcode = 36;
+ flush = opcode << 56 | 0ull << 48 | reg_num << 40 | 0ull << 16 | 0x233;
+ flush = htole64(flush);
+ memcpy(&command_stream[32], &flush, sizeof(flush));
+}
+
+igt_main {
+ int fd;
+
+ igt_fixture { fd = drm_open_driver(DRIVER_PANTHOR); }
+
+ igt_describe("Create and destroy a CSF group.");
+ igt_subtest("group_create") {
+ struct drm_panthor_gpu_info gpu_info = {};
+ struct drm_panthor_vm_create vm_create = {};
+ struct drm_panthor_group_create group_create = {};
+ struct drm_panthor_queue_create queue = {};
+ struct drm_panthor_obj_array queues = {};
+ struct drm_panthor_group_destroy group_destroy = {};
+ struct drm_panthor_vm_destroy vm_destroy = {};
+
+ igt_panthor_query(fd, DRM_PANTHOR_DEV_QUERY_GPU_INFO,
+ &gpu_info, sizeof(gpu_info), 0);
+ igt_assert(gpu_info.gpu_id != 0);
+
+ vm_create.flags = 0;
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create), 0);
+ igt_assert(vm_create.id != 0);
+
+ queue.priority = 0; // Low priority
+ queue.ringbuf_size = 4096; // Example size
+ queues = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &queue);
+
+ group_create.queues = queues;
+ group_create.max_compute_cores = 1;
+ group_create.max_fragment_cores = 1;
+ group_create.max_tiler_cores = 1;
+ group_create.priority = PANTHOR_GROUP_PRIORITY_MEDIUM;
+ group_create.compute_core_mask = gpu_info.shader_present & 0x1; // Use first core
+ group_create.fragment_core_mask = gpu_info.shader_present & 0x1; // Use first core
+ group_create.tiler_core_mask = gpu_info.tiler_present & 0x1; // Use first tiler
+ group_create.vm_id = vm_create.id;
+
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_CREATE, &group_create), 0);
+ igt_assert(group_create.group_handle != 0);
+
+ // Cleanup: Destroy the group and VM
+ group_destroy = (struct drm_panthor_group_destroy){
+ .group_handle = group_create.group_handle
+ };
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_DESTROY, &group_destroy), 0);
+
+ vm_destroy = (struct drm_panthor_vm_destroy) { .id = vm_create.id };
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy), 0);
+ }
+
+ igt_describe("Submit a job to a group and wait for completion. "
+ "The job writes a known value to a buffer object that is then "
+ "mmaped and checked.");
+ igt_subtest("group_submit") {
+ struct drm_panthor_gpu_info gpu_info = {};
+ struct drm_panthor_vm_create vm_create = {};
+ struct drm_panthor_group_create group_create = {};
+ struct drm_panthor_queue_create queue = {};
+ struct drm_panthor_obj_array queues = {};
+ struct drm_panthor_group_submit group_submit = {};
+ struct drm_panthor_queue_submit queue_submit = {};
+ struct drm_panthor_group_destroy group_destroy = {};
+ struct drm_panthor_obj_array queue_submits = {};
+ struct drm_panthor_vm_destroy vm_destroy = {};
+ struct drm_panthor_bo_create bo_create = {};
+ struct drm_panthor_vm_bind vm_bind = {};
+ struct drm_panthor_vm_bind_op vm_bind_op = {};
+ struct drm_syncobj_wait wait = {};
+ struct drm_syncobj_create syncobj_create = {};
+ struct drm_panthor_sync_op sync_op = {};
+ struct drm_gem_close gem_close = {};
+ struct drm_syncobj_destroy syncobj_destroy = {};
+ uint64_t command_stream_gpu_addr;
+ uint32_t command_stream_size;
+ uint64_t result_gpu_addr;
+ uint32_t cmd_buf_bo_handle;
+ uint32_t result_bo_handle;
+ uint32_t syncobj_handle;
+ uint8_t command_stream[64] = {0};
+ uint8_t *bo_cpu_addr;
+ uint8_t *result_cpu_addr;
+ const int INITIAL_VA = 0x1000000;
+ uint64_t bo_mmap_offset;
+
+ igt_panthor_query(fd, DRM_PANTHOR_DEV_QUERY_GPU_INFO,
+ &gpu_info, sizeof(gpu_info), 0);
+ igt_assert(gpu_info.gpu_id != 0);
+
+ vm_create.flags = 0;
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create), 0);
+ igt_assert(vm_create.id != 0);
+
+ bo_create.size = 4096;
+ bo_create.flags = 0;
+ bo_create.exclusive_vm_id = vm_create.id;
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create), 0);
+ igt_assert(bo_create.handle != 0);
+ cmd_buf_bo_handle = bo_create.handle;
+
+ vm_bind_op.flags = DRM_PANTHOR_VM_BIND_OP_TYPE_MAP;
+ vm_bind_op.bo_handle = cmd_buf_bo_handle;
+ vm_bind_op.bo_offset = 0;
+ vm_bind_op.va = INITIAL_VA;
+ vm_bind_op.size = bo_create.size;
+ vm_bind.ops = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &vm_bind_op);
+ vm_bind.vm_id = vm_create.id;
+ vm_bind.flags = 0;
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind), 0);
+
+ command_stream_gpu_addr = vm_bind_op.va;
+ command_stream_size = sizeof(command_stream);
+
+ bo_mmap_offset = igt_panthor_bo_mmap_offset(fd, cmd_buf_bo_handle, 0);
+ bo_cpu_addr = igt_panthor_mmap_bo(fd, cmd_buf_bo_handle,
+ bo_create.size, PROT_READ | PROT_WRITE,
+ bo_mmap_offset);
+ igt_assert(bo_cpu_addr);
+
+ // Create the BO to receive the result of the store.
+ memset(&bo_create, 0, sizeof(bo_create));
+ bo_create.size = 4096;
+ bo_create.flags = 0;
+ bo_create.exclusive_vm_id = vm_create.id;
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create), 0);
+ igt_assert(bo_create.handle != 0);
+ result_bo_handle = bo_create.handle;
+
+ // Also bind the result BO.
+ vm_bind_op.flags = DRM_PANTHOR_VM_BIND_OP_TYPE_MAP;
+ vm_bind_op.bo_handle = result_bo_handle;
+ vm_bind_op.bo_offset = 0;
+ vm_bind_op.va = INITIAL_VA + 4096;
+ vm_bind_op.size = bo_create.size;
+ vm_bind.ops = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &vm_bind_op);
+ vm_bind.vm_id = vm_create.id;
+ vm_bind.flags = 0;
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind), 0);
+ result_gpu_addr = vm_bind_op.va;
+
+ issue_store_multiple(command_stream, result_gpu_addr, 0xdeadbeef);
+ memcpy(bo_cpu_addr, command_stream, command_stream_size);
+ munmap(bo_cpu_addr, bo_create.size);
+
+ queue.priority = 0;
+ queue.ringbuf_size = 4096;
+ queues = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &queue);
+
+ group_create.queues = queues;
+ group_create.max_compute_cores = 1;
+ group_create.max_fragment_cores = 1;
+ group_create.max_tiler_cores = 1;
+ group_create.priority = PANTHOR_GROUP_PRIORITY_MEDIUM;
+ group_create.compute_core_mask = gpu_info.shader_present & 0x1;
+ group_create.fragment_core_mask = gpu_info.shader_present & 0x1;
+ group_create.tiler_core_mask = gpu_info.tiler_present & 0x1;
+ group_create.vm_id = vm_create.id;
+
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_CREATE, &group_create), 0);
+ igt_assert(group_create.group_handle != 0);
+
+ syncobj_create = (struct drm_syncobj_create){
+ .flags = 0,
+ };
+
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &syncobj_create), 0);
+ syncobj_handle = syncobj_create.handle;
+
+ sync_op = (struct drm_panthor_sync_op) {
+ .handle = syncobj_handle,
+ .flags = DRM_PANTHOR_SYNC_OP_SIGNAL,
+ };
+
+ queue_submit.syncs = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &sync_op);
+
+ queue_submit.queue_index = 0;
+ queue_submit.stream_size = command_stream_size;
+ queue_submit.stream_addr = command_stream_gpu_addr;
+ queue_submit.latest_flush = 0;
+ queue_submits = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &queue_submit);
+
+ group_submit.group_handle = group_create.group_handle;
+ group_submit.queue_submits = queue_submits;
+
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_SUBMIT, &group_submit), 0);
+
+ wait = (struct drm_syncobj_wait) {
+ .handles = (uint64_t)&syncobj_handle,
+ .count_handles = 1,
+ .timeout_nsec = INT64_MAX,
+ .flags = 0,
+ };
+
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, &wait), 0);
+
+ bo_mmap_offset = igt_panthor_bo_mmap_offset(fd, result_bo_handle, 0);
+ result_cpu_addr = igt_panthor_mmap_bo(fd, result_bo_handle,
+ bo_create.size, PROT_READ | PROT_WRITE, bo_mmap_offset);
+
+ igt_assert(*(uint32_t *)result_cpu_addr == 0xdeadbeef);
+ munmap(result_cpu_addr, bo_create.size);
+
+ syncobj_destroy.handle = syncobj_handle;
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &syncobj_destroy), 0);
+
+ group_destroy.group_handle = group_create.group_handle;
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_DESTROY, &group_destroy), 0);
+
+ vm_destroy.id = vm_create.id;
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy), 0);
+
+ gem_close.handle = cmd_buf_bo_handle;
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close), 0);
+
+ gem_close.handle = result_bo_handle;
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close), 0);
+}
+
+ igt_fixture { drm_close_driver(fd); }
+}
diff --git a/tests/panthor/panthor_vm.c b/tests/panthor/panthor_vm.c
new file mode 100644
index 000000000..1b641b601
--- /dev/null
+++ b/tests/panthor/panthor_vm.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
+
+#include "igt.h"
+#include "igt_core.h"
+#include "igt_panthor.h"
+#include "panthor_drm.h"
+
+igt_main {
+ int fd;
+
+ igt_fixture { fd = drm_open_driver(DRIVER_PANTHOR); }
+
+ igt_describe("Create and destroy a VM");
+ igt_subtest("vm_create_destroy") {
+ uint32_t vm_id;
+
+ igt_panthor_vm_create(fd, &vm_id, 0);
+ igt_assert(vm_id != 0);
+
+ igt_panthor_vm_destroy(fd, vm_id, 0);
+ }
+
+ igt_subtest("vm_destroy_invalid") {
+ igt_panthor_vm_destroy(fd, 0xdeadbeef, EINVAL);
+ }
+
+ igt_describe("Test the VM_BIND API synchronously");
+ igt_subtest("vm_bind") {
+ uint32_t vm_id;
+ struct panthor_bo bo;
+ uint64_t bo_size = 0x1000;
+
+ igt_panthor_vm_create(fd, &vm_id, 0);
+ igt_assert(vm_id != 0);
+
+ igt_panthor_bo_create(fd, &bo, bo_size, 0, 0);
+ igt_panthor_vm_bind(fd, vm_id, bo.handle,
+ 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0);
+
+ igt_panthor_vm_destroy(fd, vm_id, 0);
+ }
+
+ igt_describe("Test unbinding a previously bound range");
+ igt_subtest("vm_unbind") {
+ uint32_t vm_id;
+ struct panthor_bo bo;
+ uint64_t bo_size = 0x1000;
+
+ igt_panthor_vm_create(fd, &vm_id, 0);
+ igt_assert(vm_id != 0);
+
+ igt_panthor_bo_create(fd, &bo, bo_size, 0, 0);
+ igt_panthor_vm_bind(fd, vm_id, bo.handle,
+ 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0);
+ igt_panthor_vm_bind(fd, vm_id, 0,
+ 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, 0);
+
+ igt_panthor_vm_destroy(fd, vm_id, 0);
+ }
+
+ igt_describe("Test unbinding an address range that was not previously bound");
+ igt_subtest("vm_unbind_invalid_address") {
+ uint32_t vm_id;
+ struct panthor_bo bo;
+ uint64_t bo_size = 0x1000;
+
+ igt_panthor_vm_create(fd, &vm_id, 0);
+ igt_assert(vm_id != 0);
+
+ igt_panthor_bo_create(fd, &bo, bo_size, 0, 0);
+
+ /* This was not bound previously*/
+ igt_panthor_vm_bind(fd, vm_id, bo.handle,
+ 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, EINVAL);
+ igt_panthor_vm_destroy(fd, vm_id, 0);
+ }
+
+ igt_fixture { drm_close_driver(fd); }
+}
--
2.51.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH i-g-t v2 0/3] Add initial Panthor tests
2025-09-12 18:19 [PATCH i-g-t v2 0/3] Add initial Panthor tests Daniel Almeida
` (2 preceding siblings ...)
2025-09-12 18:19 ` [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests Daniel Almeida
@ 2025-09-15 14:40 ` Steven Price
3 siblings, 0 replies; 15+ messages in thread
From: Steven Price @ 2025-09-15 14:40 UTC (permalink / raw)
To: Daniel Almeida, adrinael, arek, kamil.konieczny,
juhapekka.heikkila, bhanuprakash.modem, ashutosh.dixit,
karthik.b.s, boris.brezillon, liviu.dudau, aliceryhl, jeffv
Cc: intel-gfx, igt-dev, dri-devel
On 12/09/2025 19:19, Daniel Almeida wrote:
> This series adds basic Panthor tests. In particular, these are being
> used to test both Panthor[0] and Tyr[1], i.e.: the new Rust GPU driver
> that implements Panthor's uAPI (i.e.: panthor_drm.h). Most of the
> initial tests were chosen in order to have something to test Tyr with,
> but this series lays the groundwork so that more interesting tests can
> be added to test more of Panthor itself.
>
> This work is being tested on a RockPi 5, featuring an rk3588 SoC and
> Mali-G610 Valhall.
>
> Note that there's a few (less than five?) remaining checkpatch.pl
> comments about long lines. IMHO there's no way to format them better so
> I hope we can live with this.
>
> [0]: https://patchwork.freedesktop.org/patch/msgid/20240229162230.2634044-12-boris.brezillon@collabora.com
> [1]: https://lore.kernel.org/dri-devel/aMLB0Vs0dJ_AkU4z@google.com/
>
> Changes from v1:
> - Rebased on top of the latest master
> - Squashed patch 3 from v1 into patch 2.
> - Switched to /* */ comments in headers
> - Initialized padding fields to 0 as applicable in group_destroy and
> vm_destroy
> - Removed wrong assert(gpu_rev != 0)
> - Changed indentation to use tabs
> - Rework igt_panthor_mmap_bo to take an offset (so we don't call the
> mmap_offset ioctl twice)
> - Added igt_describe and docs to the functions igt_panthor.c
> - Linked to the driver in the cover letter and patch 1.
> - Improved the commit message for patch 1.
> Link to v1: https://lore.kernel.org/dri-devel/20250828130402.2549948-1-daniel.almeida@collabora.com/
Looks good to me, and all the tests now pass (using Panthor) on my Rock5B.
Tested-by: Steven Price <steven.price@arm.com>
Thanks,
Steve
>
> Daniel Almeida (3):
> lib: add support for opening Panthor devices
> panthor: add initial infrastructure
> tests/panthor: add panthor tests
>
> lib/drmtest.c | 1 +
> lib/drmtest.h | 1 +
> lib/igt_panthor.c | 229 ++++++++++++++++++++++++++++
> lib/igt_panthor.h | 30 ++++
> lib/meson.build | 1 +
> meson.build | 8 +
> tests/meson.build | 2 +
> tests/panthor/meson.build | 15 ++
> tests/panthor/panthor_gem.c | 66 ++++++++
> tests/panthor/panthor_group.c | 276 ++++++++++++++++++++++++++++++++++
> tests/panthor/panthor_query.c | 25 +++
> tests/panthor/panthor_vm.c | 80 ++++++++++
> 12 files changed, 734 insertions(+)
> create mode 100644 lib/igt_panthor.c
> create mode 100644 lib/igt_panthor.h
> create mode 100644 tests/panthor/meson.build
> create mode 100644 tests/panthor/panthor_gem.c
> create mode 100644 tests/panthor/panthor_group.c
> create mode 100644 tests/panthor/panthor_query.c
> create mode 100644 tests/panthor/panthor_vm.c
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH i-g-t v2 1/3] lib: add support for opening Panthor devices
2025-09-12 18:19 ` [PATCH i-g-t v2 1/3] lib: add support for opening Panthor devices Daniel Almeida
@ 2025-09-16 12:03 ` Kamil Konieczny
0 siblings, 0 replies; 15+ messages in thread
From: Kamil Konieczny @ 2025-09-16 12:03 UTC (permalink / raw)
To: Daniel Almeida
Cc: adrinael, arek, juhapekka.heikkila, bhanuprakash.modem,
ashutosh.dixit, karthik.b.s, boris.brezillon, liviu.dudau,
steven.price, aliceryhl, jeffv, intel-gfx, igt-dev, dri-devel
Hi Daniel,
On 2025-09-12 at 15:19:28 -0300, Daniel Almeida wrote:
> We will be adding tests for Panthor in a subsequent patch, so first add
> the ability to open the device.
>
> In particular, these will be used to test both Panthor[0] and Tyr[1],
> i.e.: the new Rust GPU driver that implements Panthor's uAPI (i.e.:
> panthor_drm.h).
>
> This work is being tested on a RockPi 5, featuring an rk3588 SoC and
> Mali-G610 Valhall.
>
> [0]: https://patchwork.freedesktop.org/patch/msgid/20240229162230.2634044-12-boris.brezillon@collabora.com
> [1]: https://lore.kernel.org/dri-devel/aMLB0Vs0dJ_AkU4z@google.com/
>
> Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> ---
> lib/drmtest.c | 1 +
> lib/drmtest.h | 1 +
> 2 files changed, 2 insertions(+)
>
> diff --git a/lib/drmtest.c b/lib/drmtest.c
> index 551385867..ea37a886a 100644
> --- a/lib/drmtest.c
> +++ b/lib/drmtest.c
> @@ -220,6 +220,7 @@ static const struct module {
> { DRIVER_INTEL, "i915", modprobe_i915 },
> { DRIVER_MSM, "msm" },
> { DRIVER_PANFROST, "panfrost" },
> + { DRIVER_PANTHOR, "panthor" },
> { DRIVER_V3D, "v3d" },
> { DRIVER_VC4, "vc4" },
> { DRIVER_VGEM, "vgem" },
> diff --git a/lib/drmtest.h b/lib/drmtest.h
> index a9542dde2..4c34ac311 100644
> --- a/lib/drmtest.h
> +++ b/lib/drmtest.h
> @@ -56,6 +56,7 @@ int __get_drm_device_name(int fd, char *name, int name_size);
> #define DRIVER_XE (1 << 7)
> #define DRIVER_VMWGFX (1 << 8)
> #define DRIVER_VKMS (1 << 9)
> +#define DRIVER_PANTHOR (1 << 10)
>
> /*
> * Exclude DRVER_VGEM from DRIVER_ANY since if you run on a system
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH i-g-t v2 2/3] panthor: add initial infrastructure
2025-09-12 18:19 ` [PATCH i-g-t v2 2/3] panthor: add initial infrastructure Daniel Almeida
@ 2025-09-16 12:12 ` Kamil Konieczny
2025-09-25 12:42 ` Daniel Almeida
0 siblings, 1 reply; 15+ messages in thread
From: Kamil Konieczny @ 2025-09-16 12:12 UTC (permalink / raw)
To: Daniel Almeida
Cc: adrinael, arek, juhapekka.heikkila, bhanuprakash.modem,
ashutosh.dixit, karthik.b.s, boris.brezillon, liviu.dudau,
steven.price, aliceryhl, jeffv, intel-gfx, igt-dev, dri-devel
Hi Daniel,
On 2025-09-12 at 15:19:29 -0300, Daniel Almeida wrote:
> Add the necessary code needed to compile panthor tests as well as the
> basic infrastructure that will be used by the Panthor tests themselves.
>
> To make sure everything is in order, add a basic test in
> panthor_query.c.
>
> Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
> ---
> lib/igt_panthor.c | 41 +++++++++++++++++++++++++++++++++++
> lib/igt_panthor.h | 12 ++++++++++
> lib/meson.build | 1 +
> meson.build | 8 +++++++
> tests/meson.build | 2 ++
> tests/panthor/meson.build | 12 ++++++++++
> tests/panthor/panthor_query.c | 25 +++++++++++++++++++++
> 7 files changed, 101 insertions(+)
> create mode 100644 lib/igt_panthor.c
> create mode 100644 lib/igt_panthor.h
> create mode 100644 tests/panthor/meson.build
> create mode 100644 tests/panthor/panthor_query.c
>
> diff --git a/lib/igt_panthor.c b/lib/igt_panthor.c
> new file mode 100644
> index 000000000..0b690f796
> --- /dev/null
> +++ b/lib/igt_panthor.c
> @@ -0,0 +1,41 @@
> +// SPDX-License-Identifier: MIT
> +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
We use SPD for licence because they are long texts. I do not
see any benefit of SPDX for copyright lines, it makes it even
longer than needed. It could stay if you want.
Acked-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
Regards,
Kamil
> +
> +#include "drmtest.h"
> +#include "igt_panthor.h"
> +#include "ioctl_wrappers.h"
> +#include "panthor_drm.h"
> +
> +/**
> + * SECTION:igt_panthor
> + * @short_description: Panthor support library
> + * @title: Panthor
> + * @include: igt.h
> + *
> + * This library provides various auxiliary helper functions for writing Panthor
> + * tests.
> + */
> +
> +/**
> + * igt_panthor_query:
> + * @fd: device file descriptor
> + * @type: query type (e.g., DRM_PANTHOR_DEV_QUERY_GPU_INFO)
> + * @data: pointer to a struct to store the query result
> + * @size: size of the result struct
> + * @err: expected error code, or 0 for success
> + *
> + * Query GPU information.
> + */
> +void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err)
> +{
> + struct drm_panthor_dev_query query = {
> + .type = type,
> + .pointer = (uintptr_t)data,
> + .size = size,
> + };
> +
> + if (err)
> + do_ioctl_err(fd, DRM_IOCTL_PANTHOR_DEV_QUERY, &query, err);
> + else
> + do_ioctl(fd, DRM_IOCTL_PANTHOR_DEV_QUERY, &query);
> +}
> diff --git a/lib/igt_panthor.h b/lib/igt_panthor.h
> new file mode 100644
> index 000000000..a99b7102d
> --- /dev/null
> +++ b/lib/igt_panthor.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: MIT */
> +/* SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd. */
> +
> +#ifndef IGT_PANTHOR_H
> +#define IGT_PANTHOR_H
> +
> +#include <stddef.h>
> +#include <stdint.h>
> +
> +void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err);
> +
> +#endif /* IGT_PANTHOR_H */
> diff --git a/lib/meson.build b/lib/meson.build
> index f50a8d44b..4ccf3ee04 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -105,6 +105,7 @@ lib_sources = [
> 'igt_kmod.c',
> 'igt_ktap.c',
> 'igt_panfrost.c',
> + 'igt_panthor.c',
> 'igt_v3d.c',
> 'igt_vc4.c',
> 'igt_vmwgfx.c',
> diff --git a/meson.build b/meson.build
> index f7ae427b3..56ef8730e 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -288,6 +288,7 @@ libexecdir = join_paths(get_option('libexecdir'), 'igt-gpu-tools')
> amdgpudir = join_paths(libexecdir, 'amdgpu')
> msmdir = join_paths(libexecdir, 'msm')
> panfrostdir = join_paths(libexecdir, 'panfrost')
> +panthordir = join_paths(libexecdir, 'panthor')
> v3ddir = join_paths(libexecdir, 'v3d')
> vc4dir = join_paths(libexecdir, 'vc4')
> vkmsdir = join_paths(libexecdir, 'vkms')
> @@ -341,6 +342,12 @@ if get_option('use_rpath')
> endforeach
> panfrost_rpathdir = join_paths(panfrost_rpathdir, libdir)
>
> + panthor_rpathdir = '$ORIGIN'
> + foreach p : panthordir.split('/')
> + panthor_rpathdir = join_paths(panthor_rpathdir, '..')
> + endforeach
> + panthor_rpathdir = join_paths(panthor_rpathdir, libdir)
> +
> v3d_rpathdir = '$ORIGIN'
> foreach p : v3ddir.split('/')
> v3d_rpathdir = join_paths(v3d_rpathdir, '..')
> @@ -370,6 +377,7 @@ else
> amdgpudir_rpathdir = ''
> msm_rpathdir = ''
> panfrost_rpathdir = ''
> + panthor_rpathdir = ''
> v3d_rpathdir = ''
> vc4_rpathdir = ''
> vkms_rpathdir = ''
> diff --git a/tests/meson.build b/tests/meson.build
> index a7b9375ed..0b61561a4 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -486,6 +486,8 @@ subdir('msm')
>
> subdir('panfrost')
>
> +subdir('panthor')
> +
> subdir('v3d')
>
> subdir('vc4')
> diff --git a/tests/panthor/meson.build b/tests/panthor/meson.build
> new file mode 100644
> index 000000000..ce13aebaa
> --- /dev/null
> +++ b/tests/panthor/meson.build
> @@ -0,0 +1,12 @@
> +panthor_progs = [
> + 'panthor_query'
> +]
> +
> +foreach prog : panthor_progs
> + test_executables += executable(prog, prog + '.c',
> + dependencies : test_deps,
> + install_dir : panthordir,
> + install_rpath : panthor_rpathdir,
> + install : true)
> + test_list += join_paths('panthor', prog)
> +endforeach
> diff --git a/tests/panthor/panthor_query.c b/tests/panthor/panthor_query.c
> new file mode 100644
> index 000000000..7c1055763
> --- /dev/null
> +++ b/tests/panthor/panthor_query.c
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: MIT
> +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
> +
> +#include "igt.h"
> +#include "igt_core.h"
> +#include "igt_panthor.h"
> +#include "panthor_drm.h"
> +#include <stdint.h>
> +
> +igt_main {
> + int fd;
> +
> + igt_fixture { fd = drm_open_driver(DRIVER_PANTHOR); }
> +
> + igt_describe("Query GPU information from ROM.");
> + igt_subtest("query") {
> + struct drm_panthor_gpu_info gpu = {};
> +
> + igt_panthor_query(fd, DRM_PANTHOR_DEV_QUERY_GPU_INFO, &gpu, sizeof(gpu), 0);
> +
> + igt_assert(gpu.gpu_id != 0);
> + }
> +
> + igt_fixture { drm_close_driver(fd); }
> +}
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests
2025-09-12 18:19 ` [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests Daniel Almeida
@ 2025-09-16 12:15 ` Kamil Konieczny
2025-09-25 15:45 ` Daniel Stone
2025-09-25 17:46 ` Kamil Konieczny
2 siblings, 0 replies; 15+ messages in thread
From: Kamil Konieczny @ 2025-09-16 12:15 UTC (permalink / raw)
To: Daniel Almeida
Cc: adrinael, arek, juhapekka.heikkila, bhanuprakash.modem,
ashutosh.dixit, karthik.b.s, boris.brezillon, liviu.dudau,
steven.price, aliceryhl, jeffv, intel-gfx, igt-dev, dri-devel
Hi Daniel,
On 2025-09-12 at 15:19:30 -0300, Daniel Almeida wrote:
> Add an initial test suit covering query device properties, allocating
> memory, binding and unbinding VA ranges through VM_BIND and submitting a
> simple piece of work through GROUP_SUBMIT.
>
> Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
Same remark about imho unnecessary SPDX-copyright line where
simple Copyright (c) would be enough but it is not a blocker.
Acked-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
Regards,
Kamil
> ---
> lib/igt_panthor.c | 188 +++++++++++++++++++++++
> lib/igt_panthor.h | 18 +++
> tests/panthor/meson.build | 5 +-
> tests/panthor/panthor_gem.c | 66 ++++++++
> tests/panthor/panthor_group.c | 276 ++++++++++++++++++++++++++++++++++
> tests/panthor/panthor_vm.c | 80 ++++++++++
> 6 files changed, 632 insertions(+), 1 deletion(-)
> create mode 100644 tests/panthor/panthor_gem.c
> create mode 100644 tests/panthor/panthor_group.c
> create mode 100644 tests/panthor/panthor_vm.c
>
> diff --git a/lib/igt_panthor.c b/lib/igt_panthor.c
> index 0b690f796..5d3b572b4 100644
> --- a/lib/igt_panthor.c
> +++ b/lib/igt_panthor.c
> @@ -39,3 +39,191 @@ void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err)
> else
> do_ioctl(fd, DRM_IOCTL_PANTHOR_DEV_QUERY, &query);
> }
> +
> +/**
> + * igt_panthor_vm_create:
> + * @fd: device file descriptor
> + * @vm_id: pointer to store the created VM ID
> + * @err: expected error code, or 0 for success
> + *
> + * Creates a VM.
> + */
> +void igt_panthor_vm_create(int fd, uint32_t *vm_id, int err)
> +{
> + struct drm_panthor_vm_create vm_create = {};
> +
> + if (err) {
> + do_ioctl_err(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create, err);
> + } else {
> + do_ioctl(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create);
> + *vm_id = vm_create.id;
> + }
> +}
> +
> +/**
> + * igt_panthor_vm_destroy:
> + * @fd: device file descriptor
> + * @vm_id: VM ID to destroy
> + * @err: expected error code, or 0 for success
> + *
> + * Destroys a VM.
> + */
> +void igt_panthor_vm_destroy(int fd, uint32_t vm_id, int err)
> +{
> + struct drm_panthor_vm_destroy vm_destroy = {
> + .id = vm_id,
> + };
> +
> + if (err)
> + do_ioctl_err(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy, err);
> + else
> + do_ioctl(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy);
> +}
> +
> +/**
> + * igt_panthor_vm_bind:
> + * @fd: device file descriptor
> + * @vm_id: VM ID to bind the buffer to
> + * @bo_handle: buffer object handle to bind
> + * @va: virtual address to bind at
> + * @size: size of the binding
> + * @flags: binding flags
> + * @err: expected error code, or 0 for success
> + *
> + * Bind a buffer object to a virtual address in the specified VM.
> + */
> +void igt_panthor_vm_bind(int fd, uint32_t vm_id, uint32_t bo_handle,
> + uint64_t va, uint64_t size, uint32_t flags, int err)
> +{
> + struct drm_panthor_vm_bind_op bind_op = {
> + .flags = flags,
> + .bo_handle = bo_handle,
> + .va = va,
> + .size = size,
> + };
> +
> + struct drm_panthor_vm_bind vm_bind = {
> + .vm_id = vm_id,
> + .flags = 0,
> + .ops = DRM_PANTHOR_OBJ_ARRAY(1, &bind_op),
> + };
> +
> + if (err)
> + do_ioctl_err(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind, err);
> + else
> + do_ioctl(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind);
> +}
> +
> +/**
> + * igt_panthor_bo_create:
> + * @fd: device file descriptor
> + * @bo: pointer to panthor_bo structure to initialize
> + * @size: requested buffer size in bytes
> + * @flags: buffer object creation flags
> + * @err: expected error code, or 0 for success
> + *
> + * Creates a new buffer object
> + */
> +void igt_panthor_bo_create(int fd, struct panthor_bo *bo,
> + uint64_t size, uint32_t flags, int err)
> +{
> + struct drm_panthor_bo_create bo_create = {
> + .size = size,
> + .flags = flags,
> + };
> +
> + if (err)
> + do_ioctl_err(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create, err);
> + else
> + do_ioctl(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create);
> +
> + bo->handle = bo_create.handle;
> + bo->size = bo_create.size;
> + bo->offset = 0;
> + bo->map = NULL;
> +}
> +
> +/**
> + * igt_panthor_bo_mmap_offset:
> + * @fd: device file descriptor
> + * @handle: buffer object handle
> + * @err: expected error code, or 0 for success
> + *
> + * Get the mmap offset for a buffer object.
> + *
> + * Returns: the mmap offset for the buffer object
> + */
> +uint64_t igt_panthor_bo_mmap_offset(int fd, uint32_t handle, int err)
> +{
> + struct drm_panthor_bo_mmap_offset bo_mmap_offset = {
> + .handle = handle,
> + };
> +
> + if (err)
> + do_ioctl_err(fd, DRM_IOCTL_PANTHOR_BO_MMAP_OFFSET, &bo_mmap_offset, err);
> + else
> + do_ioctl(fd, DRM_IOCTL_PANTHOR_BO_MMAP_OFFSET, &bo_mmap_offset);
> +
> + return bo_mmap_offset.offset;
> +}
> +
> +/**
> + * igt_panthor_mmap_bo:
> + * @fd: device file descriptor
> + * @handle: buffer object handle
> + * @size: size of the buffer to map
> + * @prot: memory protection flags (e.g., PROT_READ | PROT_WRITE)
> + * @offset: mmap offset for the buffer object
> + *
> + * Map a buffer object into the process address space.
> + *
> + * Returns: pointer to the mapped memory, or NULL on failure
> + */
> +void *igt_panthor_mmap_bo(int fd, uint32_t handle, uint64_t size,
> + unsigned int prot, uint64_t offset)
> +{
> + void *ptr;
> +
> + ptr = mmap(0, size, prot, MAP_SHARED, fd, offset);
> + if (ptr == MAP_FAILED)
> + return NULL;
> + return ptr;
> +}
> +
> +/**
> + * igt_panthor_bo_create_mapped:
> + * @fd: device file descriptor
> + * @bo: pointer to panthor_bo structure to initialize
> + * @size: requested buffer size in bytes
> + * @flags: buffer object creation flags
> + * @err: expected error code, or 0 for success
> + *
> + * Create a new buffer object on the panthor device and map it into
> + * the process address space.
> + */
> +void igt_panthor_bo_create_mapped(int fd, struct panthor_bo *bo, uint64_t size,
> + uint32_t flags, int err)
> +{
> + igt_panthor_bo_create(fd, bo, size, flags, err);
> + bo->offset = igt_panthor_bo_mmap_offset(fd, bo->handle, err);
> + bo->map = igt_panthor_mmap_bo(fd, bo->handle, bo->size,
> + PROT_READ | PROT_WRITE, bo->offset);
> +}
> +
> +/**
> + * igt_panthor_free_bo:
> + * @fd: panthor device file descriptor
> + * @bo: pointer to panthor_bo structure to free
> + *
> + * Free a buffer object and unmap it if it was mapped.
> + */
> +void igt_panthor_free_bo(int fd, struct panthor_bo *bo)
> +{
> + if (!bo)
> + return;
> +
> + if (bo->map)
> + munmap(bo->map, bo->size);
> +
> + gem_close(fd, bo->handle);
> +}
> diff --git a/lib/igt_panthor.h b/lib/igt_panthor.h
> index a99b7102d..275ad54d6 100644
> --- a/lib/igt_panthor.h
> +++ b/lib/igt_panthor.h
> @@ -7,6 +7,24 @@
> #include <stddef.h>
> #include <stdint.h>
>
> +struct panthor_bo {
> + int handle;
> + uint64_t offset;
> + uint64_t size;
> + void *map;
> +};
> +
> void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err);
> +void igt_panthor_vm_create(int fd, uint32_t *vm_id, int err);
> +void igt_panthor_vm_destroy(int fd, uint32_t vm_id, int err);
> +void igt_panthor_vm_bind(int fd, uint32_t vm_id, uint32_t bo_handle,
> + uint64_t va, uint64_t size, uint32_t flags, int err);
> +void igt_panthor_bo_create(int fd, struct panthor_bo *bo, uint64_t size, uint32_t flags, int err);
> +uint64_t igt_panthor_bo_mmap_offset(int fd, uint32_t handle, int err);
> +void igt_panthor_free_bo(int fd, struct panthor_bo *bo);
> +void igt_panthor_bo_create_mapped(int fd, struct panthor_bo *bo, uint64_t size,
> + uint32_t flags, int err);
> +void *igt_panthor_mmap_bo(int fd, uint32_t handle, uint64_t size,
> + unsigned int prot, uint64_t offset);
>
> #endif /* IGT_PANTHOR_H */
> diff --git a/tests/panthor/meson.build b/tests/panthor/meson.build
> index ce13aebaa..42a46e993 100644
> --- a/tests/panthor/meson.build
> +++ b/tests/panthor/meson.build
> @@ -1,5 +1,8 @@
> panthor_progs = [
> - 'panthor_query'
> + 'panthor_gem',
> + 'panthor_group',
> + 'panthor_query',
> + 'panthor_vm',
> ]
>
> foreach prog : panthor_progs
> diff --git a/tests/panthor/panthor_gem.c b/tests/panthor/panthor_gem.c
> new file mode 100644
> index 000000000..7e8e2084d
> --- /dev/null
> +++ b/tests/panthor/panthor_gem.c
> @@ -0,0 +1,66 @@
> +// SPDX-License-Identifier: MIT
> +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
> +
> +#include "igt.h"
> +#include "igt_core.h"
> +#include "igt_panthor.h"
> +
> +igt_main {
> + int fd;
> +
> + igt_fixture { fd = drm_open_driver(DRIVER_PANTHOR); }
> +
> + igt_describe("Create a buffer object");
> + igt_subtest("bo_create") {
> + struct panthor_bo bo;
> +
> + igt_panthor_bo_create(fd, &bo, 4096, 0, 0);
> + igt_assert(bo.handle != 0);
> +
> + igt_panthor_free_bo(fd, &bo);
> + }
> +
> + igt_describe("Create a fake mmap offset for a buffer object");
> + igt_subtest("bo_mmap_offset") {
> + struct panthor_bo bo;
> + uint64_t mmap_offset;
> +
> + igt_panthor_bo_create(fd, &bo, 4096, 0, 0);
> + igt_assert(bo.handle != 0);
> +
> + mmap_offset = igt_panthor_bo_mmap_offset(fd, bo.handle, 0);
> + igt_assert(mmap_offset != 0);
> +
> + igt_panthor_free_bo(fd, &bo);
> + }
> +
> + igt_describe("Same as bo_mmap_offset but with an invalid handle");
> + igt_subtest("bo_mmap_offset_invalid_handle") {
> + struct panthor_bo bo;
> + uint64_t mmap_offset;
> +
> + igt_panthor_bo_create(fd, &bo, 4096, 0, 0);
> + igt_assert(bo.handle != 0);
> +
> + mmap_offset = igt_panthor_bo_mmap_offset(fd, 0xdeadbeef, ENOENT);
> + igt_assert(mmap_offset == 0);
> +
> + igt_panthor_free_bo(fd, &bo);
> + }
> +
> + igt_describe_f("Create a buffer object whose size is not page-aligned, and check "
> + "that the allocated size is rounded up to the next page size %lu.",
> + 8192UL);
> + igt_subtest("bo_create_round_size") {
> + struct panthor_bo bo;
> + uint64_t expected_size = 8192;
> +
> + igt_panthor_bo_create(fd, &bo, 5000, 0, 0);
> + igt_assert(bo.handle != 0);
> + igt_assert(bo.size == expected_size);
> +
> + igt_panthor_free_bo(fd, &bo);
> + }
> +
> + igt_fixture { drm_close_driver(fd); }
> +}
> diff --git a/tests/panthor/panthor_group.c b/tests/panthor/panthor_group.c
> new file mode 100644
> index 000000000..0a3b746d8
> --- /dev/null
> +++ b/tests/panthor/panthor_group.c
> @@ -0,0 +1,276 @@
> +// SPDX-License-Identifier: MIT
> +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
> +
> +#include <stdint.h>
> +#include <sys/mman.h>
> +#include <endian.h> // For htole64
> +#include <unistd.h>
> +
> +#include "drm.h"
> +#include "igt.h"
> +#include "igt_core.h"
> +#include "igt_panthor.h"
> +#include "panthor_drm.h"
> +
> +static void
> +issue_store_multiple(u8 *command_stream, uint64_t kernel_va, uint32_t constant)
> +{
> + uint64_t opcode, reg_num, mov48, store_multiple, flush;
> + uint64_t sr, src0, register_bitmap, offset;
> +
> + // MOV48: Load the source register ([r68; r69]) with the kernel address
> + opcode = 0x1;
> + reg_num = 68;
> + mov48 = (opcode << 56) | (reg_num << 48) | kernel_va;
> + mov48 = htole64(mov48);
> + memcpy(&command_stream[0], &mov48, sizeof(mov48));
> +
> + // MOV48: Load a known constant into r70
> + opcode = 0x1;
> + reg_num = 70;
> + mov48 = (opcode << 56) | (reg_num << 48) | constant;
> + mov48 = htole64(mov48);
> + memcpy(&command_stream[8], &mov48, sizeof(mov48));
> +
> + // STORE_MULTIPLE: Store the first register to the address pointed to by [r68; r69]
> + opcode = 0x15; // STORE_MULTIPLE
> + sr = 70; // Starting from register r70
> + src0 = 68; // Address pointed to by [r68; r69]
> + register_bitmap = 1; // Store the first register
> + offset = 0; // Offset
> + store_multiple = (opcode << 56) | (sr << 48) | (src0 << 40) |
> + (register_bitmap << 16) | offset;
> + store_multiple = htole64(store_multiple);
> + memcpy(&command_stream[16], &store_multiple, sizeof(store_multiple));
> +
> + opcode = 0x1;
> + reg_num = 68;
> + mov48 = (opcode << 56) | (reg_num << 48) | 0;
> + mov48 = htole64(mov48);
> + memcpy(&command_stream[24], &mov48, sizeof(mov48));
> +
> + opcode = 36;
> + flush = opcode << 56 | 0ull << 48 | reg_num << 40 | 0ull << 16 | 0x233;
> + flush = htole64(flush);
> + memcpy(&command_stream[32], &flush, sizeof(flush));
> +}
> +
> +igt_main {
> + int fd;
> +
> + igt_fixture { fd = drm_open_driver(DRIVER_PANTHOR); }
> +
> + igt_describe("Create and destroy a CSF group.");
> + igt_subtest("group_create") {
> + struct drm_panthor_gpu_info gpu_info = {};
> + struct drm_panthor_vm_create vm_create = {};
> + struct drm_panthor_group_create group_create = {};
> + struct drm_panthor_queue_create queue = {};
> + struct drm_panthor_obj_array queues = {};
> + struct drm_panthor_group_destroy group_destroy = {};
> + struct drm_panthor_vm_destroy vm_destroy = {};
> +
> + igt_panthor_query(fd, DRM_PANTHOR_DEV_QUERY_GPU_INFO,
> + &gpu_info, sizeof(gpu_info), 0);
> + igt_assert(gpu_info.gpu_id != 0);
> +
> + vm_create.flags = 0;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create), 0);
> + igt_assert(vm_create.id != 0);
> +
> + queue.priority = 0; // Low priority
> + queue.ringbuf_size = 4096; // Example size
> + queues = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &queue);
> +
> + group_create.queues = queues;
> + group_create.max_compute_cores = 1;
> + group_create.max_fragment_cores = 1;
> + group_create.max_tiler_cores = 1;
> + group_create.priority = PANTHOR_GROUP_PRIORITY_MEDIUM;
> + group_create.compute_core_mask = gpu_info.shader_present & 0x1; // Use first core
> + group_create.fragment_core_mask = gpu_info.shader_present & 0x1; // Use first core
> + group_create.tiler_core_mask = gpu_info.tiler_present & 0x1; // Use first tiler
> + group_create.vm_id = vm_create.id;
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_CREATE, &group_create), 0);
> + igt_assert(group_create.group_handle != 0);
> +
> + // Cleanup: Destroy the group and VM
> + group_destroy = (struct drm_panthor_group_destroy){
> + .group_handle = group_create.group_handle
> + };
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_DESTROY, &group_destroy), 0);
> +
> + vm_destroy = (struct drm_panthor_vm_destroy) { .id = vm_create.id };
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy), 0);
> + }
> +
> + igt_describe("Submit a job to a group and wait for completion. "
> + "The job writes a known value to a buffer object that is then "
> + "mmaped and checked.");
> + igt_subtest("group_submit") {
> + struct drm_panthor_gpu_info gpu_info = {};
> + struct drm_panthor_vm_create vm_create = {};
> + struct drm_panthor_group_create group_create = {};
> + struct drm_panthor_queue_create queue = {};
> + struct drm_panthor_obj_array queues = {};
> + struct drm_panthor_group_submit group_submit = {};
> + struct drm_panthor_queue_submit queue_submit = {};
> + struct drm_panthor_group_destroy group_destroy = {};
> + struct drm_panthor_obj_array queue_submits = {};
> + struct drm_panthor_vm_destroy vm_destroy = {};
> + struct drm_panthor_bo_create bo_create = {};
> + struct drm_panthor_vm_bind vm_bind = {};
> + struct drm_panthor_vm_bind_op vm_bind_op = {};
> + struct drm_syncobj_wait wait = {};
> + struct drm_syncobj_create syncobj_create = {};
> + struct drm_panthor_sync_op sync_op = {};
> + struct drm_gem_close gem_close = {};
> + struct drm_syncobj_destroy syncobj_destroy = {};
> + uint64_t command_stream_gpu_addr;
> + uint32_t command_stream_size;
> + uint64_t result_gpu_addr;
> + uint32_t cmd_buf_bo_handle;
> + uint32_t result_bo_handle;
> + uint32_t syncobj_handle;
> + uint8_t command_stream[64] = {0};
> + uint8_t *bo_cpu_addr;
> + uint8_t *result_cpu_addr;
> + const int INITIAL_VA = 0x1000000;
> + uint64_t bo_mmap_offset;
> +
> + igt_panthor_query(fd, DRM_PANTHOR_DEV_QUERY_GPU_INFO,
> + &gpu_info, sizeof(gpu_info), 0);
> + igt_assert(gpu_info.gpu_id != 0);
> +
> + vm_create.flags = 0;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create), 0);
> + igt_assert(vm_create.id != 0);
> +
> + bo_create.size = 4096;
> + bo_create.flags = 0;
> + bo_create.exclusive_vm_id = vm_create.id;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create), 0);
> + igt_assert(bo_create.handle != 0);
> + cmd_buf_bo_handle = bo_create.handle;
> +
> + vm_bind_op.flags = DRM_PANTHOR_VM_BIND_OP_TYPE_MAP;
> + vm_bind_op.bo_handle = cmd_buf_bo_handle;
> + vm_bind_op.bo_offset = 0;
> + vm_bind_op.va = INITIAL_VA;
> + vm_bind_op.size = bo_create.size;
> + vm_bind.ops = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &vm_bind_op);
> + vm_bind.vm_id = vm_create.id;
> + vm_bind.flags = 0;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind), 0);
> +
> + command_stream_gpu_addr = vm_bind_op.va;
> + command_stream_size = sizeof(command_stream);
> +
> + bo_mmap_offset = igt_panthor_bo_mmap_offset(fd, cmd_buf_bo_handle, 0);
> + bo_cpu_addr = igt_panthor_mmap_bo(fd, cmd_buf_bo_handle,
> + bo_create.size, PROT_READ | PROT_WRITE,
> + bo_mmap_offset);
> + igt_assert(bo_cpu_addr);
> +
> + // Create the BO to receive the result of the store.
> + memset(&bo_create, 0, sizeof(bo_create));
> + bo_create.size = 4096;
> + bo_create.flags = 0;
> + bo_create.exclusive_vm_id = vm_create.id;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create), 0);
> + igt_assert(bo_create.handle != 0);
> + result_bo_handle = bo_create.handle;
> +
> + // Also bind the result BO.
> + vm_bind_op.flags = DRM_PANTHOR_VM_BIND_OP_TYPE_MAP;
> + vm_bind_op.bo_handle = result_bo_handle;
> + vm_bind_op.bo_offset = 0;
> + vm_bind_op.va = INITIAL_VA + 4096;
> + vm_bind_op.size = bo_create.size;
> + vm_bind.ops = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &vm_bind_op);
> + vm_bind.vm_id = vm_create.id;
> + vm_bind.flags = 0;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind), 0);
> + result_gpu_addr = vm_bind_op.va;
> +
> + issue_store_multiple(command_stream, result_gpu_addr, 0xdeadbeef);
> + memcpy(bo_cpu_addr, command_stream, command_stream_size);
> + munmap(bo_cpu_addr, bo_create.size);
> +
> + queue.priority = 0;
> + queue.ringbuf_size = 4096;
> + queues = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &queue);
> +
> + group_create.queues = queues;
> + group_create.max_compute_cores = 1;
> + group_create.max_fragment_cores = 1;
> + group_create.max_tiler_cores = 1;
> + group_create.priority = PANTHOR_GROUP_PRIORITY_MEDIUM;
> + group_create.compute_core_mask = gpu_info.shader_present & 0x1;
> + group_create.fragment_core_mask = gpu_info.shader_present & 0x1;
> + group_create.tiler_core_mask = gpu_info.tiler_present & 0x1;
> + group_create.vm_id = vm_create.id;
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_CREATE, &group_create), 0);
> + igt_assert(group_create.group_handle != 0);
> +
> + syncobj_create = (struct drm_syncobj_create){
> + .flags = 0,
> + };
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &syncobj_create), 0);
> + syncobj_handle = syncobj_create.handle;
> +
> + sync_op = (struct drm_panthor_sync_op) {
> + .handle = syncobj_handle,
> + .flags = DRM_PANTHOR_SYNC_OP_SIGNAL,
> + };
> +
> + queue_submit.syncs = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &sync_op);
> +
> + queue_submit.queue_index = 0;
> + queue_submit.stream_size = command_stream_size;
> + queue_submit.stream_addr = command_stream_gpu_addr;
> + queue_submit.latest_flush = 0;
> + queue_submits = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &queue_submit);
> +
> + group_submit.group_handle = group_create.group_handle;
> + group_submit.queue_submits = queue_submits;
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_SUBMIT, &group_submit), 0);
> +
> + wait = (struct drm_syncobj_wait) {
> + .handles = (uint64_t)&syncobj_handle,
> + .count_handles = 1,
> + .timeout_nsec = INT64_MAX,
> + .flags = 0,
> + };
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, &wait), 0);
> +
> + bo_mmap_offset = igt_panthor_bo_mmap_offset(fd, result_bo_handle, 0);
> + result_cpu_addr = igt_panthor_mmap_bo(fd, result_bo_handle,
> + bo_create.size, PROT_READ | PROT_WRITE, bo_mmap_offset);
> +
> + igt_assert(*(uint32_t *)result_cpu_addr == 0xdeadbeef);
> + munmap(result_cpu_addr, bo_create.size);
> +
> + syncobj_destroy.handle = syncobj_handle;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &syncobj_destroy), 0);
> +
> + group_destroy.group_handle = group_create.group_handle;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_DESTROY, &group_destroy), 0);
> +
> + vm_destroy.id = vm_create.id;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy), 0);
> +
> + gem_close.handle = cmd_buf_bo_handle;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close), 0);
> +
> + gem_close.handle = result_bo_handle;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close), 0);
> +}
> +
> + igt_fixture { drm_close_driver(fd); }
> +}
> diff --git a/tests/panthor/panthor_vm.c b/tests/panthor/panthor_vm.c
> new file mode 100644
> index 000000000..1b641b601
> --- /dev/null
> +++ b/tests/panthor/panthor_vm.c
> @@ -0,0 +1,80 @@
> +// SPDX-License-Identifier: MIT
> +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
> +
> +#include "igt.h"
> +#include "igt_core.h"
> +#include "igt_panthor.h"
> +#include "panthor_drm.h"
> +
> +igt_main {
> + int fd;
> +
> + igt_fixture { fd = drm_open_driver(DRIVER_PANTHOR); }
> +
> + igt_describe("Create and destroy a VM");
> + igt_subtest("vm_create_destroy") {
> + uint32_t vm_id;
> +
> + igt_panthor_vm_create(fd, &vm_id, 0);
> + igt_assert(vm_id != 0);
> +
> + igt_panthor_vm_destroy(fd, vm_id, 0);
> + }
> +
> + igt_subtest("vm_destroy_invalid") {
> + igt_panthor_vm_destroy(fd, 0xdeadbeef, EINVAL);
> + }
> +
> + igt_describe("Test the VM_BIND API synchronously");
> + igt_subtest("vm_bind") {
> + uint32_t vm_id;
> + struct panthor_bo bo;
> + uint64_t bo_size = 0x1000;
> +
> + igt_panthor_vm_create(fd, &vm_id, 0);
> + igt_assert(vm_id != 0);
> +
> + igt_panthor_bo_create(fd, &bo, bo_size, 0, 0);
> + igt_panthor_vm_bind(fd, vm_id, bo.handle,
> + 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0);
> +
> + igt_panthor_vm_destroy(fd, vm_id, 0);
> + }
> +
> + igt_describe("Test unbinding a previously bound range");
> + igt_subtest("vm_unbind") {
> + uint32_t vm_id;
> + struct panthor_bo bo;
> + uint64_t bo_size = 0x1000;
> +
> + igt_panthor_vm_create(fd, &vm_id, 0);
> + igt_assert(vm_id != 0);
> +
> + igt_panthor_bo_create(fd, &bo, bo_size, 0, 0);
> + igt_panthor_vm_bind(fd, vm_id, bo.handle,
> + 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0);
> + igt_panthor_vm_bind(fd, vm_id, 0,
> + 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, 0);
> +
> + igt_panthor_vm_destroy(fd, vm_id, 0);
> + }
> +
> + igt_describe("Test unbinding an address range that was not previously bound");
> + igt_subtest("vm_unbind_invalid_address") {
> + uint32_t vm_id;
> + struct panthor_bo bo;
> + uint64_t bo_size = 0x1000;
> +
> + igt_panthor_vm_create(fd, &vm_id, 0);
> + igt_assert(vm_id != 0);
> +
> + igt_panthor_bo_create(fd, &bo, bo_size, 0, 0);
> +
> + /* This was not bound previously*/
> + igt_panthor_vm_bind(fd, vm_id, bo.handle,
> + 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, EINVAL);
> + igt_panthor_vm_destroy(fd, vm_id, 0);
> + }
> +
> + igt_fixture { drm_close_driver(fd); }
> +}
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH i-g-t v2 2/3] panthor: add initial infrastructure
2025-09-16 12:12 ` Kamil Konieczny
@ 2025-09-25 12:42 ` Daniel Almeida
2025-09-25 14:51 ` Kamil Konieczny
0 siblings, 1 reply; 15+ messages in thread
From: Daniel Almeida @ 2025-09-25 12:42 UTC (permalink / raw)
To: Kamil Konieczny
Cc: adrinael, arek, juhapekka.heikkila, bhanuprakash.modem,
ashutosh.dixit, karthik.b.s, boris.brezillon, liviu.dudau,
steven.price, aliceryhl, jeffv, intel-gfx, igt-dev, dri-devel
Hi Kamil,
> On 16 Sep 2025, at 14:12, Kamil Konieczny <kamil.konieczny@linux.intel.com> wrote:
>
> Hi Daniel,
> On 2025-09-12 at 15:19:29 -0300, Daniel Almeida wrote:
>> Add the necessary code needed to compile panthor tests as well as the
>> basic infrastructure that will be used by the Panthor tests themselves.
>>
>> To make sure everything is in order, add a basic test in
>> panthor_query.c.
>>
>> Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
>> ---
>> lib/igt_panthor.c | 41 +++++++++++++++++++++++++++++++++++
>> lib/igt_panthor.h | 12 ++++++++++
>> lib/meson.build | 1 +
>> meson.build | 8 +++++++
>> tests/meson.build | 2 ++
>> tests/panthor/meson.build | 12 ++++++++++
>> tests/panthor/panthor_query.c | 25 +++++++++++++++++++++
>> 7 files changed, 101 insertions(+)
>> create mode 100644 lib/igt_panthor.c
>> create mode 100644 lib/igt_panthor.h
>> create mode 100644 tests/panthor/meson.build
>> create mode 100644 tests/panthor/panthor_query.c
>>
>> diff --git a/lib/igt_panthor.c b/lib/igt_panthor.c
>> new file mode 100644
>> index 000000000..0b690f796
>> --- /dev/null
>> +++ b/lib/igt_panthor.c
>> @@ -0,0 +1,41 @@
>> +// SPDX-License-Identifier: MIT
>> +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
>
> We use SPD for licence because they are long texts. I do not
> see any benefit of SPDX for copyright lines, it makes it even
> longer than needed. It could stay if you want.
>
> Acked-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
>
> Regards,
> Kamil
>
I’d rather keep it. I tend to favor standardization and having a standard
way to declare copyrights seems beneficial to me. What are the next steps here?
Should I send a new version to pickup the tags, or can this be merged already?
Same for the other patch.
— Daniel
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH i-g-t v2 2/3] panthor: add initial infrastructure
2025-09-25 12:42 ` Daniel Almeida
@ 2025-09-25 14:51 ` Kamil Konieczny
0 siblings, 0 replies; 15+ messages in thread
From: Kamil Konieczny @ 2025-09-25 14:51 UTC (permalink / raw)
To: Daniel Almeida
Cc: adrinael, arek, juhapekka.heikkila, bhanuprakash.modem,
ashutosh.dixit, karthik.b.s, boris.brezillon, liviu.dudau,
steven.price, aliceryhl, jeffv, intel-gfx, igt-dev, dri-devel
Hi Daniel,
On 2025-09-25 at 14:42:44 +0200, Daniel Almeida wrote:
> Hi Kamil,
>
> > On 16 Sep 2025, at 14:12, Kamil Konieczny <kamil.konieczny@linux.intel.com> wrote:
> >
> > Hi Daniel,
> > On 2025-09-12 at 15:19:29 -0300, Daniel Almeida wrote:
> >> Add the necessary code needed to compile panthor tests as well as the
> >> basic infrastructure that will be used by the Panthor tests themselves.
> >>
> >> To make sure everything is in order, add a basic test in
> >> panthor_query.c.
> >>
> >> Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
> >> ---
> >> lib/igt_panthor.c | 41 +++++++++++++++++++++++++++++++++++
> >> lib/igt_panthor.h | 12 ++++++++++
> >> lib/meson.build | 1 +
> >> meson.build | 8 +++++++
> >> tests/meson.build | 2 ++
> >> tests/panthor/meson.build | 12 ++++++++++
> >> tests/panthor/panthor_query.c | 25 +++++++++++++++++++++
> >> 7 files changed, 101 insertions(+)
> >> create mode 100644 lib/igt_panthor.c
> >> create mode 100644 lib/igt_panthor.h
> >> create mode 100644 tests/panthor/meson.build
> >> create mode 100644 tests/panthor/panthor_query.c
> >>
> >> diff --git a/lib/igt_panthor.c b/lib/igt_panthor.c
> >> new file mode 100644
> >> index 000000000..0b690f796
> >> --- /dev/null
> >> +++ b/lib/igt_panthor.c
> >> @@ -0,0 +1,41 @@
> >> +// SPDX-License-Identifier: MIT
> >> +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
> >
> > We use SPD for licence because they are long texts. I do not
> > see any benefit of SPDX for copyright lines, it makes it even
> > longer than needed. It could stay if you want.
> >
> > Acked-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> >
> > Regards,
> > Kamil
> >
>
> I’d rather keep it. I tend to favor standardization and having a standard
> way to declare copyrights seems beneficial to me. What are the next steps here?
> Should I send a new version to pickup the tags, or can this be merged already?
>
> Same for the other patch.
>
> — Daniel
>
>
Will anyone familiar with Pathor do a full review or are you ok
with only my ack? If ack + tested-by is ok I could merge it.
Regards,
Kamil
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests
2025-09-12 18:19 ` [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests Daniel Almeida
2025-09-16 12:15 ` Kamil Konieczny
@ 2025-09-25 15:45 ` Daniel Stone
2025-10-07 13:39 ` Daniel Almeida
2025-09-25 17:46 ` Kamil Konieczny
2 siblings, 1 reply; 15+ messages in thread
From: Daniel Stone @ 2025-09-25 15:45 UTC (permalink / raw)
To: Daniel Almeida
Cc: adrinael, arek, kamil.konieczny, juhapekka.heikkila,
bhanuprakash.modem, ashutosh.dixit, karthik.b.s, boris.brezillon,
liviu.dudau, steven.price, aliceryhl, jeffv, intel-gfx, igt-dev,
dri-devel
Hi,
On Fri, 12 Sept 2025 at 19:20, Daniel Almeida
<daniel.almeida@collabora.com> wrote:
> +igt_main {
> + igt_describe("Create a buffer object");
> + igt_subtest("bo_create") {
> + struct panthor_bo bo;
> +
> + igt_panthor_bo_create(fd, &bo, 4096, 0, 0);
> + igt_assert(bo.handle != 0);
Please - here and everywhere else - use the specific igt_assert_*()
macros. Those print out the actual values, so are much more useful
when debugging.
> + igt_describe_f("Create a buffer object whose size is not page-aligned, and check "
> + "that the allocated size is rounded up to the next page size %lu.",
> + 8192UL);
> + igt_subtest("bo_create_round_size") {
> + struct panthor_bo bo;
> + uint64_t expected_size = 8192;
Shouldn't this be based on the actual page size in use?
> +static void
> +issue_store_multiple(u8 *command_stream, uint64_t kernel_va, uint32_t constant)
> +{
> + uint64_t opcode, reg_num, mov48, store_multiple, flush;
> + uint64_t sr, src0, register_bitmap, offset;
> +
> + // MOV48: Load the source register ([r68; r69]) with the kernel address
> + opcode = 0x1;
> + reg_num = 68;
> + mov48 = (opcode << 56) | (reg_num << 48) | kernel_va;
> + mov48 = htole64(mov48);
> + memcpy(&command_stream[0], &mov48, sizeof(mov48));
> +
> + // MOV48: Load a known constant into r70
> + opcode = 0x1;
> + reg_num = 70;
> + mov48 = (opcode << 56) | (reg_num << 48) | constant;
> + mov48 = htole64(mov48);
> + memcpy(&command_stream[8], &mov48, sizeof(mov48));
> +
> + // STORE_MULTIPLE: Store the first register to the address pointed to by [r68; r69]
> + opcode = 0x15; // STORE_MULTIPLE
> + sr = 70; // Starting from register r70
> + src0 = 68; // Address pointed to by [r68; r69]
> + register_bitmap = 1; // Store the first register
> + offset = 0; // Offset
> + store_multiple = (opcode << 56) | (sr << 48) | (src0 << 40) |
> + (register_bitmap << 16) | offset;
> + store_multiple = htole64(store_multiple);
> + memcpy(&command_stream[16], &store_multiple, sizeof(store_multiple));
// MOV48 r68, 0 on the below?
> + opcode = 0x1;
> + reg_num = 68;
> + mov48 = (opcode << 56) | (reg_num << 48) | 0;
> + mov48 = htole64(mov48);
> + memcpy(&command_stream[24], &mov48, sizeof(mov48));
// FLUSH_PAGES?
> + opcode = 36;
> + flush = opcode << 56 | 0ull << 48 | reg_num << 40 | 0ull << 16 | 0x233;
> + flush = htole64(flush);
> + memcpy(&command_stream[32], &flush, sizeof(flush));
> +}
> + group_create.queues = queues;
> + group_create.max_compute_cores = 1;
> + group_create.max_fragment_cores = 1;
> + group_create.max_tiler_cores = 1;
> + group_create.priority = PANTHOR_GROUP_PRIORITY_MEDIUM;
> + group_create.compute_core_mask = gpu_info.shader_present & 0x1; // Use first core
> + group_create.fragment_core_mask = gpu_info.shader_present & 0x1; // Use first core
> + group_create.tiler_core_mask = gpu_info.tiler_present & 0x1; // Use first tiler
This will either be 0 (rejected) or 1 (possibly valid but possibly
not). Did you mean (1 << ffs(...))? Same issue below, so maybe this
wants a little helper.
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_CREATE, &group_create), 0);
> + igt_assert(group_create.group_handle != 0);
> +
> + // Cleanup: Destroy the group and VM
igt does use /* */ rather than // everywhere, if you're respinning anyway.
> + group_destroy = (struct drm_panthor_group_destroy){
> + .group_handle = group_create.group_handle
> + };
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_DESTROY, &group_destroy), 0);
do_ioctl() - here and elsewhere.
> + igt_subtest("group_submit") {
> + struct drm_panthor_gpu_info gpu_info = {};
> + struct drm_panthor_vm_create vm_create = {};
> + struct drm_panthor_group_create group_create = {};
> + struct drm_panthor_queue_create queue = {};
> + struct drm_panthor_obj_array queues = {};
> + struct drm_panthor_group_submit group_submit = {};
> + struct drm_panthor_queue_submit queue_submit = {};
> + struct drm_panthor_group_destroy group_destroy = {};
> + struct drm_panthor_obj_array queue_submits = {};
> + struct drm_panthor_vm_destroy vm_destroy = {};
> + struct drm_panthor_bo_create bo_create = {};
> + struct drm_panthor_vm_bind vm_bind = {};
> + struct drm_panthor_vm_bind_op vm_bind_op = {};
> + struct drm_syncobj_wait wait = {};
> + struct drm_syncobj_create syncobj_create = {};
> + struct drm_panthor_sync_op sync_op = {};
> + struct drm_gem_close gem_close = {};
> + struct drm_syncobj_destroy syncobj_destroy = {};
> + uint64_t command_stream_gpu_addr;
> + uint32_t command_stream_size;
> + uint64_t result_gpu_addr;
> + uint32_t cmd_buf_bo_handle;
> + uint32_t result_bo_handle;
> + uint32_t syncobj_handle;
> + uint8_t command_stream[64] = {0};
> + uint8_t *bo_cpu_addr;
> + uint8_t *result_cpu_addr;
> + const int INITIAL_VA = 0x1000000;
> + uint64_t bo_mmap_offset;
> +
> + igt_panthor_query(fd, DRM_PANTHOR_DEV_QUERY_GPU_INFO,
> + &gpu_info, sizeof(gpu_info), 0);
> + igt_assert(gpu_info.gpu_id != 0);
> +
> + vm_create.flags = 0;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create), 0);
> + igt_assert(vm_create.id != 0);
> +
> + bo_create.size = 4096;
> + bo_create.flags = 0;
> + bo_create.exclusive_vm_id = vm_create.id;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create), 0);
> + igt_assert(bo_create.handle != 0);
> + cmd_buf_bo_handle = bo_create.handle;
Why not use the helpers here?
> + wait = (struct drm_syncobj_wait) {
> + .handles = (uint64_t)&syncobj_handle,
> + .count_handles = 1,
> + .timeout_nsec = INT64_MAX,
> + .flags = 0,
> + };
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, &wait), 0);
Similarly, syncobj_create() and syncobj_wait().
Thanks a lot for writing this up. Having more negative cases would be
really nice, but this is a really good start, so I'm happy for it to
land once it's been cleaned up.
Cheers,
Daniel
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests
2025-09-12 18:19 ` [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests Daniel Almeida
2025-09-16 12:15 ` Kamil Konieczny
2025-09-25 15:45 ` Daniel Stone
@ 2025-09-25 17:46 ` Kamil Konieczny
2 siblings, 0 replies; 15+ messages in thread
From: Kamil Konieczny @ 2025-09-25 17:46 UTC (permalink / raw)
To: Daniel Almeida
Cc: adrinael, arek, juhapekka.heikkila, bhanuprakash.modem,
ashutosh.dixit, karthik.b.s, boris.brezillon, liviu.dudau,
steven.price, aliceryhl, jeffv, intel-gfx, igt-dev, dri-devel
Hi Daniel,
On 2025-09-12 at 15:19:30 -0300, Daniel Almeida wrote:
> Add an initial test suit covering query device properties, allocating
> memory, binding and unbinding VA ranges through VM_BIND and submitting a
> simple piece of work through GROUP_SUBMIT.
One more nit on top of Daniel Stone review, see below.
>
> Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
> ---
> lib/igt_panthor.c | 188 +++++++++++++++++++++++
> lib/igt_panthor.h | 18 +++
> tests/panthor/meson.build | 5 +-
> tests/panthor/panthor_gem.c | 66 ++++++++
> tests/panthor/panthor_group.c | 276 ++++++++++++++++++++++++++++++++++
> tests/panthor/panthor_vm.c | 80 ++++++++++
> 6 files changed, 632 insertions(+), 1 deletion(-)
> create mode 100644 tests/panthor/panthor_gem.c
> create mode 100644 tests/panthor/panthor_group.c
> create mode 100644 tests/panthor/panthor_vm.c
>
> diff --git a/lib/igt_panthor.c b/lib/igt_panthor.c
> index 0b690f796..5d3b572b4 100644
> --- a/lib/igt_panthor.c
> +++ b/lib/igt_panthor.c
> @@ -39,3 +39,191 @@ void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err)
> else
> do_ioctl(fd, DRM_IOCTL_PANTHOR_DEV_QUERY, &query);
> }
> +
> +/**
> + * igt_panthor_vm_create:
> + * @fd: device file descriptor
> + * @vm_id: pointer to store the created VM ID
> + * @err: expected error code, or 0 for success
> + *
> + * Creates a VM.
> + */
> +void igt_panthor_vm_create(int fd, uint32_t *vm_id, int err)
> +{
> + struct drm_panthor_vm_create vm_create = {};
> +
> + if (err) {
> + do_ioctl_err(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create, err);
> + } else {
> + do_ioctl(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create);
> + *vm_id = vm_create.id;
> + }
> +}
> +
> +/**
> + * igt_panthor_vm_destroy:
> + * @fd: device file descriptor
> + * @vm_id: VM ID to destroy
> + * @err: expected error code, or 0 for success
> + *
> + * Destroys a VM.
> + */
> +void igt_panthor_vm_destroy(int fd, uint32_t vm_id, int err)
> +{
> + struct drm_panthor_vm_destroy vm_destroy = {
> + .id = vm_id,
> + };
> +
> + if (err)
> + do_ioctl_err(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy, err);
> + else
> + do_ioctl(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy);
> +}
> +
> +/**
> + * igt_panthor_vm_bind:
> + * @fd: device file descriptor
> + * @vm_id: VM ID to bind the buffer to
> + * @bo_handle: buffer object handle to bind
> + * @va: virtual address to bind at
> + * @size: size of the binding
> + * @flags: binding flags
> + * @err: expected error code, or 0 for success
> + *
> + * Bind a buffer object to a virtual address in the specified VM.
> + */
> +void igt_panthor_vm_bind(int fd, uint32_t vm_id, uint32_t bo_handle,
> + uint64_t va, uint64_t size, uint32_t flags, int err)
> +{
> + struct drm_panthor_vm_bind_op bind_op = {
> + .flags = flags,
> + .bo_handle = bo_handle,
> + .va = va,
> + .size = size,
> + };
> +
> + struct drm_panthor_vm_bind vm_bind = {
> + .vm_id = vm_id,
> + .flags = 0,
> + .ops = DRM_PANTHOR_OBJ_ARRAY(1, &bind_op),
> + };
> +
> + if (err)
> + do_ioctl_err(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind, err);
> + else
> + do_ioctl(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind);
> +}
> +
> +/**
> + * igt_panthor_bo_create:
> + * @fd: device file descriptor
> + * @bo: pointer to panthor_bo structure to initialize
> + * @size: requested buffer size in bytes
> + * @flags: buffer object creation flags
> + * @err: expected error code, or 0 for success
> + *
> + * Creates a new buffer object
> + */
> +void igt_panthor_bo_create(int fd, struct panthor_bo *bo,
> + uint64_t size, uint32_t flags, int err)
> +{
> + struct drm_panthor_bo_create bo_create = {
> + .size = size,
> + .flags = flags,
> + };
> +
> + if (err)
> + do_ioctl_err(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create, err);
> + else
> + do_ioctl(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create);
> +
> + bo->handle = bo_create.handle;
> + bo->size = bo_create.size;
> + bo->offset = 0;
> + bo->map = NULL;
> +}
> +
> +/**
> + * igt_panthor_bo_mmap_offset:
> + * @fd: device file descriptor
> + * @handle: buffer object handle
> + * @err: expected error code, or 0 for success
> + *
> + * Get the mmap offset for a buffer object.
> + *
> + * Returns: the mmap offset for the buffer object
> + */
> +uint64_t igt_panthor_bo_mmap_offset(int fd, uint32_t handle, int err)
> +{
> + struct drm_panthor_bo_mmap_offset bo_mmap_offset = {
> + .handle = handle,
> + };
> +
> + if (err)
> + do_ioctl_err(fd, DRM_IOCTL_PANTHOR_BO_MMAP_OFFSET, &bo_mmap_offset, err);
> + else
> + do_ioctl(fd, DRM_IOCTL_PANTHOR_BO_MMAP_OFFSET, &bo_mmap_offset);
> +
> + return bo_mmap_offset.offset;
> +}
> +
> +/**
> + * igt_panthor_mmap_bo:
> + * @fd: device file descriptor
> + * @handle: buffer object handle
> + * @size: size of the buffer to map
> + * @prot: memory protection flags (e.g., PROT_READ | PROT_WRITE)
> + * @offset: mmap offset for the buffer object
> + *
> + * Map a buffer object into the process address space.
> + *
> + * Returns: pointer to the mapped memory, or NULL on failure
> + */
> +void *igt_panthor_mmap_bo(int fd, uint32_t handle, uint64_t size,
> + unsigned int prot, uint64_t offset)
> +{
> + void *ptr;
> +
> + ptr = mmap(0, size, prot, MAP_SHARED, fd, offset);
> + if (ptr == MAP_FAILED)
> + return NULL;
> + return ptr;
> +}
> +
> +/**
> + * igt_panthor_bo_create_mapped:
> + * @fd: device file descriptor
> + * @bo: pointer to panthor_bo structure to initialize
> + * @size: requested buffer size in bytes
> + * @flags: buffer object creation flags
> + * @err: expected error code, or 0 for success
> + *
> + * Create a new buffer object on the panthor device and map it into
> + * the process address space.
> + */
> +void igt_panthor_bo_create_mapped(int fd, struct panthor_bo *bo, uint64_t size,
> + uint32_t flags, int err)
> +{
> + igt_panthor_bo_create(fd, bo, size, flags, err);
> + bo->offset = igt_panthor_bo_mmap_offset(fd, bo->handle, err);
> + bo->map = igt_panthor_mmap_bo(fd, bo->handle, bo->size,
> + PROT_READ | PROT_WRITE, bo->offset);
> +}
> +
> +/**
> + * igt_panthor_free_bo:
> + * @fd: panthor device file descriptor
> + * @bo: pointer to panthor_bo structure to free
> + *
> + * Free a buffer object and unmap it if it was mapped.
> + */
> +void igt_panthor_free_bo(int fd, struct panthor_bo *bo)
> +{
> + if (!bo)
> + return;
> +
> + if (bo->map)
> + munmap(bo->map, bo->size);
> +
> + gem_close(fd, bo->handle);
> +}
> diff --git a/lib/igt_panthor.h b/lib/igt_panthor.h
> index a99b7102d..275ad54d6 100644
> --- a/lib/igt_panthor.h
> +++ b/lib/igt_panthor.h
> @@ -7,6 +7,24 @@
> #include <stddef.h>
> #include <stdint.h>
>
> +struct panthor_bo {
> + int handle;
> + uint64_t offset;
> + uint64_t size;
> + void *map;
> +};
> +
> void igt_panthor_query(int fd, int32_t type, void *data, size_t size, int err);
> +void igt_panthor_vm_create(int fd, uint32_t *vm_id, int err);
> +void igt_panthor_vm_destroy(int fd, uint32_t vm_id, int err);
> +void igt_panthor_vm_bind(int fd, uint32_t vm_id, uint32_t bo_handle,
> + uint64_t va, uint64_t size, uint32_t flags, int err);
> +void igt_panthor_bo_create(int fd, struct panthor_bo *bo, uint64_t size, uint32_t flags, int err);
> +uint64_t igt_panthor_bo_mmap_offset(int fd, uint32_t handle, int err);
> +void igt_panthor_free_bo(int fd, struct panthor_bo *bo);
> +void igt_panthor_bo_create_mapped(int fd, struct panthor_bo *bo, uint64_t size,
> + uint32_t flags, int err);
> +void *igt_panthor_mmap_bo(int fd, uint32_t handle, uint64_t size,
> + unsigned int prot, uint64_t offset);
>
> #endif /* IGT_PANTHOR_H */
> diff --git a/tests/panthor/meson.build b/tests/panthor/meson.build
> index ce13aebaa..42a46e993 100644
> --- a/tests/panthor/meson.build
> +++ b/tests/panthor/meson.build
> @@ -1,5 +1,8 @@
> panthor_progs = [
> - 'panthor_query'
> + 'panthor_gem',
> + 'panthor_group',
> + 'panthor_query',
> + 'panthor_vm',
> ]
>
> foreach prog : panthor_progs
> diff --git a/tests/panthor/panthor_gem.c b/tests/panthor/panthor_gem.c
> new file mode 100644
> index 000000000..7e8e2084d
> --- /dev/null
> +++ b/tests/panthor/panthor_gem.c
> @@ -0,0 +1,66 @@
> +// SPDX-License-Identifier: MIT
> +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
> +
> +#include "igt.h"
> +#include "igt_core.h"
> +#include "igt_panthor.h"
> +
> +igt_main {
> + int fd;
> +
> + igt_fixture { fd = drm_open_driver(DRIVER_PANTHOR); }
> +
> + igt_describe("Create a buffer object");
> + igt_subtest("bo_create") {
> + struct panthor_bo bo;
> +
> + igt_panthor_bo_create(fd, &bo, 4096, 0, 0);
> + igt_assert(bo.handle != 0);
> +
> + igt_panthor_free_bo(fd, &bo);
> + }
> +
> + igt_describe("Create a fake mmap offset for a buffer object");
> + igt_subtest("bo_mmap_offset") {
> + struct panthor_bo bo;
> + uint64_t mmap_offset;
> +
> + igt_panthor_bo_create(fd, &bo, 4096, 0, 0);
> + igt_assert(bo.handle != 0);
> +
> + mmap_offset = igt_panthor_bo_mmap_offset(fd, bo.handle, 0);
> + igt_assert(mmap_offset != 0);
> +
> + igt_panthor_free_bo(fd, &bo);
> + }
> +
> + igt_describe("Same as bo_mmap_offset but with an invalid handle");
> + igt_subtest("bo_mmap_offset_invalid_handle") {
> + struct panthor_bo bo;
> + uint64_t mmap_offset;
> +
> + igt_panthor_bo_create(fd, &bo, 4096, 0, 0);
> + igt_assert(bo.handle != 0);
> +
> + mmap_offset = igt_panthor_bo_mmap_offset(fd, 0xdeadbeef, ENOENT);
> + igt_assert(mmap_offset == 0);
> +
> + igt_panthor_free_bo(fd, &bo);
> + }
> +
> + igt_describe_f("Create a buffer object whose size is not page-aligned, and check "
> + "that the allocated size is rounded up to the next page size %lu.",
> + 8192UL);
> + igt_subtest("bo_create_round_size") {
> + struct panthor_bo bo;
> + uint64_t expected_size = 8192;
> +
> + igt_panthor_bo_create(fd, &bo, 5000, 0, 0);
> + igt_assert(bo.handle != 0);
> + igt_assert(bo.size == expected_size);
> +
> + igt_panthor_free_bo(fd, &bo);
> + }
> +
> + igt_fixture { drm_close_driver(fd); }
> +}
> diff --git a/tests/panthor/panthor_group.c b/tests/panthor/panthor_group.c
> new file mode 100644
> index 000000000..0a3b746d8
> --- /dev/null
> +++ b/tests/panthor/panthor_group.c
> @@ -0,0 +1,276 @@
> +// SPDX-License-Identifier: MIT
> +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
> +
> +#include <stdint.h>
> +#include <sys/mman.h>
> +#include <endian.h> // For htole64
> +#include <unistd.h>
> +
> +#include "drm.h"
> +#include "igt.h"
> +#include "igt_core.h"
> +#include "igt_panthor.h"
> +#include "panthor_drm.h"
> +
> +static void
> +issue_store_multiple(u8 *command_stream, uint64_t kernel_va, uint32_t constant)
> +{
> + uint64_t opcode, reg_num, mov48, store_multiple, flush;
Why two tabs here?
> + uint64_t sr, src0, register_bitmap, offset;
> +
> + // MOV48: Load the source register ([r68; r69]) with the kernel address
> + opcode = 0x1;
> + reg_num = 68;
> + mov48 = (opcode << 56) | (reg_num << 48) | kernel_va;
> + mov48 = htole64(mov48);
> + memcpy(&command_stream[0], &mov48, sizeof(mov48));
> +
> + // MOV48: Load a known constant into r70
> + opcode = 0x1;
> + reg_num = 70;
> + mov48 = (opcode << 56) | (reg_num << 48) | constant;
> + mov48 = htole64(mov48);
> + memcpy(&command_stream[8], &mov48, sizeof(mov48));
> +
> + // STORE_MULTIPLE: Store the first register to the address pointed to by [r68; r69]
> + opcode = 0x15; // STORE_MULTIPLE
> + sr = 70; // Starting from register r70
> + src0 = 68; // Address pointed to by [r68; r69]
> + register_bitmap = 1; // Store the first register
> + offset = 0; // Offset
> + store_multiple = (opcode << 56) | (sr << 48) | (src0 << 40) |
> + (register_bitmap << 16) | offset;
Please align or make it one long line, so either
store_multiple = (opcode << 56) | (sr << 48) | (src0 << 40) |
(register_bitmap << 16) | offset;
or
store_multiple = (opcode << 56) | (sr << 48) | (src0 << 40) | (register_bitmap << 16) | offset;
Regards,
Kamil
> + store_multiple = htole64(store_multiple);
> + memcpy(&command_stream[16], &store_multiple, sizeof(store_multiple));
> +
> + opcode = 0x1;
> + reg_num = 68;
> + mov48 = (opcode << 56) | (reg_num << 48) | 0;
> + mov48 = htole64(mov48);
> + memcpy(&command_stream[24], &mov48, sizeof(mov48));
> +
> + opcode = 36;
> + flush = opcode << 56 | 0ull << 48 | reg_num << 40 | 0ull << 16 | 0x233;
> + flush = htole64(flush);
> + memcpy(&command_stream[32], &flush, sizeof(flush));
> +}
> +
> +igt_main {
> + int fd;
> +
> + igt_fixture { fd = drm_open_driver(DRIVER_PANTHOR); }
> +
> + igt_describe("Create and destroy a CSF group.");
> + igt_subtest("group_create") {
> + struct drm_panthor_gpu_info gpu_info = {};
> + struct drm_panthor_vm_create vm_create = {};
> + struct drm_panthor_group_create group_create = {};
> + struct drm_panthor_queue_create queue = {};
> + struct drm_panthor_obj_array queues = {};
> + struct drm_panthor_group_destroy group_destroy = {};
> + struct drm_panthor_vm_destroy vm_destroy = {};
> +
> + igt_panthor_query(fd, DRM_PANTHOR_DEV_QUERY_GPU_INFO,
> + &gpu_info, sizeof(gpu_info), 0);
> + igt_assert(gpu_info.gpu_id != 0);
> +
> + vm_create.flags = 0;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create), 0);
> + igt_assert(vm_create.id != 0);
> +
> + queue.priority = 0; // Low priority
> + queue.ringbuf_size = 4096; // Example size
> + queues = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &queue);
> +
> + group_create.queues = queues;
> + group_create.max_compute_cores = 1;
> + group_create.max_fragment_cores = 1;
> + group_create.max_tiler_cores = 1;
> + group_create.priority = PANTHOR_GROUP_PRIORITY_MEDIUM;
> + group_create.compute_core_mask = gpu_info.shader_present & 0x1; // Use first core
> + group_create.fragment_core_mask = gpu_info.shader_present & 0x1; // Use first core
> + group_create.tiler_core_mask = gpu_info.tiler_present & 0x1; // Use first tiler
> + group_create.vm_id = vm_create.id;
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_CREATE, &group_create), 0);
> + igt_assert(group_create.group_handle != 0);
> +
> + // Cleanup: Destroy the group and VM
> + group_destroy = (struct drm_panthor_group_destroy){
> + .group_handle = group_create.group_handle
> + };
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_DESTROY, &group_destroy), 0);
> +
> + vm_destroy = (struct drm_panthor_vm_destroy) { .id = vm_create.id };
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy), 0);
> + }
> +
> + igt_describe("Submit a job to a group and wait for completion. "
> + "The job writes a known value to a buffer object that is then "
> + "mmaped and checked.");
> + igt_subtest("group_submit") {
> + struct drm_panthor_gpu_info gpu_info = {};
> + struct drm_panthor_vm_create vm_create = {};
> + struct drm_panthor_group_create group_create = {};
> + struct drm_panthor_queue_create queue = {};
> + struct drm_panthor_obj_array queues = {};
> + struct drm_panthor_group_submit group_submit = {};
> + struct drm_panthor_queue_submit queue_submit = {};
> + struct drm_panthor_group_destroy group_destroy = {};
> + struct drm_panthor_obj_array queue_submits = {};
> + struct drm_panthor_vm_destroy vm_destroy = {};
> + struct drm_panthor_bo_create bo_create = {};
> + struct drm_panthor_vm_bind vm_bind = {};
> + struct drm_panthor_vm_bind_op vm_bind_op = {};
> + struct drm_syncobj_wait wait = {};
> + struct drm_syncobj_create syncobj_create = {};
> + struct drm_panthor_sync_op sync_op = {};
> + struct drm_gem_close gem_close = {};
> + struct drm_syncobj_destroy syncobj_destroy = {};
> + uint64_t command_stream_gpu_addr;
> + uint32_t command_stream_size;
> + uint64_t result_gpu_addr;
> + uint32_t cmd_buf_bo_handle;
> + uint32_t result_bo_handle;
> + uint32_t syncobj_handle;
> + uint8_t command_stream[64] = {0};
> + uint8_t *bo_cpu_addr;
> + uint8_t *result_cpu_addr;
> + const int INITIAL_VA = 0x1000000;
> + uint64_t bo_mmap_offset;
> +
> + igt_panthor_query(fd, DRM_PANTHOR_DEV_QUERY_GPU_INFO,
> + &gpu_info, sizeof(gpu_info), 0);
> + igt_assert(gpu_info.gpu_id != 0);
> +
> + vm_create.flags = 0;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_CREATE, &vm_create), 0);
> + igt_assert(vm_create.id != 0);
> +
> + bo_create.size = 4096;
> + bo_create.flags = 0;
> + bo_create.exclusive_vm_id = vm_create.id;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create), 0);
> + igt_assert(bo_create.handle != 0);
> + cmd_buf_bo_handle = bo_create.handle;
> +
> + vm_bind_op.flags = DRM_PANTHOR_VM_BIND_OP_TYPE_MAP;
> + vm_bind_op.bo_handle = cmd_buf_bo_handle;
> + vm_bind_op.bo_offset = 0;
> + vm_bind_op.va = INITIAL_VA;
> + vm_bind_op.size = bo_create.size;
> + vm_bind.ops = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &vm_bind_op);
> + vm_bind.vm_id = vm_create.id;
> + vm_bind.flags = 0;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind), 0);
> +
> + command_stream_gpu_addr = vm_bind_op.va;
> + command_stream_size = sizeof(command_stream);
> +
> + bo_mmap_offset = igt_panthor_bo_mmap_offset(fd, cmd_buf_bo_handle, 0);
> + bo_cpu_addr = igt_panthor_mmap_bo(fd, cmd_buf_bo_handle,
> + bo_create.size, PROT_READ | PROT_WRITE,
> + bo_mmap_offset);
> + igt_assert(bo_cpu_addr);
> +
> + // Create the BO to receive the result of the store.
> + memset(&bo_create, 0, sizeof(bo_create));
> + bo_create.size = 4096;
> + bo_create.flags = 0;
> + bo_create.exclusive_vm_id = vm_create.id;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_BO_CREATE, &bo_create), 0);
> + igt_assert(bo_create.handle != 0);
> + result_bo_handle = bo_create.handle;
> +
> + // Also bind the result BO.
> + vm_bind_op.flags = DRM_PANTHOR_VM_BIND_OP_TYPE_MAP;
> + vm_bind_op.bo_handle = result_bo_handle;
> + vm_bind_op.bo_offset = 0;
> + vm_bind_op.va = INITIAL_VA + 4096;
> + vm_bind_op.size = bo_create.size;
> + vm_bind.ops = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &vm_bind_op);
> + vm_bind.vm_id = vm_create.id;
> + vm_bind.flags = 0;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_BIND, &vm_bind), 0);
> + result_gpu_addr = vm_bind_op.va;
> +
> + issue_store_multiple(command_stream, result_gpu_addr, 0xdeadbeef);
> + memcpy(bo_cpu_addr, command_stream, command_stream_size);
> + munmap(bo_cpu_addr, bo_create.size);
> +
> + queue.priority = 0;
> + queue.ringbuf_size = 4096;
> + queues = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &queue);
> +
> + group_create.queues = queues;
> + group_create.max_compute_cores = 1;
> + group_create.max_fragment_cores = 1;
> + group_create.max_tiler_cores = 1;
> + group_create.priority = PANTHOR_GROUP_PRIORITY_MEDIUM;
> + group_create.compute_core_mask = gpu_info.shader_present & 0x1;
> + group_create.fragment_core_mask = gpu_info.shader_present & 0x1;
> + group_create.tiler_core_mask = gpu_info.tiler_present & 0x1;
> + group_create.vm_id = vm_create.id;
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_CREATE, &group_create), 0);
> + igt_assert(group_create.group_handle != 0);
> +
> + syncobj_create = (struct drm_syncobj_create){
> + .flags = 0,
> + };
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &syncobj_create), 0);
> + syncobj_handle = syncobj_create.handle;
> +
> + sync_op = (struct drm_panthor_sync_op) {
> + .handle = syncobj_handle,
> + .flags = DRM_PANTHOR_SYNC_OP_SIGNAL,
> + };
> +
> + queue_submit.syncs = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &sync_op);
> +
> + queue_submit.queue_index = 0;
> + queue_submit.stream_size = command_stream_size;
> + queue_submit.stream_addr = command_stream_gpu_addr;
> + queue_submit.latest_flush = 0;
> + queue_submits = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(1, &queue_submit);
> +
> + group_submit.group_handle = group_create.group_handle;
> + group_submit.queue_submits = queue_submits;
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_SUBMIT, &group_submit), 0);
> +
> + wait = (struct drm_syncobj_wait) {
> + .handles = (uint64_t)&syncobj_handle,
> + .count_handles = 1,
> + .timeout_nsec = INT64_MAX,
> + .flags = 0,
> + };
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, &wait), 0);
> +
> + bo_mmap_offset = igt_panthor_bo_mmap_offset(fd, result_bo_handle, 0);
> + result_cpu_addr = igt_panthor_mmap_bo(fd, result_bo_handle,
> + bo_create.size, PROT_READ | PROT_WRITE, bo_mmap_offset);
> +
> + igt_assert(*(uint32_t *)result_cpu_addr == 0xdeadbeef);
> + munmap(result_cpu_addr, bo_create.size);
> +
> + syncobj_destroy.handle = syncobj_handle;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &syncobj_destroy), 0);
> +
> + group_destroy.group_handle = group_create.group_handle;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_GROUP_DESTROY, &group_destroy), 0);
> +
> + vm_destroy.id = vm_create.id;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_PANTHOR_VM_DESTROY, &vm_destroy), 0);
> +
> + gem_close.handle = cmd_buf_bo_handle;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close), 0);
> +
> + gem_close.handle = result_bo_handle;
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &gem_close), 0);
> +}
> +
> + igt_fixture { drm_close_driver(fd); }
> +}
> diff --git a/tests/panthor/panthor_vm.c b/tests/panthor/panthor_vm.c
> new file mode 100644
> index 000000000..1b641b601
> --- /dev/null
> +++ b/tests/panthor/panthor_vm.c
> @@ -0,0 +1,80 @@
> +// SPDX-License-Identifier: MIT
> +// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
> +
> +#include "igt.h"
> +#include "igt_core.h"
> +#include "igt_panthor.h"
> +#include "panthor_drm.h"
> +
> +igt_main {
> + int fd;
> +
> + igt_fixture { fd = drm_open_driver(DRIVER_PANTHOR); }
> +
> + igt_describe("Create and destroy a VM");
> + igt_subtest("vm_create_destroy") {
> + uint32_t vm_id;
> +
> + igt_panthor_vm_create(fd, &vm_id, 0);
> + igt_assert(vm_id != 0);
> +
> + igt_panthor_vm_destroy(fd, vm_id, 0);
> + }
> +
> + igt_subtest("vm_destroy_invalid") {
> + igt_panthor_vm_destroy(fd, 0xdeadbeef, EINVAL);
> + }
> +
> + igt_describe("Test the VM_BIND API synchronously");
> + igt_subtest("vm_bind") {
> + uint32_t vm_id;
> + struct panthor_bo bo;
> + uint64_t bo_size = 0x1000;
> +
> + igt_panthor_vm_create(fd, &vm_id, 0);
> + igt_assert(vm_id != 0);
> +
> + igt_panthor_bo_create(fd, &bo, bo_size, 0, 0);
> + igt_panthor_vm_bind(fd, vm_id, bo.handle,
> + 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0);
> +
> + igt_panthor_vm_destroy(fd, vm_id, 0);
> + }
> +
> + igt_describe("Test unbinding a previously bound range");
> + igt_subtest("vm_unbind") {
> + uint32_t vm_id;
> + struct panthor_bo bo;
> + uint64_t bo_size = 0x1000;
> +
> + igt_panthor_vm_create(fd, &vm_id, 0);
> + igt_assert(vm_id != 0);
> +
> + igt_panthor_bo_create(fd, &bo, bo_size, 0, 0);
> + igt_panthor_vm_bind(fd, vm_id, bo.handle,
> + 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_MAP, 0);
> + igt_panthor_vm_bind(fd, vm_id, 0,
> + 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, 0);
> +
> + igt_panthor_vm_destroy(fd, vm_id, 0);
> + }
> +
> + igt_describe("Test unbinding an address range that was not previously bound");
> + igt_subtest("vm_unbind_invalid_address") {
> + uint32_t vm_id;
> + struct panthor_bo bo;
> + uint64_t bo_size = 0x1000;
> +
> + igt_panthor_vm_create(fd, &vm_id, 0);
> + igt_assert(vm_id != 0);
> +
> + igt_panthor_bo_create(fd, &bo, bo_size, 0, 0);
> +
> + /* This was not bound previously*/
> + igt_panthor_vm_bind(fd, vm_id, bo.handle,
> + 0x1000, 0x1000, DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP, EINVAL);
> + igt_panthor_vm_destroy(fd, vm_id, 0);
> + }
> +
> + igt_fixture { drm_close_driver(fd); }
> +}
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests
2025-09-25 15:45 ` Daniel Stone
@ 2025-10-07 13:39 ` Daniel Almeida
2025-10-07 16:40 ` Daniel Almeida
0 siblings, 1 reply; 15+ messages in thread
From: Daniel Almeida @ 2025-10-07 13:39 UTC (permalink / raw)
To: Daniel Stone
Cc: adrinael, arek, kamil.konieczny, juhapekka.heikkila,
bhanuprakash.modem, ashutosh.dixit, karthik.b.s, boris.brezillon,
liviu.dudau, steven.price, aliceryhl, jeffv, intel-gfx, igt-dev,
dri-devel
Hi Dan, thanks for the review!
[…]
>
>> +static void
>> +issue_store_multiple(u8 *command_stream, uint64_t kernel_va, uint32_t constant)
>> +{
>> + uint64_t opcode, reg_num, mov48, store_multiple, flush;
>> + uint64_t sr, src0, register_bitmap, offset;
>> +
>> + // MOV48: Load the source register ([r68; r69]) with the kernel address
>> + opcode = 0x1;
>> + reg_num = 68;
>> + mov48 = (opcode << 56) | (reg_num << 48) | kernel_va;
>> + mov48 = htole64(mov48);
>> + memcpy(&command_stream[0], &mov48, sizeof(mov48));
>> +
>> + // MOV48: Load a known constant into r70
>> + opcode = 0x1;
>> + reg_num = 70;
>> + mov48 = (opcode << 56) | (reg_num << 48) | constant;
>> + mov48 = htole64(mov48);
>> + memcpy(&command_stream[8], &mov48, sizeof(mov48));
>> +
>> + // STORE_MULTIPLE: Store the first register to the address pointed to by [r68; r69]
>> + opcode = 0x15; // STORE_MULTIPLE
>> + sr = 70; // Starting from register r70
>> + src0 = 68; // Address pointed to by [r68; r69]
>> + register_bitmap = 1; // Store the first register
>> + offset = 0; // Offset
>> + store_multiple = (opcode << 56) | (sr << 48) | (src0 << 40) |
>> + (register_bitmap << 16) | offset;
>> + store_multiple = htole64(store_multiple);
>> + memcpy(&command_stream[16], &store_multiple, sizeof(store_multiple));
>
> // MOV48 r68, 0 on the below?
Wdym? / Why?
I want to clarify what you mean here because it was a bit tricky to get this to
work, so I am trying to be really mindful about any changes so that it
doesn’t break.
>
>> + opcode = 0x1;
>> + reg_num = 68;
>> + mov48 = (opcode << 56) | (reg_num << 48) | 0;
>> + mov48 = htole64(mov48);
>> + memcpy(&command_stream[24], &mov48, sizeof(mov48));
>
> // FLUSH_PAGES?
You want this comment to be present here?
>
>> + opcode = 36;
>> + flush = opcode << 56 | 0ull << 48 | reg_num << 40 | 0ull << 16 | 0x233;
>> + flush = htole64(flush);
>> + memcpy(&command_stream[32], &flush, sizeof(flush));
>> +}
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests
2025-10-07 13:39 ` Daniel Almeida
@ 2025-10-07 16:40 ` Daniel Almeida
2025-10-07 16:50 ` Boris Brezillon
0 siblings, 1 reply; 15+ messages in thread
From: Daniel Almeida @ 2025-10-07 16:40 UTC (permalink / raw)
To: Daniel Stone
Cc: adrinael, arek, kamil.konieczny, juhapekka.heikkila,
bhanuprakash.modem, ashutosh.dixit, karthik.b.s, boris.brezillon,
liviu.dudau, steven.price, aliceryhl, jeffv, intel-gfx, igt-dev,
dri-devel
> On 7 Oct 2025, at 10:39, Daniel Almeida <daniel.almeida@collabora.com> wrote:
>
> Hi Dan, thanks for the review!
>
> […]
>
>>
>>> +static void
>>> +issue_store_multiple(u8 *command_stream, uint64_t kernel_va, uint32_t constant)
>>> +{
>>> + uint64_t opcode, reg_num, mov48, store_multiple, flush;
>>> + uint64_t sr, src0, register_bitmap, offset;
>>> +
>>> + // MOV48: Load the source register ([r68; r69]) with the kernel address
>>> + opcode = 0x1;
>>> + reg_num = 68;
>>> + mov48 = (opcode << 56) | (reg_num << 48) | kernel_va;
>>> + mov48 = htole64(mov48);
>>> + memcpy(&command_stream[0], &mov48, sizeof(mov48));
>>> +
>>> + // MOV48: Load a known constant into r70
>>> + opcode = 0x1;
>>> + reg_num = 70;
>>> + mov48 = (opcode << 56) | (reg_num << 48) | constant;
>>> + mov48 = htole64(mov48);
>>> + memcpy(&command_stream[8], &mov48, sizeof(mov48));
>>> +
>>> + // STORE_MULTIPLE: Store the first register to the address pointed to by [r68; r69]
>>> + opcode = 0x15; // STORE_MULTIPLE
>>> + sr = 70; // Starting from register r70
>>> + src0 = 68; // Address pointed to by [r68; r69]
>>> + register_bitmap = 1; // Store the first register
>>> + offset = 0; // Offset
>>> + store_multiple = (opcode << 56) | (sr << 48) | (src0 << 40) |
>>> + (register_bitmap << 16) | offset;
>>> + store_multiple = htole64(store_multiple);
>>> + memcpy(&command_stream[16], &store_multiple, sizeof(store_multiple));
>>
>> // MOV48 r68, 0 on the below?
>
> Wdym? / Why?
>
> I want to clarify what you mean here because it was a bit tricky to get this to
> work, so I am trying to be really mindful about any changes so that it
> doesn’t break.
>
Oh, I now see that you probably also want this to be a comment placed before the
opcode like the FLUSH_CACHES below.
— Daniel
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests
2025-10-07 16:40 ` Daniel Almeida
@ 2025-10-07 16:50 ` Boris Brezillon
0 siblings, 0 replies; 15+ messages in thread
From: Boris Brezillon @ 2025-10-07 16:50 UTC (permalink / raw)
To: Daniel Almeida
Cc: Daniel Stone, adrinael, arek, kamil.konieczny, juhapekka.heikkila,
bhanuprakash.modem, ashutosh.dixit, karthik.b.s, liviu.dudau,
steven.price, aliceryhl, jeffv, intel-gfx, igt-dev, dri-devel
On Tue, 7 Oct 2025 13:40:11 -0300
Daniel Almeida <daniel.almeida@collabora.com> wrote:
> > On 7 Oct 2025, at 10:39, Daniel Almeida <daniel.almeida@collabora.com> wrote:
> >
> > Hi Dan, thanks for the review!
> >
> > […]
> >
> >>
> >>> +static void
> >>> +issue_store_multiple(u8 *command_stream, uint64_t kernel_va, uint32_t constant)
> >>> +{
> >>> + uint64_t opcode, reg_num, mov48, store_multiple, flush;
> >>> + uint64_t sr, src0, register_bitmap, offset;
> >>> +
> >>> + // MOV48: Load the source register ([r68; r69]) with the kernel address
> >>> + opcode = 0x1;
> >>> + reg_num = 68;
> >>> + mov48 = (opcode << 56) | (reg_num << 48) | kernel_va;
> >>> + mov48 = htole64(mov48);
> >>> + memcpy(&command_stream[0], &mov48, sizeof(mov48));
> >>> +
> >>> + // MOV48: Load a known constant into r70
> >>> + opcode = 0x1;
> >>> + reg_num = 70;
> >>> + mov48 = (opcode << 56) | (reg_num << 48) | constant;
> >>> + mov48 = htole64(mov48);
> >>> + memcpy(&command_stream[8], &mov48, sizeof(mov48));
> >>> +
> >>> + // STORE_MULTIPLE: Store the first register to the address pointed to by [r68; r69]
> >>> + opcode = 0x15; // STORE_MULTIPLE
> >>> + sr = 70; // Starting from register r70
> >>> + src0 = 68; // Address pointed to by [r68; r69]
> >>> + register_bitmap = 1; // Store the first register
> >>> + offset = 0; // Offset
> >>> + store_multiple = (opcode << 56) | (sr << 48) | (src0 << 40) |
> >>> + (register_bitmap << 16) | offset;
> >>> + store_multiple = htole64(store_multiple);
> >>> + memcpy(&command_stream[16], &store_multiple, sizeof(store_multiple));
> >>
> >> // MOV48 r68, 0 on the below?
> >
> > Wdym? / Why?
> >
> > I want to clarify what you mean here because it was a bit tricky to get this to
> > work, so I am trying to be really mindful about any changes so that it
> > doesn’t break.
> >
>
> Oh, I now see that you probably also want this to be a comment placed before the
> opcode like the FLUSH_CACHES below.
BTW, if we start adding more tests using manually forged command
streams, it might make sense to provides some sort of helpers like
those we have in mesa[1], but let's keep that for later.
[1]https://elixir.bootlin.com/mesa/mesa-25.2.4/source/src/panfrost/genxml/cs_builder.h
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2025-10-07 16:50 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-12 18:19 [PATCH i-g-t v2 0/3] Add initial Panthor tests Daniel Almeida
2025-09-12 18:19 ` [PATCH i-g-t v2 1/3] lib: add support for opening Panthor devices Daniel Almeida
2025-09-16 12:03 ` Kamil Konieczny
2025-09-12 18:19 ` [PATCH i-g-t v2 2/3] panthor: add initial infrastructure Daniel Almeida
2025-09-16 12:12 ` Kamil Konieczny
2025-09-25 12:42 ` Daniel Almeida
2025-09-25 14:51 ` Kamil Konieczny
2025-09-12 18:19 ` [PATCH i-g-t v2 3/3] tests/panthor: add panthor tests Daniel Almeida
2025-09-16 12:15 ` Kamil Konieczny
2025-09-25 15:45 ` Daniel Stone
2025-10-07 13:39 ` Daniel Almeida
2025-10-07 16:40 ` Daniel Almeida
2025-10-07 16:50 ` Boris Brezillon
2025-09-25 17:46 ` Kamil Konieczny
2025-09-15 14:40 ` [PATCH i-g-t v2 0/3] Add initial Panthor tests Steven Price
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox