Subversion Repositories Kolibri OS

Rev

Rev 5078 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5078 serge 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 
23
 */
24
 
25
#include 
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
/**
5271 serge 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
void uvd_v1_0_fence_emit(struct radeon_device *rdev,
81
			 struct radeon_fence *fence)
82
{
83
	struct radeon_ring *ring = &rdev->ring[fence->ring];
84
	uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
85
 
86
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
87
	radeon_ring_write(ring, addr & 0xffffffff);
88
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
89
	radeon_ring_write(ring, fence->seq);
90
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
91
	radeon_ring_write(ring, 0);
92
 
93
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
94
	radeon_ring_write(ring, 0);
95
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
96
	radeon_ring_write(ring, 0);
97
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
98
	radeon_ring_write(ring, 2);
99
	return;
100
}
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
int uvd_v1_0_resume(struct radeon_device *rdev)
110
{
111
	uint64_t addr;
112
	uint32_t size;
113
	int r;
114
 
115
	r = radeon_uvd_resume(rdev);
116
	if (r)
117
		return r;
118
 
119
	/* programm the VCPU memory controller bits 0-27 */
120
	addr = (rdev->uvd.gpu_addr >> 3) + 16;
121
	size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size) >> 3;
122
	WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
123
	WREG32(UVD_VCPU_CACHE_SIZE0, size);
124
 
125
	addr += size;
126
	size = RADEON_UVD_STACK_SIZE >> 3;
127
	WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
128
	WREG32(UVD_VCPU_CACHE_SIZE1, size);
129
 
130
	addr += size;
131
	size = RADEON_UVD_HEAP_SIZE >> 3;
132
	WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
133
	WREG32(UVD_VCPU_CACHE_SIZE2, size);
134
 
135
	/* bits 28-31 */
136
	addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
137
	WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
138
 
139
	/* bits 32-39 */
140
	addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
141
	WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
142
 
143
	WREG32(UVD_FW_START, *((uint32_t*)rdev->uvd.cpu_addr));
144
 
145
	return 0;
146
}
147
 
148
/**
5078 serge 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
int uvd_v1_0_init(struct radeon_device *rdev)
156
{
157
	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
	if (rdev->family < CHIP_RV740)
163
		radeon_set_uvd_clocks(rdev, 10000, 10000);
164
	else
165
		radeon_set_uvd_clocks(rdev, 53300, 40000);
166
 
167
	r = uvd_v1_0_start(rdev);
168
	if (r)
169
		goto done;
170
 
171
	ring->ready = true;
172
	r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
173
	if (r) {
174
		ring->ready = false;
175
		goto done;
176
	}
177
 
178
	r = radeon_ring_lock(rdev, ring, 10);
179
	if (r) {
180
		DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
181
		goto done;
182
	}
183
 
184
	tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
185
	radeon_ring_write(ring, tmp);
186
	radeon_ring_write(ring, 0xFFFFF);
187
 
188
	tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
189
	radeon_ring_write(ring, tmp);
190
	radeon_ring_write(ring, 0xFFFFF);
191
 
192
	tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
193
	radeon_ring_write(ring, tmp);
194
	radeon_ring_write(ring, 0xFFFFF);
195
 
196
	/* Clear timeout status bits */
197
	radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
198
	radeon_ring_write(ring, 0x8);
199
 
200
	radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
201
	radeon_ring_write(ring, 3);
202
 
203
	radeon_ring_unlock_commit(rdev, ring, false);
204
 
205
done:
206
	/* lower clocks again */
207
	radeon_set_uvd_clocks(rdev, 0, 0);
208
 
5271 serge 209
	if (!r) {
210
		switch (rdev->family) {
211
		case CHIP_RV610:
212
		case CHIP_RV630:
213
		case CHIP_RV620:
214
			/* 64byte granularity workaround */
215
			WREG32(MC_CONFIG, 0);
216
			WREG32(MC_CONFIG, 1 << 4);
217
			WREG32(RS_DQ_RD_RET_CONF, 0x3f);
218
			WREG32(MC_CONFIG, 0x1f);
219
 
220
			/* fall through */
221
		case CHIP_RV670:
222
		case CHIP_RV635:
223
 
224
			/* write clean workaround */
225
			WREG32_P(UVD_VCPU_CNTL, 0x10, ~0x10);
226
			break;
227
 
228
		default:
229
			/* TODO: Do we need more? */
230
			break;
231
		}
232
 
5078 serge 233
		DRM_INFO("UVD initialized successfully.\n");
5271 serge 234
	}
5078 serge 235
 
236
	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
void uvd_v1_0_fini(struct radeon_device *rdev)
247
{
248
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
249
 
250
	uvd_v1_0_stop(rdev);
251
	ring->ready = false;
252
}
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
int uvd_v1_0_start(struct radeon_device *rdev)
262
{
263
	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
	WREG32(UVD_CGC_GATE, 0);
273
 
274
	/* disable interupt */
275
	WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
276
 
277
	/* Stall UMC and register bus before resetting VCPU */
278
	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
279
	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
280
	mdelay(1);
281
 
282
	/* put LMI, VCPU, RBC etc... into reset */
283
	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
	mdelay(5);
287
 
288
	/* take UVD block out of reset */
289
	WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD);
290
	mdelay(5);
291
 
292
	/* initialize UVD memory controller */
293
	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
	WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl);
302
	WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl);
303
 
304
	WREG32(UVD_MPC_SET_MUXA0, 0x40c2040);
305
	WREG32(UVD_MPC_SET_MUXA1, 0x0);
306
	WREG32(UVD_MPC_SET_MUXB0, 0x40c2040);
307
	WREG32(UVD_MPC_SET_MUXB1, 0x0);
308
	WREG32(UVD_MPC_SET_ALU, 0);
309
	WREG32(UVD_MPC_SET_MUX, 0x88);
310
 
311
	/* take all subblocks out of reset, except VCPU */
312
	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
313
	mdelay(5);
314
 
315
	/* enable VCPU clock */
316
	WREG32(UVD_VCPU_CNTL,  1 << 9);
317
 
318
	/* enable UMC */
319
	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
320
 
5271 serge 321
	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
322
 
5078 serge 323
	/* boot up the VCPU */
324
	WREG32(UVD_SOFT_RESET, 0);
325
	mdelay(10);
326
 
327
	for (i = 0; i < 10; ++i) {
328
		uint32_t status;
329
		for (j = 0; j < 100; ++j) {
330
			status = RREG32(UVD_STATUS);
331
			if (status & 2)
332
				break;
333
			mdelay(10);
334
		}
335
		r = 0;
336
		if (status & 2)
337
			break;
338
 
339
		DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
340
		WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET);
341
		mdelay(10);
342
		WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET);
343
		mdelay(10);
344
		r = -1;
345
	}
346
 
347
	if (r) {
348
		DRM_ERROR("UVD not responding, giving up!!!\n");
349
		return r;
350
	}
351
 
352
	/* enable interupt */
353
	WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
354
 
355
	/* force RBC into idle state */
356
	WREG32(UVD_RBC_RB_CNTL, 0x11010101);
357
 
358
	/* Set the write pointer delay */
359
	WREG32(UVD_RBC_RB_WPTR_CNTL, 0);
360
 
361
	/* programm the 4GB memory segment for rptr and ring buffer */
362
	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
	WREG32(UVD_RBC_RB_RPTR, 0x0);
367
 
368
	ring->wptr = RREG32(UVD_RBC_RB_RPTR);
369
	WREG32(UVD_RBC_RB_WPTR, ring->wptr);
370
 
371
	/* set the ring address */
372
	WREG32(UVD_RBC_RB_BASE, ring->gpu_addr);
373
 
374
	/* Set ring buffer size */
375
	rb_bufsz = order_base_2(ring->ring_size);
376
	rb_bufsz = (0x1 << 8) | rb_bufsz;
377
	WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f);
378
 
379
	return 0;
380
}
381
 
382
/**
383
 * uvd_v1_0_stop - stop UVD block
384
 *
385
 * @rdev: radeon_device pointer
386
 *
387
 * stop the UVD block
388
 */
389
void uvd_v1_0_stop(struct radeon_device *rdev)
390
{
391
	/* force RBC into idle state */
392
	WREG32(UVD_RBC_RB_CNTL, 0x11010101);
393
 
394
	/* Stall UMC and register bus before resetting VCPU */
395
	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
396
	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
397
	mdelay(1);
398
 
399
	/* put VCPU into reset */
400
	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
401
	mdelay(5);
402
 
403
	/* disable VCPU clock */
404
	WREG32(UVD_VCPU_CNTL, 0x0);
405
 
406
	/* Unstall UMC and register bus */
407
	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
408
	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
409
}
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
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
	WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD);
426
	r = radeon_ring_lock(rdev, ring, 3);
427
	if (r) {
428
		DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n",
429
			  ring->idx, r);
430
		return r;
431
	}
432
	radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
433
	radeon_ring_write(ring, 0xDEADBEEF);
434
	radeon_ring_unlock_commit(rdev, ring, false);
435
	for (i = 0; i < rdev->usec_timeout; i++) {
436
		tmp = RREG32(UVD_CONTEXT_ID);
437
		if (tmp == 0xDEADBEEF)
438
			break;
439
		DRM_UDELAY(1);
440
	}
441
 
442
	if (i < rdev->usec_timeout) {
443
		DRM_INFO("ring test on %d succeeded in %d usecs\n",
444
			 ring->idx, i);
445
	} else {
446
		DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
447
			  ring->idx, tmp);
448
		r = -EINVAL;
449
	}
450
	return r;
451
}
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
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
	uint64_t addr = semaphore->gpu_addr;
469
 
470
	radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
471
	radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
472
 
473
	radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
474
	radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
475
 
476
	radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
477
	radeon_ring_write(ring, emit_wait ? 1 : 0);
478
 
479
	return true;
480
}
481
 
482
/**
483
 * uvd_v1_0_ib_execute - execute indirect buffer
484
 *
485
 * @rdev: radeon_device pointer
486
 * @ib: indirect buffer to execute
487
 *
488
 * Write ring commands to execute the indirect buffer
489
 */
490
void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
491
{
492
	struct radeon_ring *ring = &rdev->ring[ib->ring];
493
 
494
	radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0));
495
	radeon_ring_write(ring, ib->gpu_addr);
496
	radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0));
497
	radeon_ring_write(ring, ib->length_dw);
498
}
499
 
500
/**
501
 * uvd_v1_0_ib_test - test ib execution
502
 *
503
 * @rdev: radeon_device pointer
504
 * @ring: radeon_ring pointer
505
 *
506
 * Test if we can successfully execute an IB
507
 */
508
int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
509
{
510
	struct radeon_fence *fence = NULL;
511
	int r;
512
 
513
	if (rdev->family < CHIP_RV740)
514
		r = radeon_set_uvd_clocks(rdev, 10000, 10000);
515
	else
516
		r = radeon_set_uvd_clocks(rdev, 53300, 40000);
517
	if (r) {
518
		DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
519
		return r;
520
	}
521
 
522
	r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
523
	if (r) {
524
		DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
525
		goto error;
526
	}
527
 
528
	r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence);
529
	if (r) {
530
		DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
531
		goto error;
532
	}
533
 
534
	r = radeon_fence_wait(fence, false);
535
	if (r) {
536
		DRM_ERROR("radeon: fence wait failed (%d).\n", r);
537
		goto error;
538
	}
539
	DRM_INFO("ib test on ring %d succeeded\n",  ring->idx);
540
error:
541
	radeon_fence_unref(&fence);
542
	radeon_set_uvd_clocks(rdev, 0, 0);
543
	return r;
544
}