diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0251-drm-amd-display-Refactor-headless-to-use-atomic-comm.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0251-drm-amd-display-Refactor-headless-to-use-atomic-comm.patch | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0251-drm-amd-display-Refactor-headless-to-use-atomic-comm.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0251-drm-amd-display-Refactor-headless-to-use-atomic-comm.patch new file mode 100644 index 00000000..00e61531 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0251-drm-amd-display-Refactor-headless-to-use-atomic-comm.patch @@ -0,0 +1,194 @@ +From 0617e90af970155938268d968b429c9e4d274684 Mon Sep 17 00:00:00 2001 +From: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> +Date: Sun, 5 Feb 2017 21:48:19 -0500 +Subject: [PATCH 0251/4131] drm/amd/display: Refactor headless to use atomic + commit. (v2) + +Headless mode set needs to be synchronized against outstanding nonblocking +commits. This achieved by building atomic state and commiting it. + +v2: rebase on 4.11 + +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> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c | 140 +++++++++------------ + 1 file changed, 61 insertions(+), 79 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c +index b6dc0ca..1e4f2b7 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c +@@ -2772,6 +2772,65 @@ void amdgpu_dm_atomic_commit_tail( + /* Release old FB */ + drm_atomic_helper_cleanup_planes(dev, state); + } ++ ++ ++static int dm_force_atomic_commit(struct drm_connector *connector) ++{ ++ int ret = 0; ++ struct drm_device *ddev = connector->dev; ++ struct drm_atomic_state *state = drm_atomic_state_alloc(ddev); ++ struct amdgpu_crtc *disconnected_acrtc = to_amdgpu_crtc(connector->encoder->crtc); ++ struct drm_plane *plane = disconnected_acrtc->base.primary; ++ struct drm_connector_state *conn_state; ++ struct drm_crtc_state *crtc_state; ++ struct drm_plane_state *plane_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 ++ */ ++ conn_state = drm_atomic_get_connector_state(state, connector); ++ ++ ret = PTR_ERR_OR_ZERO(conn_state); ++ if (ret) ++ goto err; ++ ++ /* Attach crtc to drm_atomic_state*/ ++ crtc_state = drm_atomic_get_crtc_state(state, &disconnected_acrtc->base); ++ ++ ret = PTR_ERR_OR_ZERO(crtc_state); ++ if (ret) ++ goto err; ++ ++ /* force a restore */ ++ crtc_state->mode_changed = true; ++ ++ /* Attach plane to drm_atomic_state */ ++ plane_state = drm_atomic_get_plane_state(state, plane); ++ ++ ret = PTR_ERR_OR_ZERO(plane_state); ++ 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_put(state); ++ ++ return ret; ++} ++ + /* + * This functions handle all cases when set mode does not come upon hotplug. + * This include when the same display is unplugged then plugged back into the +@@ -2779,15 +2838,8 @@ void amdgpu_dm_atomic_commit_tail( + */ + void dm_restore_drm_connector_state(struct drm_device *dev, struct drm_connector *connector) + { +- struct drm_crtc *crtc; +- struct amdgpu_device *adev = dev->dev_private; +- struct dc *dc = adev->dm.dc; + struct amdgpu_connector *aconnector = to_amdgpu_connector(connector); + struct amdgpu_crtc *disconnected_acrtc; +- const struct dc_sink *sink; +- const struct dc_stream *commit_streams[MAX_STREAMS]; +- const struct dc_stream *current_stream; +- uint32_t commit_streams_count = 0; + + if (!aconnector->dc_sink || !connector->state || !connector->encoder) + return; +@@ -2797,83 +2849,13 @@ void dm_restore_drm_connector_state(struct drm_device *dev, struct drm_connector + if (!disconnected_acrtc || !disconnected_acrtc->stream) + return; + +- sink = disconnected_acrtc->stream->sink; +- + /* + * If the previous sink is not released and different from the current, + * we deduce we are in a state where we can not rely on usermode call + * to turn on the display, so we do it here + */ +- if (sink != aconnector->dc_sink) { +- struct dm_connector_state *dm_state = +- to_dm_connector_state(aconnector->base.state); +- +- struct dc_stream *new_stream = +- create_stream_for_sink( +- aconnector, +- &disconnected_acrtc->base.state->mode, +- dm_state); +- +- DRM_INFO("Headless hotplug, restoring connector state\n"); +- /* +- * we evade vblanks and pflips on crtc that +- * should be changed +- */ +- manage_dm_interrupts(adev, disconnected_acrtc, false); +- /* this is the update mode case */ +- +- current_stream = disconnected_acrtc->stream; +- +- disconnected_acrtc->stream = new_stream; +- disconnected_acrtc->enabled = true; +- disconnected_acrtc->hw_mode = disconnected_acrtc->base.state->mode; +- +- commit_streams_count = 0; +- +- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { +- struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); +- +- if (acrtc->stream) { +- commit_streams[commit_streams_count] = acrtc->stream; +- ++commit_streams_count; +- } +- } +- +- /* DC is optimized not to do anything if 'streams' didn't change. */ +- if (!dc_commit_streams(dc, commit_streams, +- commit_streams_count)) { +- DRM_INFO("Failed to restore connector state!\n"); +- dc_stream_release(disconnected_acrtc->stream); +- disconnected_acrtc->stream = current_stream; +- manage_dm_interrupts(adev, disconnected_acrtc, true); +- return; +- } +- +- if (adev->dm.freesync_module) { +- mod_freesync_remove_stream(adev->dm.freesync_module, +- current_stream); +- +- mod_freesync_add_stream(adev->dm.freesync_module, +- new_stream, &aconnector->caps); +- } +- +- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { +- struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); +- +- if (acrtc->stream != NULL) { +- acrtc->otg_inst = +- dc_stream_get_status(acrtc->stream)->primary_otg_inst; +- } +- } +- +- dc_stream_release(current_stream); +- +- dm_dc_surface_commit(dc, &disconnected_acrtc->base); +- +- manage_dm_interrupts(adev, disconnected_acrtc, true); +- dm_crtc_cursor_reset(&disconnected_acrtc->base); +- +- } ++ if (disconnected_acrtc->stream->sink != aconnector->dc_sink) ++ dm_force_atomic_commit(&aconnector->base); + } + + static uint32_t add_val_sets_surface( +-- +2.7.4 + |