Commit 3d4e52d0 authored by Victor Lu's avatar Victor Lu Committed by Alex Deucher
Browse files

drm/amd/display: Add debugfs for forcing stream timing sync



[why]
There's currently no method to enable multi-stream synchronization from
userspace and we don't check the VSDB bits to know whether or not
specific displays should have the feature enable.

[how]
Add a debugfs entry that controls a new DM debug option,
"force_timing_sync". This debug option will set on any newly created
stream following the change to the debug option.
Expose a new interface from DC that performs the timing sync and a helper
to the "force_timing_sync" debugfs that iterates over the current streams
and modifies the current synchornization state and grouping.

Example usage to force a resync (from an X based desktop):

echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_force_timing_sync
xset dpms force off && xset dpms force on

Signed-off-by: default avatarVictor Lu <victorchengchi.lu@amd.com>
Reviewed-by: default avatarAurabindo Jayamohanan Pillai <Aurabindo.Pillai@amd.com>
Acked-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Acked-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent da83b385
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -8034,6 +8034,13 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
			goto fail;
		}

		/*
		 * TODO: Check VSDB bits to decide whether this should
		 * be enabled or not.
		 */
		new_stream->triggered_crtc_reset.enabled =
			dm->force_timing_sync;

		dm_new_crtc_state->abm_level = dm_new_conn_state->abm_level;

		ret = fill_hdr_info_packet(drm_new_conn_state,
@@ -9190,3 +9197,22 @@ static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream)

	return dc_link_set_psr_allow_active(stream->link, false, true);
}

void amdgpu_dm_trigger_timing_sync(struct drm_device *dev)
{
	struct amdgpu_device *adev = dev->dev_private;
	struct dc *dc = adev->dm.dc;
	int i;

	mutex_lock(&adev->dm.dc_lock);
	if (dc->current_state) {
		for (i = 0; i < dc->current_state->stream_count; ++i)
			dc->current_state->streams[i]
				->triggered_crtc_reset.enabled =
				adev->dm.force_timing_sync;

		dm_enable_per_frame_crtc_master_sync(dc->current_state);
		dc_trigger_sync(dc, dc->current_state);
	}
	mutex_unlock(&adev->dm.dc_lock);
}
+3 −0
Original line number Diff line number Diff line
@@ -340,6 +340,7 @@ struct amdgpu_display_manager {
	 * fake encoders used for DP MST.
	 */
	struct amdgpu_encoder mst_encoders[AMDGPU_DM_MAX_CRTC];
        bool force_timing_sync;
};

struct dsc_preferred_settings {
@@ -493,6 +494,8 @@ void dm_restore_drm_connector_state(struct drm_device *dev,
void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
					struct edid *edid);

void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);

#define MAX_COLOR_LUT_ENTRIES 4096
/* Legacy gamm LUT users such as X doesn't like large LUT sizes */
#define MAX_COLOR_LEGACY_LUT_ENTRIES 256
+35 −0
Original line number Diff line number Diff line
@@ -2183,6 +2183,38 @@ static const struct drm_info_list amdgpu_dm_debugfs_list[] = {
	{"amdgpu_mst_topology", &mst_topo},
};

/*
 * Sets the force_timing_sync debug optino from the given string.
 * All connected displays will be force synchronized immediately.
 * Usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_force_timing_sync
 */
static int force_timing_sync_set(void *data, u64 val)
{
	struct amdgpu_device *adev = data;

	adev->dm.force_timing_sync = (bool)val;

	amdgpu_dm_trigger_timing_sync(adev->ddev);

	return 0;
}

/*
 * Gets the force_timing_sync debug option value into the given buffer.
 * Usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_force_timing_sync
 */
static int force_timing_sync_get(void *data, u64 *val)
{
	struct amdgpu_device *adev = data;

	*val = adev->dm.force_timing_sync;

	return 0;
}

DEFINE_DEBUGFS_ATTRIBUTE(force_timing_sync_ops, force_timing_sync_get,
			 force_timing_sync_set, "%llu\n");

/*
 * Sets the DC visual confirm debug option from the given string.
 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_visual_confirm
@@ -2242,5 +2274,8 @@ int dtn_debugfs_init(struct amdgpu_device *adev)
	debugfs_create_file_unsafe("amdgpu_dm_dmub_fw_state", 0644, root,
				   adev, &dmub_fw_state_fops);

	debugfs_create_file_unsafe("amdgpu_dm_force_timing_sync", 0644, root,
				   adev, &force_timing_sync_ops);

	return 0;
}
+9 −4
Original line number Diff line number Diff line
@@ -1238,6 +1238,14 @@ bool dc_enable_stereo(
	return ret;
}

void dc_trigger_sync(struct dc *dc, struct dc_state *context)
{
	if (context->stream_count > 1 && !dc->debug.disable_timing_sync) {
		enable_timing_multisync(dc, context);
		program_timing_sync(dc, context);
	}
}

/*
 * Applies given context to HW and copy it into current context.
 * It's up to the user to release the src context afterwards.
@@ -1297,10 +1305,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
	if (result != DC_OK)
		return result;

	if (context->stream_count > 1 && !dc->debug.disable_timing_sync) {
		enable_timing_multisync(dc, context);
		program_timing_sync(dc, context);
	}
	dc_trigger_sync(dc, context);

	/* Program all planes within new context*/
	if (dc->hwss.program_front_end_for_ctx) {
+2 −0
Original line number Diff line number Diff line
@@ -397,6 +397,8 @@ bool dc_enable_stereo(
	struct dc_stream_state *streams[],
	uint8_t stream_count);

/* Triggers multi-stream synchronization. */
void dc_trigger_sync(struct dc *dc, struct dc_state *context);

enum surface_update_type dc_check_update_surfaces_for_stream(
		struct dc *dc,