drm/amd/display: Disable dsc root clock when not being used
authorJake Wang <haonan.wang2@amd.com>
Wed, 22 Sep 2021 20:25:36 +0000 (16:25 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 Oct 2021 21:19:24 +0000 (17:19 -0400)
[Why & How]
Disable root clock for dsc when not being used.

Reviewed-by: Nikola Cornij <Nikola.Cornij@amd.com>
Acked-by: Agustin Gutierrez Sanchez <agustin.gutierrez@amd.com>
Signed-off-by: Jake Wang <haonan.wang2@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/dcn20/dcn20_dccg.h
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h

index ede6510..f6f2d48 100644 (file)
        type DTBCLK_DTO_DIV[MAX_PIPES];\
        type DCCG_AUDIO_DTO_SEL;\
        type DCCG_AUDIO_DTO0_SOURCE_SEL;\
-       type DENTIST_DISPCLK_CHG_MODE;
+       type DENTIST_DISPCLK_CHG_MODE;\
+       type DSCCLK0_DTO_PHASE;\
+       type DSCCLK0_DTO_MODULO;\
+       type DSCCLK1_DTO_PHASE;\
+       type DSCCLK1_DTO_MODULO;\
+       type DSCCLK2_DTO_PHASE;\
+       type DSCCLK2_DTO_MODULO;\
+       type DSCCLK0_DTO_ENABLE;\
+       type DSCCLK1_DTO_ENABLE;\
+       type DSCCLK2_DTO_ENABLE;
+
 
 struct dccg_shift {
        DCCG_REG_FIELD_LIST(uint8_t)
@@ -205,6 +215,10 @@ struct dccg_registers {
        uint32_t SYMCLK32_SE_CNTL;
        uint32_t SYMCLK32_LE_CNTL;
        uint32_t DENTIST_DISPCLK_CNTL;
+       uint32_t DSCCLK_DTO_CTRL;
+       uint32_t DSCCLK0_DTO_PARAM;
+       uint32_t DSCCLK1_DTO_PARAM;
+       uint32_t DSCCLK2_DTO_PARAM;
 };
 
 struct dcn_dccg {
index 152adb5..3a325e4 100644 (file)
@@ -247,6 +247,76 @@ void dccg31_disable_symclk32_le(
        }
 }
 
+static void dccg31_disable_dscclk(struct dccg *dccg, int inst)
+{
+       struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+       if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
+               return;
+       //DTO must be enabled to generate a 0 Hz clock output
+       switch (inst) {
+       case 0:
+               REG_UPDATE(DSCCLK_DTO_CTRL,
+                               DSCCLK0_DTO_ENABLE, 1);
+               REG_UPDATE_2(DSCCLK0_DTO_PARAM,
+                               DSCCLK0_DTO_PHASE, 0,
+                               DSCCLK0_DTO_MODULO, 1);
+               break;
+       case 1:
+               REG_UPDATE(DSCCLK_DTO_CTRL,
+                               DSCCLK1_DTO_ENABLE, 1);
+               REG_UPDATE_2(DSCCLK1_DTO_PARAM,
+                               DSCCLK1_DTO_PHASE, 0,
+                               DSCCLK1_DTO_MODULO, 1);
+               break;
+       case 2:
+               REG_UPDATE(DSCCLK_DTO_CTRL,
+                               DSCCLK2_DTO_ENABLE, 1);
+               REG_UPDATE_2(DSCCLK2_DTO_PARAM,
+                               DSCCLK2_DTO_PHASE, 0,
+                               DSCCLK2_DTO_MODULO, 1);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+}
+
+static void dccg31_enable_dscclk(struct dccg *dccg, int inst)
+{
+       struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+       if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
+               return;
+       //Disable DTO
+       switch (inst) {
+       case 0:
+               REG_UPDATE_2(DSCCLK0_DTO_PARAM,
+                               DSCCLK0_DTO_PHASE, 0,
+                               DSCCLK0_DTO_MODULO, 0);
+               REG_UPDATE(DSCCLK_DTO_CTRL,
+                               DSCCLK0_DTO_ENABLE, 0);
+               break;
+       case 1:
+               REG_UPDATE_2(DSCCLK1_DTO_PARAM,
+                               DSCCLK1_DTO_PHASE, 0,
+                               DSCCLK1_DTO_MODULO, 0);
+               REG_UPDATE(DSCCLK_DTO_CTRL,
+                               DSCCLK1_DTO_ENABLE, 0);
+               break;
+       case 2:
+               REG_UPDATE_2(DSCCLK2_DTO_PARAM,
+                               DSCCLK2_DTO_PHASE, 0,
+                               DSCCLK2_DTO_MODULO, 0);
+               REG_UPDATE(DSCCLK_DTO_CTRL,
+                               DSCCLK2_DTO_ENABLE, 0);
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+}
+
 void dccg31_set_physymclk(
                struct dccg *dccg,
                int phy_inst,
@@ -469,6 +539,8 @@ static const struct dccg_funcs dccg31_funcs = {
        .set_dtbclk_dto = dccg31_set_dtbclk_dto,
        .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
        .set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
+       .disable_dsc = dccg31_disable_dscclk,
+       .enable_dsc = dccg31_enable_dscclk,
 };
 
 struct dccg *dccg31_create(
index 1e5aabc..61b457a 100644 (file)
        SR(DCCG_AUDIO_DTBCLK_DTO_MODULO),\
        SR(DCCG_AUDIO_DTBCLK_DTO_PHASE),\
        SR(DCCG_AUDIO_DTO_SOURCE),\
-       SR(DENTIST_DISPCLK_CNTL)
+       SR(DENTIST_DISPCLK_CNTL),\
+       SR(DSCCLK0_DTO_PARAM),\
+       SR(DSCCLK1_DTO_PARAM),\
+       SR(DSCCLK2_DTO_PARAM),\
+       SR(DSCCLK_DTO_CTRL)
 
 
 #define DCCG_MASK_SH_LIST_DCN31(mask_sh) \
        DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLK_DTO, DIV, 3, mask_sh),\
        DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\
        DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\
-       DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE, mask_sh)
+       DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE, mask_sh), \
+       DCCG_SF(DSCCLK0_DTO_PARAM, DSCCLK0_DTO_PHASE, mask_sh),\
+       DCCG_SF(DSCCLK0_DTO_PARAM, DSCCLK0_DTO_MODULO, mask_sh),\
+       DCCG_SF(DSCCLK1_DTO_PARAM, DSCCLK1_DTO_PHASE, mask_sh),\
+       DCCG_SF(DSCCLK1_DTO_PARAM, DSCCLK1_DTO_MODULO, mask_sh),\
+       DCCG_SF(DSCCLK2_DTO_PARAM, DSCCLK2_DTO_PHASE, mask_sh),\
+       DCCG_SF(DSCCLK2_DTO_PARAM, DSCCLK2_DTO_MODULO, mask_sh),\
+       DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK0_DTO_ENABLE, mask_sh),\
+       DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK1_DTO_ENABLE, mask_sh),\
+       DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK2_DTO_ENABLE, mask_sh)
+
 
 
 struct dccg *dccg31_create(
index 52947c0..fee385e 100644 (file)
@@ -270,6 +270,12 @@ void dcn31_dsc_pg_control(
        if (hws->ctx->dc->debug.disable_dsc_power_gate)
                return;
 
+       if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc &&
+               hws->ctx->dc->res_pool->dccg->funcs->enable_dsc &&
+               power_on)
+               hws->ctx->dc->res_pool->dccg->funcs->enable_dsc(
+                       hws->ctx->dc->res_pool->dccg, dsc_inst);
+
        REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
        if (org_ip_request_cntl == 0)
                REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
@@ -306,6 +312,17 @@ void dcn31_dsc_pg_control(
 
        if (org_ip_request_cntl == 0)
                REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);
+
+       if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc) {
+               if (hws->ctx->dc->res_pool->dccg->funcs->disable_dsc && !power_on)
+                       hws->ctx->dc->res_pool->dccg->funcs->disable_dsc(
+                               hws->ctx->dc->res_pool->dccg, dsc_inst);
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+               dc_z10_save_init(hws->ctx->dc);
+#endif
+       }
+
 }
 
 
index 09237d5..c940fdf 100644 (file)
@@ -123,6 +123,15 @@ struct dccg_funcs {
        void (*set_dispclk_change_mode)(
                        struct dccg *dccg,
                        enum dentist_dispclk_change_mode change_mode);
+
+       void (*disable_dsc)(
+               struct dccg *dccg,
+               int inst);
+
+       void (*enable_dsc)(
+               struct dccg *dccg,
+               int inst);
+
 };
 
 #endif //__DAL_DCCG_H__