Commit e5309d7f authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher

drm/amd/display: add DP sanity checks during enable stream

[why]
1. When HPD deassertion is pulled in the middle of
enabe stream link training, we will abort current training
and turn off PHY. This causes current link settings
to be zeroed this causes later stream enablement
sequence to fail as we prefer to carry on enablement
process despite of link training failure for SST.
2. When HPD is toggled after detection before before
the enable stream sequence as a result. There could be
a race condition where we could end up enable stream based
on the previous link even though the link is updated
after the HPD toggle. This causes an issue where our link
bandwidth is no longer enough to accommodate the timing
therefore causes us to oversubscribe MST payload time
slots. As discussed we decided to add basic sanity check
to make sure that our code can handle the oversubscription
failure silently without system hang.

[how]
1. Keep PHY powered on when HPD is deasserted during
enable stream and wait for the detection sequence to power
it off later.
2. Do not allocate payload if the required timeslot for
current timing is greater than 64 timeslots.
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Reviewed-by: default avatarGeorge Shen <George.Shen@amd.com>
Acked-by: default avatarHamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 0c56705d
......@@ -422,6 +422,8 @@ char *dc_status_to_str(enum dc_status status)
return "The value specified is not supported.";
case DC_NO_LINK_ENC_RESOURCE:
return "No link encoder resource";
case DC_FAIL_DP_PAYLOAD_ALLOCATION:
return "Fail dp payload allocation";
case DC_ERROR_UNEXPECTED:
return "Unexpected error";
}
......
......@@ -3597,6 +3597,7 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx,
"allocation table for "
"pipe idx: %d\n",
pipe_ctx->pipe_idx);
return DC_FAIL_DP_PAYLOAD_ALLOCATION;
}
proposed_table.stream_allocations[0].hpo_dp_stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc;
......
......@@ -2875,10 +2875,13 @@ bool perform_link_training_with_retries(
fail_count++;
dp_trace_lt_fail_count_update(link, fail_count, false);
/* latest link training still fail, skip delay and keep PHY on
*/
if (j == (attempts - 1) && link->ep_type == DISPLAY_ENDPOINT_PHY)
break;
if (link->ep_type == DISPLAY_ENDPOINT_PHY) {
/* latest link training still fail or link training is aborted
* skip delay and keep PHY on
*/
if (j == (attempts - 1) || (status == LINK_TRAINING_ABORT))
break;
}
DC_LOG_WARNING("%s: Link training attempt %u of %d failed @ rate(%d) x lane(%d)\n",
__func__, (unsigned int)j + 1, attempts, cur_link_settings.link_rate,
......@@ -6890,6 +6893,10 @@ bool dpcd_write_128b_132b_sst_payload_allocation_table(
if (allocate) {
avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, link);
req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
/// Validation should filter out modes that exceed link BW
ASSERT(req_slot_count <= MAX_MTP_SLOT_COUNT);
if (req_slot_count > MAX_MTP_SLOT_COUNT)
return false;
} else {
/// Leave req_slot_count = 0 if allocate is false.
}
......@@ -6917,7 +6924,6 @@ bool dpcd_write_128b_132b_sst_payload_allocation_table(
&start_time_slot,
1);
ASSERT(req_slot_count <= MAX_MTP_SLOT_COUNT); /// Validation should filter out modes that exceed link BW
core_link_write_dpcd(
link,
DP_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT,
......
......@@ -54,7 +54,7 @@ enum dc_status {
DC_UNSUPPORTED_VALUE = 25,
DC_NO_LINK_ENC_RESOURCE = 26,
DC_FAIL_DP_PAYLOAD_ALLOCATION = 27,
DC_ERROR_UNEXPECTED = -1
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment