[PATCH 3/3] drm/amd/display: Skip modeset for front porch change

Shashank Sharma shashank.sharma at amd.com
Fri Dec 11 05:08:41 UTC 2020


On 10/12/20 11:20 pm, Aurabindo Pillai wrote:
> On Thu, 2020-12-10 at 18:29 +0530, Shashank Sharma wrote:
>> On 10/12/20 8:15 am, Aurabindo Pillai wrote:
>>> [Why&How]
>>> Inorder to enable freesync video mode, driver adds extra
>>> modes based on preferred modes for common freesync frame rates.
>>> When commiting these mode changes, a full modeset is not needed.
>>> If the change in only in the front porch timing value, skip full
>>> modeset and continue using the same stream.
>>>
>>> Signed-off-by: Aurabindo Pillai <
>>> aurabindo.pillai at amd.com
>>> ---
>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 169
>>> ++++++++++++++++--
>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   1 +
>>>  2 files changed, 153 insertions(+), 17 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 f699a3d41cad..c8c72887906a 100644
>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>> @@ -217,6 +217,9 @@ static bool amdgpu_dm_psr_disable_all(struct
>>> amdgpu_display_manager *dm);
>>>  static const struct drm_format_info *
>>>  amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd);
>>>  
>>> +static bool
>>> +is_timing_unchanged_for_freesync(struct drm_crtc_state
>>> *old_crtc_state,
>>> +				 struct drm_crtc_state
>>> *new_crtc_state);
>>>  /*
>>>   * dm_vblank_get_counter
>>>   *
>>> @@ -5096,8 +5099,11 @@ copy_crtc_timing_for_drm_display_mode(const
>>> struct drm_display_mode *src_mode,
>>>  static void
>>>  decide_crtc_timing_for_drm_display_mode(struct drm_display_mode
>>> *drm_mode,
>>>  					const struct drm_display_mode
>>> *native_mode,
>>> -					bool scale_enabled)
>>> +					bool scale_enabled, bool
>>> fs_mode)
>>>  {
>>> +	if (fs_mode)
>>> +		return;
>> so we are adding an input flag just so that we can return from the
>> function at top ? How about adding this check at the caller without
>> changing the function parameters ?
> Will fix this.
>
>>> +
>>>  	if (scale_enabled) {
>>>  		copy_crtc_timing_for_drm_display_mode(native_mode,
>>> drm_mode);
>>>  	} else if (native_mode->clock == drm_mode->clock &&
>>> @@ -5241,6 +5247,24 @@ get_highest_freesync_mode(struct
>>> amdgpu_dm_connector *aconnector,
>>>  	return m_high;
>>>  }
>>>  
>>> +static bool is_freesync_video_mode(struct drm_display_mode *mode,
>>> +				   struct amdgpu_dm_connector
>>> *aconnector)
>>> +{
>>> +	struct drm_display_mode *high_mode;
>>> +
>> I thought we were adding a string "_FSV" in the end for the mode-
>>> name, why can't we check that instead of going through the whole
>> list of modes again ?
> Actually I only added _FSV to distinguish the newly added modes easily.
> On second thoughts, I'm not sure if there are any userspace
> applications that might depend on parsing the mode name, for maybe to
> print the resolution. I think its better not to break any such
> assumptions if they do exist by any chance. I think I'll just remove
> _FSV from the mode name. We already set DRM_MODE_TYPE_DRIVER for
> userspace to recognize these additional modes, so it shouldnt be a
> problem.

Actually, I am rather happy with this, as in when we want to test out this feature with a IGT type stuff, or if a userspace wants to utilize this option in any way, this method of differentiation would be useful. DRM_MODE_DRIVER is being used by some other places apart from freesync, so it might not be a unique identifier. So my recommendation would be to keep this.

My comment was, if we have already parsed the whole connector list once, and added the mode, there should be a better way of doing it instead of checking it again by calling "get_highest_freesync_mod"

Some things I can think on top of my mind would be:

- Add a read-only amdgpu driver private flag (not DRM flag), while adding a new freesync mode, which will uniquely identify if a mode is FS mode. On modeset, you have to just check that flag.

- As we are not handling a lot of modes, cache the FS modes locally and check only from that DB (instead of the whole modelist)

- Cache the VIC of the mode (if available) and then look into the VIC table (not sure if detailed modes provide VIC, like CEA-861 modes)

or something better than this.

- Shashank

>>> +	high_mode = get_highest_freesync_mode(aconnector, false);
>>> +	if (!high_mode)
>>> +		return false;
>>> +
>>> +	if (high_mode->clock == 0 ||
>>> +	    high_mode->hdisplay != mode->hdisplay ||
>>> +	    high_mode->clock != mode->clock ||
>>> +	    !mode)
>>> +		return false;
>>> +	else
>>> +		return true;
>>> +}
>>> +
>>>  static struct dc_stream_state *
>>>  create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
>>>  		       const struct drm_display_mode *drm_mode,
>>> @@ -5253,17 +5277,21 @@ create_stream_for_sink(struct
>>> amdgpu_dm_connector *aconnector,
>>>  	const struct drm_connector_state *con_state =
>>>  		dm_state ? &dm_state->base : NULL;
>>>  	struct dc_stream_state *stream = NULL;
>>> -	struct drm_display_mode mode = *drm_mode;
>>> +	struct drm_display_mode saved_mode, mode = *drm_mode;
>> How about shifting this definition to new line to follow the existing
>> convention ?
> Sure.
>
>>> +	struct drm_display_mode *freesync_mode = NULL;
>>>  	bool native_mode_found = false;
>>>  	bool scale = dm_state ? (dm_state->scaling != RMX_OFF) : false;
>>>  	int mode_refresh;
>>>  	int preferred_refresh = 0;
>>> +	bool is_fs_vid_mode = 0;
>>>  #if defined(CONFIG_DRM_AMD_DC_DCN)
>>>  	struct dsc_dec_dpcd_caps dsc_caps;
>>>  #endif
>>>  	uint32_t link_bandwidth_kbps;
>>> -
>>>  	struct dc_sink *sink = NULL;
>>> +
>>> +	memset(&saved_mode, 0, sizeof(struct drm_display_mode));
>>> +
>>>  	if (aconnector == NULL) {
>>>  		DRM_ERROR("aconnector is NULL!\n");
>>>  		return stream;
>>> @@ -5316,20 +5344,33 @@ create_stream_for_sink(struct
>>> amdgpu_dm_connector *aconnector,
>>>  		 */
>>>  		DRM_DEBUG_DRIVER("No preferred mode found\n");
>>>  	} else {
>>> +		is_fs_vid_mode = is_freesync_video_mode(&mode,
>>> aconnector);
>>> +		if (is_fs_vid_mode) {
>>> +			freesync_mode =
>>> get_highest_freesync_mode(aconnector, false);
>>> +			if (freesync_mode) {
>> As the freesync modes are being added by the driver, and we have
>> passed one check which says is_fs_vid_mode, will it ever be the case
>> where freesync_mode == NULL ? Ideally we should get atleast one mode
>> equal to this isn't it ? in that case we can drop one if () check.
> Yes, thanks for catching this. Will fix.
>
>
> --
>
> Regards,
> Aurabindo Pillai


More information about the amd-gfx mailing list