static struct fence *amdgpu_job_run(struct amd_sched_job *sched_job) { struct fence *fence = NULL; struct amdgpu_job *job; int r; if (!sched_job) { DRM_ERROR("job is null\n"); return NULL; } job = to_amdgpu_job(sched_job); r = amdgpu_sync_wait(&job->sync); if (r) { DRM_ERROR("failed to sync wait (%d)\n", r); return NULL; } trace_amdgpu_sched_run_job(job); r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job->sync.last_vm_update, job, &fence); if (r) { DRM_ERROR("Error scheduling IBs (%d)\n", r); goto err; } err: job->fence = fence; amdgpu_job_free(job); return fence; }
int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine, uint32_t vmid, uint64_t gpu_addr, uint32_t *ib_cmd, uint32_t ib_len) { struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct amdgpu_job *job; struct amdgpu_ib *ib; struct amdgpu_ring *ring; struct dma_fence *f = NULL; int ret; switch (engine) { case KGD_ENGINE_MEC1: ring = &adev->gfx.compute_ring[0]; break; case KGD_ENGINE_SDMA1: ring = &adev->sdma.instance[0].ring; break; case KGD_ENGINE_SDMA2: ring = &adev->sdma.instance[1].ring; break; default: pr_err("Invalid engine in IB submission: %d\n", engine); ret = -EINVAL; goto err; } ret = amdgpu_job_alloc(adev, 1, &job, NULL); if (ret) goto err; ib = &job->ibs[0]; memset(ib, 0, sizeof(struct amdgpu_ib)); ib->gpu_addr = gpu_addr; ib->ptr = ib_cmd; ib->length_dw = ib_len; /* This works for NO_HWS. TODO: need to handle without knowing VMID */ job->vmid = vmid; ret = amdgpu_ib_schedule(ring, 1, ib, job, &f); if (ret) { DRM_ERROR("amdgpu: failed to schedule IB.\n"); goto err_ib_sched; } ret = dma_fence_wait(f, false); err_ib_sched: dma_fence_put(f); amdgpu_job_free(job); err: return ret; }
/** * uvd_v6_0_enc_get_destroy_msg - generate a UVD ENC destroy msg * * @adev: amdgpu_device pointer * @ring: ring we should submit the msg to * @handle: session handle to use * @fence: optional fence to return * * Close up a stream for HW test or if userspace failed to do so */ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, struct dma_fence **fence) { const unsigned ib_size_dw = 16; struct amdgpu_job *job; struct amdgpu_ib *ib; struct dma_fence *f = NULL; uint64_t dummy; int i, r; r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); if (r) return r; ib = &job->ibs[0]; dummy = ib->gpu_addr + 1024; ib->length_dw = 0; ib->ptr[ib->length_dw++] = 0x00000018; ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ ib->ptr[ib->length_dw++] = handle; ib->ptr[ib->length_dw++] = 0x00010000; ib->ptr[ib->length_dw++] = upper_32_bits(dummy); ib->ptr[ib->length_dw++] = dummy; ib->ptr[ib->length_dw++] = 0x00000014; ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ ib->ptr[ib->length_dw++] = 0x0000001c; ib->ptr[ib->length_dw++] = 0x00000001; ib->ptr[ib->length_dw++] = 0x00000000; ib->ptr[ib->length_dw++] = 0x00000008; ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */ for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; r = amdgpu_job_submit_direct(job, ring, &f); if (r) goto err; if (fence) *fence = dma_fence_get(f); dma_fence_put(f); return 0; err: amdgpu_job_free(job); return r; }