Merge branch 'x86/cpu'
[deliverable/linux.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_ib.c
index 8443cea6821ad00cad2181d16ac450b8045223ec..34e35423b78e81d3d91102e2acacf889fa9792c0 100644 (file)
@@ -74,9 +74,6 @@ int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                        ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo);
        }
 
-       ib->vm = vm;
-       ib->vm_id = 0;
-
        return 0;
 }
 
@@ -89,7 +86,8 @@ int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
  *
  * Free an IB (all asics).
  */
-void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib, struct fence *f)
+void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib,
+                   struct fence *f)
 {
        amdgpu_sa_bo_free(adev, &ib->sa_bo, f);
 }
@@ -117,28 +115,37 @@ void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib, struct fen
  */
 int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
                       struct amdgpu_ib *ibs, struct fence *last_vm_update,
-                      struct fence **f)
+                      struct amdgpu_job *job, struct fence **f)
 {
        struct amdgpu_device *adev = ring->adev;
        struct amdgpu_ib *ib = &ibs[0];
-       struct amdgpu_ctx *ctx, *old_ctx;
+       bool skip_preamble, need_ctx_switch;
+       unsigned patch_offset = ~0;
        struct amdgpu_vm *vm;
        struct fence *hwf;
+       uint64_t ctx;
+
        unsigned i;
        int r = 0;
 
        if (num_ibs == 0)
                return -EINVAL;
 
-       ctx = ibs->ctx;
-       vm = ibs->vm;
+       /* ring tests don't use a job */
+       if (job) {
+               vm = job->vm;
+               ctx = job->ctx;
+       } else {
+               vm = NULL;
+               ctx = 0;
+       }
 
        if (!ring->ready) {
                dev_err(adev->dev, "couldn't schedule ib\n");
                return -EINVAL;
        }
 
-       if (vm && !ibs->vm_id) {
+       if (vm && !job->vm_id) {
                dev_err(adev->dev, "VM IB without ID\n");
                return -EINVAL;
        }
@@ -149,58 +156,68 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
                return r;
        }
 
+       if (ring->type == AMDGPU_RING_TYPE_SDMA && ring->funcs->init_cond_exec)
+               patch_offset = amdgpu_ring_init_cond_exec(ring);
+
        if (vm) {
-               /* do context switch */
-               amdgpu_vm_flush(ring, ib->vm_id, ib->vm_pd_addr,
-                               ib->gds_base, ib->gds_size,
-                               ib->gws_base, ib->gws_size,
-                               ib->oa_base, ib->oa_size);
-
-               if (ring->funcs->emit_hdp_flush)
-                       amdgpu_ring_emit_hdp_flush(ring);
+               r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr,
+                                   job->gds_base, job->gds_size,
+                                   job->gws_base, job->gws_size,
+                                   job->oa_base, job->oa_size);
+               if (r) {
+                       amdgpu_ring_undo(ring);
+                       return r;
+               }
        }
 
-       old_ctx = ring->current_ctx;
+       if (ring->funcs->emit_hdp_flush)
+               amdgpu_ring_emit_hdp_flush(ring);
+
+       /* always set cond_exec_polling to CONTINUE */
+       *ring->cond_exe_cpu_addr = 1;
+
+       skip_preamble = ring->current_ctx == ctx;
+       need_ctx_switch = ring->current_ctx != ctx;
        for (i = 0; i < num_ibs; ++i) {
                ib = &ibs[i];
 
-               if (ib->ctx != ctx || ib->vm != vm) {
-                       ring->current_ctx = old_ctx;
-                       if (ib->vm_id)
-                               amdgpu_vm_reset_id(adev, ib->vm_id);
-                       amdgpu_ring_undo(ring);
-                       return -EINVAL;
-               }
-               amdgpu_ring_emit_ib(ring, ib);
-               ring->current_ctx = ctx;
-       }
+               /* drop preamble IBs if we don't have a context switch */
+               if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble)
+                       continue;
 
-       if (vm) {
-               if (ring->funcs->emit_hdp_invalidate)
-                       amdgpu_ring_emit_hdp_invalidate(ring);
+               amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0,
+                                   need_ctx_switch);
+               need_ctx_switch = false;
        }
 
+       if (ring->funcs->emit_hdp_invalidate)
+               amdgpu_ring_emit_hdp_invalidate(ring);
+
        r = amdgpu_fence_emit(ring, &hwf);
        if (r) {
                dev_err(adev->dev, "failed to emit fence (%d)\n", r);
-               ring->current_ctx = old_ctx;
-               if (ib->vm_id)
-                       amdgpu_vm_reset_id(adev, ib->vm_id);
+               if (job && job->vm_id)
+                       amdgpu_vm_reset_id(adev, job->vm_id);
                amdgpu_ring_undo(ring);
                return r;
        }
 
        /* wrap the last IB with fence */
-       if (ib->user) {
-               uint64_t addr = amdgpu_bo_gpu_offset(ib->user->bo);
-               addr += ib->user->offset;
-               amdgpu_ring_emit_fence(ring, addr, ib->sequence,
+       if (job && job->uf_bo) {
+               uint64_t addr = amdgpu_bo_gpu_offset(job->uf_bo);
+
+               addr += job->uf_offset;
+               amdgpu_ring_emit_fence(ring, addr, job->uf_sequence,
                                       AMDGPU_FENCE_FLAG_64BIT);
        }
 
        if (f)
                *f = fence_get(hwf);
 
+       if (patch_offset != ~0 && ring->funcs->patch_cond_exec)
+               amdgpu_ring_patch_cond_exec(ring, patch_offset);
+
+       ring->current_ctx = ctx;
        amdgpu_ring_commit(ring);
        return 0;
 }
@@ -315,7 +332,7 @@ static int amdgpu_debugfs_sa_info(struct seq_file *m, void *data)
 
 }
 
-static struct drm_info_list amdgpu_debugfs_sa_list[] = {
+static const struct drm_info_list amdgpu_debugfs_sa_list[] = {
        {"amdgpu_sa_info", &amdgpu_debugfs_sa_info, 0, NULL},
 };
 
This page took 0.028245 seconds and 5 git commands to generate.