1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
|
/* 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>
#include <stdbool.h>
#include "panthor_drm.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);
void igt_panthor_group_create(int fd, struct drm_panthor_group_create *group_create, int err);
void igt_panthor_group_destroy(int fd, uint32_t group_handle, int err);
void igt_panthor_group_submit(int fd, struct drm_panthor_group_submit *group_submit, int err);
uint32_t igt_panthor_group_create_simple(int fd, uint32_t vm_id, int err);
void igt_panthor_group_submit_simple(int fd, uint32_t group_handle,
uint32_t queue_index, uint64_t stream_addr,
uint32_t stream_size, uint32_t syncobj_handle,
int err);
uint64_t igt_panthor_get_first_core(uint64_t cores_present);
enum cs_opcode {
CS_OPCODE_NOP = 0,
CS_OPCODE_MOVE48 = 1,
CS_OPCODE_MOVE32 = 2,
CS_OPCODE_WAIT = 3,
CS_OPCODE_STM = 21,
CS_OPCODE_FLUSH_CACHE = 36,
};
enum cs_flush_mode {
CS_FLUSH_MODE_NONE = 0,
CS_FLUSH_MODE_CLEAN = 1,
CS_FLUSH_MODE_INVALIDATE = 2,
CS_FLUSH_MODE_CLEAN_AND_INVALIDATE = 3,
};
/* There's no plan to support big endian in the UMD, so keep
* things simple and don't bother supporting it here either.
*/
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#error "big endian not supported"
#endif
struct cs_instr {
union {
struct {
uint64_t data: 56;
uint64_t opcode: 8;
} any;
struct {
uint64_t unused: 56;
uint64_t opcode: 8;
} nop;
struct {
uint64_t immediate: 48;
uint64_t dest: 8;
uint64_t opcode: 8;
} move48;
struct {
uint64_t immediate: 32;
uint64_t unused: 16;
uint64_t dest: 8;
uint64_t opcode: 8;
} move32;
struct {
uint64_t unused0: 16;
uint64_t wait_mask: 16;
uint64_t progress_inc: 1;
uint64_t unused1: 23;
uint64_t opcode: 8;
} wait;
struct {
uint64_t offset: 16;
uint64_t mask: 16;
uint64_t unused: 8;
uint64_t address: 8;
uint64_t src: 8;
uint64_t opcode: 8;
} stm;
struct {
uint64_t l2_mode: 4;
uint64_t lsc_mode: 4;
uint64_t other_mode: 4;
uint64_t unused0: 4;
uint64_t wait_mask: 16;
uint64_t unused1: 8;
uint64_t flush_id: 8;
uint64_t signal_slot: 4;
uint64_t unused2: 4;
uint64_t opcode: 8;
} flush;
uint64_t raw;
};
};
static inline uint64_t
cs_nop(void)
{
struct cs_instr instr = {
.nop = {
.opcode = CS_OPCODE_NOP,
},
};
return instr.raw;
}
static inline uint64_t
cs_mov48(uint8_t dst, uint64_t imm)
{
struct cs_instr instr = {
.move48 = {
.opcode = CS_OPCODE_MOVE48,
.dest = dst,
.immediate = (uint64_t)imm & 0xffffffffffffull,
},
};
return instr.raw;
}
static inline uint64_t
cs_mov32(uint8_t dst, uint32_t imm)
{
struct cs_instr instr = {
.move32 = {
.opcode = CS_OPCODE_MOVE32,
.dest = dst,
.immediate = (uint32_t)imm,
},
};
return instr.raw;
}
static inline uint64_t
cs_wait(uint16_t wait_mask, bool progress_inc)
{
struct cs_instr instr = {
.wait = {
.opcode = CS_OPCODE_WAIT,
.wait_mask = wait_mask,
.progress_inc = progress_inc,
},
};
return instr.raw;
}
static inline uint64_t
cs_stm(uint8_t address, uint8_t src, uint16_t mask, int16_t offset)
{
struct cs_instr instr = {
.stm = {
.opcode = CS_OPCODE_STM,
.offset = (uint16_t)offset,
.mask = mask,
.src = src,
.address = address,
},
};
return instr.raw;
}
static inline uint64_t
cs_stm32(uint8_t address, uint8_t src, int16_t offset)
{
return cs_stm(address, src, 0x1, offset);
}
static inline uint64_t
cs_stm64(uint8_t address, uint8_t src, int16_t offset)
{
return cs_stm(address, src, 0x3, offset);
}
static inline uint64_t
cs_flush(enum cs_flush_mode l2_mode,
enum cs_flush_mode lsc_mode,
enum cs_flush_mode other_mode,
uint16_t wait_mask,
uint8_t flush_id,
uint8_t signal_slot)
{
struct cs_instr instr = {
.flush = {
.l2_mode = l2_mode,
.lsc_mode = lsc_mode,
.other_mode = other_mode,
.wait_mask = wait_mask,
.flush_id = flush_id,
.signal_slot = signal_slot,
.opcode = CS_OPCODE_FLUSH_CACHE,
},
};
return instr.raw;
}
#endif /* IGT_PANTHOR_H */
|