Merge branch 'vendor/XZ'
[dragonfly.git] / sys / dev / drm / radeon / uvd_v1_0.c
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         if (rdev->family < CHIP_RV740)
87                 radeon_set_uvd_clocks(rdev, 10000, 10000);
88         else
89                 radeon_set_uvd_clocks(rdev, 53300, 40000);
90
91         r = uvd_v1_0_start(rdev);
92         if (r)
93                 goto done;
94
95         ring->ready = true;
96         r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
97         if (r) {
98                 ring->ready = false;
99                 goto done;
100         }
101
102         r = radeon_ring_lock(rdev, ring, 10);
103         if (r) {
104                 DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
105                 goto done;
106         }
107
108         tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
109         radeon_ring_write(ring, tmp);
110         radeon_ring_write(ring, 0xFFFFF);
111
112         tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
113         radeon_ring_write(ring, tmp);
114         radeon_ring_write(ring, 0xFFFFF);
115
116         tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
117         radeon_ring_write(ring, tmp);
118         radeon_ring_write(ring, 0xFFFFF);
119
120         /* Clear timeout status bits */
121         radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
122         radeon_ring_write(ring, 0x8);
123
124         radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
125         radeon_ring_write(ring, 3);
126
127         radeon_ring_unlock_commit(rdev, ring, false);
128
129 done:
130         /* lower clocks again */
131         radeon_set_uvd_clocks(rdev, 0, 0);
132
133         if (!r)
134                 DRM_INFO("UVD initialized successfully.\n");
135
136         return r;
137 }
138
139 /**
140  * uvd_v1_0_fini - stop the hardware block
141  *
142  * @rdev: radeon_device pointer
143  *
144  * Stop the UVD block, mark ring as not ready any more
145  */
146 void uvd_v1_0_fini(struct radeon_device *rdev)
147 {
148         struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
149
150         uvd_v1_0_stop(rdev);
151         ring->ready = false;
152 }
153
154 /**
155  * uvd_v1_0_start - start UVD block
156  *
157  * @rdev: radeon_device pointer
158  *
159  * Setup and start the UVD block
160  */
161 int uvd_v1_0_start(struct radeon_device *rdev)
162 {
163         struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
164         uint32_t rb_bufsz;
165         int i, j, r;
166
167         /* disable byte swapping */
168         u32 lmi_swap_cntl = 0;
169         u32 mp_swap_cntl = 0;
170
171         /* disable clock gating */
172         WREG32(UVD_CGC_GATE, 0);
173
174         /* disable interupt */
175         WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
176
177         /* Stall UMC and register bus before resetting VCPU */
178         WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
179         WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
180         mdelay(1);
181
182         /* put LMI, VCPU, RBC etc... into reset */
183         WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
184                LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
185                CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET);
186         mdelay(5);
187
188         /* take UVD block out of reset */
189         WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD);
190         mdelay(5);
191
192         /* initialize UVD memory controller */
193         WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
194                              (1 << 21) | (1 << 9) | (1 << 20));
195
196 #ifdef __BIG_ENDIAN
197         /* swap (8 in 32) RB and IB */
198         lmi_swap_cntl = 0xa;
199         mp_swap_cntl = 0;
200 #endif
201         WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl);
202         WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl);
203
204         WREG32(UVD_MPC_SET_MUXA0, 0x40c2040);
205         WREG32(UVD_MPC_SET_MUXA1, 0x0);
206         WREG32(UVD_MPC_SET_MUXB0, 0x40c2040);
207         WREG32(UVD_MPC_SET_MUXB1, 0x0);
208         WREG32(UVD_MPC_SET_ALU, 0);
209         WREG32(UVD_MPC_SET_MUX, 0x88);
210
211         /* take all subblocks out of reset, except VCPU */
212         WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
213         mdelay(5);
214
215         /* enable VCPU clock */
216         WREG32(UVD_VCPU_CNTL,  1 << 9);
217
218         /* enable UMC */
219         WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
220
221         /* boot up the VCPU */
222         WREG32(UVD_SOFT_RESET, 0);
223         mdelay(10);
224
225         WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
226
227         for (i = 0; i < 10; ++i) {
228                 uint32_t status;
229                 for (j = 0; j < 100; ++j) {
230                         status = RREG32(UVD_STATUS);
231                         if (status & 2)
232                                 break;
233                         mdelay(10);
234                 }
235                 r = 0;
236                 if (status & 2)
237                         break;
238
239                 DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
240                 WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET);
241                 mdelay(10);
242                 WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET);
243                 mdelay(10);
244                 r = -1;
245         }
246
247         if (r) {
248                 DRM_ERROR("UVD not responding, giving up!!!\n");
249                 return r;
250         }
251
252         /* enable interupt */
253         WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
254
255         /* force RBC into idle state */
256         WREG32(UVD_RBC_RB_CNTL, 0x11010101);
257
258         /* Set the write pointer delay */
259         WREG32(UVD_RBC_RB_WPTR_CNTL, 0);
260
261         /* programm the 4GB memory segment for rptr and ring buffer */
262         WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) |
263                                    (0x7 << 16) | (0x1 << 31));
264
265         /* Initialize the ring buffer's read and write pointers */
266         WREG32(UVD_RBC_RB_RPTR, 0x0);
267
268         ring->wptr = RREG32(UVD_RBC_RB_RPTR);
269         WREG32(UVD_RBC_RB_WPTR, ring->wptr);
270
271         /* set the ring address */
272         WREG32(UVD_RBC_RB_BASE, ring->gpu_addr);
273
274         /* Set ring buffer size */
275         rb_bufsz = order_base_2(ring->ring_size);
276         rb_bufsz = (0x1 << 8) | rb_bufsz;
277         WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f);
278
279         return 0;
280 }
281
282 /**
283  * uvd_v1_0_stop - stop UVD block
284  *
285  * @rdev: radeon_device pointer
286  *
287  * stop the UVD block
288  */
289 void uvd_v1_0_stop(struct radeon_device *rdev)
290 {
291         /* force RBC into idle state */
292         WREG32(UVD_RBC_RB_CNTL, 0x11010101);
293
294         /* Stall UMC and register bus before resetting VCPU */
295         WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
296         WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
297         mdelay(1);
298
299         /* put VCPU into reset */
300         WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
301         mdelay(5);
302
303         /* disable VCPU clock */
304         WREG32(UVD_VCPU_CNTL, 0x0);
305
306         /* Unstall UMC and register bus */
307         WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
308         WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
309 }
310
311 /**
312  * uvd_v1_0_ring_test - register write test
313  *
314  * @rdev: radeon_device pointer
315  * @ring: radeon_ring pointer
316  *
317  * Test if we can successfully write to the context register
318  */
319 int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
320 {
321         uint32_t tmp = 0;
322         unsigned i;
323         int r;
324
325         WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD);
326         r = radeon_ring_lock(rdev, ring, 3);
327         if (r) {
328                 DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n",
329                           ring->idx, r);
330                 return r;
331         }
332         radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
333         radeon_ring_write(ring, 0xDEADBEEF);
334         radeon_ring_unlock_commit(rdev, ring, false);
335         for (i = 0; i < rdev->usec_timeout; i++) {
336                 tmp = RREG32(UVD_CONTEXT_ID);
337                 if (tmp == 0xDEADBEEF)
338                         break;
339                 DRM_UDELAY(1);
340         }
341
342         if (i < rdev->usec_timeout) {
343                 DRM_INFO("ring test on %d succeeded in %d usecs\n",
344                          ring->idx, i);
345         } else {
346                 DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
347                           ring->idx, tmp);
348                 r = -EINVAL;
349         }
350         return r;
351 }
352
353 /**
354  * uvd_v1_0_semaphore_emit - emit semaphore command
355  *
356  * @rdev: radeon_device pointer
357  * @ring: radeon_ring pointer
358  * @semaphore: semaphore to emit commands for
359  * @emit_wait: true if we should emit a wait command
360  *
361  * Emit a semaphore command (either wait or signal) to the UVD ring.
362  */
363 bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
364                              struct radeon_ring *ring,
365                              struct radeon_semaphore *semaphore,
366                              bool emit_wait)
367 {
368         uint64_t addr = semaphore->gpu_addr;
369
370         radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
371         radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
372
373         radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
374         radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
375
376         radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
377         radeon_ring_write(ring, emit_wait ? 1 : 0);
378
379         return true;
380 }
381
382 /**
383  * uvd_v1_0_ib_execute - execute indirect buffer
384  *
385  * @rdev: radeon_device pointer
386  * @ib: indirect buffer to execute
387  *
388  * Write ring commands to execute the indirect buffer
389  */
390 void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
391 {
392         struct radeon_ring *ring = &rdev->ring[ib->ring];
393
394         radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0));
395         radeon_ring_write(ring, ib->gpu_addr);
396         radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0));
397         radeon_ring_write(ring, ib->length_dw);
398 }
399
400 /**
401  * uvd_v1_0_ib_test - test ib execution
402  *
403  * @rdev: radeon_device pointer
404  * @ring: radeon_ring pointer
405  *
406  * Test if we can successfully execute an IB
407  */
408 int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
409 {
410         struct radeon_fence *fence = NULL;
411         int r;
412
413         if (rdev->family < CHIP_RV740)
414                 r = radeon_set_uvd_clocks(rdev, 10000, 10000);
415         else
416                 r = radeon_set_uvd_clocks(rdev, 53300, 40000);
417         if (r) {
418                 DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
419                 return r;
420         }
421
422         r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
423         if (r) {
424                 DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
425                 goto error;
426         }
427
428         r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence);
429         if (r) {
430                 DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
431                 goto error;
432         }
433
434         r = radeon_fence_wait(fence, false);
435         if (r) {
436                 DRM_ERROR("radeon: fence wait failed (%d).\n", r);
437                 goto error;
438         }
439         DRM_INFO("ib test on ring %d succeeded\n",  ring->idx);
440 error:
441         radeon_fence_unref(&fence);
442         radeon_set_uvd_clocks(rdev, 0, 0);
443         return r;
444 }