[PATCH] drm/amd/display: Handle removed connector in early_unregister

Harry Wentland harry.wentland at amd.com
Thu Feb 3 16:43:30 UTC 2022



On 2022-02-02 13:49, Fangzhi Zuo wrote:
> From: Wayne Lin <Wayne.Lin at amd.com>
> 
> [Why]
> commit "drm/amd/display: turn DPMS off on connector unplug" and
> commit "drm/amd/display: Clear dc remote sinks on MST disconnect"
> were trying to resolve the resource problem when we connectors get
> disconnected under MST scenarios. However, these patches don't
> really clean up all remote sinks. Nor turns DPMS off on all affected
> streams. Also, these can't handle disconnected connectors reported by CSN.
> 
> [How]
> - Revise commit "drm/amd/display: turn DPMS off on connector unplug"
> a bit to handle none mst case only.
> - Revert commit "drm/amd/display: Clear dc remote sinks on MST disconnect"

I don't see this revert as part of this commit.

Generally, if we revert code it should be done in a single revert commit
that is generated via "git revert".

Harry

> - Revise a bit the logic in above patches and change to turn DPMS
> off/clear dc remote sink within amdgpu_dm_mst_connector_early_unregister().
> Since drm will call .early_unregister for all disconnected connectors,
> we can ensure to also handle disconnected connectors reported by CSN.
> 
> Signed-off-by: Wayne Lin <Wayne.Lin at amd.com>
> Signed-off-by: Fangzhi Zuo <Jerry.Zuo at amd.com>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  7 ++++
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 41 +++++++++++++++++--
>  .../gpu/drm/amd/display/dc/core/dc_stream.c   | 12 ++++++
>  drivers/gpu/drm/amd/display/dc/dc_stream.h    |  1 +
>  4 files changed, 58 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index f5941e59e5ad..529b3ddaa10b 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3034,6 +3034,7 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector)
>  	struct drm_connector *connector = &aconnector->base;
>  	struct drm_device *dev = connector->dev;
>  	enum dc_connection_type new_connection_type = dc_connection_none;
> +	enum dc_connection_type old_connection_type = aconnector->dc_link->type;
>  	struct amdgpu_device *adev = drm_to_adev(dev);
>  	struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state);
>  	struct dm_crtc_state *dm_crtc_state = NULL;
> @@ -3074,7 +3075,13 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector)
>  			drm_kms_helper_hotplug_event(dev);
>  
>  	} else if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) {
> +		/**
> +		 * MST cases are handled within .early_unregister where we
> +		 * can handle disconnected conectors reported by long HPD
> +		 * and CSN.
> +		 */
>  		if (new_connection_type == dc_connection_none &&
> +			old_connection_type != dc_connection_mst_branch &&
>  		    aconnector->dc_link->type == dc_connection_none &&
>  		    dm_crtc_state)
>  			dm_set_dpms_off(aconnector->dc_link, dm_crtc_state);
> 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..411b55596b00 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
> @@ -139,11 +139,46 @@ amdgpu_dm_mst_connector_late_register(struct drm_connector *connector)
>  static void
>  amdgpu_dm_mst_connector_early_unregister(struct drm_connector *connector)
>  {
> -	struct amdgpu_dm_connector *amdgpu_dm_connector =
> -		to_amdgpu_dm_connector(connector);
> -	struct drm_dp_mst_port *port = amdgpu_dm_connector->port;
> +	struct amdgpu_dm_connector *aconnector =
> +                to_amdgpu_dm_connector(connector);
> +	struct drm_dp_mst_port *port = aconnector->port;
> +	struct dc_stream_update stream_update;
> +	struct dc_stream_state *stream_state;
> +	struct drm_device *ddev = aconnector->base.dev;
> +	struct amdgpu_device *adev = drm_to_adev(ddev);
> +	struct dc_link *dc_link = aconnector->dc_link;
> +	struct dc_sink *dc_sink = aconnector->dc_sink;
> +	bool dpms_off = true;
>  
>  	drm_dp_mst_connector_early_unregister(connector, port);
> +
> +	ASSERT(dc_link);
> +
> +	if (dc_sink) {
> +			mutex_lock(&ddev->mode_config.mutex);
> +			mutex_lock(&adev->dm.dc_lock);
> +
> +			memset(&stream_update, 0, sizeof(stream_update));
> +			stream_update.dpms_off = &dpms_off;
> +
> +			/*set stream dpms_off*/
> +			stream_state = dc_stream_get_stream_by_sink(dc_sink);
> +			if (stream_state != NULL) {
> +					stream_update.stream = stream_state;
> +					dc_commit_updates_for_stream(stream_state->ctx->dc, NULL, 0,
> +											stream_state, &stream_update,
> +											stream_state->ctx->dc->current_state);
> +			}
> +
> +			/*clear the remote sink of the link*/
> +			dc_link_remove_remote_sink(dc_link, dc_sink);
> +			dc_sink_release(dc_sink);
> +			aconnector->dc_sink = NULL;
> +
> +			mutex_unlock(&adev->dm.dc_lock);
> +			mutex_unlock(&ddev->mode_config.mutex);
> +	}
> +
>  }
>  
>  static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
> index 57cf4cb82370..a77c90c14e85 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
> @@ -739,3 +739,15 @@ void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream)
>  			stream->link->link_index);
>  }
>  
> +struct dc_stream_state *dc_stream_get_stream_by_sink(struct dc_sink *sink)
> +{
> +	uint8_t i;
> +	struct dc_context *ctx = sink->ctx;
> +
> +	for (i = 0; i < ctx->dc->current_state->stream_count; i++) {
> +		if (ctx->dc->current_state->streams[i]->sink == sink)
> +			return ctx->dc->current_state->streams[i];
> +	}
> +
> +	return NULL;
> +}
> \ No newline at end of file
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> index f631b61abedd..89f67c711161 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> @@ -321,6 +321,7 @@ void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream);
>  uint8_t dc_get_current_stream_count(struct dc *dc);
>  struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i);
>  struct dc_stream_state *dc_stream_find_from_link(const struct dc_link *link);
> +struct dc_stream_state *dc_stream_get_stream_by_sink(struct dc_sink *sink);
>  
>  /*
>   * Return the current frame counter.



More information about the amd-gfx mailing list