All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Experimental freesync video mode optimization
@ 2020-12-10  2:45 Aurabindo Pillai
  2020-12-10  2:45 ` [PATCH 1/3] drm/amd/display: Add module parameter for freesync video mode Aurabindo Pillai
                   ` (2 more replies)
  0 siblings, 3 replies; 29+ messages in thread
From: Aurabindo Pillai @ 2020-12-10  2:45 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, shashank.sharma, thong.thai, Aurabindo.Pillai,
	wayne.lin, alexander.deucher, Harry.Wentland,
	nicholas.kazlauskas

This patchset enables freesync video mode usecase where the userspace
can request a freesync compatible video mode such that switching to this
mode does not trigger blanking.

This feature is guarded by a module parameter which is disabled by
default. Enabling this paramters adds additional modes to the driver
modelist, and also enables the optimization to skip modeset when using
one of these modes.

--

Aurabindo Pillai (3):
  drm/amd/display: Add module parameter for freesync video mode
  drm/amd/display: Add freesync video modes based on preferred modes
  drm/amd/display: Skip modeset for front porch change

 drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 366 +++++++++++++++++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   1 +
 4 files changed, 363 insertions(+), 17 deletions(-)

-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 1/3] drm/amd/display: Add module parameter for freesync video mode
  2020-12-10  2:45 [PATCH 0/3] Experimental freesync video mode optimization Aurabindo Pillai
@ 2020-12-10  2:45 ` Aurabindo Pillai
  2021-01-04 15:58   ` Kazlauskas, Nicholas
  2020-12-10  2:45 ` [PATCH 2/3] drm/amd/display: Add freesync video modes based on preferred modes Aurabindo Pillai
  2020-12-10  2:45 ` [PATCH 3/3] drm/amd/display: Skip modeset for front porch change Aurabindo Pillai
  2 siblings, 1 reply; 29+ messages in thread
From: Aurabindo Pillai @ 2020-12-10  2:45 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, shashank.sharma, thong.thai, Aurabindo.Pillai,
	wayne.lin, alexander.deucher, Harry.Wentland,
	nicholas.kazlauskas

[Why&How]
Adds a module parameter to enable experimental freesync video mode modeset
optimization. Enabling this mode allows the driver to skip a full modeset when
freesync compatible modes are requested by the userspace. This paramters also
adds some standard modes based on the connected monitor's VRR range.

Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h     |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 ++++++++++++
 2 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 83ac06a3ec05..efbfee93c359 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -177,6 +177,7 @@ extern int amdgpu_gpu_recovery;
 extern int amdgpu_emu_mode;
 extern uint amdgpu_smu_memory_pool_size;
 extern uint amdgpu_dc_feature_mask;
+extern uint amdgpu_exp_freesync_vid_mode;
 extern uint amdgpu_dc_debug_mask;
 extern uint amdgpu_dm_abm_level;
 extern struct amdgpu_mgpu_info mgpu_info;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index b2a1dd7581bf..ece51ecd53d1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -158,6 +158,7 @@ int amdgpu_mes;
 int amdgpu_noretry = -1;
 int amdgpu_force_asic_type = -1;
 int amdgpu_tmz;
+uint amdgpu_exp_freesync_vid_mode;
 int amdgpu_reset_method = -1; /* auto */
 int amdgpu_num_kcq = -1;
 
@@ -786,6 +787,17 @@ module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444);
 MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto, 0 = off (default), 1 = on)");
 module_param_named(tmz, amdgpu_tmz, int, 0444);
 
+/**
+ * DOC: experimental_freesync_video (uint)
+ * Enabled the optimization to adjust front porch timing to achieve seamless mode change experience
+ * when setting a freesync supported mode for which full modeset is not needed.
+ * The default value: 0 (off).
+ */
+MODULE_PARM_DESC(
+	experimental_freesync_video,
+	"Enable freesync modesetting optimization feature (0 = off (default), 1 = on)");
+module_param_named(experimental_freesync_video, amdgpu_exp_freesync_vid_mode, uint, 0444);
+
 /**
  * DOC: reset_method (int)
  * GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco)
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 2/3] drm/amd/display: Add freesync video modes based on preferred modes
  2020-12-10  2:45 [PATCH 0/3] Experimental freesync video mode optimization Aurabindo Pillai
  2020-12-10  2:45 ` [PATCH 1/3] drm/amd/display: Add module parameter for freesync video mode Aurabindo Pillai
@ 2020-12-10  2:45 ` Aurabindo Pillai
  2020-12-10 12:37   ` Shashank Sharma
  2020-12-10  2:45 ` [PATCH 3/3] drm/amd/display: Skip modeset for front porch change Aurabindo Pillai
  2 siblings, 1 reply; 29+ messages in thread
From: Aurabindo Pillai @ 2020-12-10  2:45 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, shashank.sharma, thong.thai, Aurabindo.Pillai,
	wayne.lin, alexander.deucher, Harry.Wentland,
	nicholas.kazlauskas

[Why&How]
If experimental freesync video mode module parameter is enabled, add
few extra display modes into the driver's mode list corresponding to common
video frame rates. When userspace sets these modes, no modeset will be
performed (if current mode was one of freesync modes or the base freesync mode
based off which timings have been generated for the rest of the freesync modes)
since these modes only differ from the base mode with front porch timing.

Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 197 ++++++++++++++++++
 1 file changed, 197 insertions(+)

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 fbff8d693e03..f699a3d41cad 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5178,6 +5178,69 @@ static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context)
 	set_master_stream(context->streams, context->stream_count);
 }
 
+static struct drm_display_mode *
+get_highest_freesync_mode(struct amdgpu_dm_connector *aconnector,
+			  bool use_probed_modes)
+{
+	struct drm_display_mode *m, *m_high = NULL;
+	u16 current_refresh, highest_refresh, preferred_mode_h, preferred_mode_w;
+	struct list_head *list_head = use_probed_modes ?
+						    &aconnector->base.probed_modes :
+						    &aconnector->base.modes;
+
+	/*
+	 * Find the preferred mode
+	 */
+
+	list_for_each_entry (m, list_head, head) {
+		if (!(m->type & DRM_MODE_TYPE_PREFERRED))
+			continue;
+
+		m_high = m;
+		preferred_mode_h = m_high->hdisplay;
+		preferred_mode_w = m_high->vdisplay;
+		highest_refresh = drm_mode_vrefresh(m_high);
+		break;
+	}
+
+	if (!m_high) {
+
+		/*
+		 * Probably an EDID with no preferred mode.
+		 * Fallback to first entry;
+		 */
+		m_high = list_first_entry_or_null(&aconnector->base.modes,
+						  struct drm_display_mode, head);
+		if (!m_high)
+			return NULL;
+		else {
+			preferred_mode_h = m_high->hdisplay;
+			preferred_mode_w = m_high->vdisplay;
+			highest_refresh = drm_mode_vrefresh(m_high);
+		}
+	}
+
+	/*
+	 * Find the mode with highest refresh rate with same resolution.
+	 * For some monitors, preferred mode is not the mode with highest
+	 * supported refresh rate.
+	 */
+	list_for_each_entry (m, list_head, head) {
+		current_refresh  = drm_mode_vrefresh(m);
+
+		if (m->hdisplay == preferred_mode_h &&
+		    m->vdisplay == preferred_mode_w &&
+		    highest_refresh < current_refresh) {
+			highest_refresh = current_refresh;
+			preferred_mode_h = m->hdisplay;
+			preferred_mode_w = m->vdisplay;
+			m_high = m;
+		}
+	}
+
+	return m_high;
+}
+
 static struct dc_stream_state *
 create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 		       const struct drm_display_mode *drm_mode,
@@ -7006,6 +7069,139 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
 	}
 }
 
+static bool is_duplicate_mode(struct amdgpu_dm_connector *aconnector,
+			      struct drm_display_mode *mode)
+{
+	struct drm_display_mode *m;
+
+	list_for_each_entry (m, &aconnector->base.probed_modes, head) {
+		if (m->clock == mode->clock &&
+		    m->htotal == mode->htotal &&
+		    m->vtotal == mode->vtotal &&
+		    m->hdisplay == mode->hdisplay &&
+		    m->vdisplay == mode->vdisplay &&
+		    m->hsync_start == mode->hsync_start &&
+		    m->vsync_start == mode->vsync_start &&
+		    m->vsync_end == mode->vsync_end &&
+		    m->hsync_end == mode->hsync_end)
+			return true;
+	}
+
+	return false;
+}
+
+static uint add_fs_modes(struct amdgpu_dm_connector *aconnector,
+			 struct detailed_data_monitor_range *range)
+{
+	const struct drm_display_mode *m, *m_save;
+	struct drm_display_mode *new_mode;
+	uint i;
+	uint64_t target_vtotal, target_vtotal_diff;
+	uint32_t new_modes_count = 0;
+	uint64_t num, den;
+
+	/* Standard FPS values
+	 *
+	 * 23.976 - TV/NTSC
+	 * 24	  - Cinema
+	 * 25     - TV/PAL
+	 * 29.97  - TV/NTSC
+	 * 30     - TV/NTSC
+	 * 48	  - Cinema HFR
+	 * 50	  - TV/PAL
+	 */
+	const uint32_t neededrates[] = { 23976, 24000, 25000, 29970,
+					 30000, 48000, 50000, 72000, 96000 };
+
+	/*
+	 * Find mode with highest refresh rate with the same resolution
+	 * as the preferred mode. Some monitors report a preferred mode
+	 * with lower resolution than the highest refresh rate supported.
+	 */
+
+	m_save = get_highest_freesync_mode(aconnector, true);
+
+	list_for_each_entry (m, &aconnector->base.probed_modes, head) {
+		if (m != m_save)
+			continue;
+
+		for (i = 0; i < sizeof(neededrates) / sizeof(uint32_t); i++) {
+			if (drm_mode_vrefresh(m) * 1000 < neededrates[i])
+				continue;
+
+			if (neededrates[i] < range->min_vfreq * 1000)
+				continue;
+
+			num = (unsigned long long)m->clock * 1000 * 1000;
+			den = neededrates[i] * (unsigned long long)m->htotal;
+			target_vtotal = div_u64(num, den);
+			target_vtotal_diff = target_vtotal - m->vtotal;
+
+			/*
+			 * Check for illegal modes
+			 */
+			if (m->vsync_start + target_vtotal_diff < m->vdisplay ||
+			    m->vsync_end + target_vtotal_diff < m->vsync_start ||
+			    m->vtotal + target_vtotal_diff < m->vsync_end)
+				continue;
+
+			new_mode = drm_mode_duplicate(aconnector->base.dev, m);
+			if (!new_mode)
+				goto out;
+
+			new_mode->vtotal += (u16)target_vtotal_diff;
+			new_mode->vsync_start += (u16)target_vtotal_diff;
+			new_mode->vsync_end += (u16)target_vtotal_diff;
+			new_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
+			new_mode->type |= DRM_MODE_TYPE_DRIVER;
+			strcat(new_mode->name, "_FSV\0");
+
+			if (!is_duplicate_mode(aconnector, new_mode)) {
+				drm_mode_probed_add(&aconnector->base, new_mode);
+				new_modes_count += 1;
+			} else
+				drm_mode_destroy(aconnector->base.dev, new_mode);
+		}
+	}
+ out:
+	return new_modes_count;
+}
+
+static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connector,
+						   struct edid *edid)
+{
+	uint8_t i;
+	struct detailed_timing *timing;
+	struct detailed_non_pixel *data;
+	struct detailed_data_monitor_range *range;
+	struct amdgpu_dm_connector *amdgpu_dm_connector =
+		to_amdgpu_dm_connector(connector);
+
+	if (!(amdgpu_exp_freesync_vid_mode && edid))
+		return;
+
+	if (!(amdgpu_dm_connector->dc_sink->sink_signal == SIGNAL_TYPE_EDP ||
+	      amdgpu_dm_connector->dc_sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT ||
+	      amdgpu_dm_connector->dc_sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A))
+		return;
+
+	if (edid->version == 1 && edid->revision > 1) {
+		for (i = 0; i < 4; i++) {
+			timing = &edid->detailed_timings[i];
+			data = &timing->data.other_data;
+			range = &data->data.range;
+			/*
+			 * Check if monitor has continuous frequency mode
+			 */
+			if (data->type == EDID_DETAIL_MONITOR_RANGE &&
+			    range->max_vfreq - range->min_vfreq > 10) {
+				amdgpu_dm_connector->num_modes += add_fs_modes(amdgpu_dm_connector, range);
+				break;
+			}
+		}
+	}
+}
+
 static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
 {
 	struct amdgpu_dm_connector *amdgpu_dm_connector =
@@ -7021,6 +7217,7 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
 	} else {
 		amdgpu_dm_connector_ddc_get_modes(connector, edid);
 		amdgpu_dm_connector_add_common_modes(encoder, connector);
+		amdgpu_dm_connector_add_freesync_modes(connector, edid);
 	}
 	amdgpu_dm_fbc_init(connector);
 
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 3/3] drm/amd/display: Skip modeset for front porch change
  2020-12-10  2:45 [PATCH 0/3] Experimental freesync video mode optimization Aurabindo Pillai
  2020-12-10  2:45 ` [PATCH 1/3] drm/amd/display: Add module parameter for freesync video mode Aurabindo Pillai
  2020-12-10  2:45 ` [PATCH 2/3] drm/amd/display: Add freesync video modes based on preferred modes Aurabindo Pillai
@ 2020-12-10  2:45 ` Aurabindo Pillai
  2020-12-10 10:21   ` Christian König
                     ` (2 more replies)
  2 siblings, 3 replies; 29+ messages in thread
From: Aurabindo Pillai @ 2020-12-10  2:45 UTC (permalink / raw)
  To: amd-gfx
  Cc: stylon.wang, shashank.sharma, thong.thai, Aurabindo.Pillai,
	wayne.lin, alexander.deucher, Harry.Wentland,
	nicholas.kazlauskas

[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@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;
+
 	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;
+
+	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;
+	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) {
+				saved_mode = mode;
+				mode = *freesync_mode;
+			}
+		}
+
 		decide_crtc_timing_for_drm_display_mode(
 				&mode, preferred_mode,
-				dm_state ? (dm_state->scaling != RMX_OFF) : false);
+				dm_state ? (dm_state->scaling != RMX_OFF) : false,
+				freesync_mode ? true : false);
 		preferred_refresh = drm_mode_vrefresh(preferred_mode);
 	}
 
 	if (!dm_state)
 		drm_mode_set_crtcinfo(&mode, 0);
 
-	/*
+	if (dm_state && is_fs_vid_mode && freesync_mode)
+		drm_mode_set_crtcinfo(&saved_mode, 0);
+
+       /*
 	* If scaling is enabled and refresh rate didn't change
 	* we copy the vic and polarities of the old timings
 	*/
-	if (!scale || mode_refresh != preferred_refresh)
+	if (!(scale && freesync_mode) || mode_refresh != preferred_refresh)
 		fill_stream_properties_from_drm_display_mode(stream,
 			&mode, &aconnector->base, con_state, NULL, requested_bpc);
 	else
@@ -7881,13 +7922,29 @@ static void update_stream_irq_parameters(
 	if (new_crtc_state->vrr_supported &&
 	    config.min_refresh_in_uhz &&
 	    config.max_refresh_in_uhz) {
+		/*
+		 * if freesync compatible mode was set, config.state will be set
+		 * in atomic check
+		 */
+		if (config.state == VRR_STATE_ACTIVE_FIXED &&
+		    config.fixed_refresh_in_uhz && config.max_refresh_in_uhz &&
+		    config.min_refresh_in_uhz &&
+		    (!drm_atomic_crtc_needs_modeset(&new_crtc_state->base) ||
+		     new_crtc_state->freesync_video_mode)) {
+			vrr_params.max_refresh_in_uhz = config.max_refresh_in_uhz;
+			vrr_params.min_refresh_in_uhz = config.min_refresh_in_uhz;
+			vrr_params.fixed_refresh_in_uhz = config.fixed_refresh_in_uhz;
+			vrr_params.state = VRR_STATE_ACTIVE_FIXED;
+			goto out;
+		}
+
 		config.state = new_crtc_state->base.vrr_enabled ?
 			VRR_STATE_ACTIVE_VARIABLE :
 			VRR_STATE_INACTIVE;
-	} else {
+	} else
 		config.state = VRR_STATE_UNSUPPORTED;
-	}
 
+out:
 	mod_freesync_build_vrr_params(dm->freesync_module,
 				      new_stream,
 				      &config, &vrr_params);
@@ -8205,7 +8262,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 		 * as part of commit.
 		 */
 		if (amdgpu_dm_vrr_active(dm_old_crtc_state) !=
-		    amdgpu_dm_vrr_active(acrtc_state)) {
+		    amdgpu_dm_vrr_active(acrtc_state) ||
+		    acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED ||
+		    acrtc_state->freesync_video_mode) {
 			spin_lock_irqsave(&pcrtc->dev->event_lock, flags);
 			dc_stream_adjust_vmin_vmax(
 				dm->dc, acrtc_state->stream,
@@ -8896,6 +8955,7 @@ static void get_freesync_config_for_crtc(
 			to_amdgpu_dm_connector(new_con_state->base.connector);
 	struct drm_display_mode *mode = &new_crtc_state->base.mode;
 	int vrefresh = drm_mode_vrefresh(mode);
+	bool fs_vid_mode = false;
 
 	new_crtc_state->vrr_supported = new_con_state->freesync_capable &&
 					vrefresh >= aconnector->min_vfreq &&
@@ -8903,17 +8963,26 @@ static void get_freesync_config_for_crtc(
 
 	if (new_crtc_state->vrr_supported) {
 		new_crtc_state->stream->ignore_msa_timing_param = true;
-		config.state = new_crtc_state->base.vrr_enabled ?
-				VRR_STATE_ACTIVE_VARIABLE :
-				VRR_STATE_INACTIVE;
-		config.min_refresh_in_uhz =
-				aconnector->min_vfreq * 1000000;
-		config.max_refresh_in_uhz =
-				aconnector->max_vfreq * 1000000;
+		fs_vid_mode = new_crtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED ||
+			new_crtc_state->freesync_video_mode;
+
+		config.min_refresh_in_uhz = aconnector->min_vfreq * 1000000;
+		config.max_refresh_in_uhz = aconnector->max_vfreq * 1000000;
 		config.vsif_supported = true;
 		config.btr = true;
-	}
 
+		if (fs_vid_mode) {
+			config.state = VRR_STATE_ACTIVE_FIXED;
+			config.fixed_refresh_in_uhz = new_crtc_state->freesync_config.fixed_refresh_in_uhz;
+			goto out;
+		}
+		else if (new_crtc_state->base.vrr_enabled && !fs_vid_mode)
+			config.state = VRR_STATE_ACTIVE_VARIABLE;
+		else
+			config.state = VRR_STATE_INACTIVE;
+
+	}
+out:
 	new_crtc_state->freesync_config = config;
 }
 
@@ -8926,6 +8995,51 @@ static void reset_freesync_config_for_crtc(
 	       sizeof(new_crtc_state->vrr_infopacket));
 }
 
+static bool
+is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
+				 struct drm_crtc_state *new_crtc_state)
+{
+	struct drm_display_mode old_mode, new_mode;
+
+	if (!old_crtc_state || !new_crtc_state)
+		return false;
+
+	old_mode = old_crtc_state->mode;
+	new_mode = new_crtc_state->mode;
+
+	if (old_mode.clock       == new_mode.clock &&
+	    old_mode.hdisplay    == new_mode.hdisplay &&
+	    old_mode.vdisplay    == new_mode.vdisplay &&
+	    old_mode.htotal      == new_mode.htotal &&
+	    old_mode.vtotal      != new_mode.vtotal &&
+	    old_mode.hsync_start == new_mode.hsync_start &&
+	    old_mode.vsync_start != new_mode.vsync_start &&
+	    old_mode.hsync_end   == new_mode.hsync_end &&
+	    old_mode.vsync_end   != new_mode.vsync_end &&
+	    old_mode.hskew       == new_mode.hskew &&
+	    old_mode.vscan       == new_mode.vscan &&
+	    (old_mode.vsync_end - old_mode.vsync_start) ==
+	    (new_mode.vsync_end - new_mode.vsync_start))
+		return true;
+
+	return false;
+}
+
+static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) {
+	uint64_t num, den, res;
+	struct drm_crtc_state *new_crtc_state = &dm_new_crtc_state->base;
+
+	dm_new_crtc_state->freesync_config.state = VRR_STATE_ACTIVE_FIXED;
+
+	num = (unsigned long long)new_crtc_state->mode.clock * 1000 * 1000000;
+	den = (unsigned long long)new_crtc_state->mode.htotal *
+	      (unsigned long long)new_crtc_state->mode.vtotal;
+
+	res = div_u64(num, den);
+	dm_new_crtc_state->freesync_config.fixed_refresh_in_uhz = res;
+	dm_new_crtc_state->freesync_video_mode = true;
+}
+
 static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
 				struct drm_atomic_state *state,
 				struct drm_crtc *crtc,
@@ -9016,6 +9130,11 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
 		 * TODO: Refactor this function to allow this check to work
 		 * in all conditions.
 		 */
+		if (dm_new_crtc_state->stream &&
+		    is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state) &&
+		    amdgpu_exp_freesync_vid_mode)
+			goto skip_modeset;
+
 		if (dm_new_crtc_state->stream &&
 		    dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
 		    dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
@@ -9047,6 +9166,22 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
 		if (!dm_old_crtc_state->stream)
 			goto skip_modeset;
 
+		if (dm_new_crtc_state->stream &&
+		    is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state) &&
+		    amdgpu_exp_freesync_vid_mode) {
+			new_crtc_state->mode_changed = false;
+			DRM_DEBUG_DRIVER(
+				"Mode change not required for front porch change, "
+				"setting mode_changed to %d",
+				new_crtc_state->mode_changed);
+
+			set_freesync_fixed_config(dm_new_crtc_state);
+
+			goto skip_modeset;
+		} else if (aconnector &&
+			   is_freesync_video_mode(&new_crtc_state->mode, aconnector))
+			set_freesync_fixed_config(dm_new_crtc_state);
+
 		ret = dm_atomic_get_state(state, &dm_state);
 		if (ret)
 			goto fail;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 251af783f6b1..28f2d8c9b260 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -453,6 +453,7 @@ struct dm_crtc_state {
 
 	bool freesync_timing_changed;
 	bool freesync_vrr_info_changed;
+	bool freesync_video_mode;
 
 	bool dsc_force_changed;
 	bool vrr_supported;
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/3] drm/amd/display: Skip modeset for front porch change
  2020-12-10  2:45 ` [PATCH 3/3] drm/amd/display: Skip modeset for front porch change Aurabindo Pillai
@ 2020-12-10 10:21   ` Christian König
  2020-12-10 12:59   ` Shashank Sharma
  2021-01-04 16:16   ` Kazlauskas, Nicholas
  2 siblings, 0 replies; 29+ messages in thread
From: Christian König @ 2020-12-10 10:21 UTC (permalink / raw)
  To: Aurabindo Pillai, amd-gfx
  Cc: stylon.wang, thong.thai, shashank.sharma, wayne.lin,
	alexander.deucher, Harry.Wentland, nicholas.kazlauskas

Am 10.12.20 um 03:45 schrieb Aurabindo Pillai:
> [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.

I would drop the test for amdgpu_exp_freesync_vid_mode here since this 
is a valid optimization independent if we add the extra modes or not in 
the kernel.

But that is not a hard requirement and apart from that the series looks 
good to me. Feel free to add an Acked-by: Christian König 
<christian.koenig@amd.com>.

Christian.

>
> Signed-off-by: Aurabindo Pillai <aurabindo.pillai@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;
> +
>   	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;
> +
> +	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;
> +	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) {
> +				saved_mode = mode;
> +				mode = *freesync_mode;
> +			}
> +		}
> +
>   		decide_crtc_timing_for_drm_display_mode(
>   				&mode, preferred_mode,
> -				dm_state ? (dm_state->scaling != RMX_OFF) : false);
> +				dm_state ? (dm_state->scaling != RMX_OFF) : false,
> +				freesync_mode ? true : false);
>   		preferred_refresh = drm_mode_vrefresh(preferred_mode);
>   	}
>   
>   	if (!dm_state)
>   		drm_mode_set_crtcinfo(&mode, 0);
>   
> -	/*
> +	if (dm_state && is_fs_vid_mode && freesync_mode)
> +		drm_mode_set_crtcinfo(&saved_mode, 0);
> +
> +       /*
>   	* If scaling is enabled and refresh rate didn't change
>   	* we copy the vic and polarities of the old timings
>   	*/
> -	if (!scale || mode_refresh != preferred_refresh)
> +	if (!(scale && freesync_mode) || mode_refresh != preferred_refresh)
>   		fill_stream_properties_from_drm_display_mode(stream,
>   			&mode, &aconnector->base, con_state, NULL, requested_bpc);
>   	else
> @@ -7881,13 +7922,29 @@ static void update_stream_irq_parameters(
>   	if (new_crtc_state->vrr_supported &&
>   	    config.min_refresh_in_uhz &&
>   	    config.max_refresh_in_uhz) {
> +		/*
> +		 * if freesync compatible mode was set, config.state will be set
> +		 * in atomic check
> +		 */
> +		if (config.state == VRR_STATE_ACTIVE_FIXED &&
> +		    config.fixed_refresh_in_uhz && config.max_refresh_in_uhz &&
> +		    config.min_refresh_in_uhz &&
> +		    (!drm_atomic_crtc_needs_modeset(&new_crtc_state->base) ||
> +		     new_crtc_state->freesync_video_mode)) {
> +			vrr_params.max_refresh_in_uhz = config.max_refresh_in_uhz;
> +			vrr_params.min_refresh_in_uhz = config.min_refresh_in_uhz;
> +			vrr_params.fixed_refresh_in_uhz = config.fixed_refresh_in_uhz;
> +			vrr_params.state = VRR_STATE_ACTIVE_FIXED;
> +			goto out;
> +		}
> +
>   		config.state = new_crtc_state->base.vrr_enabled ?
>   			VRR_STATE_ACTIVE_VARIABLE :
>   			VRR_STATE_INACTIVE;
> -	} else {
> +	} else
>   		config.state = VRR_STATE_UNSUPPORTED;
> -	}
>   
> +out:
>   	mod_freesync_build_vrr_params(dm->freesync_module,
>   				      new_stream,
>   				      &config, &vrr_params);
> @@ -8205,7 +8262,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
>   		 * as part of commit.
>   		 */
>   		if (amdgpu_dm_vrr_active(dm_old_crtc_state) !=
> -		    amdgpu_dm_vrr_active(acrtc_state)) {
> +		    amdgpu_dm_vrr_active(acrtc_state) ||
> +		    acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED ||
> +		    acrtc_state->freesync_video_mode) {
>   			spin_lock_irqsave(&pcrtc->dev->event_lock, flags);
>   			dc_stream_adjust_vmin_vmax(
>   				dm->dc, acrtc_state->stream,
> @@ -8896,6 +8955,7 @@ static void get_freesync_config_for_crtc(
>   			to_amdgpu_dm_connector(new_con_state->base.connector);
>   	struct drm_display_mode *mode = &new_crtc_state->base.mode;
>   	int vrefresh = drm_mode_vrefresh(mode);
> +	bool fs_vid_mode = false;
>   
>   	new_crtc_state->vrr_supported = new_con_state->freesync_capable &&
>   					vrefresh >= aconnector->min_vfreq &&
> @@ -8903,17 +8963,26 @@ static void get_freesync_config_for_crtc(
>   
>   	if (new_crtc_state->vrr_supported) {
>   		new_crtc_state->stream->ignore_msa_timing_param = true;
> -		config.state = new_crtc_state->base.vrr_enabled ?
> -				VRR_STATE_ACTIVE_VARIABLE :
> -				VRR_STATE_INACTIVE;
> -		config.min_refresh_in_uhz =
> -				aconnector->min_vfreq * 1000000;
> -		config.max_refresh_in_uhz =
> -				aconnector->max_vfreq * 1000000;
> +		fs_vid_mode = new_crtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED ||
> +			new_crtc_state->freesync_video_mode;
> +
> +		config.min_refresh_in_uhz = aconnector->min_vfreq * 1000000;
> +		config.max_refresh_in_uhz = aconnector->max_vfreq * 1000000;
>   		config.vsif_supported = true;
>   		config.btr = true;
> -	}
>   
> +		if (fs_vid_mode) {
> +			config.state = VRR_STATE_ACTIVE_FIXED;
> +			config.fixed_refresh_in_uhz = new_crtc_state->freesync_config.fixed_refresh_in_uhz;
> +			goto out;
> +		}
> +		else if (new_crtc_state->base.vrr_enabled && !fs_vid_mode)
> +			config.state = VRR_STATE_ACTIVE_VARIABLE;
> +		else
> +			config.state = VRR_STATE_INACTIVE;
> +
> +	}
> +out:
>   	new_crtc_state->freesync_config = config;
>   }
>   
> @@ -8926,6 +8995,51 @@ static void reset_freesync_config_for_crtc(
>   	       sizeof(new_crtc_state->vrr_infopacket));
>   }
>   
> +static bool
> +is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
> +				 struct drm_crtc_state *new_crtc_state)
> +{
> +	struct drm_display_mode old_mode, new_mode;
> +
> +	if (!old_crtc_state || !new_crtc_state)
> +		return false;
> +
> +	old_mode = old_crtc_state->mode;
> +	new_mode = new_crtc_state->mode;
> +
> +	if (old_mode.clock       == new_mode.clock &&
> +	    old_mode.hdisplay    == new_mode.hdisplay &&
> +	    old_mode.vdisplay    == new_mode.vdisplay &&
> +	    old_mode.htotal      == new_mode.htotal &&
> +	    old_mode.vtotal      != new_mode.vtotal &&
> +	    old_mode.hsync_start == new_mode.hsync_start &&
> +	    old_mode.vsync_start != new_mode.vsync_start &&
> +	    old_mode.hsync_end   == new_mode.hsync_end &&
> +	    old_mode.vsync_end   != new_mode.vsync_end &&
> +	    old_mode.hskew       == new_mode.hskew &&
> +	    old_mode.vscan       == new_mode.vscan &&
> +	    (old_mode.vsync_end - old_mode.vsync_start) ==
> +	    (new_mode.vsync_end - new_mode.vsync_start))
> +		return true;
> +
> +	return false;
> +}
> +
> +static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) {
> +	uint64_t num, den, res;
> +	struct drm_crtc_state *new_crtc_state = &dm_new_crtc_state->base;
> +
> +	dm_new_crtc_state->freesync_config.state = VRR_STATE_ACTIVE_FIXED;
> +
> +	num = (unsigned long long)new_crtc_state->mode.clock * 1000 * 1000000;
> +	den = (unsigned long long)new_crtc_state->mode.htotal *
> +	      (unsigned long long)new_crtc_state->mode.vtotal;
> +
> +	res = div_u64(num, den);
> +	dm_new_crtc_state->freesync_config.fixed_refresh_in_uhz = res;
> +	dm_new_crtc_state->freesync_video_mode = true;
> +}
> +
>   static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   				struct drm_atomic_state *state,
>   				struct drm_crtc *crtc,
> @@ -9016,6 +9130,11 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   		 * TODO: Refactor this function to allow this check to work
>   		 * in all conditions.
>   		 */
> +		if (dm_new_crtc_state->stream &&
> +		    is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state) &&
> +		    amdgpu_exp_freesync_vid_mode)
> +			goto skip_modeset;
> +
>   		if (dm_new_crtc_state->stream &&
>   		    dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
>   		    dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
> @@ -9047,6 +9166,22 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   		if (!dm_old_crtc_state->stream)
>   			goto skip_modeset;
>   
> +		if (dm_new_crtc_state->stream &&
> +		    is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state) &&
> +		    amdgpu_exp_freesync_vid_mode) {
> +			new_crtc_state->mode_changed = false;
> +			DRM_DEBUG_DRIVER(
> +				"Mode change not required for front porch change, "
> +				"setting mode_changed to %d",
> +				new_crtc_state->mode_changed);
> +
> +			set_freesync_fixed_config(dm_new_crtc_state);
> +
> +			goto skip_modeset;
> +		} else if (aconnector &&
> +			   is_freesync_video_mode(&new_crtc_state->mode, aconnector))
> +			set_freesync_fixed_config(dm_new_crtc_state);
> +
>   		ret = dm_atomic_get_state(state, &dm_state);
>   		if (ret)
>   			goto fail;
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> index 251af783f6b1..28f2d8c9b260 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -453,6 +453,7 @@ struct dm_crtc_state {
>   
>   	bool freesync_timing_changed;
>   	bool freesync_vrr_info_changed;
> +	bool freesync_video_mode;
>   
>   	bool dsc_force_changed;
>   	bool vrr_supported;

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/3] drm/amd/display: Add freesync video modes based on preferred modes
  2020-12-10  2:45 ` [PATCH 2/3] drm/amd/display: Add freesync video modes based on preferred modes Aurabindo Pillai
@ 2020-12-10 12:37   ` Shashank Sharma
  2020-12-10 16:56     ` Aurabindo Pillai
  0 siblings, 1 reply; 29+ messages in thread
From: Shashank Sharma @ 2020-12-10 12:37 UTC (permalink / raw)
  To: amd-gfx


[-- Attachment #1.1: Type: text/plain, Size: 8633 bytes --]

Hello Aurabindo,

On 10/12/20 8:15 am, Aurabindo Pillai wrote:
> [Why&How]
> If experimental freesync video mode module parameter is enabled, add
> few extra display modes into the driver's mode list corresponding to common
> video frame rates. When userspace sets these modes, no modeset will be
> performed (if current mode was one of freesync modes or the base freesync mode
> based off which timings have been generated for the rest of the freesync modes)
> since these modes only differ from the base mode with front porch timing.
>
> Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 197 ++++++++++++++++++
>  1 file changed, 197 insertions(+)
>
> 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 fbff8d693e03..f699a3d41cad 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -5178,6 +5178,69 @@ static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context)
>  	set_master_stream(context->streams, context->stream_count);
>  }
>  
> +static struct drm_display_mode *
> +get_highest_freesync_mode(struct amdgpu_dm_connector *aconnector,
> +			  bool use_probed_modes)
the function name is confusing, this function has nothing to do with freesync. Probably drop the 'freesync' from the name, get_highest_refresh_rate_mode or similar ?
> +{
> +	struct drm_display_mode *m, *m_high = NULL;
> +	u16 current_refresh, highest_refresh, preferred_mode_h, preferred_mode_w;
> +	struct list_head *list_head = use_probed_modes ?
> +						    &aconnector->base.probed_modes :
> +						    &aconnector->base.modes;
> +
> +	/*
> +	 * Find the preferred mode
> +	 */
Single line comment should be in /* */
> +
> +	list_for_each_entry (m, list_head, head) {
> +		if (!(m->type & DRM_MODE_TYPE_PREFERRED))
> +			continue;
> +
> +		m_high = m;
> +		preferred_mode_h = m_high->hdisplay;
> +		preferred_mode_w = m_high->vdisplay;
> +		highest_refresh = drm_mode_vrefresh(m_high);
> +		break;
> +	}
> +
> +	if (!m_high) {
> +
> +		/*
> +		 * Probably an EDID with no preferred mode.
> +		 * Fallback to first entry;
> +		 */
> +		m_high = list_first_entry_or_null(&aconnector->base.modes,
> +						  struct drm_display_mode, head);
> +		if (!m_high)
> +			return NULL;
> +		else {
> +			preferred_mode_h = m_high->hdisplay;
> +			preferred_mode_w = m_high->vdisplay;
> +			highest_refresh = drm_mode_vrefresh(m_high);
> +		}
> +	}
> +
> +	/*
> +	 * Find the mode with highest refresh rate with same resolution.
> +	 * For some monitors, preferred mode is not the mode with highest
> +	 * supported refresh rate.
> +	 */
> +	list_for_each_entry (m, list_head, head) {
> +		current_refresh  = drm_mode_vrefresh(m);
> +
> +		if (m->hdisplay == preferred_mode_h &&
> +		    m->vdisplay == preferred_mode_w &&
> +		    highest_refresh < current_refresh) {
> +			highest_refresh = current_refresh;
> +			preferred_mode_h = m->hdisplay;
> +			preferred_mode_w = m->vdisplay;
why do we need to save preferred_mode_h and w variables at all ? I thought the idea here was to get the mode with highest refresh rate, but same resolution, which is indicated in the if (cond) above also. I think we just need highest refresh rate isn't ?
> +			m_high = m;
> +		}
> +	}
> +
> +	return m_high;
> +}
> +
>  static struct dc_stream_state *
>  create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
>  		       const struct drm_display_mode *drm_mode,
> @@ -7006,6 +7069,139 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
>  	}
>  }
>  
> +static bool is_duplicate_mode(struct amdgpu_dm_connector *aconnector,
> +			      struct drm_display_mode *mode)
> +{
> +	struct drm_display_mode *m;
> +
> +	list_for_each_entry (m, &aconnector->base.probed_modes, head) {
> +		if (m->clock == mode->clock &&
> +		    m->htotal == mode->htotal &&
> +		    m->vtotal == mode->vtotal &&
> +		    m->hdisplay == mode->hdisplay &&
> +		    m->vdisplay == mode->vdisplay &&
> +		    m->hsync_start == mode->hsync_start &&
> +		    m->vsync_start == mode->vsync_start &&
> +		    m->vsync_end == mode->vsync_end &&
> +		    m->hsync_end == mode->hsync_end)
> +			return true;
> +	}
> +
> +	return false;
Why not usedrm_mode_equal() instead ?
> +}
> +
> +static uint add_fs_modes(struct amdgpu_dm_connector *aconnector,
> +			 struct detailed_data_monitor_range *range)
> +{
> +	const struct drm_display_mode *m, *m_save;
> +	struct drm_display_mode *new_mode;
> +	uint i;
> +	uint64_t target_vtotal, target_vtotal_diff;
> +	uint32_t new_modes_count = 0;
> +	uint64_t num, den;
> +
> +	/* Standard FPS values
> +	 *
> +	 * 23.976 - TV/NTSC
> +	 * 24	  - Cinema
> +	 * 25     - TV/PAL
> +	 * 29.97  - TV/NTSC
> +	 * 30     - TV/NTSC
> +	 * 48	  - Cinema HFR
> +	 * 50	  - TV/PAL
> +	 */
> +	const uint32_t neededrates[] = { 23976, 24000, 25000, 29970,
> +					 30000, 48000, 50000, 72000, 96000 };
> +
> +	/*
> +	 * Find mode with highest refresh rate with the same resolution
> +	 * as the preferred mode. Some monitors report a preferred mode
> +	 * with lower resolution than the highest refresh rate supported.
> +	 */
> +
> +	m_save = get_highest_freesync_mode(aconnector, true);
A NULL return check here to bypass the whole routine below ?
> +
> +	list_for_each_entry (m, &aconnector->base.probed_modes, head) {
> +		if (m != m_save)
> +			continue;
> +
> +		for (i = 0; i < sizeof(neededrates) / sizeof(uint32_t); i++) {
> +			if (drm_mode_vrefresh(m) * 1000 < neededrates[i])
> +				continue;
> +
> +			if (neededrates[i] < range->min_vfreq * 1000)
> +				continue;
> +
> +			num = (unsigned long long)m->clock * 1000 * 1000;
> +			den = neededrates[i] * (unsigned long long)m->htotal;
> +			target_vtotal = div_u64(num, den);
> +			target_vtotal_diff = target_vtotal - m->vtotal;
> +
> +			/*
> +			 * Check for illegal modes
> +			 */
Same here for single line comment
> +			if (m->vsync_start + target_vtotal_diff < m->vdisplay ||
> +			    m->vsync_end + target_vtotal_diff < m->vsync_start ||
> +			    m->vtotal + target_vtotal_diff < m->vsync_end)
> +				continue;
> +
> +			new_mode = drm_mode_duplicate(aconnector->base.dev, m);
> +			if (!new_mode)
> +				goto out;
> +
> +			new_mode->vtotal += (u16)target_vtotal_diff;
> +			new_mode->vsync_start += (u16)target_vtotal_diff;
> +			new_mode->vsync_end += (u16)target_vtotal_diff;
> +			new_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
> +			new_mode->type |= DRM_MODE_TYPE_DRIVER;
> +			strcat(new_mode->name, "_FSV\0");
> +
> +			if (!is_duplicate_mode(aconnector, new_mode)) {
or drm_mode_equal here ?
> +				drm_mode_probed_add(&aconnector->base, new_mode);
> +				new_modes_count += 1;
> +			} else
> +				drm_mode_destroy(aconnector->base.dev, new_mode);
> +		}
> +	}
> + out:
> +	return new_modes_count;
> +}
> +
> +static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connector,
> +						   struct edid *edid)
> +{
> +	uint8_t i;
> +	struct detailed_timing *timing;
> +	struct detailed_non_pixel *data;
> +	struct detailed_data_monitor_range *range;
> +	struct amdgpu_dm_connector *amdgpu_dm_connector =
> +		to_amdgpu_dm_connector(connector);
> +
> +	if (!(amdgpu_exp_freesync_vid_mode && edid))
> +		return;
> +
> +	if (!(amdgpu_dm_connector->dc_sink->sink_signal == SIGNAL_TYPE_EDP ||

do we want the freesync infra to be available for eDP also ?

- Shashank

> +	      amdgpu_dm_connector->dc_sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT ||
> +	      amdgpu_dm_connector->dc_sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A))
> +		return;
> +
> +	if (edid->version == 1 && edid->revision > 1) {
> +		for (i = 0; i < 4; i++) {
> +			timing = &edid->detailed_timings[i];
> +			data = &timing->data.other_data;
> +			range = &data->data.range;
> +			/*
> +			 * Check if monitor has continuous frequency mode
> +			 */
> +			if (data->type == EDID_DETAIL_MONITOR_RANGE &&
> +			    range->max_vfreq - range->min_vfreq > 10) {
> +				amdgpu_dm_connector->num_modes += add_fs_modes(amdgpu_dm_connector, range);
> +				break;
> +			}
> +		}
> +	}
> +}
> +
>  static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
>  {
>  	struct amdgpu_dm_connector *amdgpu_dm_connector =
> @@ -7021,6 +7217,7 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
>  	} else {
>  		amdgpu_dm_connector_ddc_get_modes(connector, edid);
>  		amdgpu_dm_connector_add_common_modes(encoder, connector);
> +		amdgpu_dm_connector_add_freesync_modes(connector, edid);
>  	}
>  	amdgpu_dm_fbc_init(connector);
>  

[-- Attachment #1.2: Type: text/html, Size: 10818 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/3] drm/amd/display: Skip modeset for front porch change
  2020-12-10  2:45 ` [PATCH 3/3] drm/amd/display: Skip modeset for front porch change Aurabindo Pillai
  2020-12-10 10:21   ` Christian König
@ 2020-12-10 12:59   ` Shashank Sharma
  2020-12-10 17:50     ` Aurabindo Pillai
  2021-01-04 16:16   ` Kazlauskas, Nicholas
  2 siblings, 1 reply; 29+ messages in thread
From: Shashank Sharma @ 2020-12-10 12:59 UTC (permalink / raw)
  To: Aurabindo Pillai, amd-gfx
  Cc: stylon.wang, thong.thai, wayne.lin, alexander.deucher,
	Harry.Wentland, nicholas.kazlauskas


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@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 ?
> +
>  	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 ?
> +	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 ?
> +	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.
> +				saved_mode = mode;
> +				mode = *freesync_mode;
> +			}
> +		}
> +
>  		decide_crtc_timing_for_drm_display_mode(
>  				&mode, preferred_mode,
> -				dm_state ? (dm_state->scaling != RMX_OFF) : false);
> +				dm_state ? (dm_state->scaling != RMX_OFF) : false,
> +				freesync_mode ? true : false);
>  		preferred_refresh = drm_mode_vrefresh(preferred_mode);
>  	}
>  
>  	if (!dm_state)
>  		drm_mode_set_crtcinfo(&mode, 0);
>  
> -	/*
> +	if (dm_state && is_fs_vid_mode && freesync_mode)

Same here, I guess if is_fs_vide_mode == true, freesync_mode must never be NULL

- Shashank

> +		drm_mode_set_crtcinfo(&saved_mode, 0);
> +
> +       /*
>  	* If scaling is enabled and refresh rate didn't change
>  	* we copy the vic and polarities of the old timings
>  	*/
> -	if (!scale || mode_refresh != preferred_refresh)
> +	if (!(scale && freesync_mode) || mode_refresh != preferred_refresh)
>  		fill_stream_properties_from_drm_display_mode(stream,
>  			&mode, &aconnector->base, con_state, NULL, requested_bpc);
>  	else
> @@ -7881,13 +7922,29 @@ static void update_stream_irq_parameters(
>  	if (new_crtc_state->vrr_supported &&
>  	    config.min_refresh_in_uhz &&
>  	    config.max_refresh_in_uhz) {
> +		/*
> +		 * if freesync compatible mode was set, config.state will be set
> +		 * in atomic check
> +		 */
> +		if (config.state == VRR_STATE_ACTIVE_FIXED &&
> +		    config.fixed_refresh_in_uhz && config.max_refresh_in_uhz &&
> +		    config.min_refresh_in_uhz &&
> +		    (!drm_atomic_crtc_needs_modeset(&new_crtc_state->base) ||
> +		     new_crtc_state->freesync_video_mode)) {
> +			vrr_params.max_refresh_in_uhz = config.max_refresh_in_uhz;
> +			vrr_params.min_refresh_in_uhz = config.min_refresh_in_uhz;
> +			vrr_params.fixed_refresh_in_uhz = config.fixed_refresh_in_uhz;
> +			vrr_params.state = VRR_STATE_ACTIVE_FIXED;
> +			goto out;
> +		}
> +
>  		config.state = new_crtc_state->base.vrr_enabled ?
>  			VRR_STATE_ACTIVE_VARIABLE :
>  			VRR_STATE_INACTIVE;
> -	} else {
> +	} else
>  		config.state = VRR_STATE_UNSUPPORTED;
> -	}
>  
> +out:
>  	mod_freesync_build_vrr_params(dm->freesync_module,
>  				      new_stream,
>  				      &config, &vrr_params);
> @@ -8205,7 +8262,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
>  		 * as part of commit.
>  		 */
>  		if (amdgpu_dm_vrr_active(dm_old_crtc_state) !=
> -		    amdgpu_dm_vrr_active(acrtc_state)) {
> +		    amdgpu_dm_vrr_active(acrtc_state) ||
> +		    acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED ||
> +		    acrtc_state->freesync_video_mode) {
>  			spin_lock_irqsave(&pcrtc->dev->event_lock, flags);
>  			dc_stream_adjust_vmin_vmax(
>  				dm->dc, acrtc_state->stream,
> @@ -8896,6 +8955,7 @@ static void get_freesync_config_for_crtc(
>  			to_amdgpu_dm_connector(new_con_state->base.connector);
>  	struct drm_display_mode *mode = &new_crtc_state->base.mode;
>  	int vrefresh = drm_mode_vrefresh(mode);
> +	bool fs_vid_mode = false;
>  
>  	new_crtc_state->vrr_supported = new_con_state->freesync_capable &&
>  					vrefresh >= aconnector->min_vfreq &&
> @@ -8903,17 +8963,26 @@ static void get_freesync_config_for_crtc(
>  
>  	if (new_crtc_state->vrr_supported) {
>  		new_crtc_state->stream->ignore_msa_timing_param = true;
> -		config.state = new_crtc_state->base.vrr_enabled ?
> -				VRR_STATE_ACTIVE_VARIABLE :
> -				VRR_STATE_INACTIVE;
> -		config.min_refresh_in_uhz =
> -				aconnector->min_vfreq * 1000000;
> -		config.max_refresh_in_uhz =
> -				aconnector->max_vfreq * 1000000;
> +		fs_vid_mode = new_crtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED ||
> +			new_crtc_state->freesync_video_mode;
> +
> +		config.min_refresh_in_uhz = aconnector->min_vfreq * 1000000;
> +		config.max_refresh_in_uhz = aconnector->max_vfreq * 1000000;
>  		config.vsif_supported = true;
>  		config.btr = true;
> -	}
>  
> +		if (fs_vid_mode) {
> +			config.state = VRR_STATE_ACTIVE_FIXED;
> +			config.fixed_refresh_in_uhz = new_crtc_state->freesync_config.fixed_refresh_in_uhz;
> +			goto out;
> +		}
> +		else if (new_crtc_state->base.vrr_enabled && !fs_vid_mode)
> +			config.state = VRR_STATE_ACTIVE_VARIABLE;
> +		else
> +			config.state = VRR_STATE_INACTIVE;
> +
> +	}
> +out:
>  	new_crtc_state->freesync_config = config;
>  }
>  
> @@ -8926,6 +8995,51 @@ static void reset_freesync_config_for_crtc(
>  	       sizeof(new_crtc_state->vrr_infopacket));
>  }
>  
> +static bool
> +is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
> +				 struct drm_crtc_state *new_crtc_state)
> +{
> +	struct drm_display_mode old_mode, new_mode;
> +
> +	if (!old_crtc_state || !new_crtc_state)
> +		return false;
> +
> +	old_mode = old_crtc_state->mode;
> +	new_mode = new_crtc_state->mode;
> +
> +	if (old_mode.clock       == new_mode.clock &&
> +	    old_mode.hdisplay    == new_mode.hdisplay &&
> +	    old_mode.vdisplay    == new_mode.vdisplay &&
> +	    old_mode.htotal      == new_mode.htotal &&
> +	    old_mode.vtotal      != new_mode.vtotal &&
> +	    old_mode.hsync_start == new_mode.hsync_start &&
> +	    old_mode.vsync_start != new_mode.vsync_start &&
> +	    old_mode.hsync_end   == new_mode.hsync_end &&
> +	    old_mode.vsync_end   != new_mode.vsync_end &&
> +	    old_mode.hskew       == new_mode.hskew &&
> +	    old_mode.vscan       == new_mode.vscan &&
> +	    (old_mode.vsync_end - old_mode.vsync_start) ==
> +	    (new_mode.vsync_end - new_mode.vsync_start))
> +		return true;
> +
> +	return false;
> +}
> +
> +static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) {
> +	uint64_t num, den, res;
> +	struct drm_crtc_state *new_crtc_state = &dm_new_crtc_state->base;
> +
> +	dm_new_crtc_state->freesync_config.state = VRR_STATE_ACTIVE_FIXED;
> +
> +	num = (unsigned long long)new_crtc_state->mode.clock * 1000 * 1000000;
> +	den = (unsigned long long)new_crtc_state->mode.htotal *
> +	      (unsigned long long)new_crtc_state->mode.vtotal;
> +
> +	res = div_u64(num, den);
> +	dm_new_crtc_state->freesync_config.fixed_refresh_in_uhz = res;
> +	dm_new_crtc_state->freesync_video_mode = true;
> +}
> +
>  static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>  				struct drm_atomic_state *state,
>  				struct drm_crtc *crtc,
> @@ -9016,6 +9130,11 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>  		 * TODO: Refactor this function to allow this check to work
>  		 * in all conditions.
>  		 */
> +		if (dm_new_crtc_state->stream &&
> +		    is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state) &&
> +		    amdgpu_exp_freesync_vid_mode)
> +			goto skip_modeset;
> +
>  		if (dm_new_crtc_state->stream &&
>  		    dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
>  		    dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
> @@ -9047,6 +9166,22 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>  		if (!dm_old_crtc_state->stream)
>  			goto skip_modeset;
>  
> +		if (dm_new_crtc_state->stream &&
> +		    is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state) &&
> +		    amdgpu_exp_freesync_vid_mode) {
> +			new_crtc_state->mode_changed = false;
> +			DRM_DEBUG_DRIVER(
> +				"Mode change not required for front porch change, "
> +				"setting mode_changed to %d",
> +				new_crtc_state->mode_changed);
> +
> +			set_freesync_fixed_config(dm_new_crtc_state);
> +
> +			goto skip_modeset;
> +		} else if (aconnector &&
> +			   is_freesync_video_mode(&new_crtc_state->mode, aconnector))
> +			set_freesync_fixed_config(dm_new_crtc_state);
> +
>  		ret = dm_atomic_get_state(state, &dm_state);
>  		if (ret)
>  			goto fail;
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> index 251af783f6b1..28f2d8c9b260 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -453,6 +453,7 @@ struct dm_crtc_state {
>  
>  	bool freesync_timing_changed;
>  	bool freesync_vrr_info_changed;
> +	bool freesync_video_mode;
>  
>  	bool dsc_force_changed;
>  	bool vrr_supported;
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/3] drm/amd/display: Add freesync video modes based on preferred modes
  2020-12-10 12:37   ` Shashank Sharma
@ 2020-12-10 16:56     ` Aurabindo Pillai
  0 siblings, 0 replies; 29+ messages in thread
From: Aurabindo Pillai @ 2020-12-10 16:56 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx


[-- Attachment #1.1: Type: text/plain, Size: 8964 bytes --]

Hi Shashank,

Thanks for the review. Please see my inline responses.

On Thu, 2020-12-10 at 18:07 +0530, Shashank Sharma wrote:
> Hello Aurabindo,
> 
> 
> On 10/12/20 8:15 am, Aurabindo Pillai wrote:
> 
> > [Why&How]
> > If experimental freesync video mode module parameter is enabled,
> > add
> > few extra display modes into the driver's mode list corresponding
> > to common
> > video frame rates. When userspace sets these modes, no modeset will
> > be
> > performed (if current mode was one of freesync modes or the base
> > freesync mode
> > based off which timings have been generated for the rest of the
> > freesync modes)
> > since these modes only differ from the base mode with front porch
> > timing.
> > 
> > Signed-off-by: Aurabindo Pillai 
> > <aurabindo.pillai@amd.com>
> > 
> > ---
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 197
> > ++++++++++++++++++
> >  1 file changed, 197 insertions(+)
> > 
> > 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 fbff8d693e03..f699a3d41cad 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > @@ -5178,6 +5178,69 @@ static void
> > dm_enable_per_frame_crtc_master_sync(struct dc_state *context)
> >  	set_master_stream(context->streams, context->stream_count);
> >  }
> >  
> > +static struct drm_display_mode *
> > +get_highest_freesync_mode(struct amdgpu_dm_connector *aconnector,
> > +			  bool use_probed_modes)
>  the function name is confusing, this function has nothing to do with
> freesync. Probably drop the 'freesync' from the name,
> get_highest_refresh_rate_mode or similar ?

Will do.
>  
> > +{
> > +	struct drm_display_mode *m, *m_high = NULL;
> > +	u16 current_refresh, highest_refresh, preferred_mode_h,
> > preferred_mode_w;
> > +	struct list_head *list_head = use_probed_modes ?
> > +						    &aconnector-
> > >base.probed_modes :
> > +						    &aconnector-
> > >base.modes;
> > +
> > +	/*
> > +	 * Find the preferred mode
> > +	 */
>  Single line comment should be in /* */

Will do.
> > +
> > +	list_for_each_entry (m, list_head, head) {
> > +		if (!(m->type & DRM_MODE_TYPE_PREFERRED))
> > +			continue;
> > +
> > +		m_high = m;
> > +		preferred_mode_h = m_high->hdisplay;
> > +		preferred_mode_w = m_high->vdisplay;
> > +		highest_refresh = drm_mode_vrefresh(m_high);
> > +		break;
> > +	}
> > +
> > +	if (!m_high) {
> > +
> > +		/*
> > +		 * Probably an EDID with no preferred mode.
> > +		 * Fallback to first entry;
> > +		 */
> > +		m_high = list_first_entry_or_null(&aconnector-
> > >base.modes,
> > +						  struct
> > drm_display_mode, head);
> > +		if (!m_high)
> > +			return NULL;
> > +		else {
> > +			preferred_mode_h = m_high->hdisplay;
> > +			preferred_mode_w = m_high->vdisplay;
> > +			highest_refresh = drm_mode_vrefresh(m_high);
> > +		}
> > +	}
> > +
> > +	/*
> > +	 * Find the mode with highest refresh rate with same
> > resolution.
> > +	 * For some monitors, preferred mode is not the mode with
> > highest
> > +	 * supported refresh rate.
> > +	 */
> > +	list_for_each_entry (m, list_head, head) {
> > +		current_refresh  = drm_mode_vrefresh(m);
> > +
> > +		if (m->hdisplay == preferred_mode_h &&
> > +		    m->vdisplay == preferred_mode_w &&
> > +		    highest_refresh < current_refresh) {
> > +			highest_refresh = current_refresh;
> > +			preferred_mode_h = m->hdisplay;
> > +			preferred_mode_w = m->vdisplay;
>  why do we need to save preferred_mode_h and w variables at all ? I
> thought the idea here was to get the mode with highest refresh rate,
> but same resolution, which is indicated in the if (cond) above also.
> I think we just need highest refresh rate isn't ? 

Yes you're right. Will make that change.

> > +			m_high = m;
> > +		}
> > +	}
> > +
> > +	return m_high;
> > +}
> > +
> >  static struct dc_stream_state *
> >  create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
> >  		       const struct drm_display_mode *drm_mode,
> > @@ -7006,6 +7069,139 @@ static void
> > amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
> >  	}
> >  }
> >  
> > +static bool is_duplicate_mode(struct amdgpu_dm_connector
> > *aconnector,
> > +			      struct drm_display_mode *mode)
> > +{
> > +	struct drm_display_mode *m;
> > +
> > +	list_for_each_entry (m, &aconnector->base.probed_modes, head) {
> > +		if (m->clock == mode->clock &&
> > +		    m->htotal == mode->htotal &&
> > +		    m->vtotal == mode->vtotal &&
> > +		    m->hdisplay == mode->hdisplay &&
> > +		    m->vdisplay == mode->vdisplay &&
> > +		    m->hsync_start == mode->hsync_start &&
> > +		    m->vsync_start == mode->vsync_start &&
> > +		    m->vsync_end == mode->vsync_end &&
> > +		    m->hsync_end == mode->hsync_end)
> > +			return true;
> > +	}
> > +
> > +	return false;
>  Why not use drm_mode_equal() instead ?

Wasnt aware of this API, thanks!

> > +}
> > +
> > +static uint add_fs_modes(struct amdgpu_dm_connector *aconnector,
> > +			 struct detailed_data_monitor_range *range)
> > +{
> > +	const struct drm_display_mode *m, *m_save;
> > +	struct drm_display_mode *new_mode;
> > +	uint i;
> > +	uint64_t target_vtotal, target_vtotal_diff;
> > +	uint32_t new_modes_count = 0;
> > +	uint64_t num, den;
> > +
> > +	/* Standard FPS values
> > +	 *
> > +	 * 23.976 - TV/NTSC
> > +	 * 24	  - Cinema
> > +	 * 25     - TV/PAL
> > +	 * 29.97  - TV/NTSC
> > +	 * 30     - TV/NTSC
> > +	 * 48	  - Cinema HFR
> > +	 * 50	  - TV/PAL
> > +	 */
> > +	const uint32_t neededrates[] = { 23976, 24000, 25000, 29970,
> > +					 30000, 48000, 50000, 72000,
> > 96000 };
> > +
> > +	/*
> > +	 * Find mode with highest refresh rate with the same resolution
> > +	 * as the preferred mode. Some monitors report a preferred mode
> > +	 * with lower resolution than the highest refresh rate
> > supported.
> > +	 */
> > +
> > +	m_save = get_highest_freesync_mode(aconnector, true);
>  A NULL return check here to bypass the whole routine below ? 

Will do.
> > +
> > +	list_for_each_entry (m, &aconnector->base.probed_modes, head) {
> > +		if (m != m_save)
> > +			continue;
> > +
> > +		for (i = 0; i < sizeof(neededrates) / sizeof(uint32_t);
> > i++) {
> > +			if (drm_mode_vrefresh(m) * 1000 <
> > neededrates[i])
> > +				continue;
> > +
> > +			if (neededrates[i] < range->min_vfreq * 1000)
> > +				continue;
> > +
> > +			num = (unsigned long long)m->clock * 1000 *
> > 1000;
>  
> > +			den = neededrates[i] * (unsigned long long)m-
> > >htotal;
> > +			target_vtotal = div_u64(num, den);
> > +			target_vtotal_diff = target_vtotal - m->vtotal;
> > +
> > +			/*
> > +			 * Check for illegal modes
> > +			 */
>  Same here for single line comment
> > +			if (m->vsync_start + target_vtotal_diff < m-
> > >vdisplay ||
> > +			    m->vsync_end + target_vtotal_diff < m-
> > >vsync_start ||
> > +			    m->vtotal + target_vtotal_diff < m-
> > >vsync_end)
> > +				continue;
> > +
> > +			new_mode = drm_mode_duplicate(aconnector-
> > >base.dev, m);
> > +			if (!new_mode)
> > +				goto out;
> > +
> > +			new_mode->vtotal += (u16)target_vtotal_diff;
> > +			new_mode->vsync_start +=
> > (u16)target_vtotal_diff;
> > +			new_mode->vsync_end += (u16)target_vtotal_diff;
> > +			new_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
> > +			new_mode->type |= DRM_MODE_TYPE_DRIVER;
> > +			strcat(new_mode->name, "_FSV\0");
> > +
> > +			if (!is_duplicate_mode(aconnector, new_mode)) {
>  or drm_mode_equal here ?

Will modify is_duplicate_mode() to use drm_mode_equal.

> > +				drm_mode_probed_add(&aconnector->base,
> > new_mode);
> > +				new_modes_count += 1;
> > +			} else
> > +				drm_mode_destroy(aconnector->base.dev,
> > new_mode);
> > +		}
> > +	}
> > + out:
> > +	return new_modes_count;
> > +}
> > +
> > +static void amdgpu_dm_connector_add_freesync_modes(struct
> > drm_connector *connector,
> > +						   struct edid *edid)
> > +{
> > +	uint8_t i;
> > +	struct detailed_timing *timing;
> > +	struct detailed_non_pixel *data;
> > +	struct detailed_data_monitor_range *range;
> > +	struct amdgpu_dm_connector *amdgpu_dm_connector =
> > +		to_amdgpu_dm_connector(connector);
> > +
> > +	if (!(amdgpu_exp_freesync_vid_mode && edid))
> > +		return;
>  
> > +
> > +	if (!(amdgpu_dm_connector->dc_sink->sink_signal ==
> > SIGNAL_TYPE_EDP ||
> 
> do we want the freesync infra to be available for eDP also ? 
> 

Freesync is enabled on eDP as well. There is no reason to block it.
Only requirement would be to check if the monitor actually supports
VRR. So it makes sense to remove this check. We are already checking
for VRR support below through EDID_DETAIL_MONITOR_RANGE.


--

Regards,
Aurabindo Pillai


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/3] drm/amd/display: Skip modeset for front porch change
  2020-12-10 12:59   ` Shashank Sharma
@ 2020-12-10 17:50     ` Aurabindo Pillai
  2020-12-11  5:08       ` Shashank Sharma
  0 siblings, 1 reply; 29+ messages in thread
From: Aurabindo Pillai @ 2020-12-10 17:50 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: stylon.wang, thong.thai, wayne.lin, alexander.deucher,
	Harry.Wentland, nicholas.kazlauskas


[-- Attachment #1.1: Type: text/plain, Size: 5527 bytes --]

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@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.

> > +	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

[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/3] drm/amd/display: Skip modeset for front porch change
  2020-12-10 17:50     ` Aurabindo Pillai
@ 2020-12-11  5:08       ` Shashank Sharma
  2020-12-11 14:49         ` Kazlauskas, Nicholas
  0 siblings, 1 reply; 29+ messages in thread
From: Shashank Sharma @ 2020-12-11  5:08 UTC (permalink / raw)
  To: Aurabindo Pillai, amd-gfx
  Cc: stylon.wang, thong.thai, wayne.lin, alexander.deucher,
	Harry.Wentland, nicholas.kazlauskas


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

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/3] drm/amd/display: Skip modeset for front porch change
  2020-12-11  5:08       ` Shashank Sharma
@ 2020-12-11 14:49         ` Kazlauskas, Nicholas
  2020-12-11 15:35           ` Shashank Sharma
  0 siblings, 1 reply; 29+ messages in thread
From: Kazlauskas, Nicholas @ 2020-12-11 14:49 UTC (permalink / raw)
  To: Shashank Sharma, Aurabindo Pillai, amd-gfx
  Cc: alexander.deucher, stylon.wang, thong.thai, Harry.Wentland, wayne.lin

On 2020-12-11 12:08 a.m., Shashank Sharma wrote:
> 
> 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@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

I'd rather we not make mode name part of a UAPI or to identify a 
"FreeSync mode". This is already behind a module option and from the 
driver's perspective we only need the timing to understand whether or 
not we can do an optimized modeset using FreeSync into it. Driver 
private flags can optimize the check away but it's only a few 
comparisons so I don't see much benefit.

We will always need to reference the original preferred mode regardless 
of how the FreeSync mode is identified since there could be a case where 
we're enabling the CRTC from disabled -> enabled. The display was 
previously blank and we need to reprogram the OTG timing to the mode 
that doesn't have an extended front porch.

Regards,
Nicholas Kazlauskas

> 
>>>> +	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

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/3] drm/amd/display: Skip modeset for front porch change
  2020-12-11 14:49         ` Kazlauskas, Nicholas
@ 2020-12-11 15:35           ` Shashank Sharma
  2020-12-11 16:20             ` Kazlauskas, Nicholas
  0 siblings, 1 reply; 29+ messages in thread
From: Shashank Sharma @ 2020-12-11 15:35 UTC (permalink / raw)
  To: Kazlauskas, Nicholas, Aurabindo Pillai, amd-gfx
  Cc: alexander.deucher, stylon.wang, thong.thai, Harry.Wentland, wayne.lin


On 11/12/20 8:19 pm, Kazlauskas, Nicholas wrote:
> On 2020-12-11 12:08 a.m., Shashank Sharma wrote:
>> 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@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
> I'd rather we not make mode name part of a UAPI or to identify a 
> "FreeSync mode". This is already behind a module option and from the 
> driver's perspective we only need the timing to understand whether or 
> not we can do an optimized modeset using FreeSync into it. Driver 
> private flags can optimize the check away but it's only a few 
> comparisons so I don't see much benefit.
The module parameter is just to control the addition of freesync modes or not, but that doesn't let you differentiate between a genuine EDID mode or Freesync modes added by us, to accommodate freesync solution.  
>
> We will always need to reference the original preferred mode regardless 
> of how the FreeSync mode is identified since there could be a case where 
> we're enabling the CRTC from disabled -> enabled. The display was 
> previously blank and we need to reprogram the OTG timing to the mode 
> that doesn't have an extended front porch.

I think there is a gap in understanding my comment here. If you see the current implement of function "is_freesync_video_mode", what it does is it explores all the modes from the connector's probed_modes list, and compares them with possible_fs_modes, and decides if this mode is a freesync mode or not. My point is, we have already done this exercise once, while we were adding the freesync modes in the mode list already.

Now if we can add a driver_private flag, or some identification in the mode, we don't have to do this whole thing again.

Its like:

While adding freesync modes:

- add_freesync_modes ()

{

    get_preferred_mode()

    prepare_freesync_mode_from_preferred_modes()

    add_new_freesync_mode_in_connector_modelist()  //Add a driver private flag in this new freesync mode

}


Now, as the driver is the only source of the freesync modes, we can make the identifier function during the modeset() can be as small as:

- is_freesync_video_mode (mode)

{

    retrun (mode->flags & driver_private_flag);

}


Point being, there is no need to do the same thing again, in order to identify, if a mode is freesync mode or not, as the driver only has added these modes, and it should know which are these freesync modes.  

- Shashank

> Regards,
> Nicholas Kazlauskas
>
>>>>> +	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
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/3] drm/amd/display: Skip modeset for front porch change
  2020-12-11 15:35           ` Shashank Sharma
@ 2020-12-11 16:20             ` Kazlauskas, Nicholas
  2020-12-11 18:31               ` Shashank Sharma
  0 siblings, 1 reply; 29+ messages in thread
From: Kazlauskas, Nicholas @ 2020-12-11 16:20 UTC (permalink / raw)
  To: Shashank Sharma, Aurabindo Pillai, amd-gfx
  Cc: alexander.deucher, stylon.wang, thong.thai, Harry.Wentland, wayne.lin

On 2020-12-11 10:35 a.m., Shashank Sharma wrote:
> 
> On 11/12/20 8:19 pm, Kazlauskas, Nicholas wrote:
>> On 2020-12-11 12:08 a.m., Shashank Sharma wrote:
>>> 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@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
>> I'd rather we not make mode name part of a UAPI or to identify a
>> "FreeSync mode". This is already behind a module option and from the
>> driver's perspective we only need the timing to understand whether or
>> not we can do an optimized modeset using FreeSync into it. Driver
>> private flags can optimize the check away but it's only a few
>> comparisons so I don't see much benefit.
> The module parameter is just to control the addition of freesync modes or not, but that doesn't let you differentiate between a genuine EDID mode or Freesync modes added by us, to accommodate freesync solution.

It's for both the modeset optimization and the FreeSync mode generation.

>>
>> We will always need to reference the original preferred mode regardless
>> of how the FreeSync mode is identified since there could be a case where
>> we're enabling the CRTC from disabled -> enabled. The display was
>> previously blank and we need to reprogram the OTG timing to the mode
>> that doesn't have an extended front porch.
> 
> I think there is a gap in understanding my comment here. If you see the current implement of function "is_freesync_video_mode", what it does is it explores all the modes from the connector's probed_modes list, and compares them with possible_fs_modes, and decides if this mode is a freesync mode or not. My point is, we have already done this exercise once, while we were adding the freesync modes in the mode list already.
> 
> Now if we can add a driver_private flag, or some identification in the mode, we don't have to do this whole thing again.
> 
> Its like:
> 
> While adding freesync modes:
> 
> - add_freesync_modes ()
> 
> {
> 
>      get_preferred_mode()
> 
>      prepare_freesync_mode_from_preferred_modes()
> 
>      add_new_freesync_mode_in_connector_modelist()  //Add a driver private flag in this new freesync mode
> 
> }
> 
> 
> Now, as the driver is the only source of the freesync modes, we can make the identifier function during the modeset() can be as small as:
> 
> - is_freesync_video_mode (mode)
> 
> {
> 
>      retrun (mode->flags & driver_private_flag);
> 
> }
> 
> 
> Point being, there is no need to do the same thing again, in order to identify, if a mode is freesync mode or not, as the driver only has added these modes, and it should know which are these freesync modes.
> 
> - Shashank

To clarify, the original point was that knowing whether the FreeSync 
mode is a video compatible mode isn't enough - we need to know what the 
base mode's vtotal was to correctly program the hardware.

The base mode is basically the FreeSync optimized mode - preferred mode 
+ highest refresh rate to support BTR.

So when determining whether we skip the modeset the logic should be:

1. Find the base/freesync optimized mode. We can just iterate the mode 
list for this for an unoptimized implementation but I don't think we 
really need to go further than this since this only happens on a modeset.

2. Compare the incoming mode against the freesync optimized mode. If the 
only thing that differs is the vtotal/front porch duration and it's 
within the range supported by the display then we can skip the blank.

Regards,
Nicholas Kazlauskas

> 
>> Regards,
>> Nicholas Kazlauskas
>>
>>>>>> +	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

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/3] drm/amd/display: Skip modeset for front porch change
  2020-12-11 16:20             ` Kazlauskas, Nicholas
@ 2020-12-11 18:31               ` Shashank Sharma
  0 siblings, 0 replies; 29+ messages in thread
From: Shashank Sharma @ 2020-12-11 18:31 UTC (permalink / raw)
  To: Kazlauskas, Nicholas, Aurabindo Pillai, amd-gfx
  Cc: alexander.deucher, stylon.wang, thong.thai, Harry.Wentland, wayne.lin


On 11/12/20 9:50 pm, Kazlauskas, Nicholas wrote:
> On 2020-12-11 10:35 a.m., Shashank Sharma wrote:
>> On 11/12/20 8:19 pm, Kazlauskas, Nicholas wrote:
>>> On 2020-12-11 12:08 a.m., Shashank Sharma wrote:
>>>> 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@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
>>> I'd rather we not make mode name part of a UAPI or to identify a
>>> "FreeSync mode". This is already behind a module option and from the
>>> driver's perspective we only need the timing to understand whether or
>>> not we can do an optimized modeset using FreeSync into it. Driver
>>> private flags can optimize the check away but it's only a few
>>> comparisons so I don't see much benefit.
>> The module parameter is just to control the addition of freesync modes or not, but that doesn't let you differentiate between a genuine EDID mode or Freesync modes added by us, to accommodate freesync solution.
> It's for both the modeset optimization and the FreeSync mode generation.
>
>>> We will always need to reference the original preferred mode regardless
>>> of how the FreeSync mode is identified since there could be a case where
>>> we're enabling the CRTC from disabled -> enabled. The display was
>>> previously blank and we need to reprogram the OTG timing to the mode
>>> that doesn't have an extended front porch.
>> I think there is a gap in understanding my comment here. If you see the current implement of function "is_freesync_video_mode", what it does is it explores all the modes from the connector's probed_modes list, and compares them with possible_fs_modes, and decides if this mode is a freesync mode or not. My point is, we have already done this exercise once, while we were adding the freesync modes in the mode list already.
>>
>> Now if we can add a driver_private flag, or some identification in the mode, we don't have to do this whole thing again.
>>
>> Its like:
>>
>> While adding freesync modes:
>>
>> - add_freesync_modes ()
>>
>> {
>>
>>      get_preferred_mode()
>>
>>      prepare_freesync_mode_from_preferred_modes()
>>
>>      add_new_freesync_mode_in_connector_modelist()  //Add a driver private flag in this new freesync mode
>>
>> }
>>
>>
>> Now, as the driver is the only source of the freesync modes, we can make the identifier function during the modeset() can be as small as:
>>
>> - is_freesync_video_mode (mode)
>>
>> {
>>
>>      retrun (mode->flags & driver_private_flag);
>>
>> }
>>
>>
>> Point being, there is no need to do the same thing again, in order to identify, if a mode is freesync mode or not, as the driver only has added these modes, and it should know which are these freesync modes.
>>
>> - Shashank
> To clarify, the original point was that knowing whether the FreeSync 
> mode is a video compatible mode isn't enough - we need to know what the 
> base mode's vtotal was to correctly program the hardware.
>
> The base mode is basically the FreeSync optimized mode - preferred mode 
> + highest refresh rate to support BTR.
>
> So when determining whether we skip the modeset the logic should be:
>
> 1. Find the base/freesync optimized mode. We can just iterate the mode 
> list for this for an unoptimized implementation but I don't think we 
> really need to go further than this since this only happens on a modeset.
>
> 2. Compare the incoming mode against the freesync optimized mode. If the 
> only thing that differs is the vtotal/front porch duration and it's 
> within the range supported by the display then we can skip the blank.
>
> Regards,
> Nicholas Kazlauskas

Ah, thanks for this explanation, my understanding was slightly different. But in this case, it's even easier than I thought. We just have to cache the preferred_mode and highest refresh rate for freesync operation, and we can avoid going through this whole list again. My point is still the same, we have parsed the list once (or twice) while adding the modes,  there should not be a need to do the whole thing again while identifying the same.

- Shashank

>>> Regards,
>>> Nicholas Kazlauskas
>>>
>>>>>>> +	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
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/3] drm/amd/display: Add module parameter for freesync video mode
  2020-12-10  2:45 ` [PATCH 1/3] drm/amd/display: Add module parameter for freesync video mode Aurabindo Pillai
@ 2021-01-04 15:58   ` Kazlauskas, Nicholas
  0 siblings, 0 replies; 29+ messages in thread
From: Kazlauskas, Nicholas @ 2021-01-04 15:58 UTC (permalink / raw)
  To: Aurabindo Pillai, amd-gfx
  Cc: stylon.wang, thong.thai, shashank.sharma, wayne.lin,
	alexander.deucher, Harry.Wentland

On 2020-12-09 9:45 p.m., Aurabindo Pillai wrote:
> [Why&How]
> Adds a module parameter to enable experimental freesync video mode modeset
> optimization. Enabling this mode allows the driver to skip a full modeset when
> freesync compatible modes are requested by the userspace. This paramters also
> adds some standard modes based on the connected monitor's VRR range.
> 
> Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h     |  1 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 12 ++++++++++++
>   2 files changed, 13 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 83ac06a3ec05..efbfee93c359 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -177,6 +177,7 @@ extern int amdgpu_gpu_recovery;
>   extern int amdgpu_emu_mode;
>   extern uint amdgpu_smu_memory_pool_size;
>   extern uint amdgpu_dc_feature_mask;
> +extern uint amdgpu_exp_freesync_vid_mode;
>   extern uint amdgpu_dc_debug_mask;
>   extern uint amdgpu_dm_abm_level;
>   extern struct amdgpu_mgpu_info mgpu_info;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index b2a1dd7581bf..ece51ecd53d1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -158,6 +158,7 @@ int amdgpu_mes;
>   int amdgpu_noretry = -1;
>   int amdgpu_force_asic_type = -1;
>   int amdgpu_tmz;
> +uint amdgpu_exp_freesync_vid_mode;
>   int amdgpu_reset_method = -1; /* auto */
>   int amdgpu_num_kcq = -1;
>   
> @@ -786,6 +787,17 @@ module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444);
>   MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto, 0 = off (default), 1 = on)");
>   module_param_named(tmz, amdgpu_tmz, int, 0444);
>   
> +/**
> + * DOC: experimental_freesync_video (uint)
> + * Enabled the optimization to adjust front porch timing to achieve seamless mode change experience
> + * when setting a freesync supported mode for which full modeset is not needed.
> + * The default value: 0 (off).
> + */
> +MODULE_PARM_DESC(
> +	experimental_freesync_video,
> +	"Enable freesync modesetting optimization feature (0 = off (default), 1 = on)");
> +module_param_named(experimental_freesync_video, amdgpu_exp_freesync_vid_mode, uint, 0444);
> +
>   /**
>    * DOC: reset_method (int)
>    * GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco)
> 

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/3] drm/amd/display: Skip modeset for front porch change
  2020-12-10  2:45 ` [PATCH 3/3] drm/amd/display: Skip modeset for front porch change Aurabindo Pillai
  2020-12-10 10:21   ` Christian König
  2020-12-10 12:59   ` Shashank Sharma
@ 2021-01-04 16:16   ` Kazlauskas, Nicholas
  2021-01-04 20:43     ` Aurabindo Pillai
  2 siblings, 1 reply; 29+ messages in thread
From: Kazlauskas, Nicholas @ 2021-01-04 16:16 UTC (permalink / raw)
  To: Aurabindo Pillai, amd-gfx
  Cc: stylon.wang, thong.thai, shashank.sharma, wayne.lin,
	alexander.deucher, Harry.Wentland

On 2020-12-09 9:45 p.m., 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@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;
> +
>   	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;
> +
> +	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;
> +}
> +

Need to check that the other parameters are the same:
- hsync_start
- hsync_end
- htotal
- hskew
- vdisplay
- vscan

etc.

>   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;
> +	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) {
> +				saved_mode = mode;
> +				mode = *freesync_mode;
> +			}
> +		}
> +
>   		decide_crtc_timing_for_drm_display_mode(
>   				&mode, preferred_mode,
> -				dm_state ? (dm_state->scaling != RMX_OFF) : false);
> +				dm_state ? (dm_state->scaling != RMX_OFF) : false,
> +				freesync_mode ? true : false);

I don't think we need an additional flag here - scaling/freesync behave 
the same, maybe just rename the variable in the function.

Regards,
Nicholas Kazlauskas

>   		preferred_refresh = drm_mode_vrefresh(preferred_mode);
>   	}
>   
>   	if (!dm_state)
>   		drm_mode_set_crtcinfo(&mode, 0);
>   
> -	/*
> +	if (dm_state && is_fs_vid_mode && freesync_mode)
> +		drm_mode_set_crtcinfo(&saved_mode, 0);
> +
> +       /*
>   	* If scaling is enabled and refresh rate didn't change
>   	* we copy the vic and polarities of the old timings
>   	*/
> -	if (!scale || mode_refresh != preferred_refresh)
> +	if (!(scale && freesync_mode) || mode_refresh != preferred_refresh)
>   		fill_stream_properties_from_drm_display_mode(stream,
>   			&mode, &aconnector->base, con_state, NULL, requested_bpc);
>   	else
> @@ -7881,13 +7922,29 @@ static void update_stream_irq_parameters(
>   	if (new_crtc_state->vrr_supported &&
>   	    config.min_refresh_in_uhz &&
>   	    config.max_refresh_in_uhz) {
> +		/*
> +		 * if freesync compatible mode was set, config.state will be set
> +		 * in atomic check
> +		 */
> +		if (config.state == VRR_STATE_ACTIVE_FIXED &&
> +		    config.fixed_refresh_in_uhz && config.max_refresh_in_uhz &&
> +		    config.min_refresh_in_uhz &&
> +		    (!drm_atomic_crtc_needs_modeset(&new_crtc_state->base) ||
> +		     new_crtc_state->freesync_video_mode)) {
> +			vrr_params.max_refresh_in_uhz = config.max_refresh_in_uhz;
> +			vrr_params.min_refresh_in_uhz = config.min_refresh_in_uhz;
> +			vrr_params.fixed_refresh_in_uhz = config.fixed_refresh_in_uhz;
> +			vrr_params.state = VRR_STATE_ACTIVE_FIXED;
> +			goto out;
> +		}
> +
>   		config.state = new_crtc_state->base.vrr_enabled ?
>   			VRR_STATE_ACTIVE_VARIABLE :
>   			VRR_STATE_INACTIVE;
> -	} else {
> +	} else
>   		config.state = VRR_STATE_UNSUPPORTED;
> -	}
>   
> +out:
>   	mod_freesync_build_vrr_params(dm->freesync_module,
>   				      new_stream,
>   				      &config, &vrr_params);
> @@ -8205,7 +8262,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
>   		 * as part of commit.
>   		 */
>   		if (amdgpu_dm_vrr_active(dm_old_crtc_state) !=
> -		    amdgpu_dm_vrr_active(acrtc_state)) {
> +		    amdgpu_dm_vrr_active(acrtc_state) ||
> +		    acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED ||
> +		    acrtc_state->freesync_video_mode) {
>   			spin_lock_irqsave(&pcrtc->dev->event_lock, flags);
>   			dc_stream_adjust_vmin_vmax(
>   				dm->dc, acrtc_state->stream,
> @@ -8896,6 +8955,7 @@ static void get_freesync_config_for_crtc(
>   			to_amdgpu_dm_connector(new_con_state->base.connector);
>   	struct drm_display_mode *mode = &new_crtc_state->base.mode;
>   	int vrefresh = drm_mode_vrefresh(mode);
> +	bool fs_vid_mode = false;
>   
>   	new_crtc_state->vrr_supported = new_con_state->freesync_capable &&
>   					vrefresh >= aconnector->min_vfreq &&
> @@ -8903,17 +8963,26 @@ static void get_freesync_config_for_crtc(
>   
>   	if (new_crtc_state->vrr_supported) {
>   		new_crtc_state->stream->ignore_msa_timing_param = true;
> -		config.state = new_crtc_state->base.vrr_enabled ?
> -				VRR_STATE_ACTIVE_VARIABLE :
> -				VRR_STATE_INACTIVE;
> -		config.min_refresh_in_uhz =
> -				aconnector->min_vfreq * 1000000;
> -		config.max_refresh_in_uhz =
> -				aconnector->max_vfreq * 1000000;
> +		fs_vid_mode = new_crtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED ||
> +			new_crtc_state->freesync_video_mode;
> +
> +		config.min_refresh_in_uhz = aconnector->min_vfreq * 1000000;
> +		config.max_refresh_in_uhz = aconnector->max_vfreq * 1000000;
>   		config.vsif_supported = true;
>   		config.btr = true;
> -	}
>   
> +		if (fs_vid_mode) {
> +			config.state = VRR_STATE_ACTIVE_FIXED;
> +			config.fixed_refresh_in_uhz = new_crtc_state->freesync_config.fixed_refresh_in_uhz;
> +			goto out;
> +		}
> +		else if (new_crtc_state->base.vrr_enabled && !fs_vid_mode)
> +			config.state = VRR_STATE_ACTIVE_VARIABLE;
> +		else
> +			config.state = VRR_STATE_INACTIVE;
> +
> +	}
> +out:
>   	new_crtc_state->freesync_config = config;
>   }
>   
> @@ -8926,6 +8995,51 @@ static void reset_freesync_config_for_crtc(
>   	       sizeof(new_crtc_state->vrr_infopacket));
>   }
>   
> +static bool
> +is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
> +				 struct drm_crtc_state *new_crtc_state)
> +{
> +	struct drm_display_mode old_mode, new_mode;
> +
> +	if (!old_crtc_state || !new_crtc_state)
> +		return false;
> +
> +	old_mode = old_crtc_state->mode;
> +	new_mode = new_crtc_state->mode;
> +
> +	if (old_mode.clock       == new_mode.clock &&
> +	    old_mode.hdisplay    == new_mode.hdisplay &&
> +	    old_mode.vdisplay    == new_mode.vdisplay &&
> +	    old_mode.htotal      == new_mode.htotal &&
> +	    old_mode.vtotal      != new_mode.vtotal &&
> +	    old_mode.hsync_start == new_mode.hsync_start &&
> +	    old_mode.vsync_start != new_mode.vsync_start &&
> +	    old_mode.hsync_end   == new_mode.hsync_end &&
> +	    old_mode.vsync_end   != new_mode.vsync_end &&
> +	    old_mode.hskew       == new_mode.hskew &&
> +	    old_mode.vscan       == new_mode.vscan &&
> +	    (old_mode.vsync_end - old_mode.vsync_start) ==
> +	    (new_mode.vsync_end - new_mode.vsync_start))
> +		return true;
> +
> +	return false;
> +}
> +
> +static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) {
> +	uint64_t num, den, res;
> +	struct drm_crtc_state *new_crtc_state = &dm_new_crtc_state->base;
> +
> +	dm_new_crtc_state->freesync_config.state = VRR_STATE_ACTIVE_FIXED;
> +
> +	num = (unsigned long long)new_crtc_state->mode.clock * 1000 * 1000000;
> +	den = (unsigned long long)new_crtc_state->mode.htotal *
> +	      (unsigned long long)new_crtc_state->mode.vtotal;
> +
> +	res = div_u64(num, den);
> +	dm_new_crtc_state->freesync_config.fixed_refresh_in_uhz = res;
> +	dm_new_crtc_state->freesync_video_mode = true;
> +}
> +
>   static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   				struct drm_atomic_state *state,
>   				struct drm_crtc *crtc,
> @@ -9016,6 +9130,11 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   		 * TODO: Refactor this function to allow this check to work
>   		 * in all conditions.
>   		 */
> +		if (dm_new_crtc_state->stream &&
> +		    is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state) &&
> +		    amdgpu_exp_freesync_vid_mode)
> +			goto skip_modeset;
> +
>   		if (dm_new_crtc_state->stream &&
>   		    dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
>   		    dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
> @@ -9047,6 +9166,22 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
>   		if (!dm_old_crtc_state->stream)
>   			goto skip_modeset;
>   
> +		if (dm_new_crtc_state->stream &&
> +		    is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state) &&
> +		    amdgpu_exp_freesync_vid_mode) {
> +			new_crtc_state->mode_changed = false;
> +			DRM_DEBUG_DRIVER(
> +				"Mode change not required for front porch change, "
> +				"setting mode_changed to %d",
> +				new_crtc_state->mode_changed);
> +
> +			set_freesync_fixed_config(dm_new_crtc_state);
> +
> +			goto skip_modeset;
> +		} else if (aconnector &&
> +			   is_freesync_video_mode(&new_crtc_state->mode, aconnector))
> +			set_freesync_fixed_config(dm_new_crtc_state);
> +
>   		ret = dm_atomic_get_state(state, &dm_state);
>   		if (ret)
>   			goto fail;
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> index 251af783f6b1..28f2d8c9b260 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -453,6 +453,7 @@ struct dm_crtc_state {
>   
>   	bool freesync_timing_changed;
>   	bool freesync_vrr_info_changed;
> +	bool freesync_video_mode;
>   
>   	bool dsc_force_changed;
>   	bool vrr_supported;
> 

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/3] drm/amd/display: Skip modeset for front porch change
  2021-01-04 16:16   ` Kazlauskas, Nicholas
@ 2021-01-04 20:43     ` Aurabindo Pillai
  0 siblings, 0 replies; 29+ messages in thread
From: Aurabindo Pillai @ 2021-01-04 20:43 UTC (permalink / raw)
  To: Kazlauskas, Nicholas, amd-gfx
  Cc: stylon.wang, thong.thai, shashank.sharma, wayne.lin,
	alexander.deucher, Harry.Wentland

On Mon, 2021-01-04 at 11:16 -0500, Kazlauskas, Nicholas wrote:
> On 2020-12-09 9:45 p.m., 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@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;
> > +
> >         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;
> > +
> > +       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;
> > +}
> > +
> 
> Need to check that the other parameters are the same:
> - hsync_start
> - hsync_end
> - htotal
> - hskew
> - vdisplay
> - vscan
> 
> etc.

Will do.

> 
> >   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;
> > +       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) {
> > +                               saved_mode = mode;
> > +                               mode = *freesync_mode;
> > +                       }
> > +               }
> > +
> >                 decide_crtc_timing_for_drm_display_mode(
> >                                 &mode, preferred_mode,
> > -                               dm_state ? (dm_state->scaling !=
> > RMX_OFF) : false);
> > +                               dm_state ? (dm_state->scaling !=
> > RMX_OFF) : false,
> > +                               freesync_mode ? true : false);
> 
> I don't think we need an additional flag here - scaling/freesync
> behave 
> the same, maybe just rename the variable in the function.

This was fixed in v3. Will send out a v4 with above change and the
suggestion from Alex to change the module parameter name.

> 
> Regards,
> Nicholas Kazlauskas
> 
> >                 preferred_refresh =
> > drm_mode_vrefresh(preferred_mode);
> >         }
> >   
> >         if (!dm_state)
> >                 drm_mode_set_crtcinfo(&mode, 0);
> >   
> > -       /*
> > +       if (dm_state && is_fs_vid_mode && freesync_mode)
> > +               drm_mode_set_crtcinfo(&saved_mode, 0);
> > +
> > +       /*
> >         * If scaling is enabled and refresh rate didn't change
> >         * we copy the vic and polarities of the old timings
> >         */
> > -       if (!scale || mode_refresh != preferred_refresh)
> > +       if (!(scale && freesync_mode) || mode_refresh !=
> > preferred_refresh)
> >                 fill_stream_properties_from_drm_display_mode(stream
> > ,
> >                         &mode, &aconnector->base, con_state, NULL,
> > requested_bpc);
> >         else
> > @@ -7881,13 +7922,29 @@ static void update_stream_irq_parameters(
> >         if (new_crtc_state->vrr_supported &&
> >             config.min_refresh_in_uhz &&
> >             config.max_refresh_in_uhz) {
> > +               /*
> > +                * if freesync compatible mode was set,
> > config.state will be set
> > +                * in atomic check
> > +                */
> > +               if (config.state == VRR_STATE_ACTIVE_FIXED &&
> > +                   config.fixed_refresh_in_uhz &&
> > config.max_refresh_in_uhz &&
> > +                   config.min_refresh_in_uhz &&
> > +                  
> > (!drm_atomic_crtc_needs_modeset(&new_crtc_state->base) ||
> > +                    new_crtc_state->freesync_video_mode)) {
> > +                       vrr_params.max_refresh_in_uhz =
> > config.max_refresh_in_uhz;
> > +                       vrr_params.min_refresh_in_uhz =
> > config.min_refresh_in_uhz;
> > +                       vrr_params.fixed_refresh_in_uhz =
> > config.fixed_refresh_in_uhz;
> > +                       vrr_params.state = VRR_STATE_ACTIVE_FIXED;
> > +                       goto out;
> > +               }
> > +
> >                 config.state = new_crtc_state->base.vrr_enabled ?
> >                         VRR_STATE_ACTIVE_VARIABLE :
> >                         VRR_STATE_INACTIVE;
> > -       } else {
> > +       } else
> >                 config.state = VRR_STATE_UNSUPPORTED;
> > -       }
> >   
> > +out:
> >         mod_freesync_build_vrr_params(dm->freesync_module,
> >                                       new_stream,
> >                                       &config, &vrr_params);
> > @@ -8205,7 +8262,9 @@ static void amdgpu_dm_commit_planes(struct
> > drm_atomic_state *state,
> >                  * as part of commit.
> >                  */
> >                 if (amdgpu_dm_vrr_active(dm_old_crtc_state) !=
> > -                   amdgpu_dm_vrr_active(acrtc_state)) {
> > +                   amdgpu_dm_vrr_active(acrtc_state) ||
> > +                   acrtc_state->freesync_config.state ==
> > VRR_STATE_ACTIVE_FIXED ||
> > +                   acrtc_state->freesync_video_mode) {
> >                         spin_lock_irqsave(&pcrtc->dev->event_lock,
> > flags);
> >                         dc_stream_adjust_vmin_vmax(
> >                                 dm->dc, acrtc_state->stream,
> > @@ -8896,6 +8955,7 @@ static void get_freesync_config_for_crtc(
> >                         to_amdgpu_dm_connector(new_con_state-
> > >base.connector);
> >         struct drm_display_mode *mode = &new_crtc_state->base.mode;
> >         int vrefresh = drm_mode_vrefresh(mode);
> > +       bool fs_vid_mode = false;
> >   
> >         new_crtc_state->vrr_supported = new_con_state-
> > >freesync_capable &&
> >                                         vrefresh >= aconnector-
> > >min_vfreq &&
> > @@ -8903,17 +8963,26 @@ static void get_freesync_config_for_crtc(
> >   
> >         if (new_crtc_state->vrr_supported) {
> >                 new_crtc_state->stream->ignore_msa_timing_param =
> > true;
> > -               config.state = new_crtc_state->base.vrr_enabled ?
> > -                               VRR_STATE_ACTIVE_VARIABLE :
> > -                               VRR_STATE_INACTIVE;
> > -               config.min_refresh_in_uhz =
> > -                               aconnector->min_vfreq * 1000000;
> > -               config.max_refresh_in_uhz =
> > -                               aconnector->max_vfreq * 1000000;
> > +               fs_vid_mode = new_crtc_state->freesync_config.state
> > == VRR_STATE_ACTIVE_FIXED ||
> > +                       new_crtc_state->freesync_video_mode;
> > +
> > +               config.min_refresh_in_uhz = aconnector->min_vfreq *
> > 1000000;
> > +               config.max_refresh_in_uhz = aconnector->max_vfreq *
> > 1000000;
> >                 config.vsif_supported = true;
> >                 config.btr = true;
> > -       }
> >   
> > +               if (fs_vid_mode) {
> > +                       config.state = VRR_STATE_ACTIVE_FIXED;
> > +                       config.fixed_refresh_in_uhz =
> > new_crtc_state->freesync_config.fixed_refresh_in_uhz;
> > +                       goto out;
> > +               }
> > +               else if (new_crtc_state->base.vrr_enabled &&
> > !fs_vid_mode)
> > +                       config.state = VRR_STATE_ACTIVE_VARIABLE;
> > +               else
> > +                       config.state = VRR_STATE_INACTIVE;
> > +
> > +       }
> > +out:
> >         new_crtc_state->freesync_config = config;
> >   }
> >   
> > @@ -8926,6 +8995,51 @@ static void reset_freesync_config_for_crtc(
> >                sizeof(new_crtc_state->vrr_infopacket));
> >   }
> >   
> > +static bool
> > +is_timing_unchanged_for_freesync(struct drm_crtc_state
> > *old_crtc_state,
> > +                                struct drm_crtc_state
> > *new_crtc_state)
> > +{
> > +       struct drm_display_mode old_mode, new_mode;
> > +
> > +       if (!old_crtc_state || !new_crtc_state)
> > +               return false;
> > +
> > +       old_mode = old_crtc_state->mode;
> > +       new_mode = new_crtc_state->mode;
> > +
> > +       if (old_mode.clock       == new_mode.clock &&
> > +           old_mode.hdisplay    == new_mode.hdisplay &&
> > +           old_mode.vdisplay    == new_mode.vdisplay &&
> > +           old_mode.htotal      == new_mode.htotal &&
> > +           old_mode.vtotal      != new_mode.vtotal &&
> > +           old_mode.hsync_start == new_mode.hsync_start &&
> > +           old_mode.vsync_start != new_mode.vsync_start &&
> > +           old_mode.hsync_end   == new_mode.hsync_end &&
> > +           old_mode.vsync_end   != new_mode.vsync_end &&
> > +           old_mode.hskew       == new_mode.hskew &&
> > +           old_mode.vscan       == new_mode.vscan &&
> > +           (old_mode.vsync_end - old_mode.vsync_start) ==
> > +           (new_mode.vsync_end - new_mode.vsync_start))
> > +               return true;
> > +
> > +       return false;
> > +}
> > +
> > +static void set_freesync_fixed_config(struct dm_crtc_state
> > *dm_new_crtc_state) {
> > +       uint64_t num, den, res;
> > +       struct drm_crtc_state *new_crtc_state = &dm_new_crtc_state-
> > >base;
> > +
> > +       dm_new_crtc_state->freesync_config.state =
> > VRR_STATE_ACTIVE_FIXED;
> > +
> > +       num = (unsigned long long)new_crtc_state->mode.clock * 1000
> > * 1000000;
> > +       den = (unsigned long long)new_crtc_state->mode.htotal *
> > +             (unsigned long long)new_crtc_state->mode.vtotal;
> > +
> > +       res = div_u64(num, den);
> > +       dm_new_crtc_state->freesync_config.fixed_refresh_in_uhz =
> > res;
> > +       dm_new_crtc_state->freesync_video_mode = true;
> > +}
> > +
> >   static int dm_update_crtc_state(struct amdgpu_display_manager
> > *dm,
> >                                 struct drm_atomic_state *state,
> >                                 struct drm_crtc *crtc,
> > @@ -9016,6 +9130,11 @@ static int dm_update_crtc_state(struct
> > amdgpu_display_manager *dm,
> >                  * TODO: Refactor this function to allow this check
> > to work
> >                  * in all conditions.
> >                  */
> > +               if (dm_new_crtc_state->stream &&
> > +                  
> > is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state) &&
> > +                   amdgpu_exp_freesync_vid_mode)
> > +                       goto skip_modeset;
> > +
> >                 if (dm_new_crtc_state->stream &&
> >                     dc_is_stream_unchanged(new_stream,
> > dm_old_crtc_state->stream) &&
> >                     dc_is_stream_scaling_unchanged(new_stream,
> > dm_old_crtc_state->stream)) {
> > @@ -9047,6 +9166,22 @@ static int dm_update_crtc_state(struct
> > amdgpu_display_manager *dm,
> >                 if (!dm_old_crtc_state->stream)
> >                         goto skip_modeset;
> >   
> > +               if (dm_new_crtc_state->stream &&
> > +                  
> > is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state) &&
> > +                   amdgpu_exp_freesync_vid_mode) {
> > +                       new_crtc_state->mode_changed = false;
> > +                       DRM_DEBUG_DRIVER(
> > +                               "Mode change not required for front
> > porch change, "
> > +                               "setting mode_changed to %d",
> > +                               new_crtc_state->mode_changed);
> > +
> > +                       set_freesync_fixed_config(dm_new_crtc_state
> > );
> > +
> > +                       goto skip_modeset;
> > +               } else if (aconnector &&
> > +                          is_freesync_video_mode(&new_crtc_state-
> > >mode, aconnector))
> > +                       set_freesync_fixed_config(dm_new_crtc_state
> > );
> > +
> >                 ret = dm_atomic_get_state(state, &dm_state);
> >                 if (ret)
> >                         goto fail;
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > index 251af783f6b1..28f2d8c9b260 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > @@ -453,6 +453,7 @@ struct dm_crtc_state {
> >   
> >         bool freesync_timing_changed;
> >         bool freesync_vrr_info_changed;
> > +       bool freesync_video_mode;
> >   
> >         bool dsc_force_changed;
> >         bool vrr_supported;
> > 
> 


_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/3] Experimental freesync video mode optimization
  2021-01-22 15:16       ` Alex Deucher
@ 2021-02-02 14:27         ` Daniel Vetter
  -1 siblings, 0 replies; 29+ messages in thread
From: Daniel Vetter @ 2021-02-02 14:27 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Stylon Wang, Shashank Sharma, Thong Thai,
	Maling list - DRI developers, Christian Koenig, Aurabindo Pillai,
	amd-gfx list, Wayne Lin, Deucher, Alexander, Kazlauskas,
	Nicholas

On Fri, Jan 22, 2021 at 10:16:45AM -0500, Alex Deucher wrote:
> On Fri, Jan 22, 2021 at 4:43 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> >
> > On Fri, Jan 22, 2021 at 10:32:48AM +0200, Pekka Paalanen wrote:
> > > On Tue, 19 Jan 2021 10:50:26 -0500
> > > Aurabindo Pillai <aurabindo.pillai@amd.com> wrote:
> > >
> > > > Changes in V5
> > > > =============
> > > >
> > > > * More info in commit messages on the rationale of changes being added
> > > > to the kernel.
> > > > * Minor fixes
> > >
> > > Hi,
> > >
> > > thank you for adding the explanations in the commit messages I asked
> > > for. It is now up to DRM maintainers to determine if this is
> > > conceptually fine.
> > >
> > > I do see that apparently setting the opt-in option does not yet taint
> > > the kernel although Daniel Vetter suggested it might be a good idea. I
> > > guess tainting the kernel would make it easier to remove this feature
> > > in the future because it would be easier to dismiss people that claim a
> > > kernel regression due to the removal.
> >
> > Reading the descriptions I'm honestly not sure why this isn't enabled by
> > default?
> >
> > Maybe the explanations should also capture why this is maybe not a good
> > idea ...
> 
> I don't know that it's a bad idea, I guess we are just cautious to
> avoid unforeseen consequences until we have more real world experience
> using the feature.  One issue brought up as a possible problem, but
> not actually verified to my knowledge, was the possibility of using a
> bit more power with freesync modes.  E.g., if you just change the
> front porch to set the refresh to 48 Hz on a 90Hz mode, you are
> technically running the display phys at the higher clock speed so you
> can seamlessly transition to 90Hz or whatever.  I don't know that it
> uses that much additional power and lets you get some nice features in
> a relatively seamless manner that already works today with most media
> players.

Hm yeah that's a good point. You can't change the dotclock to something
lower on the fly? We have that on some intel laptops, but it's kinda been
superseeded with manual update (PSR on DP) in most places, and then
everything is shut down anyway. But either of these happen automatically,
and we even have self refresh helpers now if you don't have hw assitance
for these to automatically ramp back up to max refresh rate (Intel loves
baking stuff into hw a bit too much, so drm/i915 isn't using it).

> I guess for media player folks, is this something you'd like as is?  A
> more explicit API may be nicer, but I think I think the ultimate
> solution will end up getting tied up in what are plans are for bigger
> features like more advanced flip queues and stuff like that.  So this
> seems like a nice intermediate step.

Yeah I think knobs to figure out details is good, but ime they're just
have a tendency to stay around forever and eventually we suffer from
combinatorial explosion and also a bit (for this one here) uapi
fragmentation. Which isn't nice if the solution to a user problem is "add
this obscure kernel cmdline to your grub file".

That's why I think the taining module param is a good interim step for
figuring stuff out, while reducing a bit the risk it'll become a permanent
thing users have to fiddle.

Cheers, Daniel

> 
> Alex
> 
> 
> > -Daniel
> >
> > >
> > >
> > > Thanks,
> > > pq
> > >
> > >
> > > > --
> > > >
> > > > This patchset enables freesync video mode usecase where the userspace
> > > > can request a freesync compatible video mode such that switching to this
> > > > mode does not trigger blanking.
> > > >
> > > > This feature is guarded by a module parameter which is disabled by
> > > > default. Enabling this paramters adds additional modes to the driver
> > > > modelist, and also enables the optimization to skip modeset when using
> > > > one of these modes.
> > > >
> > > > --
> > > >
> > > > Aurabindo Pillai (3):
> > > >   drm/amd/display: Add module parameter for freesync video mode
> > > >   drm/amd/display: Add freesync video modes based on preferred modes
> > > >   drm/amd/display: Skip modeset for front porch change
> > > >
> > > >  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
> > > >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
> > > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
> > > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
> > > >  4 files changed, 382 insertions(+), 35 deletions(-)
> > > >
> > >
> >
> >
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/3] Experimental freesync video mode optimization
@ 2021-02-02 14:27         ` Daniel Vetter
  0 siblings, 0 replies; 29+ messages in thread
From: Daniel Vetter @ 2021-02-02 14:27 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Stylon Wang, Shashank Sharma, Thong Thai,
	Maling list - DRI developers, Christian Koenig, Pekka Paalanen,
	Aurabindo Pillai, amd-gfx list, Daniel Vetter, Wayne Lin,
	Deucher, Alexander, Kazlauskas, Nicholas

On Fri, Jan 22, 2021 at 10:16:45AM -0500, Alex Deucher wrote:
> On Fri, Jan 22, 2021 at 4:43 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> >
> > On Fri, Jan 22, 2021 at 10:32:48AM +0200, Pekka Paalanen wrote:
> > > On Tue, 19 Jan 2021 10:50:26 -0500
> > > Aurabindo Pillai <aurabindo.pillai@amd.com> wrote:
> > >
> > > > Changes in V5
> > > > =============
> > > >
> > > > * More info in commit messages on the rationale of changes being added
> > > > to the kernel.
> > > > * Minor fixes
> > >
> > > Hi,
> > >
> > > thank you for adding the explanations in the commit messages I asked
> > > for. It is now up to DRM maintainers to determine if this is
> > > conceptually fine.
> > >
> > > I do see that apparently setting the opt-in option does not yet taint
> > > the kernel although Daniel Vetter suggested it might be a good idea. I
> > > guess tainting the kernel would make it easier to remove this feature
> > > in the future because it would be easier to dismiss people that claim a
> > > kernel regression due to the removal.
> >
> > Reading the descriptions I'm honestly not sure why this isn't enabled by
> > default?
> >
> > Maybe the explanations should also capture why this is maybe not a good
> > idea ...
> 
> I don't know that it's a bad idea, I guess we are just cautious to
> avoid unforeseen consequences until we have more real world experience
> using the feature.  One issue brought up as a possible problem, but
> not actually verified to my knowledge, was the possibility of using a
> bit more power with freesync modes.  E.g., if you just change the
> front porch to set the refresh to 48 Hz on a 90Hz mode, you are
> technically running the display phys at the higher clock speed so you
> can seamlessly transition to 90Hz or whatever.  I don't know that it
> uses that much additional power and lets you get some nice features in
> a relatively seamless manner that already works today with most media
> players.

Hm yeah that's a good point. You can't change the dotclock to something
lower on the fly? We have that on some intel laptops, but it's kinda been
superseeded with manual update (PSR on DP) in most places, and then
everything is shut down anyway. But either of these happen automatically,
and we even have self refresh helpers now if you don't have hw assitance
for these to automatically ramp back up to max refresh rate (Intel loves
baking stuff into hw a bit too much, so drm/i915 isn't using it).

> I guess for media player folks, is this something you'd like as is?  A
> more explicit API may be nicer, but I think I think the ultimate
> solution will end up getting tied up in what are plans are for bigger
> features like more advanced flip queues and stuff like that.  So this
> seems like a nice intermediate step.

Yeah I think knobs to figure out details is good, but ime they're just
have a tendency to stay around forever and eventually we suffer from
combinatorial explosion and also a bit (for this one here) uapi
fragmentation. Which isn't nice if the solution to a user problem is "add
this obscure kernel cmdline to your grub file".

That's why I think the taining module param is a good interim step for
figuring stuff out, while reducing a bit the risk it'll become a permanent
thing users have to fiddle.

Cheers, Daniel

> 
> Alex
> 
> 
> > -Daniel
> >
> > >
> > >
> > > Thanks,
> > > pq
> > >
> > >
> > > > --
> > > >
> > > > This patchset enables freesync video mode usecase where the userspace
> > > > can request a freesync compatible video mode such that switching to this
> > > > mode does not trigger blanking.
> > > >
> > > > This feature is guarded by a module parameter which is disabled by
> > > > default. Enabling this paramters adds additional modes to the driver
> > > > modelist, and also enables the optimization to skip modeset when using
> > > > one of these modes.
> > > >
> > > > --
> > > >
> > > > Aurabindo Pillai (3):
> > > >   drm/amd/display: Add module parameter for freesync video mode
> > > >   drm/amd/display: Add freesync video modes based on preferred modes
> > > >   drm/amd/display: Skip modeset for front porch change
> > > >
> > > >  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
> > > >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
> > > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
> > > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
> > > >  4 files changed, 382 insertions(+), 35 deletions(-)
> > > >
> > >
> >
> >
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/3] Experimental freesync video mode optimization
  2021-01-22  9:42     ` Daniel Vetter
@ 2021-01-22 15:16       ` Alex Deucher
  -1 siblings, 0 replies; 29+ messages in thread
From: Alex Deucher @ 2021-01-22 15:16 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Stylon Wang, Shashank Sharma, Thong Thai,
	Maling list - DRI developers, Christian Koenig, Aurabindo Pillai,
	amd-gfx list, Wayne Lin, Deucher, Alexander, Kazlauskas,
	Nicholas

On Fri, Jan 22, 2021 at 4:43 AM Daniel Vetter <daniel@ffwll.ch> wrote:
>
> On Fri, Jan 22, 2021 at 10:32:48AM +0200, Pekka Paalanen wrote:
> > On Tue, 19 Jan 2021 10:50:26 -0500
> > Aurabindo Pillai <aurabindo.pillai@amd.com> wrote:
> >
> > > Changes in V5
> > > =============
> > >
> > > * More info in commit messages on the rationale of changes being added
> > > to the kernel.
> > > * Minor fixes
> >
> > Hi,
> >
> > thank you for adding the explanations in the commit messages I asked
> > for. It is now up to DRM maintainers to determine if this is
> > conceptually fine.
> >
> > I do see that apparently setting the opt-in option does not yet taint
> > the kernel although Daniel Vetter suggested it might be a good idea. I
> > guess tainting the kernel would make it easier to remove this feature
> > in the future because it would be easier to dismiss people that claim a
> > kernel regression due to the removal.
>
> Reading the descriptions I'm honestly not sure why this isn't enabled by
> default?
>
> Maybe the explanations should also capture why this is maybe not a good
> idea ...

I don't know that it's a bad idea, I guess we are just cautious to
avoid unforeseen consequences until we have more real world experience
using the feature.  One issue brought up as a possible problem, but
not actually verified to my knowledge, was the possibility of using a
bit more power with freesync modes.  E.g., if you just change the
front porch to set the refresh to 48 Hz on a 90Hz mode, you are
technically running the display phys at the higher clock speed so you
can seamlessly transition to 90Hz or whatever.  I don't know that it
uses that much additional power and lets you get some nice features in
a relatively seamless manner that already works today with most media
players.

I guess for media player folks, is this something you'd like as is?  A
more explicit API may be nicer, but I think I think the ultimate
solution will end up getting tied up in what are plans are for bigger
features like more advanced flip queues and stuff like that.  So this
seems like a nice intermediate step.

Alex


> -Daniel
>
> >
> >
> > Thanks,
> > pq
> >
> >
> > > --
> > >
> > > This patchset enables freesync video mode usecase where the userspace
> > > can request a freesync compatible video mode such that switching to this
> > > mode does not trigger blanking.
> > >
> > > This feature is guarded by a module parameter which is disabled by
> > > default. Enabling this paramters adds additional modes to the driver
> > > modelist, and also enables the optimization to skip modeset when using
> > > one of these modes.
> > >
> > > --
> > >
> > > Aurabindo Pillai (3):
> > >   drm/amd/display: Add module parameter for freesync video mode
> > >   drm/amd/display: Add freesync video modes based on preferred modes
> > >   drm/amd/display: Skip modeset for front porch change
> > >
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
> > >  4 files changed, 382 insertions(+), 35 deletions(-)
> > >
> >
>
>
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/3] Experimental freesync video mode optimization
@ 2021-01-22 15:16       ` Alex Deucher
  0 siblings, 0 replies; 29+ messages in thread
From: Alex Deucher @ 2021-01-22 15:16 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Stylon Wang, Shashank Sharma, Thong Thai,
	Maling list - DRI developers, Christian Koenig, Pekka Paalanen,
	Aurabindo Pillai, amd-gfx list, Wayne Lin, Deucher, Alexander,
	Kazlauskas, Nicholas

On Fri, Jan 22, 2021 at 4:43 AM Daniel Vetter <daniel@ffwll.ch> wrote:
>
> On Fri, Jan 22, 2021 at 10:32:48AM +0200, Pekka Paalanen wrote:
> > On Tue, 19 Jan 2021 10:50:26 -0500
> > Aurabindo Pillai <aurabindo.pillai@amd.com> wrote:
> >
> > > Changes in V5
> > > =============
> > >
> > > * More info in commit messages on the rationale of changes being added
> > > to the kernel.
> > > * Minor fixes
> >
> > Hi,
> >
> > thank you for adding the explanations in the commit messages I asked
> > for. It is now up to DRM maintainers to determine if this is
> > conceptually fine.
> >
> > I do see that apparently setting the opt-in option does not yet taint
> > the kernel although Daniel Vetter suggested it might be a good idea. I
> > guess tainting the kernel would make it easier to remove this feature
> > in the future because it would be easier to dismiss people that claim a
> > kernel regression due to the removal.
>
> Reading the descriptions I'm honestly not sure why this isn't enabled by
> default?
>
> Maybe the explanations should also capture why this is maybe not a good
> idea ...

I don't know that it's a bad idea, I guess we are just cautious to
avoid unforeseen consequences until we have more real world experience
using the feature.  One issue brought up as a possible problem, but
not actually verified to my knowledge, was the possibility of using a
bit more power with freesync modes.  E.g., if you just change the
front porch to set the refresh to 48 Hz on a 90Hz mode, you are
technically running the display phys at the higher clock speed so you
can seamlessly transition to 90Hz or whatever.  I don't know that it
uses that much additional power and lets you get some nice features in
a relatively seamless manner that already works today with most media
players.

I guess for media player folks, is this something you'd like as is?  A
more explicit API may be nicer, but I think I think the ultimate
solution will end up getting tied up in what are plans are for bigger
features like more advanced flip queues and stuff like that.  So this
seems like a nice intermediate step.

Alex


> -Daniel
>
> >
> >
> > Thanks,
> > pq
> >
> >
> > > --
> > >
> > > This patchset enables freesync video mode usecase where the userspace
> > > can request a freesync compatible video mode such that switching to this
> > > mode does not trigger blanking.
> > >
> > > This feature is guarded by a module parameter which is disabled by
> > > default. Enabling this paramters adds additional modes to the driver
> > > modelist, and also enables the optimization to skip modeset when using
> > > one of these modes.
> > >
> > > --
> > >
> > > Aurabindo Pillai (3):
> > >   drm/amd/display: Add module parameter for freesync video mode
> > >   drm/amd/display: Add freesync video modes based on preferred modes
> > >   drm/amd/display: Skip modeset for front porch change
> > >
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
> > >  4 files changed, 382 insertions(+), 35 deletions(-)
> > >
> >
>
>
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/3] Experimental freesync video mode optimization
  2021-01-22  9:42     ` Daniel Vetter
@ 2021-01-22  9:44       ` Daniel Vetter
  -1 siblings, 0 replies; 29+ messages in thread
From: Daniel Vetter @ 2021-01-22  9:44 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: stylon.wang, thong.thai, shashank.sharma, dri-devel,
	nicholas.kazlauskas, Aurabindo Pillai, amd-gfx, wayne.lin,
	alexander.deucher, christian.koenig

On Fri, Jan 22, 2021 at 10:42:53AM +0100, Daniel Vetter wrote:
> On Fri, Jan 22, 2021 at 10:32:48AM +0200, Pekka Paalanen wrote:
> > On Tue, 19 Jan 2021 10:50:26 -0500
> > Aurabindo Pillai <aurabindo.pillai@amd.com> wrote:
> > 
> > > Changes in V5
> > > =============
> > > 
> > > * More info in commit messages on the rationale of changes being added
> > > to the kernel.
> > > * Minor fixes
> > 
> > Hi,
> > 
> > thank you for adding the explanations in the commit messages I asked
> > for. It is now up to DRM maintainers to determine if this is
> > conceptually fine.
> > 
> > I do see that apparently setting the opt-in option does not yet taint
> > the kernel although Daniel Vetter suggested it might be a good idea. I
> > guess tainting the kernel would make it easier to remove this feature
> > in the future because it would be easier to dismiss people that claim a
> > kernel regression due to the removal.
> 
> Reading the descriptions I'm honestly not sure why this isn't enabled by
> default?
> 
> Maybe the explanations should also capture why this is maybe not a good
> idea ...

And also, if this is a bad idea uapi-vise, then it definitely needs to be
behind the tainting module option until we've sorted it out (and then just
enable it by default once that's done).
-Daniel

> -Daniel
> 
> > 
> > 
> > Thanks,
> > pq
> > 
> > 
> > > --
> > > 
> > > This patchset enables freesync video mode usecase where the userspace
> > > can request a freesync compatible video mode such that switching to this
> > > mode does not trigger blanking.
> > > 
> > > This feature is guarded by a module parameter which is disabled by
> > > default. Enabling this paramters adds additional modes to the driver
> > > modelist, and also enables the optimization to skip modeset when using
> > > one of these modes.
> > > 
> > > --
> > > 
> > > Aurabindo Pillai (3):
> > >   drm/amd/display: Add module parameter for freesync video mode
> > >   drm/amd/display: Add freesync video modes based on preferred modes
> > >   drm/amd/display: Skip modeset for front porch change
> > > 
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
> > >  4 files changed, 382 insertions(+), 35 deletions(-)
> > > 
> > 
> 
> 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/3] Experimental freesync video mode optimization
@ 2021-01-22  9:44       ` Daniel Vetter
  0 siblings, 0 replies; 29+ messages in thread
From: Daniel Vetter @ 2021-01-22  9:44 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: stylon.wang, thong.thai, shashank.sharma, dri-devel,
	nicholas.kazlauskas, Aurabindo Pillai, amd-gfx, Daniel Vetter,
	wayne.lin, alexander.deucher, christian.koenig

On Fri, Jan 22, 2021 at 10:42:53AM +0100, Daniel Vetter wrote:
> On Fri, Jan 22, 2021 at 10:32:48AM +0200, Pekka Paalanen wrote:
> > On Tue, 19 Jan 2021 10:50:26 -0500
> > Aurabindo Pillai <aurabindo.pillai@amd.com> wrote:
> > 
> > > Changes in V5
> > > =============
> > > 
> > > * More info in commit messages on the rationale of changes being added
> > > to the kernel.
> > > * Minor fixes
> > 
> > Hi,
> > 
> > thank you for adding the explanations in the commit messages I asked
> > for. It is now up to DRM maintainers to determine if this is
> > conceptually fine.
> > 
> > I do see that apparently setting the opt-in option does not yet taint
> > the kernel although Daniel Vetter suggested it might be a good idea. I
> > guess tainting the kernel would make it easier to remove this feature
> > in the future because it would be easier to dismiss people that claim a
> > kernel regression due to the removal.
> 
> Reading the descriptions I'm honestly not sure why this isn't enabled by
> default?
> 
> Maybe the explanations should also capture why this is maybe not a good
> idea ...

And also, if this is a bad idea uapi-vise, then it definitely needs to be
behind the tainting module option until we've sorted it out (and then just
enable it by default once that's done).
-Daniel

> -Daniel
> 
> > 
> > 
> > Thanks,
> > pq
> > 
> > 
> > > --
> > > 
> > > This patchset enables freesync video mode usecase where the userspace
> > > can request a freesync compatible video mode such that switching to this
> > > mode does not trigger blanking.
> > > 
> > > This feature is guarded by a module parameter which is disabled by
> > > default. Enabling this paramters adds additional modes to the driver
> > > modelist, and also enables the optimization to skip modeset when using
> > > one of these modes.
> > > 
> > > --
> > > 
> > > Aurabindo Pillai (3):
> > >   drm/amd/display: Add module parameter for freesync video mode
> > >   drm/amd/display: Add freesync video modes based on preferred modes
> > >   drm/amd/display: Skip modeset for front porch change
> > > 
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
> > >  4 files changed, 382 insertions(+), 35 deletions(-)
> > > 
> > 
> 
> 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/3] Experimental freesync video mode optimization
  2021-01-22  8:32   ` Pekka Paalanen
@ 2021-01-22  9:42     ` Daniel Vetter
  -1 siblings, 0 replies; 29+ messages in thread
From: Daniel Vetter @ 2021-01-22  9:42 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: stylon.wang, thong.thai, shashank.sharma, dri-devel,
	nicholas.kazlauskas, Aurabindo Pillai, amd-gfx, wayne.lin,
	alexander.deucher, christian.koenig

On Fri, Jan 22, 2021 at 10:32:48AM +0200, Pekka Paalanen wrote:
> On Tue, 19 Jan 2021 10:50:26 -0500
> Aurabindo Pillai <aurabindo.pillai@amd.com> wrote:
> 
> > Changes in V5
> > =============
> > 
> > * More info in commit messages on the rationale of changes being added
> > to the kernel.
> > * Minor fixes
> 
> Hi,
> 
> thank you for adding the explanations in the commit messages I asked
> for. It is now up to DRM maintainers to determine if this is
> conceptually fine.
> 
> I do see that apparently setting the opt-in option does not yet taint
> the kernel although Daniel Vetter suggested it might be a good idea. I
> guess tainting the kernel would make it easier to remove this feature
> in the future because it would be easier to dismiss people that claim a
> kernel regression due to the removal.

Reading the descriptions I'm honestly not sure why this isn't enabled by
default?

Maybe the explanations should also capture why this is maybe not a good
idea ...
-Daniel

> 
> 
> Thanks,
> pq
> 
> 
> > --
> > 
> > This patchset enables freesync video mode usecase where the userspace
> > can request a freesync compatible video mode such that switching to this
> > mode does not trigger blanking.
> > 
> > This feature is guarded by a module parameter which is disabled by
> > default. Enabling this paramters adds additional modes to the driver
> > modelist, and also enables the optimization to skip modeset when using
> > one of these modes.
> > 
> > --
> > 
> > Aurabindo Pillai (3):
> >   drm/amd/display: Add module parameter for freesync video mode
> >   drm/amd/display: Add freesync video modes based on preferred modes
> >   drm/amd/display: Skip modeset for front porch change
> > 
> >  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
> >  4 files changed, 382 insertions(+), 35 deletions(-)
> > 
> 



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/3] Experimental freesync video mode optimization
@ 2021-01-22  9:42     ` Daniel Vetter
  0 siblings, 0 replies; 29+ messages in thread
From: Daniel Vetter @ 2021-01-22  9:42 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: stylon.wang, thong.thai, shashank.sharma, dri-devel,
	nicholas.kazlauskas, Aurabindo Pillai, amd-gfx, Daniel Vetter,
	wayne.lin, alexander.deucher, christian.koenig

On Fri, Jan 22, 2021 at 10:32:48AM +0200, Pekka Paalanen wrote:
> On Tue, 19 Jan 2021 10:50:26 -0500
> Aurabindo Pillai <aurabindo.pillai@amd.com> wrote:
> 
> > Changes in V5
> > =============
> > 
> > * More info in commit messages on the rationale of changes being added
> > to the kernel.
> > * Minor fixes
> 
> Hi,
> 
> thank you for adding the explanations in the commit messages I asked
> for. It is now up to DRM maintainers to determine if this is
> conceptually fine.
> 
> I do see that apparently setting the opt-in option does not yet taint
> the kernel although Daniel Vetter suggested it might be a good idea. I
> guess tainting the kernel would make it easier to remove this feature
> in the future because it would be easier to dismiss people that claim a
> kernel regression due to the removal.

Reading the descriptions I'm honestly not sure why this isn't enabled by
default?

Maybe the explanations should also capture why this is maybe not a good
idea ...
-Daniel

> 
> 
> Thanks,
> pq
> 
> 
> > --
> > 
> > This patchset enables freesync video mode usecase where the userspace
> > can request a freesync compatible video mode such that switching to this
> > mode does not trigger blanking.
> > 
> > This feature is guarded by a module parameter which is disabled by
> > default. Enabling this paramters adds additional modes to the driver
> > modelist, and also enables the optimization to skip modeset when using
> > one of these modes.
> > 
> > --
> > 
> > Aurabindo Pillai (3):
> >   drm/amd/display: Add module parameter for freesync video mode
> >   drm/amd/display: Add freesync video modes based on preferred modes
> >   drm/amd/display: Skip modeset for front porch change
> > 
> >  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
> >  4 files changed, 382 insertions(+), 35 deletions(-)
> > 
> 



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/3] Experimental freesync video mode optimization
  2021-01-19 15:50 ` Aurabindo Pillai
@ 2021-01-22  8:32   ` Pekka Paalanen
  -1 siblings, 0 replies; 29+ messages in thread
From: Pekka Paalanen @ 2021-01-22  8:32 UTC (permalink / raw)
  To: Aurabindo Pillai
  Cc: stylon.wang, thong.thai, shashank.sharma, dri-devel,
	nicholas.kazlauskas, amd-gfx, wayne.lin, alexander.deucher,
	christian.koenig


[-- Attachment #1.1: Type: text/plain, Size: 1735 bytes --]

On Tue, 19 Jan 2021 10:50:26 -0500
Aurabindo Pillai <aurabindo.pillai@amd.com> wrote:

> Changes in V5
> =============
> 
> * More info in commit messages on the rationale of changes being added
> to the kernel.
> * Minor fixes

Hi,

thank you for adding the explanations in the commit messages I asked
for. It is now up to DRM maintainers to determine if this is
conceptually fine.

I do see that apparently setting the opt-in option does not yet taint
the kernel although Daniel Vetter suggested it might be a good idea. I
guess tainting the kernel would make it easier to remove this feature
in the future because it would be easier to dismiss people that claim a
kernel regression due to the removal.


Thanks,
pq


> --
> 
> This patchset enables freesync video mode usecase where the userspace
> can request a freesync compatible video mode such that switching to this
> mode does not trigger blanking.
> 
> This feature is guarded by a module parameter which is disabled by
> default. Enabling this paramters adds additional modes to the driver
> modelist, and also enables the optimization to skip modeset when using
> one of these modes.
> 
> --
> 
> Aurabindo Pillai (3):
>   drm/amd/display: Add module parameter for freesync video mode
>   drm/amd/display: Add freesync video modes based on preferred modes
>   drm/amd/display: Skip modeset for front porch change
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
>  4 files changed, 382 insertions(+), 35 deletions(-)
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/3] Experimental freesync video mode optimization
@ 2021-01-22  8:32   ` Pekka Paalanen
  0 siblings, 0 replies; 29+ messages in thread
From: Pekka Paalanen @ 2021-01-22  8:32 UTC (permalink / raw)
  To: Aurabindo Pillai
  Cc: stylon.wang, thong.thai, shashank.sharma, dri-devel,
	nicholas.kazlauskas, amd-gfx, Daniel Vetter, wayne.lin,
	alexander.deucher, christian.koenig


[-- Attachment #1.1: Type: text/plain, Size: 1735 bytes --]

On Tue, 19 Jan 2021 10:50:26 -0500
Aurabindo Pillai <aurabindo.pillai@amd.com> wrote:

> Changes in V5
> =============
> 
> * More info in commit messages on the rationale of changes being added
> to the kernel.
> * Minor fixes

Hi,

thank you for adding the explanations in the commit messages I asked
for. It is now up to DRM maintainers to determine if this is
conceptually fine.

I do see that apparently setting the opt-in option does not yet taint
the kernel although Daniel Vetter suggested it might be a good idea. I
guess tainting the kernel would make it easier to remove this feature
in the future because it would be easier to dismiss people that claim a
kernel regression due to the removal.


Thanks,
pq


> --
> 
> This patchset enables freesync video mode usecase where the userspace
> can request a freesync compatible video mode such that switching to this
> mode does not trigger blanking.
> 
> This feature is guarded by a module parameter which is disabled by
> default. Enabling this paramters adds additional modes to the driver
> modelist, and also enables the optimization to skip modeset when using
> one of these modes.
> 
> --
> 
> Aurabindo Pillai (3):
>   drm/amd/display: Add module parameter for freesync video mode
>   drm/amd/display: Add freesync video modes based on preferred modes
>   drm/amd/display: Skip modeset for front porch change
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
>  4 files changed, 382 insertions(+), 35 deletions(-)
> 


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 0/3] Experimental freesync video mode optimization
@ 2021-01-19 15:50 ` Aurabindo Pillai
  0 siblings, 0 replies; 29+ messages in thread
From: Aurabindo Pillai @ 2021-01-19 15:50 UTC (permalink / raw)
  To: amd-gfx, dri-devel
  Cc: stylon.wang, shashank.sharma, thong.thai, christian.koenig,
	aurabindo.pillai, wayne.lin, alexander.deucher,
	nicholas.kazlauskas

Changes in V5
=============

* More info in commit messages on the rationale of changes being added
to the kernel.
* Minor fixes

Changes in V4
=============

1) Add module parameter for freesync video mode

* Change module parameter name to freesync_video

2) Add freesync video modes based on preferred modes:

* Cosmetic fixes
* Added comments about all modes being added by the driver.

3) Skip modeset for front porch change

* Added more conditions for checking freesync video mode

Changes in V3
=============

1) Add freesync video modes based on preferred modes:

* Cache base freesync video mode during the first iteration to avoid
  iterating over modelist again later.
* Add mode for 60 fps videos

2) Skip modeset for front porch change

* Fixes for bug exposed by caching of modes.

Changes in V2
=============

1) Add freesync video modes based on preferred modes:

* Remove check for connector type before adding freesync compatible
  modes as VRR support is being checked, and there is no reason to block
  freesync video support on eDP.
* use drm_mode_equal() instead of creating same functionality.
* Additional null pointer deference check
* Removed unnecessary variables.
* Cosmetic fixes.

2) Skip modeset for front porch change

* Remove _FSV string being appended to freesync video modes so as to not
  define new policies or break existing application that might use the
  mode name to figure out mode resolution.
* Remove unnecessary variables
* Cosmetic fixes.

--

This patchset enables freesync video mode usecase where the userspace
can request a freesync compatible video mode such that switching to this
mode does not trigger blanking.

This feature is guarded by a module parameter which is disabled by
default. Enabling this paramters adds additional modes to the driver
modelist, and also enables the optimization to skip modeset when using
one of these modes.

--

Aurabindo Pillai (3):
  drm/amd/display: Add module parameter for freesync video mode
  drm/amd/display: Add freesync video modes based on preferred modes
  drm/amd/display: Skip modeset for front porch change

 drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
 4 files changed, 382 insertions(+), 35 deletions(-)

-- 
2.30.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 0/3] Experimental freesync video mode optimization
@ 2021-01-19 15:50 ` Aurabindo Pillai
  0 siblings, 0 replies; 29+ messages in thread
From: Aurabindo Pillai @ 2021-01-19 15:50 UTC (permalink / raw)
  To: amd-gfx, dri-devel
  Cc: stylon.wang, shashank.sharma, thong.thai, christian.koenig,
	aurabindo.pillai, daniel, wayne.lin, alexander.deucher,
	Harry.Wentland, nicholas.kazlauskas

Changes in V5
=============

* More info in commit messages on the rationale of changes being added
to the kernel.
* Minor fixes

Changes in V4
=============

1) Add module parameter for freesync video mode

* Change module parameter name to freesync_video

2) Add freesync video modes based on preferred modes:

* Cosmetic fixes
* Added comments about all modes being added by the driver.

3) Skip modeset for front porch change

* Added more conditions for checking freesync video mode

Changes in V3
=============

1) Add freesync video modes based on preferred modes:

* Cache base freesync video mode during the first iteration to avoid
  iterating over modelist again later.
* Add mode for 60 fps videos

2) Skip modeset for front porch change

* Fixes for bug exposed by caching of modes.

Changes in V2
=============

1) Add freesync video modes based on preferred modes:

* Remove check for connector type before adding freesync compatible
  modes as VRR support is being checked, and there is no reason to block
  freesync video support on eDP.
* use drm_mode_equal() instead of creating same functionality.
* Additional null pointer deference check
* Removed unnecessary variables.
* Cosmetic fixes.

2) Skip modeset for front porch change

* Remove _FSV string being appended to freesync video modes so as to not
  define new policies or break existing application that might use the
  mode name to figure out mode resolution.
* Remove unnecessary variables
* Cosmetic fixes.

--

This patchset enables freesync video mode usecase where the userspace
can request a freesync compatible video mode such that switching to this
mode does not trigger blanking.

This feature is guarded by a module parameter which is disabled by
default. Enabling this paramters adds additional modes to the driver
modelist, and also enables the optimization to skip modeset when using
one of these modes.

--

Aurabindo Pillai (3):
  drm/amd/display: Add module parameter for freesync video mode
  drm/amd/display: Add freesync video modes based on preferred modes
  drm/amd/display: Skip modeset for front porch change

 drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  12 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 401 ++++++++++++++++--
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
 4 files changed, 382 insertions(+), 35 deletions(-)

-- 
2.30.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2021-02-02 14:27 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-10  2:45 [PATCH 0/3] Experimental freesync video mode optimization Aurabindo Pillai
2020-12-10  2:45 ` [PATCH 1/3] drm/amd/display: Add module parameter for freesync video mode Aurabindo Pillai
2021-01-04 15:58   ` Kazlauskas, Nicholas
2020-12-10  2:45 ` [PATCH 2/3] drm/amd/display: Add freesync video modes based on preferred modes Aurabindo Pillai
2020-12-10 12:37   ` Shashank Sharma
2020-12-10 16:56     ` Aurabindo Pillai
2020-12-10  2:45 ` [PATCH 3/3] drm/amd/display: Skip modeset for front porch change Aurabindo Pillai
2020-12-10 10:21   ` Christian König
2020-12-10 12:59   ` Shashank Sharma
2020-12-10 17:50     ` Aurabindo Pillai
2020-12-11  5:08       ` Shashank Sharma
2020-12-11 14:49         ` Kazlauskas, Nicholas
2020-12-11 15:35           ` Shashank Sharma
2020-12-11 16:20             ` Kazlauskas, Nicholas
2020-12-11 18:31               ` Shashank Sharma
2021-01-04 16:16   ` Kazlauskas, Nicholas
2021-01-04 20:43     ` Aurabindo Pillai
2021-01-19 15:50 [PATCH 0/3] Experimental freesync video mode optimization Aurabindo Pillai
2021-01-19 15:50 ` Aurabindo Pillai
2021-01-22  8:32 ` Pekka Paalanen
2021-01-22  8:32   ` Pekka Paalanen
2021-01-22  9:42   ` Daniel Vetter
2021-01-22  9:42     ` Daniel Vetter
2021-01-22  9:44     ` Daniel Vetter
2021-01-22  9:44       ` Daniel Vetter
2021-01-22 15:16     ` Alex Deucher
2021-01-22 15:16       ` Alex Deucher
2021-02-02 14:27       ` Daniel Vetter
2021-02-02 14:27         ` Daniel Vetter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.