drm/amd/display: Add MPC meory shutdown support
authorJake Wang <haonan.wang2@amd.com>
Wed, 13 Oct 2021 18:39:41 +0000 (14:39 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 3 Nov 2021 16:32:34 +0000 (12:32 -0400)
[Why & How]
The MPC memory clocks should be powered down when not in use.

Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Jake Wang <haonan.wang2@amd.com>
Reviewed-by: Eric Yang <eric.yang2@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h

index a82319f4d081d42ba66f19ce903bab65dbe4ca1c..95149734378baadfbfbfd04a42f2f96b28ca1d0c 100644 (file)
@@ -1381,13 +1381,11 @@ int mpcc3_release_rmu(struct mpc *mpc, int mpcc_id)
 
 }
 
-static void mpc3_mpc_init(struct mpc *mpc)
+static void mpc3_set_mpc_mem_lp_mode(struct mpc *mpc)
 {
        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
        int mpcc_id;
 
-       mpc1_mpc_init(mpc);
-
        if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
                if (mpc30->mpc_mask->MPC_RMU0_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPC_RMU1_MEM_LOW_PWR_MODE) {
                        REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_LOW_PWR_MODE, 3);
@@ -1405,7 +1403,7 @@ const struct mpc_funcs dcn30_mpc_funcs = {
        .read_mpcc_state = mpc1_read_mpcc_state,
        .insert_plane = mpc1_insert_plane,
        .remove_mpcc = mpc1_remove_mpcc,
-       .mpc_init = mpc3_mpc_init,
+       .mpc_init = mpc1_mpc_init,
        .mpc_init_single_inst = mpc1_mpc_init_single_inst,
        .update_blending = mpc2_update_blending,
        .cursor_lock = mpc1_cursor_lock,
@@ -1432,6 +1430,7 @@ const struct mpc_funcs dcn30_mpc_funcs = {
        .power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,
        .get_mpc_out_mux = mpc1_get_mpc_out_mux,
        .set_bg_color = mpc1_set_bg_color,
+       .set_mpc_mem_lp_mode = mpc3_set_mpc_mem_lp_mode,
 };
 
 void dcn30_mpc_construct(struct dcn30_mpc *mpc30,
index 1b089893460a5408a43e6ef1e1d4f4481b905782..5dd1ce9ddb539afb2aa1dbfb16f6550086402ecd 100644 (file)
 #define FN(reg_name, field_name) \
        hws->shifts->field_name, hws->masks->field_name
 
+static void enable_memory_low_power(struct dc *dc)
+{
+       struct dce_hwseq *hws = dc->hwseq;
+       int i;
+
+       if (dc->debug.enable_mem_low_power.bits.dmcu) {
+               // Force ERAM to shutdown if DMCU is not enabled
+               if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
+                       REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
+               }
+       }
+
+       // Set default OPTC memory power states
+       if (dc->debug.enable_mem_low_power.bits.optc) {
+               // Shutdown when unassigned and light sleep in VBLANK
+               REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
+       }
+
+       if (dc->debug.enable_mem_low_power.bits.vga) {
+               // Power down VGA memory
+               REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
+       }
+
+       if (dc->debug.enable_mem_low_power.bits.mpc)
+               dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode(dc->res_pool->mpc);
+
+
+       if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
+               // Power down VPGs
+               for (i = 0; i < dc->res_pool->stream_enc_count; i++)
+                       dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+               for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
+                       dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
+#endif
+       }
+
+}
+
 void dcn31_init_hw(struct dc *dc)
 {
        struct abm **abms = dc->res_pool->multiple_abms;
@@ -108,35 +147,7 @@ void dcn31_init_hw(struct dc *dc)
        if (res_pool->dccg->funcs->dccg_init)
                res_pool->dccg->funcs->dccg_init(res_pool->dccg);
 
-       if (dc->debug.enable_mem_low_power.bits.dmcu) {
-               // Force ERAM to shutdown if DMCU is not enabled
-               if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
-                       REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
-               }
-       }
-
-       // Set default OPTC memory power states
-       if (dc->debug.enable_mem_low_power.bits.optc) {
-               // Shutdown when unassigned and light sleep in VBLANK
-               REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);
-       }
-
-       if (dc->debug.enable_mem_low_power.bits.vga) {
-               // Power down VGA memory
-               REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);
-       }
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
-       if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
-               // Power down VPGs
-               for (i = 0; i < dc->res_pool->stream_enc_count; i++)
-                       dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
-#if defined(CONFIG_DRM_AMD_DC_DP2_0)
-               for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)
-                       dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);
-#endif
-       }
-#endif
+       enable_memory_low_power(dc);
 
        if (dc->ctx->dc_bios->fw_info_valid) {
                res_pool->ref_clocks.xtalin_clock_inKhz =
index 04d6ec3f021f08b6b76fe6c1237f49e89f9c5811..f5fd2a06732306f93c1a769fdf029d69601adb41 100644 (file)
@@ -367,6 +367,7 @@ struct mpc_funcs {
        void (*set_bg_color)(struct mpc *mpc,
                        struct tg_color *bg_color,
                        int mpcc_id);
+       void (*set_mpc_mem_lp_mode)(struct mpc *mpc);
 };
 
 #endif