From 21b704d78352c289d31697824ceea7ad0ff4ce59 Mon Sep 17 00:00:00 2001 From: James Zhu Date: Thu, 2 Apr 2020 23:25:45 -0400 Subject: [PATCH] drm/amdgpu/vcn: add shared memory restore after wake up from sleep. VCN shared memory needs restore after wake up during S3 test. v2: Allocate shared memory saved_bo at sw_init and free it in sw_fini. Signed-off-by: James Zhu Reviewed-by: Feifei Xu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 28 ++++++++++++++++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index d653a18dcbc3..dab34f695121 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -56,7 +56,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work); int amdgpu_vcn_sw_init(struct amdgpu_device *adev) { - unsigned long bo_size; + unsigned long bo_size, fw_shared_bo_size; const char *fw_name; const struct common_firmware_header *hdr; unsigned char fw_check; @@ -190,6 +190,9 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) dev_err(adev->dev, "VCN %d (%d) failed to allocate firmware shared bo\n", i, r); return r; } + + fw_shared_bo_size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo); + adev->vcn.inst[i].saved_shm_bo = kvmalloc(fw_shared_bo_size, GFP_KERNEL); } return 0; @@ -205,6 +208,7 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev) if (adev->vcn.harvest_config & (1 << j)) continue; + kvfree(adev->vcn.inst[j].saved_shm_bo); amdgpu_bo_free_kernel(&adev->vcn.inst[j].fw_shared_bo, &adev->vcn.inst[j].fw_shared_gpu_addr, (void **)&adev->vcn.inst[j].fw_shared_cpu_addr); @@ -254,6 +258,17 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev) return -ENOMEM; memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size); + + if (adev->vcn.inst[i].fw_shared_bo == NULL) + return 0; + + if (!adev->vcn.inst[i].saved_shm_bo) + return -ENOMEM; + + size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo); + ptr = adev->vcn.inst[i].fw_shared_cpu_addr; + + memcpy_fromio(adev->vcn.inst[i].saved_shm_bo, ptr, size); } return 0; } @@ -291,6 +306,17 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) } memset_io(ptr, 0, size); } + + if (adev->vcn.inst[i].fw_shared_bo == NULL) + return -EINVAL; + + size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo); + ptr = adev->vcn.inst[i].fw_shared_cpu_addr; + + if (adev->vcn.inst[i].saved_shm_bo != NULL) + memcpy_toio(ptr, adev->vcn.inst[i].saved_shm_bo, size); + else + memset_io(ptr, 0, size); } return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h index 6da6e2e0fdd8..90aa12b22725 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h @@ -194,6 +194,7 @@ struct amdgpu_vcn_inst { atomic_t dpg_enc_submission_cnt; void *fw_shared_cpu_addr; uint64_t fw_shared_gpu_addr; + void *saved_shm_bo; }; struct amdgpu_vcn {