[Why] We can issue HDR static metadata as part of stream updates for non-modesets as long as we force a modeset when entering or exiting HDR. This avoids unnecessary blanking for simple metadata updates. [How] When changing scaling and abm for the stream also check if HDR has changed and send the stream update. This will only happen in non-modeset cases. Cc: Harry Wentland <harry.wentland@xxxxxxx> Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@xxxxxxx> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 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 eb31acca7ed6..443b13ec268d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3978,9 +3978,16 @@ amdgpu_dm_connector_atomic_check(struct drm_connector *conn, * DC considers the stream backends changed if the * static metadata changes. Forcing the modeset also * gives a simple way for userspace to switch from - * 8bpc to 10bpc when setting the metadata. + * 8bpc to 10bpc when setting the metadata to enter + * or exit HDR. + * + * Changing the static metadata after it's been + * set is permissible, however. So only force a + * modeset if we're entering or exiting HDR. */ - new_crtc_state->mode_changed = true; + new_crtc_state->mode_changed = + !old_con_state->hdr_output_metadata || + !new_con_state->hdr_output_metadata; } return 0; @@ -5881,7 +5888,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); struct dc_surface_update dummy_updates[MAX_SURFACES]; struct dc_stream_update stream_update; + struct dc_info_packet hdr_packet; struct dc_stream_status *status = NULL; + bool abm_changed, hdr_changed, scaling_changed; memset(&dummy_updates, 0, sizeof(dummy_updates)); memset(&stream_update, 0, sizeof(stream_update)); @@ -5898,11 +5907,19 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); - if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state) && - (dm_new_crtc_state->abm_level == dm_old_crtc_state->abm_level)) + scaling_changed = is_scaling_state_different(dm_new_con_state, + dm_old_con_state); + + abm_changed = dm_new_crtc_state->abm_level != + dm_old_crtc_state->abm_level; + + hdr_changed = + is_hdr_metadata_different(old_con_state, new_con_state); + + if (!scaling_changed && !abm_changed && !hdr_changed) continue; - if (is_scaling_state_different(dm_new_con_state, dm_old_con_state)) { + if (scaling_changed) { update_stream_scaling_settings(&dm_new_con_state->base.crtc->mode, dm_new_con_state, (struct dc_stream_state *)dm_new_crtc_state->stream); @@ -5910,12 +5927,17 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) stream_update.dst = dm_new_crtc_state->stream->dst; } - if (dm_new_crtc_state->abm_level != dm_old_crtc_state->abm_level) { + if (abm_changed) { dm_new_crtc_state->stream->abm_level = dm_new_crtc_state->abm_level; stream_update.abm_level = &dm_new_crtc_state->abm_level; } + if (hdr_changed) { + fill_hdr_info_packet(new_con_state, &hdr_packet); + stream_update.hdr_static_metadata = &hdr_packet; + } + status = dc_stream_get_status(dm_new_crtc_state->stream); WARN_ON(!status); WARN_ON(!status->plane_count); -- 2.17.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel