Commit 29b9ba74 authored by Mikita Lipski's avatar Mikita Lipski Committed by Alex Deucher
Browse files

drm/amd/display: Recalculate VCPI slots for new DSC connectors



[why]
Since for DSC MST connector's PBN is claculated differently
due to compression, we have to recalculate both PBN and
VCPI slots for that connector.

[how]
The function iterates through all the active streams to
find, which have DSC enabled, then recalculates PBN for
it and calls drm_dp_helper_update_vcpi_slots_for_dsc to
update connector's VCPI slots.

v2: - use drm_dp_mst_atomic_enable_dsc per port to
enable/disable DSC

v3: - Iterate through connector states from the state passed
    - On each connector state get stream from dc_state,
instead CRTC state

Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
Signed-off-by: default avatarMikita Lipski <mikita.lipski@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 34d95c3d
Loading
Loading
Loading
Loading
+71 −5
Original line number Diff line number Diff line
@@ -4952,6 +4952,69 @@ const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs = {
	.atomic_check = dm_encoder_helper_atomic_check
};

static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
					    struct dc_state *dc_state)
{
	struct dc_stream_state *stream = NULL;
	struct drm_connector *connector;
	struct drm_connector_state *new_con_state, *old_con_state;
	struct amdgpu_dm_connector *aconnector;
	struct dm_connector_state *dm_conn_state;
	int i, j, clock, bpp;
	int vcpi, pbn_div, pbn = 0;

	for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {

		aconnector = to_amdgpu_dm_connector(connector);

		if (!aconnector->port)
			continue;

		if (!new_con_state || !new_con_state->crtc)
			continue;

		dm_conn_state = to_dm_connector_state(new_con_state);

		for (j = 0; j < dc_state->stream_count; j++) {
			stream = dc_state->streams[j];
			if (!stream)
				continue;

			if ((struct amdgpu_dm_connector*)stream->dm_stream_context == aconnector)
				break;

			stream = NULL;
		}

		if (!stream)
			continue;

		if (stream->timing.flags.DSC != 1) {
			drm_dp_mst_atomic_enable_dsc(state,
						     aconnector->port,
						     dm_conn_state->pbn,
						     0,
						     false);
			continue;
		}

		pbn_div = dm_mst_get_pbn_divider(stream->link);
		bpp = stream->timing.dsc_cfg.bits_per_pixel;
		clock = stream->timing.pix_clk_100hz / 10;
		pbn = drm_dp_calc_pbn_mode(clock, bpp, true);
		vcpi = drm_dp_mst_atomic_enable_dsc(state,
						    aconnector->port,
						    pbn, pbn_div,
						    true);
		if (vcpi < 0)
			return vcpi;

		dm_conn_state->pbn = pbn;
		dm_conn_state->vcpi_slots = vcpi;
	}
	return 0;
}

static void dm_drm_plane_reset(struct drm_plane *plane)
{
	struct dm_plane_state *amdgpu_state = NULL;
@@ -7985,11 +8048,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
	if (ret)
		goto fail;

	/* Perform validation of MST topology in the state*/
	ret = drm_dp_mst_atomic_check(state);
	if (ret)
		goto fail;

	if (state->legacy_cursor_update) {
		/*
		 * This is a fast cursor update coming from the plane update
@@ -8061,6 +8119,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
		if (!compute_mst_dsc_configs_for_state(state, dm_state->context))
			goto fail;

		ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context);
		if (ret)
			goto fail;

		if (dc_validate_global_state(dc, dm_state->context, false) != DC_OK) {
			ret = -EINVAL;
			goto fail;
@@ -8089,6 +8151,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
				dc_retain_state(old_dm_state->context);
		}
	}
	/* Perform validation of MST topology in the state*/
	ret = drm_dp_mst_atomic_check(state);
	if (ret)
		goto fail;

	/* Store the overall update type for use later in atomic check. */
	for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {