1d722e3fbSopenharmony_ci/* 2d722e3fbSopenharmony_ci * Copyright 2014 Advanced Micro Devices, Inc. 3d722e3fbSopenharmony_ci * 4d722e3fbSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5d722e3fbSopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6d722e3fbSopenharmony_ci * to deal in the Software without restriction, including without limitation 7d722e3fbSopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8d722e3fbSopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9d722e3fbSopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10d722e3fbSopenharmony_ci * 11d722e3fbSopenharmony_ci * The above copyright notice and this permission notice shall be included in 12d722e3fbSopenharmony_ci * all copies or substantial portions of the Software. 13d722e3fbSopenharmony_ci * 14d722e3fbSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15d722e3fbSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16d722e3fbSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17d722e3fbSopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18d722e3fbSopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19d722e3fbSopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20d722e3fbSopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 21d722e3fbSopenharmony_ci * 22d722e3fbSopenharmony_ci */ 23d722e3fbSopenharmony_ci 24d722e3fbSopenharmony_ci#include <stdlib.h> 25d722e3fbSopenharmony_ci#include <stdio.h> 26d722e3fbSopenharmony_ci#include <string.h> 27d722e3fbSopenharmony_ci#include <errno.h> 28d722e3fbSopenharmony_ci#include <pthread.h> 29d722e3fbSopenharmony_ci#include <sched.h> 30d722e3fbSopenharmony_ci#include <sys/ioctl.h> 31d722e3fbSopenharmony_ci#if HAVE_ALLOCA_H 32d722e3fbSopenharmony_ci# include <alloca.h> 33d722e3fbSopenharmony_ci#endif 34d722e3fbSopenharmony_ci 35d722e3fbSopenharmony_ci#include "xf86drm.h" 36d722e3fbSopenharmony_ci#include "amdgpu_drm.h" 37d722e3fbSopenharmony_ci#include "amdgpu_internal.h" 38d722e3fbSopenharmony_ci 39d722e3fbSopenharmony_cistatic int amdgpu_cs_unreference_sem(amdgpu_semaphore_handle sem); 40d722e3fbSopenharmony_cistatic int amdgpu_cs_reset_sem(amdgpu_semaphore_handle sem); 41d722e3fbSopenharmony_ci 42d722e3fbSopenharmony_ci/** 43d722e3fbSopenharmony_ci * Create command submission context 44d722e3fbSopenharmony_ci * 45d722e3fbSopenharmony_ci * \param dev - \c [in] Device handle. See #amdgpu_device_initialize() 46d722e3fbSopenharmony_ci * \param priority - \c [in] Context creation flags. See AMDGPU_CTX_PRIORITY_* 47d722e3fbSopenharmony_ci * \param context - \c [out] GPU Context handle 48d722e3fbSopenharmony_ci * 49d722e3fbSopenharmony_ci * \return 0 on success otherwise POSIX Error code 50d722e3fbSopenharmony_ci*/ 51d722e3fbSopenharmony_cidrm_public int amdgpu_cs_ctx_create2(amdgpu_device_handle dev, 52d722e3fbSopenharmony_ci uint32_t priority, 53d722e3fbSopenharmony_ci amdgpu_context_handle *context) 54d722e3fbSopenharmony_ci{ 55d722e3fbSopenharmony_ci struct amdgpu_context *gpu_context; 56d722e3fbSopenharmony_ci union drm_amdgpu_ctx args; 57d722e3fbSopenharmony_ci int i, j, k; 58d722e3fbSopenharmony_ci int r; 59d722e3fbSopenharmony_ci 60d722e3fbSopenharmony_ci if (!dev || !context) 61d722e3fbSopenharmony_ci return -EINVAL; 62d722e3fbSopenharmony_ci 63d722e3fbSopenharmony_ci gpu_context = calloc(1, sizeof(struct amdgpu_context)); 64d722e3fbSopenharmony_ci if (!gpu_context) 65d722e3fbSopenharmony_ci return -ENOMEM; 66d722e3fbSopenharmony_ci 67d722e3fbSopenharmony_ci gpu_context->dev = dev; 68d722e3fbSopenharmony_ci 69d722e3fbSopenharmony_ci r = pthread_mutex_init(&gpu_context->sequence_mutex, NULL); 70d722e3fbSopenharmony_ci if (r) 71d722e3fbSopenharmony_ci goto error; 72d722e3fbSopenharmony_ci 73d722e3fbSopenharmony_ci /* Create the context */ 74d722e3fbSopenharmony_ci memset(&args, 0, sizeof(args)); 75d722e3fbSopenharmony_ci args.in.op = AMDGPU_CTX_OP_ALLOC_CTX; 76d722e3fbSopenharmony_ci args.in.priority = priority; 77d722e3fbSopenharmony_ci 78d722e3fbSopenharmony_ci r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_CTX, &args, sizeof(args)); 79d722e3fbSopenharmony_ci if (r) 80d722e3fbSopenharmony_ci goto error; 81d722e3fbSopenharmony_ci 82d722e3fbSopenharmony_ci gpu_context->id = args.out.alloc.ctx_id; 83d722e3fbSopenharmony_ci for (i = 0; i < AMDGPU_HW_IP_NUM; i++) 84d722e3fbSopenharmony_ci for (j = 0; j < AMDGPU_HW_IP_INSTANCE_MAX_COUNT; j++) 85d722e3fbSopenharmony_ci for (k = 0; k < AMDGPU_CS_MAX_RINGS; k++) 86d722e3fbSopenharmony_ci list_inithead(&gpu_context->sem_list[i][j][k]); 87d722e3fbSopenharmony_ci *context = (amdgpu_context_handle)gpu_context; 88d722e3fbSopenharmony_ci 89d722e3fbSopenharmony_ci return 0; 90d722e3fbSopenharmony_ci 91d722e3fbSopenharmony_cierror: 92d722e3fbSopenharmony_ci pthread_mutex_destroy(&gpu_context->sequence_mutex); 93d722e3fbSopenharmony_ci free(gpu_context); 94d722e3fbSopenharmony_ci return r; 95d722e3fbSopenharmony_ci} 96d722e3fbSopenharmony_ci 97d722e3fbSopenharmony_cidrm_public int amdgpu_cs_ctx_create(amdgpu_device_handle dev, 98d722e3fbSopenharmony_ci amdgpu_context_handle *context) 99d722e3fbSopenharmony_ci{ 100d722e3fbSopenharmony_ci return amdgpu_cs_ctx_create2(dev, AMDGPU_CTX_PRIORITY_NORMAL, context); 101d722e3fbSopenharmony_ci} 102d722e3fbSopenharmony_ci 103d722e3fbSopenharmony_ci/** 104d722e3fbSopenharmony_ci * Release command submission context 105d722e3fbSopenharmony_ci * 106d722e3fbSopenharmony_ci * \param dev - \c [in] amdgpu device handle 107d722e3fbSopenharmony_ci * \param context - \c [in] amdgpu context handle 108d722e3fbSopenharmony_ci * 109d722e3fbSopenharmony_ci * \return 0 on success otherwise POSIX Error code 110d722e3fbSopenharmony_ci*/ 111d722e3fbSopenharmony_cidrm_public int amdgpu_cs_ctx_free(amdgpu_context_handle context) 112d722e3fbSopenharmony_ci{ 113d722e3fbSopenharmony_ci union drm_amdgpu_ctx args; 114d722e3fbSopenharmony_ci int i, j, k; 115d722e3fbSopenharmony_ci int r; 116d722e3fbSopenharmony_ci 117d722e3fbSopenharmony_ci if (!context) 118d722e3fbSopenharmony_ci return -EINVAL; 119d722e3fbSopenharmony_ci 120d722e3fbSopenharmony_ci pthread_mutex_destroy(&context->sequence_mutex); 121d722e3fbSopenharmony_ci 122d722e3fbSopenharmony_ci /* now deal with kernel side */ 123d722e3fbSopenharmony_ci memset(&args, 0, sizeof(args)); 124d722e3fbSopenharmony_ci args.in.op = AMDGPU_CTX_OP_FREE_CTX; 125d722e3fbSopenharmony_ci args.in.ctx_id = context->id; 126d722e3fbSopenharmony_ci r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CTX, 127d722e3fbSopenharmony_ci &args, sizeof(args)); 128d722e3fbSopenharmony_ci for (i = 0; i < AMDGPU_HW_IP_NUM; i++) { 129d722e3fbSopenharmony_ci for (j = 0; j < AMDGPU_HW_IP_INSTANCE_MAX_COUNT; j++) { 130d722e3fbSopenharmony_ci for (k = 0; k < AMDGPU_CS_MAX_RINGS; k++) { 131d722e3fbSopenharmony_ci amdgpu_semaphore_handle sem; 132d722e3fbSopenharmony_ci LIST_FOR_EACH_ENTRY(sem, &context->sem_list[i][j][k], list) { 133d722e3fbSopenharmony_ci list_del(&sem->list); 134d722e3fbSopenharmony_ci amdgpu_cs_reset_sem(sem); 135d722e3fbSopenharmony_ci amdgpu_cs_unreference_sem(sem); 136d722e3fbSopenharmony_ci } 137d722e3fbSopenharmony_ci } 138d722e3fbSopenharmony_ci } 139d722e3fbSopenharmony_ci } 140d722e3fbSopenharmony_ci free(context); 141d722e3fbSopenharmony_ci 142d722e3fbSopenharmony_ci return r; 143d722e3fbSopenharmony_ci} 144d722e3fbSopenharmony_ci 145d722e3fbSopenharmony_cidrm_public int amdgpu_cs_ctx_override_priority(amdgpu_device_handle dev, 146d722e3fbSopenharmony_ci amdgpu_context_handle context, 147d722e3fbSopenharmony_ci int master_fd, 148d722e3fbSopenharmony_ci unsigned priority) 149d722e3fbSopenharmony_ci{ 150d722e3fbSopenharmony_ci union drm_amdgpu_sched args; 151d722e3fbSopenharmony_ci int r; 152d722e3fbSopenharmony_ci 153d722e3fbSopenharmony_ci if (!dev || !context || master_fd < 0) 154d722e3fbSopenharmony_ci return -EINVAL; 155d722e3fbSopenharmony_ci 156d722e3fbSopenharmony_ci memset(&args, 0, sizeof(args)); 157d722e3fbSopenharmony_ci 158d722e3fbSopenharmony_ci args.in.op = AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE; 159d722e3fbSopenharmony_ci args.in.fd = dev->fd; 160d722e3fbSopenharmony_ci args.in.priority = priority; 161d722e3fbSopenharmony_ci args.in.ctx_id = context->id; 162d722e3fbSopenharmony_ci 163d722e3fbSopenharmony_ci r = drmCommandWrite(master_fd, DRM_AMDGPU_SCHED, &args, sizeof(args)); 164d722e3fbSopenharmony_ci if (r) 165d722e3fbSopenharmony_ci return r; 166d722e3fbSopenharmony_ci 167d722e3fbSopenharmony_ci return 0; 168d722e3fbSopenharmony_ci} 169d722e3fbSopenharmony_ci 170d722e3fbSopenharmony_cidrm_public int amdgpu_cs_ctx_stable_pstate(amdgpu_context_handle context, 171d722e3fbSopenharmony_ci uint32_t op, 172d722e3fbSopenharmony_ci uint32_t flags, 173d722e3fbSopenharmony_ci uint32_t *out_flags) 174d722e3fbSopenharmony_ci{ 175d722e3fbSopenharmony_ci union drm_amdgpu_ctx args; 176d722e3fbSopenharmony_ci int r; 177d722e3fbSopenharmony_ci 178d722e3fbSopenharmony_ci if (!context) 179d722e3fbSopenharmony_ci return -EINVAL; 180d722e3fbSopenharmony_ci 181d722e3fbSopenharmony_ci memset(&args, 0, sizeof(args)); 182d722e3fbSopenharmony_ci args.in.op = op; 183d722e3fbSopenharmony_ci args.in.ctx_id = context->id; 184d722e3fbSopenharmony_ci args.in.flags = flags; 185d722e3fbSopenharmony_ci r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CTX, 186d722e3fbSopenharmony_ci &args, sizeof(args)); 187d722e3fbSopenharmony_ci if (!r && out_flags) 188d722e3fbSopenharmony_ci *out_flags = args.out.pstate.flags; 189d722e3fbSopenharmony_ci return r; 190d722e3fbSopenharmony_ci} 191d722e3fbSopenharmony_ci 192d722e3fbSopenharmony_cidrm_public int amdgpu_cs_query_reset_state(amdgpu_context_handle context, 193d722e3fbSopenharmony_ci uint32_t *state, uint32_t *hangs) 194d722e3fbSopenharmony_ci{ 195d722e3fbSopenharmony_ci union drm_amdgpu_ctx args; 196d722e3fbSopenharmony_ci int r; 197d722e3fbSopenharmony_ci 198d722e3fbSopenharmony_ci if (!context) 199d722e3fbSopenharmony_ci return -EINVAL; 200d722e3fbSopenharmony_ci 201d722e3fbSopenharmony_ci memset(&args, 0, sizeof(args)); 202d722e3fbSopenharmony_ci args.in.op = AMDGPU_CTX_OP_QUERY_STATE; 203d722e3fbSopenharmony_ci args.in.ctx_id = context->id; 204d722e3fbSopenharmony_ci r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CTX, 205d722e3fbSopenharmony_ci &args, sizeof(args)); 206d722e3fbSopenharmony_ci if (!r) { 207d722e3fbSopenharmony_ci *state = args.out.state.reset_status; 208d722e3fbSopenharmony_ci *hangs = args.out.state.hangs; 209d722e3fbSopenharmony_ci } 210d722e3fbSopenharmony_ci return r; 211d722e3fbSopenharmony_ci} 212d722e3fbSopenharmony_ci 213d722e3fbSopenharmony_cidrm_public int amdgpu_cs_query_reset_state2(amdgpu_context_handle context, 214d722e3fbSopenharmony_ci uint64_t *flags) 215d722e3fbSopenharmony_ci{ 216d722e3fbSopenharmony_ci union drm_amdgpu_ctx args; 217d722e3fbSopenharmony_ci int r; 218d722e3fbSopenharmony_ci 219d722e3fbSopenharmony_ci if (!context) 220d722e3fbSopenharmony_ci return -EINVAL; 221d722e3fbSopenharmony_ci 222d722e3fbSopenharmony_ci memset(&args, 0, sizeof(args)); 223d722e3fbSopenharmony_ci args.in.op = AMDGPU_CTX_OP_QUERY_STATE2; 224d722e3fbSopenharmony_ci args.in.ctx_id = context->id; 225d722e3fbSopenharmony_ci r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_CTX, 226d722e3fbSopenharmony_ci &args, sizeof(args)); 227d722e3fbSopenharmony_ci if (!r) 228d722e3fbSopenharmony_ci *flags = args.out.state.flags; 229d722e3fbSopenharmony_ci return r; 230d722e3fbSopenharmony_ci} 231d722e3fbSopenharmony_ci 232d722e3fbSopenharmony_ci/** 233d722e3fbSopenharmony_ci * Submit command to kernel DRM 234d722e3fbSopenharmony_ci * \param dev - \c [in] Device handle 235d722e3fbSopenharmony_ci * \param context - \c [in] GPU Context 236d722e3fbSopenharmony_ci * \param ibs_request - \c [in] Pointer to submission requests 237d722e3fbSopenharmony_ci * \param fence - \c [out] return fence for this submission 238d722e3fbSopenharmony_ci * 239d722e3fbSopenharmony_ci * \return 0 on success otherwise POSIX Error code 240d722e3fbSopenharmony_ci * \sa amdgpu_cs_submit() 241d722e3fbSopenharmony_ci*/ 242d722e3fbSopenharmony_cistatic int amdgpu_cs_submit_one(amdgpu_context_handle context, 243d722e3fbSopenharmony_ci struct amdgpu_cs_request *ibs_request) 244d722e3fbSopenharmony_ci{ 245d722e3fbSopenharmony_ci struct drm_amdgpu_cs_chunk *chunks; 246d722e3fbSopenharmony_ci struct drm_amdgpu_cs_chunk_data *chunk_data; 247d722e3fbSopenharmony_ci struct drm_amdgpu_cs_chunk_dep *dependencies = NULL; 248d722e3fbSopenharmony_ci struct drm_amdgpu_cs_chunk_dep *sem_dependencies = NULL; 249d722e3fbSopenharmony_ci amdgpu_device_handle dev = context->dev; 250d722e3fbSopenharmony_ci struct list_head *sem_list; 251d722e3fbSopenharmony_ci amdgpu_semaphore_handle sem, tmp; 252d722e3fbSopenharmony_ci uint32_t i, size, num_chunks, bo_list_handle = 0, sem_count = 0; 253d722e3fbSopenharmony_ci uint64_t seq_no; 254d722e3fbSopenharmony_ci bool user_fence; 255d722e3fbSopenharmony_ci int r = 0; 256d722e3fbSopenharmony_ci 257d722e3fbSopenharmony_ci if (ibs_request->ip_type >= AMDGPU_HW_IP_NUM) 258d722e3fbSopenharmony_ci return -EINVAL; 259d722e3fbSopenharmony_ci if (ibs_request->ring >= AMDGPU_CS_MAX_RINGS) 260d722e3fbSopenharmony_ci return -EINVAL; 261d722e3fbSopenharmony_ci if (ibs_request->number_of_ibs == 0) { 262d722e3fbSopenharmony_ci ibs_request->seq_no = AMDGPU_NULL_SUBMIT_SEQ; 263d722e3fbSopenharmony_ci return 0; 264d722e3fbSopenharmony_ci } 265d722e3fbSopenharmony_ci user_fence = (ibs_request->fence_info.handle != NULL); 266d722e3fbSopenharmony_ci 267d722e3fbSopenharmony_ci size = ibs_request->number_of_ibs + (user_fence ? 2 : 1) + 1; 268d722e3fbSopenharmony_ci 269d722e3fbSopenharmony_ci chunks = alloca(sizeof(struct drm_amdgpu_cs_chunk) * size); 270d722e3fbSopenharmony_ci 271d722e3fbSopenharmony_ci size = ibs_request->number_of_ibs + (user_fence ? 1 : 0); 272d722e3fbSopenharmony_ci 273d722e3fbSopenharmony_ci chunk_data = alloca(sizeof(struct drm_amdgpu_cs_chunk_data) * size); 274d722e3fbSopenharmony_ci 275d722e3fbSopenharmony_ci if (ibs_request->resources) 276d722e3fbSopenharmony_ci bo_list_handle = ibs_request->resources->handle; 277d722e3fbSopenharmony_ci num_chunks = ibs_request->number_of_ibs; 278d722e3fbSopenharmony_ci /* IB chunks */ 279d722e3fbSopenharmony_ci for (i = 0; i < ibs_request->number_of_ibs; i++) { 280d722e3fbSopenharmony_ci struct amdgpu_cs_ib_info *ib; 281d722e3fbSopenharmony_ci chunks[i].chunk_id = AMDGPU_CHUNK_ID_IB; 282d722e3fbSopenharmony_ci chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_ib) / 4; 283d722e3fbSopenharmony_ci chunks[i].chunk_data = (uint64_t)(uintptr_t)&chunk_data[i]; 284d722e3fbSopenharmony_ci 285d722e3fbSopenharmony_ci ib = &ibs_request->ibs[i]; 286d722e3fbSopenharmony_ci 287d722e3fbSopenharmony_ci chunk_data[i].ib_data._pad = 0; 288d722e3fbSopenharmony_ci chunk_data[i].ib_data.va_start = ib->ib_mc_address; 289d722e3fbSopenharmony_ci chunk_data[i].ib_data.ib_bytes = ib->size * 4; 290d722e3fbSopenharmony_ci chunk_data[i].ib_data.ip_type = ibs_request->ip_type; 291d722e3fbSopenharmony_ci chunk_data[i].ib_data.ip_instance = ibs_request->ip_instance; 292d722e3fbSopenharmony_ci chunk_data[i].ib_data.ring = ibs_request->ring; 293d722e3fbSopenharmony_ci chunk_data[i].ib_data.flags = ib->flags; 294d722e3fbSopenharmony_ci } 295d722e3fbSopenharmony_ci 296d722e3fbSopenharmony_ci pthread_mutex_lock(&context->sequence_mutex); 297d722e3fbSopenharmony_ci 298d722e3fbSopenharmony_ci if (user_fence) { 299d722e3fbSopenharmony_ci i = num_chunks++; 300d722e3fbSopenharmony_ci 301d722e3fbSopenharmony_ci /* fence chunk */ 302d722e3fbSopenharmony_ci chunks[i].chunk_id = AMDGPU_CHUNK_ID_FENCE; 303d722e3fbSopenharmony_ci chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_fence) / 4; 304d722e3fbSopenharmony_ci chunks[i].chunk_data = (uint64_t)(uintptr_t)&chunk_data[i]; 305d722e3fbSopenharmony_ci 306d722e3fbSopenharmony_ci /* fence bo handle */ 307d722e3fbSopenharmony_ci chunk_data[i].fence_data.handle = ibs_request->fence_info.handle->handle; 308d722e3fbSopenharmony_ci /* offset */ 309d722e3fbSopenharmony_ci chunk_data[i].fence_data.offset = 310d722e3fbSopenharmony_ci ibs_request->fence_info.offset * sizeof(uint64_t); 311d722e3fbSopenharmony_ci } 312d722e3fbSopenharmony_ci 313d722e3fbSopenharmony_ci if (ibs_request->number_of_dependencies) { 314d722e3fbSopenharmony_ci dependencies = alloca(sizeof(struct drm_amdgpu_cs_chunk_dep) * 315d722e3fbSopenharmony_ci ibs_request->number_of_dependencies); 316d722e3fbSopenharmony_ci if (!dependencies) { 317d722e3fbSopenharmony_ci r = -ENOMEM; 318d722e3fbSopenharmony_ci goto error_unlock; 319d722e3fbSopenharmony_ci } 320d722e3fbSopenharmony_ci 321d722e3fbSopenharmony_ci for (i = 0; i < ibs_request->number_of_dependencies; ++i) { 322d722e3fbSopenharmony_ci struct amdgpu_cs_fence *info = &ibs_request->dependencies[i]; 323d722e3fbSopenharmony_ci struct drm_amdgpu_cs_chunk_dep *dep = &dependencies[i]; 324d722e3fbSopenharmony_ci dep->ip_type = info->ip_type; 325d722e3fbSopenharmony_ci dep->ip_instance = info->ip_instance; 326d722e3fbSopenharmony_ci dep->ring = info->ring; 327d722e3fbSopenharmony_ci dep->ctx_id = info->context->id; 328d722e3fbSopenharmony_ci dep->handle = info->fence; 329d722e3fbSopenharmony_ci } 330d722e3fbSopenharmony_ci 331d722e3fbSopenharmony_ci i = num_chunks++; 332d722e3fbSopenharmony_ci 333d722e3fbSopenharmony_ci /* dependencies chunk */ 334d722e3fbSopenharmony_ci chunks[i].chunk_id = AMDGPU_CHUNK_ID_DEPENDENCIES; 335d722e3fbSopenharmony_ci chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_dep) / 4 336d722e3fbSopenharmony_ci * ibs_request->number_of_dependencies; 337d722e3fbSopenharmony_ci chunks[i].chunk_data = (uint64_t)(uintptr_t)dependencies; 338d722e3fbSopenharmony_ci } 339d722e3fbSopenharmony_ci 340d722e3fbSopenharmony_ci sem_list = &context->sem_list[ibs_request->ip_type][ibs_request->ip_instance][ibs_request->ring]; 341d722e3fbSopenharmony_ci LIST_FOR_EACH_ENTRY(sem, sem_list, list) 342d722e3fbSopenharmony_ci sem_count++; 343d722e3fbSopenharmony_ci if (sem_count) { 344d722e3fbSopenharmony_ci sem_dependencies = alloca(sizeof(struct drm_amdgpu_cs_chunk_dep) * sem_count); 345d722e3fbSopenharmony_ci if (!sem_dependencies) { 346d722e3fbSopenharmony_ci r = -ENOMEM; 347d722e3fbSopenharmony_ci goto error_unlock; 348d722e3fbSopenharmony_ci } 349d722e3fbSopenharmony_ci sem_count = 0; 350d722e3fbSopenharmony_ci LIST_FOR_EACH_ENTRY_SAFE(sem, tmp, sem_list, list) { 351d722e3fbSopenharmony_ci struct amdgpu_cs_fence *info = &sem->signal_fence; 352d722e3fbSopenharmony_ci struct drm_amdgpu_cs_chunk_dep *dep = &sem_dependencies[sem_count++]; 353d722e3fbSopenharmony_ci dep->ip_type = info->ip_type; 354d722e3fbSopenharmony_ci dep->ip_instance = info->ip_instance; 355d722e3fbSopenharmony_ci dep->ring = info->ring; 356d722e3fbSopenharmony_ci dep->ctx_id = info->context->id; 357d722e3fbSopenharmony_ci dep->handle = info->fence; 358d722e3fbSopenharmony_ci 359d722e3fbSopenharmony_ci list_del(&sem->list); 360d722e3fbSopenharmony_ci amdgpu_cs_reset_sem(sem); 361d722e3fbSopenharmony_ci amdgpu_cs_unreference_sem(sem); 362d722e3fbSopenharmony_ci } 363d722e3fbSopenharmony_ci i = num_chunks++; 364d722e3fbSopenharmony_ci 365d722e3fbSopenharmony_ci /* dependencies chunk */ 366d722e3fbSopenharmony_ci chunks[i].chunk_id = AMDGPU_CHUNK_ID_DEPENDENCIES; 367d722e3fbSopenharmony_ci chunks[i].length_dw = sizeof(struct drm_amdgpu_cs_chunk_dep) / 4 * sem_count; 368d722e3fbSopenharmony_ci chunks[i].chunk_data = (uint64_t)(uintptr_t)sem_dependencies; 369d722e3fbSopenharmony_ci } 370d722e3fbSopenharmony_ci 371d722e3fbSopenharmony_ci r = amdgpu_cs_submit_raw2(dev, context, bo_list_handle, num_chunks, 372d722e3fbSopenharmony_ci chunks, &seq_no); 373d722e3fbSopenharmony_ci if (r) 374d722e3fbSopenharmony_ci goto error_unlock; 375d722e3fbSopenharmony_ci 376d722e3fbSopenharmony_ci ibs_request->seq_no = seq_no; 377d722e3fbSopenharmony_ci context->last_seq[ibs_request->ip_type][ibs_request->ip_instance][ibs_request->ring] = ibs_request->seq_no; 378d722e3fbSopenharmony_cierror_unlock: 379d722e3fbSopenharmony_ci pthread_mutex_unlock(&context->sequence_mutex); 380d722e3fbSopenharmony_ci return r; 381d722e3fbSopenharmony_ci} 382d722e3fbSopenharmony_ci 383d722e3fbSopenharmony_cidrm_public int amdgpu_cs_submit(amdgpu_context_handle context, 384d722e3fbSopenharmony_ci uint64_t flags, 385d722e3fbSopenharmony_ci struct amdgpu_cs_request *ibs_request, 386d722e3fbSopenharmony_ci uint32_t number_of_requests) 387d722e3fbSopenharmony_ci{ 388d722e3fbSopenharmony_ci uint32_t i; 389d722e3fbSopenharmony_ci int r; 390d722e3fbSopenharmony_ci 391d722e3fbSopenharmony_ci if (!context || !ibs_request) 392d722e3fbSopenharmony_ci return -EINVAL; 393d722e3fbSopenharmony_ci 394d722e3fbSopenharmony_ci r = 0; 395d722e3fbSopenharmony_ci for (i = 0; i < number_of_requests; i++) { 396d722e3fbSopenharmony_ci r = amdgpu_cs_submit_one(context, ibs_request); 397d722e3fbSopenharmony_ci if (r) 398d722e3fbSopenharmony_ci break; 399d722e3fbSopenharmony_ci ibs_request++; 400d722e3fbSopenharmony_ci } 401d722e3fbSopenharmony_ci 402d722e3fbSopenharmony_ci return r; 403d722e3fbSopenharmony_ci} 404d722e3fbSopenharmony_ci 405d722e3fbSopenharmony_ci/** 406d722e3fbSopenharmony_ci * Calculate absolute timeout. 407d722e3fbSopenharmony_ci * 408d722e3fbSopenharmony_ci * \param timeout - \c [in] timeout in nanoseconds. 409d722e3fbSopenharmony_ci * 410d722e3fbSopenharmony_ci * \return absolute timeout in nanoseconds 411d722e3fbSopenharmony_ci*/ 412d722e3fbSopenharmony_cidrm_private uint64_t amdgpu_cs_calculate_timeout(uint64_t timeout) 413d722e3fbSopenharmony_ci{ 414d722e3fbSopenharmony_ci int r; 415d722e3fbSopenharmony_ci 416d722e3fbSopenharmony_ci if (timeout != AMDGPU_TIMEOUT_INFINITE) { 417d722e3fbSopenharmony_ci struct timespec current; 418d722e3fbSopenharmony_ci uint64_t current_ns; 419d722e3fbSopenharmony_ci r = clock_gettime(CLOCK_MONOTONIC, ¤t); 420d722e3fbSopenharmony_ci if (r) { 421d722e3fbSopenharmony_ci fprintf(stderr, "clock_gettime() returned error (%d)!", errno); 422d722e3fbSopenharmony_ci return AMDGPU_TIMEOUT_INFINITE; 423d722e3fbSopenharmony_ci } 424d722e3fbSopenharmony_ci 425d722e3fbSopenharmony_ci current_ns = ((uint64_t)current.tv_sec) * 1000000000ull; 426d722e3fbSopenharmony_ci current_ns += current.tv_nsec; 427d722e3fbSopenharmony_ci timeout += current_ns; 428d722e3fbSopenharmony_ci if (timeout < current_ns) 429d722e3fbSopenharmony_ci timeout = AMDGPU_TIMEOUT_INFINITE; 430d722e3fbSopenharmony_ci } 431d722e3fbSopenharmony_ci return timeout; 432d722e3fbSopenharmony_ci} 433d722e3fbSopenharmony_ci 434d722e3fbSopenharmony_cistatic int amdgpu_ioctl_wait_cs(amdgpu_context_handle context, 435d722e3fbSopenharmony_ci unsigned ip, 436d722e3fbSopenharmony_ci unsigned ip_instance, 437d722e3fbSopenharmony_ci uint32_t ring, 438d722e3fbSopenharmony_ci uint64_t handle, 439d722e3fbSopenharmony_ci uint64_t timeout_ns, 440d722e3fbSopenharmony_ci uint64_t flags, 441d722e3fbSopenharmony_ci bool *busy) 442d722e3fbSopenharmony_ci{ 443d722e3fbSopenharmony_ci amdgpu_device_handle dev = context->dev; 444d722e3fbSopenharmony_ci union drm_amdgpu_wait_cs args; 445d722e3fbSopenharmony_ci int r; 446d722e3fbSopenharmony_ci 447d722e3fbSopenharmony_ci memset(&args, 0, sizeof(args)); 448d722e3fbSopenharmony_ci args.in.handle = handle; 449d722e3fbSopenharmony_ci args.in.ip_type = ip; 450d722e3fbSopenharmony_ci args.in.ip_instance = ip_instance; 451d722e3fbSopenharmony_ci args.in.ring = ring; 452d722e3fbSopenharmony_ci args.in.ctx_id = context->id; 453d722e3fbSopenharmony_ci 454d722e3fbSopenharmony_ci if (flags & AMDGPU_QUERY_FENCE_TIMEOUT_IS_ABSOLUTE) 455d722e3fbSopenharmony_ci args.in.timeout = timeout_ns; 456d722e3fbSopenharmony_ci else 457d722e3fbSopenharmony_ci args.in.timeout = amdgpu_cs_calculate_timeout(timeout_ns); 458d722e3fbSopenharmony_ci 459d722e3fbSopenharmony_ci r = drmIoctl(dev->fd, DRM_IOCTL_AMDGPU_WAIT_CS, &args); 460d722e3fbSopenharmony_ci if (r) 461d722e3fbSopenharmony_ci return -errno; 462d722e3fbSopenharmony_ci 463d722e3fbSopenharmony_ci *busy = args.out.status; 464d722e3fbSopenharmony_ci return 0; 465d722e3fbSopenharmony_ci} 466d722e3fbSopenharmony_ci 467d722e3fbSopenharmony_cidrm_public int amdgpu_cs_query_fence_status(struct amdgpu_cs_fence *fence, 468d722e3fbSopenharmony_ci uint64_t timeout_ns, 469d722e3fbSopenharmony_ci uint64_t flags, 470d722e3fbSopenharmony_ci uint32_t *expired) 471d722e3fbSopenharmony_ci{ 472d722e3fbSopenharmony_ci bool busy = true; 473d722e3fbSopenharmony_ci int r; 474d722e3fbSopenharmony_ci 475d722e3fbSopenharmony_ci if (!fence || !expired || !fence->context) 476d722e3fbSopenharmony_ci return -EINVAL; 477d722e3fbSopenharmony_ci if (fence->ip_type >= AMDGPU_HW_IP_NUM) 478d722e3fbSopenharmony_ci return -EINVAL; 479d722e3fbSopenharmony_ci if (fence->ring >= AMDGPU_CS_MAX_RINGS) 480d722e3fbSopenharmony_ci return -EINVAL; 481d722e3fbSopenharmony_ci if (fence->fence == AMDGPU_NULL_SUBMIT_SEQ) { 482d722e3fbSopenharmony_ci *expired = true; 483d722e3fbSopenharmony_ci return 0; 484d722e3fbSopenharmony_ci } 485d722e3fbSopenharmony_ci 486d722e3fbSopenharmony_ci *expired = false; 487d722e3fbSopenharmony_ci 488d722e3fbSopenharmony_ci r = amdgpu_ioctl_wait_cs(fence->context, fence->ip_type, 489d722e3fbSopenharmony_ci fence->ip_instance, fence->ring, 490d722e3fbSopenharmony_ci fence->fence, timeout_ns, flags, &busy); 491d722e3fbSopenharmony_ci 492d722e3fbSopenharmony_ci if (!r && !busy) 493d722e3fbSopenharmony_ci *expired = true; 494d722e3fbSopenharmony_ci 495d722e3fbSopenharmony_ci return r; 496d722e3fbSopenharmony_ci} 497d722e3fbSopenharmony_ci 498d722e3fbSopenharmony_cistatic int amdgpu_ioctl_wait_fences(struct amdgpu_cs_fence *fences, 499d722e3fbSopenharmony_ci uint32_t fence_count, 500d722e3fbSopenharmony_ci bool wait_all, 501d722e3fbSopenharmony_ci uint64_t timeout_ns, 502d722e3fbSopenharmony_ci uint32_t *status, 503d722e3fbSopenharmony_ci uint32_t *first) 504d722e3fbSopenharmony_ci{ 505d722e3fbSopenharmony_ci struct drm_amdgpu_fence *drm_fences; 506d722e3fbSopenharmony_ci amdgpu_device_handle dev = fences[0].context->dev; 507d722e3fbSopenharmony_ci union drm_amdgpu_wait_fences args; 508d722e3fbSopenharmony_ci int r; 509d722e3fbSopenharmony_ci uint32_t i; 510d722e3fbSopenharmony_ci 511d722e3fbSopenharmony_ci drm_fences = alloca(sizeof(struct drm_amdgpu_fence) * fence_count); 512d722e3fbSopenharmony_ci for (i = 0; i < fence_count; i++) { 513d722e3fbSopenharmony_ci drm_fences[i].ctx_id = fences[i].context->id; 514d722e3fbSopenharmony_ci drm_fences[i].ip_type = fences[i].ip_type; 515d722e3fbSopenharmony_ci drm_fences[i].ip_instance = fences[i].ip_instance; 516d722e3fbSopenharmony_ci drm_fences[i].ring = fences[i].ring; 517d722e3fbSopenharmony_ci drm_fences[i].seq_no = fences[i].fence; 518d722e3fbSopenharmony_ci } 519d722e3fbSopenharmony_ci 520d722e3fbSopenharmony_ci memset(&args, 0, sizeof(args)); 521d722e3fbSopenharmony_ci args.in.fences = (uint64_t)(uintptr_t)drm_fences; 522d722e3fbSopenharmony_ci args.in.fence_count = fence_count; 523d722e3fbSopenharmony_ci args.in.wait_all = wait_all; 524d722e3fbSopenharmony_ci args.in.timeout_ns = amdgpu_cs_calculate_timeout(timeout_ns); 525d722e3fbSopenharmony_ci 526d722e3fbSopenharmony_ci r = drmIoctl(dev->fd, DRM_IOCTL_AMDGPU_WAIT_FENCES, &args); 527d722e3fbSopenharmony_ci if (r) 528d722e3fbSopenharmony_ci return -errno; 529d722e3fbSopenharmony_ci 530d722e3fbSopenharmony_ci *status = args.out.status; 531d722e3fbSopenharmony_ci 532d722e3fbSopenharmony_ci if (first) 533d722e3fbSopenharmony_ci *first = args.out.first_signaled; 534d722e3fbSopenharmony_ci 535d722e3fbSopenharmony_ci return 0; 536d722e3fbSopenharmony_ci} 537d722e3fbSopenharmony_ci 538d722e3fbSopenharmony_cidrm_public int amdgpu_cs_wait_fences(struct amdgpu_cs_fence *fences, 539d722e3fbSopenharmony_ci uint32_t fence_count, 540d722e3fbSopenharmony_ci bool wait_all, 541d722e3fbSopenharmony_ci uint64_t timeout_ns, 542d722e3fbSopenharmony_ci uint32_t *status, 543d722e3fbSopenharmony_ci uint32_t *first) 544d722e3fbSopenharmony_ci{ 545d722e3fbSopenharmony_ci uint32_t i; 546d722e3fbSopenharmony_ci 547d722e3fbSopenharmony_ci /* Sanity check */ 548d722e3fbSopenharmony_ci if (!fences || !status || !fence_count) 549d722e3fbSopenharmony_ci return -EINVAL; 550d722e3fbSopenharmony_ci 551d722e3fbSopenharmony_ci for (i = 0; i < fence_count; i++) { 552d722e3fbSopenharmony_ci if (NULL == fences[i].context) 553d722e3fbSopenharmony_ci return -EINVAL; 554d722e3fbSopenharmony_ci if (fences[i].ip_type >= AMDGPU_HW_IP_NUM) 555d722e3fbSopenharmony_ci return -EINVAL; 556d722e3fbSopenharmony_ci if (fences[i].ring >= AMDGPU_CS_MAX_RINGS) 557d722e3fbSopenharmony_ci return -EINVAL; 558d722e3fbSopenharmony_ci } 559d722e3fbSopenharmony_ci 560d722e3fbSopenharmony_ci *status = 0; 561d722e3fbSopenharmony_ci 562d722e3fbSopenharmony_ci return amdgpu_ioctl_wait_fences(fences, fence_count, wait_all, 563d722e3fbSopenharmony_ci timeout_ns, status, first); 564d722e3fbSopenharmony_ci} 565d722e3fbSopenharmony_ci 566d722e3fbSopenharmony_cidrm_public int amdgpu_cs_create_semaphore(amdgpu_semaphore_handle *sem) 567d722e3fbSopenharmony_ci{ 568d722e3fbSopenharmony_ci struct amdgpu_semaphore *gpu_semaphore; 569d722e3fbSopenharmony_ci 570d722e3fbSopenharmony_ci if (!sem) 571d722e3fbSopenharmony_ci return -EINVAL; 572d722e3fbSopenharmony_ci 573d722e3fbSopenharmony_ci gpu_semaphore = calloc(1, sizeof(struct amdgpu_semaphore)); 574d722e3fbSopenharmony_ci if (!gpu_semaphore) 575d722e3fbSopenharmony_ci return -ENOMEM; 576d722e3fbSopenharmony_ci 577d722e3fbSopenharmony_ci atomic_set(&gpu_semaphore->refcount, 1); 578d722e3fbSopenharmony_ci *sem = gpu_semaphore; 579d722e3fbSopenharmony_ci 580d722e3fbSopenharmony_ci return 0; 581d722e3fbSopenharmony_ci} 582d722e3fbSopenharmony_ci 583d722e3fbSopenharmony_cidrm_public int amdgpu_cs_signal_semaphore(amdgpu_context_handle ctx, 584d722e3fbSopenharmony_ci uint32_t ip_type, 585d722e3fbSopenharmony_ci uint32_t ip_instance, 586d722e3fbSopenharmony_ci uint32_t ring, 587d722e3fbSopenharmony_ci amdgpu_semaphore_handle sem) 588d722e3fbSopenharmony_ci{ 589d722e3fbSopenharmony_ci if (!ctx || !sem) 590d722e3fbSopenharmony_ci return -EINVAL; 591d722e3fbSopenharmony_ci if (ip_type >= AMDGPU_HW_IP_NUM) 592d722e3fbSopenharmony_ci return -EINVAL; 593d722e3fbSopenharmony_ci if (ring >= AMDGPU_CS_MAX_RINGS) 594d722e3fbSopenharmony_ci return -EINVAL; 595d722e3fbSopenharmony_ci /* sem has been signaled */ 596d722e3fbSopenharmony_ci if (sem->signal_fence.context) 597d722e3fbSopenharmony_ci return -EINVAL; 598d722e3fbSopenharmony_ci pthread_mutex_lock(&ctx->sequence_mutex); 599d722e3fbSopenharmony_ci sem->signal_fence.context = ctx; 600d722e3fbSopenharmony_ci sem->signal_fence.ip_type = ip_type; 601d722e3fbSopenharmony_ci sem->signal_fence.ip_instance = ip_instance; 602d722e3fbSopenharmony_ci sem->signal_fence.ring = ring; 603d722e3fbSopenharmony_ci sem->signal_fence.fence = ctx->last_seq[ip_type][ip_instance][ring]; 604d722e3fbSopenharmony_ci update_references(NULL, &sem->refcount); 605d722e3fbSopenharmony_ci pthread_mutex_unlock(&ctx->sequence_mutex); 606d722e3fbSopenharmony_ci return 0; 607d722e3fbSopenharmony_ci} 608d722e3fbSopenharmony_ci 609d722e3fbSopenharmony_cidrm_public int amdgpu_cs_wait_semaphore(amdgpu_context_handle ctx, 610d722e3fbSopenharmony_ci uint32_t ip_type, 611d722e3fbSopenharmony_ci uint32_t ip_instance, 612d722e3fbSopenharmony_ci uint32_t ring, 613d722e3fbSopenharmony_ci amdgpu_semaphore_handle sem) 614d722e3fbSopenharmony_ci{ 615d722e3fbSopenharmony_ci if (!ctx || !sem) 616d722e3fbSopenharmony_ci return -EINVAL; 617d722e3fbSopenharmony_ci if (ip_type >= AMDGPU_HW_IP_NUM) 618d722e3fbSopenharmony_ci return -EINVAL; 619d722e3fbSopenharmony_ci if (ring >= AMDGPU_CS_MAX_RINGS) 620d722e3fbSopenharmony_ci return -EINVAL; 621d722e3fbSopenharmony_ci /* must signal first */ 622d722e3fbSopenharmony_ci if (!sem->signal_fence.context) 623d722e3fbSopenharmony_ci return -EINVAL; 624d722e3fbSopenharmony_ci 625d722e3fbSopenharmony_ci pthread_mutex_lock(&ctx->sequence_mutex); 626d722e3fbSopenharmony_ci list_add(&sem->list, &ctx->sem_list[ip_type][ip_instance][ring]); 627d722e3fbSopenharmony_ci pthread_mutex_unlock(&ctx->sequence_mutex); 628d722e3fbSopenharmony_ci return 0; 629d722e3fbSopenharmony_ci} 630d722e3fbSopenharmony_ci 631d722e3fbSopenharmony_cistatic int amdgpu_cs_reset_sem(amdgpu_semaphore_handle sem) 632d722e3fbSopenharmony_ci{ 633d722e3fbSopenharmony_ci if (!sem || !sem->signal_fence.context) 634d722e3fbSopenharmony_ci return -EINVAL; 635d722e3fbSopenharmony_ci 636d722e3fbSopenharmony_ci sem->signal_fence.context = NULL; 637d722e3fbSopenharmony_ci sem->signal_fence.ip_type = 0; 638d722e3fbSopenharmony_ci sem->signal_fence.ip_instance = 0; 639d722e3fbSopenharmony_ci sem->signal_fence.ring = 0; 640d722e3fbSopenharmony_ci sem->signal_fence.fence = 0; 641d722e3fbSopenharmony_ci 642d722e3fbSopenharmony_ci return 0; 643d722e3fbSopenharmony_ci} 644d722e3fbSopenharmony_ci 645d722e3fbSopenharmony_cistatic int amdgpu_cs_unreference_sem(amdgpu_semaphore_handle sem) 646d722e3fbSopenharmony_ci{ 647d722e3fbSopenharmony_ci if (!sem) 648d722e3fbSopenharmony_ci return -EINVAL; 649d722e3fbSopenharmony_ci 650d722e3fbSopenharmony_ci if (update_references(&sem->refcount, NULL)) 651d722e3fbSopenharmony_ci free(sem); 652d722e3fbSopenharmony_ci return 0; 653d722e3fbSopenharmony_ci} 654d722e3fbSopenharmony_ci 655d722e3fbSopenharmony_cidrm_public int amdgpu_cs_destroy_semaphore(amdgpu_semaphore_handle sem) 656d722e3fbSopenharmony_ci{ 657d722e3fbSopenharmony_ci return amdgpu_cs_unreference_sem(sem); 658d722e3fbSopenharmony_ci} 659d722e3fbSopenharmony_ci 660d722e3fbSopenharmony_cidrm_public int amdgpu_cs_create_syncobj2(amdgpu_device_handle dev, 661d722e3fbSopenharmony_ci uint32_t flags, 662d722e3fbSopenharmony_ci uint32_t *handle) 663d722e3fbSopenharmony_ci{ 664d722e3fbSopenharmony_ci if (NULL == dev) 665d722e3fbSopenharmony_ci return -EINVAL; 666d722e3fbSopenharmony_ci 667d722e3fbSopenharmony_ci return drmSyncobjCreate(dev->fd, flags, handle); 668d722e3fbSopenharmony_ci} 669d722e3fbSopenharmony_ci 670d722e3fbSopenharmony_cidrm_public int amdgpu_cs_create_syncobj(amdgpu_device_handle dev, 671d722e3fbSopenharmony_ci uint32_t *handle) 672d722e3fbSopenharmony_ci{ 673d722e3fbSopenharmony_ci if (NULL == dev) 674d722e3fbSopenharmony_ci return -EINVAL; 675d722e3fbSopenharmony_ci 676d722e3fbSopenharmony_ci return drmSyncobjCreate(dev->fd, 0, handle); 677d722e3fbSopenharmony_ci} 678d722e3fbSopenharmony_ci 679d722e3fbSopenharmony_cidrm_public int amdgpu_cs_destroy_syncobj(amdgpu_device_handle dev, 680d722e3fbSopenharmony_ci uint32_t handle) 681d722e3fbSopenharmony_ci{ 682d722e3fbSopenharmony_ci if (NULL == dev) 683d722e3fbSopenharmony_ci return -EINVAL; 684d722e3fbSopenharmony_ci 685d722e3fbSopenharmony_ci return drmSyncobjDestroy(dev->fd, handle); 686d722e3fbSopenharmony_ci} 687d722e3fbSopenharmony_ci 688d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev, 689d722e3fbSopenharmony_ci const uint32_t *syncobjs, 690d722e3fbSopenharmony_ci uint32_t syncobj_count) 691d722e3fbSopenharmony_ci{ 692d722e3fbSopenharmony_ci if (NULL == dev) 693d722e3fbSopenharmony_ci return -EINVAL; 694d722e3fbSopenharmony_ci 695d722e3fbSopenharmony_ci return drmSyncobjReset(dev->fd, syncobjs, syncobj_count); 696d722e3fbSopenharmony_ci} 697d722e3fbSopenharmony_ci 698d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev, 699d722e3fbSopenharmony_ci const uint32_t *syncobjs, 700d722e3fbSopenharmony_ci uint32_t syncobj_count) 701d722e3fbSopenharmony_ci{ 702d722e3fbSopenharmony_ci if (NULL == dev) 703d722e3fbSopenharmony_ci return -EINVAL; 704d722e3fbSopenharmony_ci 705d722e3fbSopenharmony_ci return drmSyncobjSignal(dev->fd, syncobjs, syncobj_count); 706d722e3fbSopenharmony_ci} 707d722e3fbSopenharmony_ci 708d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev, 709d722e3fbSopenharmony_ci const uint32_t *syncobjs, 710d722e3fbSopenharmony_ci uint64_t *points, 711d722e3fbSopenharmony_ci uint32_t syncobj_count) 712d722e3fbSopenharmony_ci{ 713d722e3fbSopenharmony_ci if (NULL == dev) 714d722e3fbSopenharmony_ci return -EINVAL; 715d722e3fbSopenharmony_ci 716d722e3fbSopenharmony_ci return drmSyncobjTimelineSignal(dev->fd, syncobjs, 717d722e3fbSopenharmony_ci points, syncobj_count); 718d722e3fbSopenharmony_ci} 719d722e3fbSopenharmony_ci 720d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev, 721d722e3fbSopenharmony_ci uint32_t *handles, unsigned num_handles, 722d722e3fbSopenharmony_ci int64_t timeout_nsec, unsigned flags, 723d722e3fbSopenharmony_ci uint32_t *first_signaled) 724d722e3fbSopenharmony_ci{ 725d722e3fbSopenharmony_ci if (NULL == dev) 726d722e3fbSopenharmony_ci return -EINVAL; 727d722e3fbSopenharmony_ci 728d722e3fbSopenharmony_ci return drmSyncobjWait(dev->fd, handles, num_handles, timeout_nsec, 729d722e3fbSopenharmony_ci flags, first_signaled); 730d722e3fbSopenharmony_ci} 731d722e3fbSopenharmony_ci 732d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev, 733d722e3fbSopenharmony_ci uint32_t *handles, uint64_t *points, 734d722e3fbSopenharmony_ci unsigned num_handles, 735d722e3fbSopenharmony_ci int64_t timeout_nsec, unsigned flags, 736d722e3fbSopenharmony_ci uint32_t *first_signaled) 737d722e3fbSopenharmony_ci{ 738d722e3fbSopenharmony_ci if (NULL == dev) 739d722e3fbSopenharmony_ci return -EINVAL; 740d722e3fbSopenharmony_ci 741d722e3fbSopenharmony_ci return drmSyncobjTimelineWait(dev->fd, handles, points, num_handles, 742d722e3fbSopenharmony_ci timeout_nsec, flags, first_signaled); 743d722e3fbSopenharmony_ci} 744d722e3fbSopenharmony_ci 745d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_query(amdgpu_device_handle dev, 746d722e3fbSopenharmony_ci uint32_t *handles, uint64_t *points, 747d722e3fbSopenharmony_ci unsigned num_handles) 748d722e3fbSopenharmony_ci{ 749d722e3fbSopenharmony_ci if (NULL == dev) 750d722e3fbSopenharmony_ci return -EINVAL; 751d722e3fbSopenharmony_ci 752d722e3fbSopenharmony_ci return drmSyncobjQuery(dev->fd, handles, points, num_handles); 753d722e3fbSopenharmony_ci} 754d722e3fbSopenharmony_ci 755d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_query2(amdgpu_device_handle dev, 756d722e3fbSopenharmony_ci uint32_t *handles, uint64_t *points, 757d722e3fbSopenharmony_ci unsigned num_handles, uint32_t flags) 758d722e3fbSopenharmony_ci{ 759d722e3fbSopenharmony_ci if (!dev) 760d722e3fbSopenharmony_ci return -EINVAL; 761d722e3fbSopenharmony_ci 762d722e3fbSopenharmony_ci return drmSyncobjQuery2(dev->fd, handles, points, num_handles, flags); 763d722e3fbSopenharmony_ci} 764d722e3fbSopenharmony_ci 765d722e3fbSopenharmony_cidrm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev, 766d722e3fbSopenharmony_ci uint32_t handle, 767d722e3fbSopenharmony_ci int *shared_fd) 768d722e3fbSopenharmony_ci{ 769d722e3fbSopenharmony_ci if (NULL == dev) 770d722e3fbSopenharmony_ci return -EINVAL; 771d722e3fbSopenharmony_ci 772d722e3fbSopenharmony_ci return drmSyncobjHandleToFD(dev->fd, handle, shared_fd); 773d722e3fbSopenharmony_ci} 774d722e3fbSopenharmony_ci 775d722e3fbSopenharmony_cidrm_public int amdgpu_cs_import_syncobj(amdgpu_device_handle dev, 776d722e3fbSopenharmony_ci int shared_fd, 777d722e3fbSopenharmony_ci uint32_t *handle) 778d722e3fbSopenharmony_ci{ 779d722e3fbSopenharmony_ci if (NULL == dev) 780d722e3fbSopenharmony_ci return -EINVAL; 781d722e3fbSopenharmony_ci 782d722e3fbSopenharmony_ci return drmSyncobjFDToHandle(dev->fd, shared_fd, handle); 783d722e3fbSopenharmony_ci} 784d722e3fbSopenharmony_ci 785d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev, 786d722e3fbSopenharmony_ci uint32_t syncobj, 787d722e3fbSopenharmony_ci int *sync_file_fd) 788d722e3fbSopenharmony_ci{ 789d722e3fbSopenharmony_ci if (NULL == dev) 790d722e3fbSopenharmony_ci return -EINVAL; 791d722e3fbSopenharmony_ci 792d722e3fbSopenharmony_ci return drmSyncobjExportSyncFile(dev->fd, syncobj, sync_file_fd); 793d722e3fbSopenharmony_ci} 794d722e3fbSopenharmony_ci 795d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev, 796d722e3fbSopenharmony_ci uint32_t syncobj, 797d722e3fbSopenharmony_ci int sync_file_fd) 798d722e3fbSopenharmony_ci{ 799d722e3fbSopenharmony_ci if (NULL == dev) 800d722e3fbSopenharmony_ci return -EINVAL; 801d722e3fbSopenharmony_ci 802d722e3fbSopenharmony_ci return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd); 803d722e3fbSopenharmony_ci} 804d722e3fbSopenharmony_ci 805d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev, 806d722e3fbSopenharmony_ci uint32_t syncobj, 807d722e3fbSopenharmony_ci uint64_t point, 808d722e3fbSopenharmony_ci uint32_t flags, 809d722e3fbSopenharmony_ci int *sync_file_fd) 810d722e3fbSopenharmony_ci{ 811d722e3fbSopenharmony_ci uint32_t binary_handle; 812d722e3fbSopenharmony_ci int ret; 813d722e3fbSopenharmony_ci 814d722e3fbSopenharmony_ci if (NULL == dev) 815d722e3fbSopenharmony_ci return -EINVAL; 816d722e3fbSopenharmony_ci 817d722e3fbSopenharmony_ci if (!point) 818d722e3fbSopenharmony_ci return drmSyncobjExportSyncFile(dev->fd, syncobj, sync_file_fd); 819d722e3fbSopenharmony_ci 820d722e3fbSopenharmony_ci ret = drmSyncobjCreate(dev->fd, 0, &binary_handle); 821d722e3fbSopenharmony_ci if (ret) 822d722e3fbSopenharmony_ci return ret; 823d722e3fbSopenharmony_ci 824d722e3fbSopenharmony_ci ret = drmSyncobjTransfer(dev->fd, binary_handle, 0, 825d722e3fbSopenharmony_ci syncobj, point, flags); 826d722e3fbSopenharmony_ci if (ret) 827d722e3fbSopenharmony_ci goto out; 828d722e3fbSopenharmony_ci ret = drmSyncobjExportSyncFile(dev->fd, binary_handle, sync_file_fd); 829d722e3fbSopenharmony_ciout: 830d722e3fbSopenharmony_ci drmSyncobjDestroy(dev->fd, binary_handle); 831d722e3fbSopenharmony_ci return ret; 832d722e3fbSopenharmony_ci} 833d722e3fbSopenharmony_ci 834d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev, 835d722e3fbSopenharmony_ci uint32_t syncobj, 836d722e3fbSopenharmony_ci uint64_t point, 837d722e3fbSopenharmony_ci int sync_file_fd) 838d722e3fbSopenharmony_ci{ 839d722e3fbSopenharmony_ci uint32_t binary_handle; 840d722e3fbSopenharmony_ci int ret; 841d722e3fbSopenharmony_ci 842d722e3fbSopenharmony_ci if (NULL == dev) 843d722e3fbSopenharmony_ci return -EINVAL; 844d722e3fbSopenharmony_ci 845d722e3fbSopenharmony_ci if (!point) 846d722e3fbSopenharmony_ci return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd); 847d722e3fbSopenharmony_ci 848d722e3fbSopenharmony_ci ret = drmSyncobjCreate(dev->fd, 0, &binary_handle); 849d722e3fbSopenharmony_ci if (ret) 850d722e3fbSopenharmony_ci return ret; 851d722e3fbSopenharmony_ci ret = drmSyncobjImportSyncFile(dev->fd, binary_handle, sync_file_fd); 852d722e3fbSopenharmony_ci if (ret) 853d722e3fbSopenharmony_ci goto out; 854d722e3fbSopenharmony_ci ret = drmSyncobjTransfer(dev->fd, syncobj, point, 855d722e3fbSopenharmony_ci binary_handle, 0, 0); 856d722e3fbSopenharmony_ciout: 857d722e3fbSopenharmony_ci drmSyncobjDestroy(dev->fd, binary_handle); 858d722e3fbSopenharmony_ci return ret; 859d722e3fbSopenharmony_ci} 860d722e3fbSopenharmony_ci 861d722e3fbSopenharmony_cidrm_public int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev, 862d722e3fbSopenharmony_ci uint32_t dst_handle, 863d722e3fbSopenharmony_ci uint64_t dst_point, 864d722e3fbSopenharmony_ci uint32_t src_handle, 865d722e3fbSopenharmony_ci uint64_t src_point, 866d722e3fbSopenharmony_ci uint32_t flags) 867d722e3fbSopenharmony_ci{ 868d722e3fbSopenharmony_ci if (NULL == dev) 869d722e3fbSopenharmony_ci return -EINVAL; 870d722e3fbSopenharmony_ci 871d722e3fbSopenharmony_ci return drmSyncobjTransfer(dev->fd, 872d722e3fbSopenharmony_ci dst_handle, dst_point, 873d722e3fbSopenharmony_ci src_handle, src_point, 874d722e3fbSopenharmony_ci flags); 875d722e3fbSopenharmony_ci} 876d722e3fbSopenharmony_ci 877d722e3fbSopenharmony_cidrm_public int amdgpu_cs_submit_raw(amdgpu_device_handle dev, 878d722e3fbSopenharmony_ci amdgpu_context_handle context, 879d722e3fbSopenharmony_ci amdgpu_bo_list_handle bo_list_handle, 880d722e3fbSopenharmony_ci int num_chunks, 881d722e3fbSopenharmony_ci struct drm_amdgpu_cs_chunk *chunks, 882d722e3fbSopenharmony_ci uint64_t *seq_no) 883d722e3fbSopenharmony_ci{ 884d722e3fbSopenharmony_ci union drm_amdgpu_cs cs; 885d722e3fbSopenharmony_ci uint64_t *chunk_array; 886d722e3fbSopenharmony_ci int i, r; 887d722e3fbSopenharmony_ci if (num_chunks == 0) 888d722e3fbSopenharmony_ci return -EINVAL; 889d722e3fbSopenharmony_ci 890d722e3fbSopenharmony_ci memset(&cs, 0, sizeof(cs)); 891d722e3fbSopenharmony_ci chunk_array = alloca(sizeof(uint64_t) * num_chunks); 892d722e3fbSopenharmony_ci for (i = 0; i < num_chunks; i++) 893d722e3fbSopenharmony_ci chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i]; 894d722e3fbSopenharmony_ci cs.in.chunks = (uint64_t)(uintptr_t)chunk_array; 895d722e3fbSopenharmony_ci cs.in.ctx_id = context->id; 896d722e3fbSopenharmony_ci cs.in.bo_list_handle = bo_list_handle ? bo_list_handle->handle : 0; 897d722e3fbSopenharmony_ci cs.in.num_chunks = num_chunks; 898d722e3fbSopenharmony_ci r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_CS, 899d722e3fbSopenharmony_ci &cs, sizeof(cs)); 900d722e3fbSopenharmony_ci if (r) 901d722e3fbSopenharmony_ci return r; 902d722e3fbSopenharmony_ci 903d722e3fbSopenharmony_ci if (seq_no) 904d722e3fbSopenharmony_ci *seq_no = cs.out.handle; 905d722e3fbSopenharmony_ci return 0; 906d722e3fbSopenharmony_ci} 907d722e3fbSopenharmony_ci 908d722e3fbSopenharmony_cidrm_public int amdgpu_cs_submit_raw2(amdgpu_device_handle dev, 909d722e3fbSopenharmony_ci amdgpu_context_handle context, 910d722e3fbSopenharmony_ci uint32_t bo_list_handle, 911d722e3fbSopenharmony_ci int num_chunks, 912d722e3fbSopenharmony_ci struct drm_amdgpu_cs_chunk *chunks, 913d722e3fbSopenharmony_ci uint64_t *seq_no) 914d722e3fbSopenharmony_ci{ 915d722e3fbSopenharmony_ci union drm_amdgpu_cs cs; 916d722e3fbSopenharmony_ci uint64_t *chunk_array; 917d722e3fbSopenharmony_ci int i, r; 918d722e3fbSopenharmony_ci 919d722e3fbSopenharmony_ci memset(&cs, 0, sizeof(cs)); 920d722e3fbSopenharmony_ci chunk_array = alloca(sizeof(uint64_t) * num_chunks); 921d722e3fbSopenharmony_ci for (i = 0; i < num_chunks; i++) 922d722e3fbSopenharmony_ci chunk_array[i] = (uint64_t)(uintptr_t)&chunks[i]; 923d722e3fbSopenharmony_ci cs.in.chunks = (uint64_t)(uintptr_t)chunk_array; 924d722e3fbSopenharmony_ci cs.in.ctx_id = context->id; 925d722e3fbSopenharmony_ci cs.in.bo_list_handle = bo_list_handle; 926d722e3fbSopenharmony_ci cs.in.num_chunks = num_chunks; 927d722e3fbSopenharmony_ci r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_CS, 928d722e3fbSopenharmony_ci &cs, sizeof(cs)); 929d722e3fbSopenharmony_ci if (!r && seq_no) 930d722e3fbSopenharmony_ci *seq_no = cs.out.handle; 931d722e3fbSopenharmony_ci return r; 932d722e3fbSopenharmony_ci} 933d722e3fbSopenharmony_ci 934d722e3fbSopenharmony_cidrm_public void amdgpu_cs_chunk_fence_info_to_data(struct amdgpu_cs_fence_info *fence_info, 935d722e3fbSopenharmony_ci struct drm_amdgpu_cs_chunk_data *data) 936d722e3fbSopenharmony_ci{ 937d722e3fbSopenharmony_ci data->fence_data.handle = fence_info->handle->handle; 938d722e3fbSopenharmony_ci data->fence_data.offset = fence_info->offset * sizeof(uint64_t); 939d722e3fbSopenharmony_ci} 940d722e3fbSopenharmony_ci 941d722e3fbSopenharmony_cidrm_public void amdgpu_cs_chunk_fence_to_dep(struct amdgpu_cs_fence *fence, 942d722e3fbSopenharmony_ci struct drm_amdgpu_cs_chunk_dep *dep) 943d722e3fbSopenharmony_ci{ 944d722e3fbSopenharmony_ci dep->ip_type = fence->ip_type; 945d722e3fbSopenharmony_ci dep->ip_instance = fence->ip_instance; 946d722e3fbSopenharmony_ci dep->ring = fence->ring; 947d722e3fbSopenharmony_ci dep->ctx_id = fence->context->id; 948d722e3fbSopenharmony_ci dep->handle = fence->fence; 949d722e3fbSopenharmony_ci} 950d722e3fbSopenharmony_ci 951d722e3fbSopenharmony_cidrm_public int amdgpu_cs_fence_to_handle(amdgpu_device_handle dev, 952d722e3fbSopenharmony_ci struct amdgpu_cs_fence *fence, 953d722e3fbSopenharmony_ci uint32_t what, 954d722e3fbSopenharmony_ci uint32_t *out_handle) 955d722e3fbSopenharmony_ci{ 956d722e3fbSopenharmony_ci union drm_amdgpu_fence_to_handle fth; 957d722e3fbSopenharmony_ci int r; 958d722e3fbSopenharmony_ci 959d722e3fbSopenharmony_ci memset(&fth, 0, sizeof(fth)); 960d722e3fbSopenharmony_ci fth.in.fence.ctx_id = fence->context->id; 961d722e3fbSopenharmony_ci fth.in.fence.ip_type = fence->ip_type; 962d722e3fbSopenharmony_ci fth.in.fence.ip_instance = fence->ip_instance; 963d722e3fbSopenharmony_ci fth.in.fence.ring = fence->ring; 964d722e3fbSopenharmony_ci fth.in.fence.seq_no = fence->fence; 965d722e3fbSopenharmony_ci fth.in.what = what; 966d722e3fbSopenharmony_ci 967d722e3fbSopenharmony_ci r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_FENCE_TO_HANDLE, 968d722e3fbSopenharmony_ci &fth, sizeof(fth)); 969d722e3fbSopenharmony_ci if (r == 0) 970d722e3fbSopenharmony_ci *out_handle = fth.out.handle; 971d722e3fbSopenharmony_ci return r; 972d722e3fbSopenharmony_ci} 973