summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-04-07 00:08:46 +0300
committerDave Airlie <airlied@redhat.com>2016-04-07 00:08:46 +0300
commitfd8c61ebd4265ff1c5fa80ba351e8e1dd710fac0 (patch)
tree07cdc132e647d30aadb5418b837d33db7bc25681 /drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
parent30aab1897b9592ae40123bc83888d23af06261eb (diff)
parent7c0ecda15b01bc88d762d9263d2cf0f69ffd4c23 (diff)
downloadlinux-fd8c61ebd4265ff1c5fa80ba351e8e1dd710fac0.tar.xz
Merge branch 'drm-fixes-4.6' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
Lots of misc bug fixes for radeon and amdgpu and one for ttm. - fix vram info fetching on Fiji and unposted boards - additional vblank fixes from the conversion to drm_vblank_on/off - UVD dGPU suspend and resume fixes - lots of powerplay fixes - fix a fence leak in the pageflip code - ttm fix for platforms where CPU is 32 bit, but physical addresses are >32bits * 'drm-fixes-4.6' of git://people.freedesktop.org/~agd5f/linux: (21 commits) drm/amdgpu: total vram size also reduces pin size drm/amd/powerplay: add uvd/vce dpm enabling flag default. drm/amd/powerplay: fix issue that resume back, dpm can't work on FIJI. drm/amdgpu: save and restore the firwmware cache part when suspend resume drm/amdgpu: save and restore UVD context with suspend and resume drm/ttm: use phys_addr_t for ttm_bus_placement drm/radeon: Only call drm_vblank_on/off between drm_vblank_init/cleanup drm/amdgpu: fence wait old rcu slot drm/amdgpu: fix leaking fence in the pageflip code drm/amdgpu: print vram type rather than just DDR drm/amdgpu/gmc: use proper register for vram type on Fiji drm/amdgpu/gmc: move vram type fetching into sw_init drm/amdgpu: Set vblank_disable_allowed = true drm/radeon: Set vblank_disable_allowed = true drm/amd/powerplay: Need to change boot to performance state in resume. drm/amd/powerplay: add new Fiji function for not setting same ps. drm/amdgpu: check dpm state before pm system fs initialized. drm/amd/powerplay: notify amdgpu whether dpm is enabled or not. drm/amdgpu: Not support disable dpm in powerplay. drm/amdgpu: add an cgs interface to notify amdgpu the dpm state. ...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c58
1 files changed, 30 insertions, 28 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index c1a581044417..338da80006b6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -241,32 +241,28 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
int amdgpu_uvd_suspend(struct amdgpu_device *adev)
{
- struct amdgpu_ring *ring = &adev->uvd.ring;
- int i, r;
+ unsigned size;
+ void *ptr;
+ int i;
if (adev->uvd.vcpu_bo == NULL)
return 0;
- for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) {
- uint32_t handle = atomic_read(&adev->uvd.handles[i]);
- if (handle != 0) {
- struct fence *fence;
+ for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i)
+ if (atomic_read(&adev->uvd.handles[i]))
+ break;
- amdgpu_uvd_note_usage(adev);
+ if (i == AMDGPU_MAX_UVD_HANDLES)
+ return 0;
- r = amdgpu_uvd_get_destroy_msg(ring, handle, false, &fence);
- if (r) {
- DRM_ERROR("Error destroying UVD (%d)!\n", r);
- continue;
- }
+ size = amdgpu_bo_size(adev->uvd.vcpu_bo);
+ ptr = adev->uvd.cpu_addr;
- fence_wait(fence, false);
- fence_put(fence);
+ adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
+ if (!adev->uvd.saved_bo)
+ return -ENOMEM;
- adev->uvd.filp[i] = NULL;
- atomic_set(&adev->uvd.handles[i], 0);
- }
- }
+ memcpy(adev->uvd.saved_bo, ptr, size);
return 0;
}
@@ -275,23 +271,29 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
{
unsigned size;
void *ptr;
- const struct common_firmware_header *hdr;
- unsigned offset;
if (adev->uvd.vcpu_bo == NULL)
return -EINVAL;
- hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
- offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
- memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset,
- (adev->uvd.fw->size) - offset);
-
size = amdgpu_bo_size(adev->uvd.vcpu_bo);
- size -= le32_to_cpu(hdr->ucode_size_bytes);
ptr = adev->uvd.cpu_addr;
- ptr += le32_to_cpu(hdr->ucode_size_bytes);
- memset(ptr, 0, size);
+ if (adev->uvd.saved_bo != NULL) {
+ memcpy(ptr, adev->uvd.saved_bo, size);
+ kfree(adev->uvd.saved_bo);
+ adev->uvd.saved_bo = NULL;
+ } else {
+ const struct common_firmware_header *hdr;
+ unsigned offset;
+
+ hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
+ offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
+ memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset,
+ (adev->uvd.fw->size) - offset);
+ size -= le32_to_cpu(hdr->ucode_size_bytes);
+ ptr += le32_to_cpu(hdr->ucode_size_bytes);
+ memset(ptr, 0, size);
+ }
return 0;
}