drm/amdgpu: Add submit IB function for KFD
authorFelix Kuehling <Felix.Kuehling@amd.com>
Wed, 7 Feb 2018 01:32:39 +0000 (20:32 -0500)
committerOded Gabbay <oded.gabbay@gmail.com>
Wed, 7 Feb 2018 01:32:39 +0000 (20:32 -0500)
This can be used for flushing caches when not using the HWS.

Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
drivers/gpu/drm/amd/include/kgd_kfd_interface.h

index 5a881107a15adec0c9356a1fcadd0efb6ee971b3..8a23aa8f9c732247740ded28e41e868be8ba1003 100644 (file)
@@ -367,6 +367,61 @@ uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd)
        return amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
 }
 
+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;
+}
+
 bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid)
 {
        if (adev->kfd) {
index 05a228d60241c354ea9279f5054f84bbea78abf8..d7509b706b26bb39b277d52c17d85eefd27116c9 100644 (file)
@@ -124,6 +124,10 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev);
 void amdgpu_amdkfd_device_init(struct amdgpu_device *adev);
 void amdgpu_amdkfd_device_fini(struct amdgpu_device *adev);
 
+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 kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void);
 struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void);
 
index 65783d1eddcac157c6dff0aede96c32ab4b25f2e..7485c376b90ee2cb850e174cb65365c14dfd9f8a 100644 (file)
@@ -217,6 +217,7 @@ static const struct kfd2kgd_calls kfd2kgd = {
        .restore_process_bos = amdgpu_amdkfd_gpuvm_restore_process_bos,
        .invalidate_tlbs = invalidate_tlbs,
        .invalidate_tlbs_vmid = invalidate_tlbs_vmid,
+       .submit_ib = amdgpu_amdkfd_submit_ib,
 };
 
 struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void)
index 1b5bf1353f0c46793e9bc29daeeb4ee9ee3abff5..7be453494423cce6a1ed5293bb73f705c4ee6857 100644 (file)
@@ -177,6 +177,7 @@ static const struct kfd2kgd_calls kfd2kgd = {
        .restore_process_bos = amdgpu_amdkfd_gpuvm_restore_process_bos,
        .invalidate_tlbs = invalidate_tlbs,
        .invalidate_tlbs_vmid = invalidate_tlbs_vmid,
+       .submit_ib = amdgpu_amdkfd_submit_ib,
 };
 
 struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void)
index 5984fec78be4aca533f7566bfbfbba13f1a099f2..1e5c22ceb256880e8ffe38bf1ad7cb16ce7431ef 100644 (file)
@@ -240,6 +240,10 @@ struct tile_config {
  *
  * @invalidate_tlbs_vmid: Invalidate TLBs for a specific VMID
  *
+ * @submit_ib: Submits an IB to the engine specified by inserting the
+ * IB to the corresponding ring (ring type). The IB is executed with the
+ * specified VMID in a user mode context.
+ *
  * This structure contains function pointers to services that the kgd driver
  * provides to amdkfd driver.
  *
@@ -352,6 +356,10 @@ struct kfd2kgd_calls {
 
        int (*invalidate_tlbs)(struct kgd_dev *kgd, uint16_t pasid);
        int (*invalidate_tlbs_vmid)(struct kgd_dev *kgd, uint16_t vmid);
+
+       int (*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);
 };
 
 /**