Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Only force modesets when toggling HDR

[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@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190528190836.10738-3-nicholas.kazlauskas@amd.com

authored by

Nicholas Kazlauskas and committed by
Harry Wentland
b232d4ed 88694af9

+28 -6
+28 -6
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 3978 3978 * DC considers the stream backends changed if the 3979 3979 * static metadata changes. Forcing the modeset also 3980 3980 * gives a simple way for userspace to switch from 3981 - * 8bpc to 10bpc when setting the metadata. 3981 + * 8bpc to 10bpc when setting the metadata to enter 3982 + * or exit HDR. 3983 + * 3984 + * Changing the static metadata after it's been 3985 + * set is permissible, however. So only force a 3986 + * modeset if we're entering or exiting HDR. 3982 3987 */ 3983 - new_crtc_state->mode_changed = true; 3988 + new_crtc_state->mode_changed = 3989 + !old_con_state->hdr_output_metadata || 3990 + !new_con_state->hdr_output_metadata; 3984 3991 } 3985 3992 3986 3993 return 0; ··· 5888 5881 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); 5889 5882 struct dc_surface_update dummy_updates[MAX_SURFACES]; 5890 5883 struct dc_stream_update stream_update; 5884 + struct dc_info_packet hdr_packet; 5891 5885 struct dc_stream_status *status = NULL; 5886 + bool abm_changed, hdr_changed, scaling_changed; 5892 5887 5893 5888 memset(&dummy_updates, 0, sizeof(dummy_updates)); 5894 5889 memset(&stream_update, 0, sizeof(stream_update)); ··· 5907 5898 dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); 5908 5899 dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); 5909 5900 5910 - if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state) && 5911 - (dm_new_crtc_state->abm_level == dm_old_crtc_state->abm_level)) 5901 + scaling_changed = is_scaling_state_different(dm_new_con_state, 5902 + dm_old_con_state); 5903 + 5904 + abm_changed = dm_new_crtc_state->abm_level != 5905 + dm_old_crtc_state->abm_level; 5906 + 5907 + hdr_changed = 5908 + is_hdr_metadata_different(old_con_state, new_con_state); 5909 + 5910 + if (!scaling_changed && !abm_changed && !hdr_changed) 5912 5911 continue; 5913 5912 5914 - if (is_scaling_state_different(dm_new_con_state, dm_old_con_state)) { 5913 + if (scaling_changed) { 5915 5914 update_stream_scaling_settings(&dm_new_con_state->base.crtc->mode, 5916 5915 dm_new_con_state, (struct dc_stream_state *)dm_new_crtc_state->stream); 5917 5916 ··· 5927 5910 stream_update.dst = dm_new_crtc_state->stream->dst; 5928 5911 } 5929 5912 5930 - if (dm_new_crtc_state->abm_level != dm_old_crtc_state->abm_level) { 5913 + if (abm_changed) { 5931 5914 dm_new_crtc_state->stream->abm_level = dm_new_crtc_state->abm_level; 5932 5915 5933 5916 stream_update.abm_level = &dm_new_crtc_state->abm_level; 5917 + } 5918 + 5919 + if (hdr_changed) { 5920 + fill_hdr_info_packet(new_con_state, &hdr_packet); 5921 + stream_update.hdr_static_metadata = &hdr_packet; 5934 5922 } 5935 5923 5936 5924 status = dc_stream_get_status(dm_new_crtc_state->stream);