linux/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c
<<
>>
Prefs
   1/*
   2 * Copyright 2016 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 */
  23
  24#include "smu7_hwmgr.h"
  25#include "smu7_clockpowergating.h"
  26#include "smu7_common.h"
  27
  28static int smu7_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
  29{
  30        return smum_send_msg_to_smc(hwmgr, enable ?
  31                        PPSMC_MSG_UVDDPM_Enable :
  32                        PPSMC_MSG_UVDDPM_Disable);
  33}
  34
  35static int smu7_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
  36{
  37        return smum_send_msg_to_smc(hwmgr, enable ?
  38                        PPSMC_MSG_VCEDPM_Enable :
  39                        PPSMC_MSG_VCEDPM_Disable);
  40}
  41
  42static int smu7_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
  43{
  44        if (!bgate)
  45                smum_update_smc_table(hwmgr, SMU_UVD_TABLE);
  46        return smu7_enable_disable_uvd_dpm(hwmgr, !bgate);
  47}
  48
  49static int smu7_update_vce_dpm(struct pp_hwmgr *hwmgr, bool bgate)
  50{
  51        if (!bgate)
  52                smum_update_smc_table(hwmgr, SMU_VCE_TABLE);
  53        return smu7_enable_disable_vce_dpm(hwmgr, !bgate);
  54}
  55
  56int smu7_powerdown_uvd(struct pp_hwmgr *hwmgr)
  57{
  58        if (phm_cf_want_uvd_power_gating(hwmgr))
  59                return smum_send_msg_to_smc(hwmgr,
  60                                PPSMC_MSG_UVDPowerOFF);
  61        return 0;
  62}
  63
  64static int smu7_powerup_uvd(struct pp_hwmgr *hwmgr)
  65{
  66        if (phm_cf_want_uvd_power_gating(hwmgr)) {
  67                if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
  68                                  PHM_PlatformCaps_UVDDynamicPowerGating)) {
  69                        return smum_send_msg_to_smc_with_parameter(hwmgr,
  70                                        PPSMC_MSG_UVDPowerON, 1);
  71                } else {
  72                        return smum_send_msg_to_smc_with_parameter(hwmgr,
  73                                        PPSMC_MSG_UVDPowerON, 0);
  74                }
  75        }
  76
  77        return 0;
  78}
  79
  80static int smu7_powerdown_vce(struct pp_hwmgr *hwmgr)
  81{
  82        if (phm_cf_want_vce_power_gating(hwmgr))
  83                return smum_send_msg_to_smc(hwmgr,
  84                                PPSMC_MSG_VCEPowerOFF);
  85        return 0;
  86}
  87
  88static int smu7_powerup_vce(struct pp_hwmgr *hwmgr)
  89{
  90        if (phm_cf_want_vce_power_gating(hwmgr))
  91                return smum_send_msg_to_smc(hwmgr,
  92                                PPSMC_MSG_VCEPowerON);
  93        return 0;
  94}
  95
  96int smu7_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
  97{
  98        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
  99
 100        data->uvd_power_gated = false;
 101        data->vce_power_gated = false;
 102
 103        smu7_powerup_uvd(hwmgr);
 104        smu7_powerup_vce(hwmgr);
 105
 106        return 0;
 107}
 108
 109void smu7_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
 110{
 111        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
 112
 113        data->uvd_power_gated = bgate;
 114
 115        if (bgate) {
 116                amdgpu_device_ip_set_powergating_state(hwmgr->adev,
 117                                                AMD_IP_BLOCK_TYPE_UVD,
 118                                                AMD_PG_STATE_GATE);
 119                amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
 120                                AMD_IP_BLOCK_TYPE_UVD,
 121                                AMD_CG_STATE_GATE);
 122                smu7_update_uvd_dpm(hwmgr, true);
 123                smu7_powerdown_uvd(hwmgr);
 124        } else {
 125                smu7_powerup_uvd(hwmgr);
 126                amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
 127                                AMD_IP_BLOCK_TYPE_UVD,
 128                                AMD_CG_STATE_UNGATE);
 129                amdgpu_device_ip_set_powergating_state(hwmgr->adev,
 130                                                AMD_IP_BLOCK_TYPE_UVD,
 131                                                AMD_PG_STATE_UNGATE);
 132                smu7_update_uvd_dpm(hwmgr, false);
 133        }
 134
 135}
 136
 137void smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
 138{
 139        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
 140
 141        data->vce_power_gated = bgate;
 142
 143        if (bgate) {
 144                amdgpu_device_ip_set_powergating_state(hwmgr->adev,
 145                                                AMD_IP_BLOCK_TYPE_VCE,
 146                                                AMD_PG_STATE_GATE);
 147                amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
 148                                AMD_IP_BLOCK_TYPE_VCE,
 149                                AMD_CG_STATE_GATE);
 150                smu7_update_vce_dpm(hwmgr, true);
 151                smu7_powerdown_vce(hwmgr);
 152        } else {
 153                smu7_powerup_vce(hwmgr);
 154                amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
 155                                AMD_IP_BLOCK_TYPE_VCE,
 156                                AMD_CG_STATE_UNGATE);
 157                amdgpu_device_ip_set_powergating_state(hwmgr->adev,
 158                                                AMD_IP_BLOCK_TYPE_VCE,
 159                                                AMD_PG_STATE_UNGATE);
 160                smu7_update_vce_dpm(hwmgr, false);
 161        }
 162}
 163
 164int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 165                                        const uint32_t *msg_id)
 166{
 167        PPSMC_Msg msg;
 168        uint32_t value;
 169
 170        if (!(hwmgr->feature_mask & PP_ENABLE_GFX_CG_THRU_SMU))
 171                return 0;
 172
 173        switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
 174        case PP_GROUP_GFX:
 175                switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
 176                case PP_BLOCK_GFX_CG:
 177                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 178                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 179                                                PPSMC_MSG_EnableClockGatingFeature :
 180                                                PPSMC_MSG_DisableClockGatingFeature;
 181                                value = CG_GFX_CGCG_MASK;
 182
 183                                if (smum_send_msg_to_smc_with_parameter(
 184                                                hwmgr, msg, value))
 185                                        return -EINVAL;
 186                        }
 187                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 188                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
 189                                        ? PPSMC_MSG_EnableClockGatingFeature
 190                                        : PPSMC_MSG_DisableClockGatingFeature;
 191                                value = CG_GFX_CGLS_MASK;
 192
 193                                if (smum_send_msg_to_smc_with_parameter(
 194                                                hwmgr, msg, value))
 195                                        return -EINVAL;
 196                        }
 197                        break;
 198
 199                case PP_BLOCK_GFX_3D:
 200                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 201                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 202                                                PPSMC_MSG_EnableClockGatingFeature :
 203                                                PPSMC_MSG_DisableClockGatingFeature;
 204                                value = CG_GFX_3DCG_MASK;
 205
 206                                if (smum_send_msg_to_smc_with_parameter(
 207                                                hwmgr, msg, value))
 208                                        return -EINVAL;
 209                        }
 210
 211                        if  (PP_STATE_SUPPORT_LS & *msg_id) {
 212                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 213                                                PPSMC_MSG_EnableClockGatingFeature :
 214                                                PPSMC_MSG_DisableClockGatingFeature;
 215                                value = CG_GFX_3DLS_MASK;
 216
 217                                if (smum_send_msg_to_smc_with_parameter(
 218                                                hwmgr, msg, value))
 219                                        return -EINVAL;
 220                        }
 221                        break;
 222
 223                case PP_BLOCK_GFX_RLC:
 224                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 225                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 226                                                PPSMC_MSG_EnableClockGatingFeature :
 227                                                PPSMC_MSG_DisableClockGatingFeature;
 228                                value = CG_GFX_RLC_LS_MASK;
 229
 230                                if (smum_send_msg_to_smc_with_parameter(
 231                                                hwmgr, msg, value))
 232                                        return -EINVAL;
 233                        }
 234                        break;
 235
 236                case PP_BLOCK_GFX_CP:
 237                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 238                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 239                                                PPSMC_MSG_EnableClockGatingFeature :
 240                                                PPSMC_MSG_DisableClockGatingFeature;
 241                                value = CG_GFX_CP_LS_MASK;
 242
 243                                if (smum_send_msg_to_smc_with_parameter(
 244                                                hwmgr, msg, value))
 245                                        return -EINVAL;
 246                        }
 247                        break;
 248
 249                case PP_BLOCK_GFX_MG:
 250                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 251                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 252                                                PPSMC_MSG_EnableClockGatingFeature :
 253                                                PPSMC_MSG_DisableClockGatingFeature;
 254                                value = (CG_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
 255                                                CG_GFX_OTHERS_MGCG_MASK);
 256
 257                                if (smum_send_msg_to_smc_with_parameter(
 258                                                hwmgr, msg, value))
 259                                        return -EINVAL;
 260                        }
 261                        break;
 262
 263                default:
 264                        return -EINVAL;
 265                }
 266                break;
 267
 268        case PP_GROUP_SYS:
 269                switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
 270                case PP_BLOCK_SYS_BIF:
 271                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 272                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
 273                                                PPSMC_MSG_EnableClockGatingFeature :
 274                                                PPSMC_MSG_DisableClockGatingFeature;
 275                                value = CG_SYS_BIF_MGCG_MASK;
 276
 277                                if (smum_send_msg_to_smc_with_parameter(
 278                                                hwmgr, msg, value))
 279                                        return -EINVAL;
 280                        }
 281                        if  (PP_STATE_SUPPORT_LS & *msg_id) {
 282                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 283                                                PPSMC_MSG_EnableClockGatingFeature :
 284                                                PPSMC_MSG_DisableClockGatingFeature;
 285                                value = CG_SYS_BIF_MGLS_MASK;
 286
 287                                if (smum_send_msg_to_smc_with_parameter(
 288                                                hwmgr, msg, value))
 289                                        return -EINVAL;
 290                        }
 291                        break;
 292
 293                case PP_BLOCK_SYS_MC:
 294                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 295                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 296                                                PPSMC_MSG_EnableClockGatingFeature :
 297                                                PPSMC_MSG_DisableClockGatingFeature;
 298                                value = CG_SYS_MC_MGCG_MASK;
 299
 300                                if (smum_send_msg_to_smc_with_parameter(
 301                                                hwmgr, msg, value))
 302                                        return -EINVAL;
 303                        }
 304
 305                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 306                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 307                                                PPSMC_MSG_EnableClockGatingFeature :
 308                                                PPSMC_MSG_DisableClockGatingFeature;
 309                                value = CG_SYS_MC_MGLS_MASK;
 310
 311                                if (smum_send_msg_to_smc_with_parameter(
 312                                                hwmgr, msg, value))
 313                                        return -EINVAL;
 314                        }
 315                        break;
 316
 317                case PP_BLOCK_SYS_DRM:
 318                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 319                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
 320                                                PPSMC_MSG_EnableClockGatingFeature :
 321                                                PPSMC_MSG_DisableClockGatingFeature;
 322                                value = CG_SYS_DRM_MGCG_MASK;
 323
 324                                if (smum_send_msg_to_smc_with_parameter(
 325                                                hwmgr, msg, value))
 326                                        return -EINVAL;
 327                        }
 328                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 329                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 330                                                PPSMC_MSG_EnableClockGatingFeature :
 331                                                PPSMC_MSG_DisableClockGatingFeature;
 332                                value = CG_SYS_DRM_MGLS_MASK;
 333
 334                                if (smum_send_msg_to_smc_with_parameter(
 335                                                hwmgr, msg, value))
 336                                        return -EINVAL;
 337                        }
 338                        break;
 339
 340                case PP_BLOCK_SYS_HDP:
 341                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 342                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 343                                                PPSMC_MSG_EnableClockGatingFeature :
 344                                                PPSMC_MSG_DisableClockGatingFeature;
 345                                value = CG_SYS_HDP_MGCG_MASK;
 346
 347                                if (smum_send_msg_to_smc_with_parameter(
 348                                                hwmgr, msg, value))
 349                                        return -EINVAL;
 350                        }
 351
 352                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 353                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 354                                                PPSMC_MSG_EnableClockGatingFeature :
 355                                                PPSMC_MSG_DisableClockGatingFeature;
 356                                value = CG_SYS_HDP_MGLS_MASK;
 357
 358                                if (smum_send_msg_to_smc_with_parameter(
 359                                                hwmgr, msg, value))
 360                                        return -EINVAL;
 361                        }
 362                        break;
 363
 364                case PP_BLOCK_SYS_SDMA:
 365                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 366                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 367                                                PPSMC_MSG_EnableClockGatingFeature :
 368                                                PPSMC_MSG_DisableClockGatingFeature;
 369                                value = CG_SYS_SDMA_MGCG_MASK;
 370
 371                                if (smum_send_msg_to_smc_with_parameter(
 372                                                hwmgr, msg, value))
 373                                        return -EINVAL;
 374                        }
 375
 376                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 377                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 378                                                PPSMC_MSG_EnableClockGatingFeature :
 379                                                PPSMC_MSG_DisableClockGatingFeature;
 380                                value = CG_SYS_SDMA_MGLS_MASK;
 381
 382                                if (smum_send_msg_to_smc_with_parameter(
 383                                                hwmgr, msg, value))
 384                                        return -EINVAL;
 385                        }
 386                        break;
 387
 388                case PP_BLOCK_SYS_ROM:
 389                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 390                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 391                                                PPSMC_MSG_EnableClockGatingFeature :
 392                                                PPSMC_MSG_DisableClockGatingFeature;
 393                                value = CG_SYS_ROM_MASK;
 394
 395                                if (smum_send_msg_to_smc_with_parameter(
 396                                                hwmgr, msg, value))
 397                                        return -EINVAL;
 398                        }
 399                        break;
 400
 401                default:
 402                        return -EINVAL;
 403
 404                }
 405                break;
 406
 407        default:
 408                return -EINVAL;
 409
 410        }
 411
 412        return 0;
 413}
 414
 415/* This function is for Polaris11 only for now,
 416 * Powerplay will only control the static per CU Power Gating.
 417 * Dynamic per CU Power Gating will be done in gfx.
 418 */
 419int smu7_powergate_gfx(struct pp_hwmgr *hwmgr, bool enable)
 420{
 421        struct amdgpu_device *adev = hwmgr->adev;
 422
 423        if (enable)
 424                return smum_send_msg_to_smc_with_parameter(hwmgr,
 425                                        PPSMC_MSG_GFX_CU_PG_ENABLE,
 426                                        adev->gfx.cu_info.number);
 427        else
 428                return smum_send_msg_to_smc(hwmgr,
 429                                PPSMC_MSG_GFX_CU_PG_DISABLE);
 430}
 431