diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1007-drm-amd-display-Refactor-atomic-check.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1007-drm-amd-display-Refactor-atomic-check.patch | 666 |
1 files changed, 0 insertions, 666 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1007-drm-amd-display-Refactor-atomic-check.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1007-drm-amd-display-Refactor-atomic-check.patch deleted file mode 100644 index 96b6c2b3..00000000 --- a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1007-drm-amd-display-Refactor-atomic-check.patch +++ /dev/null @@ -1,666 +0,0 @@ -From ad3d14ad6eff85578426d10db69eaf2fc56b1c81 Mon Sep 17 00:00:00 2001 -From: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> -Date: Fri, 18 Aug 2017 10:52:20 -0400 -Subject: [PATCH 1007/4131] drm/amd/display: Refactor atomic check. - -Split into update crtcs and update plane functions. - -Change-Id: I57a739070861553de9b787f995e44a1da4e3c2d0 -Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> -Reviewed-by: Harry Wentland <Harry.Wentland@amd.com> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 550 ++++++++++++---------- - 1 file changed, 303 insertions(+), 247 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 4b817bf..edbf952 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -1789,12 +1789,6 @@ static bool modeset_required(struct drm_crtc_state *crtc_state, - struct dc_stream_state *new_stream, - struct dc_stream_state *old_stream) - { -- if (dc_is_stream_unchanged(new_stream, old_stream)) { -- crtc_state->mode_changed = false; -- DRM_DEBUG_KMS("Mode change not required, setting mode_changed to %d", -- crtc_state->mode_changed); -- } -- - if (!drm_atomic_crtc_needs_modeset(crtc_state)) - return false; - -@@ -4119,9 +4113,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, - continue; - } - -- if (!fb || !crtc || pcrtc != crtc || !crtc->state->active || -- (!crtc->state->planes_changed && -- !pcrtc->state->color_mgmt_changed)) -+ if (!fb || !crtc || pcrtc != crtc || !crtc->state->active) - continue; - - pflip_needed = !state->allow_modeset; -@@ -4598,76 +4590,18 @@ static int do_aquire_global_lock( - return ret < 0 ? ret : 0; - } - --int amdgpu_dm_atomic_check(struct drm_device *dev, -- struct drm_atomic_state *state) -+static int dm_update_crtcs_state( -+ struct dc *dc, -+ struct drm_atomic_state *state, -+ bool enable, -+ bool *lock_and_validation_needed) - { - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; -- struct drm_plane *plane; -- struct drm_plane_state *plane_state; -- int i, j; -- int ret; -- struct amdgpu_device *adev = dev->dev_private; -- struct dc *dc = adev->dm.dc; -- struct drm_connector *connector; -- struct drm_connector_state *conn_state; -+ int i; - struct dm_crtc_state *old_acrtc_state, *new_acrtc_state; - struct dm_atomic_state *dm_state = to_dm_atomic_state(state); -- bool pflip_needed = !state->allow_modeset; -- -- /* -- * This bool will be set for true for any modeset/reset -- * or plane update which implies non fast surface update. -- */ -- bool lock_and_validation_needed = false; -- -- ret = drm_atomic_helper_check_modeset(dev, state); -- -- if (ret) { -- DRM_ERROR("Atomic state validation failed with error :%d !\n", ret); -- return ret; -- } -- -- /* Remove exiting planes if they are disabled or their CRTC is updated */ -- for_each_crtc_in_state(state, crtc, crtc_state, i) { -- new_acrtc_state = to_dm_crtc_state(crtc_state); -- -- if (pflip_needed) -- continue; -- -- for_each_plane_in_state(state, plane, plane_state, j) { -- struct drm_crtc *plane_crtc = plane_state->crtc; -- struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); -- -- if (plane->type == DRM_PLANE_TYPE_CURSOR) -- continue; -- -- if (crtc != plane_crtc || !dm_plane_state->dc_state) -- continue; -- -- WARN_ON(!new_acrtc_state->stream); -- -- if (drm_atomic_plane_disabling(plane->state, plane_state) || -- drm_atomic_crtc_needs_modeset(crtc_state)) { -- if (!dc_remove_plane_from_context( -- dc, -- new_acrtc_state->stream, -- dm_plane_state->dc_state, -- dm_state->context)) { -- -- ret = EINVAL; -- goto fail; -- } -- -- } -- -- dc_plane_state_release(dm_plane_state->dc_state); -- dm_plane_state->dc_state = NULL; -- -- DRM_DEBUG_KMS("Disabling DRM plane: %d on DRM crtc %d\n", -- plane->base.id, crtc->base.id); -- } -- } -+ int ret = 0; - - /*TODO Move this code into dm_crtc_atomic_check once we get rid of dc_validation_set */ - /* update changed items */ -@@ -4677,12 +4611,52 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, - struct dc_stream_state *new_stream = NULL; - struct drm_connector_state *conn_state = NULL; - struct dm_connector_state *dm_conn_state = NULL; -- -+ - old_acrtc_state = to_dm_crtc_state(crtc->state); - new_acrtc_state = to_dm_crtc_state(crtc_state); - acrtc = to_amdgpu_crtc(crtc); - - aconnector = amdgpu_dm_find_first_crct_matching_connector(state, crtc, true); -+ -+ /* TODO This hack should go away */ -+ if (aconnector && aconnector->dc_sink) { -+ conn_state = drm_atomic_get_connector_state(state, -+ &aconnector->base); -+ -+ if (IS_ERR(conn_state)) { -+ ret = PTR_ERR_OR_ZERO(conn_state); -+ break; -+ } -+ -+ dm_conn_state = to_dm_connector_state(conn_state); -+ -+ new_stream = create_stream_for_sink(aconnector, -+ &crtc_state->mode, -+ dm_conn_state); -+ /* -+ * we can have no stream 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_stream) { -+ DRM_DEBUG_KMS("%s: Failed to create new stream for crtc %d\n", -+ __func__, acrtc->base.base.id); -+ break; -+ } -+ } -+ -+ if (dc_is_stream_unchanged(new_stream, -+ old_acrtc_state->stream)) { -+ crtc_state->mode_changed = false; -+ DRM_DEBUG_KMS("Mode change not required, setting mode_changed to %d", -+ crtc_state->mode_changed); -+ } -+ -+ -+ if (!drm_atomic_crtc_needs_modeset(crtc_state)) -+ continue; - - DRM_DEBUG_KMS( - "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " -@@ -4696,228 +4670,310 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, - crtc_state->active_changed, - crtc_state->connectors_changed); - -- if (modereset_required(crtc_state)) { -- -- /* i.e. reset mode */ -- if (new_acrtc_state->stream) { -- -- if (!dc_remove_stream_from_ctx( -- dc, -- dm_state->context, -- new_acrtc_state->stream)) { -- ret = -EINVAL; -- goto fail; -- } -- -- dc_stream_release(new_acrtc_state->stream); -- new_acrtc_state->stream = NULL; -- -- lock_and_validation_needed = true; -- } -- -- } else { -- -- if (aconnector) { -- conn_state = drm_atomic_get_connector_state(state, -- &aconnector->base); -- -- if (IS_ERR(conn_state)) { -- ret = PTR_ERR_OR_ZERO(conn_state); -- goto fail; -- } -- -- dm_conn_state = to_dm_connector_state(conn_state); -- -- new_stream = create_stream_for_sink(aconnector, -- &crtc_state->mode, -- dm_conn_state); -- -- /* -- * we can have no stream 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_stream) { -- DRM_DEBUG_KMS("%s: Failed to create new stream for crtc %d\n", -- __func__, acrtc->base.base.id); -- break; -- } -+ /* Remove stream for any changed/disabled CRTC */ -+ if (!enable) { - -+ if (!old_acrtc_state->stream) -+ continue; - -+ DRM_DEBUG_KMS("Disabling DRM crtc: %d\n", -+ crtc->base.id); -+ /* i.e. reset mode */ -+ if (!dc_remove_stream_from_ctx( -+ dc, -+ dm_state->context, -+ old_acrtc_state->stream)) { -+ ret = -EINVAL; -+ break; - } - -- if (modeset_required(crtc_state, new_stream, -- old_acrtc_state->stream)) { -+ dc_stream_release(old_acrtc_state->stream); -+ new_acrtc_state->stream = NULL; - -- if (new_acrtc_state->stream) { -+ *lock_and_validation_needed = true; - -- if (!dc_remove_stream_from_ctx( -- dc, -- dm_state->context, -- new_acrtc_state->stream)) { -- ret = -EINVAL; -- goto fail; -- } -+ } else {/* Add stream for any updated/enabled CRTC */ - -+ if (modereset_required(crtc_state)) -+ continue; - -- dc_stream_release(new_acrtc_state->stream); -- } -+ if (modeset_required(crtc_state, new_stream, -+ old_acrtc_state->stream)) { -+ -+ WARN_ON(new_acrtc_state->stream); - - new_acrtc_state->stream = new_stream; -+ dc_stream_retain(new_stream); - -+ DRM_DEBUG_KMS("Enabling DRM crtc: %d\n", -+ crtc->base.id); -+ - if (!dc_add_stream_to_ctx( - dc, - dm_state->context, - new_acrtc_state->stream)) { - ret = -EINVAL; -- goto fail; -+ break; - } -- -- lock_and_validation_needed = true; -- } else { -- /* -- * The new stream is unused, so we release it -- */ -- if (new_stream) -- dc_stream_release(new_stream); -- -+ -+ *lock_and_validation_needed = true; - } - } - -+ /* Release extra reference */ -+ if (new_stream) -+ dc_stream_release(new_stream); -+ } - -- /* -- * Hack: Commit needs planes right now, specifically for gamma -- * TODO rework commit to check CRTC for gamma change -- */ -- if (crtc_state->color_mgmt_changed) { -+ return ret; -+} - -- ret = drm_atomic_add_affected_planes(state, crtc); -- if (ret) -- goto fail; -- } -- } -+static int dm_update_planes_state( -+ struct dc *dc, -+ struct drm_atomic_state *state, -+ bool enable, -+ bool *lock_and_validation_needed) -+{ -+ struct drm_crtc *new_plane_crtc, *old_plane_crtc; -+ struct drm_crtc_state *new_crtc_state; -+ struct drm_plane *plane; -+ struct drm_plane_state *old_plane_state, *new_plane_state; -+ struct dm_crtc_state *new_acrtc_state, *old_acrtc_state; -+ struct dm_atomic_state *dm_state = to_dm_atomic_state(state); -+ struct dm_plane_state *new_dm_plane_state, *old_dm_plane_state; -+ int i ; -+ /* TODO return page_flip_needed() function */ -+ bool pflip_needed = !state->allow_modeset; -+ int ret = 0; - -- /* Check scaling and undersacn changes*/ -- /*TODO Removed scaling changes validation due to inability to commit -- * new stream into context w\o causing full reset. Need to -- * decide how to handle. -- */ -- for_each_connector_in_state(state, connector, conn_state, i) { -- struct amdgpu_connector *aconnector = to_amdgpu_connector(connector); -- struct dm_connector_state *con_old_state = -- to_dm_connector_state(aconnector->base.state); -- struct dm_connector_state *con_new_state = -- to_dm_connector_state(conn_state); -- struct amdgpu_crtc *acrtc = to_amdgpu_crtc(con_new_state->base.crtc); -+ if (pflip_needed) -+ return ret; - -- /* Skip any modesets/resets */ -- if (!acrtc || drm_atomic_crtc_needs_modeset(acrtc->base.state)) -- continue; -+ /* Add new planes */ -+ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { -+ new_plane_crtc = new_plane_state->crtc; -+ old_plane_crtc = old_plane_state->crtc; -+ new_dm_plane_state = to_dm_plane_state(new_plane_state); -+ old_dm_plane_state = to_dm_plane_state(old_plane_state); - -- /* Skip any thing not scale or underscan changes */ -- if (!is_scaling_state_different(con_new_state, con_old_state)) -- continue; -+ /*TODO Implement atomic check for cursor plane */ -+ if (plane->type == DRM_PLANE_TYPE_CURSOR) -+ continue; - -- lock_and_validation_needed = true; -- } -+ /* Remove any changed/removed planes */ -+ if (!enable) { - -- /* Add new planes */ -- for_each_crtc_in_state(state, crtc, crtc_state, i) { -- new_acrtc_state = to_dm_crtc_state(crtc_state); -+ if (!old_plane_crtc) -+ continue; - -- if (pflip_needed) -- continue; -+ old_acrtc_state = to_dm_crtc_state( -+ drm_atomic_get_old_crtc_state( -+ state, -+ old_plane_crtc)); - -- for_each_plane_in_state(state, plane, plane_state, j) { -- struct drm_crtc *plane_crtc = plane_state->crtc; -- struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); -+ if (!old_acrtc_state->stream) -+ continue; - -- /*TODO Implement atomic check for cursor plane */ -- if (plane->type == DRM_PLANE_TYPE_CURSOR) -- continue; -+ DRM_DEBUG_KMS("Disabling DRM plane: %d on DRM crtc %d\n", -+ plane->base.id, old_plane_crtc->base.id); - -- if (crtc != plane_crtc) -- continue; -+ if (!dc_remove_plane_from_context( -+ dc, -+ old_acrtc_state->stream, -+ old_dm_plane_state->dc_state, -+ dm_state->context)) { - -- if (!drm_atomic_plane_disabling(plane->state, plane_state)) { -- struct dc_plane_state *dc_plane_state; -+ ret = EINVAL; -+ return ret; -+ } - -- WARN_ON(!new_acrtc_state->stream); - -- dc_plane_state = dc_create_plane_state(dc); -+ dc_plane_state_release(old_dm_plane_state->dc_state); -+ new_dm_plane_state->dc_state = NULL; - -- WARN_ON(dm_plane_state->dc_state); -+ *lock_and_validation_needed = true; - -- dm_plane_state->dc_state = dc_plane_state; -+ } else { /* Add new planes */ - -- ret = fill_plane_attributes( -- plane_crtc->dev->dev_private, -- dc_plane_state, -- plane_state, -- crtc_state, -- false); -- if (ret) -- goto fail; -+ if (drm_atomic_plane_disabling(plane->state, new_plane_state)) -+ continue; - -+ if (!new_plane_crtc) -+ continue; - -- if (!dc_add_plane_to_context( -- dc, -- new_acrtc_state->stream, -- dc_plane_state, -- dm_state->context)) { -+ new_crtc_state = drm_atomic_get_new_crtc_state(state, new_plane_crtc); -+ new_acrtc_state = to_dm_crtc_state(new_crtc_state); - -- ret = EINVAL; -- goto fail; -- } -+ if (!new_acrtc_state->stream) -+ continue; - - -- lock_and_validation_needed = true; -- } -- } -- } -+ WARN_ON(new_dm_plane_state->dc_state); - -- /* Run this here since we want to validate the streams we created */ -- ret = drm_atomic_helper_check_planes(dev, state); -- if (ret) -- goto fail; -+ new_dm_plane_state->dc_state = dc_create_plane_state(dc); - -- /* -- * For full updates case when -- * removing/adding/updating streams on once CRTC while flipping -- * on another CRTC, -- * acquiring global lock will guarantee that any such full -- * update commit -- * will wait for completion of any outstanding flip using DRMs -- * synchronization events. -- */ -+ DRM_DEBUG_KMS("Enabling DRM plane: %d on DRM crtc %d\n", -+ plane->base.id, new_plane_crtc->base.id); - -- if (lock_and_validation_needed) { -+ if (!new_dm_plane_state->dc_state) { -+ ret = -EINVAL; -+ return ret; -+ } - -- ret = do_aquire_global_lock(dev, state); -- if (ret) -- goto fail; -+ ret = fill_plane_attributes( -+ new_plane_crtc->dev->dev_private, -+ new_dm_plane_state->dc_state, -+ new_plane_state, -+ new_crtc_state, -+ false); -+ if (ret) -+ return ret; - -- if (!dc_validate_global_state(dc, dm_state->context)) { -- ret = -EINVAL; -- goto fail; -- } -- } - -- /* Must be success */ -- WARN_ON(ret); -- return ret; -+ if (!dc_add_plane_to_context( -+ dc, -+ new_acrtc_state->stream, -+ new_dm_plane_state->dc_state, -+ dm_state->context)) { - --fail: -- if (ret == -EDEADLK) -- DRM_DEBUG_KMS("Atomic check stopped due to to deadlock.\n"); -- else if (ret == -EINTR || ret == -EAGAIN || ret == -ERESTARTSYS) -- DRM_DEBUG_KMS("Atomic check stopped due to to signal.\n"); -- else -- DRM_ERROR("Atomic check failed with err: %d .\n", ret); -+ ret = -EINVAL; -+ return ret; -+ } - -- return ret; -+ *lock_and_validation_needed = true; -+ } -+ } -+ -+ -+ return ret; -+} -+ -+int amdgpu_dm_atomic_check(struct drm_device *dev, -+ struct drm_atomic_state *state) -+{ -+ int i; -+ int ret; -+ struct amdgpu_device *adev = dev->dev_private; -+ struct dc *dc = adev->dm.dc; -+ struct dm_atomic_state *dm_state = to_dm_atomic_state(state); -+ struct drm_connector *connector; -+ struct drm_connector_state *conn_state; -+ struct drm_crtc *crtc; -+ struct drm_crtc_state *crtc_state; -+ -+ /* -+ * This bool will be set for true for any modeset/reset -+ * or plane update which implies non fast surface update. -+ */ -+ bool lock_and_validation_needed = false; -+ -+ ret = drm_atomic_helper_check_modeset(dev, state); -+ -+ if (ret) { -+ DRM_ERROR("Atomic state validation failed with error :%d !\n", ret); -+ return ret; -+ } -+ -+ /* -+ * Hack: Commit needs planes right now, specifically for gamma -+ * TODO rework commit to check CRTC for gamma change -+ */ -+ for_each_crtc_in_state(state, crtc, crtc_state, i) { -+ if (crtc_state->color_mgmt_changed) { -+ ret = drm_atomic_add_affected_planes(state, crtc); -+ if (ret) -+ goto fail; -+ } -+ } -+ -+ /* Remove exiting planes if they are modified */ -+ ret = dm_update_planes_state(dc, state, false, &lock_and_validation_needed); -+ if (ret) { -+ goto fail; -+ } -+ -+ /* Disable all crtcs which require disable */ -+ ret = dm_update_crtcs_state(dc, state, false, &lock_and_validation_needed); -+ if (ret) { -+ goto fail; -+ } -+ -+ /* Enable all crtcs which require enable */ -+ ret = dm_update_crtcs_state(dc, state, true, &lock_and_validation_needed); -+ if (ret) { -+ goto fail; -+ } -+ -+ /* Add new/modified planes */ -+ ret = dm_update_planes_state(dc, state, true, &lock_and_validation_needed); -+ if (ret) { -+ goto fail; -+ } -+ -+ /* Run this here since we want to validate the streams we created */ -+ ret = drm_atomic_helper_check_planes(dev, state); -+ if (ret) -+ goto fail; -+ -+ /* Check scaling and undersacn changes*/ -+ /*TODO Removed scaling changes validation due to inability to commit -+ * new stream into context w\o causing full reset. Need to -+ * decide how to handle. -+ */ -+ for_each_connector_in_state(state, connector, conn_state, i) { -+ struct amdgpu_connector *aconnector = to_amdgpu_connector(connector); -+ struct dm_connector_state *con_old_state = -+ to_dm_connector_state(aconnector->base.state); -+ struct dm_connector_state *con_new_state = -+ to_dm_connector_state(conn_state); -+ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(con_new_state->base.crtc); -+ -+ /* Skip any modesets/resets */ -+ if (!acrtc || drm_atomic_crtc_needs_modeset(acrtc->base.state)) -+ continue; -+ -+ /* Skip any thing not scale or underscan changes */ -+ if (!is_scaling_state_different(con_new_state, con_old_state)) -+ continue; -+ -+ lock_and_validation_needed = true; -+ } -+ -+ /* -+ * For full updates case when -+ * removing/adding/updating streams on once CRTC while flipping -+ * on another CRTC, -+ * acquiring global lock will guarantee that any such full -+ * update commit -+ * will wait for completion of any outstanding flip using DRMs -+ * synchronization events. -+ */ -+ -+ if (lock_and_validation_needed) { -+ -+ ret = do_aquire_global_lock(dev, state); -+ if (ret) -+ goto fail; -+ -+ if (!dc_validate_global_state(dc, dm_state->context)) { -+ ret = -EINVAL; -+ goto fail; -+ } -+ } -+ -+ /* Must be success */ -+ WARN_ON(ret); -+ return ret; -+ -+fail: -+ if (ret == -EDEADLK) -+ DRM_DEBUG_KMS("Atomic check stopped due to to deadlock.\n"); -+ else if (ret == -EINTR || ret == -EAGAIN || ret == -ERESTARTSYS) -+ DRM_DEBUG_KMS("Atomic check stopped due to to signal.\n"); -+ else -+ DRM_ERROR("Atomic check failed with err: %d \n", ret); -+ -+ return ret; - } - - static bool is_dp_capable_without_timing_msa( --- -2.7.4 - |