drm/amdgpu: add VCN2.0 decode ib test
[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(adev->vcn.external.scratch9, 0xCAFEDEAD);
316         r = amdgpu_ring_alloc(ring, 3);
317         if (r)
318                 return r;
319         amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.scratch9, 0));
320         amdgpu_ring_write(ring, 0xDEADBEEF);
321         amdgpu_ring_commit(ring);
322         for (i = 0; i < adev->usec_timeout; i++) {
323                 tmp = RREG32(adev->vcn.external.scratch9);
324                 if (tmp == 0xDEADBEEF)
325                         break;
326                 DRM_UDELAY(1);
327         }
328
329         if (i >= adev->usec_timeout)
330                 r = -ETIMEDOUT;
331
332         return r;
333 }
334
335 static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
336                                    struct amdgpu_bo *bo,
337                                    struct dma_fence **fence)
338 {
339         struct amdgpu_device *adev = ring->adev;
340         struct dma_fence *f = NULL;
341         struct amdgpu_job *job;
342         struct amdgpu_ib *ib;
343         uint64_t addr;
344         int i, r;
345
346         r = amdgpu_job_alloc_with_ib(adev, 64, &job);
347         if (r)
348                 goto err;
349
350         ib = &job->ibs[0];
351         addr = amdgpu_bo_gpu_offset(bo);
352         ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0);
353         ib->ptr[1] = addr;
354         ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0);
355         ib->ptr[3] = addr >> 32;
356         ib->ptr[4] = PACKET0(adev->vcn.internal.cmd, 0);
357         ib->ptr[5] = 0;
358         for (i = 6; i < 16; i += 2) {
359                 ib->ptr[i] = PACKET0(adev->vcn.internal.nop, 0);
360                 ib->ptr[i+1] = 0;
361         }
362         ib->length_dw = 16;
363
364         r = amdgpu_job_submit_direct(job, ring, &f);
365         if (r)
366                 goto err_free;
367
368         amdgpu_bo_fence(bo, f, false);
369         amdgpu_bo_unreserve(bo);
370         amdgpu_bo_unref(&bo);
371
372         if (fence)
373                 *fence = dma_fence_get(f);
374         dma_fence_put(f);
375
376         return 0;
377
378 err_free:
379         amdgpu_job_free(job);
380
381 err:
382         amdgpu_bo_unreserve(bo);
383         amdgpu_bo_unref(&bo);
384         return r;
385 }
386
387 static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
388                               struct dma_fence **fence)
389 {
390         struct amdgpu_device *adev = ring->adev;
391         struct amdgpu_bo *bo = NULL;
392         uint32_t *msg;
393         int r, i;
394
395         r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
396                                       AMDGPU_GEM_DOMAIN_VRAM,
397                                       &bo, NULL, (void **)&msg);
398         if (r)
399                 return r;
400
401         msg[0] = cpu_to_le32(0x00000028);
402         msg[1] = cpu_to_le32(0x00000038);
403         msg[2] = cpu_to_le32(0x00000001);
404         msg[3] = cpu_to_le32(0x00000000);
405         msg[4] = cpu_to_le32(handle);
406         msg[5] = cpu_to_le32(0x00000000);
407         msg[6] = cpu_to_le32(0x00000001);
408         msg[7] = cpu_to_le32(0x00000028);
409         msg[8] = cpu_to_le32(0x00000010);
410         msg[9] = cpu_to_le32(0x00000000);
411         msg[10] = cpu_to_le32(0x00000007);
412         msg[11] = cpu_to_le32(0x00000000);
413         msg[12] = cpu_to_le32(0x00000780);
414         msg[13] = cpu_to_le32(0x00000440);
415         for (i = 14; i < 1024; ++i)
416                 msg[i] = cpu_to_le32(0x0);
417
418         return amdgpu_vcn_dec_send_msg(ring, bo, fence);
419 }
420
421 static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
422                                struct dma_fence **fence)
423 {
424         struct amdgpu_device *adev = ring->adev;
425         struct amdgpu_bo *bo = NULL;
426         uint32_t *msg;
427         int r, i;
428
429         r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
430                                       AMDGPU_GEM_DOMAIN_VRAM,
431                                       &bo, NULL, (void **)&msg);
432         if (r)
433                 return r;
434
435         msg[0] = cpu_to_le32(0x00000028);
436         msg[1] = cpu_to_le32(0x00000018);
437         msg[2] = cpu_to_le32(0x00000000);
438         msg[3] = cpu_to_le32(0x00000002);
439         msg[4] = cpu_to_le32(handle);
440         msg[5] = cpu_to_le32(0x00000000);
441         for (i = 6; i < 1024; ++i)
442                 msg[i] = cpu_to_le32(0x0);
443
444         return amdgpu_vcn_dec_send_msg(ring, bo, fence);
445 }
446
447 int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
448 {
449         struct dma_fence *fence;
450         long r;
451
452         r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL);
453         if (r)
454                 goto error;
455
456         r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence);
457         if (r)
458                 goto error;
459
460         r = dma_fence_wait_timeout(fence, false, timeout);
461         if (r == 0)
462                 r = -ETIMEDOUT;
463         else if (r > 0)
464                 r = 0;
465
466         dma_fence_put(fence);
467 error:
468         return r;
469 }
470
471 int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
472 {
473         struct amdgpu_device *adev = ring->adev;
474         uint32_t rptr;
475         unsigned i;
476         int r;
477
478         r = amdgpu_ring_alloc(ring, 16);
479         if (r)
480                 return r;
481
482         rptr = amdgpu_ring_get_rptr(ring);
483
484         amdgpu_ring_write(ring, VCN_ENC_CMD_END);
485         amdgpu_ring_commit(ring);
486
487         for (i = 0; i < adev->usec_timeout; i++) {
488                 if (amdgpu_ring_get_rptr(ring) != rptr)
489                         break;
490                 DRM_UDELAY(1);
491         }
492
493         if (i >= adev->usec_timeout)
494                 r = -ETIMEDOUT;
495
496         return r;
497 }
498
499 static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
500                               struct dma_fence **fence)
501 {
502         const unsigned ib_size_dw = 16;
503         struct amdgpu_job *job;
504         struct amdgpu_ib *ib;
505         struct dma_fence *f = NULL;
506         uint64_t dummy;
507         int i, r;
508
509         r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
510         if (r)
511                 return r;
512
513         ib = &job->ibs[0];
514         dummy = ib->gpu_addr + 1024;
515
516         ib->length_dw = 0;
517         ib->ptr[ib->length_dw++] = 0x00000018;
518         ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
519         ib->ptr[ib->length_dw++] = handle;
520         ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
521         ib->ptr[ib->length_dw++] = dummy;
522         ib->ptr[ib->length_dw++] = 0x0000000b;
523
524         ib->ptr[ib->length_dw++] = 0x00000014;
525         ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
526         ib->ptr[ib->length_dw++] = 0x0000001c;
527         ib->ptr[ib->length_dw++] = 0x00000000;
528         ib->ptr[ib->length_dw++] = 0x00000000;
529
530         ib->ptr[ib->length_dw++] = 0x00000008;
531         ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */
532
533         for (i = ib->length_dw; i < ib_size_dw; ++i)
534                 ib->ptr[i] = 0x0;
535
536         r = amdgpu_job_submit_direct(job, ring, &f);
537         if (r)
538                 goto err;
539
540         if (fence)
541                 *fence = dma_fence_get(f);
542         dma_fence_put(f);
543
544         return 0;
545
546 err:
547         amdgpu_job_free(job);
548         return r;
549 }
550
551 static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
552                                 struct dma_fence **fence)
553 {
554         const unsigned ib_size_dw = 16;
555         struct amdgpu_job *job;
556         struct amdgpu_ib *ib;
557         struct dma_fence *f = NULL;
558         uint64_t dummy;
559         int i, r;
560
561         r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
562         if (r)
563                 return r;
564
565         ib = &job->ibs[0];
566         dummy = ib->gpu_addr + 1024;
567
568         ib->length_dw = 0;
569         ib->ptr[ib->length_dw++] = 0x00000018;
570         ib->ptr[ib->length_dw++] = 0x00000001;
571         ib->ptr[ib->length_dw++] = handle;
572         ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
573         ib->ptr[ib->length_dw++] = dummy;
574         ib->ptr[ib->length_dw++] = 0x0000000b;
575
576         ib->ptr[ib->length_dw++] = 0x00000014;
577         ib->ptr[ib->length_dw++] = 0x00000002;
578         ib->ptr[ib->length_dw++] = 0x0000001c;
579         ib->ptr[ib->length_dw++] = 0x00000000;
580         ib->ptr[ib->length_dw++] = 0x00000000;
581
582         ib->ptr[ib->length_dw++] = 0x00000008;
583         ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */
584
585         for (i = ib->length_dw; i < ib_size_dw; ++i)
586                 ib->ptr[i] = 0x0;
587
588         r = amdgpu_job_submit_direct(job, ring, &f);
589         if (r)
590                 goto err;
591
592         if (fence)
593                 *fence = dma_fence_get(f);
594         dma_fence_put(f);
595
596         return 0;
597
598 err:
599         amdgpu_job_free(job);
600         return r;
601 }
602
603 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
604 {
605         struct dma_fence *fence = NULL;
606         long r;
607
608         r = amdgpu_vcn_enc_get_create_msg(ring, 1, NULL);
609         if (r)
610                 goto error;
611
612         r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &fence);
613         if (r)
614                 goto error;
615
616         r = dma_fence_wait_timeout(fence, false, timeout);
617         if (r == 0)
618                 r = -ETIMEDOUT;
619         else if (r > 0)
620                 r = 0;
621
622 error:
623         dma_fence_put(fence);
624         return r;
625 }
626
627 int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring)
628 {
629         struct amdgpu_device *adev = ring->adev;
630         uint32_t tmp = 0;
631         unsigned i;
632         int r;
633
634         WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD);
635         r = amdgpu_ring_alloc(ring, 3);
636
637         if (r)
638                 return r;
639
640         amdgpu_ring_write(ring,
641                 PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, 0));
642         amdgpu_ring_write(ring, 0xDEADBEEF);
643         amdgpu_ring_commit(ring);
644
645         for (i = 0; i < adev->usec_timeout; i++) {
646                 tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9));
647                 if (tmp == 0xDEADBEEF)
648                         break;
649                 DRM_UDELAY(1);
650         }
651
652         if (i >= adev->usec_timeout)
653                 r = -ETIMEDOUT;
654
655         return r;
656 }
657
658 static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring *ring, uint32_t handle,
659                 struct dma_fence **fence)
660 {
661         struct amdgpu_device *adev = ring->adev;
662         struct amdgpu_job *job;
663         struct amdgpu_ib *ib;
664         struct dma_fence *f = NULL;
665         const unsigned ib_size_dw = 16;
666         int i, r;
667
668         r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
669         if (r)
670                 return r;
671
672         ib = &job->ibs[0];
673
674         ib->ptr[0] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, PACKETJ_TYPE0);
675         ib->ptr[1] = 0xDEADBEEF;
676         for (i = 2; i < 16; i += 2) {
677                 ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
678                 ib->ptr[i+1] = 0;
679         }
680         ib->length_dw = 16;
681
682         r = amdgpu_job_submit_direct(job, ring, &f);
683         if (r)
684                 goto err;
685
686         if (fence)
687                 *fence = dma_fence_get(f);
688         dma_fence_put(f);
689
690         return 0;
691
692 err:
693         amdgpu_job_free(job);
694         return r;
695 }
696
697 int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout)
698 {
699         struct amdgpu_device *adev = ring->adev;
700         uint32_t tmp = 0;
701         unsigned i;
702         struct dma_fence *fence = NULL;
703         long r = 0;
704
705         r = amdgpu_vcn_jpeg_set_reg(ring, 1, &fence);
706         if (r)
707                 goto error;
708
709         r = dma_fence_wait_timeout(fence, false, timeout);
710         if (r == 0) {
711                 r = -ETIMEDOUT;
712                 goto error;
713         } else if (r < 0) {
714                 goto error;
715         } else {
716                 r = 0;
717         }
718
719         for (i = 0; i < adev->usec_timeout; i++) {
720                 tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9));
721                 if (tmp == 0xDEADBEEF)
722                         break;
723                 DRM_UDELAY(1);
724         }
725
726         if (i >= adev->usec_timeout)
727                 r = -ETIMEDOUT;
728
729         dma_fence_put(fence);
730 error:
731         return r;
732 }