xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/radeon/radeon_uvd_v1_0.c (revision d30a51c8d8d00c17dc8adad6bab3fe34c0fe15a5)
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