drm/amdgpu: add Navi10 VCN firmware support
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_vcn.c
1 /*
2  * Copyright 2016 Advanced Micro Devices, Inc.
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19  * USE OR OTHER DEALINGS IN THE SOFTWARE.
20  *
21  * The above copyright notice and this permission notice (including the
22  * next paragraph) shall be included in all copies or substantial portions
23  * of the Software.
24  *
25  */
26
27 #include <linux/firmware.h>
28 #include <linux/module.h>
29 #include <drm/drmP.h>
30 #include <drm/drm.h>
31
32 #include "amdgpu.h"
33 #include "amdgpu_pm.h"
34 #include "amdgpu_vcn.h"
35 #include "soc15d.h"
36 #include "soc15_common.h"
37
38 #include "vcn/vcn_1_0_offset.h"
39 #include "vcn/vcn_1_0_sh_mask.h"
40
41 /* 1 second timeout */
42 #define VCN_IDLE_TIMEOUT        msecs_to_jiffies(1000)
43
44 /* Firmware Names */
45 #define FIRMWARE_RAVEN          "amdgpu/raven_vcn.bin"
46 #define FIRMWARE_PICASSO        "amdgpu/picasso_vcn.bin"
47 #define FIRMWARE_RAVEN2         "amdgpu/raven2_vcn.bin"
48 #define FIRMWARE_NAVI10         "amdgpu/navi10_vcn.bin"
49
50 MODULE_FIRMWARE(FIRMWARE_RAVEN);
51 MODULE_FIRMWARE(FIRMWARE_PICASSO);
52 MODULE_FIRMWARE(FIRMWARE_RAVEN2);
53 MODULE_FIRMWARE(FIRMWARE_NAVI10);
54
55 static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
56
57 int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
58 {
59         unsigned long bo_size;
60         const char *fw_name;
61         const struct common_firmware_header *hdr;
62         unsigned char fw_check;
63         int r;
64
65         INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler);
66
67         switch (adev->asic_type) {
68         case CHIP_RAVEN:
69                 if (adev->rev_id >= 8)
70                         fw_name = FIRMWARE_RAVEN2;
71                 else if (adev->pdev->device == 0x15d8)
72                         fw_name = FIRMWARE_PICASSO;
73                 else
74                         fw_name = FIRMWARE_RAVEN;
75                 break;
76         case CHIP_NAVI10:
77                 fw_name = FIRMWARE_NAVI10;
78                 break;
79         default:
80                 return -EINVAL;
81         }
82
83         r = request_firmware(&adev->vcn.fw, fw_name, adev->dev);
84         if (r) {
85                 dev_err(adev->dev, "amdgpu_vcn: Can't load firmware \"%s\"\n",
86                         fw_name);
87                 return r;
88         }
89
90         r = amdgpu_ucode_validate(adev->vcn.fw);
91         if (r) {
92                 dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware \"%s\"\n",
93                         fw_name);
94                 release_firmware(adev->vcn.fw);
95                 adev->vcn.fw = NULL;
96                 return r;
97         }
98
99         hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
100         adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
101
102         /* Bit 20-23, it is encode major and non-zero for new naming convention.
103          * This field is part of version minor and DRM_DISABLED_FLAG in old naming
104          * convention. Since the l:wq!atest version minor is 0x5B and DRM_DISABLED_FLAG
105          * is zero in old naming convention, this field is always zero so far.
106          * These four bits are used to tell which naming convention is present.
107          */
108         fw_check = (le32_to_cpu(hdr->ucode_version) >> 20) & 0xf;
109         if (fw_check) {
110                 unsigned int dec_ver, enc_major, enc_minor, vep, fw_rev;
111
112                 fw_rev = le32_to_cpu(hdr->ucode_version) & 0xfff;
113                 enc_minor = (le32_to_cpu(hdr->ucode_version) >> 12) & 0xff;
114                 enc_major = fw_check;
115                 dec_ver = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xf;
116                 vep = (le32_to_cpu(hdr->ucode_version) >> 28) & 0xf;
117                 DRM_INFO("Found VCN firmware Version ENC: %hu.%hu DEC: %hu VEP: %hu Revision: %hu\n",
118                         enc_major, enc_minor, dec_ver, vep, fw_rev);
119         } else {
120                 unsigned int version_major, version_minor, family_id;
121
122                 family_id = le32_to_cpu(hdr->ucode_version) & 0xff;
123                 version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff;
124                 version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff;
125                 DRM_INFO("Found VCN firmware Version: %hu.%hu Family ID: %hu\n",
126                         version_major, version_minor, family_id);
127         }
128
129         bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_CONTEXT_SIZE;
130         if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
131                 bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
132         r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
133                                     AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.vcpu_bo,
134                                     &adev->vcn.gpu_addr, &adev->vcn.cpu_addr);
135         if (r) {
136                 dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r);
137                 return r;
138         }
139
140         return 0;
141 }
142
143 int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
144 {
145         int i;
146
147         kvfree(adev->vcn.saved_bo);
148
149         amdgpu_bo_free_kernel(&adev->vcn.vcpu_bo,
150                               &adev->vcn.gpu_addr,
151                               (void **)&adev->vcn.cpu_addr);
152
153         amdgpu_ring_fini(&adev->vcn.ring_dec);
154
155         for (i = 0; i < adev->vcn.num_enc_rings; ++i)
156                 amdgpu_ring_fini(&adev->vcn.ring_enc[i]);
157
158         amdgpu_ring_fini(&adev->vcn.ring_jpeg);
159
160         release_firmware(adev->vcn.fw);
161
162         return 0;
163 }
164
165 int amdgpu_vcn_suspend(struct amdgpu_device *adev)
166 {
167         unsigned size;
168         void *ptr;
169
170         cancel_delayed_work_sync(&adev->vcn.idle_work);
171
172         if (adev->vcn.vcpu_bo == NULL)
173                 return 0;
174
175         size = amdgpu_bo_size(adev->vcn.vcpu_bo);
176         ptr = adev->vcn.cpu_addr;
177
178         adev->vcn.saved_bo = kvmalloc(size, GFP_KERNEL);
179         if (!adev->vcn.saved_bo)
180                 return -ENOMEM;
181
182         memcpy_fromio(adev->vcn.saved_bo, ptr, size);
183
184         return 0;
185 }
186
187 int amdgpu_vcn_resume(struct amdgpu_device *adev)
188 {
189         unsigned size;
190         void *ptr;
191
192         if (adev->vcn.vcpu_bo == NULL)
193                 return -EINVAL;
194
195         size = amdgpu_bo_size(adev->vcn.vcpu_bo);
196         ptr = adev->vcn.cpu_addr;
197
198         if (adev->vcn.saved_bo != NULL) {
199                 memcpy_toio(ptr, adev->vcn.saved_bo, size);
200                 kvfree(adev->vcn.saved_bo);
201                 adev->vcn.saved_bo = NULL;
202         } else {
203                 const struct common_firmware_header *hdr;
204                 unsigned offset;
205
206                 hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
207                 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
208                         offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
209                         memcpy_toio(adev->vcn.cpu_addr, adev->vcn.fw->data + offset,
210                                     le32_to_cpu(hdr->ucode_size_bytes));
211                         size -= le32_to_cpu(hdr->ucode_size_bytes);
212                         ptr += le32_to_cpu(hdr->ucode_size_bytes);
213                 }
214                 memset_io(ptr, 0, size);
215         }
216
217         return 0;
218 }
219
220 static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
221 {
222         struct amdgpu_device *adev =
223                 container_of(work, struct amdgpu_device, vcn.idle_work.work);
224         unsigned int fences = 0;
225         unsigned int i;
226
227         for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
228                 fences += amdgpu_fence_count_emitted(&adev->vcn.ring_enc[i]);
229         }
230
231         if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)    {
232                 struct dpg_pause_state new_state;
233
234                 if (fences)
235                         new_state.fw_based = VCN_DPG_STATE__PAUSE;
236                 else
237                         new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
238
239                 if (amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg))
240                         new_state.jpeg = VCN_DPG_STATE__PAUSE;
241                 else
242                         new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
243
244                 adev->vcn.pause_dpg_mode(adev, &new_state);
245         }
246
247         fences += amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg);
248         fences += amdgpu_fence_count_emitted(&adev->vcn.ring_dec);
249
250         if (fences == 0) {
251                 amdgpu_gfx_off_ctrl(adev, true);
252                 if (adev->pm.dpm_enabled)
253                         amdgpu_dpm_enable_uvd(adev, false);
254                 else
255                         amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
256                                                                AMD_PG_STATE_GATE);
257         } else {
258                 schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
259         }
260 }
261
262 void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
263 {
264         struct amdgpu_device *adev = ring->adev;
265         bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
266
267         if (set_clocks) {
268                 amdgpu_gfx_off_ctrl(adev, false);
269                 if (adev->pm.dpm_enabled)
270                         amdgpu_dpm_enable_uvd(adev, true);
271                 else
272                         amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
273                                                                AMD_PG_STATE_UNGATE);
274         }
275
276         if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)    {
277                 struct dpg_pause_state new_state;
278                 unsigned int fences = 0;
279                 unsigned int i;
280
281                 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
282                         fences += amdgpu_fence_count_emitted(&adev->vcn.ring_enc[i]);
283                 }
284                 if (fences)
285                         new_state.fw_based = VCN_DPG_STATE__PAUSE;
286                 else
287                         new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
288
289                 if (amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg))
290                         new_state.jpeg = VCN_DPG_STATE__PAUSE;
291                 else
292                         new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
293
294                 if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
295                         new_state.fw_based = VCN_DPG_STATE__PAUSE;
296                 else if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG)
297                         new_state.jpeg = VCN_DPG_STATE__PAUSE;
298
299                 adev->vcn.pause_dpg_mode(adev, &new_state);
300         }
301 }
302
303 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
304 {
305         schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
306 }
307
308 int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
309 {
310         struct amdgpu_device *adev = ring->adev;
311         uint32_t tmp = 0;
312         unsigned i;
313         int r;
314
315         WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD);
316         r = amdgpu_ring_alloc(ring, 3);
317         if (r)
318                 return r;
319
320         amdgpu_ring_write(ring,
321                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0));
322         amdgpu_ring_write(ring, 0xDEADBEEF);
323         amdgpu_ring_commit(ring);
324         for (i = 0; i < adev->usec_timeout; i++) {
325                 tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9));
326                 if (tmp == 0xDEADBEEF)
327                         break;
328                 DRM_UDELAY(1);
329         }
330
331         if (i >= adev->usec_timeout)
332                 r = -ETIMEDOUT;
333
334         return r;
335 }
336
337 static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
338                                    struct amdgpu_bo *bo,
339                                    struct dma_fence **fence)
340 {
341         struct amdgpu_device *adev = ring->adev;
342         struct dma_fence *f = NULL;
343         struct amdgpu_job *job;
344         struct amdgpu_ib *ib;
345         uint64_t addr;
346         int i, r;
347
348         r = amdgpu_job_alloc_with_ib(adev, 64, &job);
349         if (r)
350                 goto err;
351
352         ib = &job->ibs[0];
353         addr = amdgpu_bo_gpu_offset(bo);
354         ib->ptr[0] = PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0);
355         ib->ptr[1] = addr;
356         ib->ptr[2] = PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0);
357         ib->ptr[3] = addr >> 32;
358         ib->ptr[4] = PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0);
359         ib->ptr[5] = 0;
360         for (i = 6; i < 16; i += 2) {
361                 ib->ptr[i] = PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP), 0);
362                 ib->ptr[i+1] = 0;
363         }
364         ib->length_dw = 16;
365
366         r = amdgpu_job_submit_direct(job, ring, &f);
367         if (r)
368                 goto err_free;
369
370         amdgpu_bo_fence(bo, f, false);
371         amdgpu_bo_unreserve(bo);
372         amdgpu_bo_unref(&bo);
373
374         if (fence)
375                 *fence = dma_fence_get(f);
376         dma_fence_put(f);
377
378         return 0;
379
380 err_free:
381         amdgpu_job_free(job);
382
383 err:
384         amdgpu_bo_unreserve(bo);
385         amdgpu_bo_unref(&bo);
386         return r;
387 }
388
389 static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
390                               struct dma_fence **fence)
391 {
392         struct amdgpu_device *adev = ring->adev;
393         struct amdgpu_bo *bo = NULL;
394         uint32_t *msg;
395         int r, i;
396
397         r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
398                                       AMDGPU_GEM_DOMAIN_VRAM,
399                                       &bo, NULL, (void **)&msg);
400         if (r)
401                 return r;
402
403         msg[0] = cpu_to_le32(0x00000028);
404         msg[1] = cpu_to_le32(0x00000038);
405         msg[2] = cpu_to_le32(0x00000001);
406         msg[3] = cpu_to_le32(0x00000000);
407         msg[4] = cpu_to_le32(handle);
408         msg[5] = cpu_to_le32(0x00000000);
409         msg[6] = cpu_to_le32(0x00000001);
410         msg[7] = cpu_to_le32(0x00000028);
411         msg[8] = cpu_to_le32(0x00000010);
412         msg[9] = cpu_to_le32(0x00000000);
413         msg[10] = cpu_to_le32(0x00000007);
414         msg[11] = cpu_to_le32(0x00000000);
415         msg[12] = cpu_to_le32(0x00000780);
416         msg[13] = cpu_to_le32(0x00000440);
417         for (i = 14; i < 1024; ++i)
418                 msg[i] = cpu_to_le32(0x0);
419
420         return amdgpu_vcn_dec_send_msg(ring, bo, fence);
421 }
422
423 static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
424                                struct dma_fence **fence)
425 {
426         struct amdgpu_device *adev = ring->adev;
427         struct amdgpu_bo *bo = NULL;
428         uint32_t *msg;
429         int r, i;
430
431         r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
432                                       AMDGPU_GEM_DOMAIN_VRAM,
433                                       &bo, NULL, (void **)&msg);
434         if (r)
435                 return r;
436
437         msg[0] = cpu_to_le32(0x00000028);
438         msg[1] = cpu_to_le32(0x00000018);
439         msg[2] = cpu_to_le32(0x00000000);
440         msg[3] = cpu_to_le32(0x00000002);
441         msg[4] = cpu_to_le32(handle);
442         msg[5] = cpu_to_le32(0x00000000);
443         for (i = 6; i < 1024; ++i)
444                 msg[i] = cpu_to_le32(0x0);
445
446         return amdgpu_vcn_dec_send_msg(ring, bo, fence);
447 }
448
449 int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
450 {
451         struct dma_fence *fence;
452         long r;
453
454         r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL);
455         if (r)
456                 goto error;
457
458         r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence);
459         if (r)
460                 goto error;
461
462         r = dma_fence_wait_timeout(fence, false, timeout);
463         if (r == 0)
464                 r = -ETIMEDOUT;
465         else if (r > 0)
466                 r = 0;
467
468         dma_fence_put(fence);
469 error:
470         return r;
471 }
472
473 int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
474 {
475         struct amdgpu_device *adev = ring->adev;
476         uint32_t rptr;
477         unsigned i;
478         int r;
479
480         r = amdgpu_ring_alloc(ring, 16);
481         if (r)
482                 return r;
483
484         rptr = amdgpu_ring_get_rptr(ring);
485
486         amdgpu_ring_write(ring, VCN_ENC_CMD_END);
487         amdgpu_ring_commit(ring);
488
489         for (i = 0; i < adev->usec_timeout; i++) {
490                 if (amdgpu_ring_get_rptr(ring) != rptr)
491                         break;
492                 DRM_UDELAY(1);
493         }
494
495         if (i >= adev->usec_timeout)
496                 r = -ETIMEDOUT;
497
498         return r;
499 }
500
501 static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
502                               struct dma_fence **fence)
503 {
504         const unsigned ib_size_dw = 16;
505         struct amdgpu_job *job;
506         struct amdgpu_ib *ib;
507         struct dma_fence *f = NULL;
508         uint64_t dummy;
509         int i, r;
510
511         r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
512         if (r)
513                 return r;
514
515         ib = &job->ibs[0];
516         dummy = ib->gpu_addr + 1024;
517
518         ib->length_dw = 0;
519         ib->ptr[ib->length_dw++] = 0x00000018;
520         ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
521         ib->ptr[ib->length_dw++] = handle;
522         ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
523         ib->ptr[ib->length_dw++] = dummy;
524         ib->ptr[ib->length_dw++] = 0x0000000b;
525
526         ib->ptr[ib->length_dw++] = 0x00000014;
527         ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
528         ib->ptr[ib->length_dw++] = 0x0000001c;
529         ib->ptr[ib->length_dw++] = 0x00000000;
530         ib->ptr[ib->length_dw++] = 0x00000000;
531
532         ib->ptr[ib->length_dw++] = 0x00000008;
533         ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */
534
535         for (i = ib->length_dw; i < ib_size_dw; ++i)
536                 ib->ptr[i] = 0x0;
537
538         r = amdgpu_job_submit_direct(job, ring, &f);
539         if (r)
540                 goto err;
541
542         if (fence)
543                 *fence = dma_fence_get(f);
544         dma_fence_put(f);
545
546         return 0;
547
548 err:
549         amdgpu_job_free(job);
550         return r;
551 }
552
553 static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
554                                 struct dma_fence **fence)
555 {
556         const unsigned ib_size_dw = 16;
557         struct amdgpu_job *job;
558         struct amdgpu_ib *ib;
559         struct dma_fence *f = NULL;
560         uint64_t dummy;
561         int i, r;
562
563         r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
564         if (r)
565                 return r;
566
567         ib = &job->ibs[0];
568         dummy = ib->gpu_addr + 1024;
569
570         ib->length_dw = 0;
571         ib->ptr[ib->length_dw++] = 0x00000018;
572         ib->ptr[ib->length_dw++] = 0x00000001;
573         ib->ptr[ib->length_dw++] = handle;
574         ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
575         ib->ptr[ib->length_dw++] = dummy;
576         ib->ptr[ib->length_dw++] = 0x0000000b;
577
578         ib->ptr[ib->length_dw++] = 0x00000014;
579         ib->ptr[ib->length_dw++] = 0x00000002;
580         ib->ptr[ib->length_dw++] = 0x0000001c;
581         ib->ptr[ib->length_dw++] = 0x00000000;
582         ib->ptr[ib->length_dw++] = 0x00000000;
583
584         ib->ptr[ib->length_dw++] = 0x00000008;
585         ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */
586
587         for (i = ib->length_dw; i < ib_size_dw; ++i)
588                 ib->ptr[i] = 0x0;
589
590         r = amdgpu_job_submit_direct(job, ring, &f);
591         if (r)
592                 goto err;
593
594         if (fence)
595                 *fence = dma_fence_get(f);
596         dma_fence_put(f);
597
598         return 0;
599
600 err:
601         amdgpu_job_free(job);
602         return r;
603 }
604
605 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
606 {
607         struct dma_fence *fence = NULL;
608         long r;
609
610         r = amdgpu_vcn_enc_get_create_msg(ring, 1, NULL);
611         if (r)
612                 goto error;
613
614         r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &fence);
615         if (r)
616                 goto error;
617
618         r = dma_fence_wait_timeout(fence, false, timeout);
619         if (r == 0)
620                 r = -ETIMEDOUT;
621         else if (r > 0)
622                 r = 0;
623
624 error:
625         dma_fence_put(fence);
626         return r;
627 }
628
629 int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring)
630 {
631         struct amdgpu_device *adev = ring->adev;
632         uint32_t tmp = 0;
633         unsigned i;
634         int r;
635
636         WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD);
637         r = amdgpu_ring_alloc(ring, 3);
638
639         if (r)
640                 return r;
641
642         amdgpu_ring_write(ring,
643                 PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, 0));
644         amdgpu_ring_write(ring, 0xDEADBEEF);
645         amdgpu_ring_commit(ring);
646
647         for (i = 0; i < adev->usec_timeout; i++) {
648                 tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9));
649                 if (tmp == 0xDEADBEEF)
650                         break;
651                 DRM_UDELAY(1);
652         }
653
654         if (i >= adev->usec_timeout)
655                 r = -ETIMEDOUT;
656
657         return r;
658 }
659
660 static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring *ring, uint32_t handle,
661                 struct dma_fence **fence)
662 {
663         struct amdgpu_device *adev = ring->adev;
664         struct amdgpu_job *job;
665         struct amdgpu_ib *ib;
666         struct dma_fence *f = NULL;
667         const unsigned ib_size_dw = 16;
668         int i, r;
669
670         r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
671         if (r)
672                 return r;
673
674         ib = &job->ibs[0];
675
676         ib->ptr[0] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, PACKETJ_TYPE0);
677         ib->ptr[1] = 0xDEADBEEF;
678         for (i = 2; i < 16; i += 2) {
679                 ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
680                 ib->ptr[i+1] = 0;
681         }
682         ib->length_dw = 16;
683
684         r = amdgpu_job_submit_direct(job, ring, &f);
685         if (r)
686                 goto err;
687
688         if (fence)
689                 *fence = dma_fence_get(f);
690         dma_fence_put(f);
691
692         return 0;
693
694 err:
695         amdgpu_job_free(job);
696         return r;
697 }
698
699 int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout)
700 {
701         struct amdgpu_device *adev = ring->adev;
702         uint32_t tmp = 0;
703         unsigned i;
704         struct dma_fence *fence = NULL;
705         long r = 0;
706
707         r = amdgpu_vcn_jpeg_set_reg(ring, 1, &fence);
708         if (r)
709                 goto error;
710
711         r = dma_fence_wait_timeout(fence, false, timeout);
712         if (r == 0) {
713                 r = -ETIMEDOUT;
714                 goto error;
715         } else if (r < 0) {
716                 goto error;
717         } else {
718                 r = 0;
719         }
720
721         for (i = 0; i < adev->usec_timeout; i++) {
722                 tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9));
723                 if (tmp == 0xDEADBEEF)
724                         break;
725                 DRM_UDELAY(1);
726         }
727
728         if (i >= adev->usec_timeout)
729                 r = -ETIMEDOUT;
730
731         dma_fence_put(fence);
732 error:
733         return r;
734 }