Commit ffdaeb1f authored by Paul Hsieh's avatar Paul Hsieh Committed by Alex Deucher
Browse files

drm/amd/display: reallocate MST payload when link loss



[Why]
Try to allocate MST payload but receive HPD short pulse with link loss
casue driver allocate payload twice. It cause monitor can't light up
successfully.

[How]
When driver receive HPD short pulse with link loss, we need to
deallocate payload then allocate payload.
Then we will not allocate payload twice with same sink.

Signed-off-by: default avatarPaul Hsieh <paul.hsieh@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 34ad0230
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -2873,6 +2873,39 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)

	return DC_OK;
}

enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link)
{
	int i;
	struct pipe_ctx *pipe_ctx;

	// Clear all of MST payload then reallocate
	for (i = 0; i < MAX_PIPES; i++) {
		pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
		if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link &&
				pipe_ctx->stream->dpms_off == false &&
				pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
			deallocate_mst_payload(pipe_ctx);
		}
	}

	for (i = 0; i < MAX_PIPES; i++) {
		pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
		if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link &&
				pipe_ctx->stream->dpms_off == false &&
				pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
			/* enable/disable PHY will clear connection between BE and FE
			 * need to restore it.
			 */
			link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
									pipe_ctx->stream_res.stream_enc->id, true);
			dc_link_allocate_mst_payload(pipe_ctx);
		}
	}

	return DC_OK;
}

#if defined(CONFIG_DRM_AMD_DC_HDCP)
static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
{
+2 −5
Original line number Diff line number Diff line
@@ -2901,11 +2901,8 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
			pipe_ctx,
			pipe_ctx->stream->signal);

		if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link &&
				pipe_ctx->stream->dpms_off == false &&
				pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
			dc_link_allocate_mst_payload(pipe_ctx);
		}
		if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
			dc_link_reallocate_mst_payload(link);

		status = false;
		if (out_link_loss)
+1 −0
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ enum dc_detect_reason {
bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
bool dc_link_get_hpd_state(struct dc_link *dc_link);
enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link);

/* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
 * Return: