1 /* 2 * Copyright 2020 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 #define SWSMU_CODE_LAYER_L2 25 26 #include "amdgpu.h" 27 #include "amdgpu_smu.h" 28 #include "smu_v11_0.h" 29 #include "smu11_driver_if_vangogh.h" 30 #include "vangogh_ppt.h" 31 #include "smu_v11_5_ppsmc.h" 32 #include "smu_v11_5_pmfw.h" 33 #include "smu_cmn.h" 34 35 /* 36 * DO NOT use these for err/warn/info/debug messages. 37 * Use dev_err, dev_warn, dev_info and dev_dbg instead. 38 * They are more MGPU friendly. 39 */ 40 #undef pr_err 41 #undef pr_warn 42 #undef pr_info 43 #undef pr_debug 44 45 #define FEATURE_MASK(feature) (1ULL << feature) 46 #define SMC_DPM_FEATURE ( \ 47 FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ 48 FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ 49 FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ 50 FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT) | \ 51 FEATURE_MASK(FEATURE_MP0CLK_DPM_BIT) | \ 52 FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ 53 FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT) | \ 54 FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT)| \ 55 FEATURE_MASK(FEATURE_GFX_DPM_BIT)| \ 56 FEATURE_MASK(FEATURE_ISP_DPM_BIT)| \ 57 FEATURE_MASK(FEATURE_A55_DPM_BIT)| \ 58 FEATURE_MASK(FEATURE_CVIP_DSP_DPM_BIT)) 59 60 static struct cmn2asic_msg_mapping vangogh_message_map[SMU_MSG_MAX_COUNT] = { 61 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), 62 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), 63 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1), 64 MSG_MAP(AllowGfxOff, PPSMC_MSG_EnableGfxOff, 1), 65 MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisableGfxOff, 1), 66 MSG_MAP(PowerDownIspByTile, PPSMC_MSG_PowerDownIspByTile, 1), 67 MSG_MAP(PowerUpIspByTile, PPSMC_MSG_PowerUpIspByTile, 1), 68 MSG_MAP(PowerDownVcn, PPSMC_MSG_PowerDownVcn, 1), 69 MSG_MAP(PowerUpVcn, PPSMC_MSG_PowerUpVcn, 1), 70 MSG_MAP(Spare, PPSMC_MSG_spare, 1), 71 MSG_MAP(SetHardMinVcn, PPSMC_MSG_SetHardMinVcn, 1), 72 MSG_MAP(SetMinVideoGfxclkFreq, PPSMC_MSG_SetMinVideoGfxclkFreq, 1), 73 MSG_MAP(ActiveProcessNotify, PPSMC_MSG_ActiveProcessNotify, 1), 74 MSG_MAP(SetHardMinIspiclkByFreq, PPSMC_MSG_SetHardMinIspiclkByFreq, 1), 75 MSG_MAP(SetHardMinIspxclkByFreq, PPSMC_MSG_SetHardMinIspxclkByFreq, 1), 76 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1), 77 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1), 78 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1), 79 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 1), 80 MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDeviceDriverReset, 1), 81 MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 1), 82 MSG_MAP(Spare1, PPSMC_MSG_spare1, 1), 83 MSG_MAP(SetHardMinSocclkByFreq, PPSMC_MSG_SetHardMinSocclkByFreq, 1), 84 MSG_MAP(SetMinVideoFclkFreq, PPSMC_MSG_SetMinVideoFclkFreq, 1), 85 MSG_MAP(SetSoftMinVcn, PPSMC_MSG_SetSoftMinVcn, 1), 86 MSG_MAP(EnablePostCode, PPSMC_MSG_EnablePostCode, 1), 87 MSG_MAP(GetGfxclkFrequency, PPSMC_MSG_GetGfxclkFrequency, 1), 88 MSG_MAP(GetFclkFrequency, PPSMC_MSG_GetFclkFrequency, 1), 89 MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 1), 90 MSG_MAP(SetHardMinGfxClk, PPSMC_MSG_SetHardMinGfxClk, 1), 91 MSG_MAP(SetSoftMaxSocclkByFreq, PPSMC_MSG_SetSoftMaxSocclkByFreq, 1), 92 MSG_MAP(SetSoftMaxFclkByFreq, PPSMC_MSG_SetSoftMaxFclkByFreq, 1), 93 MSG_MAP(SetSoftMaxVcn, PPSMC_MSG_SetSoftMaxVcn, 1), 94 MSG_MAP(GpuChangeState, PPSMC_MSG_GpuChangeState, 1), 95 MSG_MAP(SetPowerLimitPercentage, PPSMC_MSG_SetPowerLimitPercentage, 1), 96 MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg, 1), 97 MSG_MAP(PowerUpJpeg, PPSMC_MSG_PowerUpJpeg, 1), 98 MSG_MAP(SetHardMinFclkByFreq, PPSMC_MSG_SetHardMinFclkByFreq, 1), 99 MSG_MAP(SetSoftMinSocclkByFreq, PPSMC_MSG_SetSoftMinSocclkByFreq, 1), 100 MSG_MAP(PowerUpCvip, PPSMC_MSG_PowerUpCvip, 1), 101 MSG_MAP(PowerDownCvip, PPSMC_MSG_PowerDownCvip, 1), 102 }; 103 104 static struct cmn2asic_mapping vangogh_feature_mask_map[SMU_FEATURE_COUNT] = { 105 FEA_MAP(PPT), 106 FEA_MAP(TDC), 107 FEA_MAP(THERMAL), 108 FEA_MAP(DS_GFXCLK), 109 FEA_MAP(DS_SOCCLK), 110 FEA_MAP(DS_LCLK), 111 FEA_MAP(DS_FCLK), 112 FEA_MAP(DS_MP1CLK), 113 FEA_MAP(DS_MP0CLK), 114 FEA_MAP(ATHUB_PG), 115 FEA_MAP(CCLK_DPM), 116 FEA_MAP(FAN_CONTROLLER), 117 FEA_MAP(ULV), 118 FEA_MAP(VCN_DPM), 119 FEA_MAP(FCLK_DPM), 120 FEA_MAP(SOCCLK_DPM), 121 FEA_MAP(MP0CLK_DPM), 122 FEA_MAP(LCLK_DPM), 123 FEA_MAP(SHUBCLK_DPM), 124 FEA_MAP(DCFCLK_DPM), 125 FEA_MAP(GFX_DPM), 126 FEA_MAP(DS_DCFCLK), 127 FEA_MAP(S0I2), 128 FEA_MAP(SMU_LOW_POWER), 129 FEA_MAP(GFX_DEM), 130 FEA_MAP(PSI), 131 FEA_MAP(PROCHOT), 132 FEA_MAP(CPUOFF), 133 FEA_MAP(STAPM), 134 FEA_MAP(S0I3), 135 FEA_MAP(DF_CSTATES), 136 FEA_MAP(PERF_LIMIT), 137 FEA_MAP(CORE_DLDO), 138 FEA_MAP(RSMU_LOW_POWER), 139 FEA_MAP(SMN_LOW_POWER), 140 FEA_MAP(THM_LOW_POWER), 141 FEA_MAP(SMUIO_LOW_POWER), 142 FEA_MAP(MP1_LOW_POWER), 143 FEA_MAP(DS_VCN), 144 FEA_MAP(CPPC), 145 FEA_MAP(OS_CSTATES), 146 FEA_MAP(ISP_DPM), 147 FEA_MAP(A55_DPM), 148 FEA_MAP(CVIP_DSP_DPM), 149 FEA_MAP(MSMU_LOW_POWER), 150 }; 151 152 static struct cmn2asic_mapping vangogh_table_map[SMU_TABLE_COUNT] = { 153 TAB_MAP_VALID(WATERMARKS), 154 TAB_MAP_VALID(SMU_METRICS), 155 TAB_MAP_VALID(CUSTOM_DPM), 156 TAB_MAP_VALID(DPMCLOCKS), 157 }; 158 159 static int vangogh_tables_init(struct smu_context *smu) 160 { 161 struct smu_table_context *smu_table = &smu->smu_table; 162 struct smu_table *tables = smu_table->tables; 163 164 SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t), 165 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 166 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), 167 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 168 SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t), 169 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 170 SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE, 171 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 172 SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF, sizeof(DpmActivityMonitorCoeffExt_t), 173 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 174 smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); 175 if (!smu_table->metrics_table) 176 goto err0_out; 177 smu_table->metrics_time = 0; 178 179 smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_0); 180 smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); 181 if (!smu_table->gpu_metrics_table) 182 goto err1_out; 183 184 smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); 185 if (!smu_table->watermarks_table) 186 goto err2_out; 187 188 return 0; 189 190 err2_out: 191 kfree(smu_table->gpu_metrics_table); 192 err1_out: 193 kfree(smu_table->metrics_table); 194 err0_out: 195 return -ENOMEM; 196 } 197 198 static int vangogh_allocate_dpm_context(struct smu_context *smu) 199 { 200 struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 201 202 smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context), 203 GFP_KERNEL); 204 if (!smu_dpm->dpm_context) 205 return -ENOMEM; 206 207 smu_dpm->dpm_context_size = sizeof(struct smu_11_0_dpm_context); 208 209 return 0; 210 } 211 212 static int vangogh_init_smc_tables(struct smu_context *smu) 213 { 214 int ret = 0; 215 216 ret = vangogh_tables_init(smu); 217 if (ret) 218 return ret; 219 220 ret = vangogh_allocate_dpm_context(smu); 221 if (ret) 222 return ret; 223 224 return smu_v11_0_init_smc_tables(smu); 225 } 226 227 static int vangogh_dpm_set_vcn_enable(struct smu_context *smu, bool enable) 228 { 229 int ret = 0; 230 231 if (enable) { 232 /* vcn dpm on is a prerequisite for vcn power gate messages */ 233 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { 234 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL); 235 if (ret) 236 return ret; 237 } 238 } else { 239 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { 240 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL); 241 if (ret) 242 return ret; 243 } 244 } 245 246 return ret; 247 } 248 249 static int vangogh_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) 250 { 251 int ret = 0; 252 253 if (enable) { 254 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { 255 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpJpeg, 0, NULL); 256 if (ret) 257 return ret; 258 } 259 } else { 260 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { 261 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL); 262 if (ret) 263 return ret; 264 } 265 } 266 267 return ret; 268 } 269 270 static int vangogh_set_default_dpm_table(struct smu_context *smu) 271 { 272 struct smu_table_context *smu_table = &smu->smu_table; 273 274 return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false); 275 } 276 277 static int vangogh_get_allowed_feature_mask(struct smu_context *smu, 278 uint32_t *feature_mask, 279 uint32_t num) 280 { 281 struct amdgpu_device *adev = smu->adev; 282 283 if (num > 2) 284 return -EINVAL; 285 286 memset(feature_mask, 0, sizeof(uint32_t) * num); 287 288 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_DPM_BIT) 289 | FEATURE_MASK(FEATURE_MP0CLK_DPM_BIT) 290 | FEATURE_MASK(FEATURE_DS_SOCCLK_BIT) 291 | FEATURE_MASK(FEATURE_PPT_BIT) 292 | FEATURE_MASK(FEATURE_TDC_BIT) 293 | FEATURE_MASK(FEATURE_FAN_CONTROLLER_BIT) 294 | FEATURE_MASK(FEATURE_DS_LCLK_BIT) 295 | FEATURE_MASK(FEATURE_DS_DCFCLK_BIT); 296 297 if (adev->pm.pp_feature & PP_SOCCLK_DPM_MASK) 298 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT); 299 300 if (adev->pm.pp_feature & PP_DCEFCLK_DPM_MASK) 301 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT); 302 303 if (smu->adev->pg_flags & AMD_PG_SUPPORT_ATHUB) 304 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ATHUB_PG_BIT); 305 306 return 0; 307 } 308 309 static bool vangogh_is_dpm_running(struct smu_context *smu) 310 { 311 struct amdgpu_device *adev = smu->adev; 312 313 /* 314 * Until now, the pmfw hasn't exported the interface of SMU 315 * feature mask to APU SKU so just force on all the feature 316 * at early initial stage. 317 */ 318 if (adev->in_suspend) 319 return false; 320 else 321 return true; 322 323 } 324 325 static const struct pptable_funcs vangogh_ppt_funcs = { 326 .dpm_set_vcn_enable = vangogh_dpm_set_vcn_enable, 327 .dpm_set_jpeg_enable = vangogh_dpm_set_jpeg_enable, 328 .check_fw_status = smu_v11_0_check_fw_status, 329 .check_fw_version = smu_v11_0_check_fw_version, 330 .init_smc_tables = vangogh_init_smc_tables, 331 .fini_smc_tables = smu_v11_0_fini_smc_tables, 332 .init_power = smu_v11_0_init_power, 333 .fini_power = smu_v11_0_fini_power, 334 .register_irq_handler = smu_v11_0_register_irq_handler, 335 .get_allowed_feature_mask = vangogh_get_allowed_feature_mask, 336 .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location, 337 .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param, 338 .send_smc_msg = smu_cmn_send_smc_msg, 339 .set_default_dpm_table = vangogh_set_default_dpm_table, 340 .is_dpm_running = vangogh_is_dpm_running, 341 .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, 342 .set_pp_feature_mask = smu_cmn_set_pp_feature_mask, 343 .disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception, 344 .interrupt_work = smu_v11_0_interrupt_work, 345 }; 346 347 void vangogh_set_ppt_funcs(struct smu_context *smu) 348 { 349 smu->ppt_funcs = &vangogh_ppt_funcs; 350 smu->message_map = vangogh_message_map; 351 smu->feature_map = vangogh_feature_mask_map; 352 smu->table_map = vangogh_table_map; 353 smu->is_apu = true; 354 } 355