1f46a221bSXiaojian Du /* 2f46a221bSXiaojian Du * Copyright 2020 Advanced Micro Devices, Inc. 3f46a221bSXiaojian Du * 4f46a221bSXiaojian Du * Permission is hereby granted, free of charge, to any person obtaining a 5f46a221bSXiaojian Du * copy of this software and associated documentation files (the "Software"), 6f46a221bSXiaojian Du * to deal in the Software without restriction, including without limitation 7f46a221bSXiaojian Du * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8f46a221bSXiaojian Du * and/or sell copies of the Software, and to permit persons to whom the 9f46a221bSXiaojian Du * Software is furnished to do so, subject to the following conditions: 10f46a221bSXiaojian Du * 11f46a221bSXiaojian Du * The above copyright notice and this permission notice shall be included in 12f46a221bSXiaojian Du * all copies or substantial portions of the Software. 13f46a221bSXiaojian Du * 14f46a221bSXiaojian Du * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15f46a221bSXiaojian Du * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16f46a221bSXiaojian Du * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17f46a221bSXiaojian Du * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18f46a221bSXiaojian Du * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19f46a221bSXiaojian Du * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20f46a221bSXiaojian Du * OTHER DEALINGS IN THE SOFTWARE. 21f46a221bSXiaojian Du * 22f46a221bSXiaojian Du */ 23f46a221bSXiaojian Du 24f46a221bSXiaojian Du #define SWSMU_CODE_LAYER_L2 25f46a221bSXiaojian Du 26f46a221bSXiaojian Du #include "amdgpu.h" 27f46a221bSXiaojian Du #include "amdgpu_smu.h" 28f46a221bSXiaojian Du #include "smu_v11_0.h" 29f46a221bSXiaojian Du #include "smu11_driver_if_vangogh.h" 30f46a221bSXiaojian Du #include "vangogh_ppt.h" 31f46a221bSXiaojian Du #include "smu_v11_5_ppsmc.h" 32f46a221bSXiaojian Du #include "smu_v11_5_pmfw.h" 33f46a221bSXiaojian Du #include "smu_cmn.h" 34f46a221bSXiaojian Du 35f46a221bSXiaojian Du /* 36f46a221bSXiaojian Du * DO NOT use these for err/warn/info/debug messages. 37f46a221bSXiaojian Du * Use dev_err, dev_warn, dev_info and dev_dbg instead. 38f46a221bSXiaojian Du * They are more MGPU friendly. 39f46a221bSXiaojian Du */ 40f46a221bSXiaojian Du #undef pr_err 41f46a221bSXiaojian Du #undef pr_warn 42f46a221bSXiaojian Du #undef pr_info 43f46a221bSXiaojian Du #undef pr_debug 44f46a221bSXiaojian Du 45f46a221bSXiaojian Du #define FEATURE_MASK(feature) (1ULL << feature) 46f46a221bSXiaojian Du #define SMC_DPM_FEATURE ( \ 47f46a221bSXiaojian Du FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ 48f46a221bSXiaojian Du FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ 49f46a221bSXiaojian Du FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ 50f46a221bSXiaojian Du FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT) | \ 51f46a221bSXiaojian Du FEATURE_MASK(FEATURE_MP0CLK_DPM_BIT) | \ 52f46a221bSXiaojian Du FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ 53f46a221bSXiaojian Du FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT) | \ 54f46a221bSXiaojian Du FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT)| \ 55271ab489SXiaojian Du FEATURE_MASK(FEATURE_GFX_DPM_BIT)) 56f46a221bSXiaojian Du 57f46a221bSXiaojian Du static struct cmn2asic_msg_mapping vangogh_message_map[SMU_MSG_MAX_COUNT] = { 58271ab489SXiaojian Du MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), 59271ab489SXiaojian Du MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 0), 60271ab489SXiaojian Du MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 0), 61271ab489SXiaojian Du MSG_MAP(EnableGfxOff, PPSMC_MSG_EnableGfxOff, 0), 62271ab489SXiaojian Du MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisableGfxOff, 0), 63271ab489SXiaojian Du MSG_MAP(PowerDownIspByTile, PPSMC_MSG_PowerDownIspByTile, 0), 64271ab489SXiaojian Du MSG_MAP(PowerUpIspByTile, PPSMC_MSG_PowerUpIspByTile, 0), 65271ab489SXiaojian Du MSG_MAP(PowerDownVcn, PPSMC_MSG_PowerDownVcn, 0), 66271ab489SXiaojian Du MSG_MAP(PowerUpVcn, PPSMC_MSG_PowerUpVcn, 0), 67a0f55287SXiaomeng Hou MSG_MAP(RlcPowerNotify, PPSMC_MSG_RlcPowerNotify, 0), 68271ab489SXiaojian Du MSG_MAP(SetHardMinVcn, PPSMC_MSG_SetHardMinVcn, 0), 69271ab489SXiaojian Du MSG_MAP(SetSoftMinGfxclk, PPSMC_MSG_SetSoftMinGfxclk, 0), 70271ab489SXiaojian Du MSG_MAP(ActiveProcessNotify, PPSMC_MSG_ActiveProcessNotify, 0), 71271ab489SXiaojian Du MSG_MAP(SetHardMinIspiclkByFreq, PPSMC_MSG_SetHardMinIspiclkByFreq, 0), 72271ab489SXiaojian Du MSG_MAP(SetHardMinIspxclkByFreq, PPSMC_MSG_SetHardMinIspxclkByFreq, 0), 73271ab489SXiaojian Du MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 0), 74271ab489SXiaojian Du MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 0), 75271ab489SXiaojian Du MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 0), 76271ab489SXiaojian Du MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 0), 77271ab489SXiaojian Du MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDeviceDriverReset, 0), 78271ab489SXiaojian Du MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 0), 79271ab489SXiaojian Du MSG_MAP(Spare1, PPSMC_MSG_spare1, 0), 80271ab489SXiaojian Du MSG_MAP(SetHardMinSocclkByFreq, PPSMC_MSG_SetHardMinSocclkByFreq, 0), 81271ab489SXiaojian Du MSG_MAP(SetSoftMinFclk, PPSMC_MSG_SetSoftMinFclk, 0), 82271ab489SXiaojian Du MSG_MAP(SetSoftMinVcn, PPSMC_MSG_SetSoftMinVcn, 0), 83271ab489SXiaojian Du MSG_MAP(EnablePostCode, PPSMC_MSG_EnablePostCode, 0), 84271ab489SXiaojian Du MSG_MAP(GetGfxclkFrequency, PPSMC_MSG_GetGfxclkFrequency, 0), 85271ab489SXiaojian Du MSG_MAP(GetFclkFrequency, PPSMC_MSG_GetFclkFrequency, 0), 86271ab489SXiaojian Du MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 0), 87271ab489SXiaojian Du MSG_MAP(SetHardMinGfxClk, PPSMC_MSG_SetHardMinGfxClk, 0), 88271ab489SXiaojian Du MSG_MAP(SetSoftMaxSocclkByFreq, PPSMC_MSG_SetSoftMaxSocclkByFreq, 0), 89271ab489SXiaojian Du MSG_MAP(SetSoftMaxFclkByFreq, PPSMC_MSG_SetSoftMaxFclkByFreq, 0), 90271ab489SXiaojian Du MSG_MAP(SetSoftMaxVcn, PPSMC_MSG_SetSoftMaxVcn, 0), 91271ab489SXiaojian Du MSG_MAP(Spare2, PPSMC_MSG_spare2, 0), 92271ab489SXiaojian Du MSG_MAP(SetPowerLimitPercentage, PPSMC_MSG_SetPowerLimitPercentage, 0), 93271ab489SXiaojian Du MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg, 0), 94271ab489SXiaojian Du MSG_MAP(PowerUpJpeg, PPSMC_MSG_PowerUpJpeg, 0), 95271ab489SXiaojian Du MSG_MAP(SetHardMinFclkByFreq, PPSMC_MSG_SetHardMinFclkByFreq, 0), 96271ab489SXiaojian Du MSG_MAP(SetSoftMinSocclkByFreq, PPSMC_MSG_SetSoftMinSocclkByFreq, 0), 97271ab489SXiaojian Du MSG_MAP(PowerUpCvip, PPSMC_MSG_PowerUpCvip, 0), 98271ab489SXiaojian Du MSG_MAP(PowerDownCvip, PPSMC_MSG_PowerDownCvip, 0), 99271ab489SXiaojian Du MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit, 0), 100271ab489SXiaojian Du MSG_MAP(GetThermalLimit, PPSMC_MSG_GetThermalLimit, 0), 101271ab489SXiaojian Du MSG_MAP(GetCurrentTemperature, PPSMC_MSG_GetCurrentTemperature, 0), 102271ab489SXiaojian Du MSG_MAP(GetCurrentPower, PPSMC_MSG_GetCurrentPower, 0), 103271ab489SXiaojian Du MSG_MAP(GetCurrentVoltage, PPSMC_MSG_GetCurrentVoltage, 0), 104271ab489SXiaojian Du MSG_MAP(GetCurrentCurrent, PPSMC_MSG_GetCurrentCurrent, 0), 105271ab489SXiaojian Du MSG_MAP(GetAverageCpuActivity, PPSMC_MSG_GetAverageCpuActivity, 0), 106271ab489SXiaojian Du MSG_MAP(GetAverageGfxActivity, PPSMC_MSG_GetAverageGfxActivity, 0), 107271ab489SXiaojian Du MSG_MAP(GetAveragePower, PPSMC_MSG_GetAveragePower, 0), 108271ab489SXiaojian Du MSG_MAP(GetAverageTemperature, PPSMC_MSG_GetAverageTemperature, 0), 109271ab489SXiaojian Du MSG_MAP(SetAveragePowerTimeConstant, PPSMC_MSG_SetAveragePowerTimeConstant, 0), 110271ab489SXiaojian Du MSG_MAP(SetAverageActivityTimeConstant, PPSMC_MSG_SetAverageActivityTimeConstant, 0), 111271ab489SXiaojian Du MSG_MAP(SetAverageTemperatureTimeConstant, PPSMC_MSG_SetAverageTemperatureTimeConstant, 0), 112271ab489SXiaojian Du MSG_MAP(SetMitigationEndHysteresis, PPSMC_MSG_SetMitigationEndHysteresis, 0), 113271ab489SXiaojian Du MSG_MAP(GetCurrentFreq, PPSMC_MSG_GetCurrentFreq, 0), 114271ab489SXiaojian Du MSG_MAP(SetReducedPptLimit, PPSMC_MSG_SetReducedPptLimit, 0), 115271ab489SXiaojian Du MSG_MAP(SetReducedThermalLimit, PPSMC_MSG_SetReducedThermalLimit, 0), 116271ab489SXiaojian Du MSG_MAP(DramLogSetDramAddr, PPSMC_MSG_DramLogSetDramAddr, 0), 117271ab489SXiaojian Du MSG_MAP(StartDramLogging, PPSMC_MSG_StartDramLogging, 0), 118271ab489SXiaojian Du MSG_MAP(StopDramLogging, PPSMC_MSG_StopDramLogging, 0), 119271ab489SXiaojian Du MSG_MAP(SetSoftMinCclk, PPSMC_MSG_SetSoftMinCclk, 0), 120271ab489SXiaojian Du MSG_MAP(SetSoftMaxCclk, PPSMC_MSG_SetSoftMaxCclk, 0), 121f46a221bSXiaojian Du }; 122f46a221bSXiaojian Du 123f46a221bSXiaojian Du static struct cmn2asic_mapping vangogh_feature_mask_map[SMU_FEATURE_COUNT] = { 124f46a221bSXiaojian Du FEA_MAP(PPT), 125f46a221bSXiaojian Du FEA_MAP(TDC), 126f46a221bSXiaojian Du FEA_MAP(THERMAL), 127f46a221bSXiaojian Du FEA_MAP(DS_GFXCLK), 128f46a221bSXiaojian Du FEA_MAP(DS_SOCCLK), 129f46a221bSXiaojian Du FEA_MAP(DS_LCLK), 130f46a221bSXiaojian Du FEA_MAP(DS_FCLK), 131f46a221bSXiaojian Du FEA_MAP(DS_MP1CLK), 132f46a221bSXiaojian Du FEA_MAP(DS_MP0CLK), 133f46a221bSXiaojian Du FEA_MAP(ATHUB_PG), 134f46a221bSXiaojian Du FEA_MAP(CCLK_DPM), 135f46a221bSXiaojian Du FEA_MAP(FAN_CONTROLLER), 136f46a221bSXiaojian Du FEA_MAP(ULV), 137f46a221bSXiaojian Du FEA_MAP(VCN_DPM), 138f46a221bSXiaojian Du FEA_MAP(LCLK_DPM), 139f46a221bSXiaojian Du FEA_MAP(SHUBCLK_DPM), 140f46a221bSXiaojian Du FEA_MAP(DCFCLK_DPM), 141f46a221bSXiaojian Du FEA_MAP(DS_DCFCLK), 142f46a221bSXiaojian Du FEA_MAP(S0I2), 143f46a221bSXiaojian Du FEA_MAP(SMU_LOW_POWER), 144f46a221bSXiaojian Du FEA_MAP(GFX_DEM), 145f46a221bSXiaojian Du FEA_MAP(PSI), 146f46a221bSXiaojian Du FEA_MAP(PROCHOT), 147f46a221bSXiaojian Du FEA_MAP(CPUOFF), 148f46a221bSXiaojian Du FEA_MAP(STAPM), 149f46a221bSXiaojian Du FEA_MAP(S0I3), 150f46a221bSXiaojian Du FEA_MAP(DF_CSTATES), 151f46a221bSXiaojian Du FEA_MAP(PERF_LIMIT), 152f46a221bSXiaojian Du FEA_MAP(CORE_DLDO), 153f46a221bSXiaojian Du FEA_MAP(RSMU_LOW_POWER), 154f46a221bSXiaojian Du FEA_MAP(SMN_LOW_POWER), 155f46a221bSXiaojian Du FEA_MAP(THM_LOW_POWER), 156f46a221bSXiaojian Du FEA_MAP(SMUIO_LOW_POWER), 157f46a221bSXiaojian Du FEA_MAP(MP1_LOW_POWER), 158f46a221bSXiaojian Du FEA_MAP(DS_VCN), 159f46a221bSXiaojian Du FEA_MAP(CPPC), 160f46a221bSXiaojian Du FEA_MAP(OS_CSTATES), 161f46a221bSXiaojian Du FEA_MAP(ISP_DPM), 162f46a221bSXiaojian Du FEA_MAP(A55_DPM), 163f46a221bSXiaojian Du FEA_MAP(CVIP_DSP_DPM), 164f46a221bSXiaojian Du FEA_MAP(MSMU_LOW_POWER), 165f46a221bSXiaojian Du }; 166f46a221bSXiaojian Du 167f46a221bSXiaojian Du static struct cmn2asic_mapping vangogh_table_map[SMU_TABLE_COUNT] = { 168f46a221bSXiaojian Du TAB_MAP_VALID(WATERMARKS), 169f46a221bSXiaojian Du TAB_MAP_VALID(SMU_METRICS), 170f46a221bSXiaojian Du TAB_MAP_VALID(CUSTOM_DPM), 171f46a221bSXiaojian Du TAB_MAP_VALID(DPMCLOCKS), 172f46a221bSXiaojian Du }; 173f46a221bSXiaojian Du 174f46a221bSXiaojian Du static int vangogh_tables_init(struct smu_context *smu) 175f46a221bSXiaojian Du { 176f46a221bSXiaojian Du struct smu_table_context *smu_table = &smu->smu_table; 177f46a221bSXiaojian Du struct smu_table *tables = smu_table->tables; 178f46a221bSXiaojian Du 179f46a221bSXiaojian Du SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t), 180f46a221bSXiaojian Du PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 181f46a221bSXiaojian Du SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), 182f46a221bSXiaojian Du PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 183f46a221bSXiaojian Du SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t), 184f46a221bSXiaojian Du PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 185f46a221bSXiaojian Du SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE, 186f46a221bSXiaojian Du PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 187f46a221bSXiaojian Du SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF, sizeof(DpmActivityMonitorCoeffExt_t), 188f46a221bSXiaojian Du PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 189f46a221bSXiaojian Du smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); 190f46a221bSXiaojian Du if (!smu_table->metrics_table) 191f46a221bSXiaojian Du goto err0_out; 192f46a221bSXiaojian Du smu_table->metrics_time = 0; 193f46a221bSXiaojian Du 194f46a221bSXiaojian Du smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_0); 195f46a221bSXiaojian Du smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); 196f46a221bSXiaojian Du if (!smu_table->gpu_metrics_table) 197f46a221bSXiaojian Du goto err1_out; 198f46a221bSXiaojian Du 199f46a221bSXiaojian Du smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); 200f46a221bSXiaojian Du if (!smu_table->watermarks_table) 201f46a221bSXiaojian Du goto err2_out; 202f46a221bSXiaojian Du 203c98ee897SXiaojian Du smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); 204c98ee897SXiaojian Du if (!smu_table->clocks_table) 205c98ee897SXiaojian Du goto err3_out; 206c98ee897SXiaojian Du 207f46a221bSXiaojian Du return 0; 208f46a221bSXiaojian Du 209c98ee897SXiaojian Du err3_out: 210c98ee897SXiaojian Du kfree(smu_table->clocks_table); 211f46a221bSXiaojian Du err2_out: 212f46a221bSXiaojian Du kfree(smu_table->gpu_metrics_table); 213f46a221bSXiaojian Du err1_out: 214f46a221bSXiaojian Du kfree(smu_table->metrics_table); 215f46a221bSXiaojian Du err0_out: 216f46a221bSXiaojian Du return -ENOMEM; 217f46a221bSXiaojian Du } 218f46a221bSXiaojian Du 219271ab489SXiaojian Du static int vangogh_get_smu_metrics_data(struct smu_context *smu, 220271ab489SXiaojian Du MetricsMember_t member, 221271ab489SXiaojian Du uint32_t *value) 222271ab489SXiaojian Du { 223271ab489SXiaojian Du struct smu_table_context *smu_table = &smu->smu_table; 224271ab489SXiaojian Du 225271ab489SXiaojian Du SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; 226271ab489SXiaojian Du int ret = 0; 227271ab489SXiaojian Du 228271ab489SXiaojian Du mutex_lock(&smu->metrics_lock); 229271ab489SXiaojian Du 230271ab489SXiaojian Du ret = smu_cmn_get_metrics_table_locked(smu, 231271ab489SXiaojian Du NULL, 232271ab489SXiaojian Du false); 233271ab489SXiaojian Du if (ret) { 234271ab489SXiaojian Du mutex_unlock(&smu->metrics_lock); 235271ab489SXiaojian Du return ret; 236271ab489SXiaojian Du } 237271ab489SXiaojian Du 238271ab489SXiaojian Du switch (member) { 239271ab489SXiaojian Du case METRICS_AVERAGE_GFXCLK: 240271ab489SXiaojian Du *value = metrics->GfxclkFrequency; 241271ab489SXiaojian Du break; 242271ab489SXiaojian Du case METRICS_AVERAGE_SOCCLK: 243271ab489SXiaojian Du *value = metrics->SocclkFrequency; 244271ab489SXiaojian Du break; 245271ab489SXiaojian Du case METRICS_AVERAGE_UCLK: 246271ab489SXiaojian Du *value = metrics->MemclkFrequency; 247271ab489SXiaojian Du break; 248271ab489SXiaojian Du case METRICS_AVERAGE_GFXACTIVITY: 249271ab489SXiaojian Du *value = metrics->GfxActivity / 100; 250271ab489SXiaojian Du break; 251271ab489SXiaojian Du case METRICS_AVERAGE_VCNACTIVITY: 252271ab489SXiaojian Du *value = metrics->UvdActivity; 253271ab489SXiaojian Du break; 254271ab489SXiaojian Du case METRICS_AVERAGE_SOCKETPOWER: 255271ab489SXiaojian Du *value = metrics->CurrentSocketPower; 256271ab489SXiaojian Du break; 257271ab489SXiaojian Du case METRICS_TEMPERATURE_EDGE: 258271ab489SXiaojian Du *value = metrics->GfxTemperature / 100 * 259271ab489SXiaojian Du SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 260271ab489SXiaojian Du break; 261271ab489SXiaojian Du case METRICS_TEMPERATURE_HOTSPOT: 262271ab489SXiaojian Du *value = metrics->SocTemperature / 100 * 263271ab489SXiaojian Du SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 264271ab489SXiaojian Du break; 265271ab489SXiaojian Du case METRICS_THROTTLER_STATUS: 266271ab489SXiaojian Du *value = metrics->ThrottlerStatus; 267271ab489SXiaojian Du break; 2682139d12bSAlex Deucher case METRICS_VOLTAGE_VDDGFX: 2692139d12bSAlex Deucher *value = metrics->Voltage[2]; 2702139d12bSAlex Deucher break; 2712139d12bSAlex Deucher case METRICS_VOLTAGE_VDDSOC: 2722139d12bSAlex Deucher *value = metrics->Voltage[1]; 2732139d12bSAlex Deucher break; 274271ab489SXiaojian Du default: 275271ab489SXiaojian Du *value = UINT_MAX; 276271ab489SXiaojian Du break; 277271ab489SXiaojian Du } 278271ab489SXiaojian Du 279271ab489SXiaojian Du mutex_unlock(&smu->metrics_lock); 280271ab489SXiaojian Du 281271ab489SXiaojian Du return ret; 282271ab489SXiaojian Du } 283271ab489SXiaojian Du 284f46a221bSXiaojian Du static int vangogh_allocate_dpm_context(struct smu_context *smu) 285f46a221bSXiaojian Du { 286f46a221bSXiaojian Du struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 287f46a221bSXiaojian Du 288f46a221bSXiaojian Du smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context), 289f46a221bSXiaojian Du GFP_KERNEL); 290f46a221bSXiaojian Du if (!smu_dpm->dpm_context) 291f46a221bSXiaojian Du return -ENOMEM; 292f46a221bSXiaojian Du 293f46a221bSXiaojian Du smu_dpm->dpm_context_size = sizeof(struct smu_11_0_dpm_context); 294f46a221bSXiaojian Du 295f46a221bSXiaojian Du return 0; 296f46a221bSXiaojian Du } 297f46a221bSXiaojian Du 298f46a221bSXiaojian Du static int vangogh_init_smc_tables(struct smu_context *smu) 299f46a221bSXiaojian Du { 300f46a221bSXiaojian Du int ret = 0; 301f46a221bSXiaojian Du 302f46a221bSXiaojian Du ret = vangogh_tables_init(smu); 303f46a221bSXiaojian Du if (ret) 304f46a221bSXiaojian Du return ret; 305f46a221bSXiaojian Du 306f46a221bSXiaojian Du ret = vangogh_allocate_dpm_context(smu); 307f46a221bSXiaojian Du if (ret) 308f46a221bSXiaojian Du return ret; 309f46a221bSXiaojian Du 310f46a221bSXiaojian Du return smu_v11_0_init_smc_tables(smu); 311f46a221bSXiaojian Du } 312f46a221bSXiaojian Du 313f46a221bSXiaojian Du static int vangogh_dpm_set_vcn_enable(struct smu_context *smu, bool enable) 314f46a221bSXiaojian Du { 315f46a221bSXiaojian Du int ret = 0; 316f46a221bSXiaojian Du 317f46a221bSXiaojian Du if (enable) { 318f46a221bSXiaojian Du /* vcn dpm on is a prerequisite for vcn power gate messages */ 319271ab489SXiaojian Du if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { 320f46a221bSXiaojian Du ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL); 321f46a221bSXiaojian Du if (ret) 322f46a221bSXiaojian Du return ret; 323f46a221bSXiaojian Du } 324f46a221bSXiaojian Du } else { 325271ab489SXiaojian Du if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { 326f46a221bSXiaojian Du ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL); 327f46a221bSXiaojian Du if (ret) 328f46a221bSXiaojian Du return ret; 329f46a221bSXiaojian Du } 330f46a221bSXiaojian Du } 331f46a221bSXiaojian Du 332f46a221bSXiaojian Du return ret; 333f46a221bSXiaojian Du } 334f46a221bSXiaojian Du 335f46a221bSXiaojian Du static int vangogh_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) 336f46a221bSXiaojian Du { 337f46a221bSXiaojian Du int ret = 0; 338f46a221bSXiaojian Du 339f46a221bSXiaojian Du if (enable) { 340271ab489SXiaojian Du if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) { 341f46a221bSXiaojian Du ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpJpeg, 0, NULL); 342f46a221bSXiaojian Du if (ret) 343f46a221bSXiaojian Du return ret; 344f46a221bSXiaojian Du } 345f46a221bSXiaojian Du } else { 346271ab489SXiaojian Du if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) { 347f46a221bSXiaojian Du ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL); 348f46a221bSXiaojian Du if (ret) 349f46a221bSXiaojian Du return ret; 350f46a221bSXiaojian Du } 351f46a221bSXiaojian Du } 352f46a221bSXiaojian Du 353f46a221bSXiaojian Du return ret; 354f46a221bSXiaojian Du } 355f46a221bSXiaojian Du 356f46a221bSXiaojian Du static int vangogh_get_allowed_feature_mask(struct smu_context *smu, 357f46a221bSXiaojian Du uint32_t *feature_mask, 358f46a221bSXiaojian Du uint32_t num) 359f46a221bSXiaojian Du { 360f46a221bSXiaojian Du struct amdgpu_device *adev = smu->adev; 361f46a221bSXiaojian Du 362f46a221bSXiaojian Du if (num > 2) 363f46a221bSXiaojian Du return -EINVAL; 364f46a221bSXiaojian Du 365f46a221bSXiaojian Du memset(feature_mask, 0, sizeof(uint32_t) * num); 366f46a221bSXiaojian Du 367f46a221bSXiaojian Du *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_DPM_BIT) 368f46a221bSXiaojian Du | FEATURE_MASK(FEATURE_MP0CLK_DPM_BIT) 369f46a221bSXiaojian Du | FEATURE_MASK(FEATURE_DS_SOCCLK_BIT) 370f46a221bSXiaojian Du | FEATURE_MASK(FEATURE_PPT_BIT) 371f46a221bSXiaojian Du | FEATURE_MASK(FEATURE_TDC_BIT) 372f46a221bSXiaojian Du | FEATURE_MASK(FEATURE_FAN_CONTROLLER_BIT) 373f46a221bSXiaojian Du | FEATURE_MASK(FEATURE_DS_LCLK_BIT) 374f46a221bSXiaojian Du | FEATURE_MASK(FEATURE_DS_DCFCLK_BIT); 375f46a221bSXiaojian Du 376f46a221bSXiaojian Du if (adev->pm.pp_feature & PP_SOCCLK_DPM_MASK) 377f46a221bSXiaojian Du *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT); 378f46a221bSXiaojian Du 379f46a221bSXiaojian Du if (adev->pm.pp_feature & PP_DCEFCLK_DPM_MASK) 380f46a221bSXiaojian Du *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT); 381f46a221bSXiaojian Du 382f46a221bSXiaojian Du if (smu->adev->pg_flags & AMD_PG_SUPPORT_ATHUB) 383f46a221bSXiaojian Du *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ATHUB_PG_BIT); 384f46a221bSXiaojian Du 385f46a221bSXiaojian Du return 0; 386f46a221bSXiaojian Du } 387f46a221bSXiaojian Du 388f46a221bSXiaojian Du static bool vangogh_is_dpm_running(struct smu_context *smu) 389f46a221bSXiaojian Du { 390271ab489SXiaojian Du int ret = 0; 391271ab489SXiaojian Du uint32_t feature_mask[2]; 392271ab489SXiaojian Du uint64_t feature_enabled; 393f46a221bSXiaojian Du 394271ab489SXiaojian Du ret = smu_cmn_get_enabled_32_bits_mask(smu, feature_mask, 2); 395271ab489SXiaojian Du 396271ab489SXiaojian Du if (ret) 397f46a221bSXiaojian Du return false; 398f46a221bSXiaojian Du 399271ab489SXiaojian Du feature_enabled = (unsigned long)((uint64_t)feature_mask[0] | 400271ab489SXiaojian Du ((uint64_t)feature_mask[1] << 32)); 401271ab489SXiaojian Du 402271ab489SXiaojian Du return !!(feature_enabled & SMC_DPM_FEATURE); 403271ab489SXiaojian Du } 404271ab489SXiaojian Du 405c98ee897SXiaojian Du static int vangogh_print_fine_grain_clk(struct smu_context *smu, 406c98ee897SXiaojian Du enum smu_clk_type clk_type, char *buf) 407c98ee897SXiaojian Du { 408c98ee897SXiaojian Du int size = 0; 409c98ee897SXiaojian Du 410c98ee897SXiaojian Du switch (clk_type) { 411c98ee897SXiaojian Du case SMU_OD_SCLK: 412c98ee897SXiaojian Du if (smu->od_enabled) { 413c98ee897SXiaojian Du size = sprintf(buf, "%s:\n", "OD_SCLK"); 414c98ee897SXiaojian Du size += sprintf(buf + size, "0: %10uMhz\n", 415c98ee897SXiaojian Du (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); 416c98ee897SXiaojian Du size += sprintf(buf + size, "1: %10uMhz\n", 417c98ee897SXiaojian Du (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); 418c98ee897SXiaojian Du } 419c98ee897SXiaojian Du break; 420c98ee897SXiaojian Du case SMU_OD_RANGE: 421c98ee897SXiaojian Du if (smu->od_enabled) { 422c98ee897SXiaojian Du size = sprintf(buf, "%s:\n", "OD_RANGE"); 423c98ee897SXiaojian Du size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n", 424c98ee897SXiaojian Du smu->gfx_default_hard_min_freq, smu->gfx_default_soft_max_freq); 425c98ee897SXiaojian Du } 426c98ee897SXiaojian Du break; 427c98ee897SXiaojian Du default: 428c98ee897SXiaojian Du break; 429c98ee897SXiaojian Du } 430c98ee897SXiaojian Du 431c98ee897SXiaojian Du return size; 432c98ee897SXiaojian Du } 433c98ee897SXiaojian Du 434271ab489SXiaojian Du static int vangogh_read_sensor(struct smu_context *smu, 435271ab489SXiaojian Du enum amd_pp_sensors sensor, 436271ab489SXiaojian Du void *data, uint32_t *size) 437271ab489SXiaojian Du { 438271ab489SXiaojian Du int ret = 0; 439271ab489SXiaojian Du 440271ab489SXiaojian Du if (!data || !size) 441271ab489SXiaojian Du return -EINVAL; 442271ab489SXiaojian Du 443271ab489SXiaojian Du mutex_lock(&smu->sensor_lock); 444271ab489SXiaojian Du switch (sensor) { 445271ab489SXiaojian Du case AMDGPU_PP_SENSOR_GPU_LOAD: 4466cc24d8dSAlex Deucher ret = vangogh_get_smu_metrics_data(smu, 4476cc24d8dSAlex Deucher METRICS_AVERAGE_GFXACTIVITY, 4486cc24d8dSAlex Deucher (uint32_t *)data); 449271ab489SXiaojian Du *size = 4; 450271ab489SXiaojian Du break; 451271ab489SXiaojian Du case AMDGPU_PP_SENSOR_GPU_POWER: 4526cc24d8dSAlex Deucher ret = vangogh_get_smu_metrics_data(smu, 4536cc24d8dSAlex Deucher METRICS_AVERAGE_SOCKETPOWER, 4546cc24d8dSAlex Deucher (uint32_t *)data); 455271ab489SXiaojian Du *size = 4; 456271ab489SXiaojian Du break; 457271ab489SXiaojian Du case AMDGPU_PP_SENSOR_EDGE_TEMP: 4586cc24d8dSAlex Deucher ret = vangogh_get_smu_metrics_data(smu, 4596cc24d8dSAlex Deucher METRICS_TEMPERATURE_EDGE, 4606cc24d8dSAlex Deucher (uint32_t *)data); 4616cc24d8dSAlex Deucher *size = 4; 4626cc24d8dSAlex Deucher break; 463271ab489SXiaojian Du case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: 4646cc24d8dSAlex Deucher ret = vangogh_get_smu_metrics_data(smu, 4656cc24d8dSAlex Deucher METRICS_TEMPERATURE_HOTSPOT, 4666cc24d8dSAlex Deucher (uint32_t *)data); 467271ab489SXiaojian Du *size = 4; 468271ab489SXiaojian Du break; 469271ab489SXiaojian Du case AMDGPU_PP_SENSOR_GFX_MCLK: 4706cc24d8dSAlex Deucher ret = vangogh_get_smu_metrics_data(smu, 4716cc24d8dSAlex Deucher METRICS_AVERAGE_UCLK, 4726cc24d8dSAlex Deucher (uint32_t *)data); 473271ab489SXiaojian Du *(uint32_t *)data *= 100; 474271ab489SXiaojian Du *size = 4; 475271ab489SXiaojian Du break; 476271ab489SXiaojian Du case AMDGPU_PP_SENSOR_GFX_SCLK: 4776cc24d8dSAlex Deucher ret = vangogh_get_smu_metrics_data(smu, 4786cc24d8dSAlex Deucher METRICS_AVERAGE_GFXCLK, 4796cc24d8dSAlex Deucher (uint32_t *)data); 480271ab489SXiaojian Du *(uint32_t *)data *= 100; 481271ab489SXiaojian Du *size = 4; 482271ab489SXiaojian Du break; 483271ab489SXiaojian Du case AMDGPU_PP_SENSOR_VDDGFX: 4842139d12bSAlex Deucher ret = vangogh_get_smu_metrics_data(smu, 4852139d12bSAlex Deucher METRICS_VOLTAGE_VDDGFX, 4862139d12bSAlex Deucher (uint32_t *)data); 4872139d12bSAlex Deucher *size = 4; 4882139d12bSAlex Deucher break; 4892139d12bSAlex Deucher case AMDGPU_PP_SENSOR_VDDNB: 4902139d12bSAlex Deucher ret = vangogh_get_smu_metrics_data(smu, 4912139d12bSAlex Deucher METRICS_VOLTAGE_VDDSOC, 4922139d12bSAlex Deucher (uint32_t *)data); 493271ab489SXiaojian Du *size = 4; 494271ab489SXiaojian Du break; 495271ab489SXiaojian Du default: 496271ab489SXiaojian Du ret = -EOPNOTSUPP; 497271ab489SXiaojian Du break; 498271ab489SXiaojian Du } 499271ab489SXiaojian Du mutex_unlock(&smu->sensor_lock); 500271ab489SXiaojian Du 501271ab489SXiaojian Du return ret; 502271ab489SXiaojian Du } 503271ab489SXiaojian Du 504271ab489SXiaojian Du static int vangogh_set_watermarks_table(struct smu_context *smu, 505271ab489SXiaojian Du struct pp_smu_wm_range_sets *clock_ranges) 506271ab489SXiaojian Du { 507271ab489SXiaojian Du int i; 508271ab489SXiaojian Du int ret = 0; 509271ab489SXiaojian Du Watermarks_t *table = smu->smu_table.watermarks_table; 510271ab489SXiaojian Du 511271ab489SXiaojian Du if (!table || !clock_ranges) 512271ab489SXiaojian Du return -EINVAL; 513271ab489SXiaojian Du 514271ab489SXiaojian Du if (clock_ranges) { 515271ab489SXiaojian Du if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES || 516271ab489SXiaojian Du clock_ranges->num_writer_wm_sets > NUM_WM_RANGES) 517271ab489SXiaojian Du return -EINVAL; 518271ab489SXiaojian Du 519271ab489SXiaojian Du for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) { 520271ab489SXiaojian Du table->WatermarkRow[WM_DCFCLK][i].MinClock = 521271ab489SXiaojian Du clock_ranges->reader_wm_sets[i].min_drain_clk_mhz; 522271ab489SXiaojian Du table->WatermarkRow[WM_DCFCLK][i].MaxClock = 523271ab489SXiaojian Du clock_ranges->reader_wm_sets[i].max_drain_clk_mhz; 524271ab489SXiaojian Du table->WatermarkRow[WM_DCFCLK][i].MinMclk = 525271ab489SXiaojian Du clock_ranges->reader_wm_sets[i].min_fill_clk_mhz; 526271ab489SXiaojian Du table->WatermarkRow[WM_DCFCLK][i].MaxMclk = 527271ab489SXiaojian Du clock_ranges->reader_wm_sets[i].max_fill_clk_mhz; 528271ab489SXiaojian Du 529271ab489SXiaojian Du table->WatermarkRow[WM_DCFCLK][i].WmSetting = 530271ab489SXiaojian Du clock_ranges->reader_wm_sets[i].wm_inst; 531271ab489SXiaojian Du } 532271ab489SXiaojian Du 533271ab489SXiaojian Du for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) { 534271ab489SXiaojian Du table->WatermarkRow[WM_SOCCLK][i].MinClock = 535271ab489SXiaojian Du clock_ranges->writer_wm_sets[i].min_fill_clk_mhz; 536271ab489SXiaojian Du table->WatermarkRow[WM_SOCCLK][i].MaxClock = 537271ab489SXiaojian Du clock_ranges->writer_wm_sets[i].max_fill_clk_mhz; 538271ab489SXiaojian Du table->WatermarkRow[WM_SOCCLK][i].MinMclk = 539271ab489SXiaojian Du clock_ranges->writer_wm_sets[i].min_drain_clk_mhz; 540271ab489SXiaojian Du table->WatermarkRow[WM_SOCCLK][i].MaxMclk = 541271ab489SXiaojian Du clock_ranges->writer_wm_sets[i].max_drain_clk_mhz; 542271ab489SXiaojian Du 543271ab489SXiaojian Du table->WatermarkRow[WM_SOCCLK][i].WmSetting = 544271ab489SXiaojian Du clock_ranges->writer_wm_sets[i].wm_inst; 545271ab489SXiaojian Du } 546271ab489SXiaojian Du 547271ab489SXiaojian Du smu->watermarks_bitmap |= WATERMARKS_EXIST; 548271ab489SXiaojian Du } 549271ab489SXiaojian Du 550271ab489SXiaojian Du /* pass data to smu controller */ 551271ab489SXiaojian Du if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && 552271ab489SXiaojian Du !(smu->watermarks_bitmap & WATERMARKS_LOADED)) { 553271ab489SXiaojian Du ret = smu_cmn_write_watermarks_table(smu); 554271ab489SXiaojian Du if (ret) { 555271ab489SXiaojian Du dev_err(smu->adev->dev, "Failed to update WMTABLE!"); 556271ab489SXiaojian Du return ret; 557271ab489SXiaojian Du } 558271ab489SXiaojian Du smu->watermarks_bitmap |= WATERMARKS_LOADED; 559271ab489SXiaojian Du } 560271ab489SXiaojian Du 561271ab489SXiaojian Du return 0; 562f46a221bSXiaojian Du } 563f46a221bSXiaojian Du 564fd253334SXiaojian Du static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu, 565fd253334SXiaojian Du void **table) 566fd253334SXiaojian Du { 567fd253334SXiaojian Du struct smu_table_context *smu_table = &smu->smu_table; 568fd253334SXiaojian Du struct gpu_metrics_v2_0 *gpu_metrics = 569fd253334SXiaojian Du (struct gpu_metrics_v2_0 *)smu_table->gpu_metrics_table; 570fd253334SXiaojian Du SmuMetrics_t metrics; 571fd253334SXiaojian Du int ret = 0; 572fd253334SXiaojian Du 573fd253334SXiaojian Du ret = smu_cmn_get_metrics_table(smu, &metrics, true); 574fd253334SXiaojian Du if (ret) 575fd253334SXiaojian Du return ret; 576fd253334SXiaojian Du 577fd253334SXiaojian Du smu_v11_0_init_gpu_metrics_v2_0(gpu_metrics); 578fd253334SXiaojian Du 579fd253334SXiaojian Du gpu_metrics->temperature_gfx = metrics.GfxTemperature; 580fd253334SXiaojian Du gpu_metrics->temperature_soc = metrics.SocTemperature; 581fd253334SXiaojian Du memcpy(&gpu_metrics->temperature_core[0], 582fd253334SXiaojian Du &metrics.CoreTemperature[0], 583fd253334SXiaojian Du sizeof(uint16_t) * 8); 584fd253334SXiaojian Du gpu_metrics->temperature_l3[0] = metrics.L3Temperature[0]; 585fd253334SXiaojian Du gpu_metrics->temperature_l3[1] = metrics.L3Temperature[1]; 586fd253334SXiaojian Du 587fd253334SXiaojian Du gpu_metrics->average_gfx_activity = metrics.GfxActivity; 588fd253334SXiaojian Du gpu_metrics->average_mm_activity = metrics.UvdActivity; 589fd253334SXiaojian Du 590fd253334SXiaojian Du gpu_metrics->average_socket_power = metrics.CurrentSocketPower; 591fd253334SXiaojian Du gpu_metrics->average_cpu_power = metrics.Power[0]; 592fd253334SXiaojian Du gpu_metrics->average_soc_power = metrics.Power[1]; 593fd253334SXiaojian Du memcpy(&gpu_metrics->average_core_power[0], 594fd253334SXiaojian Du &metrics.CorePower[0], 595fd253334SXiaojian Du sizeof(uint16_t) * 8); 596fd253334SXiaojian Du 597fd253334SXiaojian Du gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency; 598fd253334SXiaojian Du gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency; 599fd253334SXiaojian Du gpu_metrics->average_fclk_frequency = metrics.MemclkFrequency; 600fd253334SXiaojian Du gpu_metrics->average_vclk_frequency = metrics.VclkFrequency; 601fd253334SXiaojian Du 602fd253334SXiaojian Du memcpy(&gpu_metrics->current_coreclk[0], 603fd253334SXiaojian Du &metrics.CoreFrequency[0], 604fd253334SXiaojian Du sizeof(uint16_t) * 8); 605fd253334SXiaojian Du gpu_metrics->current_l3clk[0] = metrics.L3Frequency[0]; 606fd253334SXiaojian Du gpu_metrics->current_l3clk[1] = metrics.L3Frequency[1]; 607fd253334SXiaojian Du 608fd253334SXiaojian Du gpu_metrics->throttle_status = metrics.ThrottlerStatus; 609fd253334SXiaojian Du 610fd253334SXiaojian Du *table = (void *)gpu_metrics; 611fd253334SXiaojian Du 612fd253334SXiaojian Du return sizeof(struct gpu_metrics_v2_0); 613fd253334SXiaojian Du } 614fd253334SXiaojian Du 615c98ee897SXiaojian Du static int vangogh_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, 616c98ee897SXiaojian Du long input[], uint32_t size) 617c98ee897SXiaojian Du { 618c98ee897SXiaojian Du int ret = 0; 619c98ee897SXiaojian Du 620c98ee897SXiaojian Du if (!smu->od_enabled) { 621c98ee897SXiaojian Du dev_warn(smu->adev->dev, "Fine grain is not enabled!\n"); 622c98ee897SXiaojian Du return -EINVAL; 623c98ee897SXiaojian Du } 624c98ee897SXiaojian Du 625c98ee897SXiaojian Du switch (type) { 626c98ee897SXiaojian Du case PP_OD_EDIT_SCLK_VDDC_TABLE: 627c98ee897SXiaojian Du if (size != 2) { 628c98ee897SXiaojian Du dev_err(smu->adev->dev, "Input parameter number not correct\n"); 629c98ee897SXiaojian Du return -EINVAL; 630c98ee897SXiaojian Du } 631c98ee897SXiaojian Du 632c98ee897SXiaojian Du if (input[0] == 0) { 633c98ee897SXiaojian Du if (input[1] < smu->gfx_default_hard_min_freq) { 63417863170SColin Ian King dev_warn(smu->adev->dev, "Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n", 635c98ee897SXiaojian Du input[1], smu->gfx_default_hard_min_freq); 636c98ee897SXiaojian Du return -EINVAL; 637c98ee897SXiaojian Du } 638c98ee897SXiaojian Du smu->gfx_actual_hard_min_freq = input[1]; 639c98ee897SXiaojian Du } else if (input[0] == 1) { 640c98ee897SXiaojian Du if (input[1] > smu->gfx_default_soft_max_freq) { 64117863170SColin Ian King dev_warn(smu->adev->dev, "Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n", 642c98ee897SXiaojian Du input[1], smu->gfx_default_soft_max_freq); 643c98ee897SXiaojian Du return -EINVAL; 644c98ee897SXiaojian Du } 645c98ee897SXiaojian Du smu->gfx_actual_soft_max_freq = input[1]; 646c98ee897SXiaojian Du } else { 647c98ee897SXiaojian Du return -EINVAL; 648c98ee897SXiaojian Du } 649c98ee897SXiaojian Du break; 650c98ee897SXiaojian Du case PP_OD_RESTORE_DEFAULT_TABLE: 651c98ee897SXiaojian Du if (size != 0) { 652c98ee897SXiaojian Du dev_err(smu->adev->dev, "Input parameter number not correct\n"); 653c98ee897SXiaojian Du return -EINVAL; 654c98ee897SXiaojian Du } else { 655c98ee897SXiaojian Du smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; 656c98ee897SXiaojian Du smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; 657c98ee897SXiaojian Du 658c98ee897SXiaojian Du ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, 659c98ee897SXiaojian Du smu->gfx_actual_hard_min_freq, NULL); 660c98ee897SXiaojian Du if (ret) { 661c98ee897SXiaojian Du dev_err(smu->adev->dev, "Restore the default hard min sclk failed!"); 662c98ee897SXiaojian Du return ret; 663c98ee897SXiaojian Du } 664c98ee897SXiaojian Du 665c98ee897SXiaojian Du ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, 666c98ee897SXiaojian Du smu->gfx_actual_soft_max_freq, NULL); 667c98ee897SXiaojian Du if (ret) { 668c98ee897SXiaojian Du dev_err(smu->adev->dev, "Restore the default soft max sclk failed!"); 669c98ee897SXiaojian Du return ret; 670c98ee897SXiaojian Du } 671c98ee897SXiaojian Du } 672c98ee897SXiaojian Du break; 673c98ee897SXiaojian Du case PP_OD_COMMIT_DPM_TABLE: 674c98ee897SXiaojian Du if (size != 0) { 675c98ee897SXiaojian Du dev_err(smu->adev->dev, "Input parameter number not correct\n"); 676c98ee897SXiaojian Du return -EINVAL; 677c98ee897SXiaojian Du } else { 678c98ee897SXiaojian Du if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) { 679c98ee897SXiaojian Du dev_err(smu->adev->dev, "The setting minimun sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n", 680c98ee897SXiaojian Du smu->gfx_actual_hard_min_freq, smu->gfx_actual_soft_max_freq); 681c98ee897SXiaojian Du return -EINVAL; 682c98ee897SXiaojian Du } 683c98ee897SXiaojian Du 684c98ee897SXiaojian Du ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, 685c98ee897SXiaojian Du smu->gfx_actual_hard_min_freq, NULL); 686c98ee897SXiaojian Du if (ret) { 687c98ee897SXiaojian Du dev_err(smu->adev->dev, "Set hard min sclk failed!"); 688c98ee897SXiaojian Du return ret; 689c98ee897SXiaojian Du } 690c98ee897SXiaojian Du 691c98ee897SXiaojian Du ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, 692c98ee897SXiaojian Du smu->gfx_actual_soft_max_freq, NULL); 693c98ee897SXiaojian Du if (ret) { 694c98ee897SXiaojian Du dev_err(smu->adev->dev, "Set soft max sclk failed!"); 695c98ee897SXiaojian Du return ret; 696c98ee897SXiaojian Du } 697c98ee897SXiaojian Du } 698c98ee897SXiaojian Du break; 699c98ee897SXiaojian Du default: 700c98ee897SXiaojian Du return -ENOSYS; 701c98ee897SXiaojian Du } 702c98ee897SXiaojian Du 703c98ee897SXiaojian Du return ret; 704c98ee897SXiaojian Du } 705c98ee897SXiaojian Du 706fce8a4acSJinzhou Su static int vangogh_set_default_dpm_tables(struct smu_context *smu) 707c98ee897SXiaojian Du { 708c98ee897SXiaojian Du struct smu_table_context *smu_table = &smu->smu_table; 709c98ee897SXiaojian Du 710c98ee897SXiaojian Du return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false); 711c98ee897SXiaojian Du } 712c98ee897SXiaojian Du 713c98ee897SXiaojian Du static int vangogh_set_fine_grain_gfx_freq_parameters(struct smu_context *smu) 714c98ee897SXiaojian Du { 715c98ee897SXiaojian Du DpmClocks_t *clk_table = smu->smu_table.clocks_table; 716c98ee897SXiaojian Du 717c98ee897SXiaojian Du smu->gfx_default_hard_min_freq = clk_table->MinGfxClk; 718c98ee897SXiaojian Du smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk; 719c98ee897SXiaojian Du smu->gfx_actual_hard_min_freq = 0; 720c98ee897SXiaojian Du smu->gfx_actual_soft_max_freq = 0; 721c98ee897SXiaojian Du 722c98ee897SXiaojian Du return 0; 723c98ee897SXiaojian Du } 724c98ee897SXiaojian Du 725a0f55287SXiaomeng Hou static int vangogh_system_features_control(struct smu_context *smu, bool en) 726a0f55287SXiaomeng Hou { 727*9e3a6ab7SXiaomeng Hou struct amdgpu_device *adev = smu->adev; 728*9e3a6ab7SXiaomeng Hou 729*9e3a6ab7SXiaomeng Hou if (adev->pm.fw_version >= 0x43f1700) 730a0f55287SXiaomeng Hou return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_RlcPowerNotify, 731a0f55287SXiaomeng Hou en ? RLC_STATUS_NORMAL : RLC_STATUS_OFF, NULL); 732*9e3a6ab7SXiaomeng Hou else 733*9e3a6ab7SXiaomeng Hou return 0; 734a0f55287SXiaomeng Hou } 735a0f55287SXiaomeng Hou 736f46a221bSXiaojian Du static const struct pptable_funcs vangogh_ppt_funcs = { 737271ab489SXiaojian Du 738f46a221bSXiaojian Du .check_fw_status = smu_v11_0_check_fw_status, 739f46a221bSXiaojian Du .check_fw_version = smu_v11_0_check_fw_version, 740f46a221bSXiaojian Du .init_smc_tables = vangogh_init_smc_tables, 741f46a221bSXiaojian Du .fini_smc_tables = smu_v11_0_fini_smc_tables, 742f46a221bSXiaojian Du .init_power = smu_v11_0_init_power, 743f46a221bSXiaojian Du .fini_power = smu_v11_0_fini_power, 744f46a221bSXiaojian Du .register_irq_handler = smu_v11_0_register_irq_handler, 745f46a221bSXiaojian Du .get_allowed_feature_mask = vangogh_get_allowed_feature_mask, 746f46a221bSXiaojian Du .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location, 747f46a221bSXiaojian Du .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param, 748f46a221bSXiaojian Du .send_smc_msg = smu_cmn_send_smc_msg, 749271ab489SXiaojian Du .dpm_set_vcn_enable = vangogh_dpm_set_vcn_enable, 750271ab489SXiaojian Du .dpm_set_jpeg_enable = vangogh_dpm_set_jpeg_enable, 751f46a221bSXiaojian Du .is_dpm_running = vangogh_is_dpm_running, 752271ab489SXiaojian Du .read_sensor = vangogh_read_sensor, 753271ab489SXiaojian Du .get_enabled_mask = smu_cmn_get_enabled_32_bits_mask, 754f46a221bSXiaojian Du .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, 755271ab489SXiaojian Du .set_watermarks_table = vangogh_set_watermarks_table, 756271ab489SXiaojian Du .set_driver_table_location = smu_v11_0_set_driver_table_location, 757f46a221bSXiaojian Du .interrupt_work = smu_v11_0_interrupt_work, 758fd253334SXiaojian Du .get_gpu_metrics = vangogh_get_gpu_metrics, 759c98ee897SXiaojian Du .od_edit_dpm_table = vangogh_od_edit_dpm_table, 760c98ee897SXiaojian Du .print_clk_levels = vangogh_print_fine_grain_clk, 761c98ee897SXiaojian Du .set_default_dpm_table = vangogh_set_default_dpm_tables, 762c98ee897SXiaojian Du .set_fine_grain_gfx_freq_parameters = vangogh_set_fine_grain_gfx_freq_parameters, 763a0f55287SXiaomeng Hou .system_features_control = vangogh_system_features_control, 764f46a221bSXiaojian Du }; 765f46a221bSXiaojian Du 766f46a221bSXiaojian Du void vangogh_set_ppt_funcs(struct smu_context *smu) 767f46a221bSXiaojian Du { 768f46a221bSXiaojian Du smu->ppt_funcs = &vangogh_ppt_funcs; 769f46a221bSXiaojian Du smu->message_map = vangogh_message_map; 770f46a221bSXiaojian Du smu->feature_map = vangogh_feature_mask_map; 771f46a221bSXiaojian Du smu->table_map = vangogh_table_map; 772f46a221bSXiaojian Du smu->is_apu = true; 773f46a221bSXiaojian Du } 774