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