Skip to content

Commit

Permalink
drm/radeon: only save UVD bo when we have open handles
Browse files Browse the repository at this point in the history
Otherwise just reinitialize from scratch on resume,
and so make it more likely to succeed.

Signed-off-by: Christian König <christian.koenig@amd.com>
Cc: stable@vger.kernel.org
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
Christian König authored and Alex Deucher committed Aug 7, 2013
1 parent 6fab3fe commit 4ad9c1c
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 17 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/radeon/cik.c
Original file line number Diff line number Diff line change
Expand Up @@ -6980,7 +6980,7 @@ int cik_uvd_resume(struct radeon_device *rdev)

/* programm the VCPU memory controller bits 0-27 */
addr = rdev->uvd.gpu_addr >> 3;
size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3;
size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
WREG32(UVD_VCPU_CACHE_SIZE0, size);

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/radeon/radeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -1468,7 +1468,6 @@ struct radeon_uvd {
void *cpu_addr;
uint64_t gpu_addr;
void *saved_bo;
unsigned fw_size;
atomic_t handles[RADEON_MAX_UVD_HANDLES];
struct drm_file *filp[RADEON_MAX_UVD_HANDLES];
struct delayed_work idle_work;
Expand Down Expand Up @@ -2066,6 +2065,7 @@ struct radeon_device {
const struct firmware *mec_fw; /* CIK MEC firmware */
const struct firmware *sdma_fw; /* CIK SDMA firmware */
const struct firmware *smc_fw; /* SMC firmware */
const struct firmware *uvd_fw; /* UVD firmware */
struct r600_blit r600_blit;
struct r600_vram_scratch vram_scratch;
int msi_enabled; /* msi enabled */
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/radeon/radeon_fence.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)

} else {
/* put fence directly behind firmware */
index = ALIGN(rdev->uvd.fw_size, 8);
index = ALIGN(rdev->uvd_fw->size, 8);
rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index;
rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index;
}
Expand Down
46 changes: 33 additions & 13 deletions drivers/gpu/drm/radeon/radeon_uvd.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work);

int radeon_uvd_init(struct radeon_device *rdev)
{
const struct firmware *fw;
unsigned long bo_size;
const char *fw_name;
int i, r;
Expand Down Expand Up @@ -105,14 +104,14 @@ int radeon_uvd_init(struct radeon_device *rdev)
return -EINVAL;
}

r = request_firmware(&fw, fw_name, rdev->dev);
r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev);
if (r) {
dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n",
fw_name);
return r;
}

bo_size = RADEON_GPU_PAGE_ALIGN(fw->size + 8) +
bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) +
RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE;
r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo);
Expand Down Expand Up @@ -145,12 +144,6 @@ int radeon_uvd_init(struct radeon_device *rdev)

radeon_bo_unreserve(rdev->uvd.vcpu_bo);

rdev->uvd.fw_size = fw->size;
memset(rdev->uvd.cpu_addr, 0, bo_size);
memcpy(rdev->uvd.cpu_addr, fw->data, fw->size);

release_firmware(fw);

for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
atomic_set(&rdev->uvd.handles[i], 0);
rdev->uvd.filp[i] = NULL;
Expand All @@ -174,33 +167,60 @@ void radeon_uvd_fini(struct radeon_device *rdev)
}

radeon_bo_unref(&rdev->uvd.vcpu_bo);

release_firmware(rdev->uvd_fw);
}

int radeon_uvd_suspend(struct radeon_device *rdev)
{
unsigned size;
void *ptr;
int i;

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;

if (i == RADEON_MAX_UVD_HANDLES)
return 0;

size = radeon_bo_size(rdev->uvd.vcpu_bo);
size -= rdev->uvd_fw->size;

ptr = rdev->uvd.cpu_addr;
ptr += rdev->uvd_fw->size;

rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
memcpy(rdev->uvd.saved_bo, rdev->uvd.cpu_addr, size);
memcpy(rdev->uvd.saved_bo, ptr, size);

return 0;
}

int radeon_uvd_resume(struct radeon_device *rdev)
{
unsigned size;
void *ptr;

if (rdev->uvd.vcpu_bo == NULL)
return -EINVAL;

memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size);

size = radeon_bo_size(rdev->uvd.vcpu_bo);
size -= rdev->uvd_fw->size;

ptr = rdev->uvd.cpu_addr;
ptr += rdev->uvd_fw->size;

if (rdev->uvd.saved_bo != NULL) {
unsigned size = radeon_bo_size(rdev->uvd.vcpu_bo);
memcpy(rdev->uvd.cpu_addr, rdev->uvd.saved_bo, size);
memcpy(ptr, rdev->uvd.saved_bo, size);
kfree(rdev->uvd.saved_bo);
rdev->uvd.saved_bo = NULL;
}
} else
memset(ptr, 0, size);

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/radeon/rv770.c
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ int rv770_uvd_resume(struct radeon_device *rdev)

/* programm the VCPU memory controller bits 0-27 */
addr = rdev->uvd.gpu_addr >> 3;
size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3;
size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
WREG32(UVD_VCPU_CACHE_SIZE0, size);

Expand Down

0 comments on commit 4ad9c1c

Please sign in to comment.