cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

smu7_clockpowergating.c (11880B)


      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}