Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6103 → Rev 6104

/drivers/video/drm/radeon/radeon_uvd.c
40,6 → 40,9
#define UVD_IDLE_TIMEOUT_MS 1000
 
/* Firmware Names */
#define FIRMWARE_R600 "radeon/R600_uvd.bin"
#define FIRMWARE_RS780 "radeon/RS780_uvd.bin"
#define FIRMWARE_RV770 "radeon/RV770_uvd.bin"
#define FIRMWARE_RV710 "radeon/RV710_uvd.bin"
#define FIRMWARE_CYPRESS "radeon/CYPRESS_uvd.bin"
#define FIRMWARE_SUMO "radeon/SUMO_uvd.bin"
66,6 → 69,23
// INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler);
 
switch (rdev->family) {
case CHIP_RV610:
case CHIP_RV630:
case CHIP_RV670:
case CHIP_RV620:
case CHIP_RV635:
fw_name = FIRMWARE_R600;
break;
 
case CHIP_RS780:
case CHIP_RS880:
fw_name = FIRMWARE_RS780;
break;
 
case CHIP_RV770:
fw_name = FIRMWARE_RV770;
break;
 
case CHIP_RV710:
case CHIP_RV730:
case CHIP_RV740:
184,28 → 204,32
 
int radeon_uvd_suspend(struct radeon_device *rdev)
{
unsigned size;
void *ptr;
int i;
int i, r;
 
if (rdev->uvd.vcpu_bo == NULL)
return 0;
 
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
if (atomic_read(&rdev->uvd.handles[i]))
break;
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
if (handle != 0) {
struct radeon_fence *fence;
 
if (i == RADEON_MAX_UVD_HANDLES)
return 0;
radeon_uvd_note_usage(rdev);
 
size = radeon_bo_size(rdev->uvd.vcpu_bo);
size -= rdev->uvd_fw->size;
r = radeon_uvd_get_destroy_msg(rdev,
R600_RING_TYPE_UVD_INDEX, handle, &fence);
if (r) {
DRM_ERROR("Error destroying UVD (%d)!\n", r);
continue;
}
 
ptr = rdev->uvd.cpu_addr;
ptr += rdev->uvd_fw->size;
radeon_fence_wait(fence, false);
radeon_fence_unref(&fence);
 
rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
memcpy(rdev->uvd.saved_bo, ptr, size);
rdev->uvd.filp[i] = NULL;
atomic_set(&rdev->uvd.handles[i], 0);
}
}
 
return 0;
}
226,11 → 250,6
ptr = rdev->uvd.cpu_addr;
ptr += rdev->uvd_fw->size;
 
if (rdev->uvd.saved_bo != NULL) {
memcpy(ptr, rdev->uvd.saved_bo, size);
kfree(rdev->uvd.saved_bo);
rdev->uvd.saved_bo = NULL;
} else
memset(ptr, 0, size);
 
return 0;
376,6 → 395,29
return 0;
}
 
static int radeon_uvd_validate_codec(struct radeon_cs_parser *p,
unsigned stream_type)
{
switch (stream_type) {
case 0: /* H264 */
case 1: /* VC1 */
/* always supported */
return 0;
 
case 3: /* MPEG2 */
case 4: /* MPEG4 */
/* only since UVD 3 */
if (p->rdev->family >= CHIP_PALM)
return 0;
 
/* fall through */
default:
DRM_ERROR("UVD codec not supported by hardware %d!\n",
stream_type);
return -EINVAL;
}
}
 
static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
unsigned offset, unsigned buf_sizes[])
{
416,50 → 458,70
return -EINVAL;
}
 
if (msg_type == 1) {
/* it's a decode msg, calc buffer sizes */
r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
/* calc image size (width * height) */
img_size = msg[6] * msg[7];
switch (msg_type) {
case 0:
/* it's a create msg, calc image size (width * height) */
img_size = msg[7] * msg[8];
 
r = radeon_uvd_validate_codec(p, msg[4]);
radeon_bo_kunmap(bo);
if (r)
return r;
 
} else if (msg_type == 2) {
/* it's a destroy msg, free the handle */
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0);
radeon_bo_kunmap(bo);
return 0;
} else {
/* it's a create msg, calc image size (width * height) */
img_size = msg[7] * msg[8];
radeon_bo_kunmap(bo);
 
if (msg_type != 0) {
DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
/* try to alloc a new handle */
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
if (atomic_read(&p->rdev->uvd.handles[i]) == handle) {
DRM_ERROR("Handle 0x%x already in use!\n", handle);
return -EINVAL;
}
 
/* it's a create msg, no special handling needed */
if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) {
p->rdev->uvd.filp[i] = p->filp;
p->rdev->uvd.img_size[i] = img_size;
return 0;
}
}
 
/* create or decode, validate the handle */
DRM_ERROR("No more free UVD handles!\n");
return -EINVAL;
 
case 1:
/* it's a decode msg, validate codec and calc buffer sizes */
r = radeon_uvd_validate_codec(p, msg[4]);
if (!r)
r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
radeon_bo_kunmap(bo);
if (r)
return r;
 
/* validate the handle */
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
if (atomic_read(&p->rdev->uvd.handles[i]) == handle)
if (atomic_read(&p->rdev->uvd.handles[i]) == handle) {
if (p->rdev->uvd.filp[i] != p->filp) {
DRM_ERROR("UVD handle collision detected!\n");
return -EINVAL;
}
return 0;
}
}
 
/* handle not found try to alloc a new one */
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) {
p->rdev->uvd.filp[i] = p->filp;
p->rdev->uvd.img_size[i] = img_size;
DRM_ERROR("Invalid UVD handle 0x%x!\n", handle);
return -ENOENT;
 
case 2:
/* it's a destroy msg, free the handle */
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
atomic_cmpxchg(&p->rdev->uvd.handles[i], handle, 0);
radeon_bo_kunmap(bo);
return 0;
 
default:
 
DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
return -EINVAL;
}
}
 
DRM_ERROR("No more free UVD handles!\n");
BUG();
return -EINVAL;
}