[PATCH v2 RESEND 2/5] drm: panthor: add devcoredump support

Daniel Almeida
2024-08-21T14:39:16Z

Dump the GPU state using devcoredump. This is useful for debugging
purposes.

Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com>
---
drivers/gpu/drm/panthor/Kconfig | 1 +
drivers/gpu/drm/panthor/Makefile | 1 +
drivers/gpu/drm/panthor/panthor_dump.c | 376 ++++++++++++++++++++++++
drivers/gpu/drm/panthor/panthor_dump.h | 21 ++
drivers/gpu/drm/panthor/panthor_mmu.c | 22 ++
drivers/gpu/drm/panthor/panthor_mmu.h | 6 +
drivers/gpu/drm/panthor/panthor_sched.c | 51 +++-
drivers/gpu/drm/panthor/panthor_sched.h | 10 +
include/uapi/drm/panthor_drm.h | 124 ++++++++
9 files changed, 611 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/drm/panthor/panthor_dump.c
create mode 100644 drivers/gpu/drm/panthor/panthor_dump.h

diff --git a/drivers/gpu/drm/panthor/Kconfig b/drivers/gpu/drm/panthor/Kconfig
index 55b40ad07f3b..eeb80d8e8064 100644
--- a/drivers/gpu/drm/panthor/Kconfig
+++ b/drivers/gpu/drm/panthor/Kconfig
@@ -14,6 +14,7 @@ config DRM_PANTHOR
select IOMMU_IO_PGTABLE_LPAE
select IOMMU_SUPPORT
select PM_DEVFREQ
+ select WANT_DEVCOREDUMP
help
DRM driver for ARM Mali CSF-based GPUs.

diff --git a/drivers/gpu/drm/panthor/Makefile b/drivers/gpu/drm/panthor/Makefile
index 15294719b09c..19be24ddf577 100644
--- a/drivers/gpu/drm/panthor/Makefile
+++ b/drivers/gpu/drm/panthor/Makefile
@@ -4,6 +4,7 @@ panthor-y := \
panthor_devfreq.o \
panthor_device.o \
panthor_drv.o \
+ panthor_dump.o \
panthor_fw.o \
panthor_gem.o \
panthor_gpu.o \
diff --git a/drivers/gpu/drm/panthor/panthor_dump.c b/drivers/gpu/drm/panthor/panthor_dump.c
new file mode 100644
index 000000000000..7ec0e21dc7e9
--- /dev/null
+++ b/drivers/gpu/drm/panthor/panthor_dump.c
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: GPL-2.0 or MIT
+/* SPDX-FileCopyrightText: Copyright Collabora 2024 */
+
+#include <drm/drm_gem.h>
+#include <linux/iosys-map.h>
+#include <linux/devcoredump.h>
+#include <linux/err.h>
+#include <linux/vmalloc.h>
+#include <linux/types.h>
+#include <uapi/drm/panthor_drm.h>
+
+#include "panthor_device.h"
+#include "panthor_dump.h"
+#include "panthor_mmu.h"
+#include "panthor_sched.h"
+
+/* A magic value used when starting a new section in the dump */
+#define PANT_DUMP_MAGIC 0x544e4150 /* PANT */
+#define PANT_DUMP_MAJOR 1
+#define PANT_DUMP_MINOR 0
+
+/* keep track of where we are in the underlying buffer */
+struct dump_allocator {
+ u8 *start;
+ u8 *curr;
+ size_t pos;
+ size_t capacity;
+};
+
+struct vm_dump_count {
+ u64 size;
+ u32 vas;
+};
+
+struct queue_count {
+ u32 queues;
+};
+
+struct dump_group_args {
+ struct panthor_device *ptdev;
+ struct dump_allocator *alloc;
+ struct panthor_group *group;
+};
+
+struct dump_va_args {
+ struct panthor_device *ptdev;
+ struct dump_allocator *alloc;
+};
+
+static void *alloc_bytes(struct dump_allocator *alloc, size_t size)
+{
+ void *ret;
+
+ if (alloc->pos + size > alloc->capacity)
+ return ERR_PTR(-ENOMEM);
+
+ ret = alloc->curr;
+ alloc->curr += size;
+ alloc->pos += size;
+ return ret;
+}
+
+static struct drm_panthor_dump_header *
+alloc_header(struct dump_allocator *alloc, u32 type, size_t size)
+{
+ struct drm_panthor_dump_header *hdr;
+ int header_size = sizeof(*hdr);
+
+ hdr = alloc_bytes(alloc, header_size);
+ if (IS_ERR(hdr))
+ return hdr;
+
+ hdr->magic = PANT_DUMP_MAGIC;
+ hdr->header_type = type;
+ hdr->header_size = header_size;
+ hdr->data_size = size;
+ return hdr;
+}
+
+static int dump_bo(struct panthor_device *ptdev, u8 *dst,
+ struct drm_gem_object *obj, int offset, int size)
+{
+ struct iosys_map map = {};
+ int ret;
+
+ ret = drm_gem_vmap_unlocked(obj, &map);
+ if (ret)
+ return ret;
+
+ drm_dbg(&ptdev->base, "dumping bo %p, offset %d, size %d\n", obj,
+ offset, size);
+
+ memcpy(dst, map.vaddr + offset, size);
+ drm_gem_vunmap_unlocked(obj, &map);
+ return ret;
+}
+
+static int dump_va(struct dump_va_args *dump_va_args,
+ const struct drm_gpuva *va, int type)
+{
+ struct drm_gem_object *obj = va->gem.obj;
+ const int hdr_size =
+ sizeof(struct drm_panthor_dump_gpuva) + va->va.range;
+ struct drm_panthor_dump_gpuva *dump_va;
+ struct drm_panthor_dump_header *dump_hdr;
+ u8 *bo_data;
+
+ dump_hdr = alloc_header(dump_va_args->alloc, type, hdr_size);
+ if (IS_ERR(dump_hdr))
+ return PTR_ERR(dump_hdr);
+
+ dump_va = alloc_bytes(dump_va_args->alloc, sizeof(*dump_va));
+ if (IS_ERR(dump_va))
+ return PTR_ERR(dump_va);
+
+ bo_data = alloc_bytes(dump_va_args->alloc, va->va.range);
+ if (IS_ERR(bo_data))
+ return PTR_ERR(bo_data);
+
+ dump_va->addr = va->va.addr;
+ dump_va->range = va->va.range;
+
+ return dump_bo(dump_va_args->ptdev, bo_data, obj, va->gem.offset,
+ va->va.range);
+}
+
+static int dump_va_cb(void *priv, const struct drm_gpuva *va)
+{
+ struct dump_va_args *dump_va_args = priv;
+ int ret;
+
+ ret = dump_va(dump_va_args, va, DRM_PANTHOR_DUMP_HEADER_TYPE_VM);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int count_va_cb(void *priv, const struct drm_gpuva *va)
+{
+ struct vm_dump_count *count = priv;
+
+ count->vas++;
+ count->size += va->va.range;
+ return 0;
+}
+
+static void count_queues(struct queue_count *count,
+ struct drm_panthor_dump_group_info *info)
+{
+ count->queues += info->queue_count;
+}
+
+static int compute_dump_size(struct vm_dump_count *va_count,
+ struct queue_count *group_and_q_cnt)
+{
+ int size = 0;
+ int i;
+
+ size += sizeof(struct drm_panthor_dump_header);
+ size += sizeof(struct drm_panthor_dump_version);
+
+ size += sizeof(struct drm_panthor_dump_header);
+ size += sizeof(struct drm_panthor_gpu_info);
+
+ size += sizeof(struct drm_panthor_dump_header);
+ size += sizeof(struct drm_panthor_csif_info);
+
+ size += sizeof(struct drm_panthor_dump_header);
+ size += sizeof(struct drm_panthor_fw_info);
+
+ for (i = 0; i < va_count->vas; i++) {
+ size += sizeof(struct drm_panthor_dump_header);
+ size += sizeof(struct drm_panthor_dump_gpuva);
+ }
+
+ size += va_count->size;
+
+ size += sizeof(struct drm_panthor_dump_header);
+ size += sizeof(struct drm_panthor_dump_group_info);
+
+ for (i = 0; i < group_and_q_cnt->queues; i++) {
+ size += sizeof(struct drm_panthor_dump_header);
+ size += sizeof(struct drm_panthor_dump_queue_info);
+ }
+
+ return size;
+}
+
+static int dump_queue_info(struct dump_group_args *dump_group_args,
+ struct drm_panthor_dump_queue_info *info)
+{
+ struct drm_panthor_dump_header *hdr;
+ struct drm_panthor_dump_queue_info *queue_info;
+
+ drm_dbg(&dump_group_args->ptdev->base,
+ "dumping queue info for cs_id %d, gpuva: %llx, insert: %llx, extract: %llx\n",
+ info->cs_id, info->ringbuf_gpuva, info->ringbuf_insert,
+ info->ringbuf_extract);
+
+ hdr = alloc_header(dump_group_args->alloc,
+ DRM_PANTHOR_DUMP_HEADER_TYPE_QUEUE_INFO,
+ sizeof(*info));
+ if (IS_ERR(hdr))
+ return PTR_ERR(hdr);
+
+ queue_info = alloc_bytes(dump_group_args->alloc, sizeof(*queue_info));
+ if (IS_ERR(queue_info))
+ return PTR_ERR(queue_info);
+
+ *queue_info = *info;
+ return 0;
+}
+
+static int dump_group_info(struct dump_group_args *dump_group_args,
+ struct drm_panthor_dump_group_info *info)
+{
+ struct drm_panthor_dump_header *hdr;
+ struct drm_panthor_dump_group_info *group_info;
+ int ret = 0;
+
+ drm_dbg(&dump_group_args->ptdev->base,
+ "dumping group info for num_queues: %d, faulty bitmask: %d\n",
+ info->queue_count, info->faulty_bitmask);
+
+ hdr = alloc_header(dump_group_args->alloc,
+ DRM_PANTHOR_DUMP_HEADER_TYPE_GROUP_INFO,
+ sizeof(*info));
+ if (IS_ERR(hdr))
+ return PTR_ERR(hdr);
+
+ group_info = alloc_bytes(dump_group_args->alloc, sizeof(*group_info));
+ if (IS_ERR(group_info))
+ return PTR_ERR(group_info);
+
+ *group_info = *info;
+
+ for (int i = 0; i < info->queue_count; i++) {
+ struct drm_panthor_dump_queue_info qinfo;
+
+ ret = panthor_sched_get_queueinfo(dump_group_args->group, i,
+ &qinfo);
+ if (ret)
+ break;
+ ret = dump_queue_info(dump_group_args, &qinfo);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+int panthor_core_dump(struct panthor_core_dump_args *args)
+{
+ u8 *mem;
+ int dump_size;
+ int ret = 0;
+ struct dump_allocator alloc = {};
+ struct vm_dump_count va_count = {};
+ struct drm_panthor_dump_header *hdr;
+ struct drm_panthor_dump_version *version;
+ struct drm_panthor_gpu_info *gpu_info;
+ struct drm_panthor_csif_info *csif_info;
+ struct drm_panthor_fw_info *fw_info;
+ struct queue_count group_and_q_cnt = {};
+ struct dump_va_args dump_va_args = {};
+ struct drm_panthor_dump_group_info group_info;
+ struct dump_group_args dump_group_args;
+
+ panthor_vm_foreach_va(args->group_vm, count_va_cb, &va_count);
+
+ panthor_sched_get_groupinfo(args->group, &group_info);
+
+ count_queues(&group_and_q_cnt, &group_info);
+
+ dump_size = compute_dump_size(&va_count, &group_and_q_cnt);
+
+ mem = vzalloc(dump_size);
+ if (!mem)
+ return ret;
+
+ alloc = (struct dump_allocator){
+ .start = mem,
+ .curr = mem,
+ .pos = 0,
+ .capacity = dump_size,
+ };
+
+ hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_VERSION,
+ sizeof(struct drm_panthor_dump_version));
+ if (IS_ERR(hdr)) {
+ ret = PTR_ERR(hdr);
+ goto free_valloc;
+ }
+
+ version = alloc_bytes(&alloc, sizeof(*version));
+ if (IS_ERR(version)) {
+ ret = PTR_ERR(version);
+ goto free_valloc;
+ }
+
+ *version = (struct drm_panthor_dump_version){
+ .major = PANT_DUMP_MAJOR,
+ .minor = PANT_DUMP_MINOR,
+ };
+
+ hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_GPU_INFO,
+ sizeof(args->ptdev->gpu_info));
+ if (IS_ERR(hdr)) {
+ ret = PTR_ERR(hdr);
+ goto free_valloc;
+ }
+
+ gpu_info = alloc_bytes(&alloc, sizeof(*gpu_info));
+ if (IS_ERR(gpu_info)) {
+ ret = PTR_ERR(gpu_info);
+ goto free_valloc;
+ }
+
+ *gpu_info = args->ptdev->gpu_info;
+
+ hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_CSIF_INFO,
+ sizeof(args->ptdev->csif_info));
+ if (IS_ERR(hdr)) {
+ ret = PTR_ERR(hdr);
+ goto free_valloc;
+ }
+
+ csif_info = alloc_bytes(&alloc, sizeof(*csif_info));
+ if (IS_ERR(csif_info)) {
+ ret = PTR_ERR(csif_info);
+ goto free_valloc;
+ }
+
+ *csif_info = args->ptdev->csif_info;
+
+ hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_FW_INFO,
+ sizeof(args->ptdev->fw_info));
+ if (IS_ERR(hdr)) {
+ ret = PTR_ERR(hdr);
+ goto free_valloc;
+ }
+
+ fw_info = alloc_bytes(&alloc, sizeof(*fw_info));
+ if (IS_ERR(fw_info)) {
+ ret = PTR_ERR(fw_info);
+ goto free_valloc;
+ }
+
+ *fw_info = args->ptdev->fw_info;
+
+ dump_va_args.ptdev = args->ptdev;
+ dump_va_args.alloc = &alloc;
+ ret = panthor_vm_foreach_va(args->group_vm, dump_va_cb, &dump_va_args);
+ if (ret)
+ goto free_valloc;
+
+ dump_group_args =
+ (struct dump_group_args){ args->ptdev, &alloc, args->group };
+ panthor_sched_get_groupinfo(args->group, &group_info);
+ dump_group_info(&dump_group_args, &group_info);
+
+ if (alloc.pos < dump_size)
+ drm_warn(&args->ptdev->base,
+ "dump size mismatch: expected %d, got %zu\n",
+ dump_size, alloc.pos);
+
+ dev_coredumpv(args->ptdev->base.dev, alloc.start, alloc.pos,
+ GFP_KERNEL);
+
+ return ret;
+
+free_valloc:
+ vfree(mem);
+ return ret;
+}
diff --git a/drivers/gpu/drm/panthor/panthor_dump.h b/drivers/gpu/drm/panthor/panthor_dump.h
new file mode 100644
index 000000000000..2a02943a2dbd
--- /dev/null
+++ b/drivers/gpu/drm/panthor/panthor_dump.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 or MIT */
+/* SPDX-FileCopyrightText: Copyright Collabora 2024 */
+
+#ifndef __PANTHOR_DUMP_H__
+#define __PANTHOR_DUMP_H__
+
+#include <drm/drm_gpuvm.h>
+#include <drm/panthor_drm.h>
+
+#include "panthor_device.h"
+#include "panthor_gem.h"
+
+struct panthor_core_dump_args {
+ struct panthor_device *ptdev;
+ struct panthor_vm *group_vm;
+ struct panthor_group *group;
+};
+
+int panthor_core_dump(struct panthor_core_dump_args *args);
+
+#endif /* __PANTHOR_DUMP_H__ */
diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
index 412e95fcfb92..61d61157ace0 100644
--- a/drivers/gpu/drm/panthor/panthor_mmu.c
+++ b/drivers/gpu/drm/panthor/panthor_mmu.c
@@ -2632,6 +2632,28 @@ int panthor_vm_prepare_mapped_bos_resvs(struct drm_exec *exec, struct panthor_vm
return drm_gpuvm_prepare_objects(&vm->base, exec, slot_count);
}

+/**
+ * panthor_vm_foreachva() - Execute a callback for each VA in a VM
+ *
+ */
+int panthor_vm_foreach_va(struct panthor_vm *vm,
+ int (*cb)(void *priv, const struct drm_gpuva *va),
+ void *priv)
+{
+ struct drm_gpuva *va;
+ int ret = 0;
+
+ mutex_lock(&vm->op_lock);
+ drm_gpuvm_for_each_va(va, &vm->base) {
+ ret = cb(priv, va);
+ if (ret)
+ break;
+ }
+ mutex_unlock(&vm->op_lock);
+
+ return ret;
+}
+
/**
* panthor_mmu_unplug() - Unplug the MMU logic
* @ptdev: Device.
diff --git a/drivers/gpu/drm/panthor/panthor_mmu.h b/drivers/gpu/drm/panthor/panthor_mmu.h
index 6788771071e3..05a5d68b23ae 100644
--- a/drivers/gpu/drm/panthor/panthor_mmu.h
+++ b/drivers/gpu/drm/panthor/panthor_mmu.h
@@ -8,6 +8,7 @@
#include <linux/dma-resv.h>

struct drm_exec;
+struct drm_gpuva;
struct drm_sched_job;
struct panthor_gem_object;
struct panthor_heap_pool;
@@ -52,6 +53,11 @@ void panthor_vm_add_job_fence_to_bos_resvs(struct panthor_vm *vm,
struct drm_sched_job *job);

struct dma_resv *panthor_vm_resv(struct panthor_vm *vm);
+
+int panthor_vm_foreach_va(struct panthor_vm *vm,
+ int (*cb)(void *priv, const struct drm_gpuva *va),
+ void *priv);
+
struct drm_gem_object *panthor_vm_root_gem(struct panthor_vm *vm);

void panthor_vm_pool_destroy(struct panthor_file *pfile);
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index e0ecc8bcfaae..59c30b311ee9 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -24,6 +24,7 @@

#include "panthor_devfreq.h"
#include "panthor_device.h"
+#include "panthor_dump.h"
#include "panthor_fw.h"
#include "panthor_gem.h"
#include "panthor_gpu.h"
@@ -2805,6 +2806,45 @@ static void group_sync_upd_work(struct work_struct *work)
group_put(group);
}

+/**
+ * panthor_sched_get_groupinfo() - Build a group info structure for the group
+ *
+ * @group: the group to build a group info structure for
+ * @info: the group info structure to fill
+ */
+void panthor_sched_get_groupinfo(struct panthor_group *group,
+ struct drm_panthor_dump_group_info *info)
+{
+ info->queue_count = group->queue_count;
+ info->faulty_bitmask = group->fatal_queues;
+}
+
+/** panthor_sched_get_queueinfo() - Build a queue info structure for a queue
+ * given its group and its cs_id
+ *
+ * @group: the group the queue belongs to
+ * @cs_id: the command stream ID of the queue
+ * @info: the queue info structure to fill
+ */
+int panthor_sched_get_queueinfo(struct panthor_group *group, u32 cs_id,
+ struct drm_panthor_dump_queue_info *info)
+{
+ struct panthor_queue *queue;
+
+ if (cs_id >= group->queue_count)
+ return -EINVAL;
+
+ queue = group->queues[cs_id];
+
+ info->cs_id = cs_id;
+ info->ringbuf_insert = queue->iface.input->insert;
+ info->ringbuf_extract = queue->iface.output->extract;
+ info->ringbuf_gpuva = panthor_kernel_bo_gpuva(queue->ringbuf);
+ info->ringbuf_size = panthor_kernel_bo_size(queue->ringbuf);
+
+ return 0;
+}
+
static struct dma_fence *
queue_run_job(struct drm_sched_job *sched_job)
{
@@ -2946,7 +2986,7 @@ queue_timedout_job(struct drm_sched_job *sched_job)
struct panthor_device *ptdev = group->ptdev;
struct panthor_scheduler *sched = ptdev->scheduler;
struct panthor_queue *queue = group->queues[job->queue_idx];
-
+ struct panthor_core_dump_args core_dump_args;
drm_warn(&ptdev->base, "job timeout\n");

drm_WARN_ON(&ptdev->base, atomic_read(&sched->reset.in_progress));
@@ -2955,6 +2995,15 @@ queue_timedout_job(struct drm_sched_job *sched_job)

mutex_lock(&sched->lock);
group->timedout = true;
+
+ core_dump_args = (struct panthor_core_dump_args) {
+ .ptdev = ptdev,
+ .group_vm = job->group->vm,
+ .group = job->group,
+ };
+
+ panthor_core_dump(&core_dump_args);
+
if (group->csg_id >= 0) {
sched_queue_delayed_work(ptdev->scheduler, tick, 0);
} else {
diff --git a/drivers/gpu/drm/panthor/panthor_sched.h b/drivers/gpu/drm/panthor/panthor_sched.h
index 3a30d2328b30..9a5b53498dcc 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.h
+++ b/drivers/gpu/drm/panthor/panthor_sched.h
@@ -17,6 +17,9 @@ struct panthor_device;
struct panthor_file;
struct panthor_group_pool;
struct panthor_job;
+struct panthor_group;
+struct drm_panthor_dump_group_info;
+struct drm_panthor_dump_queue_info;

int panthor_group_create(struct panthor_file *pfile,
const struct drm_panthor_group_create *group_args,
@@ -41,6 +44,13 @@ int panthor_sched_init(struct panthor_device *ptdev);
void panthor_sched_unplug(struct panthor_device *ptdev);
void panthor_sched_pre_reset(struct panthor_device *ptdev);
void panthor_sched_post_reset(struct panthor_device *ptdev, bool reset_failed);
+
+void panthor_sched_get_groupinfo(struct panthor_group *group,
+ struct drm_panthor_dump_group_info *info);
+
+int panthor_sched_get_queueinfo(struct panthor_group *group, u32 cs_id,
+ struct drm_panthor_dump_queue_info *info);
+
void panthor_sched_suspend(struct panthor_device *ptdev);
void panthor_sched_resume(struct panthor_device *ptdev);

diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h
index e235cf452460..82ec0f20c49e 100644
--- a/include/uapi/drm/panthor_drm.h
+++ b/include/uapi/drm/panthor_drm.h
@@ -969,6 +969,130 @@ struct drm_panthor_tiler_heap_destroy {
__u32 pad;
};

+/**
+ * enum drm_panthor_dump_header_type - Identifies the type of data that follows
+ * in a panthor core dump.
+ */
+enum drm_panthor_dump_header_type {
+ DRM_PANTHOR_DUMP_HEADER_TYPE_VERSION = 0,
+ /**
+ * @DRM_PANTHOR_DUMP_HEADER_TYPE_GPU_INFO: Gpu information.
+ */
+ DRM_PANTHOR_DUMP_HEADER_TYPE_GPU_INFO = 1,
+ /**
+ * @DRM_PANTHOR_DUMP_HEADER_TYPE_CSIF_INFO: Command stream interface information.
+ */
+ DRM_PANTHOR_DUMP_HEADER_TYPE_CSIF_INFO = 2,
+ /**
+ * @DRM_PANTHOR_DUMP_HEADER_TYPE_FW_INFO: Information about the firmware.
+ */
+ DRM_PANTHOR_DUMP_HEADER_TYPE_FW_INFO = 3,
+ /**
+ * @DRM_PANTHOR_DUMP_HEADER_TYPE_VM: A dump of the VM for the context.
+ */
+ DRM_PANTHOR_DUMP_HEADER_TYPE_VM = 4,
+ /**
+ * @DRM_PANTHOR_DUMP_HEADER_TYPE_GROUP_INFO: Describes a group. A dump can
+ * contain either the faulty group, or all groups for the DRM FD.
+ */
+ DRM_PANTHOR_DUMP_HEADER_TYPE_GROUP_INFO = 5,
+ /**
+ * @DRM_PANTHOR_DUMP_HEADER_TYPE_QUEUE_INFO: Describes a faulty queue. This
+ * will immediately follow a group info.
+ */
+ DRM_PANTHOR_DUMP_HEADER_TYPE_QUEUE_INFO = 6,
+};
+
+/**
+ * struct drm_panthor_dump_header - A header that describes a section of a panthor core dump.
+ */
+struct drm_panthor_dump_header {
+ /** @magic: Always set to PANT (0x544e4150). */
+ __u32 magic;
+
+ /** @header_type: Identifies the type of data in the following section of the
+ * core dump file
+ */
+ enum drm_panthor_dump_header_type header_type;
+
+ /** @header_size: The size of the header.
+ *
+ * This is for backward-compatibility purposes in case this structure is
+ * augmented in the future. It allows userspace to skip over the header and
+ * access the actual data it describes.
+ */
+ __u32 header_size;
+
+ /** @data_size: The size of the following section */
+ __u32 data_size;
+};
+
+/**
+ * struct drm_panthor_dump_version - Version information for a Panthor GPU dump.
+ *
+ * This structure is used to hold version information when performing a dump of
+ * the state of a Panthor GPU.
+ */
+struct drm_panthor_dump_version {
+ /** @major: Versioning information for backwards compatibility */
+ __u32 major;
+ /** @minor: Versioning information for backwards compatibility */
+ __u32 minor;
+};
+
+/**
+ * struct drm_panthor_dump_group_info - Group information for a Panthor GPU
+ * dump.
+ *
+ * This structure is used to hold information about a group when performing a
+ * dump of the state of a Panthor GPU.
+ */
+struct drm_panthor_dump_group_info {
+ /** @queue_count: The number of queues in the group. */
+ __u32 queue_count;
+ /** @faulty_queues: A bitmask denoting the faulty queues */
+ __u32 faulty_bitmask;
+};
+
+#define DRM_PANTHOR_DUMP_QUEUE_INFO_FLAGS_FAULTY (1 << 0)
+
+/**
+ * struct drm_panthor_dump_queue_info - Queue information for a Panthor GPU
+ * dump.
+ *
+ * This structure is used to hold information about a queue when performing a
+ * dump of the state of a Panthor GPU.
+ */
+struct drm_panthor_dump_queue_info {
+ /** See DRM_PANTHOR_DUMP_QUEUE_INFO_FLAGS_XXX */
+ u32 flags;
+ /** @cs_id: The ID of the command stream. */
+ __s32 cs_id;
+ /** @faulty: Whether this queue has faulted */
+ /** @ringbuf_gpuva: The GPU virtual address of the ring buffer. */
+ __u64 ringbuf_gpuva;
+ /** @ringbuf_insert: The insert point (i.e.: offset) in the ring buffer. This
+ * is where a instruction would be inserted next by the CPU.
+ */
+ __u64 ringbuf_insert;
+ /** @ringbuf_extract: The extract point (i.e.: offset) in the ring buffer.
+ * This is where the GPU would read the next instruction.
+ */
+ __u64 ringbuf_extract;
+ /** @ringbuf_size: The size of the ring buffer */
+ __u64 ringbuf_size;
+};
+
+/**
+ * struct drm_panthor_dump_gpuva - Describes a GPU VA range in the dump.
+ */
+struct drm_panthor_dump_gpuva {
+ /** @addr: The start address for the mapping */
+ __u64 addr;
+ /** @range: The range covered by the VA mapping */
+ __u64 range;
+};
+
#if defined(__cplusplus)
}
#endif
--
2.45.2