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

Reply via email to