]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
drm/amd/display: Switch to DRM helpers in s3.
authorAndrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Thu, 20 Apr 2017 19:59:25 +0000 (15:59 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Sep 2017 21:18:36 +0000 (17:18 -0400)
Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Reviewed-by: Jordan Lazare <Jordan.Lazare@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/inc/core_dc.h

index da499ab7eab5bcb1d506e70889297a32eb08b579..a69ce27b8ed621e25add40bee21fff2679d8cc44 100644 (file)
@@ -451,28 +451,17 @@ static int dm_suspend(void *handle)
        struct amdgpu_device *adev = handle;
        struct amdgpu_display_manager *dm = &adev->dm;
        int ret = 0;
-       struct drm_crtc *crtc;
 
        s3_handle_mst(adev->ddev, true);
 
-       /* flash all pending vblank events and turn interrupt off
-        * before disabling CRTCs. They will be enabled back in
-        * dm_display_resume
-        */
-       drm_modeset_lock_all(adev->ddev);
-       list_for_each_entry(crtc, &adev->ddev->mode_config.crtc_list, head) {
-               struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
-               if (acrtc->stream)
-                               drm_crtc_vblank_off(crtc);
-       }
-       drm_modeset_unlock_all(adev->ddev);
-
        amdgpu_dm_irq_suspend(adev);
 
+       adev->dm.cached_state = drm_atomic_helper_suspend(adev->ddev);
+
        dc_set_power_state(
                dm->dc,
-               DC_ACPI_CM_POWER_STATE_D3,
-               DC_VIDEO_POWER_SUSPEND);
+               DC_ACPI_CM_POWER_STATE_D3
+               );
 
        return ret;
 }
@@ -504,120 +493,6 @@ struct amdgpu_connector *amdgpu_dm_find_first_crct_matching_connector(
        return NULL;
 }
 
-static int dm_display_resume(struct drm_device *ddev)
-{
-       int ret = 0;
-       struct drm_connector *connector;
-
-       struct drm_atomic_state *state = drm_atomic_state_alloc(ddev);
-       struct drm_plane *plane;
-       struct drm_crtc *crtc;
-       struct amdgpu_connector *aconnector;
-       struct drm_connector_state *conn_state;
-
-       if (!state)
-               return ENOMEM;
-
-       state->acquire_ctx = ddev->mode_config.acquire_ctx;
-
-       /* Construct an atomic state to restore previous display setting */
-
-       /*
-        * Attach connectors to drm_atomic_state
-        * Should be done in the first place in order to make connectors
-        * available in state during crtc state processing. It is used for
-        * making decision if crtc should be disabled in case sink got
-        * disconnected.
-        *
-        * Connectors state crtc with NULL dc_sink should be cleared, because it
-        * will fail validation during commit
-        */
-       list_for_each_entry(connector, &ddev->mode_config.connector_list, head) {
-               aconnector = to_amdgpu_connector(connector);
-               conn_state = drm_atomic_get_connector_state(state, connector);
-
-               ret = PTR_ERR_OR_ZERO(conn_state);
-               if (ret)
-                       goto err;
-       }
-
-       /* Attach crtcs to drm_atomic_state*/
-       list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
-               struct drm_crtc_state *crtc_state =
-                       drm_atomic_get_crtc_state(state, crtc);
-
-               ret = PTR_ERR_OR_ZERO(crtc_state);
-               if (ret)
-                       goto err;
-
-               /* force a restore */
-               crtc_state->mode_changed = true;
-       }
-
-
-       /* Attach planes to drm_atomic_state */
-       list_for_each_entry(plane, &ddev->mode_config.plane_list, head) {
-
-               struct drm_crtc *crtc;
-               struct drm_gem_object *obj;
-               struct drm_framebuffer *fb;
-               struct amdgpu_framebuffer *afb;
-               struct amdgpu_bo *rbo;
-               int r;
-               struct drm_plane_state *plane_state = drm_atomic_get_plane_state(state, plane);
-
-               ret = PTR_ERR_OR_ZERO(plane_state);
-               if (ret)
-                       goto err;
-
-               crtc = plane_state->crtc;
-               fb = plane_state->fb;
-
-               if (!crtc || !crtc->state || !crtc->state->active)
-                       continue;
-
-               if (!fb) {
-                       DRM_DEBUG_KMS("No FB bound\n");
-                       return 0;
-               }
-
-               /*
-                * Pin back the front buffers, cursor buffer was already pinned
-                * back in amdgpu_resume_kms
-                */
-
-               afb = to_amdgpu_framebuffer(fb);
-
-               obj = afb->obj;
-               rbo = gem_to_amdgpu_bo(obj);
-               r = amdgpu_bo_reserve(rbo, false);
-               if (unlikely(r != 0))
-                      return r;
-
-               r = amdgpu_bo_pin(rbo, AMDGPU_GEM_DOMAIN_VRAM, NULL);
-
-               amdgpu_bo_unreserve(rbo);
-
-               if (unlikely(r != 0)) {
-                       DRM_ERROR("Failed to pin framebuffer\n");
-                       return r;
-               }
-
-       }
-
-
-       /* Call commit internally with the state we just constructed */
-       ret = drm_atomic_commit(state);
-       if (!ret)
-               return 0;
-
-err:
-       DRM_ERROR("Restoring old state failed with %i\n", ret);
-       drm_atomic_state_put(state);
-
-       return ret;
-}
-
 static int dm_resume(void *handle)
 {
        struct amdgpu_device *adev = handle;
@@ -626,8 +501,8 @@ static int dm_resume(void *handle)
        /* power on hardware */
        dc_set_power_state(
                dm->dc,
-               DC_ACPI_CM_POWER_STATE_D0,
-               DC_VIDEO_POWER_ON);
+               DC_ACPI_CM_POWER_STATE_D0
+               );
 
        return 0;
 }
@@ -638,8 +513,10 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev )
        struct amdgpu_display_manager *dm = &adev->dm;
        struct amdgpu_connector *aconnector;
        struct drm_connector *connector;
-       int ret = 0;
        struct drm_crtc *crtc;
+       struct drm_crtc_state *crtc_state;
+       int ret = 0;
+       int i;
 
        /* program HPD filter */
        dc_resume(dm->dc);
@@ -653,14 +530,6 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev )
         */
        amdgpu_dm_irq_resume_early(adev);
 
-       drm_modeset_lock_all(ddev);
-       list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
-               struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
-               if (acrtc->stream)
-                               drm_crtc_vblank_on(crtc);
-       }
-       drm_modeset_unlock_all(ddev);
-
        /* Do detection*/
        list_for_each_entry(connector,
                        &ddev->mode_config.connector_list, head) {
@@ -678,9 +547,11 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev )
                amdgpu_dm_update_connector_after_detect(aconnector);
        }
 
-       drm_modeset_lock_all(ddev);
-       ret = dm_display_resume(ddev);
-       drm_modeset_unlock_all(ddev);
+       /* Force mode set in atomic comit */
+       for_each_crtc_in_state(adev->dm.cached_state, crtc, crtc_state, i)
+                       crtc_state->active_changed = true;
+
+       ret = drm_atomic_helper_resume(ddev, adev->dm.cached_state);
 
        amdgpu_dm_irq_resume(adev);
 
index d6ebba012e15ab20aeff0cee6e819466a942c498..ee69179636a1f0efe7da3dc18957ec7cabc780d6 100644 (file)
@@ -128,6 +128,11 @@ struct amdgpu_display_manager {
        struct work_struct mst_hotplug_work;
 
        struct mod_freesync *freesync_module;
+
+       /**
+        * Caches device atomic state for suspend/resume
+        */
+       struct drm_atomic_state *cached_state;
 };
 
 /* basic init/fini API */
index a39b9987b9d6915759f1b520f8937022afdbfdbe..edcb731a3aea4fe19ea10971609a10846cfa1510 100644 (file)
@@ -1589,21 +1589,15 @@ void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src)
 
 void dc_set_power_state(
        struct dc *dc,
-       enum dc_acpi_cm_power_state power_state,
-       enum dc_video_power_state video_power_state)
+       enum dc_acpi_cm_power_state power_state)
 {
        struct core_dc *core_dc = DC_TO_CORE(dc);
 
-       core_dc->previous_power_state = core_dc->current_power_state;
-       core_dc->current_power_state = video_power_state;
-
        switch (power_state) {
        case DC_ACPI_CM_POWER_STATE_D0:
                core_dc->hwss.init_hw(core_dc);
                break;
        default:
-               /* NULL means "reset/release all DC streams" */
-               dc_commit_streams(dc, NULL, 0);
 
                core_dc->hwss.power_down(core_dc);
 
index 69ae94bb209fd9de74a452143a6d4748171d8f60..e2c2a0bf764dc5a34746a6acd6c489270b45f8bd 100644 (file)
@@ -705,8 +705,7 @@ enum dc_irq_source dc_get_hpd_irq_source_at_index(
 
 void dc_set_power_state(
                struct dc *dc,
-               enum dc_acpi_cm_power_state power_state,
-               enum dc_video_power_state video_power_state);
+               enum dc_acpi_cm_power_state power_state);
 void dc_resume(const struct dc *dc);
 
 /*******************************************************************************
index 7a6444dc2957cbfee7a06fea0ce0ff689cfa8ac8..8d87f490dc1c016f0de8fa488bfb9901d2889ee3 100644 (file)
@@ -26,10 +26,6 @@ struct core_dc {
        struct validate_context *scratch_val_ctx;
        struct resource_pool *res_pool;
 
-       /*Power State*/
-       enum dc_video_power_state previous_power_state;
-       enum dc_video_power_state current_power_state;
-
        /* Display Engine Clock levels */
        struct dm_pp_clock_levels sclk_lvls;