drm/amd/powerplay: Add CG and PG support for tonga
authorRex Zhu <Rex.Zhu@amd.com>
Thu, 15 Oct 2015 13:12:58 +0000 (21:12 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 21 Dec 2015 21:42:23 +0000 (16:42 -0500)
Implement clock and power gating support for tonga.  On Tonga
this is handles by the SMU rather than direct register settings
in the driver.

Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/powerplay/hwmgr/Makefile
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_clockpowergating.c [new file with mode: 0644]
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_clockpowergating.h [new file with mode: 0644]
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h

index c78e38c..6f38811 100644 (file)
@@ -7,7 +7,7 @@ HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \
                cz_clockpowergating.o \
               tonga_processpptables.o ppatomctrl.o \
                tonga_hwmgr.o   pppcielanes.o \
-               fiji_powertune.o fiji_hwmgr.o
+               fiji_powertune.o fiji_hwmgr.o tonga_clockpowergating.o
 
 AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR))
 
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_clockpowergating.c
new file mode 100644 (file)
index 0000000..e58d038
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "hwmgr.h"
+#include "tonga_clockpowergating.h"
+#include "tonga_ppsmc.h"
+#include "tonga_hwmgr.h"
+
+int tonga_phm_powerdown_uvd(struct pp_hwmgr *hwmgr)
+{
+       if (phm_cf_want_uvd_power_gating(hwmgr))
+               return smum_send_msg_to_smc(hwmgr->smumgr,
+                                                    PPSMC_MSG_UVDPowerOFF);
+       return 0;
+}
+
+int tonga_phm_powerup_uvd(struct pp_hwmgr *hwmgr)
+{
+       if (phm_cf_want_uvd_power_gating(hwmgr)) {
+               if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+                                 PHM_PlatformCaps_UVDDynamicPowerGating)) {
+                       return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+                                                               PPSMC_MSG_UVDPowerON, 1);
+               } else {
+                       return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+                                                               PPSMC_MSG_UVDPowerON, 0);
+               }
+       }
+
+       return 0;
+}
+
+int tonga_phm_powerdown_vce(struct pp_hwmgr *hwmgr)
+{
+       if (phm_cf_want_vce_power_gating(hwmgr))
+               return smum_send_msg_to_smc(hwmgr->smumgr,
+                                                 PPSMC_MSG_VCEPowerOFF);
+       return 0;
+}
+
+int tonga_phm_powerup_vce(struct pp_hwmgr *hwmgr)
+{
+       if (phm_cf_want_vce_power_gating(hwmgr))
+               return smum_send_msg_to_smc(hwmgr->smumgr,
+                                                 PPSMC_MSG_VCEPowerON);
+       return 0;
+}
+
+int tonga_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating)
+{
+       int ret = 0;
+
+       switch (block) {
+       case PHM_AsicBlock_UVD_MVC:
+       case PHM_AsicBlock_UVD:
+       case PHM_AsicBlock_UVD_HD:
+       case PHM_AsicBlock_UVD_SD:
+               if (gating == PHM_ClockGateSetting_StaticOff)
+                       ret = tonga_phm_powerdown_uvd(hwmgr);
+               else
+                       ret = tonga_phm_powerup_uvd(hwmgr);
+               break;
+       case PHM_AsicBlock_GFX:
+       default:
+               break;
+       }
+
+       return ret;
+}
+
+int tonga_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
+{
+       struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+       data->uvd_power_gated = false;
+       data->vce_power_gated = false;
+
+       tonga_phm_powerup_uvd(hwmgr);
+       tonga_phm_powerup_vce(hwmgr);
+
+       return 0;
+}
+
+int tonga_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
+{
+       struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+
+       if (data->uvd_power_gated == bgate)
+               return 0;
+
+       data->uvd_power_gated = bgate;
+
+       if (bgate) {
+               cgs_set_clockgating_state(hwmgr->device,
+                                               AMD_IP_BLOCK_TYPE_UVD,
+                                               AMD_CG_STATE_UNGATE);
+               cgs_set_powergating_state(hwmgr->device,
+                                               AMD_IP_BLOCK_TYPE_UVD,
+                                               AMD_PG_STATE_GATE);
+               tonga_update_uvd_dpm(hwmgr, true);
+               tonga_phm_powerdown_uvd(hwmgr);
+       } else {
+               tonga_phm_powerup_uvd(hwmgr);
+               cgs_set_powergating_state(hwmgr->device,
+                                               AMD_IP_BLOCK_TYPE_UVD,
+                                               AMD_PG_STATE_UNGATE);
+               cgs_set_clockgating_state(hwmgr->device,
+                                               AMD_IP_BLOCK_TYPE_UVD,
+                                               AMD_PG_STATE_GATE);
+
+               tonga_update_uvd_dpm(hwmgr, false);
+       }
+
+       return 0;
+}
+
+int tonga_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
+{
+       struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+       struct phm_set_power_state_input states;
+       const struct pp_power_state  *pcurrent;
+       struct pp_power_state  *requested;
+
+       pcurrent = hwmgr->current_ps;
+       requested = hwmgr->request_ps;
+
+       states.pcurrent_state = &(pcurrent->hardware);
+       states.pnew_state = &(requested->hardware);
+
+       if (phm_cf_want_vce_power_gating(hwmgr)) {
+               if (data->vce_power_gated != bgate) {
+                       if (bgate) {
+                               cgs_set_clockgating_state(
+                                                       hwmgr->device,
+                                                       AMD_IP_BLOCK_TYPE_VCE,
+                                                       AMD_CG_STATE_UNGATE);
+                               cgs_set_powergating_state(
+                                                       hwmgr->device,
+                                                       AMD_IP_BLOCK_TYPE_VCE,
+                                                       AMD_PG_STATE_GATE);
+                               tonga_enable_disable_vce_dpm(hwmgr, false);
+                               data->vce_power_gated = true;
+                       } else {
+                               tonga_phm_powerup_vce(hwmgr);
+                               data->vce_power_gated = false;
+                               cgs_set_powergating_state(
+                                                       hwmgr->device,
+                                                       AMD_IP_BLOCK_TYPE_VCE,
+                                                       AMD_PG_STATE_UNGATE);
+                               cgs_set_clockgating_state(
+                                                       hwmgr->device,
+                                                       AMD_IP_BLOCK_TYPE_VCE,
+                                                       AMD_PG_STATE_GATE);
+
+                               tonga_update_vce_dpm(hwmgr, &states);
+                               tonga_enable_disable_vce_dpm(hwmgr, true);
+                               return 0;
+                       }
+               }
+       } else {
+               tonga_update_vce_dpm(hwmgr, &states);
+               tonga_enable_disable_vce_dpm(hwmgr, true);
+               return 0;
+       }
+
+       if (!data->vce_power_gated)
+               tonga_update_vce_dpm(hwmgr, &states);
+
+       return 0;
+}
+
+int tonga_phm_update_clock_gatings(struct pp_hwmgr *hwmgr,
+                                       const uint32_t *msg_id)
+{
+       PPSMC_Msg msg;
+       uint32_t value;
+
+       switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
+       case PP_GROUP_GFX:
+               switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
+               case PP_BLOCK_GFX_CG:
+                       if (PP_STATE_SUPPORT_CG & *msg_id) {
+                               msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+                                 ? PPSMC_MSG_EnableClockGatingFeature
+                                 : PPSMC_MSG_DisableClockGatingFeature;
+                               value = CG_GFX_CGCG_MASK;
+
+                               if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+                                       return -1;
+                       }
+                       if (PP_STATE_SUPPORT_LS & *msg_id) {
+                               msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
+                                       ? PPSMC_MSG_EnableClockGatingFeature
+                                       : PPSMC_MSG_DisableClockGatingFeature;
+                               value = CG_GFX_CGLS_MASK;
+
+                               if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+                                       return -1;
+                       }
+                       break;
+
+               case PP_BLOCK_GFX_MG:
+                       /* For GFX MGCG, there are three different ones;
+                        * CPF, RLC, and all others.  CPF MGCG will not be used for Tonga.
+                        * For GFX MGLS, Tonga will not support it.
+                        * */
+                       if (PP_STATE_SUPPORT_CG & *msg_id) {
+                               msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+                               ? PPSMC_MSG_EnableClockGatingFeature
+                               : PPSMC_MSG_DisableClockGatingFeature;
+                               value = (CG_RLC_MGCG_MASK | CG_GFX_OTHERS_MGCG_MASK);
+
+                               if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+                                       return -1;
+                       }
+                       break;
+
+               default:
+                       return -1;
+               }
+               break;
+
+       case PP_GROUP_SYS:
+               switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
+               case PP_BLOCK_SYS_BIF:
+                       if (PP_STATE_SUPPORT_LS & *msg_id) {
+                               msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
+                               ? PPSMC_MSG_EnableClockGatingFeature
+                               : PPSMC_MSG_DisableClockGatingFeature;
+                               value = CG_SYS_BIF_MGLS_MASK;
+
+                               if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+                                       return -1;
+                       }
+                       break;
+
+               case PP_BLOCK_SYS_MC:
+                       if (PP_STATE_SUPPORT_CG & *msg_id) {
+                               msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+                               ? PPSMC_MSG_EnableClockGatingFeature
+                               : PPSMC_MSG_DisableClockGatingFeature;
+                               value = CG_SYS_MC_MGCG_MASK;
+
+                               if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+                                       return -1;
+                       }
+
+                       if (PP_STATE_SUPPORT_LS & *msg_id) {
+                               msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
+                               ? PPSMC_MSG_EnableClockGatingFeature
+                               : PPSMC_MSG_DisableClockGatingFeature;
+                               value = CG_SYS_MC_MGLS_MASK;
+
+                               if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+                                       return -1;
+
+                       }
+                       break;
+
+               case PP_BLOCK_SYS_HDP:
+                       if (PP_STATE_SUPPORT_CG & *msg_id) {
+                               msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+                                       ? PPSMC_MSG_EnableClockGatingFeature
+                                       : PPSMC_MSG_DisableClockGatingFeature;
+                               value = CG_SYS_HDP_MGCG_MASK;
+
+                               if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+                                       return -1;
+                       }
+
+                       if (PP_STATE_SUPPORT_LS & *msg_id) {
+                               msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
+                                       ? PPSMC_MSG_EnableClockGatingFeature
+                                       : PPSMC_MSG_DisableClockGatingFeature;
+
+                               value = CG_SYS_HDP_MGLS_MASK;
+
+                               if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+                                       return -1;
+                       }
+                       break;
+
+               case PP_BLOCK_SYS_SDMA:
+                       if (PP_STATE_SUPPORT_CG & *msg_id) {
+                               msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+                               ? PPSMC_MSG_EnableClockGatingFeature
+                               : PPSMC_MSG_DisableClockGatingFeature;
+                               value = CG_SYS_SDMA_MGCG_MASK;
+
+                               if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+                                       return -1;
+                       }
+
+                       if (PP_STATE_SUPPORT_LS & *msg_id) {
+                               msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
+                               ? PPSMC_MSG_EnableClockGatingFeature
+                               : PPSMC_MSG_DisableClockGatingFeature;
+
+                               value = CG_SYS_SDMA_MGLS_MASK;
+
+                               if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+                                       return -1;
+                       }
+                       break;
+
+               case PP_BLOCK_SYS_ROM:
+                       if (PP_STATE_SUPPORT_CG & *msg_id) {
+                               msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG)
+                               ? PPSMC_MSG_EnableClockGatingFeature
+                               : PPSMC_MSG_DisableClockGatingFeature;
+                               value = CG_SYS_ROM_MASK;
+
+                               if (0 != smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, value))
+                                       return -1;
+                       }
+                       break;
+
+               default:
+                       return -1;
+
+               }
+               break;
+
+       default:
+               return -1;
+
+       }
+
+       return 0;
+}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_clockpowergating.h b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_clockpowergating.h
new file mode 100644 (file)
index 0000000..8bc38cb
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _TONGA_CLOCK_POWER_GATING_H_
+#define _TONGA_CLOCK_POWER_GATING_H_
+
+#include "tonga_hwmgr.h"
+#include "pp_asicblocks.h"
+
+extern int tonga_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating);
+extern int tonga_phm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate);
+extern int tonga_phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate);
+extern int tonga_phm_powerdown_uvd(struct pp_hwmgr *hwmgr);
+extern int tonga_phm_disable_clock_power_gating(struct pp_hwmgr *hwmgr);
+extern int tonga_phm_update_clock_gatings(struct pp_hwmgr *hwmgr, const uint32_t *msg_id);
+#endif /* _TONGA_CLOCK_POWER_GATING_H_ */
index fe8b315..9a7de1f 100644 (file)
@@ -39,6 +39,7 @@
 #include "tonga_dyn_defaults.h"
 #include "smumgr.h"
 #include "tonga_smumgr.h"
+#include "tonga_clockpowergating.h"
 
 #include "smu/smu_7_1_2_d.h"
 #include "smu/smu_7_1_2_sh_mask.h"
@@ -5488,14 +5489,47 @@ static int tonga_generate_dpm_level_enable_mask(struct pp_hwmgr *hwmgr, const vo
        return 0;
 }
 
-static int tonga_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
+int tonga_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
 {
-       return smum_send_msg_to_smc(hwmgr->smumgr, enable?
+       return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
                                  (PPSMC_Msg)PPSMC_MSG_VCEDPM_Enable :
                                  (PPSMC_Msg)PPSMC_MSG_VCEDPM_Disable);
 }
 
-static int tonga_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input)
+int tonga_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
+{
+       return smum_send_msg_to_smc(hwmgr->smumgr, enable ?
+                                 (PPSMC_Msg)PPSMC_MSG_UVDDPM_Enable :
+                                 (PPSMC_Msg)PPSMC_MSG_UVDDPM_Disable);
+}
+
+int tonga_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
+{
+       struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
+       uint32_t mm_boot_level_offset, mm_boot_level_value;
+       struct phm_ppt_v1_information *ptable_information = (struct phm_ppt_v1_information *)(hwmgr->pptable);
+
+       if (!bgate) {
+               data->smc_state_table.UvdBootLevel = (uint8_t) (ptable_information->mm_dep_table->count - 1);
+               mm_boot_level_offset = data->dpm_table_start + offsetof(SMU72_Discrete_DpmTable, UvdBootLevel);
+               mm_boot_level_offset /= 4;
+               mm_boot_level_offset *= 4;
+               mm_boot_level_value = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, mm_boot_level_offset);
+               mm_boot_level_value &= 0x00FFFFFF;
+               mm_boot_level_value |= data->smc_state_table.UvdBootLevel << 24;
+               cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
+
+               if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM) ||
+                   phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
+                       smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+                                               PPSMC_MSG_UVDDPM_SetEnabledMask,
+                                               (uint32_t)(1 << data->smc_state_table.UvdBootLevel));
+       }
+
+       return tonga_enable_disable_uvd_dpm(hwmgr, !bgate);
+}
+
+int tonga_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input)
 {
        const struct phm_set_power_state_input *states = (const struct phm_set_power_state_input *)input;
        struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend);
@@ -5505,8 +5539,7 @@ static int tonga_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input)
        uint32_t mm_boot_level_offset, mm_boot_level_value;
        struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
 
-       if(tonga_nps->vce_clocks.EVCLK >0 &&
-       (tonga_cps == NULL || tonga_cps->vce_clocks.EVCLK == 0)) {
+       if (tonga_nps->vce_clocks.EVCLK > 0 && (tonga_cps == NULL || tonga_cps->vce_clocks.EVCLK == 0)) {
                data->smc_state_table.VceBootLevel = (uint8_t) (pptable_info->mm_dep_table->count - 1);
 
                mm_boot_level_offset = data->dpm_table_start + offsetof(SMU72_Discrete_DpmTable, VceBootLevel);
@@ -5517,16 +5550,14 @@ static int tonga_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input)
                mm_boot_level_value |= data->smc_state_table.VceBootLevel << 16;
                cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, mm_boot_level_offset, mm_boot_level_value);
 
-               if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState)) {
-                               smum_send_msg_to_smc_with_parameter(
-                                                          hwmgr->smumgr,
-                       (PPSMC_Msg)(PPSMC_MSG_VCEDPM_SetEnabledMask),
-                       (uint32_t)1 << data->smc_state_table.VceBootLevel);
+               if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState))
+                       smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+                                       PPSMC_MSG_VCEDPM_SetEnabledMask,
+                               (uint32_t)(1 << data->smc_state_table.VceBootLevel));
 
-                       tonga_enable_disable_vce_dpm(hwmgr, true);
-               } else if (tonga_nps->vce_clocks.EVCLK == 0 && tonga_cps != NULL && tonga_cps->vce_clocks.EVCLK > 0)
-                       tonga_enable_disable_vce_dpm(hwmgr, false);
-       }
+               tonga_enable_disable_vce_dpm(hwmgr, true);
+       } else if (tonga_nps->vce_clocks.EVCLK == 0 && tonga_cps != NULL && tonga_cps->vce_clocks.EVCLK > 0)
+               tonga_enable_disable_vce_dpm(hwmgr, false);
 
        return 0;
 }
@@ -5783,6 +5814,10 @@ static const struct pp_hwmgr_func tonga_hwmgr_funcs = {
        .get_pp_table_entry = tonga_get_pp_table_entry,
        .get_num_of_pp_table_entries = tonga_get_number_of_powerplay_table_entries,
        .print_current_perforce_level = tonga_print_current_perforce_level,
+       .powerdown_uvd = tonga_phm_powerdown_uvd,
+       .powergate_uvd = tonga_phm_powergate_uvd,
+       .powergate_vce = tonga_phm_powergate_vce,
+       .disable_clock_power_gating = tonga_phm_disable_clock_power_gating,
        .notify_smc_display_config_after_ps_adjustment = tonga_notify_smc_display_config_after_ps_adjustment,
        .display_config_changed = tonga_display_configuration_changed_task,
 };
index d007706..c3ac966 100644 (file)
@@ -422,6 +422,10 @@ typedef struct tonga_hwmgr tonga_hwmgr;
 #define CONVERT_FROM_HOST_TO_SMC_US(X) ((X) = PP_HOST_TO_SMC_US(X))
 
 int tonga_hwmgr_init(struct pp_hwmgr *hwmgr);
+int tonga_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input);
+int tonga_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate);
+int tonga_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable);
+int tonga_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable);
 
 #endif