]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
drm/amd/display: fix audio endpoint not getting disabled issue
authorSu Sung Chung <Su.Chung@amd.com>
Thu, 25 Jul 2019 18:43:55 +0000 (14:43 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 23 Aug 2019 16:37:11 +0000 (11:37 -0500)
[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>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h
drivers/gpu/drm/amd/display/dc/inc/core_types.h
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h

index f09811c0bf02f4125c13ffeea286e7916a31974f..84f12e13c900bdc33a27c3050b20ad5df9c740be 100644 (file)
@@ -1918,7 +1918,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)
index 70dbdb38144609cc372a415ae96634fbf99b61cf..ca20b150afcc237ba21f8ad46f4bc3bb3b1d97d4 100644 (file)
@@ -2804,7 +2804,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;
@@ -2839,7 +2839,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
index fe9a4e4b9d1f97c9345f41aee87c19e6202ede0e..79438c4f1e20be86f2cadd3a6b7a28c2a577fee9 100644 (file)
@@ -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,
index e475a6488234d8f524522e916f0eb4a92222f9a1..d2d887972956da05319ec8a89548b7ba2f134cd1 100644 (file)
@@ -981,7 +981,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;
@@ -1004,24 +1004,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);
@@ -1034,7 +1023,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;
@@ -1051,7 +1040,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,
@@ -1914,8 +1903,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)) {
index 668feb0d169d512103c4d40267ece9cc9e014a62..2f9b7dbdf4157dd3256a6d789696159fd8cf687b 100644 (file)
@@ -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);
 
index 283915b2c2b13c9e1b44c36722eb22d9e90787bb..f61f59ac1e00b618881d9d45cd4adb8a8d537d19 100644 (file)
@@ -828,11 +828,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.
index e49325940fd3351ba8c5b471fb6c82efb4386149..e9d8a761016088c3f8d8729fd1431a9ba21a187a 100644 (file)
@@ -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
index 689c2765b0712ad90e3bf39e04b31cc17a2fa614..92ab3dd91814ff8bccb90c235023047ff82c7504 100644 (file)
@@ -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,
index bfe0d06d1c2099e2e2cda509f38cb94649a403cb..df28fbc4c63c05d392482e26a17b803c8a5449a9 100644 (file)
@@ -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*********************/
index 80de2febd7cb03b4618524d326934599c2237506..68b1185f0636238452a7f8557ec75d4a7ed3a9af 100644 (file)
@@ -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,