diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0693-drm-amd-dal-S3-implementation-using-atomic-commit.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0693-drm-amd-dal-S3-implementation-using-atomic-commit.patch | 268 |
1 files changed, 0 insertions, 268 deletions
diff --git a/common/recipes-kernel/linux/files/0693-drm-amd-dal-S3-implementation-using-atomic-commit.patch b/common/recipes-kernel/linux/files/0693-drm-amd-dal-S3-implementation-using-atomic-commit.patch deleted file mode 100644 index 7a51dfd2..00000000 --- a/common/recipes-kernel/linux/files/0693-drm-amd-dal-S3-implementation-using-atomic-commit.patch +++ /dev/null @@ -1,268 +0,0 @@ -From 6b7df58f42c838b25452e13e26b054564d352730 Mon Sep 17 00:00:00 2001 -From: Eric Yang <eric.yang2@amd.com> -Date: Tue, 12 Jan 2016 12:02:08 -0500 -Subject: [PATCH 0693/1110] drm/amd/dal: S3 implementation using atomic commit - -Allow suspend resume by reconstructing the drm_atomic_state on -resume and calling atomic commit. This implementation works -with display configurationas up to 3 displays, but cannot handle -display swapping due to modelist not being properly updated. -Modes in the mode list are only emptied during disconnect, the -swap display during S3 use case never goes through a disconnect state - -Signed-off-by: Eric Yang <eric.yang2@amd.com> -Acked-by: Jordan Lazare <Jordan.Lazare@amd.com> ---- - drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm.c | 164 ++++++++++++++++++--- - .../gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c | 17 ++- - 2 files changed, 151 insertions(+), 30 deletions(-) - -diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm.c -index 0f281b6..6de5703 100644 ---- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm.c -@@ -451,20 +451,6 @@ static int dm_set_powergating_state(void *handle, - /* Prototypes of private functions */ - static int dm_early_init(void* handle); - --static void detect_on_all_dc_links(struct amdgpu_display_manager *dm) --{ -- uint32_t i; -- const struct dc_link *dc_link; -- struct dc_caps caps = { 0 }; -- -- dc_get_caps(dm->dc, &caps); -- -- for (i = 0; i < caps.max_links; i++) { -- dc_link = dc_get_link_at_index(dm->dc, i); -- dc_link_detect(dc_link, false); -- } --} -- - static void hotplug_notify_work_func(struct work_struct *work) - { - struct amdgpu_display_manager *dm = container_of(work, struct amdgpu_display_manager, mst_hotplug_work); -@@ -663,11 +649,78 @@ static int dm_hw_fini(void *handle) - return 0; - } - -+static int dm_display_suspend(struct drm_device *ddev) -+{ -+ struct drm_mode_config *config = &ddev->mode_config; -+ struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx; -+ struct drm_atomic_state *state; -+ struct drm_crtc *crtc; -+ unsigned crtc_mask = 0; -+ int ret = 0; -+ -+ if (WARN_ON(!ctx)) -+ return 0; -+ -+ lockdep_assert_held(&ctx->ww_ctx); -+ -+ state = drm_atomic_state_alloc(ddev); -+ if (WARN_ON(!state)) -+ return -ENOMEM; -+ -+ state->acquire_ctx = ctx; -+ state->allow_modeset = true; -+ -+ /* Set all active crtcs to inactive, to turn off displays*/ -+ 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 free; -+ -+ if (!crtc_state->active) -+ continue; -+ -+ crtc_state->active = false; -+ crtc_mask |= (1 << drm_crtc_index(crtc)); -+ } -+ -+ if (crtc_mask) { -+ ret = drm_atomic_commit(state); -+ -+ /* In case of failure, revert everything we did*/ -+ if (!ret) { -+ list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) -+ if (crtc_mask & (1 << drm_crtc_index(crtc))) -+ crtc->state->active = true; -+ -+ return ret; -+ } -+ } -+ -+free: -+ if (ret) { -+ DRM_ERROR("Suspending crtc's failed with %i\n", ret); -+ drm_atomic_state_free(state); -+ return ret; -+ } -+ -+ return 0; -+} - static int dm_suspend(void *handle) - { - struct amdgpu_device *adev = handle; - struct amdgpu_display_manager *dm = &adev->dm; -- struct drm_crtc *crtc; -+ struct drm_device *ddev = adev->ddev; -+ int ret = 0; -+ -+ drm_modeset_lock_all(ddev); -+ ret = dm_display_suspend(ddev); -+ drm_modeset_unlock_all(ddev); -+ -+ if (ret) -+ goto fail; - - dc_set_power_state( - dm->dc, -@@ -675,32 +728,95 @@ static int dm_suspend(void *handle) - DC_VIDEO_POWER_SUSPEND); - - amdgpu_dm_irq_suspend(adev); -+fail: -+ return ret; -+} -+ -+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; - -- list_for_each_entry(crtc, &dm->ddev->mode_config.crtc_list, head) { -- crtc->mode.clock = 0; -+ if (!state) -+ return ENOMEM; -+ -+ state->acquire_ctx = ddev->mode_config.acquire_ctx; -+ -+ /* Construct an atomic state to restore previous display setting*/ -+ /* 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; - } - -- return 0; -+ /* Attach planes to drm_atomic_state*/ -+ list_for_each_entry(plane, &ddev->mode_config.plane_list, head) { -+ ret = PTR_ERR_OR_ZERO(drm_atomic_get_plane_state(state, plane)); -+ if (ret) -+ goto err; -+ } -+ -+ /* Attach connectors to drm_atomic_state*/ -+ list_for_each_entry(connector, &ddev->mode_config.connector_list, head) { -+ ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(state, connector)); -+ if (ret) -+ goto err; -+ } -+ -+ /* 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_free(state); -+ -+ return ret; - } - - static int dm_resume(void *handle) - { -- int ret = 0; - struct amdgpu_device *adev = handle; -+ struct drm_device *ddev = adev->ddev; - struct amdgpu_display_manager *dm = &adev->dm; -+ struct amdgpu_connector *aconnector; -+ struct drm_connector *connector; -+ int ret = 0; - -+ /* power on hardware */ - dc_set_power_state( - dm->dc, - DC_ACPI_CM_POWER_STATE_D0, - DC_VIDEO_POWER_ON); - -- amdgpu_dm_irq_resume(adev); -- -+ /* program HPD filter*/ - dc_resume(dm->dc); -+ /* resume IRQ */ -+ amdgpu_dm_irq_resume(adev); -+ /* Do detection*/ -+ list_for_each_entry(connector, -+ &ddev->mode_config.connector_list, head) { -+ aconnector = to_amdgpu_connector(connector); -+ dc_link_detect(aconnector->dc_link, false); -+ aconnector->dc_sink = NULL; -+ amdgpu_dm_update_connector_after_detect(aconnector); -+ } - -- detect_on_all_dc_links(dm); -- -- drm_mode_config_reset(adev->ddev); -+ drm_modeset_lock_all(ddev); -+ ret = dm_display_resume(ddev); -+ drm_modeset_unlock_all(ddev); - - return ret; - } -diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c -index 7df2d28..04044ff 100644 ---- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c -+++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c -@@ -2171,6 +2171,8 @@ int amdgpu_dm_atomic_commit( - * during resume sequence ended - */ - new_state->planes_changed = false; -+ DRM_DEBUG_KMS("%s: Failed to create new target for crtc %d\n", -+ __func__, acrtc->base.base.id); - break; - } - -@@ -2458,13 +2460,16 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, - aconnector, - &mode); - -+ /* -+ * we can have no target on ACTION_SET if a display -+ * was disconnected during S3, in this case it not and -+ * error, the OS will be updated after detection, and -+ * do the right thing on next atomic commit -+ */ - if (!new_target) { -- DRM_ERROR( -- "%s: Can't create target for crtc %d\n", -- __func__, -- acrtc->crtc_id); -- goto connector_not_found; -- -+ DRM_DEBUG_KMS("%s: Failed to create new target for crtc %d\n", -+ __func__, acrtc->base.base.id); -+ break; - } - - new_targets[new_target_count] = new_target; --- -2.7.4 - |