1 /* $NetBSD: radeon_uvd_v1_0.c,v 1.6 2021/12/19 00:25:04 riastradh Exp $ */
2
3 /*
4 * Copyright 2013 Advanced Micro Devices, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Christian König <christian.koenig@amd.com>
25 */
26
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: radeon_uvd_v1_0.c,v 1.6 2021/12/19 00:25:04 riastradh Exp $");
29
30 #include <linux/firmware.h>
31
32 #include "radeon.h"
33 #include "radeon_asic.h"
34 #include "r600d.h"
35
36 /**
37 * uvd_v1_0_get_rptr - get read pointer
38 *
39 * @rdev: radeon_device pointer
40 * @ring: radeon_ring pointer
41 *
42 * Returns the current hardware read pointer
43 */
uvd_v1_0_get_rptr(struct radeon_device * rdev,struct radeon_ring * ring)44 uint32_t uvd_v1_0_get_rptr(struct radeon_device *rdev,
45 struct radeon_ring *ring)
46 {
47 return RREG32(UVD_RBC_RB_RPTR);
48 }
49
50 /**
51 * uvd_v1_0_get_wptr - get write pointer
52 *
53 * @rdev: radeon_device pointer
54 * @ring: radeon_ring pointer
55 *
56 * Returns the current hardware write pointer
57 */
uvd_v1_0_get_wptr(struct radeon_device * rdev,struct radeon_ring * ring)58 uint32_t uvd_v1_0_get_wptr(struct radeon_device *rdev,
59 struct radeon_ring *ring)
60 {
61 return RREG32(UVD_RBC_RB_WPTR);
62 }
63
64 /**
65 * uvd_v1_0_set_wptr - set write pointer
66 *
67 * @rdev: radeon_device pointer
68 * @ring: radeon_ring pointer
69 *
70 * Commits the write pointer to the hardware
71 */
uvd_v1_0_set_wptr(struct radeon_device * rdev,struct radeon_ring * ring)72 void uvd_v1_0_set_wptr(struct radeon_device *rdev,
73 struct radeon_ring *ring)
74 {
75 WREG32(UVD_RBC_RB_WPTR, ring->wptr);
76 }
77
78 /**
79 * uvd_v1_0_fence_emit - emit an fence & trap command
80 *
81 * @rdev: radeon_device pointer
82 * @fence: fence to emit
83 *
84 * Write a fence and a trap command to the ring.
85 */
uvd_v1_0_fence_emit(struct radeon_device * rdev,struct radeon_fence * fence)86 void uvd_v1_0_fence_emit(struct radeon_device *rdev,
87 struct radeon_fence *fence)
88 {
89 struct radeon_ring *ring = &rdev->ring[fence->ring];
90 uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
91
92 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
93 radeon_ring_write(ring, addr & 0xffffffff);
94 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
95 radeon_ring_write(ring, fence->seq);
96 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
97 radeon_ring_write(ring, 0);
98
99 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
100 radeon_ring_write(ring, 0);
101 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
102 radeon_ring_write(ring, 0);
103 radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
104 radeon_ring_write(ring, 2);
105 return;
106 }
107
108 /**
109 * uvd_v1_0_resume - memory controller programming
110 *
111 * @rdev: radeon_device pointer
112 *
113 * Let the UVD memory controller know it's offsets
114 */
uvd_v1_0_resume(struct radeon_device * rdev)115 int uvd_v1_0_resume(struct radeon_device *rdev)
116 {
117 uint64_t addr;
118 uint32_t size;
119 int r;
120
121 r = radeon_uvd_resume(rdev);
122 if (r)
123 return r;
124
125 /* programm the VCPU memory controller bits 0-27 */
126 addr = (rdev->uvd.gpu_addr >> 3) + 16;
127 size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size) >> 3;
128 WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
129 WREG32(UVD_VCPU_CACHE_SIZE0, size);
130
131 addr += size;
132 size = RADEON_UVD_HEAP_SIZE >> 3;
133 WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
134 WREG32(UVD_VCPU_CACHE_SIZE1, size);
135
136 addr += size;
137 size = (RADEON_UVD_STACK_SIZE +
138 (RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3;
139 WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
140 WREG32(UVD_VCPU_CACHE_SIZE2, size);
141
142 /* bits 28-31 */
143 addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
144 WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
145
146 /* bits 32-39 */
147 addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
148 WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1U << 31));
149
150 WREG32(UVD_FW_START, *((uint32_t*)rdev->uvd.cpu_addr));
151
152 return 0;
153 }
154
155 /**
156 * uvd_v1_0_init - start and test UVD block
157 *
158 * @rdev: radeon_device pointer
159 *
160 * Initialize the hardware, boot up the VCPU and do some testing
161 */
uvd_v1_0_init(struct radeon_device * rdev)162 int uvd_v1_0_init(struct radeon_device *rdev)
163 {
164 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
165 uint32_t tmp;
166 int r;
167
168 /* raise clocks while booting up the VCPU */
169 if (rdev->family < CHIP_RV740)
170 radeon_set_uvd_clocks(rdev, 10000, 10000);
171 else
172 radeon_set_uvd_clocks(rdev, 53300, 40000);
173
174 r = uvd_v1_0_start(rdev);
175 if (r)
176 goto done;
177
178 ring->ready = true;
179 r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
180 if (r) {
181 ring->ready = false;
182 goto done;
183 }
184
185 r = radeon_ring_lock(rdev, ring, 10);
186 if (r) {
187 DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
188 goto done;
189 }
190
191 tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
192 radeon_ring_write(ring, tmp);
193 radeon_ring_write(ring, 0xFFFFF);
194
195 tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
196 radeon_ring_write(ring, tmp);
197 radeon_ring_write(ring, 0xFFFFF);
198
199 tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
200 radeon_ring_write(ring, tmp);
201 radeon_ring_write(ring, 0xFFFFF);
202
203 /* Clear timeout status bits */
204 radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
205 radeon_ring_write(ring, 0x8);
206
207 radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
208 radeon_ring_write(ring, 3);
209
210 radeon_ring_unlock_commit(rdev, ring, false);
211
212 done:
213 /* lower clocks again */
214 radeon_set_uvd_clocks(rdev, 0, 0);
215
216 if (!r) {
217 switch (rdev->family) {
218 case CHIP_RV610:
219 case CHIP_RV630:
220 case CHIP_RV620:
221 /* 64byte granularity workaround */
222 WREG32(MC_CONFIG, 0);
223 WREG32(MC_CONFIG, 1 << 4);
224 WREG32(RS_DQ_RD_RET_CONF, 0x3f);
225 WREG32(MC_CONFIG, 0x1f);
226
227 /* fall through */
228 case CHIP_RV670:
229 case CHIP_RV635:
230
231 /* write clean workaround */
232 WREG32_P(UVD_VCPU_CNTL, 0x10, ~0x10);
233 break;
234
235 default:
236 /* TODO: Do we need more? */
237 break;
238 }
239
240 DRM_INFO("UVD initialized successfully.\n");
241 }
242
243 return r;
244 }
245
246 /**
247 * uvd_v1_0_fini - stop the hardware block
248 *
249 * @rdev: radeon_device pointer
250 *
251 * Stop the UVD block, mark ring as not ready any more
252 */
uvd_v1_0_fini(struct radeon_device * rdev)253 void uvd_v1_0_fini(struct radeon_device *rdev)
254 {
255 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
256
257 uvd_v1_0_stop(rdev);
258 ring->ready = false;
259 }
260
261 /**
262 * uvd_v1_0_start - start UVD block
263 *
264 * @rdev: radeon_device pointer
265 *
266 * Setup and start the UVD block
267 */
uvd_v1_0_start(struct radeon_device * rdev)268 int uvd_v1_0_start(struct radeon_device *rdev)
269 {
270 struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
271 uint32_t rb_bufsz;
272 int i, j, r;
273
274 /* disable byte swapping */
275 u32 lmi_swap_cntl = 0;
276 u32 mp_swap_cntl = 0;
277
278 /* disable clock gating */
279 WREG32(UVD_CGC_GATE, 0);
280
281 /* disable interupt */
282 WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
283
284 /* Stall UMC and register bus before resetting VCPU */
285 WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
286 WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
287 mdelay(1);
288
289 /* put LMI, VCPU, RBC etc... into reset */
290 WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
291 LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
292 CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET);
293 mdelay(5);
294
295 /* take UVD block out of reset */
296 WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD);
297 mdelay(5);
298
299 /* initialize UVD memory controller */
300 WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
301 (1 << 21) | (1 << 9) | (1 << 20));
302
303 #ifdef __BIG_ENDIAN
304 /* swap (8 in 32) RB and IB */
305 lmi_swap_cntl = 0xa;
306 mp_swap_cntl = 0;
307 #endif
308 WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl);
309 WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl);
310
311 WREG32(UVD_MPC_SET_MUXA0, 0x40c2040);
312 WREG32(UVD_MPC_SET_MUXA1, 0x0);
313 WREG32(UVD_MPC_SET_MUXB0, 0x40c2040);
314 WREG32(UVD_MPC_SET_MUXB1, 0x0);
315 WREG32(UVD_MPC_SET_ALU, 0);
316 WREG32(UVD_MPC_SET_MUX, 0x88);
317
318 /* take all subblocks out of reset, except VCPU */
319 WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
320 mdelay(5);
321
322 /* enable VCPU clock */
323 WREG32(UVD_VCPU_CNTL, 1 << 9);
324
325 /* enable UMC */
326 WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
327
328 WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
329
330 /* boot up the VCPU */
331 WREG32(UVD_SOFT_RESET, 0);
332 mdelay(10);
333
334 for (i = 0; i < 10; ++i) {
335 uint32_t status;
336 for (j = 0; j < 100; ++j) {
337 status = RREG32(UVD_STATUS);
338 if (status & 2)
339 break;
340 mdelay(10);
341 }
342 r = 0;
343 if (status & 2)
344 break;
345
346 DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
347 WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET);
348 mdelay(10);
349 WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET);
350 mdelay(10);
351 r = -1;
352 }
353
354 if (r) {
355 DRM_ERROR("UVD not responding, giving up!!!\n");
356 return r;
357 }
358
359 /* enable interupt */
360 WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
361
362 /* force RBC into idle state */
363 WREG32(UVD_RBC_RB_CNTL, 0x11010101);
364
365 /* Set the write pointer delay */
366 WREG32(UVD_RBC_RB_WPTR_CNTL, 0);
367
368 /* programm the 4GB memory segment for rptr and ring buffer */
369 WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) |
370 (0x7 << 16) | (0x1U << 31));
371
372 /* Initialize the ring buffer's read and write pointers */
373 WREG32(UVD_RBC_RB_RPTR, 0x0);
374
375 ring->wptr = RREG32(UVD_RBC_RB_RPTR);
376 WREG32(UVD_RBC_RB_WPTR, ring->wptr);
377
378 /* set the ring address */
379 WREG32(UVD_RBC_RB_BASE, ring->gpu_addr);
380
381 /* Set ring buffer size */
382 rb_bufsz = order_base_2(ring->ring_size);
383 rb_bufsz = (0x1 << 8) | rb_bufsz;
384 WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f);
385
386 return 0;
387 }
388
389 /**
390 * uvd_v1_0_stop - stop UVD block
391 *
392 * @rdev: radeon_device pointer
393 *
394 * stop the UVD block
395 */
uvd_v1_0_stop(struct radeon_device * rdev)396 void uvd_v1_0_stop(struct radeon_device *rdev)
397 {
398 /* force RBC into idle state */
399 WREG32(UVD_RBC_RB_CNTL, 0x11010101);
400
401 /* Stall UMC and register bus before resetting VCPU */
402 WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
403 WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
404 mdelay(1);
405
406 /* put VCPU into reset */
407 WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
408 mdelay(5);
409
410 /* disable VCPU clock */
411 WREG32(UVD_VCPU_CNTL, 0x0);
412
413 /* Unstall UMC and register bus */
414 WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
415 WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
416 }
417
418 /**
419 * uvd_v1_0_ring_test - register write test
420 *
421 * @rdev: radeon_device pointer
422 * @ring: radeon_ring pointer
423 *
424 * Test if we can successfully write to the context register
425 */
uvd_v1_0_ring_test(struct radeon_device * rdev,struct radeon_ring * ring)426 int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
427 {
428 uint32_t tmp = 0;
429 unsigned i;
430 int r;
431
432 WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD);
433 r = radeon_ring_lock(rdev, ring, 3);
434 if (r) {
435 DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n",
436 ring->idx, r);
437 return r;
438 }
439 radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
440 radeon_ring_write(ring, 0xDEADBEEF);
441 radeon_ring_unlock_commit(rdev, ring, false);
442 for (i = 0; i < rdev->usec_timeout; i++) {
443 tmp = RREG32(UVD_CONTEXT_ID);
444 if (tmp == 0xDEADBEEF)
445 break;
446 udelay(1);
447 }
448
449 if (i < rdev->usec_timeout) {
450 DRM_INFO("ring test on %d succeeded in %d usecs\n",
451 ring->idx, i);
452 } else {
453 DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
454 ring->idx, tmp);
455 r = -EINVAL;
456 }
457 return r;
458 }
459
460 /**
461 * uvd_v1_0_semaphore_emit - emit semaphore command
462 *
463 * @rdev: radeon_device pointer
464 * @ring: radeon_ring pointer
465 * @semaphore: semaphore to emit commands for
466 * @emit_wait: true if we should emit a wait command
467 *
468 * Emit a semaphore command (either wait or signal) to the UVD ring.
469 */
uvd_v1_0_semaphore_emit(struct radeon_device * rdev,struct radeon_ring * ring,struct radeon_semaphore * semaphore,bool emit_wait)470 bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
471 struct radeon_ring *ring,
472 struct radeon_semaphore *semaphore,
473 bool emit_wait)
474 {
475 /* disable semaphores for UVD V1 hardware */
476 return false;
477 }
478
479 /**
480 * uvd_v1_0_ib_execute - execute indirect buffer
481 *
482 * @rdev: radeon_device pointer
483 * @ib: indirect buffer to execute
484 *
485 * Write ring commands to execute the indirect buffer
486 */
uvd_v1_0_ib_execute(struct radeon_device * rdev,struct radeon_ib * ib)487 void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
488 {
489 struct radeon_ring *ring = &rdev->ring[ib->ring];
490
491 radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0));
492 radeon_ring_write(ring, ib->gpu_addr);
493 radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0));
494 radeon_ring_write(ring, ib->length_dw);
495 }
496
497 /**
498 * uvd_v1_0_ib_test - test ib execution
499 *
500 * @rdev: radeon_device pointer
501 * @ring: radeon_ring pointer
502 *
503 * Test if we can successfully execute an IB
504 */
uvd_v1_0_ib_test(struct radeon_device * rdev,struct radeon_ring * ring)505 int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
506 {
507 struct radeon_fence *fence = NULL;
508 int r;
509
510 if (rdev->family < CHIP_RV740)
511 r = radeon_set_uvd_clocks(rdev, 10000, 10000);
512 else
513 r = radeon_set_uvd_clocks(rdev, 53300, 40000);
514 if (r) {
515 DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
516 return r;
517 }
518
519 r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
520 if (r) {
521 DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
522 goto error;
523 }
524
525 r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence);
526 if (r) {
527 DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
528 goto error;
529 }
530
531 r = radeon_fence_wait_timeout(fence, false, usecs_to_jiffies(
532 RADEON_USEC_IB_TEST_TIMEOUT));
533 if (r < 0) {
534 DRM_ERROR("radeon: fence wait failed (%d).\n", r);
535 goto error;
536 } else if (r == 0) {
537 DRM_ERROR("radeon: fence wait timed out.\n");
538 r = -ETIMEDOUT;
539 goto error;
540 }
541 r = 0;
542 DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
543 error:
544 radeon_fence_unref(&fence);
545 radeon_set_uvd_clocks(rdev, 0, 0);
546 return r;
547 }
548