drm/amdgpu: unpin cursor BOs on suspend and pin them again on resume
authorAlex Deucher <alexander.deucher@amd.com>
Thu, 8 Oct 2015 04:03:36 +0000 (00:03 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 14 Oct 2015 20:16:35 +0000 (16:16 -0400)
Everything is evicted from VRAM before suspend, so we need to make
sure all BOs are unpinned and re-pinned after resume. Fixes broken
mouse cursor after resume introduced by commit b9729b17.

Port of radeon commit:
f3cbb17bcf676a2fc6aedebe9fbebd59e550c51a

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

index 4256b00d0b37d056e8ad9f18fbf27445a65766f9..901a460b2c5573bfe4ae1af93c16d8be95140420 100644 (file)
@@ -1657,11 +1657,21 @@ int amdgpu_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
        }
        drm_modeset_unlock_all(dev);
 
-       /* unpin the front buffers */
+       /* unpin the front buffers and cursors */
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
                struct amdgpu_framebuffer *rfb = to_amdgpu_framebuffer(crtc->primary->fb);
                struct amdgpu_bo *robj;
 
+               if (amdgpu_crtc->cursor_bo) {
+                       struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
+                       r = amdgpu_bo_reserve(aobj, false);
+                       if (r == 0) {
+                               amdgpu_bo_unpin(aobj);
+                               amdgpu_bo_unreserve(aobj);
+                       }
+               }
+
                if (rfb == NULL || rfb->obj == NULL) {
                        continue;
                }
@@ -1713,6 +1723,7 @@ int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon)
 {
        struct drm_connector *connector;
        struct amdgpu_device *adev = dev->dev_private;
+       struct drm_crtc *crtc;
        int r;
 
        if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
@@ -1746,6 +1757,24 @@ int amdgpu_resume_kms(struct drm_device *dev, bool resume, bool fbcon)
        if (r)
                return r;
 
+       /* pin cursors */
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+
+               if (amdgpu_crtc->cursor_bo) {
+                       struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
+                       r = amdgpu_bo_reserve(aobj, false);
+                       if (r == 0) {
+                               r = amdgpu_bo_pin(aobj,
+                                                 AMDGPU_GEM_DOMAIN_VRAM,
+                                                 &amdgpu_crtc->cursor_addr);
+                               if (r != 0)
+                                       DRM_ERROR("Failed to pin cursor BO (%d)\n", r);
+                               amdgpu_bo_unreserve(aobj);
+                       }
+               }
+       }
+
        /* blat the mode back in */
        if (fbcon) {
                drm_helper_resume_force_mode(dev);