Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2016 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  */
0023 
0024 #include "smu7_hwmgr.h"
0025 #include "smu7_clockpowergating.h"
0026 #include "smu7_common.h"
0027 
0028 static int smu7_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
0029 {
0030     return smum_send_msg_to_smc(hwmgr, enable ?
0031             PPSMC_MSG_UVDDPM_Enable :
0032             PPSMC_MSG_UVDDPM_Disable,
0033             NULL);
0034 }
0035 
0036 static int smu7_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
0037 {
0038     return smum_send_msg_to_smc(hwmgr, enable ?
0039             PPSMC_MSG_VCEDPM_Enable :
0040             PPSMC_MSG_VCEDPM_Disable,
0041             NULL);
0042 }
0043 
0044 static int smu7_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
0045 {
0046     if (!bgate)
0047         smum_update_smc_table(hwmgr, SMU_UVD_TABLE);
0048     return smu7_enable_disable_uvd_dpm(hwmgr, !bgate);
0049 }
0050 
0051 static int smu7_update_vce_dpm(struct pp_hwmgr *hwmgr, bool bgate)
0052 {
0053     if (!bgate)
0054         smum_update_smc_table(hwmgr, SMU_VCE_TABLE);
0055     return smu7_enable_disable_vce_dpm(hwmgr, !bgate);
0056 }
0057 
0058 int smu7_powerdown_uvd(struct pp_hwmgr *hwmgr)
0059 {
0060     if (phm_cf_want_uvd_power_gating(hwmgr))
0061         return smum_send_msg_to_smc(hwmgr,
0062                 PPSMC_MSG_UVDPowerOFF,
0063                 NULL);
0064     return 0;
0065 }
0066 
0067 static int smu7_powerup_uvd(struct pp_hwmgr *hwmgr)
0068 {
0069     if (phm_cf_want_uvd_power_gating(hwmgr)) {
0070         if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
0071                   PHM_PlatformCaps_UVDDynamicPowerGating)) {
0072             return smum_send_msg_to_smc_with_parameter(hwmgr,
0073                     PPSMC_MSG_UVDPowerON, 1, NULL);
0074         } else {
0075             return smum_send_msg_to_smc_with_parameter(hwmgr,
0076                     PPSMC_MSG_UVDPowerON, 0, NULL);
0077         }
0078     }
0079 
0080     return 0;
0081 }
0082 
0083 static int smu7_powerdown_vce(struct pp_hwmgr *hwmgr)
0084 {
0085     if (phm_cf_want_vce_power_gating(hwmgr))
0086         return smum_send_msg_to_smc(hwmgr,
0087                 PPSMC_MSG_VCEPowerOFF,
0088                 NULL);
0089     return 0;
0090 }
0091 
0092 static int smu7_powerup_vce(struct pp_hwmgr *hwmgr)
0093 {
0094     if (phm_cf_want_vce_power_gating(hwmgr))
0095         return smum_send_msg_to_smc(hwmgr,
0096                 PPSMC_MSG_VCEPowerON,
0097                 NULL);
0098     return 0;
0099 }
0100 
0101 int smu7_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
0102 {
0103     struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
0104 
0105     data->uvd_power_gated = false;
0106     data->vce_power_gated = false;
0107 
0108     smu7_powerup_uvd(hwmgr);
0109     smu7_powerup_vce(hwmgr);
0110 
0111     return 0;
0112 }
0113 
0114 void smu7_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
0115 {
0116     struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
0117 
0118     data->uvd_power_gated = bgate;
0119 
0120     if (bgate) {
0121         amdgpu_device_ip_set_powergating_state(hwmgr->adev,
0122                         AMD_IP_BLOCK_TYPE_UVD,
0123                         AMD_PG_STATE_GATE);
0124         amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
0125                 AMD_IP_BLOCK_TYPE_UVD,
0126                 AMD_CG_STATE_GATE);
0127         smu7_update_uvd_dpm(hwmgr, true);
0128         smu7_powerdown_uvd(hwmgr);
0129     } else {
0130         smu7_powerup_uvd(hwmgr);
0131         amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
0132                 AMD_IP_BLOCK_TYPE_UVD,
0133                 AMD_CG_STATE_UNGATE);
0134         amdgpu_device_ip_set_powergating_state(hwmgr->adev,
0135                         AMD_IP_BLOCK_TYPE_UVD,
0136                         AMD_PG_STATE_UNGATE);
0137         smu7_update_uvd_dpm(hwmgr, false);
0138     }
0139 
0140 }
0141 
0142 void smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
0143 {
0144     struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
0145 
0146     data->vce_power_gated = bgate;
0147 
0148     if (bgate) {
0149         amdgpu_device_ip_set_powergating_state(hwmgr->adev,
0150                         AMD_IP_BLOCK_TYPE_VCE,
0151                         AMD_PG_STATE_GATE);
0152         amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
0153                 AMD_IP_BLOCK_TYPE_VCE,
0154                 AMD_CG_STATE_GATE);
0155         smu7_update_vce_dpm(hwmgr, true);
0156         smu7_powerdown_vce(hwmgr);
0157     } else {
0158         smu7_powerup_vce(hwmgr);
0159         amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
0160                 AMD_IP_BLOCK_TYPE_VCE,
0161                 AMD_CG_STATE_UNGATE);
0162         amdgpu_device_ip_set_powergating_state(hwmgr->adev,
0163                         AMD_IP_BLOCK_TYPE_VCE,
0164                         AMD_PG_STATE_UNGATE);
0165         smu7_update_vce_dpm(hwmgr, false);
0166     }
0167 }
0168 
0169 int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
0170                     const uint32_t *msg_id)
0171 {
0172     PPSMC_Msg msg;
0173     uint32_t value;
0174 
0175     if (!(hwmgr->feature_mask & PP_ENABLE_GFX_CG_THRU_SMU))
0176         return 0;
0177 
0178     switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
0179     case PP_GROUP_GFX:
0180         switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
0181         case PP_BLOCK_GFX_CG:
0182             if (PP_STATE_SUPPORT_CG & *msg_id) {
0183                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
0184                         PPSMC_MSG_EnableClockGatingFeature :
0185                         PPSMC_MSG_DisableClockGatingFeature;
0186                 value = CG_GFX_CGCG_MASK;
0187 
0188                 if (smum_send_msg_to_smc_with_parameter(
0189                         hwmgr, msg, value, NULL))
0190                     return -EINVAL;
0191             }
0192             if (PP_STATE_SUPPORT_LS & *msg_id) {
0193                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
0194                     ? PPSMC_MSG_EnableClockGatingFeature
0195                     : PPSMC_MSG_DisableClockGatingFeature;
0196                 value = CG_GFX_CGLS_MASK;
0197 
0198                 if (smum_send_msg_to_smc_with_parameter(
0199                         hwmgr, msg, value, NULL))
0200                     return -EINVAL;
0201             }
0202             break;
0203 
0204         case PP_BLOCK_GFX_3D:
0205             if (PP_STATE_SUPPORT_CG & *msg_id) {
0206                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
0207                         PPSMC_MSG_EnableClockGatingFeature :
0208                         PPSMC_MSG_DisableClockGatingFeature;
0209                 value = CG_GFX_3DCG_MASK;
0210 
0211                 if (smum_send_msg_to_smc_with_parameter(
0212                         hwmgr, msg, value, NULL))
0213                     return -EINVAL;
0214             }
0215 
0216             if  (PP_STATE_SUPPORT_LS & *msg_id) {
0217                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
0218                         PPSMC_MSG_EnableClockGatingFeature :
0219                         PPSMC_MSG_DisableClockGatingFeature;
0220                 value = CG_GFX_3DLS_MASK;
0221 
0222                 if (smum_send_msg_to_smc_with_parameter(
0223                         hwmgr, msg, value, NULL))
0224                     return -EINVAL;
0225             }
0226             break;
0227 
0228         case PP_BLOCK_GFX_RLC:
0229             if (PP_STATE_SUPPORT_LS & *msg_id) {
0230                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
0231                         PPSMC_MSG_EnableClockGatingFeature :
0232                         PPSMC_MSG_DisableClockGatingFeature;
0233                 value = CG_GFX_RLC_LS_MASK;
0234 
0235                 if (smum_send_msg_to_smc_with_parameter(
0236                         hwmgr, msg, value, NULL))
0237                     return -EINVAL;
0238             }
0239             break;
0240 
0241         case PP_BLOCK_GFX_CP:
0242             if (PP_STATE_SUPPORT_LS & *msg_id) {
0243                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
0244                         PPSMC_MSG_EnableClockGatingFeature :
0245                         PPSMC_MSG_DisableClockGatingFeature;
0246                 value = CG_GFX_CP_LS_MASK;
0247 
0248                 if (smum_send_msg_to_smc_with_parameter(
0249                         hwmgr, msg, value, NULL))
0250                     return -EINVAL;
0251             }
0252             break;
0253 
0254         case PP_BLOCK_GFX_MG:
0255             if (PP_STATE_SUPPORT_CG & *msg_id) {
0256                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
0257                         PPSMC_MSG_EnableClockGatingFeature :
0258                         PPSMC_MSG_DisableClockGatingFeature;
0259                 value = (CG_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
0260                         CG_GFX_OTHERS_MGCG_MASK);
0261 
0262                 if (smum_send_msg_to_smc_with_parameter(
0263                         hwmgr, msg, value, NULL))
0264                     return -EINVAL;
0265             }
0266             break;
0267 
0268         default:
0269             return -EINVAL;
0270         }
0271         break;
0272 
0273     case PP_GROUP_SYS:
0274         switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
0275         case PP_BLOCK_SYS_BIF:
0276             if (PP_STATE_SUPPORT_CG & *msg_id) {
0277                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
0278                         PPSMC_MSG_EnableClockGatingFeature :
0279                         PPSMC_MSG_DisableClockGatingFeature;
0280                 value = CG_SYS_BIF_MGCG_MASK;
0281 
0282                 if (smum_send_msg_to_smc_with_parameter(
0283                         hwmgr, msg, value, NULL))
0284                     return -EINVAL;
0285             }
0286             if  (PP_STATE_SUPPORT_LS & *msg_id) {
0287                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
0288                         PPSMC_MSG_EnableClockGatingFeature :
0289                         PPSMC_MSG_DisableClockGatingFeature;
0290                 value = CG_SYS_BIF_MGLS_MASK;
0291 
0292                 if (smum_send_msg_to_smc_with_parameter(
0293                         hwmgr, msg, value, NULL))
0294                     return -EINVAL;
0295             }
0296             break;
0297 
0298         case PP_BLOCK_SYS_MC:
0299             if (PP_STATE_SUPPORT_CG & *msg_id) {
0300                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
0301                         PPSMC_MSG_EnableClockGatingFeature :
0302                         PPSMC_MSG_DisableClockGatingFeature;
0303                 value = CG_SYS_MC_MGCG_MASK;
0304 
0305                 if (smum_send_msg_to_smc_with_parameter(
0306                         hwmgr, msg, value, NULL))
0307                     return -EINVAL;
0308             }
0309 
0310             if (PP_STATE_SUPPORT_LS & *msg_id) {
0311                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
0312                         PPSMC_MSG_EnableClockGatingFeature :
0313                         PPSMC_MSG_DisableClockGatingFeature;
0314                 value = CG_SYS_MC_MGLS_MASK;
0315 
0316                 if (smum_send_msg_to_smc_with_parameter(
0317                         hwmgr, msg, value, NULL))
0318                     return -EINVAL;
0319             }
0320             break;
0321 
0322         case PP_BLOCK_SYS_DRM:
0323             if (PP_STATE_SUPPORT_CG & *msg_id) {
0324                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
0325                         PPSMC_MSG_EnableClockGatingFeature :
0326                         PPSMC_MSG_DisableClockGatingFeature;
0327                 value = CG_SYS_DRM_MGCG_MASK;
0328 
0329                 if (smum_send_msg_to_smc_with_parameter(
0330                         hwmgr, msg, value, NULL))
0331                     return -EINVAL;
0332             }
0333             if (PP_STATE_SUPPORT_LS & *msg_id) {
0334                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
0335                         PPSMC_MSG_EnableClockGatingFeature :
0336                         PPSMC_MSG_DisableClockGatingFeature;
0337                 value = CG_SYS_DRM_MGLS_MASK;
0338 
0339                 if (smum_send_msg_to_smc_with_parameter(
0340                         hwmgr, msg, value, NULL))
0341                     return -EINVAL;
0342             }
0343             break;
0344 
0345         case PP_BLOCK_SYS_HDP:
0346             if (PP_STATE_SUPPORT_CG & *msg_id) {
0347                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
0348                         PPSMC_MSG_EnableClockGatingFeature :
0349                         PPSMC_MSG_DisableClockGatingFeature;
0350                 value = CG_SYS_HDP_MGCG_MASK;
0351 
0352                 if (smum_send_msg_to_smc_with_parameter(
0353                         hwmgr, msg, value, NULL))
0354                     return -EINVAL;
0355             }
0356 
0357             if (PP_STATE_SUPPORT_LS & *msg_id) {
0358                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
0359                         PPSMC_MSG_EnableClockGatingFeature :
0360                         PPSMC_MSG_DisableClockGatingFeature;
0361                 value = CG_SYS_HDP_MGLS_MASK;
0362 
0363                 if (smum_send_msg_to_smc_with_parameter(
0364                         hwmgr, msg, value, NULL))
0365                     return -EINVAL;
0366             }
0367             break;
0368 
0369         case PP_BLOCK_SYS_SDMA:
0370             if (PP_STATE_SUPPORT_CG & *msg_id) {
0371                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
0372                         PPSMC_MSG_EnableClockGatingFeature :
0373                         PPSMC_MSG_DisableClockGatingFeature;
0374                 value = CG_SYS_SDMA_MGCG_MASK;
0375 
0376                 if (smum_send_msg_to_smc_with_parameter(
0377                         hwmgr, msg, value, NULL))
0378                     return -EINVAL;
0379             }
0380 
0381             if (PP_STATE_SUPPORT_LS & *msg_id) {
0382                 msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
0383                         PPSMC_MSG_EnableClockGatingFeature :
0384                         PPSMC_MSG_DisableClockGatingFeature;
0385                 value = CG_SYS_SDMA_MGLS_MASK;
0386 
0387                 if (smum_send_msg_to_smc_with_parameter(
0388                         hwmgr, msg, value, NULL))
0389                     return -EINVAL;
0390             }
0391             break;
0392 
0393         case PP_BLOCK_SYS_ROM:
0394             if (PP_STATE_SUPPORT_CG & *msg_id) {
0395                 msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
0396                         PPSMC_MSG_EnableClockGatingFeature :
0397                         PPSMC_MSG_DisableClockGatingFeature;
0398                 value = CG_SYS_ROM_MASK;
0399 
0400                 if (smum_send_msg_to_smc_with_parameter(
0401                         hwmgr, msg, value, NULL))
0402                     return -EINVAL;
0403             }
0404             break;
0405 
0406         default:
0407             return -EINVAL;
0408 
0409         }
0410         break;
0411 
0412     default:
0413         return -EINVAL;
0414 
0415     }
0416 
0417     return 0;
0418 }
0419 
0420 /* This function is for Polaris11 only for now,
0421  * Powerplay will only control the static per CU Power Gating.
0422  * Dynamic per CU Power Gating will be done in gfx.
0423  */
0424 int smu7_powergate_gfx(struct pp_hwmgr *hwmgr, bool enable)
0425 {
0426     struct amdgpu_device *adev = hwmgr->adev;
0427 
0428     if (enable)
0429         return smum_send_msg_to_smc_with_parameter(hwmgr,
0430                     PPSMC_MSG_GFX_CU_PG_ENABLE,
0431                     adev->gfx.cu_info.number,
0432                     NULL);
0433     else
0434         return smum_send_msg_to_smc(hwmgr,
0435                 PPSMC_MSG_GFX_CU_PG_DISABLE,
0436                 NULL);
0437 }