Line data Source code
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 <dev/pci/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 0 : uint32_t uvd_v1_0_get_rptr(struct radeon_device *rdev,
39 : struct radeon_ring *ring)
40 : {
41 0 : 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 0 : uint32_t uvd_v1_0_get_wptr(struct radeon_device *rdev,
53 : struct radeon_ring *ring)
54 : {
55 0 : 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 0 : void uvd_v1_0_set_wptr(struct radeon_device *rdev,
67 : struct radeon_ring *ring)
68 : {
69 0 : WREG32(UVD_RBC_RB_WPTR, ring->wptr);
70 0 : }
71 :
72 : /**
73 : * uvd_v1_0_fence_emit - emit an fence & trap command
74 : *
75 : * @rdev: radeon_device pointer
76 : * @fence: fence to emit
77 : *
78 : * Write a fence and a trap command to the ring.
79 : */
80 0 : void uvd_v1_0_fence_emit(struct radeon_device *rdev,
81 : struct radeon_fence *fence)
82 : {
83 0 : struct radeon_ring *ring = &rdev->ring[fence->ring];
84 0 : uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
85 :
86 0 : radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
87 0 : radeon_ring_write(ring, addr & 0xffffffff);
88 0 : radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
89 0 : radeon_ring_write(ring, fence->seq);
90 0 : radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
91 0 : radeon_ring_write(ring, 0);
92 :
93 0 : radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
94 0 : radeon_ring_write(ring, 0);
95 0 : radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
96 0 : radeon_ring_write(ring, 0);
97 0 : radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
98 0 : radeon_ring_write(ring, 2);
99 : return;
100 0 : }
101 :
102 : /**
103 : * uvd_v1_0_resume - memory controller programming
104 : *
105 : * @rdev: radeon_device pointer
106 : *
107 : * Let the UVD memory controller know it's offsets
108 : */
109 0 : int uvd_v1_0_resume(struct radeon_device *rdev)
110 : {
111 : uint64_t addr;
112 : uint32_t size;
113 : int r;
114 :
115 0 : r = radeon_uvd_resume(rdev);
116 0 : if (r)
117 0 : return r;
118 :
119 : /* programm the VCPU memory controller bits 0-27 */
120 0 : addr = (rdev->uvd.gpu_addr >> 3) + 16;
121 0 : size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size) >> 3;
122 0 : WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
123 0 : WREG32(UVD_VCPU_CACHE_SIZE0, size);
124 :
125 0 : addr += size;
126 : size = RADEON_UVD_STACK_SIZE >> 3;
127 0 : WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
128 0 : WREG32(UVD_VCPU_CACHE_SIZE1, size);
129 :
130 0 : addr += size;
131 : size = RADEON_UVD_HEAP_SIZE >> 3;
132 0 : WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
133 0 : WREG32(UVD_VCPU_CACHE_SIZE2, size);
134 :
135 : /* bits 28-31 */
136 0 : addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
137 0 : WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
138 :
139 : /* bits 32-39 */
140 0 : addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
141 0 : WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
142 :
143 0 : WREG32(UVD_FW_START, *((uint32_t*)rdev->uvd.cpu_addr));
144 :
145 0 : return 0;
146 0 : }
147 :
148 : /**
149 : * uvd_v1_0_init - start and test UVD block
150 : *
151 : * @rdev: radeon_device pointer
152 : *
153 : * Initialize the hardware, boot up the VCPU and do some testing
154 : */
155 0 : int uvd_v1_0_init(struct radeon_device *rdev)
156 : {
157 0 : struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
158 : uint32_t tmp;
159 : int r;
160 :
161 : /* raise clocks while booting up the VCPU */
162 0 : if (rdev->family < CHIP_RV740)
163 0 : radeon_set_uvd_clocks(rdev, 10000, 10000);
164 : else
165 0 : radeon_set_uvd_clocks(rdev, 53300, 40000);
166 :
167 0 : r = uvd_v1_0_start(rdev);
168 0 : if (r)
169 : goto done;
170 :
171 0 : ring->ready = true;
172 0 : r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
173 0 : if (r) {
174 0 : ring->ready = false;
175 0 : goto done;
176 : }
177 :
178 0 : r = radeon_ring_lock(rdev, ring, 10);
179 0 : if (r) {
180 0 : DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
181 0 : goto done;
182 : }
183 :
184 : tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
185 0 : radeon_ring_write(ring, tmp);
186 0 : radeon_ring_write(ring, 0xFFFFF);
187 :
188 : tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
189 0 : radeon_ring_write(ring, tmp);
190 0 : radeon_ring_write(ring, 0xFFFFF);
191 :
192 : tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
193 0 : radeon_ring_write(ring, tmp);
194 0 : radeon_ring_write(ring, 0xFFFFF);
195 :
196 : /* Clear timeout status bits */
197 0 : radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
198 0 : radeon_ring_write(ring, 0x8);
199 :
200 0 : radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
201 0 : radeon_ring_write(ring, 3);
202 :
203 0 : radeon_ring_unlock_commit(rdev, ring, false);
204 :
205 : done:
206 : /* lower clocks again */
207 0 : radeon_set_uvd_clocks(rdev, 0, 0);
208 :
209 0 : if (!r) {
210 0 : switch (rdev->family) {
211 : case CHIP_RV610:
212 : case CHIP_RV630:
213 : case CHIP_RV620:
214 : /* 64byte granularity workaround */
215 0 : WREG32(MC_CONFIG, 0);
216 0 : WREG32(MC_CONFIG, 1 << 4);
217 0 : WREG32(RS_DQ_RD_RET_CONF, 0x3f);
218 0 : WREG32(MC_CONFIG, 0x1f);
219 :
220 : /* fall through */
221 : case CHIP_RV670:
222 : case CHIP_RV635:
223 :
224 : /* write clean workaround */
225 0 : WREG32_P(UVD_VCPU_CNTL, 0x10, ~0x10);
226 0 : break;
227 :
228 : default:
229 : /* TODO: Do we need more? */
230 : break;
231 : }
232 :
233 : DRM_INFO("UVD initialized successfully.\n");
234 : }
235 :
236 0 : return r;
237 : }
238 :
239 : /**
240 : * uvd_v1_0_fini - stop the hardware block
241 : *
242 : * @rdev: radeon_device pointer
243 : *
244 : * Stop the UVD block, mark ring as not ready any more
245 : */
246 0 : void uvd_v1_0_fini(struct radeon_device *rdev)
247 : {
248 0 : struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
249 :
250 0 : uvd_v1_0_stop(rdev);
251 0 : ring->ready = false;
252 0 : }
253 :
254 : /**
255 : * uvd_v1_0_start - start UVD block
256 : *
257 : * @rdev: radeon_device pointer
258 : *
259 : * Setup and start the UVD block
260 : */
261 0 : int uvd_v1_0_start(struct radeon_device *rdev)
262 : {
263 0 : struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
264 : uint32_t rb_bufsz;
265 : int i, j, r;
266 :
267 : /* disable byte swapping */
268 : u32 lmi_swap_cntl = 0;
269 : u32 mp_swap_cntl = 0;
270 :
271 : /* disable clock gating */
272 0 : WREG32(UVD_CGC_GATE, 0);
273 :
274 : /* disable interupt */
275 0 : WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
276 :
277 : /* Stall UMC and register bus before resetting VCPU */
278 0 : WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
279 0 : WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
280 0 : mdelay(1);
281 :
282 : /* put LMI, VCPU, RBC etc... into reset */
283 0 : WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
284 : LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
285 : CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET);
286 0 : mdelay(5);
287 :
288 : /* take UVD block out of reset */
289 0 : WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD);
290 0 : mdelay(5);
291 :
292 : /* initialize UVD memory controller */
293 0 : WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
294 : (1 << 21) | (1 << 9) | (1 << 20));
295 :
296 : #ifdef __BIG_ENDIAN
297 : /* swap (8 in 32) RB and IB */
298 : lmi_swap_cntl = 0xa;
299 : mp_swap_cntl = 0;
300 : #endif
301 0 : WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl);
302 0 : WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl);
303 :
304 0 : WREG32(UVD_MPC_SET_MUXA0, 0x40c2040);
305 0 : WREG32(UVD_MPC_SET_MUXA1, 0x0);
306 0 : WREG32(UVD_MPC_SET_MUXB0, 0x40c2040);
307 0 : WREG32(UVD_MPC_SET_MUXB1, 0x0);
308 0 : WREG32(UVD_MPC_SET_ALU, 0);
309 0 : WREG32(UVD_MPC_SET_MUX, 0x88);
310 :
311 : /* take all subblocks out of reset, except VCPU */
312 0 : WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
313 0 : mdelay(5);
314 :
315 : /* enable VCPU clock */
316 0 : WREG32(UVD_VCPU_CNTL, 1 << 9);
317 :
318 : /* enable UMC */
319 0 : WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
320 :
321 0 : WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
322 :
323 : /* boot up the VCPU */
324 0 : WREG32(UVD_SOFT_RESET, 0);
325 0 : mdelay(10);
326 :
327 0 : for (i = 0; i < 10; ++i) {
328 : uint32_t status;
329 0 : for (j = 0; j < 100; ++j) {
330 0 : status = RREG32(UVD_STATUS);
331 0 : if (status & 2)
332 : break;
333 0 : mdelay(10);
334 : }
335 : r = 0;
336 0 : if (status & 2)
337 0 : break;
338 :
339 0 : DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
340 0 : WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET);
341 0 : mdelay(10);
342 0 : WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET);
343 0 : mdelay(10);
344 : r = -1;
345 0 : }
346 :
347 0 : if (r) {
348 0 : DRM_ERROR("UVD not responding, giving up!!!\n");
349 0 : return r;
350 : }
351 :
352 : /* enable interupt */
353 0 : WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
354 :
355 : /* force RBC into idle state */
356 0 : WREG32(UVD_RBC_RB_CNTL, 0x11010101);
357 :
358 : /* Set the write pointer delay */
359 0 : WREG32(UVD_RBC_RB_WPTR_CNTL, 0);
360 :
361 : /* programm the 4GB memory segment for rptr and ring buffer */
362 0 : WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) |
363 : (0x7 << 16) | (0x1 << 31));
364 :
365 : /* Initialize the ring buffer's read and write pointers */
366 0 : WREG32(UVD_RBC_RB_RPTR, 0x0);
367 :
368 0 : ring->wptr = RREG32(UVD_RBC_RB_RPTR);
369 0 : WREG32(UVD_RBC_RB_WPTR, ring->wptr);
370 :
371 : /* set the ring address */
372 0 : WREG32(UVD_RBC_RB_BASE, ring->gpu_addr);
373 :
374 : /* Set ring buffer size */
375 0 : rb_bufsz = order_base_2(ring->ring_size);
376 0 : rb_bufsz = (0x1 << 8) | rb_bufsz;
377 0 : WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f);
378 :
379 0 : return 0;
380 0 : }
381 :
382 : /**
383 : * uvd_v1_0_stop - stop UVD block
384 : *
385 : * @rdev: radeon_device pointer
386 : *
387 : * stop the UVD block
388 : */
389 0 : void uvd_v1_0_stop(struct radeon_device *rdev)
390 : {
391 : /* force RBC into idle state */
392 0 : WREG32(UVD_RBC_RB_CNTL, 0x11010101);
393 :
394 : /* Stall UMC and register bus before resetting VCPU */
395 0 : WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
396 0 : WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
397 0 : mdelay(1);
398 :
399 : /* put VCPU into reset */
400 0 : WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
401 0 : mdelay(5);
402 :
403 : /* disable VCPU clock */
404 0 : WREG32(UVD_VCPU_CNTL, 0x0);
405 :
406 : /* Unstall UMC and register bus */
407 0 : WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
408 0 : WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
409 0 : }
410 :
411 : /**
412 : * uvd_v1_0_ring_test - register write test
413 : *
414 : * @rdev: radeon_device pointer
415 : * @ring: radeon_ring pointer
416 : *
417 : * Test if we can successfully write to the context register
418 : */
419 0 : int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
420 : {
421 : uint32_t tmp = 0;
422 : unsigned i;
423 : int r;
424 :
425 0 : WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD);
426 0 : r = radeon_ring_lock(rdev, ring, 3);
427 0 : if (r) {
428 0 : DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n",
429 : ring->idx, r);
430 0 : return r;
431 : }
432 0 : radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
433 0 : radeon_ring_write(ring, 0xDEADBEEF);
434 0 : radeon_ring_unlock_commit(rdev, ring, false);
435 0 : for (i = 0; i < rdev->usec_timeout; i++) {
436 0 : tmp = RREG32(UVD_CONTEXT_ID);
437 0 : if (tmp == 0xDEADBEEF)
438 : break;
439 0 : DRM_UDELAY(1);
440 : }
441 :
442 0 : if (i < rdev->usec_timeout) {
443 : DRM_INFO("ring test on %d succeeded in %d usecs\n",
444 : ring->idx, i);
445 : } else {
446 0 : DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
447 : ring->idx, tmp);
448 : r = -EINVAL;
449 : }
450 0 : return r;
451 0 : }
452 :
453 : /**
454 : * uvd_v1_0_semaphore_emit - emit semaphore command
455 : *
456 : * @rdev: radeon_device pointer
457 : * @ring: radeon_ring pointer
458 : * @semaphore: semaphore to emit commands for
459 : * @emit_wait: true if we should emit a wait command
460 : *
461 : * Emit a semaphore command (either wait or signal) to the UVD ring.
462 : */
463 0 : bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
464 : struct radeon_ring *ring,
465 : struct radeon_semaphore *semaphore,
466 : bool emit_wait)
467 : {
468 : /* disable semaphores for UVD V1 hardware */
469 0 : return false;
470 : }
471 :
472 : /**
473 : * uvd_v1_0_ib_execute - execute indirect buffer
474 : *
475 : * @rdev: radeon_device pointer
476 : * @ib: indirect buffer to execute
477 : *
478 : * Write ring commands to execute the indirect buffer
479 : */
480 0 : void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
481 : {
482 0 : struct radeon_ring *ring = &rdev->ring[ib->ring];
483 :
484 0 : radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0));
485 0 : radeon_ring_write(ring, ib->gpu_addr);
486 0 : radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0));
487 0 : radeon_ring_write(ring, ib->length_dw);
488 0 : }
489 :
490 : /**
491 : * uvd_v1_0_ib_test - test ib execution
492 : *
493 : * @rdev: radeon_device pointer
494 : * @ring: radeon_ring pointer
495 : *
496 : * Test if we can successfully execute an IB
497 : */
498 0 : int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
499 : {
500 0 : struct radeon_fence *fence = NULL;
501 : int r;
502 :
503 0 : if (rdev->family < CHIP_RV740)
504 0 : r = radeon_set_uvd_clocks(rdev, 10000, 10000);
505 : else
506 0 : r = radeon_set_uvd_clocks(rdev, 53300, 40000);
507 0 : if (r) {
508 0 : DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
509 0 : return r;
510 : }
511 :
512 0 : r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
513 0 : if (r) {
514 0 : DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
515 0 : goto error;
516 : }
517 :
518 0 : r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence);
519 0 : if (r) {
520 0 : DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
521 0 : goto error;
522 : }
523 :
524 0 : r = radeon_fence_wait(fence, false);
525 0 : if (r) {
526 0 : DRM_ERROR("radeon: fence wait failed (%d).\n", r);
527 0 : goto error;
528 : }
529 : DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
530 : error:
531 0 : radeon_fence_unref(&fence);
532 0 : radeon_set_uvd_clocks(rdev, 0, 0);
533 0 : return r;
534 0 : }
|