Subversion Repositories Kolibri OS

Rev

Rev 5271 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5271 Rev 6104
Line 38... Line 38...
38
 
38
 
39
/* 1 second timeout */
39
/* 1 second timeout */
Line 40... Line 40...
40
#define UVD_IDLE_TIMEOUT_MS	1000
40
#define UVD_IDLE_TIMEOUT_MS	1000
-
 
41
 
-
 
42
/* Firmware Names */
-
 
43
#define FIRMWARE_R600		"radeon/R600_uvd.bin"
41
 
44
#define FIRMWARE_RS780		"radeon/RS780_uvd.bin"
42
/* Firmware Names */
45
#define FIRMWARE_RV770		"radeon/RV770_uvd.bin"
43
#define FIRMWARE_RV710		"radeon/RV710_uvd.bin"
46
#define FIRMWARE_RV710		"radeon/RV710_uvd.bin"
44
#define FIRMWARE_CYPRESS	"radeon/CYPRESS_uvd.bin"
47
#define FIRMWARE_CYPRESS	"radeon/CYPRESS_uvd.bin"
45
#define FIRMWARE_SUMO		"radeon/SUMO_uvd.bin"
48
#define FIRMWARE_SUMO		"radeon/SUMO_uvd.bin"
Line 64... Line 67...
64
	int i, r;
67
	int i, r;
Line 65... Line 68...
65
 
68
 
Line 66... Line 69...
66
//   INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler);
69
//   INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler);
-
 
70
 
-
 
71
	switch (rdev->family) {
-
 
72
	case CHIP_RV610:
-
 
73
	case CHIP_RV630:
-
 
74
	case CHIP_RV670:
-
 
75
	case CHIP_RV620:
-
 
76
	case CHIP_RV635:
-
 
77
		fw_name = FIRMWARE_R600;
-
 
78
		break;
-
 
79
 
-
 
80
	case CHIP_RS780:
-
 
81
	case CHIP_RS880:
-
 
82
		fw_name = FIRMWARE_RS780;
-
 
83
		break;
-
 
84
 
-
 
85
	case CHIP_RV770:
-
 
86
		fw_name = FIRMWARE_RV770;
67
 
87
		break;
68
	switch (rdev->family) {
88
 
69
	case CHIP_RV710:
89
	case CHIP_RV710:
70
	case CHIP_RV730:
90
	case CHIP_RV730:
71
	case CHIP_RV740:
91
	case CHIP_RV740:
Line 182... Line 202...
182
	release_firmware(rdev->uvd_fw);
202
	release_firmware(rdev->uvd_fw);
183
}
203
}
Line 184... Line 204...
184
 
204
 
185
int radeon_uvd_suspend(struct radeon_device *rdev)
205
int radeon_uvd_suspend(struct radeon_device *rdev)
186
{
-
 
187
	unsigned size;
-
 
188
	void *ptr;
206
{
Line 189... Line 207...
189
	int i;
207
	int i, r;
190
 
208
 
Line 191... Line 209...
191
	if (rdev->uvd.vcpu_bo == NULL)
209
	if (rdev->uvd.vcpu_bo == NULL)
192
		return 0;
210
		return 0;
193
 
211
 
-
 
212
	for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
Line 194... Line 213...
194
	for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
213
		uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
195
		if (atomic_read(&rdev->uvd.handles[i]))
-
 
Line 196... Line 214...
196
			break;
214
		if (handle != 0) {
-
 
215
			struct radeon_fence *fence;
-
 
216
 
197
 
217
			radeon_uvd_note_usage(rdev);
-
 
218
 
-
 
219
			r = radeon_uvd_get_destroy_msg(rdev,
Line 198... Line 220...
198
	if (i == RADEON_MAX_UVD_HANDLES)
220
				R600_RING_TYPE_UVD_INDEX, handle, &fence);
199
		return 0;
221
			if (r) {
Line 200... Line 222...
200
 
222
				DRM_ERROR("Error destroying UVD (%d)!\n", r);
201
	size = radeon_bo_size(rdev->uvd.vcpu_bo);
223
				continue;
-
 
224
			}
-
 
225
 
Line 202... Line 226...
202
	size -= rdev->uvd_fw->size;
226
			radeon_fence_wait(fence, false);
203
 
227
			radeon_fence_unref(&fence);
Line 204... Line 228...
204
	ptr = rdev->uvd.cpu_addr;
228
 
Line 224... Line 248...
224
	size -= rdev->uvd_fw->size;
248
	size -= rdev->uvd_fw->size;
Line 225... Line 249...
225
 
249
 
226
	ptr = rdev->uvd.cpu_addr;
250
	ptr = rdev->uvd.cpu_addr;
Line 227... Line -...
227
	ptr += rdev->uvd_fw->size;
-
 
228
 
-
 
229
	if (rdev->uvd.saved_bo != NULL) {
-
 
230
		memcpy(ptr, rdev->uvd.saved_bo, size);
-
 
231
		kfree(rdev->uvd.saved_bo);
-
 
232
		rdev->uvd.saved_bo = NULL;
251
	ptr += rdev->uvd_fw->size;
Line 233... Line 252...
233
	} else
252
 
234
		memset(ptr, 0, size);
253
	memset(ptr, 0, size);
Line 374... Line 393...
374
	buf_sizes[0x1] = dpb_size;
393
	buf_sizes[0x1] = dpb_size;
375
	buf_sizes[0x2] = image_size;
394
	buf_sizes[0x2] = image_size;
376
	return 0;
395
	return 0;
377
}
396
}
Line -... Line 397...
-
 
397
 
-
 
398
static int radeon_uvd_validate_codec(struct radeon_cs_parser *p,
-
 
399
				     unsigned stream_type)
-
 
400
{
-
 
401
	switch (stream_type) {
-
 
402
	case 0: /* H264 */
-
 
403
	case 1: /* VC1 */
-
 
404
		/* always supported */
-
 
405
		return 0;
-
 
406
 
-
 
407
	case 3: /* MPEG2 */
-
 
408
	case 4: /* MPEG4 */
-
 
409
		/* only since UVD 3 */
-
 
410
		if (p->rdev->family >= CHIP_PALM)
-
 
411
			return 0;
-
 
412
 
-
 
413
		/* fall through */
-
 
414
	default:
-
 
415
		DRM_ERROR("UVD codec not supported by hardware %d!\n",
-
 
416
			  stream_type);
-
 
417
		return -EINVAL;
-
 
418
	}
-
 
419
}
378
 
420
 
379
static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
421
static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
380
			     unsigned offset, unsigned buf_sizes[])
422
			     unsigned offset, unsigned buf_sizes[])
381
{
423
{
382
	int32_t *msg, msg_type, handle;
424
	int32_t *msg, msg_type, handle;
Line 414... Line 456...
414
	if (handle == 0) {
456
	if (handle == 0) {
415
		DRM_ERROR("Invalid UVD handle!\n");
457
		DRM_ERROR("Invalid UVD handle!\n");
416
		return -EINVAL;
458
		return -EINVAL;
417
	}
459
	}
Line 418... Line 460...
418
 
460
 
419
	if (msg_type == 1) {
-
 
420
		/* it's a decode msg, calc buffer sizes */
-
 
421
		r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
-
 
422
		/* calc image size (width * height) */
-
 
423
		img_size = msg[6] * msg[7];
-
 
424
		radeon_bo_kunmap(bo);
-
 
425
		if (r)
-
 
426
			return r;
-
 
427
 
-
 
428
	} else if (msg_type == 2) {
-
 
429
		/* it's a destroy msg, free the handle */
-
 
430
		for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
-
 
431
			atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0);
-
 
432
		radeon_bo_kunmap(bo);
-
 
433
		return 0;
461
	switch (msg_type) {
434
	} else {
462
	case 0:
435
		/* it's a create msg, calc image size (width * height) */
463
		/* it's a create msg, calc image size (width * height) */
-
 
464
		img_size = msg[7] * msg[8];
-
 
465
 
436
		img_size = msg[7] * msg[8];
466
		r = radeon_uvd_validate_codec(p, msg[4]);
-
 
467
		radeon_bo_kunmap(bo);
-
 
468
		if (r)
Line 437... Line 469...
437
		radeon_bo_kunmap(bo);
469
			return r;
-
 
470
 
-
 
471
		/* try to alloc a new handle */
438
 
472
		for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
439
		if (msg_type != 0) {
473
			if (atomic_read(&p->rdev->uvd.handles[i]) == handle) {
440
			DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
474
				DRM_ERROR("Handle 0x%x already in use!\n", handle);
Line 441... Line 475...
441
			return -EINVAL;
475
				return -EINVAL;
-
 
476
			}
-
 
477
 
-
 
478
			if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) {
-
 
479
				p->rdev->uvd.filp[i] = p->filp;
442
		}
480
				p->rdev->uvd.img_size[i] = img_size;
Line -... Line 481...
-
 
481
				return 0;
-
 
482
			}
-
 
483
		}
-
 
484
 
-
 
485
		DRM_ERROR("No more free UVD handles!\n");
-
 
486
		return -EINVAL;
-
 
487
 
-
 
488
	case 1:
-
 
489
		/* it's a decode msg, validate codec and calc buffer sizes */
-
 
490
		r = radeon_uvd_validate_codec(p, msg[4]);
-
 
491
		if (!r)
-
 
492
			r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
443
 
493
		radeon_bo_kunmap(bo);
444
		/* it's a create msg, no special handling needed */
494
		if (r)
445
	}
495
			return r;
-
 
496
 
-
 
497
		/* validate the handle */
-
 
498
		for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
-
 
499
			if (atomic_read(&p->rdev->uvd.handles[i]) == handle) {
446
 
500
				if (p->rdev->uvd.filp[i] != p->filp) {
447
	/* create or decode, validate the handle */
501
					DRM_ERROR("UVD handle collision detected!\n");
-
 
502
					return -EINVAL;
Line -... Line 503...
-
 
503
				}
-
 
504
				return 0;
-
 
505
			}
-
 
506
		}
448
	for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
507
 
449
		if (atomic_read(&p->rdev->uvd.handles[i]) == handle)
508
		DRM_ERROR("Invalid UVD handle 0x%x!\n", handle);
450
			return 0;
509
		return -ENOENT;
451
	}
510
 
452
 
-
 
453
	/* handle not found try to alloc a new one */
511
	case 2:
-
 
512
		/* it's a destroy msg, free the handle */
-
 
513
		for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
454
	for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
514
			atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0);
-
 
515
		radeon_bo_kunmap(bo);
-
 
516
		return 0;
455
		if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) {
517
 
Line 456... Line 518...
456
			p->rdev->uvd.filp[i] = p->filp;
518
	default:
457
			p->rdev->uvd.img_size[i] = img_size;
519
 
458
			return 0;
520
		DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
Line 459... Line 521...
459
		}
521
		return -EINVAL;
460
	}
522
	}