From: Hersen Wu <hersenwu@xxxxxxx> [why] when unplug 1 dp from dsc mst hub, atomic_check new request dc_state only include info for the unplug dp. this will not trigger re-compute pbn for displays still connected to hub. [how] all displays connected to dsc hub are available in dc->current_state, by comparing dc->current_state and new request from atomic_chceck, it will provide info of displays connected to hub and do pbn re-compute. Reviewed-by: Roman Li <Roman.Li@xxxxxxx> Acked-by: Jasdeep Dhillon <jdhillon@xxxxxxx> Signed-off-by: Hersen Wu <hersenwu@xxxxxxx> --- .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 53 ++++++++++++++++--- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 8e97d21bdf5c..914d59821c03 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -911,22 +911,31 @@ static bool is_dsc_need_re_compute( struct dc_state *dc_state, struct dc_link *dc_link) { - int i; + int i, j; bool is_dsc_need_re_compute = false; + struct amdgpu_dm_connector *stream_on_link[MAX_PIPES]; + int new_stream_on_link_num = 0; + struct amdgpu_dm_connector *aconnector; + struct dc_stream_state *stream; + const struct dc *dc = dc_link->dc; - /* only check phy used by mst branch */ + /* only check phy used by dsc mst branch */ if (dc_link->type != dc_connection_mst_branch) return false; + if (!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT || + dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT)) + return false; + + for (i = 0; i < MAX_PIPES; i++) + stream_on_link[i] = NULL; + /* check if there is mode change in new request */ for (i = 0; i < dc_state->stream_count; i++) { - struct amdgpu_dm_connector *aconnector; - struct dc_stream_state *stream; struct drm_crtc_state *new_crtc_state; struct drm_connector_state *new_conn_state; stream = dc_state->streams[i]; - if (!stream) continue; @@ -938,8 +947,10 @@ static bool is_dsc_need_re_compute( if (!aconnector) continue; - new_conn_state = drm_atomic_get_new_connector_state(state, &aconnector->base); + stream_on_link[new_stream_on_link_num] = aconnector; + new_stream_on_link_num++; + new_conn_state = drm_atomic_get_new_connector_state(state, &aconnector->base); if (!new_conn_state) continue; @@ -950,7 +961,6 @@ static bool is_dsc_need_re_compute( continue; new_crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc); - if (!new_crtc_state) continue; @@ -960,7 +970,34 @@ static bool is_dsc_need_re_compute( if (new_crtc_state->enable && new_crtc_state->active) { if (new_crtc_state->mode_changed || new_crtc_state->active_changed || new_crtc_state->connectors_changed) - is_dsc_need_re_compute = true; + return true; + } + } + + /* check current_state if there stream on link but it is not in + * new request state + */ + for (i = 0; i < dc->current_state->stream_count; i++) { + stream = dc->current_state->streams[i]; + /* only check stream on the mst hub */ + if (stream->link != dc_link) + continue; + + aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; + if (!aconnector) + continue; + + for (j = 0; j < new_stream_on_link_num; j++) { + if (stream_on_link[j]) { + if (aconnector == stream_on_link[j]) + break; + } + } + + if (j == new_stream_on_link_num) { + /* not in new state */ + is_dsc_need_re_compute = true; + break; } } -- 2.25.1