Commit 8ec04671 authored by Mikita Lipski's avatar Mikita Lipski Committed by Alex Deucher
Browse files

drm/dp_mst: Add helper to trigger modeset on affected DSC MST CRTCs



[why]
Whenever a connector on an MST network is changed or
undergoes a modeset, the DSC configs for each stream on that
topology will be recalculated. This can change their required
bandwidth, requiring a full reprogramming, as though a modeset
was performed, even if that stream did not change timing.

[how]
Adding helper to trigger modesets on MST DSC connectors
by setting mode_changed flag on CRTCs in the same topology
as affected connector

v2: use drm_dp_mst_dsc_aux_for_port function to verify
if the port is DSC capable

v3: - added _must_check attribute
    - removed topology manager check
    - fix typos and indentations

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 29b9ba74
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
@@ -4848,6 +4848,67 @@ drm_dp_mst_atomic_check_vcpi_alloc_limit(struct drm_dp_mst_topology_mgr *mgr,
	return 0;
}

/**
 * drm_dp_mst_add_affected_dsc_crtcs
 * @state: Pointer to the new struct drm_dp_mst_topology_state
 * @port: Port pointer of connector with new state
 *
 * Whenever there is a change in mst topology
 * DSC configuration would have to be recalculated
 * therefore we need to trigger modeset on all affected
 * CRTCs in that topology
 *
 * See also:
 * drm_dp_mst_atomic_enable_dsc()
 */
int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr)
{
	struct drm_dp_mst_topology_state *mst_state;
	struct drm_dp_vcpi_allocation *pos;
	struct drm_connector *connector;
	struct drm_connector_state *conn_state;
	struct drm_crtc *crtc;
	struct drm_crtc_state *crtc_state;

	mst_state = drm_atomic_get_mst_topology_state(state, mgr);

	if (IS_ERR(mst_state))
		return -EINVAL;

	list_for_each_entry(pos, &mst_state->vcpis, next) {

		connector = pos->port->connector;

		if (!connector)
			return -EINVAL;

		conn_state = drm_atomic_get_connector_state(state, connector);

		if (IS_ERR(conn_state))
			return PTR_ERR(conn_state);

		crtc = conn_state->crtc;

		if (WARN_ON(!crtc))
			return -EINVAL;

		if (!drm_dp_mst_dsc_aux_for_port(pos->port))
			continue;

		crtc_state = drm_atomic_get_crtc_state(mst_state->base.state, crtc);

		if (IS_ERR(crtc_state))
			return PTR_ERR(crtc_state);

		DRM_DEBUG_ATOMIC("[MST MGR:%p] Setting mode_changed flag on CRTC %p\n",
				 mgr, crtc);

		crtc_state->mode_changed = true;
	}
	return 0;
}
EXPORT_SYMBOL(drm_dp_mst_add_affected_dsc_crtcs);

/**
 * drm_dp_mst_atomic_enable_dsc - Set DSC Enable Flag to On/Off
 * @state: Pointer to the new drm_atomic_state
+3 −0
Original line number Diff line number Diff line
@@ -788,6 +788,9 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state,
				 int pbn, int pbn_div,
				 bool enable);
int __must_check
drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state,
				  struct drm_dp_mst_topology_mgr *mgr);
int __must_check
drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
				 struct drm_dp_mst_topology_mgr *mgr,
				 struct drm_dp_mst_port *port);