From: Charlene Liu <[email protected]> [Why & How] Use dmub to notify pme instead of pmfw. This is for asic which has no pmfw-driver-if interface support.
Reviewed-by: Chris Park <[email protected]> Signed-off-by: Charlene Liu <[email protected]> Signed-off-by: Ray Wu <[email protected]> --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 17 +++++++++++++++++ drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 11 +++++++++++ .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 15 +++++++++++---- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 9cc90c406d86..91d4a8ec7a94 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1331,6 +1331,7 @@ struct dc_debug_options { uint8_t iommu_mismatch_temp_wka; bool disable_dynamic_expansion_for_test_pattern; bool psr_phy_force_phy_power_down_up_level_2; + bool dmub_send_az_pme_restore; uint32_t dml21_custom_derate_num_dpms; uint32_t dml21_custom_derate_at_dpm[DML2_MAX_NUM_DPM_LVL]; bool override_utm_client_qc_profile; diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 0485ff5217f1..f1a0225bbf84 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -2606,3 +2606,20 @@ void dc_dmub_srv_hubbub_set_riommu_pctrl(const struct dc_context *ctx, uint32_t dc_wake_and_execute_dmub_cmd(ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); } + +void dc_dmub_srv_nbif_az_pme_restore(const struct dc_context *ctx, uint32_t az_inst) +{ + union dmub_rb_cmd cmd; + + az_inst = (az_inst < 0x7) ? az_inst : 0; //dcnhw max aud_end point is 7 + + memset(&cmd, 0, sizeof(cmd)); + + cmd.nbif_az_pme_restore.header.type = DMUB_CMD__NBIF_AZ_PME_RESTORE; + cmd.nbif_az_pme_restore.header.payload_bytes = sizeof(cmd.nbif_az_pme_restore.data); + + cmd.nbif_az_pme_restore.data.az_inst = az_inst & 0xF; + + /* AZ must be out of D3 before the endpoint is accessed, so wait for completion */ + dc_wake_and_execute_dmub_cmd(ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); +} diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h index 8056824d90e0..684b66dc9771 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h @@ -476,4 +476,15 @@ bool dc_dmub_srv_panel_polarity_get_polarity(struct dc_dmub_srv *dc_dmub_srv, ui */ void dc_dmub_srv_hubbub_set_riommu_pctrl(const struct dc_context *ctx, uint32_t value); +/** + * dc_dmub_srv_nbif_az_pme_restore() - Wake the AZ endpoint from D3 via DMCUB. + * + * Replaces the clk_mgr PME workaround on DCN4_2, where the NBIF AZ PME restore + * is performed by DMCUB on the driver's behalf. No-op on other ASICs. + * + * @ctx: dc context + * @az_inst: Azalia codec endpoint instance + */ +void dc_dmub_srv_nbif_az_pme_restore(const struct dc_context *ctx, uint32_t az_inst); + #endif /* _DMUB_DC_SRV_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c index 1abb28504aec..ed6c2096272c 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c @@ -60,6 +60,7 @@ #include "dpcd_defs.h" #include "dsc.h" #include "dc_dp_types.h" +#include "dc_dmub_srv.h" /* include DCE11 register header files */ #include "dce/dce_11_0_d.h" #include "dce/dce_11_0_sh_mask.h" @@ -1146,7 +1147,10 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) num_audio++; } - if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) { + if (dc->debug.dmub_send_az_pme_restore) { + /*wake AZ from D3 first before access az endpoint*/ + dc_dmub_srv_nbif_az_pme_restore(dc->ctx, pipe_ctx->stream_res.audio->inst); + } else if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) { /*wake AZ from D3 first before access az endpoint*/ clk_mgr->funcs->enable_pme_wa(clk_mgr); } @@ -1184,10 +1188,13 @@ void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx) if (pipe_ctx->stream_res.audio) { pipe_ctx->stream_res.audio->enabled = false; - if (clk_mgr->funcs->enable_pme_wa) - /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ + if (dc->debug.dmub_send_az_pme_restore) { + /*wake AZ from D3 first before access az endpoint*/ + dc_dmub_srv_nbif_az_pme_restore(dc->ctx, pipe_ctx->stream_res.audio->inst); + } else if (clk_mgr->funcs->enable_pme_wa) { + /*wake AZ from D3 first before access az endpoint*/ clk_mgr->funcs->enable_pme_wa(clk_mgr); - + } /* TODO: notify audio driver for if audio modes list changed * add audio mode list change flag */ /* dal_audio_disable_azalia_audio_jack_presence(stream->audio, -- 2.43.0
