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