diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3566-drm-amd-display-fix-audio-endpoint-not-getting-disab.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3566-drm-amd-display-fix-audio-endpoint-not-getting-disab.patch | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3566-drm-amd-display-fix-audio-endpoint-not-getting-disab.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3566-drm-amd-display-fix-audio-endpoint-not-getting-disab.patch new file mode 100644 index 00000000..874b5207 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3566-drm-amd-display-fix-audio-endpoint-not-getting-disab.patch @@ -0,0 +1,337 @@ +From befdded6f23fe1dcab77243770596fa8ee85e322 Mon Sep 17 00:00:00 2001 +From: Su Sung Chung <Su.Chung@amd.com> +Date: Thu, 25 Jul 2019 14:43:55 -0400 +Subject: [PATCH 3566/4256] drm/amd/display: fix audio endpoint not getting + disabled issue + +[Why] +Disable_audio_stream gets enum option as a paramenter which will decide +if we free acquired resources or not. However checks for the option is +guarded by the other condition which check if audio stream is getting +diabled more than once. With both conditions combined, if we attempt to +disable audio stream twice in a row, first with keep and second with +free as an option, we will never free any resources, which will make +system think there is audio endpoint connected even after we plug out +the device + +[How] +Get rid of option as parameter to disable_audio_stream and move the part +of the code that free acquired resources to outside where to keep or to +free resources is actually determined + +Signed-off-by: Su Sung Chung <Su.Chung@amd.com> +Reviewed-by: Jun Lei <Jun.Lei@amd.com> +Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 6 ++- + drivers/gpu/drm/amd/display/dc/core/dc_link.c | 4 +- + .../drm/amd/display/dc/core/dc_link_hwss.c | 4 +- + .../display/dc/dce110/dce110_hw_sequencer.c | 40 +++++++++++-------- + .../display/dc/dce110/dce110_hw_sequencer.h | 4 +- + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 20 ++++++++-- + .../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 24 ++++++++--- + .../drm/amd/display/dc/dcn20/dcn20_hwseq.h | 2 +- + .../gpu/drm/amd/display/dc/inc/core_types.h | 7 +--- + .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 5 +-- + 10 files changed, 74 insertions(+), 42 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index bc713677faa9..f7959e122348 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1927,7 +1927,11 @@ static void commit_planes_do_stream_update(struct dc *dc, + dc->hwss.pipe_control_lock(dc, pipe_ctx, true); + + if (*stream_update->dpms_off) { +- core_link_disable_stream(pipe_ctx, KEEP_ACQUIRED_RESOURCE); ++ core_link_disable_stream(pipe_ctx); ++ /* for dpms, keep acquired resources*/ ++ if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only) ++ pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); ++ + dc->hwss.optimize_bandwidth(dc, dc->current_state); + } else { + if (!dc->optimize_seamless_boot) +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +index 0ccf0cd0a44d..3dfebfd4c130 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +@@ -2802,7 +2802,7 @@ void core_link_enable_stream( + #endif + } + +-void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option) ++void core_link_disable_stream(struct pipe_ctx *pipe_ctx) + { + struct dc *core_dc = pipe_ctx->stream->ctx->dc; + struct dc_stream_state *stream = pipe_ctx->stream; +@@ -2837,7 +2837,7 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option) + write_i2c_redriver_setting(pipe_ctx, false); + } + } +- core_dc->hwss.disable_stream(pipe_ctx, option); ++ core_dc->hwss.disable_stream(pipe_ctx); + + disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal); + #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +index fe9a4e4b9d1f..79438c4f1e20 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +@@ -289,7 +289,9 @@ void dp_retrain_link_dp_test(struct dc_link *link, + + dp_receiver_power_ctrl(link, false); + +- link->dc->hwss.disable_stream(&pipes[i], KEEP_ACQUIRED_RESOURCE); ++ link->dc->hwss.disable_stream(&pipes[i]); ++ if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only) ++ (&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio); + + link->link_enc->funcs->disable_output( + link->link_enc, +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index 2693404cab1a..c2d026ba269f 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +@@ -978,7 +978,7 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) + } + } + +-void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option) ++void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx) + { + struct dc *dc; + struct pp_smu_funcs *pp_smu = NULL; +@@ -1001,24 +1001,13 @@ void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option) + if (dc->res_pool->pp_smu) + pp_smu = dc->res_pool->pp_smu; + +- if (option != KEEP_ACQUIRED_RESOURCE || +- !dc->debug.az_endpoint_mute_only) +- /*only disalbe az_endpoint if power down or free*/ +- pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); +- + if (dc_is_dp_signal(pipe_ctx->stream->signal)) + pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable( + pipe_ctx->stream_res.stream_enc); + else + pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable( + pipe_ctx->stream_res.stream_enc); +- /*don't free audio if it is from retrain or internal disable stream*/ +- if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) { +- /*we have to dynamic arbitrate the audio endpoints*/ +- /*we free the resource, need reset is_audio_acquired*/ +- update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false); +- pipe_ctx->stream_res.audio = NULL; +- } ++ + if (clk_mgr->funcs->enable_pme_wa) + /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ + clk_mgr->funcs->enable_pme_wa(clk_mgr); +@@ -1031,7 +1020,7 @@ void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option) + } + } + +-void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option) ++void dce110_disable_stream(struct pipe_ctx *pipe_ctx) + { + struct dc_stream_state *stream = pipe_ctx->stream; + struct dc_link *link = stream->link; +@@ -1048,7 +1037,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option) + pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( + pipe_ctx->stream_res.stream_enc); + +- dc->hwss.disable_audio_stream(pipe_ctx, option); ++ dc->hwss.disable_audio_stream(pipe_ctx); + + link->link_enc->funcs->connect_dig_be_to_fe( + link->link_enc, +@@ -1911,8 +1900,25 @@ static void dce110_reset_hw_ctx_wrap( + /* Disable if new stream is null. O/w, if stream is + * disabled already, no need to disable again. + */ +- if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) +- core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE); ++ if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) { ++ core_link_disable_stream(pipe_ctx_old); ++ ++ /* free acquired resources*/ ++ if (pipe_ctx_old->stream_res.audio) { ++ /*disable az_endpoint*/ ++ pipe_ctx_old->stream_res.audio->funcs-> ++ az_disable(pipe_ctx_old->stream_res.audio); ++ ++ /*free audio*/ ++ if (dc->caps.dynamic_audio == true) { ++ /*we have to dynamic arbitrate the audio endpoints*/ ++ /*we free the resource, need reset is_audio_acquired*/ ++ update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, ++ pipe_ctx_old->stream_res.audio, false); ++ pipe_ctx_old->stream_res.audio = NULL; ++ } ++ } ++ } + + pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); + if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h +index 668feb0d169d..2f9b7dbdf415 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h +@@ -42,7 +42,7 @@ enum dc_status dce110_apply_ctx_to_hw( + + void dce110_enable_stream(struct pipe_ctx *pipe_ctx); + +-void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option); ++void dce110_disable_stream(struct pipe_ctx *pipe_ctx); + + void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, + struct dc_link_settings *link_settings); +@@ -50,7 +50,7 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, + void dce110_blank_stream(struct pipe_ctx *pipe_ctx); + + void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx); +-void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option); ++void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx); + + void dce110_update_info_frame(struct pipe_ctx *pipe_ctx); + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index 344190be93ae..fd721edbb9f4 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -827,11 +827,23 @@ static void dcn10_reset_back_end_for_pipe( + if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { + /* DPMS may already disable */ + if (!pipe_ctx->stream->dpms_off) +- core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE); +- else if (pipe_ctx->stream_res.audio) { +- dc->hwss.disable_audio_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE); ++ core_link_disable_stream(pipe_ctx); ++ else if (pipe_ctx->stream_res.audio) ++ dc->hwss.disable_audio_stream(pipe_ctx); ++ ++ if (pipe_ctx->stream_res.audio) { ++ /*disable az_endpoint*/ ++ pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); ++ ++ /*free audio*/ ++ if (dc->caps.dynamic_audio == true) { ++ /*we have to dynamic arbitrate the audio endpoints*/ ++ /*we free the resource, need reset is_audio_acquired*/ ++ update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, ++ pipe_ctx->stream_res.audio, false); ++ pipe_ctx->stream_res.audio = NULL; ++ } + } +- + } + + /* by upper caller loop, parent pipe: pipe0, will be reset last. +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 c8c17fac2e24..56c4df262dc0 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +@@ -1461,9 +1461,9 @@ void dcn20_set_dmdata_attributes(struct pipe_ctx *pipe_ctx) + hubp->funcs->dmdata_set_attributes(hubp, &attr); + } + +-void dcn20_disable_stream(struct pipe_ctx *pipe_ctx, int option) ++void dcn20_disable_stream(struct pipe_ctx *pipe_ctx) + { +- dce110_disable_stream(pipe_ctx, option); ++ dce110_disable_stream(pipe_ctx); + } + + static void dcn20_init_vm_ctx( +@@ -1617,9 +1617,23 @@ static void dcn20_reset_back_end_for_pipe( + if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { + /* DPMS may already disable */ + if (!pipe_ctx->stream->dpms_off) +- core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE); +- else if (pipe_ctx->stream_res.audio) { +- dc->hwss.disable_audio_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE); ++ core_link_disable_stream(pipe_ctx); ++ else if (pipe_ctx->stream_res.audio) ++ dc->hwss.disable_audio_stream(pipe_ctx); ++ ++ /* free acquired resources */ ++ if (pipe_ctx->stream_res.audio) { ++ /*disable az_endpoint*/ ++ pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); ++ ++ /*free audio*/ ++ if (dc->caps.dynamic_audio == true) { ++ /*we have to dynamic arbitrate the audio endpoints*/ ++ /*we free the resource, need reset is_audio_acquired*/ ++ update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, ++ pipe_ctx->stream_res.audio, false); ++ pipe_ctx->stream_res.audio = NULL; ++ } + } + } + #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h +index 689c2765b071..92ab3dd91814 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h +@@ -75,7 +75,7 @@ bool dcn20_dmdata_status_done(struct pipe_ctx *pipe_ctx); + + void dcn20_set_dmdata_attributes(struct pipe_ctx *pipe_ctx); + +-void dcn20_disable_stream(struct pipe_ctx *pipe_ctx, int option); ++void dcn20_disable_stream(struct pipe_ctx *pipe_ctx); + + void dcn20_program_tripleBuffer( + const struct dc *dc, +diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h +index bfe0d06d1c20..df28fbc4c63c 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h +@@ -63,11 +63,6 @@ struct link_init_data { + TODO: remove it when DC is complete. */ + }; + +-enum { +- FREE_ACQUIRED_RESOURCE = 0, +- KEEP_ACQUIRED_RESOURCE = 1, +-}; +- + struct dc_link *link_create(const struct link_init_data *init_params); + void link_destroy(struct dc_link **link); + +@@ -82,7 +77,7 @@ void core_link_enable_stream( + struct dc_state *state, + struct pipe_ctx *pipe_ctx); + +-void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option); ++void core_link_disable_stream(struct pipe_ctx *pipe_ctx); + + void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable); + /********** DAL Core*********************/ +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +index 80de2febd7cb..68b1185f0636 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -196,8 +196,7 @@ struct hw_sequencer_funcs { + + void (*enable_stream)(struct pipe_ctx *pipe_ctx); + +- void (*disable_stream)(struct pipe_ctx *pipe_ctx, +- int option); ++ void (*disable_stream)(struct pipe_ctx *pipe_ctx); + + void (*unblank_stream)(struct pipe_ctx *pipe_ctx, + struct dc_link_settings *link_settings); +@@ -206,7 +205,7 @@ struct hw_sequencer_funcs { + + void (*enable_audio_stream)(struct pipe_ctx *pipe_ctx); + +- void (*disable_audio_stream)(struct pipe_ctx *pipe_ctx, int option); ++ void (*disable_audio_stream)(struct pipe_ctx *pipe_ctx); + + void (*pipe_control_lock)( + struct dc *dc, +-- +2.17.1 + |