linux/drivers/gpu/drm/amd/pm/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                        NULL);
  34}
  35
  36static int smu7_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
  37{
  38        return smum_send_msg_to_smc(hwmgr, enable ?
  39                        PPSMC_MSG_VCEDPM_Enable :
  40                        PPSMC_MSG_VCEDPM_Disable,
  41                        NULL);
  42}
  43
  44static int smu7_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate)
  45{
  46        if (!bgate)
  47                smum_update_smc_table(hwmgr, SMU_UVD_TABLE);
  48        return smu7_enable_disable_uvd_dpm(hwmgr, !bgate);
  49}
  50
  51static int smu7_update_vce_dpm(struct pp_hwmgr *hwmgr, bool bgate)
  52{
  53        if (!bgate)
  54                smum_update_smc_table(hwmgr, SMU_VCE_TABLE);
  55        return smu7_enable_disable_vce_dpm(hwmgr, !bgate);
  56}
  57
  58int smu7_powerdown_uvd(struct pp_hwmgr *hwmgr)
  59{
  60        if (phm_cf_want_uvd_power_gating(hwmgr))
  61                return smum_send_msg_to_smc(hwmgr,
  62                                PPSMC_MSG_UVDPowerOFF,
  63                                NULL);
  64        return 0;
  65}
  66
  67static int smu7_powerup_uvd(struct pp_hwmgr *hwmgr)
  68{
  69        if (phm_cf_want_uvd_power_gating(hwmgr)) {
  70                if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
  71                                  PHM_PlatformCaps_UVDDynamicPowerGating)) {
  72                        return smum_send_msg_to_smc_with_parameter(hwmgr,
  73                                        PPSMC_MSG_UVDPowerON, 1, NULL);
  74                } else {
  75                        return smum_send_msg_to_smc_with_parameter(hwmgr,
  76                                        PPSMC_MSG_UVDPowerON, 0, NULL);
  77                }
  78        }
  79
  80        return 0;
  81}
  82
  83static int smu7_powerdown_vce(struct pp_hwmgr *hwmgr)
  84{
  85        if (phm_cf_want_vce_power_gating(hwmgr))
  86                return smum_send_msg_to_smc(hwmgr,
  87                                PPSMC_MSG_VCEPowerOFF,
  88                                NULL);
  89        return 0;
  90}
  91
  92static int smu7_powerup_vce(struct pp_hwmgr *hwmgr)
  93{
  94        if (phm_cf_want_vce_power_gating(hwmgr))
  95                return smum_send_msg_to_smc(hwmgr,
  96                                PPSMC_MSG_VCEPowerON,
  97                                NULL);
  98        return 0;
  99}
 100
 101int smu7_disable_clock_power_gating(struct pp_hwmgr *hwmgr)
 102{
 103        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
 104
 105        data->uvd_power_gated = false;
 106        data->vce_power_gated = false;
 107
 108        smu7_powerup_uvd(hwmgr);
 109        smu7_powerup_vce(hwmgr);
 110
 111        return 0;
 112}
 113
 114void smu7_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
 115{
 116        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
 117
 118        data->uvd_power_gated = bgate;
 119
 120        if (bgate) {
 121                amdgpu_device_ip_set_powergating_state(hwmgr->adev,
 122                                                AMD_IP_BLOCK_TYPE_UVD,
 123                                                AMD_PG_STATE_GATE);
 124                amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
 125                                AMD_IP_BLOCK_TYPE_UVD,
 126                                AMD_CG_STATE_GATE);
 127                smu7_update_uvd_dpm(hwmgr, true);
 128                smu7_powerdown_uvd(hwmgr);
 129        } else {
 130                smu7_powerup_uvd(hwmgr);
 131                amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
 132                                AMD_IP_BLOCK_TYPE_UVD,
 133                                AMD_CG_STATE_UNGATE);
 134                amdgpu_device_ip_set_powergating_state(hwmgr->adev,
 135                                                AMD_IP_BLOCK_TYPE_UVD,
 136                                                AMD_PG_STATE_UNGATE);
 137                smu7_update_uvd_dpm(hwmgr, false);
 138        }
 139
 140}
 141
 142void smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
 143{
 144        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
 145
 146        data->vce_power_gated = bgate;
 147
 148        if (bgate) {
 149                amdgpu_device_ip_set_powergating_state(hwmgr->adev,
 150                                                AMD_IP_BLOCK_TYPE_VCE,
 151                                                AMD_PG_STATE_GATE);
 152                amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
 153                                AMD_IP_BLOCK_TYPE_VCE,
 154                                AMD_CG_STATE_GATE);
 155                smu7_update_vce_dpm(hwmgr, true);
 156                smu7_powerdown_vce(hwmgr);
 157        } else {
 158                smu7_powerup_vce(hwmgr);
 159                amdgpu_device_ip_set_clockgating_state(hwmgr->adev,
 160                                AMD_IP_BLOCK_TYPE_VCE,
 161                                AMD_CG_STATE_UNGATE);
 162                amdgpu_device_ip_set_powergating_state(hwmgr->adev,
 163                                                AMD_IP_BLOCK_TYPE_VCE,
 164                                                AMD_PG_STATE_UNGATE);
 165                smu7_update_vce_dpm(hwmgr, false);
 166        }
 167}
 168
 169int smu7_update_clock_gatings(struct pp_hwmgr *hwmgr,
 170                                        const uint32_t *msg_id)
 171{
 172        PPSMC_Msg msg;
 173        uint32_t value;
 174
 175        if (!(hwmgr->feature_mask & PP_ENABLE_GFX_CG_THRU_SMU))
 176                return 0;
 177
 178        switch ((*msg_id & PP_GROUP_MASK) >> PP_GROUP_SHIFT) {
 179        case PP_GROUP_GFX:
 180                switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
 181                case PP_BLOCK_GFX_CG:
 182                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 183                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 184                                                PPSMC_MSG_EnableClockGatingFeature :
 185                                                PPSMC_MSG_DisableClockGatingFeature;
 186                                value = CG_GFX_CGCG_MASK;
 187
 188                                if (smum_send_msg_to_smc_with_parameter(
 189                                                hwmgr, msg, value, NULL))
 190                                        return -EINVAL;
 191                        }
 192                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 193                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS
 194                                        ? PPSMC_MSG_EnableClockGatingFeature
 195                                        : PPSMC_MSG_DisableClockGatingFeature;
 196                                value = CG_GFX_CGLS_MASK;
 197
 198                                if (smum_send_msg_to_smc_with_parameter(
 199                                                hwmgr, msg, value, NULL))
 200                                        return -EINVAL;
 201                        }
 202                        break;
 203
 204                case PP_BLOCK_GFX_3D:
 205                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 206                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 207                                                PPSMC_MSG_EnableClockGatingFeature :
 208                                                PPSMC_MSG_DisableClockGatingFeature;
 209                                value = CG_GFX_3DCG_MASK;
 210
 211                                if (smum_send_msg_to_smc_with_parameter(
 212                                                hwmgr, msg, value, NULL))
 213                                        return -EINVAL;
 214                        }
 215
 216                        if  (PP_STATE_SUPPORT_LS & *msg_id) {
 217                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 218                                                PPSMC_MSG_EnableClockGatingFeature :
 219                                                PPSMC_MSG_DisableClockGatingFeature;
 220                                value = CG_GFX_3DLS_MASK;
 221
 222                                if (smum_send_msg_to_smc_with_parameter(
 223                                                hwmgr, msg, value, NULL))
 224                                        return -EINVAL;
 225                        }
 226                        break;
 227
 228                case PP_BLOCK_GFX_RLC:
 229                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 230                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 231                                                PPSMC_MSG_EnableClockGatingFeature :
 232                                                PPSMC_MSG_DisableClockGatingFeature;
 233                                value = CG_GFX_RLC_LS_MASK;
 234
 235                                if (smum_send_msg_to_smc_with_parameter(
 236                                                hwmgr, msg, value, NULL))
 237                                        return -EINVAL;
 238                        }
 239                        break;
 240
 241                case PP_BLOCK_GFX_CP:
 242                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 243                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 244                                                PPSMC_MSG_EnableClockGatingFeature :
 245                                                PPSMC_MSG_DisableClockGatingFeature;
 246                                value = CG_GFX_CP_LS_MASK;
 247
 248                                if (smum_send_msg_to_smc_with_parameter(
 249                                                hwmgr, msg, value, NULL))
 250                                        return -EINVAL;
 251                        }
 252                        break;
 253
 254                case PP_BLOCK_GFX_MG:
 255                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 256                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 257                                                PPSMC_MSG_EnableClockGatingFeature :
 258                                                PPSMC_MSG_DisableClockGatingFeature;
 259                                value = (CG_CPF_MGCG_MASK | CG_RLC_MGCG_MASK |
 260                                                CG_GFX_OTHERS_MGCG_MASK);
 261
 262                                if (smum_send_msg_to_smc_with_parameter(
 263                                                hwmgr, msg, value, NULL))
 264                                        return -EINVAL;
 265                        }
 266                        break;
 267
 268                default:
 269                        return -EINVAL;
 270                }
 271                break;
 272
 273        case PP_GROUP_SYS:
 274                switch ((*msg_id & PP_BLOCK_MASK) >> PP_BLOCK_SHIFT) {
 275                case PP_BLOCK_SYS_BIF:
 276                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 277                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
 278                                                PPSMC_MSG_EnableClockGatingFeature :
 279                                                PPSMC_MSG_DisableClockGatingFeature;
 280                                value = CG_SYS_BIF_MGCG_MASK;
 281
 282                                if (smum_send_msg_to_smc_with_parameter(
 283                                                hwmgr, msg, value, NULL))
 284                                        return -EINVAL;
 285                        }
 286                        if  (PP_STATE_SUPPORT_LS & *msg_id) {
 287                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 288                                                PPSMC_MSG_EnableClockGatingFeature :
 289                                                PPSMC_MSG_DisableClockGatingFeature;
 290                                value = CG_SYS_BIF_MGLS_MASK;
 291
 292                                if (smum_send_msg_to_smc_with_parameter(
 293                                                hwmgr, msg, value, NULL))
 294                                        return -EINVAL;
 295                        }
 296                        break;
 297
 298                case PP_BLOCK_SYS_MC:
 299                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 300                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 301                                                PPSMC_MSG_EnableClockGatingFeature :
 302                                                PPSMC_MSG_DisableClockGatingFeature;
 303                                value = CG_SYS_MC_MGCG_MASK;
 304
 305                                if (smum_send_msg_to_smc_with_parameter(
 306                                                hwmgr, msg, value, NULL))
 307                                        return -EINVAL;
 308                        }
 309
 310                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 311                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 312                                                PPSMC_MSG_EnableClockGatingFeature :
 313                                                PPSMC_MSG_DisableClockGatingFeature;
 314                                value = CG_SYS_MC_MGLS_MASK;
 315
 316                                if (smum_send_msg_to_smc_with_parameter(
 317                                                hwmgr, msg, value, NULL))
 318                                        return -EINVAL;
 319                        }
 320                        break;
 321
 322                case PP_BLOCK_SYS_DRM:
 323                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 324                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_CG ?
 325                                                PPSMC_MSG_EnableClockGatingFeature :
 326                                                PPSMC_MSG_DisableClockGatingFeature;
 327                                value = CG_SYS_DRM_MGCG_MASK;
 328
 329                                if (smum_send_msg_to_smc_with_parameter(
 330                                                hwmgr, msg, value, NULL))
 331                                        return -EINVAL;
 332                        }
 333                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 334                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 335                                                PPSMC_MSG_EnableClockGatingFeature :
 336                                                PPSMC_MSG_DisableClockGatingFeature;
 337                                value = CG_SYS_DRM_MGLS_MASK;
 338
 339                                if (smum_send_msg_to_smc_with_parameter(
 340                                                hwmgr, msg, value, NULL))
 341                                        return -EINVAL;
 342                        }
 343                        break;
 344
 345                case PP_BLOCK_SYS_HDP:
 346                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 347                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 348                                                PPSMC_MSG_EnableClockGatingFeature :
 349                                                PPSMC_MSG_DisableClockGatingFeature;
 350                                value = CG_SYS_HDP_MGCG_MASK;
 351
 352                                if (smum_send_msg_to_smc_with_parameter(
 353                                                hwmgr, msg, value, NULL))
 354                                        return -EINVAL;
 355                        }
 356
 357                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 358                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 359                                                PPSMC_MSG_EnableClockGatingFeature :
 360                                                PPSMC_MSG_DisableClockGatingFeature;
 361                                value = CG_SYS_HDP_MGLS_MASK;
 362
 363                                if (smum_send_msg_to_smc_with_parameter(
 364                                                hwmgr, msg, value, NULL))
 365                                        return -EINVAL;
 366                        }
 367                        break;
 368
 369                case PP_BLOCK_SYS_SDMA:
 370                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 371                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 372                                                PPSMC_MSG_EnableClockGatingFeature :
 373                                                PPSMC_MSG_DisableClockGatingFeature;
 374                                value = CG_SYS_SDMA_MGCG_MASK;
 375
 376                                if (smum_send_msg_to_smc_with_parameter(
 377                                                hwmgr, msg, value, NULL))
 378                                        return -EINVAL;
 379                        }
 380
 381                        if (PP_STATE_SUPPORT_LS & *msg_id) {
 382                                msg = (*msg_id & PP_STATE_MASK) & PP_STATE_LS ?
 383                                                PPSMC_MSG_EnableClockGatingFeature :
 384                                                PPSMC_MSG_DisableClockGatingFeature;
 385                                value = CG_SYS_SDMA_MGLS_MASK;
 386
 387                                if (smum_send_msg_to_smc_with_parameter(
 388                                                hwmgr, msg, value, NULL))
 389                                        return -EINVAL;
 390                        }
 391                        break;
 392
 393                case PP_BLOCK_SYS_ROM:
 394                        if (PP_STATE_SUPPORT_CG & *msg_id) {
 395                                msg = ((*msg_id & PP_STATE_MASK) & PP_STATE_CG) ?
 396                                                PPSMC_MSG_EnableClockGatingFeature :
 397                                                PPSMC_MSG_DisableClockGatingFeature;
 398                                value = CG_SYS_ROM_MASK;
 399
 400                                if (smum_send_msg_to_smc_with_parameter(
 401                                                hwmgr, msg, value, NULL))
 402                                        return -EINVAL;
 403                        }
 404                        break;
 405
 406                default:
 407                        return -EINVAL;
 408
 409                }
 410                break;
 411
 412        default:
 413                return -EINVAL;
 414
 415        }
 416
 417        return 0;
 418}
 419
 420/* This function is for Polaris11 only for now,
 421 * Powerplay will only control the static per CU Power Gating.
 422 * Dynamic per CU Power Gating will be done in gfx.
 423 */
 424int smu7_powergate_gfx(struct pp_hwmgr *hwmgr, bool enable)
 425{
 426        struct amdgpu_device *adev = hwmgr->adev;
 427
 428        if (enable)
 429                return smum_send_msg_to_smc_with_parameter(hwmgr,
 430                                        PPSMC_MSG_GFX_CU_PG_ENABLE,
 431                                        adev->gfx.cu_info.number,
 432                                        NULL);
 433        else
 434                return smum_send_msg_to_smc(hwmgr,
 435                                PPSMC_MSG_GFX_CU_PG_DISABLE,
 436                                NULL);
 437}
 438