mirror of https://gitee.com/openkylin/linux.git
drm/radeon: only save UVD bo when we have open handles
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>
This commit is contained in:
parent
6fab3febf6
commit
4ad9c1c774
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue