From 4176664b1fc8aa052f886037590cac4fb0dd8afb Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Wed, 27 Sep 2017 23:23:16 -0400 Subject: [PATCH] drm/amd/display: audio dynamic resource acquired related Signed-off-by: Charlene Liu Reviewed-by: Anthony Koo Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 4 ++-- .../drm/amd/display/dc/core/dc_link_hwss.c | 2 +- .../gpu/drm/amd/display/dc/core/dc_resource.c | 24 ++++++++++++++----- drivers/gpu/drm/amd/display/dc/dc.h | 1 + .../display/dc/dce110/dce110_hw_sequencer.c | 12 ++++++++-- .../display/dc/dce110/dce110_hw_sequencer.h | 2 +- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- .../gpu/drm/amd/display/dc/inc/core_types.h | 7 +++++- .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 3 ++- drivers/gpu/drm/amd/display/dc/inc/resource.h | 5 ++++ 10 files changed, 47 insertions(+), 15 deletions(-) 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 e414e4770789..2d59f77fa9a2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2323,14 +2323,14 @@ void core_link_enable_stream( allocate_mst_payload(pipe_ctx); } -void core_link_disable_stream(struct pipe_ctx *pipe_ctx) +void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option) { struct dc *core_dc = pipe_ctx->stream->ctx->dc; if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) deallocate_mst_payload(pipe_ctx); - core_dc->hwss.disable_stream(pipe_ctx); + core_dc->hwss.disable_stream(pipe_ctx, option); disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal); } 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 34b6d1cb151e..9a33b471270a 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 @@ -282,7 +282,7 @@ void dp_retrain_link_dp_test(struct dc_link *link, dp_receiver_power_ctrl(link, false); - link->dc->hwss.disable_stream(&pipes[i]); + link->dc->hwss.disable_stream(&pipes[i], KEEP_ACQUIRED_RESOURCE); link->link_enc->funcs->disable_output( link->link_enc, diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index bbfec7cb2ad1..68c613229a10 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -242,7 +242,10 @@ bool resource_construct( pool->stream_enc_count++; } } - + dc->caps.dynamic_audio = false; + if (pool->audio_count < pool->stream_enc_count) { + dc->caps.dynamic_audio = true; + } for (i = 0; i < num_virtual_links; i++) { pool->stream_enc[pool->stream_enc_count] = virtual_stream_encoder_create( @@ -1330,7 +1333,7 @@ static void update_stream_engine_usage( } /* TODO: release audio object */ -static void update_audio_usage( +void update_audio_usage( struct resource_context *res_ctx, const struct resource_pool *pool, struct audio *audio, @@ -1414,12 +1417,21 @@ static struct audio *find_first_free_audio( const struct resource_pool *pool) { int i; - for (i = 0; i < pool->audio_count; i++) { - if (res_ctx->is_audio_acquired[i] == false) { - return pool->audios[i]; + if (pool->audio_count >= pool->stream_enc_count) { + for (i = 0; i < pool->audio_count; i++) { + if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) { + /*we have enough audio endpoint, no need to do dynamic distribution*/ + return pool->audios[i]; + } } - } + } else { /*first come first serve*/ + for (i = 0; i < pool->audio_count; i++) { + if (res_ctx->is_audio_acquired[i] == false) { + return pool->audios[i]; + } + } + } return 0; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index adadfad2bd51..2517fb821fff 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -58,6 +58,7 @@ struct dc_caps { uint32_t i2c_speed_in_khz; unsigned int max_cursor_size; bool dcc_const_color; + bool dynamic_audio; }; struct dc_dcc_surface_param { 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 247e81806c4a..453d2ffd5c4a 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 @@ -985,10 +985,11 @@ void hwss_edp_backlight_control( link_transmitter_control(link->dc->ctx->dc_bios, &cntl); } -void dce110_disable_stream(struct pipe_ctx *pipe_ctx) +void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option) { struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->sink->link; + struct dc *dc = pipe_ctx->stream->ctx->dc; if (pipe_ctx->stream_res.audio) { pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); @@ -999,6 +1000,13 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) 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*/ + pipe_ctx->stream_res.audio = NULL; + /*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); + } /* TODO: notify audio driver for if audio modes list changed * add audio mode list change flag */ @@ -1871,7 +1879,7 @@ static void dce110_reset_hw_ctx_wrap( pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { struct clock_source *old_clk = pipe_ctx_old->clock_source; - core_link_disable_stream(pipe_ctx_old); + core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE); 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)) { dm_error("DC: failed to blank crtc!\n"); 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 a1e964af60ac..4d72bb99be93 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 @@ -47,7 +47,7 @@ void dce110_set_displaymarks( void dce110_enable_stream(struct pipe_ctx *pipe_ctx); -void dce110_disable_stream(struct pipe_ctx *pipe_ctx); +void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option); void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, struct dc_link_settings *link_settings); 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 84d9d202d3b5..072c48188b79 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 @@ -1025,7 +1025,7 @@ static void reset_back_end_for_pipe( * which is used by otg. Move disable_link after disable_crtc */ if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) - core_link_disable_stream(pipe_ctx); + core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE); /* by upper caller loop, parent pipe: pipe0, will be reset last. * back end share by all pipes and will be disable only when disable 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 ff23f268fe02..5230dddc8617 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -58,6 +58,11 @@ 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); @@ -72,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); +void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option); 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 bf3ab5d7398e..8734689a9245 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -134,7 +134,8 @@ struct hw_sequencer_funcs { void (*enable_stream)(struct pipe_ctx *pipe_ctx); - void (*disable_stream)(struct pipe_ctx *pipe_ctx); + void (*disable_stream)(struct pipe_ctx *pipe_ctx, + int option); void (*unblank_stream)(struct pipe_ctx *pipe_ctx, struct dc_link_settings *link_settings); diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index 614bb691ab59..5467332faf7b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -164,4 +164,9 @@ bool pipe_need_reprogram( void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream, struct bit_depth_reduction_params *fmt_bit_depth); +void update_audio_usage( + struct resource_context *res_ctx, + const struct resource_pool *pool, + struct audio *audio, + bool acquired); #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */ -- 2.30.2