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