diff options
author | Jimmy Kizito <Jimmy.Kizito@amd.com> | 2021-08-10 19:07:43 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2021-09-14 15:57:09 -0400 |
commit | 64d283cb379eadcb412ebba3b61808b58d0c6193 (patch) | |
tree | 9166eab38ab708baceb6244936a9cdf52a325d0d /drivers/gpu/drm/amd/display/dc/dcn20 | |
parent | drm/amd/display: Add flag to detect dpms force off during HPD (diff) | |
download | linux-dev-64d283cb379eadcb412ebba3b61808b58d0c6193.tar.xz linux-dev-64d283cb379eadcb412ebba3b61808b58d0c6193.zip |
drm/amd/display: Fix dynamic link encoder access.
[Why]
Assuming DIG link encoders are statically mapped to links can cause
system instability due to null pointer accesses.
[How]
- Add checks for non-null link encoder pointers before trying to access
them.
- When a hardware platform uses dynamic DIG assignment (i.e. resource
function 'link_encs_assign' defined) and a link supports flexible
mapping to DIGs, use the link_enc_cfg API to access the DIG assigned to
a link or stream.
Reviewed-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
Acked-by: Mikita Lipski <mikita.lipski@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn20')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 20 |
2 files changed, 29 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index ffc0b9ab976f..c0aed7d07eeb 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -2381,6 +2381,13 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) uint32_t active_total_with_borders; uint32_t early_control = 0; struct timing_generator *tg = pipe_ctx->stream_res.tg; + struct link_encoder *link_enc; + + if (link->is_dig_mapping_flexible && + link->dc->res_pool->funcs->link_encs_assign) + link_enc = pipe_ctx->stream->link_enc; + else + link_enc = link->link_enc; /* For MST, there are multiply stream go to only one link. * connect DIG back_end to front_end while enable_stream and @@ -2397,9 +2404,9 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) link->hpo_dp_link_enc->inst); } - if (!is_dp_128b_132b_signal(pipe_ctx)) - link->link_enc->funcs->connect_dig_be_to_fe( - link->link_enc, pipe_ctx->stream_res.stream_enc->id, true); + if (!is_dp_128b_132b_signal(pipe_ctx) && link_enc) + link_enc->funcs->connect_dig_be_to_fe( + link_enc, pipe_ctx->stream_res.stream_enc->id, true); if (dc_is_dp_signal(pipe_ctx->stream->signal)) dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE); diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 7bab88356df4..e69f553d680f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -87,6 +87,7 @@ #include "dce/dce_aux.h" #include "dce/dce_i2c.h" #include "vm_helper.h" +#include "link_enc_cfg.h" #include "amdgpu_socbb.h" @@ -1596,12 +1597,29 @@ static void get_pixel_clock_parameters( const struct dc_stream_state *stream = pipe_ctx->stream; struct pipe_ctx *odm_pipe; int opp_cnt = 1; + struct dc_link *link = stream->link; + struct link_encoder *link_enc = NULL; for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) opp_cnt++; pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz; - pixel_clk_params->encoder_object_id = stream->link->link_enc->id; + + /* 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_stream(stream->link->dc->current_state, stream); + if (link_enc == NULL) + link_enc = link_enc_cfg_get_next_avail_link_enc(stream->link->dc, + stream->link->dc->current_state); + } else + link_enc = stream->link->link_enc; + ASSERT(link_enc); + + if (link_enc) + pixel_clk_params->encoder_object_id = link_enc->id; pixel_clk_params->signal_type = pipe_ctx->stream->signal; pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1; /* TODO: un-hardcode*/ |