[PATCH 2/2] drm/amd/display: Fix Scaling (RMX_*) for DC driver
Li, Sun peng (Leo)
Sunpeng.Li at amd.com
Wed Nov 21 14:37:45 UTC 2018
On 2018-11-16 2:59 p.m., Bhawanpreet Lakha wrote:
> Before:
> We use drm_match_cea_mode() to get the vic for any mode we
> want to set, most of the time vic will be different for the new mode.
>
> DC uses memcmp to check if timing changed, in this case DC will
> say timing changed and we endup doing a full modeset.
>
> Current:
> Now we check if !RMX_OFF and old_refresh == new_refresh if so
> we copy the vic from old timing. In a case where we are currently on
> a lower timing and want to change to higher mode, stream->dst will be
> different and cause us to do a full modeset, which is what we want.
>
> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
> ---
> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 49 ++++++++++++++++++-----
> 1 file changed, 38 insertions(+), 11 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 e0328e8dcff3..61e994770f08 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -2554,7 +2554,8 @@ static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_
> static void
> fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
> const struct drm_display_mode *mode_in,
> - const struct drm_connector *connector)
> + const struct drm_connector *connector,
> + const struct dc_stream_state *old_stream)
> {
> struct dc_crtc_timing *timing_out = &stream->timing;
> const struct drm_display_info *info = &connector->display_info;
> @@ -2580,7 +2581,18 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
> connector);
> timing_out->scan_type = SCANNING_TYPE_NODATA;
> timing_out->hdmi_vic = 0;
> - timing_out->vic = drm_match_cea_mode(mode_in);
> +
> + if(old_stream) {
> + timing_out->vic = old_stream->timing.vic;
> + timing_out->flags.HSYNC_POSITIVE_POLARITY = old_stream->timing.flags.HSYNC_POSITIVE_POLARITY;
> + timing_out->flags.VSYNC_POSITIVE_POLARITY = old_stream->timing.flags.VSYNC_POSITIVE_POLARITY;
> + } else {
> + timing_out->vic = drm_match_cea_mode(mode_in);
> + if (mode_in->flags & DRM_MODE_FLAG_PHSYNC)
> + timing_out->flags.HSYNC_POSITIVE_POLARITY = 1;
> + if (mode_in->flags & DRM_MODE_FLAG_PVSYNC)
> + timing_out->flags.VSYNC_POSITIVE_POLARITY = 1;
> + }
>
> timing_out->h_addressable = mode_in->crtc_hdisplay;
> timing_out->h_total = mode_in->crtc_htotal;
> @@ -2596,10 +2608,6 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
> mode_in->crtc_vsync_end - mode_in->crtc_vsync_start;
> timing_out->pix_clk_khz = mode_in->crtc_clock;
> timing_out->aspect_ratio = get_aspect_ratio(mode_in);
> - if (mode_in->flags & DRM_MODE_FLAG_PHSYNC)
> - timing_out->flags.HSYNC_POSITIVE_POLARITY = 1;
> - if (mode_in->flags & DRM_MODE_FLAG_PVSYNC)
> - timing_out->flags.VSYNC_POSITIVE_POLARITY = 1;
>
> stream->output_color_space = get_output_color_space(timing_out);
>
> @@ -2762,13 +2770,18 @@ static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context)
> static struct dc_stream_state *
> create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
> const struct drm_display_mode *drm_mode,
> - const struct dm_connector_state *dm_state)
> + const struct dm_connector_state *dm_state,
> + const struct dc_stream_state *old_stream)
> {
> struct drm_display_mode *preferred_mode = NULL;
> struct drm_connector *drm_connector;
> struct dc_stream_state *stream = NULL;
> struct drm_display_mode mode = *drm_mode;
> bool native_mode_found = false;
> + bool scale = dm_state ? (dm_state->scaling != RMX_OFF) : false;
> + int mode_refresh;
> + int preferred_refresh;
> +
> struct dc_sink *sink = NULL;
> if (aconnector == NULL) {
> DRM_ERROR("aconnector is NULL!\n");
> @@ -2807,6 +2820,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
> struct drm_display_mode,
> head);
>
> + mode_refresh = drm_mode_vrefresh(&mode);
> +
> if (preferred_mode == NULL) {
> /*
> * This may not be an error, the use case is when we have no
> @@ -2824,8 +2839,19 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
> if (!dm_state)
> drm_mode_set_crtcinfo(&mode, 0);
>
> - fill_stream_properties_from_drm_display_mode(stream,
> - &mode, &aconnector->base);
> + preferred_refresh = drm_mode_vrefresh(preferred_mode);
> +
> + /*
> + * If scaling is enabled and refresh rate didn't change
> + * we copy the vic and polarities of the old timings, in case
Looks like something got cut in the comments?
With that fixed, series is
Reviewed-by: Leo Li <sunpeng.li at amd.com>
> + */
> + if (!scale || mode_refresh != preferred_refresh)
> + fill_stream_properties_from_drm_display_mode(stream,
> + &mode, &aconnector->base, NULL);
> + else
> + fill_stream_properties_from_drm_display_mode(stream,
> + &mode, &aconnector->base, old_stream);
> +
> update_stream_scaling_settings(&mode, dm_state, stream);
>
> fill_audio_info(
> @@ -3246,7 +3272,7 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec
> goto fail;
> }
>
> - stream = create_stream_for_sink(aconnector, mode, NULL);
> + stream = create_stream_for_sink(aconnector, mode, NULL, NULL);
> if (stream == NULL) {
> DRM_ERROR("Failed to create stream for sink!\n");
> goto fail;
> @@ -5109,7 +5135,8 @@ static int dm_update_crtcs_state(struct amdgpu_display_manager *dm,
>
> new_stream = create_stream_for_sink(aconnector,
> &new_crtc_state->mode,
> - dm_new_conn_state);
> + dm_new_conn_state,
> + dm_old_crtc_state->stream);
>
> /*
> * we can have no stream on ACTION_SET if a display
>
More information about the amd-gfx
mailing list