From: Jacky Liao <ziyu.l...@amd.com>

[Why]
The OPTC memory blocks should be powered down when they are not in use.
This will reduce power consumption.

[How]
1. Set ODM_MEM_UNASSIGNED_PWR_MODE to shutdown memory when unassigned
2. Set ODM_MEM_VBLANK_PWR_MODE to light sleep mode when in vblank
3. Added a debug option to allow this behaviour to be turned off
4. Restructured debug options to use a bitfield in a way that's more clear

Signed-off-by: Jacky Liao <ziyu.l...@amd.com>
Reviewed-by: Eric Yang <eric.ya...@amd.com>
Acked-by: Qingqing Zhuo <qingqing.z...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc.h                | 10 +++++++++-
 drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h     | 12 ++++++++++--
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c |  6 ++++++
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c   | 14 +++++++-------
 4 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 273963e8e61a..87bc10279349 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -414,6 +414,14 @@ struct dc_bw_validation_profile {
                        } \
                }
 
+union mem_low_power_enable_options {
+       struct {
+               bool mpc: 1;
+               bool optc: 1;
+       } bits;
+       uint32_t u32All;
+};
+
 struct dc_debug_options {
        enum visual_confirm visual_confirm;
        bool sanity_checks;
@@ -506,7 +514,7 @@ struct dc_debug_options {
        bool disable_dsc;
        bool enable_dram_clock_change_one_display_vactive;
        bool force_ignore_link_settings;
-       bool enable_mpc_mem_powerdown: 1;
+       union mem_low_power_enable_options enable_mem_low_power;
 };
 
 struct dc_debug_data {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h 
b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
index b77e22bf6aec..a8103c762c08 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
@@ -607,6 +607,10 @@ struct dce_hwseq_registers {
        uint32_t MC_VM_XGMI_LFB_CNTL;
        uint32_t AZALIA_AUDIO_DTO;
        uint32_t AZALIA_CONTROLLER_CLOCK_GATING;
+ #if defined(CONFIG_DRM_AMD_DC_DCN3_0)
+       uint32_t HPO_TOP_CLOCK_CONTROL;
+       uint32_t ODM_MEM_PWR_CTRL3;
+ #endif
 };
  /* set field name */
 #define HWS_SF(blk_name, reg_name, field_name, post_fix)\
@@ -845,7 +849,9 @@ struct dce_hwseq_registers {
 #if defined(CONFIG_DRM_AMD_DC_DCN3_0)
 #define HWSEQ_DCN30_MASK_SH_LIST(mask_sh)\
        HWSEQ_DCN2_MASK_SH_LIST(mask_sh), \
-       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh)
+       HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
+       HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
+       HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh)
 #endif
 
 #if defined(CONFIG_DRM_AMD_DC_DCN3_01)
@@ -1059,7 +1065,9 @@ struct dce_hwseq_registers {
        type D2VGA_MODE_ENABLE; \
        type D3VGA_MODE_ENABLE; \
        type D4VGA_MODE_ENABLE; \
-       type AZALIA_AUDIO_DTO_MODULE;
+       type AZALIA_AUDIO_DTO_MODULE; \
+       type ODM_MEM_UNASSIGNED_PWR_MODE; \
+       type ODM_MEM_VBLANK_PWR_MODE;
 
 #if defined(CONFIG_DRM_AMD_DC_DCN3_0)
 #define HWSEQ_DCN3_REG_FIELD_LIST(type) \
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index 3699c9a2789c..53b892f16da4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -462,6 +462,12 @@ void dcn30_init_hw(struct dc *dc)
                hws->funcs.disable_vga(dc->hwseq);
        }
 
+       // 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->ctx->dc_bios->fw_info_valid) {
                res_pool->ref_clocks.xtalin_clock_inKhz =
                                
dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
index 1671688557f4..d7d053fc6e91 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
@@ -143,7 +143,7 @@ static void mpc3_power_on_ogam_lut(
 {
        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 
-       if (mpc->ctx->dc->debug.enable_mpc_mem_powerdown) {
+       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
                // Force power on
                REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_DIS, 
power_on == true ? 1:0);
                // Wait for confirmation when powering on
@@ -369,7 +369,7 @@ void mpc3_set_output_gamma(
        REG_UPDATE(MPCC_OGAM_CONTROL[mpcc_id],
                        MPCC_OGAM_SELECT, next_mode == LUT_RAM_A ? 0:1);
 
-       if (mpc->ctx->dc->debug.enable_mpc_mem_powerdown)
+       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
                mpc3_power_on_ogam_lut(mpc, mpcc_id, false);
 }
 
@@ -818,7 +818,7 @@ static void mpc3_power_on_shaper_3dlut(
                REG_SET(MPC_RMU_MEM_PWR_CTRL, 0,
                        MPC_RMU0_MEM_PWR_DIS, power_on == true ? 1:0);
                /* wait for memory to fully power up */
-               if (power_on && mpc->ctx->dc->debug.enable_mpc_mem_powerdown) {
+               if (power_on && 
mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
                        REG_WAIT(MPC_RMU_MEM_PWR_CTRL, 
MPC_RMU0_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
                        REG_WAIT(MPC_RMU_MEM_PWR_CTRL, 
MPC_RMU0_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
                }
@@ -829,7 +829,7 @@ static void mpc3_power_on_shaper_3dlut(
        } else if (rmu_idx == 1) {
                REG_SET(MPC_RMU_MEM_PWR_CTRL, 0,
                        MPC_RMU1_MEM_PWR_DIS, power_on == true ? 1:0);
-               if (power_on && mpc->ctx->dc->debug.enable_mpc_mem_powerdown) {
+               if (power_on && 
mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
                        REG_WAIT(MPC_RMU_MEM_PWR_CTRL, 
MPC_RMU1_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
                        REG_WAIT(MPC_RMU_MEM_PWR_CTRL, 
MPC_RMU1_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
                }
@@ -862,7 +862,7 @@ bool mpc3_program_shaper(
                return false;
        }
 
-       if (mpc->ctx->dc->debug.enable_mpc_mem_powerdown)
+       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
                mpc3_power_on_shaper_3dlut(mpc, rmu_idx, true);
 
        current_mode = mpc3_get_shaper_current(mpc, rmu_idx);
@@ -1223,7 +1223,7 @@ bool mpc3_program_3dlut(
        mpc3_set_3dlut_mode(mpc, mode, is_12bits_color_channel,
                                        is_17x17x17, rmu_idx);
 
-       if (mpc->ctx->dc->debug.enable_mpc_mem_powerdown)
+       if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
                mpc3_power_on_shaper_3dlut(mpc, rmu_idx, false);
 
        return true;
@@ -1386,7 +1386,7 @@ static void mpc3_mpc_init(struct mpc *mpc)
 
        mpc1_mpc_init(mpc);
 
-       if (mpc->ctx->dc->debug.enable_mpc_mem_powerdown) {
+       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);
                        REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, 
MPC_RMU1_MEM_LOW_PWR_MODE, 3);
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to