From: Mikita Lipski <mikita.lipski@xxxxxxx> [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 Signed-off-by: Mikita Lipski <mikita.lipski@xxxxxxx> --- drivers/gpu/drm/drm_dp_mst_topology.c | 90 +++++++++++++++++++++++++++ include/drm/drm_dp_mst_helper.h | 2 + 2 files changed, 92 insertions(+) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 5072c1e3dcfe..4d9089fe84c1 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -73,6 +73,7 @@ static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr, static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux); static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux); static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr); +static bool drm_dp_mst_is_dsc_supported(struct drm_dp_mst_port *port); #define DP_STR(x) [DP_ ## x] = #x @@ -3936,6 +3937,66 @@ drm_dp_mst_atomic_check_topology_state(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: Pointer tothe port 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_port *port) +{ + 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; + + if (!port) + return -EINVAL; + + mst_state = drm_atomic_get_mst_topology_state(state, port->mgr); + + 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 (!crtc) + return -EINVAL; + + if (!drm_dp_mst_is_dsc_supported(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 PORT:%p] Setting mode_changed flag on CRTC %p\n", port, 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 @@ -4433,3 +4494,32 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) return NULL; } EXPORT_SYMBOL(drm_dp_mst_dsc_aux_for_port); + +/** + * drm_dp_mst_is_dsc_supported() - Verify DSC support on connector + * @port: The port to check. A leaf of the MST tree with an attached display. + * + * Acquiring correct aux from drm_dp_mst_dsc_aux_for_port + * and verifying DPCD flag that the aux is DSC capable + * + * Returns: + * True / False - if DSC is supported + */ +static bool drm_dp_mst_is_dsc_supported(struct drm_dp_mst_port *port) +{ + struct drm_dp_aux *dsc_aux; + u8 endpoint_dsc; + + dsc_aux = drm_dp_mst_dsc_aux_for_port(port); + + if (!dsc_aux) + return false; + + if (drm_dp_dpcd_read(&port->aux, DP_DSC_SUPPORT, &endpoint_dsc, 1) < 0) + return false; + + if (endpoint_dsc & DP_DSC_DECOMPRESSION_IS_SUPPORTED) + return true; + + return false; +} diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 5a119a40ed5a..7d1e5e42c9ac 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -669,6 +669,8 @@ int drm_dp_mst_atomic_enable_dsc(struct drm_atomic_state *state, struct drm_dp_mst_port *port, int pbn, int pbn_div, bool enable); +int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, + struct drm_dp_mst_port *port); int __must_check drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, -- 2.17.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel