1 /* 2 * Copyright (c) 2006-2023, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2021-11-11 GuEe-GUI the first version 9 */ 10 11 #ifndef __VIRTIO_GPU_H__ 12 #define __VIRTIO_GPU_H__ 13 14 #include <rtdef.h> 15 16 #include <virtio.h> 17 18 #define VIRTIO_GPU_QUEUE_CTRL 0 19 #define VIRTIO_GPU_QUEUE_CURSOR 1 20 #define VIRTIO_GPU_QUEUE_SIZE 32 21 22 #define VIRTIO_GPU_F_VIRGL 0 /* VIRTIO_GPU_CMD_CTX_*, VIRTIO_GPU_CMD_*_3D */ 23 #define VIRTIO_GPU_F_EDID 1 /* VIRTIO_GPU_CMD_GET_EDID */ 24 #define VIRTIO_GPU_F_RESOURCE_UUID 2 /* VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID */ 25 #define VIRTIO_GPU_F_RESOURCE_BLOB 3 /* VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB */ 26 #define VIRTIO_GPU_F_CONTEXT_INIT 4 /* VIRTIO_GPU_CMD_CREATE_CONTEXT with context_init and multiple timelines */ 27 28 #define VIRTIO_GPU_EVENT_DISPLAY (1 << 0) 29 30 #define VIRTIO_GPU_FORMAT_BPP 32 31 #define VIRTIO_GPU_FORMAT_PIXEL 4 32 #define VIRTIO_GPU_CURSOR_WIDTH 64 33 #define VIRTIO_GPU_CURSOR_HEIGHT 64 34 #define VIRTIO_GPU_CURSOR_IMG_SIZE (VIRTIO_GPU_CURSOR_WIDTH * VIRTIO_GPU_CURSOR_HEIGHT * VIRTIO_GPU_FORMAT_PIXEL) 35 #define VIRTIO_GPU_INVALID_PMODE_ID RT_UINT32_MAX 36 37 /* GPU control */ 38 39 struct virtio_gpu_config 40 { 41 rt_uint32_t events_read; 42 rt_uint32_t events_clear; 43 rt_uint32_t num_scanouts; /* 1 ~ 16 */ 44 rt_uint32_t reserved; 45 }; 46 47 enum virtio_gpu_ctrl_type 48 { 49 VIRTIO_GPU_UNDEFINED = 0, 50 51 /* 2d commands */ 52 VIRTIO_GPU_CMD_GET_DISPLAY_INFO = 0x0100, 53 VIRTIO_GPU_CMD_RESOURCE_CREATE_2D, 54 VIRTIO_GPU_CMD_RESOURCE_UNREF, 55 VIRTIO_GPU_CMD_SET_SCANOUT, 56 VIRTIO_GPU_CMD_RESOURCE_FLUSH, 57 VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D, 58 VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING, 59 VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING, 60 VIRTIO_GPU_CMD_GET_CAPSET_INFO, 61 VIRTIO_GPU_CMD_GET_CAPSET, 62 VIRTIO_GPU_CMD_GET_EDID, 63 VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID, 64 VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB, 65 VIRTIO_GPU_CMD_SET_SCANOUT_BLOB, 66 67 /* 3d commands */ 68 VIRTIO_GPU_CMD_CTX_CREATE = 0x0200, 69 VIRTIO_GPU_CMD_CTX_DESTROY, 70 VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE, 71 VIRTIO_GPU_CMD_CTX_DETACH_RESOURCE, 72 VIRTIO_GPU_CMD_RESOURCE_CREATE_3D, 73 VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D, 74 VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D, 75 VIRTIO_GPU_CMD_SUBMIT_3D, 76 VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB, 77 VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB, 78 79 /* cursor commands */ 80 VIRTIO_GPU_CMD_UPDATE_CURSOR = 0x0300, 81 VIRTIO_GPU_CMD_MOVE_CURSOR, 82 83 /* success responses */ 84 VIRTIO_GPU_RESP_OK_NODATA = 0x1100, 85 VIRTIO_GPU_RESP_OK_DISPLAY_INFO, 86 VIRTIO_GPU_RESP_OK_CAPSET_INFO, 87 VIRTIO_GPU_RESP_OK_CAPSET, 88 VIRTIO_GPU_RESP_OK_EDID, 89 VIRTIO_GPU_RESP_OK_RESOURCE_UUID, 90 VIRTIO_GPU_RESP_OK_MAP_INFO, 91 92 /* error responses */ 93 VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200, 94 VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY, 95 VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID, 96 VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID, 97 VIRTIO_GPU_RESP_ERR_INVALID_CONTEXT_ID, 98 VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER, 99 }; 100 101 #define VIRTIO_GPU_FLAG_FENCE (1 << 0) 102 103 struct virtio_gpu_ctrl_hdr 104 { 105 rt_uint32_t type; 106 rt_uint32_t flags; 107 rt_uint64_t fence_id; 108 rt_uint32_t ctx_id; 109 rt_uint8_t ring_idx; 110 rt_uint8_t padding[3]; 111 }; 112 113 #define VIRTIO_GPU_MAX_SCANOUTS 16 114 115 struct virtio_gpu_rect 116 { 117 rt_uint32_t x; 118 rt_uint32_t y; 119 rt_uint32_t width; 120 rt_uint32_t height; 121 }; 122 123 struct virtio_gpu_resp_display_info 124 { 125 struct virtio_gpu_ctrl_hdr hdr; 126 struct virtio_gpu_display_one 127 { 128 struct virtio_gpu_rect r; 129 rt_uint32_t enabled; 130 rt_uint32_t flags; 131 } pmodes[VIRTIO_GPU_MAX_SCANOUTS]; 132 }; 133 134 struct virtio_gpu_get_edid 135 { 136 struct virtio_gpu_ctrl_hdr hdr; 137 rt_uint32_t scanout; 138 rt_uint32_t padding; 139 }; 140 141 struct virtio_gpu_resp_edid 142 { 143 struct virtio_gpu_ctrl_hdr hdr; 144 rt_uint32_t size; 145 rt_uint32_t padding; 146 rt_uint8_t edid[1024]; 147 }; 148 149 enum virtio_gpu_formats 150 { 151 VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM = 1, 152 VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM = 2, 153 VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM = 3, 154 VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM = 4, 155 156 VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM = 67, 157 VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM = 68, 158 159 VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM = 121, 160 VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM = 134, 161 }; 162 163 struct virtio_gpu_resource_create_2d 164 { 165 struct virtio_gpu_ctrl_hdr hdr; 166 rt_uint32_t resource_id; 167 rt_uint32_t format; 168 rt_uint32_t width; 169 rt_uint32_t height; 170 }; 171 172 struct virtio_gpu_resource_unref 173 { 174 struct virtio_gpu_ctrl_hdr hdr; 175 rt_uint32_t resource_id; 176 rt_uint32_t padding; 177 }; 178 179 struct virtio_gpu_set_scanout 180 { 181 struct virtio_gpu_ctrl_hdr hdr; 182 struct virtio_gpu_rect r; 183 rt_uint32_t scanout_id; 184 rt_uint32_t resource_id; 185 }; 186 187 struct virtio_gpu_resource_flush 188 { 189 struct virtio_gpu_ctrl_hdr hdr; 190 struct virtio_gpu_rect r; 191 rt_uint32_t resource_id; 192 rt_uint32_t padding; 193 }; 194 195 struct virtio_gpu_transfer_to_host_2d 196 { 197 struct virtio_gpu_ctrl_hdr hdr; 198 struct virtio_gpu_rect r; 199 rt_uint64_t offset; 200 rt_uint32_t resource_id; 201 rt_uint32_t padding; 202 }; 203 204 struct virtio_gpu_resource_attach_backing 205 { 206 struct virtio_gpu_ctrl_hdr hdr; 207 rt_uint32_t resource_id; 208 rt_uint32_t nr_entries; 209 }; 210 211 struct virtio_gpu_mem_entry 212 { 213 rt_uint64_t addr; 214 rt_uint32_t length; 215 rt_uint32_t padding; 216 }; 217 218 struct virtio_gpu_resource_detach_backing 219 { 220 struct virtio_gpu_ctrl_hdr hdr; 221 rt_uint32_t resource_id; 222 rt_uint32_t padding; 223 }; 224 225 struct virtio_gpu_get_capset_info 226 { 227 struct virtio_gpu_ctrl_hdr hdr; 228 rt_uint32_t capset_index; 229 rt_uint32_t padding; 230 }; 231 232 #define VIRTIO_GPU_CAPSET_VIRGL 1 233 #define VIRTIO_GPU_CAPSET_VIRGL2 2 234 #define VIRTIO_GPU_CAPSET_GFXSTREAM 3 235 #define VIRTIO_GPU_CAPSET_VENUS 4 236 #define VIRTIO_GPU_CAPSET_CROSS_DOMAIN 5 237 238 struct virtio_gpu_resp_capset_info 239 { 240 struct virtio_gpu_ctrl_hdr hdr; 241 rt_uint32_t capset_id; 242 rt_uint32_t capset_max_version; 243 rt_uint32_t capset_max_size; 244 rt_uint32_t padding; 245 }; 246 247 struct virtio_gpu_get_capset 248 { 249 struct virtio_gpu_ctrl_hdr hdr; 250 rt_uint32_t capset_id; 251 rt_uint32_t capset_version; 252 }; 253 254 struct virtio_gpu_resp_capset 255 { 256 struct virtio_gpu_ctrl_hdr hdr; 257 rt_uint8_t capset_data[]; 258 }; 259 260 struct virtio_gpu_resource_assign_uuid 261 { 262 struct virtio_gpu_ctrl_hdr hdr; 263 rt_uint32_t resource_id; 264 rt_uint32_t padding; 265 }; 266 267 struct virtio_gpu_resp_resource_uuid 268 { 269 struct virtio_gpu_ctrl_hdr hdr; 270 rt_uint8_t uuid[16]; 271 }; 272 273 #define VIRTIO_GPU_BLOB_MEM_GUEST 0x0001 274 #define VIRTIO_GPU_BLOB_MEM_HOST3D 0x0002 275 #define VIRTIO_GPU_BLOB_MEM_HOST3D_GUEST 0x0003 276 277 #define VIRTIO_GPU_BLOB_FLAG_USE_MAPPABLE 0x0001 278 #define VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE 0x0002 279 #define VIRTIO_GPU_BLOB_FLAG_USE_CROSS_DEVICE 0x0004 280 281 struct virtio_gpu_resource_create_blob 282 { 283 struct virtio_gpu_ctrl_hdr hdr; 284 rt_uint32_t resource_id; 285 rt_uint32_t blob_mem; 286 rt_uint32_t blob_flags; 287 rt_uint32_t nr_entries; 288 rt_uint64_t blob_id; 289 rt_uint64_t size; 290 }; 291 292 struct virtio_gpu_set_scanout_blob 293 { 294 struct virtio_gpu_ctrl_hdr hdr; 295 struct virtio_gpu_rect r; 296 rt_uint32_t scanout_id; 297 rt_uint32_t resource_id; 298 rt_uint32_t width; 299 rt_uint32_t height; 300 rt_uint32_t format; 301 rt_uint32_t padding; 302 rt_uint32_t strides[4]; 303 rt_uint32_t offsets[4]; 304 }; 305 306 #define VIRTIO_GPU_CONTEXT_INIT_CAPSET_ID_MASK 0x000000ff 307 struct virtio_gpu_ctx_create 308 { 309 struct virtio_gpu_ctrl_hdr hdr; 310 rt_uint32_t nlen; 311 rt_uint32_t context_init; 312 char debug_name[64]; 313 }; 314 315 struct virtio_gpu_resource_map_blob 316 { 317 struct virtio_gpu_ctrl_hdr hdr; 318 rt_uint32_t resource_id; 319 rt_uint32_t padding; 320 rt_uint64_t offset; 321 }; 322 323 #define VIRTIO_GPU_MAP_CACHE_MASK 0x0f 324 #define VIRTIO_GPU_MAP_CACHE_NONE 0x00 325 #define VIRTIO_GPU_MAP_CACHE_CACHED 0x01 326 #define VIRTIO_GPU_MAP_CACHE_UNCACHED 0x02 327 #define VIRTIO_GPU_MAP_CACHE_WC 0x03 328 329 struct virtio_gpu_resp_map_info 330 { 331 struct virtio_gpu_ctrl_hdr hdr; 332 rt_uint32_t map_info; 333 rt_uint32_t padding; 334 }; 335 336 struct virtio_gpu_resource_unmap_blob 337 { 338 struct virtio_gpu_ctrl_hdr hdr; 339 rt_uint32_t resource_id; 340 rt_uint32_t padding; 341 }; 342 343 /* GPU cursor */ 344 345 struct virtio_gpu_cursor_pos 346 { 347 rt_uint32_t scanout_id; 348 rt_uint32_t x; 349 rt_uint32_t y; 350 rt_uint32_t padding; 351 }; 352 353 struct virtio_gpu_update_cursor 354 { 355 struct virtio_gpu_ctrl_hdr hdr; 356 struct virtio_gpu_cursor_pos pos; 357 rt_uint32_t resource_id; 358 rt_uint32_t hot_x; 359 rt_uint32_t hot_y; 360 rt_uint32_t padding; 361 }; 362 363 struct virtio_gpu_device 364 { 365 struct rt_device parent; 366 367 struct virtio_device virtio_dev; 368 369 /* Current display's info */ 370 struct virtio_gpu_display_one pmode; 371 enum virtio_gpu_formats format; 372 rt_uint32_t pmode_id; 373 rt_uint32_t cursor_x, cursor_y; 374 rt_uint32_t display_resource_id; 375 rt_uint32_t cursor_resource_id; 376 rt_uint32_t next_resource_id; 377 378 /* Display framebuffer */ 379 struct rt_mutex rw_mutex; 380 void *framebuffer; 381 rt_uint32_t smem_len; 382 383 /* Cursor image info */ 384 rt_bool_t cursor_enable; 385 struct rt_mutex ops_mutex; 386 rt_uint8_t cursor_img[VIRTIO_GPU_CURSOR_IMG_SIZE]; 387 388 /* GPU request info */ 389 struct virtio_gpu_resp_display_info gpu_request; 390 391 struct 392 { 393 rt_bool_t ctrl_valid; 394 rt_bool_t cursor_valid; 395 396 struct virtio_gpu_update_cursor cursor_cmd; 397 } info[VIRTIO_GPU_QUEUE_SIZE]; 398 }; 399 400 rt_err_t rt_virtio_gpu_init(rt_ubase_t *mmio_base, rt_uint32_t irq); 401 402 enum 403 { 404 VIRTIO_DEVICE_CTRL_GPU_SET_PRIMARY = 0x20, 405 VIRTIO_DEVICE_CTRL_GPU_CREATE_2D, 406 407 VIRTIO_DEVICE_CTRL_CURSOR_SETUP, 408 VIRTIO_DEVICE_CTRL_CURSOR_SET_IMG, 409 VIRTIO_DEVICE_CTRL_CURSOR_MOVE, 410 }; 411 412 #endif /* __VIRTIO_GPU_H__ */ 413