From: Mikita Lipski <mikita.lipski@xxxxxxx> Adding the following elements to add MST DSC support to DRM: - dsc_enable boolean flag to drm_dp_vcpi_allocation structure to signal, which port got DSC enabled - function drm_dp_helper_update_vcpi_slots_for_dsc allows reallocation of newly recalculated VCPI slots and raises dsc_enable flag on the port. - function drm_dp_mst_update_dsc_crtcs is called in drm_dp_mst_atomic_check, its purpose is to iterate through all the ports in the topology and set mode_changed flag on crtc if DSC has been enabled. Cc: Harry Wentland <harry.wentland@xxxxxxx> Cc: Lyude Paul <lyude@xxxxxxxxxx> Signed-off-by: Mikita Lipski <mikita.lipski@xxxxxxx> --- drivers/gpu/drm/drm_dp_mst_topology.c | 103 +++++++++++++++++++++++++- include/drm/drm_dp_mst_helper.h | 4 + 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index d5df02315e14..4f2f09fe32f8 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 void drm_dp_mst_update_dsc_crtcs(struct drm_dp_mst_topology_state *mst_state); #define DP_STR(x) [DP_ ## x] = #x @@ -3293,6 +3294,65 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots); +/** + * drm_dp_helper_update_vcpi_slots_for_dsc() - Update VCPI slots with new on the state + * + * @state: global atomic state + * @port: port to find vcpi slots + * @pbn: updated bandwidth required for the mode in PBN + * + * Function reallocates VCPI slots to the @port by calling + * drm_dp_atomic_find_vcpi_slots. The assumption is that VCPI slots + * have already been allocated and this is second call overwritting + * initial values. After the VCPI is allocated dsc_enable flag is set to + * true for atomic check. + * + * It is driver's responsibility to call this function after it decides + * to enable DSC. + * + * See also: + * drm_dp_mst_update_dsc_crtcs() + * + * Returns: + * Total slots in the atomic state assigned for this port, or a negative error + * code if the port no longer exists or vcpi slots haven't been assigned. + */ +int drm_dp_helper_update_vcpi_slots_for_dsc(struct drm_atomic_state *state, + struct drm_dp_mst_port *port, + int pbn) +{ + struct drm_dp_mst_topology_state *topology_state; + struct drm_dp_vcpi_allocation *pos; + bool found = false; + int vcpi = 0; + + topology_state = drm_atomic_get_mst_topology_state(state, port->mgr); + + if (IS_ERR(topology_state)) + return PTR_ERR(topology_state); + + list_for_each_entry(pos, &topology_state->vcpis, next) { + if (pos->port == port) { + found = true; + break; + } + } + + if (!found || !pos->vcpi) + return -EINVAL; + + vcpi = drm_dp_atomic_find_vcpi_slots(state, port->mgr, + port, pbn); + + if (vcpi < 0) + return -EINVAL; + + pos->dsc_enable = true; + + return vcpi; +} + +EXPORT_SYMBOL(drm_dp_helper_update_vcpi_slots_for_dsc); /** * drm_dp_atomic_release_vcpi_slots() - Release allocated vcpi slots * @state: global atomic state @@ -3871,6 +3931,46 @@ drm_dp_mst_atomic_check_topology_state(struct drm_dp_mst_topology_mgr *mgr, return 0; } +/** + * drm_dp_mst_update_dsc_crtcs - Set mode change flag on CRTCs which + * just got DSC enabled + * @state: Pointer to the new &struct drm_dp_mst_topology_state + * + * Itearate through all the ports in MST topology to check if DSC + * has been enabled on any of them. Set mode_changed to true on + * crtc state that just got DSC enabled. + * + * See also: + * drm_dp_helper_update_vcpi_slots_for_dsc() + */ +static void +drm_dp_mst_update_dsc_crtcs(struct drm_dp_mst_topology_state *mst_state) +{ + struct drm_dp_vcpi_allocation *pos; + struct drm_dp_mst_port *port; + struct drm_connector_state *conn_state; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + + list_for_each_entry(pos, &mst_state->vcpis, next) { + + port = pos->port; + conn_state = drm_atomic_get_connector_state(mst_state->base.state, + port->connector); + crtc = conn_state->crtc; + if (!crtc) + continue; + + crtc_state = drm_atomic_get_crtc_state(mst_state->base.state, crtc); + if (port->vcpi.vcpi == pos->vcpi) + continue; + + if (pos->dsc_enable) { + crtc_state->mode_changed = true; + pos->dsc_enable = false; + } + } +} /** * drm_dp_mst_atomic_check - Check that the new state of an MST topology in an * atomic update is valid @@ -3887,9 +3987,9 @@ drm_dp_mst_atomic_check_topology_state(struct drm_dp_mst_topology_mgr *mgr, * See also: * drm_dp_atomic_find_vcpi_slots() * drm_dp_atomic_release_vcpi_slots() - * * Returns: * + * * 0 if the new state is valid, negative error code otherwise. */ int drm_dp_mst_atomic_check(struct drm_atomic_state *state) @@ -3902,6 +4002,7 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state *state) ret = drm_dp_mst_atomic_check_topology_state(mgr, mst_state); if (ret) break; + drm_dp_mst_update_dsc_crtcs(mst_state); } return ret; diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 4cf738545dfb..185e29895f5f 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -431,6 +431,7 @@ struct drm_dp_payload { struct drm_dp_vcpi_allocation { struct drm_dp_mst_port *port; int vcpi; + bool dsc_enable; struct list_head next; }; @@ -662,6 +663,9 @@ int __must_check drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn); +int drm_dp_helper_update_vcpi_slots_for_dsc(struct drm_atomic_state *state, + struct drm_dp_mst_port *port, + int pbn); int __must_check drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr, -- 2.17.1 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx