Commit 98e6436d authored by Anthony Koo's avatar Anthony Koo Committed by Alex Deucher
Browse files

drm/amd/display: Refactor FreeSync module



Remove dependency on internal sink map and instead
use existing stream and plane state

Signed-off-by: default avatarAnthony Koo <Anthony.Koo@amd.com>
Signed-off-by: default avatarHarry Wentland <harry.wentland@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 8c3db128
Loading
Loading
Loading
Loading
+152 −136
Original line number Diff line number Diff line
@@ -839,8 +839,7 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)

		if (sink) {
			if (aconnector->dc_sink) {
				amdgpu_dm_remove_sink_from_freesync_module(
								connector);
				amdgpu_dm_update_freesync_caps(connector, NULL);
				/* retain and release bellow are used for
				 * bump up refcount for sink because the link don't point
				 * to it anymore after disconnect so on next crtc to connector
@@ -850,10 +849,10 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
					dc_sink_release(aconnector->dc_sink);
			}
			aconnector->dc_sink = sink;
			amdgpu_dm_add_sink_to_freesync_module(
						connector, aconnector->edid);
			amdgpu_dm_update_freesync_caps(connector,
					aconnector->edid);
		} else {
			amdgpu_dm_remove_sink_from_freesync_module(connector);
			amdgpu_dm_update_freesync_caps(connector, NULL);
			if (!aconnector->dc_sink)
				aconnector->dc_sink = aconnector->dc_em_sink;
			else if (aconnector->dc_sink != aconnector->dc_em_sink)
@@ -890,8 +889,7 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
		/* TODO: check if we still need the S3 mode update workaround.
		 * If yes, put it here. */
		if (aconnector->dc_sink)
			amdgpu_dm_remove_sink_from_freesync_module(
							connector);
			amdgpu_dm_update_freesync_caps(connector, NULL);

		aconnector->dc_sink = sink;
		if (sink->dc_edid.length == 0) {
@@ -904,10 +902,10 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
			drm_connector_update_edid_property(connector,
					aconnector->edid);
		}
		amdgpu_dm_add_sink_to_freesync_module(connector, aconnector->edid);
		amdgpu_dm_update_freesync_caps(connector, aconnector->edid);

	} else {
		amdgpu_dm_remove_sink_from_freesync_module(connector);
		amdgpu_dm_update_freesync_caps(connector, NULL);
		drm_connector_update_edid_property(connector, NULL);
		aconnector->num_modes = 0;
		aconnector->dc_sink = NULL;
@@ -1580,26 +1578,68 @@ static void dm_bandwidth_update(struct amdgpu_device *adev)
static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
				struct drm_file *filp)
{
	struct mod_freesync_params freesync_params;
	uint8_t num_streams;
	struct drm_atomic_state *state;
	struct drm_modeset_acquire_ctx ctx;
	struct drm_crtc *crtc;
	struct drm_connector *connector;
	struct drm_connector_state *old_con_state, *new_con_state;
	int ret = 0;
	uint8_t i;
	bool enable = false;

	struct amdgpu_device *adev = dev->dev_private;
	int r = 0;
	drm_modeset_acquire_init(&ctx, 0);

	/* Get freesync enable flag from DRM */
	state = drm_atomic_state_alloc(dev);
	if (!state) {
		ret = -ENOMEM;
		goto out;
	}
	state->acquire_ctx = &ctx;

	num_streams = dc_get_current_stream_count(adev->dm.dc);
retry:
	drm_for_each_crtc(crtc, dev) {
		ret = drm_atomic_add_affected_connectors(state, crtc);
		if (ret)
			goto fail;

	for (i = 0; i < num_streams; i++) {
		struct dc_stream_state *stream;
		stream = dc_get_stream_at_index(adev->dm.dc, i);
		/* TODO rework amdgpu_dm_commit_planes so we don't need this */
		ret = drm_atomic_add_affected_planes(state, crtc);
		if (ret)
			goto fail;
	}

		mod_freesync_update_state(adev->dm.freesync_module,
					  &stream, 1, &freesync_params);
	for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
		struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
		struct drm_crtc_state *new_crtc_state;
		struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
		struct dm_crtc_state *dm_new_crtc_state;

		if (!acrtc) {
			ASSERT(0);
			continue;
		}

	return r;
		new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);

		dm_new_crtc_state->freesync_enabled = enable;
	}

	ret = drm_atomic_commit(state);

fail:
	if (ret == -EDEADLK) {
		drm_atomic_state_clear(state);
		drm_modeset_backoff(&ctx);
		goto retry;
	}

	drm_atomic_state_put(state);

out:
	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);
	return ret;
}

static const struct amdgpu_display_funcs dm_display_funcs = {
@@ -2563,6 +2603,10 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
		dc_stream_retain(state->stream);
	}

	state->adjust = cur->adjust;
	state->vrr_infopacket = cur->vrr_infopacket;
	state->freesync_enabled = cur->freesync_enabled;

	/* TODO Duplicate dc_stream after objects are stream object is flattened */

	return &state->base;
@@ -2770,13 +2814,15 @@ amdgpu_dm_connector_atomic_duplicate_state(struct drm_connector *connector)
	struct dm_connector_state *new_state =
			kmemdup(state, sizeof(*state), GFP_KERNEL);

	if (new_state) {
		__drm_atomic_helper_connector_duplicate_state(connector,
							      &new_state->base);
		return &new_state->base;
	}

	if (!new_state)
		return NULL;

	__drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);

	new_state->freesync_capable = state->freesync_capable;
	new_state->freesync_enable = state->freesync_enable;

	return &new_state->base;
}

static const struct drm_connector_funcs amdgpu_dm_connector_funcs = {
@@ -3786,8 +3832,6 @@ static void remove_stream(struct amdgpu_device *adev,
			  struct dc_stream_state *stream)
{
	/* this is the update mode case */
	if (adev->dm.freesync_module)
		mod_freesync_remove_stream(adev->dm.freesync_module, stream);

	acrtc->otg_inst = -1;
	acrtc->enabled = false;
@@ -4055,6 +4099,11 @@ static bool commit_planes_to_stream(
	stream_update->dst = dc_stream->dst;
	stream_update->out_transfer_func = dc_stream->out_transfer_func;

	if (dm_new_crtc_state->freesync_enabled != dm_old_crtc_state->freesync_enabled) {
		stream_update->vrr_infopacket = &dc_stream->vrr_infopacket;
		stream_update->adjust = &dc_stream->adjust;
	}

	for (i = 0; i < new_plane_count; i++) {
		updates[i].surface = plane_states[i];
		updates[i].gamma =
@@ -4190,6 +4239,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
			spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
		}

		dc_stream_attach->adjust = acrtc_state->adjust;
		dc_stream_attach->vrr_infopacket = acrtc_state->vrr_infopacket;

		if (false == commit_planes_to_stream(dm->dc,
							plane_states_constructed,
@@ -4339,62 +4390,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
		}
	} /* for_each_crtc_in_state() */

	/*
	 * Add streams after required streams from new and replaced streams
	 * are removed from freesync module
	 */
	if (adev->dm.freesync_module) {
		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
					      new_crtc_state, i) {
			struct amdgpu_dm_connector *aconnector = NULL;
			struct dm_connector_state *dm_new_con_state = NULL;
			struct amdgpu_crtc *acrtc = NULL;
			bool modeset_needed;

			dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
			dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
			modeset_needed = modeset_required(
					new_crtc_state,
					dm_new_crtc_state->stream,
					dm_old_crtc_state->stream);
			/* We add stream to freesync if:
			 * 1. Said stream is not null, and
			 * 2. A modeset is requested. This means that the
			 *    stream was removed previously, and needs to be
			 *    replaced.
			 */
			if (dm_new_crtc_state->stream == NULL ||
					!modeset_needed)
				continue;

			acrtc = to_amdgpu_crtc(crtc);

			aconnector =
				amdgpu_dm_find_first_crtc_matching_connector(
					state, crtc);
			if (!aconnector) {
				DRM_DEBUG_DRIVER("Atomic commit: Failed to "
						 "find connector for acrtc "
						 "id:%d skipping freesync "
						 "init\n",
						 acrtc->crtc_id);
				continue;
			}

			mod_freesync_add_stream(adev->dm.freesync_module,
						dm_new_crtc_state->stream,
						&aconnector->caps);
			new_con_state = drm_atomic_get_new_connector_state(
					state, &aconnector->base);
			dm_new_con_state = to_dm_connector_state(new_con_state);

			mod_freesync_set_user_enable(adev->dm.freesync_module,
						     &dm_new_crtc_state->stream,
						     1,
						     &dm_new_con_state->user_enable);
		}
	}

	if (dm_state->context) {
		dm_enable_per_frame_crtc_master_sync(dm_state->context);
		WARN_ON(!dc_commit_state(dm->dc, dm_state->context));
@@ -4448,6 +4443,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
		WARN_ON(!status);
		WARN_ON(!status->plane_count);

		dm_new_crtc_state->stream->adjust = dm_new_crtc_state->adjust;
		dm_new_crtc_state->stream->vrr_infopacket = dm_new_crtc_state->vrr_infopacket;

		/*TODO How it works with MPO ?*/
		if (!commit_planes_to_stream(
				dm->dc,
@@ -4480,11 +4478,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
		if (dm_new_crtc_state->stream == NULL || !modeset_needed)
			continue;

		if (adev->dm.freesync_module)
			mod_freesync_notify_mode_change(
				adev->dm.freesync_module,
				&dm_new_crtc_state->stream, 1);

		manage_dm_interrupts(adev, acrtc, true);
	}

@@ -4667,7 +4660,42 @@ static int do_aquire_global_lock(struct drm_device *dev,
	return ret < 0 ? ret : 0;
}

static int dm_update_crtcs_state(struct dc *dc,
void set_freesync_on_stream(struct amdgpu_display_manager *dm,
			    struct dm_crtc_state *new_crtc_state,
			    struct dm_connector_state *new_con_state,
			    struct dc_stream_state *new_stream)
{
	struct mod_freesync_config config = {0};
	struct mod_vrr_params vrr = {0};
	struct dc_info_packet vrr_infopacket = {0};
	struct amdgpu_dm_connector *aconnector =
			to_amdgpu_dm_connector(new_con_state->base.connector);

	if (new_con_state->freesync_capable &&
	    new_con_state->freesync_enable) {
		config.state = new_crtc_state->freesync_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;
	}

	mod_freesync_build_vrr_params(dm->freesync_module,
				      new_stream,
				      &config, &vrr);

	mod_freesync_build_vrr_infopacket(dm->freesync_module,
					  new_stream,
					  &vrr,
					  &vrr_infopacket);

	new_crtc_state->adjust = vrr.adjust;
	new_crtc_state->vrr_infopacket = vrr_infopacket;
}

static int dm_update_crtcs_state(struct amdgpu_display_manager *dm,
				 struct drm_atomic_state *state,
				 bool enable,
				 bool *lock_and_validation_needed)
@@ -4737,6 +4765,9 @@ static int dm_update_crtcs_state(struct dc *dc,
				break;
			}

			set_freesync_on_stream(dm, dm_new_crtc_state,
					       dm_new_conn_state, new_stream);

			if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
			    dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
				new_crtc_state->mode_changed = false;
@@ -4745,6 +4776,9 @@ static int dm_update_crtcs_state(struct dc *dc,
			}
		}

		if (dm_old_crtc_state->freesync_enabled != dm_new_crtc_state->freesync_enabled)
			new_crtc_state->mode_changed = true;

		if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
			goto next_crtc;

@@ -4771,7 +4805,7 @@ static int dm_update_crtcs_state(struct dc *dc,

			/* i.e. reset mode */
			if (dc_remove_stream_from_ctx(
					dc,
					dm->dc,
					dm_state->context,
					dm_old_crtc_state->stream) != DC_OK) {
				ret = -EINVAL;
@@ -4808,7 +4842,7 @@ static int dm_update_crtcs_state(struct dc *dc,
							crtc->base.id);

				if (dc_add_stream_to_ctx(
						dc,
						dm->dc,
						dm_state->context,
						dm_new_crtc_state->stream) != DC_OK) {
					ret = -EINVAL;
@@ -4857,6 +4891,8 @@ next_crtc:
				goto fail;
			amdgpu_dm_set_ctm(dm_new_crtc_state);
		}


	}

	return ret;
@@ -5024,8 +5060,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
		goto fail;

	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
		struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
		struct dm_crtc_state *dm_old_crtc_state  = to_dm_crtc_state(old_crtc_state);

		if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
		    !new_crtc_state->color_mgmt_changed)
		    !new_crtc_state->color_mgmt_changed &&
		    (dm_old_crtc_state->freesync_enabled == dm_new_crtc_state->freesync_enabled))
			continue;

		if (!new_crtc_state->enable)
@@ -5051,13 +5091,13 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
	}

	/* Disable all crtcs which require disable */
	ret = dm_update_crtcs_state(dc, state, false, &lock_and_validation_needed);
	ret = dm_update_crtcs_state(&adev->dm, state, false, &lock_and_validation_needed);
	if (ret) {
		goto fail;
	}

	/* Enable all crtcs which require enable */
	ret = dm_update_crtcs_state(dc, state, true, &lock_and_validation_needed);
	ret = dm_update_crtcs_state(&adev->dm, state, true, &lock_and_validation_needed);
	if (ret) {
		goto fail;
	}
@@ -5150,7 +5190,7 @@ static bool is_dp_capable_without_timing_msa(struct dc *dc,

	return capable;
}
void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,
void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
					struct edid *edid)
{
	int i;
@@ -5170,6 +5210,18 @@ void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,
		return;
	}

	if (!edid) {
		dm_con_state = to_dm_connector_state(connector->state);

		amdgpu_dm_connector->min_vfreq = 0;
		amdgpu_dm_connector->max_vfreq = 0;
		amdgpu_dm_connector->pixel_clock_mhz = 0;

		dm_con_state->freesync_capable = false;
		dm_con_state->freesync_enable = false;
		return;
	}

	dm_con_state = to_dm_connector_state(connector->state);

	edid_check_required = false;
@@ -5221,45 +5273,9 @@ void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,

		if (amdgpu_dm_connector->max_vfreq -
		    amdgpu_dm_connector->min_vfreq > 10) {
			amdgpu_dm_connector->caps.supported = true;
			amdgpu_dm_connector->caps.min_refresh_in_micro_hz =
					amdgpu_dm_connector->min_vfreq * 1000000;
			amdgpu_dm_connector->caps.max_refresh_in_micro_hz =
					amdgpu_dm_connector->max_vfreq * 1000000;

			dm_con_state->freesync_capable = true;
		}
	}
}
void amdgpu_dm_remove_sink_from_freesync_module(struct drm_connector *connector)
{
	struct amdgpu_dm_connector *amdgpu_dm_connector =
			to_amdgpu_dm_connector(connector);
	struct dm_connector_state *dm_con_state;
	struct drm_device *dev = connector->dev;
	struct amdgpu_device *adev = dev->dev_private;

	if (!amdgpu_dm_connector->dc_sink || !adev->dm.freesync_module) {
		DRM_ERROR("dc_sink NULL or no free_sync module.\n");
		return;
	}

	if (!connector->state) {
		DRM_ERROR("%s - Connector has no state", __func__);
		return;
	}

	dm_con_state = to_dm_connector_state(connector->state);

	amdgpu_dm_connector->min_vfreq = 0;
	amdgpu_dm_connector->max_vfreq = 0;
	amdgpu_dm_connector->pixel_clock_mhz = 0;

	memset(&amdgpu_dm_connector->caps, 0, sizeof(amdgpu_dm_connector->caps));

	dm_con_state->freesync_capable = false;

	dm_con_state->user_enable.enable_for_gaming = false;
	dm_con_state->user_enable.enable_for_static = false;
	dm_con_state->user_enable.enable_for_video = false;
}
+8 −10
Original line number Diff line number Diff line
@@ -167,9 +167,6 @@ struct amdgpu_dm_connector {
	int max_vfreq ;
	int pixel_clock_mhz;

	/*freesync caps*/
	struct mod_freesync_caps caps;

	struct mutex hpd_lock;

	bool fake_enable;
@@ -197,6 +194,10 @@ struct dm_crtc_state {

	int crc_skip_count;
	bool crc_enabled;

	bool freesync_enabled;
	struct dc_crtc_timing_adjust adjust;
	struct dc_info_packet vrr_infopacket;
};

#define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
@@ -216,7 +217,7 @@ struct dm_connector_state {
	uint8_t underscan_vborder;
	uint8_t underscan_hborder;
	bool underscan_enable;
	struct mod_freesync_user_enable user_enable;
	bool freesync_enable;
	bool freesync_capable;
};

@@ -250,12 +251,9 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec
void dm_restore_drm_connector_state(struct drm_device *dev,
				    struct drm_connector *connector);

void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,
void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
					struct edid *edid);

void
amdgpu_dm_remove_sink_from_freesync_module(struct drm_connector *connector);

/* amdgpu_dm_crc.c */
#ifdef CONFIG_DEBUG_FS
int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name,
+6 −4
Original line number Diff line number Diff line
@@ -234,7 +234,8 @@ void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
	dc_sink->priv = aconnector;
	aconnector->dc_sink = dc_sink;

	amdgpu_dm_add_sink_to_freesync_module(
	if (aconnector->dc_sink)
		amdgpu_dm_update_freesync_caps(
				connector, aconnector->edid);
}

@@ -275,8 +276,9 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
		aconnector->dc_sink = dc_sink;

		if (aconnector->dc_sink)
			amdgpu_dm_add_sink_to_freesync_module(
			amdgpu_dm_update_freesync_caps(
					connector, aconnector->edid);

	}

	drm_connector_update_edid_property(
@@ -439,7 +441,7 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,

	aconnector->port = NULL;
	if (aconnector->dc_sink) {
		amdgpu_dm_remove_sink_from_freesync_module(connector);
		amdgpu_dm_update_freesync_caps(connector, NULL);
		dc_link_remove_remote_sink(aconnector->dc_link, aconnector->dc_sink);
		dc_sink_release(aconnector->dc_sink);
		aconnector->dc_sink = NULL;
+43 −17
Original line number Diff line number Diff line
@@ -188,11 +188,9 @@ failed_alloc:
 *****************************************************************************
 */
bool dc_stream_adjust_vmin_vmax(struct dc *dc,
		struct dc_stream_state **streams, int num_streams,
		int vmin, int vmax)
		struct dc_stream_state *stream,
		struct dc_crtc_timing_adjust *adjust)
{
	/* TODO: Support multiple streams */
	struct dc_stream_state *stream = streams[0];
	int i = 0;
	bool ret = false;

@@ -200,11 +198,11 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
		struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];

		if (pipe->stream == stream && pipe->stream_res.stream_enc) {
			dc->hwss.set_drr(&pipe, 1, vmin, vmax);

			/* build and update the info frame */
			resource_build_info_frame(pipe);
			dc->hwss.update_info_frame(pipe);
			pipe->stream->adjust = *adjust;
			dc->hwss.set_drr(&pipe,
					1,
					adjust->v_total_min,
					adjust->v_total_max);

			ret = true;
		}
@@ -217,7 +215,7 @@ bool dc_stream_get_crtc_position(struct dc *dc,
		unsigned int *v_pos, unsigned int *nom_v_pos)
{
	/* TODO: Support multiple streams */
	struct dc_stream_state *stream = streams[0];
	const struct dc_stream_state *stream = streams[0];
	int i = 0;
	bool ret = false;
	struct crtc_position position;
@@ -1257,9 +1255,26 @@ static enum surface_update_type check_update_surfaces_for_stream(
	if (stream_status == NULL || stream_status->plane_count != surface_count)
		return UPDATE_TYPE_FULL;

	if (stream_update)
	/* some stream updates require passive update */
	if (stream_update) {
		if ((stream_update->src.height != 0) &&
				(stream_update->src.width != 0))
			return UPDATE_TYPE_FULL;

		if ((stream_update->dst.height != 0) &&
				(stream_update->dst.width != 0))
			return UPDATE_TYPE_FULL;

		if (stream_update->out_transfer_func)
			return UPDATE_TYPE_FULL;

		if (stream_update->hdr_static_metadata)
			return UPDATE_TYPE_FULL;

		if (stream_update->abm_level)
			return UPDATE_TYPE_FULL;
	}

	for (i = 0 ; i < surface_count; i++) {
		enum surface_update_type type =
				det_surface_update(dc, &updates[i]);
@@ -1337,7 +1352,6 @@ static void commit_planes_for_stream(struct dc *dc,
		return;
	}

	/* Full fe update*/
	for (j = 0; j < dc->res_pool->pipe_count; j++) {
		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];

@@ -1348,7 +1362,18 @@ static void commit_planes_for_stream(struct dc *dc,

			top_pipe_to_program = pipe_ctx;

			if (update_type == UPDATE_TYPE_FAST || !pipe_ctx->plane_state)
			if (!pipe_ctx->plane_state)
				continue;

			/* Fast update*/
			// VRR program can be done as part of FAST UPDATE
			if (stream_update && stream_update->adjust)
				dc->hwss.set_drr(&pipe_ctx, 1,
					stream_update->adjust->v_total_min,
					stream_update->adjust->v_total_max);

			/* Full fe update*/
			if (update_type == UPDATE_TYPE_FAST)
				continue;

			stream_status =
@@ -1407,7 +1432,7 @@ static void commit_planes_for_stream(struct dc *dc,
		dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
	}

	if (stream && stream_update && update_type > UPDATE_TYPE_FAST)
	if (stream && stream_update)
		for (j = 0; j < dc->res_pool->pipe_count; j++) {
			struct pipe_ctx *pipe_ctx =
					&context->res_ctx.pipe_ctx[j];
@@ -1415,7 +1440,8 @@ static void commit_planes_for_stream(struct dc *dc,
			if (pipe_ctx->stream != stream)
				continue;

			if (stream_update->hdr_static_metadata) {
			if (stream_update->hdr_static_metadata ||
				(stream_update->vrr_infopacket)) {
				resource_build_info_frame(pipe_ctx);
				dc->hwss.update_info_frame(pipe_ctx);
			}
+3 −0
Original line number Diff line number Diff line
@@ -2389,6 +2389,9 @@ static bool retrieve_link_cap(struct dc_link *link)

	dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data));

	down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
				 DP_DPCD_REV];

	link->dpcd_caps.allow_invalid_MSA_timing_param =
		down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;

Loading