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@xxxxxxx> > --- > 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@xxxxxxx> > + */ > + 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 > _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx