We are using PSP to resume firmware after suspend, and it is
resumed at where it got suspended, so we'd better save the
the context.

Signed-off-by: Leo Liu <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h |  1 +
 drivers/gpu/drm/amd/amdgpu/vce_v4_0.c   | 39 ++++++++++++++++++++++++++++-----
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
index c93f74a..5ce54cd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
@@ -34,6 +34,7 @@ struct amdgpu_vce {
        struct amdgpu_bo        *vcpu_bo;
        uint64_t                gpu_addr;
        void                    *cpu_addr;
+       void                    *saved_bo;
        unsigned                fw_version;
        unsigned                fb_version;
        atomic_t                handles[AMDGPU_MAX_VCE_HANDLES];
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c 
b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
index 0b7fcc1..2230a99 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
@@ -522,8 +522,22 @@ static int vce_v4_0_hw_fini(void *handle)
 
 static int vce_v4_0_suspend(void *handle)
 {
-       int r;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+       int r;
+
+       if (adev->vce.vcpu_bo == NULL)
+               return 0;
+
+       if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
+               unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo);
+               void *ptr = adev->vce.cpu_addr;
+
+               adev->vce.saved_bo = kmalloc(size, GFP_KERNEL);
+               if (!adev->vce.saved_bo)
+                       return -ENOMEM;
+
+               memcpy_fromio(adev->vce.saved_bo, ptr, size);
+       }
 
        r = vce_v4_0_hw_fini(adev);
        if (r)
@@ -534,12 +548,27 @@ static int vce_v4_0_suspend(void *handle)
 
 static int vce_v4_0_resume(void *handle)
 {
-       int r;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+       int r;
 
-       r = amdgpu_vce_resume(adev);
-       if (r)
-               return r;
+       if (adev->vce.vcpu_bo == NULL)
+               return -EINVAL;
+
+       if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
+               unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo);
+               void *ptr = adev->vce.cpu_addr;
+
+               if (adev->vce.saved_bo != NULL) {
+                       memcpy_toio(ptr, adev->vce.saved_bo, size);
+                       kfree(adev->vce.saved_bo);
+                       adev->vce.saved_bo = NULL;
+               } else
+                       memset_io(ptr, 0, size);
+       } else {
+               r = amdgpu_vce_resume(adev);
+               if (r)
+                       return r;
+       }
 
        return vce_v4_0_hw_init(adev);
 }
-- 
2.7.4

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to