Commit d715c9a2 authored by Martin Tsai's avatar Martin Tsai Committed by Alex Deucher

drm/amd/display: add protection in link encoder matching logic

[Why]
Link encoders are created based on its engine ID. The position of a link
encoder in an array could be null since it didn't be allocated.  Current
matching logic didn't consider this situation and could get null
encoder.

[How]
To add null encoder check to make the matching logic can go to next to
get a valid one.
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarMartin Tsai <martin.tsai@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 09ece5ac
...@@ -8366,7 +8366,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, ...@@ -8366,7 +8366,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
break; break;
case DRM_MODE_CONNECTOR_DisplayPort: case DRM_MODE_CONNECTOR_DisplayPort:
aconnector->base.polled = DRM_CONNECTOR_POLL_HPD; aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
link->link_enc = dp_get_link_enc(link); link->link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link->link_enc); ASSERT(link->link_enc);
if (link->link_enc) if (link->link_enc)
aconnector->base.ycbcr_420_allowed = aconnector->base.ycbcr_420_allowed =
......
...@@ -4621,16 +4621,7 @@ bool dc_link_is_fec_supported(const struct dc_link *link) ...@@ -4621,16 +4621,7 @@ bool dc_link_is_fec_supported(const struct dc_link *link)
*/ */
struct link_encoder *link_enc = NULL; struct link_encoder *link_enc = NULL;
/* Links supporting dynamically assigned link encoder will be assigned next link_enc = link_enc_cfg_get_link_enc(link);
* available encoder if one not already assigned.
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign) {
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
if (link_enc == NULL)
link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
} else
link_enc = link->link_enc;
ASSERT(link_enc); ASSERT(link_enc);
return (dc_is_dp_signal(link->connector_signal) && link_enc && return (dc_is_dp_signal(link->connector_signal) && link_enc &&
......
...@@ -261,14 +261,7 @@ static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *li ...@@ -261,14 +261,7 @@ static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *li
struct dpcd_caps *rx_caps = &link->dpcd_caps; struct dpcd_caps *rx_caps = &link->dpcd_caps;
enum dc_dp_training_pattern pattern = DP_TRAINING_PATTERN_SEQUENCE_2; enum dc_dp_training_pattern pattern = DP_TRAINING_PATTERN_SEQUENCE_2;
/* Access link encoder capability based on whether it is statically link_enc = link_enc_cfg_get_link_enc(link);
* or dynamically assigned to a link.
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign)
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
else
link_enc = link->link_enc;
ASSERT(link_enc); ASSERT(link_enc);
enc_caps = &link_enc->features; enc_caps = &link_enc->features;
...@@ -2997,16 +2990,7 @@ bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_ ...@@ -2997,16 +2990,7 @@ bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_
return false; return false;
} }
/* Links supporting dynamically assigned link encoder will be assigned next link_enc = link_enc_cfg_get_link_enc(link);
* available encoder if one not already assigned.
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign) {
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
if (link_enc == NULL)
link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
} else
link_enc = link->link_enc;
ASSERT(link_enc); ASSERT(link_enc);
if (link_enc && link_enc->funcs->get_max_link_cap) { if (link_enc && link_enc->funcs->get_max_link_cap) {
...@@ -3027,16 +3011,7 @@ struct dc_link_settings dp_get_max_link_cap(struct dc_link *link) ...@@ -3027,16 +3011,7 @@ struct dc_link_settings dp_get_max_link_cap(struct dc_link *link)
enum dc_link_rate lttpr_max_link_rate; enum dc_link_rate lttpr_max_link_rate;
struct link_encoder *link_enc = NULL; struct link_encoder *link_enc = NULL;
/* Links supporting dynamically assigned link encoder will be assigned next link_enc = link_enc_cfg_get_link_enc(link);
* available encoder if one not already assigned.
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign) {
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
if (link_enc == NULL)
link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc);
} else
link_enc = link->link_enc;
ASSERT(link_enc); ASSERT(link_enc);
/* get max link encoder capability */ /* get max link encoder capability */
...@@ -6175,14 +6150,7 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource ...@@ -6175,14 +6150,7 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource
enum dc_status status = DC_OK; enum dc_status status = DC_OK;
uint8_t fec_config = 0; uint8_t fec_config = 0;
/* Access link encoder based on whether it is statically link_enc = link_enc_cfg_get_link_enc(link);
* or dynamically assigned to a link.
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign)
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
else
link_enc = link->link_enc;
ASSERT(link_enc); ASSERT(link_enc);
if (!dc_link_should_enable_fec(link)) if (!dc_link_should_enable_fec(link))
...@@ -6222,14 +6190,7 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) ...@@ -6222,14 +6190,7 @@ void dp_set_fec_enable(struct dc_link *link, bool enable)
{ {
struct link_encoder *link_enc = NULL; struct link_encoder *link_enc = NULL;
/* Access link encoder based on whether it is statically link_enc = link_enc_cfg_get_link_enc(link);
* or dynamically assigned to a link.
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign)
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
else
link_enc = link->link_enc;
ASSERT(link_enc); ASSERT(link_enc);
if (!dc_link_should_enable_fec(link)) if (!dc_link_should_enable_fec(link))
...@@ -6255,23 +6216,6 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) ...@@ -6255,23 +6216,6 @@ void dp_set_fec_enable(struct dc_link *link, bool enable)
} }
} }
struct link_encoder *dp_get_link_enc(struct dc_link *link)
{
struct link_encoder *link_enc;
link_enc = link->link_enc;
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign) {
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc,
link);
if (!link->link_enc)
link_enc = link_enc_cfg_get_next_avail_link_enc(
link->ctx->dc);
}
return link_enc;
}
void dpcd_set_source_specific_data(struct dc_link *link) void dpcd_set_source_specific_data(struct dc_link *link)
{ {
if (!link->dc->vendor_signature.is_valid) { if (!link->dc->vendor_signature.is_valid) {
......
...@@ -486,7 +486,8 @@ struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc) ...@@ -486,7 +486,8 @@ struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc)
} }
for (i = 0; i < dc->res_pool->res_cap->num_dig_link_enc; i++) { for (i = 0; i < dc->res_pool->res_cap->num_dig_link_enc; i++) {
if (encs_assigned[i] == ENGINE_ID_UNKNOWN) { if (encs_assigned[i] == ENGINE_ID_UNKNOWN &&
dc->res_pool->link_encoders[i] != NULL) {
link_enc = dc->res_pool->link_encoders[i]; link_enc = dc->res_pool->link_encoders[i];
break; break;
} }
...@@ -506,6 +507,26 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream( ...@@ -506,6 +507,26 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
return link_enc; return link_enc;
} }
struct link_encoder *link_enc_cfg_get_link_enc(
const struct dc_link *link)
{
struct link_encoder *link_enc = NULL;
/* Links supporting dynamically assigned link encoder will be assigned next
* available encoder if one not already assigned.
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign) {
link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
if (link_enc == NULL)
link_enc = link_enc_cfg_get_next_avail_link_enc(
link->ctx->dc);
} else
link_enc = link->link_enc;
return link_enc;
}
bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link) bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link)
{ {
bool is_avail = true; bool is_avail = true;
......
...@@ -86,11 +86,7 @@ void dp_enable_link_phy( ...@@ -86,11 +86,7 @@ void dp_enable_link_phy(
link->dc->res_pool->dp_clock_source; link->dc->res_pool->dp_clock_source;
unsigned int i; unsigned int i;
/* Link should always be assigned encoder when en-/disabling. */ link_enc = link_enc_cfg_get_link_enc(link);
if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign)
link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, link);
else
link_enc = link->link_enc;
ASSERT(link_enc); ASSERT(link_enc);
if (link->connector_signal == SIGNAL_TYPE_EDP) { if (link->connector_signal == SIGNAL_TYPE_EDP) {
...@@ -228,11 +224,7 @@ void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_ ...@@ -228,11 +224,7 @@ void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_
struct hpo_dp_link_encoder *hpo_link_enc = link_res->hpo_dp_link_enc; struct hpo_dp_link_encoder *hpo_link_enc = link_res->hpo_dp_link_enc;
struct link_encoder *link_enc; struct link_encoder *link_enc;
/* Link should always be assigned encoder when en-/disabling. */ link_enc = link_enc_cfg_get_link_enc(link);
if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign)
link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, link);
else
link_enc = link->link_enc;
ASSERT(link_enc); ASSERT(link_enc);
if (!link->wa_flags.dp_keep_receiver_powered) if (!link->wa_flags.dp_keep_receiver_powered)
...@@ -360,14 +352,8 @@ void dp_set_hw_test_pattern( ...@@ -360,14 +352,8 @@ void dp_set_hw_test_pattern(
struct link_encoder *encoder; struct link_encoder *encoder;
enum dp_link_encoding link_encoding_format = dp_get_link_encoding_format(&link->cur_link_settings); enum dp_link_encoding link_encoding_format = dp_get_link_encoding_format(&link->cur_link_settings);
/* Access link encoder based on whether it is statically encoder = link_enc_cfg_get_link_enc(link);
* or dynamically assigned to a link. ASSERT(encoder);
*/
if (link->is_dig_mapping_flexible &&
link->dc->res_pool->funcs->link_encs_assign)
encoder = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link);
else
encoder = link->link_enc;
pattern_param.dp_phy_pattern = test_pattern; pattern_param.dp_phy_pattern = test_pattern;
pattern_param.custom_pattern = custom_pattern; pattern_param.custom_pattern = custom_pattern;
......
...@@ -171,7 +171,6 @@ uint8_t dc_dp_initialize_scrambling_data_symbols( ...@@ -171,7 +171,6 @@ uint8_t dc_dp_initialize_scrambling_data_symbols(
enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready); enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready);
void dp_set_fec_enable(struct dc_link *link, bool enable); void dp_set_fec_enable(struct dc_link *link, bool enable);
struct link_encoder *dp_get_link_enc(struct dc_link *link);
bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable); bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update); bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update);
void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable); void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
......
...@@ -96,6 +96,9 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream( ...@@ -96,6 +96,9 @@ struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream(
struct dc *dc, struct dc *dc,
const struct dc_stream_state *stream); const struct dc_stream_state *stream);
/* Return DIG link encoder. NULL if unused. */
struct link_encoder *link_enc_cfg_get_link_enc(const struct dc_link *link);
/* Return true if encoder available to use. */ /* Return true if encoder available to use. */
bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link); bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link);
......
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