]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
scsi_dh: don't try to load a device handler during async probing
[karo-tx-linux.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_vce.c
index d3ca73090e39d94f8eaf0762dcb22b4209a07712..3cab96c42aa8843487190248b98d999fb6b3598c 100644 (file)
@@ -48,6 +48,7 @@
 #endif
 #define FIRMWARE_TONGA         "amdgpu/tonga_vce.bin"
 #define FIRMWARE_CARRIZO       "amdgpu/carrizo_vce.bin"
+#define FIRMWARE_FIJI          "amdgpu/fiji_vce.bin"
 
 #ifdef CONFIG_DRM_AMDGPU_CIK
 MODULE_FIRMWARE(FIRMWARE_BONAIRE);
@@ -58,6 +59,7 @@ MODULE_FIRMWARE(FIRMWARE_MULLINS);
 #endif
 MODULE_FIRMWARE(FIRMWARE_TONGA);
 MODULE_FIRMWARE(FIRMWARE_CARRIZO);
+MODULE_FIRMWARE(FIRMWARE_FIJI);
 
 static void amdgpu_vce_idle_work_handler(struct work_struct *work);
 
@@ -101,6 +103,9 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
        case CHIP_CARRIZO:
                fw_name = FIRMWARE_CARRIZO;
                break;
+       case CHIP_FIJI:
+               fw_name = FIRMWARE_FIJI;
+               break;
 
        default:
                return -EINVAL;
@@ -136,7 +141,9 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
        /* allocate firmware, stack and heap BO */
 
        r = amdgpu_bo_create(adev, size, PAGE_SIZE, true,
-                            AMDGPU_GEM_DOMAIN_VRAM, 0, NULL, &adev->vce.vcpu_bo);
+                            AMDGPU_GEM_DOMAIN_VRAM,
+                            AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
+                            NULL, &adev->vce.vcpu_bo);
        if (r) {
                dev_err(adev->dev, "(%d) failed to allocate VCE bo\n", r);
                return r;
@@ -334,6 +341,14 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
        }
 }
 
+static int amdgpu_vce_free_job(
+       struct amdgpu_job *sched_job)
+{
+       amdgpu_ib_free(sched_job->adev, sched_job->ibs);
+       kfree(sched_job->ibs);
+       return 0;
+}
+
 /**
  * amdgpu_vce_get_create_msg - generate a VCE create msg
  *
@@ -345,59 +360,69 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
  * Open up a stream for HW test
  */
 int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
-                             struct amdgpu_fence **fence)
+                             struct fence **fence)
 {
        const unsigned ib_size_dw = 1024;
-       struct amdgpu_ib ib;
+       struct amdgpu_ib *ib = NULL;
+       struct fence *f = NULL;
+       struct amdgpu_device *adev = ring->adev;
        uint64_t dummy;
        int i, r;
 
-       r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, &ib);
+       ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL);
+       if (!ib)
+               return -ENOMEM;
+       r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, ib);
        if (r) {
                DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
+               kfree(ib);
                return r;
        }
 
-       dummy = ib.gpu_addr + 1024;
+       dummy = ib->gpu_addr + 1024;
 
        /* stitch together an VCE create msg */
-       ib.length_dw = 0;
-       ib.ptr[ib.length_dw++] = 0x0000000c; /* len */
-       ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */
-       ib.ptr[ib.length_dw++] = handle;
-
-       ib.ptr[ib.length_dw++] = 0x00000030; /* len */
-       ib.ptr[ib.length_dw++] = 0x01000001; /* create cmd */
-       ib.ptr[ib.length_dw++] = 0x00000000;
-       ib.ptr[ib.length_dw++] = 0x00000042;
-       ib.ptr[ib.length_dw++] = 0x0000000a;
-       ib.ptr[ib.length_dw++] = 0x00000001;
-       ib.ptr[ib.length_dw++] = 0x00000080;
-       ib.ptr[ib.length_dw++] = 0x00000060;
-       ib.ptr[ib.length_dw++] = 0x00000100;
-       ib.ptr[ib.length_dw++] = 0x00000100;
-       ib.ptr[ib.length_dw++] = 0x0000000c;
-       ib.ptr[ib.length_dw++] = 0x00000000;
-
-       ib.ptr[ib.length_dw++] = 0x00000014; /* len */
-       ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */
-       ib.ptr[ib.length_dw++] = upper_32_bits(dummy);
-       ib.ptr[ib.length_dw++] = dummy;
-       ib.ptr[ib.length_dw++] = 0x00000001;
-
-       for (i = ib.length_dw; i < ib_size_dw; ++i)
-               ib.ptr[i] = 0x0;
-
-       r = amdgpu_ib_schedule(ring->adev, 1, &ib, AMDGPU_FENCE_OWNER_UNDEFINED);
-       if (r) {
-               DRM_ERROR("amdgpu: failed to schedule ib (%d).\n", r);
-       }
-
+       ib->length_dw = 0;
+       ib->ptr[ib->length_dw++] = 0x0000000c; /* len */
+       ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */
+       ib->ptr[ib->length_dw++] = handle;
+
+       ib->ptr[ib->length_dw++] = 0x00000030; /* len */
+       ib->ptr[ib->length_dw++] = 0x01000001; /* create cmd */
+       ib->ptr[ib->length_dw++] = 0x00000000;
+       ib->ptr[ib->length_dw++] = 0x00000042;
+       ib->ptr[ib->length_dw++] = 0x0000000a;
+       ib->ptr[ib->length_dw++] = 0x00000001;
+       ib->ptr[ib->length_dw++] = 0x00000080;
+       ib->ptr[ib->length_dw++] = 0x00000060;
+       ib->ptr[ib->length_dw++] = 0x00000100;
+       ib->ptr[ib->length_dw++] = 0x00000100;
+       ib->ptr[ib->length_dw++] = 0x0000000c;
+       ib->ptr[ib->length_dw++] = 0x00000000;
+
+       ib->ptr[ib->length_dw++] = 0x00000014; /* len */
+       ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */
+       ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
+       ib->ptr[ib->length_dw++] = dummy;
+       ib->ptr[ib->length_dw++] = 0x00000001;
+
+       for (i = ib->length_dw; i < ib_size_dw; ++i)
+               ib->ptr[i] = 0x0;
+
+       r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1,
+                                                &amdgpu_vce_free_job,
+                                                AMDGPU_FENCE_OWNER_UNDEFINED,
+                                                &f);
+       if (r)
+               goto err;
        if (fence)
-               *fence = amdgpu_fence_ref(ib.fence);
-
-       amdgpu_ib_free(ring->adev, &ib);
-
+               *fence = fence_get(f);
+       fence_put(f);
+       if (amdgpu_enable_scheduler)
+               return 0;
+err:
+       amdgpu_ib_free(adev, ib);
+       kfree(ib);
        return r;
 }
 
@@ -412,49 +437,59 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
  * Close up a stream for HW test or if userspace failed to do so
  */
 int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
-                              struct amdgpu_fence **fence)
+                              struct fence **fence)
 {
        const unsigned ib_size_dw = 1024;
-       struct amdgpu_ib ib;
+       struct amdgpu_ib *ib = NULL;
+       struct fence *f = NULL;
+       struct amdgpu_device *adev = ring->adev;
        uint64_t dummy;
        int i, r;
 
-       r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, &ib);
+       ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL);
+       if (!ib)
+               return -ENOMEM;
+
+       r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, ib);
        if (r) {
+               kfree(ib);
                DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
                return r;
        }
 
-       dummy = ib.gpu_addr + 1024;
+       dummy = ib->gpu_addr + 1024;
 
        /* stitch together an VCE destroy msg */
-       ib.length_dw = 0;
-       ib.ptr[ib.length_dw++] = 0x0000000c; /* len */
-       ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */
-       ib.ptr[ib.length_dw++] = handle;
-
-       ib.ptr[ib.length_dw++] = 0x00000014; /* len */
-       ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */
-       ib.ptr[ib.length_dw++] = upper_32_bits(dummy);
-       ib.ptr[ib.length_dw++] = dummy;
-       ib.ptr[ib.length_dw++] = 0x00000001;
-
-       ib.ptr[ib.length_dw++] = 0x00000008; /* len */
-       ib.ptr[ib.length_dw++] = 0x02000001; /* destroy cmd */
-
-       for (i = ib.length_dw; i < ib_size_dw; ++i)
-               ib.ptr[i] = 0x0;
-
-       r = amdgpu_ib_schedule(ring->adev, 1, &ib, AMDGPU_FENCE_OWNER_UNDEFINED);
-       if (r) {
-               DRM_ERROR("amdgpu: failed to schedule ib (%d).\n", r);
-       }
-
+       ib->length_dw = 0;
+       ib->ptr[ib->length_dw++] = 0x0000000c; /* len */
+       ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */
+       ib->ptr[ib->length_dw++] = handle;
+
+       ib->ptr[ib->length_dw++] = 0x00000014; /* len */
+       ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */
+       ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
+       ib->ptr[ib->length_dw++] = dummy;
+       ib->ptr[ib->length_dw++] = 0x00000001;
+
+       ib->ptr[ib->length_dw++] = 0x00000008; /* len */
+       ib->ptr[ib->length_dw++] = 0x02000001; /* destroy cmd */
+
+       for (i = ib->length_dw; i < ib_size_dw; ++i)
+               ib->ptr[i] = 0x0;
+       r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1,
+                                                &amdgpu_vce_free_job,
+                                                AMDGPU_FENCE_OWNER_UNDEFINED,
+                                                &f);
+       if (r)
+               goto err;
        if (fence)
-               *fence = amdgpu_fence_ref(ib.fence);
-
-       amdgpu_ib_free(ring->adev, &ib);
-
+               *fence = fence_get(f);
+       fence_put(f);
+       if (amdgpu_enable_scheduler)
+               return 0;
+err:
+       amdgpu_ib_free(adev, ib);
+       kfree(ib);
        return r;
 }
 
@@ -800,9 +835,13 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring)
  */
 int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring)
 {
-       struct amdgpu_fence *fence = NULL;
+       struct fence *fence = NULL;
        int r;
 
+       /* skip vce ring1 ib test for now, since it's not reliable */
+       if (ring == &ring->adev->vce.ring[1])
+               return 0;
+
        r = amdgpu_vce_get_create_msg(ring, 1, NULL);
        if (r) {
                DRM_ERROR("amdgpu: failed to get create msg (%d).\n", r);
@@ -815,13 +854,13 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring)
                goto error;
        }
 
-       r = amdgpu_fence_wait(fence, false);
+       r = fence_wait(fence, false);
        if (r) {
                DRM_ERROR("amdgpu: fence wait failed (%d).\n", r);
        } else {
                DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
        }
 error:
-       amdgpu_fence_unref(&fence);
+       fence_put(fence);
        return r;
 }