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