diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1049-drm-amd-display-Move-iteration-out-of-dm_update_crtc.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1049-drm-amd-display-Move-iteration-out-of-dm_update_crtc.patch | 446 |
1 files changed, 446 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1049-drm-amd-display-Move-iteration-out-of-dm_update_crtc.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1049-drm-amd-display-Move-iteration-out-of-dm_update_crtc.patch new file mode 100644 index 00000000..5d301964 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1049-drm-amd-display-Move-iteration-out-of-dm_update_crtc.patch @@ -0,0 +1,446 @@ +From 3edb872251b939022310a7dd1df099236ac744d5 Mon Sep 17 00:00:00 2001 +From: Leo Li <sunpeng.li@amd.com> +Date: Sun, 11 Nov 2018 11:35:13 -0500 +Subject: [PATCH 1049/2940] drm/amd/display: Move iteration out of + dm_update_crtcs + +[Why] +To reduce indent in dm_update_crtcs, and to make it operate on single +instances. + +[How] +Move iteration of plane states into atomic_check. +No functional change is intended. + +Signed-off-by: Leo Li <sunpeng.li@amd.com> +Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Chaudhary Amit Kumar <Chaudharyamit.Kumar@amd.com> +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 372 +++++++++--------- + 1 file changed, 187 insertions(+), 185 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 7a0c9bd48703..355939d3ab71 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -5492,213 +5492,205 @@ static void reset_freesync_config_for_crtc( + sizeof(new_crtc_state->vrr_infopacket)); + } + +-static int dm_update_crtcs_state(struct amdgpu_display_manager *dm, +- struct drm_atomic_state *state, +- bool enable, +- bool *lock_and_validation_needed) ++static int dm_update_crtc_state(struct amdgpu_display_manager *dm, ++ struct drm_atomic_state *state, ++ struct drm_crtc *crtc, ++ struct drm_crtc_state *old_crtc_state, ++ struct drm_crtc_state *new_crtc_state, ++ bool enable, ++ bool *lock_and_validation_needed) + { + struct dm_atomic_state *dm_state = NULL; +- struct drm_crtc *crtc; +- struct drm_crtc_state *old_crtc_state, *new_crtc_state; +- int i; + struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state; + struct dc_stream_state *new_stream; + int ret = 0; + +- /*TODO Move this code into dm_crtc_atomic_check once we get rid of dc_validation_set */ +- /* update changed items */ +- for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { +- struct amdgpu_crtc *acrtc = NULL; +- struct amdgpu_dm_connector *aconnector = NULL; +- struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_conn_state = NULL; +- struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state = NULL; +- struct drm_plane_state *new_plane_state = NULL; +- +- new_stream = NULL; +- +- dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); +- dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); +- acrtc = to_amdgpu_crtc(crtc); +- +- new_plane_state = drm_atomic_get_new_plane_state(state, new_crtc_state->crtc->primary); +- +- if (new_crtc_state->enable && new_plane_state && !new_plane_state->fb) { +- ret = -EINVAL; +- goto fail; +- } +- +- aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc); +- +- /* TODO This hack should go away */ +- if (aconnector && enable) { +- /* Make sure fake sink is created in plug-in scenario */ +- drm_new_conn_state = drm_atomic_get_new_connector_state(state, +- &aconnector->base); +- drm_old_conn_state = drm_atomic_get_old_connector_state(state, +- &aconnector->base); +- +- if (IS_ERR(drm_new_conn_state)) { +- ret = PTR_ERR_OR_ZERO(drm_new_conn_state); +- break; +- } +- +- dm_new_conn_state = to_dm_connector_state(drm_new_conn_state); +- dm_old_conn_state = to_dm_connector_state(drm_old_conn_state); ++ /* ++ * TODO Move this code into dm_crtc_atomic_check once we get rid of dc_validation_set ++ * update changed items ++ */ ++ struct amdgpu_crtc *acrtc = NULL; ++ struct amdgpu_dm_connector *aconnector = NULL; ++ struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_conn_state = NULL; ++ struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state = NULL; ++ struct drm_plane_state *new_plane_state = NULL; + +- new_stream = create_stream_for_sink(aconnector, +- &new_crtc_state->mode, +- dm_new_conn_state, +- dm_old_crtc_state->stream); ++ new_stream = NULL; + +- /* +- * we can have no stream on ACTION_SET if a display +- * was disconnected during S3, in this case it not an +- * error, the OS will be updated after detection, and +- * will do the right thing on next atomic commit +- */ ++ dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); ++ dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); ++ acrtc = to_amdgpu_crtc(crtc); + +- if (!new_stream) { +- DRM_DEBUG_DRIVER("%s: Failed to create new stream for crtc %d\n", +- __func__, acrtc->base.base.id); +- break; +- } ++ new_plane_state = drm_atomic_get_new_plane_state(state, new_crtc_state->crtc->primary); + +- dm_new_crtc_state->abm_level = dm_new_conn_state->abm_level; ++ if (new_crtc_state->enable && new_plane_state && !new_plane_state->fb) { ++ ret = -EINVAL; ++ goto fail; ++ } + +- if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) && +- dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) { +- new_crtc_state->mode_changed = false; +- DRM_DEBUG_DRIVER("Mode change not required, setting mode_changed to %d", +- new_crtc_state->mode_changed); +- } ++ aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc); ++ ++ /* TODO This hack should go away */ ++ if (aconnector && enable) { ++ /* Make sure fake sink is created in plug-in scenario */ ++ drm_new_conn_state = drm_atomic_get_new_connector_state(state, ++ &aconnector->base); ++ drm_old_conn_state = drm_atomic_get_old_connector_state(state, ++ &aconnector->base); ++ if (IS_ERR(drm_new_conn_state)) { ++ ret = PTR_ERR_OR_ZERO(drm_new_conn_state); ++ goto fail; ++ } ++ ++ dm_new_conn_state = to_dm_connector_state(drm_new_conn_state); ++ dm_old_conn_state = to_dm_connector_state(drm_old_conn_state); ++ ++ new_stream = create_stream_for_sink(aconnector, ++ &new_crtc_state->mode, ++ dm_new_conn_state, ++ dm_old_crtc_state->stream); ++ /* ++ * we can have no stream on ACTION_SET if a display ++ * was disconnected during S3, in this case it is not an ++ * error, the OS will be updated after detection, and ++ * will do the right thing on next atomic commit ++ */ ++ if (!new_stream) { ++ DRM_DEBUG_DRIVER("%s: Failed to create new stream for crtc %d\n", ++ __func__, acrtc->base.base.id); ++ ret = -ENOMEM; ++ goto fail; ++ } ++ ++ dm_new_crtc_state->abm_level = dm_new_conn_state->abm_level; ++ if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) && ++ dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) { ++ new_crtc_state->mode_changed = false; ++ DRM_DEBUG_DRIVER("Mode change not required, setting mode_changed to %d", ++ new_crtc_state->mode_changed); + } ++ } + +- if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) +- goto next_crtc; +- +- DRM_DEBUG_DRIVER( +- "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " +- "planes_changed:%d, mode_changed:%d,active_changed:%d," +- "connectors_changed:%d\n", +- acrtc->crtc_id, +- new_crtc_state->enable, +- new_crtc_state->active, +- new_crtc_state->planes_changed, +- new_crtc_state->mode_changed, +- new_crtc_state->active_changed, +- new_crtc_state->connectors_changed); +- +- /* Remove stream for any changed/disabled CRTC */ +- if (!enable) { +- +- if (!dm_old_crtc_state->stream) +- goto next_crtc; +- +- ret = dm_atomic_get_state(state, &dm_state); +- if (ret) +- goto fail; +- +- DRM_DEBUG_DRIVER("Disabling DRM crtc: %d\n", +- crtc->base.id); +- +- /* i.e. reset mode */ +- if (dc_remove_stream_from_ctx( +- dm->dc, +- dm_state->context, +- dm_old_crtc_state->stream) != DC_OK) { +- ret = -EINVAL; +- goto fail; +- } +- +- dc_stream_release(dm_old_crtc_state->stream); +- dm_new_crtc_state->stream = NULL; +- +- reset_freesync_config_for_crtc(dm_new_crtc_state); +- +- *lock_and_validation_needed = true; ++ if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) ++ goto skip_modeset; ++ ++ DRM_DEBUG_DRIVER( ++ "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " ++ "planes_changed:%d, mode_changed:%d,active_changed:%d," ++ "connectors_changed:%d\n", ++ acrtc->crtc_id, ++ new_crtc_state->enable, ++ new_crtc_state->active, ++ new_crtc_state->planes_changed, ++ new_crtc_state->mode_changed, ++ new_crtc_state->active_changed, ++ new_crtc_state->connectors_changed); ++ ++ /* Remove stream for any changed/disabled CRTC */ ++ if (!enable) { + +- } else {/* Add stream for any updated/enabled CRTC */ +- /* +- * Quick fix to prevent NULL pointer on new_stream when +- * added MST connectors not found in existing crtc_state in the chained mode +- * TODO: need to dig out the root cause of that +- */ +- if (!aconnector || (!aconnector->dc_sink && aconnector->mst_port)) +- goto next_crtc; ++ if (!dm_old_crtc_state->stream) ++ goto skip_modeset; + +- if (modereset_required(new_crtc_state)) +- goto next_crtc; ++ ret = dm_atomic_get_state(state, &dm_state); ++ if (ret) ++ goto fail; + +- if (modeset_required(new_crtc_state, new_stream, +- dm_old_crtc_state->stream)) { ++ DRM_DEBUG_DRIVER("Disabling DRM crtc: %d\n", ++ crtc->base.id); ++ /* i.e. reset mode */ ++ if (dc_remove_stream_from_ctx( ++ dm->dc, ++ dm_state->context, ++ dm_old_crtc_state->stream) != DC_OK) { ++ ret = -EINVAL; ++ goto fail; ++ } + +- WARN_ON(dm_new_crtc_state->stream); ++ dc_stream_release(dm_old_crtc_state->stream); ++ dm_new_crtc_state->stream = NULL; + +- ret = dm_atomic_get_state(state, &dm_state); +- if (ret) +- goto fail; ++ reset_freesync_config_for_crtc(dm_new_crtc_state); + +- dm_new_crtc_state->stream = new_stream; ++ *lock_and_validation_needed = true; + +- dc_stream_retain(new_stream); ++ } else {/* Add stream for any updated/enabled CRTC */ ++ /* ++ * Quick fix to prevent NULL pointer on new_stream when ++ * added MST connectors not found in existing crtc_state in the chained mode ++ * TODO: need to dig out the root cause of that ++ */ ++ if (!aconnector || (!aconnector->dc_sink && aconnector->mst_port)) ++ goto skip_modeset; + +- DRM_DEBUG_DRIVER("Enabling DRM crtc: %d\n", +- crtc->base.id); ++ if (modereset_required(new_crtc_state)) ++ goto skip_modeset; + +- if (dc_add_stream_to_ctx( +- dm->dc, +- dm_state->context, +- dm_new_crtc_state->stream) != DC_OK) { +- ret = -EINVAL; +- goto fail; +- } ++ if (modeset_required(new_crtc_state, new_stream, ++ dm_old_crtc_state->stream)) { ++ ++ WARN_ON(dm_new_crtc_state->stream); ++ ret = dm_atomic_get_state(state, &dm_state); ++ if (ret) ++ goto fail; ++ dm_new_crtc_state->stream = new_stream; ++ dc_stream_retain(new_stream); ++ ++ DRM_DEBUG_DRIVER("Enabling DRM crtc: %d\n", ++ crtc->base.id); ++ if (dc_add_stream_to_ctx( ++ dm->dc, ++ dm_state->context, ++ dm_new_crtc_state->stream) != DC_OK) { ++ ret = -EINVAL; ++ goto fail; + +- *lock_and_validation_needed = true; + } +- } ++ *lock_and_validation_needed = true; ++ } ++ } + +-next_crtc: +- /* Release extra reference */ +- if (new_stream) +- dc_stream_release(new_stream); ++skip_modeset: ++ /* Release extra reference */ ++ if (new_stream) ++ dc_stream_release(new_stream); + +- /* +- * We want to do dc stream updates that do not require a +- * full modeset below. +- */ +- if (!(enable && aconnector && new_crtc_state->enable && +- new_crtc_state->active)) +- continue; +- /* +- * Given above conditions, the dc state cannot be NULL because: +- * 1. We're in the process of enabling CRTCs (just been added +- * to the dc context, or already is on the context) +- * 2. Has a valid connector attached, and +- * 3. Is currently active and enabled. +- * => The dc stream state currently exists. +- */ +- BUG_ON(dm_new_crtc_state->stream == NULL); +- +- /* Scaling or underscan settings */ +- if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state)) +- update_stream_scaling_settings( +- &new_crtc_state->mode, dm_new_conn_state, dm_new_crtc_state->stream); ++ /* ++ * We want to do dc stream updates that do not require a ++ * full modeset below. ++ */ ++ if (!(enable && aconnector && new_crtc_state->enable && ++ new_crtc_state->active)) ++ return 0; ++ /* ++ * Given above conditions, the dc state cannot be NULL because: ++ * 1. We're in the process of enabling CRTCs (just been added ++ * to the dc context, or already is on the context) ++ * 2. Has a valid connector attached, and ++ * 3. Is currently active and enabled. ++ * => The dc stream state currently exists. ++ */ ++ BUG_ON(dm_new_crtc_state->stream == NULL); + +- /* +- * Color management settings. We also update color properties +- * when a modeset is needed, to ensure it gets reprogrammed. +- */ +- if (dm_new_crtc_state->base.color_mgmt_changed || +- drm_atomic_crtc_needs_modeset(new_crtc_state)) { +- ret = amdgpu_dm_set_regamma_lut(dm_new_crtc_state); +- if (ret) +- goto fail; +- amdgpu_dm_set_ctm(dm_new_crtc_state); +- } +- /* Update Freesync settings. */ +- get_freesync_config_for_crtc(dm_new_crtc_state, +- dm_new_conn_state); ++ /* Scaling or underscan settings */ ++ if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state)) ++ update_stream_scaling_settings( ++ &new_crtc_state->mode, dm_new_conn_state, dm_new_crtc_state->stream); ++ /* ++ * Color management settings. We also update color properties ++ * when a modeset is needed, to ensure it gets reprogrammed. ++ */ ++ if (dm_new_crtc_state->base.color_mgmt_changed || ++ drm_atomic_crtc_needs_modeset(new_crtc_state)) { ++ ret = amdgpu_dm_set_regamma_lut(dm_new_crtc_state); ++ if (ret) ++ goto fail; ++ amdgpu_dm_set_ctm(dm_new_crtc_state); + } ++ /* Update Freesync settings. */ ++ get_freesync_config_for_crtc(dm_new_crtc_state, ++ dm_new_conn_state); ++ + + return ret; + +@@ -6048,15 +6040,25 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, + } + + /* Disable all crtcs which require disable */ +- ret = dm_update_crtcs_state(&adev->dm, state, false, &lock_and_validation_needed); +- if (ret) { +- goto fail; ++ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { ++ ret = dm_update_crtc_state(&adev->dm, state, crtc, ++ old_crtc_state, ++ new_crtc_state, ++ false, ++ &lock_and_validation_needed); ++ if (ret) ++ goto fail; + } + + /* Enable all crtcs which require enable */ +- ret = dm_update_crtcs_state(&adev->dm, state, true, &lock_and_validation_needed); +- if (ret) { +- goto fail; ++ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { ++ ret = dm_update_crtc_state(&adev->dm, state, crtc, ++ old_crtc_state, ++ new_crtc_state, ++ true, ++ &lock_and_validation_needed); ++ if (ret) ++ goto fail; + } + + /* Add new/modified planes */ +-- +2.17.1 + |