Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/powerplay: enable power containment features for tonga.

v2: fix build error introduced when fix code style problems.

Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Rex Zhu and committed by
Alex Deucher
2a702ccd e9f11dc8

+548 -9
+1 -1
drivers/gpu/drm/amd/powerplay/hwmgr/Makefile
··· 4 4 5 5 HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \ 6 6 hardwaremanager.o pp_acpi.o cz_hwmgr.o \ 7 - cz_clockpowergating.o \ 7 + cz_clockpowergating.o tonga_powertune.o\ 8 8 tonga_processpptables.o ppatomctrl.o \ 9 9 tonga_hwmgr.o pppcielanes.o tonga_thermal.o\ 10 10 fiji_powertune.o fiji_hwmgr.o tonga_clockpowergating.o \
+23 -1
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
··· 302 302 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 303 303 PHM_PlatformCaps_DisableMemoryTransition); 304 304 305 + tonga_initialize_power_tune_defaults(hwmgr); 306 + 305 307 data->mclk_strobe_mode_threshold = 40000; 306 308 data->mclk_stutter_mode_threshold = 30000; 307 309 data->mclk_edc_enable_threshold = 40000; ··· 2481 2479 graphic_level->VoltageDownHyst = 0; 2482 2480 graphic_level->PowerThrottle = 0; 2483 2481 2484 - threshold = engine_clock * data->fast_watemark_threshold / 100; 2482 + threshold = engine_clock * data->fast_watermark_threshold / 100; 2485 2483 /* 2486 2484 *get the DAL clock. do it in funture. 2487 2485 PECI_GetMinClockSettings(hwmgr->peci, &minClocks); ··· 2983 2981 result = tonga_populate_smc_boot_level(hwmgr, table); 2984 2982 PP_ASSERT_WITH_CODE(0 == result, 2985 2983 "Failed to initialize Boot Level!", return result;); 2984 + 2985 + result = tonga_populate_bapm_parameters_in_dpm_table(hwmgr); 2986 + PP_ASSERT_WITH_CODE(result == 0, 2987 + "Failed to populate BAPM Parameters!", return result); 2986 2988 2987 2989 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 2988 2990 PHM_PlatformCaps_ClockStretcher)) { ··· 4376 4370 PP_ASSERT_WITH_CODE((0 == tmp_result), 4377 4371 "Failed to initialize ARB table index!", result = tmp_result); 4378 4372 4373 + tmp_result = tonga_populate_pm_fuses(hwmgr); 4374 + PP_ASSERT_WITH_CODE((tmp_result == 0), 4375 + "Failed to populate PM fuses!", result = tmp_result); 4376 + 4379 4377 tmp_result = tonga_populate_initial_mc_reg_table(hwmgr); 4380 4378 PP_ASSERT_WITH_CODE((0 == tmp_result), 4381 4379 "Failed to populate initialize MC Reg table!", result = tmp_result); ··· 4397 4387 tmp_result = tonga_start_dpm(hwmgr); 4398 4388 PP_ASSERT_WITH_CODE((0 == tmp_result), 4399 4389 "Failed to start DPM!", result = tmp_result); 4390 + 4391 + tmp_result = tonga_enable_smc_cac(hwmgr); 4392 + PP_ASSERT_WITH_CODE((tmp_result == 0), 4393 + "Failed to enable SMC CAC!", result = tmp_result); 4394 + 4395 + tmp_result = tonga_enable_power_containment(hwmgr); 4396 + PP_ASSERT_WITH_CODE((tmp_result == 0), 4397 + "Failed to enable power containment!", result = tmp_result); 4398 + 4399 + tmp_result = tonga_power_control_set_level(hwmgr); 4400 + PP_ASSERT_WITH_CODE((tmp_result == 0), 4401 + "Failed to power control set level!", result = tmp_result); 4400 4402 4401 4403 return result; 4402 4404 }
+8 -3
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h
··· 300 300 bool dll_defaule_on; 301 301 bool performance_request_registered; 302 302 303 + 303 304 /* ----------------- Low Power Features ---------------------*/ 304 305 phw_tonga_bacos bacos; 305 306 phw_tonga_ulv_parm ulv; ··· 315 314 bool enable_tdc_limit_feature; 316 315 bool enable_pkg_pwr_tracking_feature; 317 316 bool disable_uvd_power_tune_feature; 318 - phw_tonga_pt_defaults *power_tune_defaults; 317 + struct tonga_pt_defaults *power_tune_defaults; 319 318 SMU72_Discrete_PmFuses power_tune_table; 320 - uint32_t ul_dte_tj_offset; /* Fudge factor in DPM table to correct HW DTE errors */ 321 - uint32_t fast_watemark_threshold; /* use fast watermark if clock is equal or above this. In percentage of the target high sclk. */ 319 + uint32_t dte_tj_offset; /* Fudge factor in DPM table to correct HW DTE errors */ 320 + uint32_t fast_watermark_threshold; /* use fast watermark if clock is equal or above this. In percentage of the target high sclk. */ 321 + 322 + 323 + bool enable_dte_feature; 324 + 322 325 323 326 /* ----------------- Phase Shedding ---------------------*/ 324 327 bool vddc_phase_shed_control;
+498
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.c
··· 1 + /* 2 + * Copyright 2015 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 "hwmgr.h" 25 + #include "smumgr.h" 26 + #include "tonga_hwmgr.h" 27 + #include "tonga_powertune.h" 28 + #include "tonga_smumgr.h" 29 + #include "smu72_discrete.h" 30 + #include "pp_debug.h" 31 + #include "tonga_ppsmc.h" 32 + 33 + #define VOLTAGE_SCALE 4 34 + #define POWERTUNE_DEFAULT_SET_MAX 1 35 + 36 + struct tonga_pt_defaults tonga_power_tune_data_set_array[POWERTUNE_DEFAULT_SET_MAX] = { 37 + /* sviLoadLIneEn, SviLoadLineVddC, TDC_VDDC_ThrottleReleaseLimitPerc, TDC_MAWt, TdcWaterfallCtl, DTEAmbientTempBase, DisplayCac, BAPM_TEMP_GRADIENT */ 38 + {1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000, 39 + {0x79, 0x253, 0x25D, 0xAE, 0x72, 0x80, 0x83, 0x86, 0x6F, 0xC8, 0xC9, 0xC9, 0x2F, 0x4D, 0x61}, 40 + {0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } }, 41 + }; 42 + 43 + void tonga_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr) 44 + { 45 + struct tonga_hwmgr *tonga_hwmgr = (struct tonga_hwmgr *)(hwmgr->backend); 46 + struct phm_ppt_v1_information *table_info = 47 + (struct phm_ppt_v1_information *)(hwmgr->pptable); 48 + uint32_t tmp = 0; 49 + 50 + if (table_info && 51 + table_info->cac_dtp_table->usPowerTuneDataSetID <= POWERTUNE_DEFAULT_SET_MAX && 52 + table_info->cac_dtp_table->usPowerTuneDataSetID) 53 + tonga_hwmgr->power_tune_defaults = 54 + &tonga_power_tune_data_set_array 55 + [table_info->cac_dtp_table->usPowerTuneDataSetID - 1]; 56 + else 57 + tonga_hwmgr->power_tune_defaults = &tonga_power_tune_data_set_array[0]; 58 + 59 + /* Assume disabled */ 60 + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 61 + PHM_PlatformCaps_PowerContainment); 62 + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 63 + PHM_PlatformCaps_CAC); 64 + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 65 + PHM_PlatformCaps_SQRamping); 66 + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 67 + PHM_PlatformCaps_DBRamping); 68 + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 69 + PHM_PlatformCaps_TDRamping); 70 + phm_cap_unset(hwmgr->platform_descriptor.platformCaps, 71 + PHM_PlatformCaps_TCPRamping); 72 + 73 + tonga_hwmgr->dte_tj_offset = tmp; 74 + 75 + if (!tmp) { 76 + phm_cap_set(hwmgr->platform_descriptor.platformCaps, 77 + PHM_PlatformCaps_CAC); 78 + 79 + tonga_hwmgr->fast_watermark_threshold = 100; 80 + 81 + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 82 + PHM_PlatformCaps_PowerContainment)) { 83 + tmp = 1; 84 + tonga_hwmgr->enable_dte_feature = tmp ? false : true; 85 + tonga_hwmgr->enable_tdc_limit_feature = tmp ? true : false; 86 + tonga_hwmgr->enable_pkg_pwr_tracking_feature = tmp ? true : false; 87 + } 88 + } 89 + } 90 + 91 + 92 + int tonga_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr) 93 + { 94 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 95 + struct tonga_pt_defaults *defaults = data->power_tune_defaults; 96 + SMU72_Discrete_DpmTable *dpm_table = &(data->smc_state_table); 97 + struct phm_ppt_v1_information *table_info = 98 + (struct phm_ppt_v1_information *)(hwmgr->pptable); 99 + struct phm_cac_tdp_table *cac_dtp_table = table_info->cac_dtp_table; 100 + int i, j, k; 101 + uint16_t *pdef1; 102 + uint16_t *pdef2; 103 + 104 + 105 + /* TDP number of fraction bits are changed from 8 to 7 for Fiji 106 + * as requested by SMC team 107 + */ 108 + dpm_table->DefaultTdp = PP_HOST_TO_SMC_US( 109 + (uint16_t)(cac_dtp_table->usTDP * 256)); 110 + dpm_table->TargetTdp = PP_HOST_TO_SMC_US( 111 + (uint16_t)(cac_dtp_table->usConfigurableTDP * 256)); 112 + 113 + PP_ASSERT_WITH_CODE(cac_dtp_table->usTargetOperatingTemp <= 255, 114 + "Target Operating Temp is out of Range!", 115 + ); 116 + 117 + dpm_table->GpuTjMax = (uint8_t)(cac_dtp_table->usTargetOperatingTemp); 118 + dpm_table->GpuTjHyst = 8; 119 + 120 + dpm_table->DTEAmbientTempBase = defaults->dte_ambient_temp_base; 121 + 122 + dpm_table->BAPM_TEMP_GRADIENT = PP_HOST_TO_SMC_UL(defaults->bamp_temp_gradient); 123 + pdef1 = defaults->bapmti_r; 124 + pdef2 = defaults->bapmti_rc; 125 + 126 + for (i = 0; i < SMU72_DTE_ITERATIONS; i++) { 127 + for (j = 0; j < SMU72_DTE_SOURCES; j++) { 128 + for (k = 0; k < SMU72_DTE_SINKS; k++) { 129 + dpm_table->BAPMTI_R[i][j][k] = PP_HOST_TO_SMC_US(*pdef1); 130 + dpm_table->BAPMTI_RC[i][j][k] = PP_HOST_TO_SMC_US(*pdef2); 131 + pdef1++; 132 + pdef2++; 133 + } 134 + } 135 + } 136 + 137 + return 0; 138 + } 139 + 140 + static int tonga_populate_svi_load_line(struct pp_hwmgr *hwmgr) 141 + { 142 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 143 + const struct tonga_pt_defaults *defaults = data->power_tune_defaults; 144 + 145 + data->power_tune_table.SviLoadLineEn = defaults->svi_load_line_en; 146 + data->power_tune_table.SviLoadLineVddC = defaults->svi_load_line_vddC; 147 + data->power_tune_table.SviLoadLineTrimVddC = 3; 148 + data->power_tune_table.SviLoadLineOffsetVddC = 0; 149 + 150 + return 0; 151 + } 152 + 153 + static int tonga_populate_tdc_limit(struct pp_hwmgr *hwmgr) 154 + { 155 + uint16_t tdc_limit; 156 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 157 + struct phm_ppt_v1_information *table_info = 158 + (struct phm_ppt_v1_information *)(hwmgr->pptable); 159 + const struct tonga_pt_defaults *defaults = data->power_tune_defaults; 160 + 161 + /* TDC number of fraction bits are changed from 8 to 7 162 + * for Fiji as requested by SMC team 163 + */ 164 + tdc_limit = (uint16_t)(table_info->cac_dtp_table->usTDC * 256); 165 + data->power_tune_table.TDC_VDDC_PkgLimit = 166 + CONVERT_FROM_HOST_TO_SMC_US(tdc_limit); 167 + data->power_tune_table.TDC_VDDC_ThrottleReleaseLimitPerc = 168 + defaults->tdc_vddc_throttle_release_limit_perc; 169 + data->power_tune_table.TDC_MAWt = defaults->tdc_mawt; 170 + 171 + return 0; 172 + } 173 + 174 + static int tonga_populate_dw8(struct pp_hwmgr *hwmgr, uint32_t fuse_table_offset) 175 + { 176 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 177 + const struct tonga_pt_defaults *defaults = data->power_tune_defaults; 178 + uint32_t temp; 179 + 180 + if (tonga_read_smc_sram_dword(hwmgr->smumgr, 181 + fuse_table_offset + 182 + offsetof(SMU72_Discrete_PmFuses, TdcWaterfallCtl), 183 + (uint32_t *)&temp, data->sram_end)) 184 + PP_ASSERT_WITH_CODE(false, 185 + "Attempt to read PmFuses.DW6 (SviLoadLineEn) from SMC Failed!", 186 + return -EINVAL); 187 + else 188 + data->power_tune_table.TdcWaterfallCtl = defaults->tdc_waterfall_ctl; 189 + 190 + return 0; 191 + } 192 + 193 + static int tonga_populate_temperature_scaler(struct pp_hwmgr *hwmgr) 194 + { 195 + int i; 196 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 197 + 198 + /* Currently not used. Set all to zero. */ 199 + for (i = 0; i < 16; i++) 200 + data->power_tune_table.LPMLTemperatureScaler[i] = 0; 201 + 202 + return 0; 203 + } 204 + 205 + static int tonga_populate_fuzzy_fan(struct pp_hwmgr *hwmgr) 206 + { 207 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 208 + 209 + if ((hwmgr->thermal_controller.advanceFanControlParameters. 210 + usFanOutputSensitivity & (1 << 15)) || 211 + (hwmgr->thermal_controller.advanceFanControlParameters.usFanOutputSensitivity == 0)) 212 + hwmgr->thermal_controller.advanceFanControlParameters. 213 + usFanOutputSensitivity = hwmgr->thermal_controller. 214 + advanceFanControlParameters.usDefaultFanOutputSensitivity; 215 + 216 + data->power_tune_table.FuzzyFan_PwmSetDelta = 217 + PP_HOST_TO_SMC_US(hwmgr->thermal_controller. 218 + advanceFanControlParameters.usFanOutputSensitivity); 219 + return 0; 220 + } 221 + 222 + static int tonga_populate_gnb_lpml(struct pp_hwmgr *hwmgr) 223 + { 224 + int i; 225 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 226 + 227 + /* Currently not used. Set all to zero. */ 228 + for (i = 0; i < 16; i++) 229 + data->power_tune_table.GnbLPML[i] = 0; 230 + 231 + return 0; 232 + } 233 + 234 + static int tonga_min_max_vgnb_lpml_id_from_bapm_vddc(struct pp_hwmgr *hwmgr) 235 + { 236 + return 0; 237 + } 238 + 239 + static int tonga_populate_bapm_vddc_base_leakage_sidd(struct pp_hwmgr *hwmgr) 240 + { 241 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 242 + struct phm_ppt_v1_information *table_info = 243 + (struct phm_ppt_v1_information *)(hwmgr->pptable); 244 + uint16_t hi_sidd = data->power_tune_table.BapmVddCBaseLeakageHiSidd; 245 + uint16_t lo_sidd = data->power_tune_table.BapmVddCBaseLeakageLoSidd; 246 + struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table; 247 + 248 + hi_sidd = (uint16_t)(cac_table->usHighCACLeakage / 100 * 256); 249 + lo_sidd = (uint16_t)(cac_table->usLowCACLeakage / 100 * 256); 250 + 251 + data->power_tune_table.BapmVddCBaseLeakageHiSidd = 252 + CONVERT_FROM_HOST_TO_SMC_US(hi_sidd); 253 + data->power_tune_table.BapmVddCBaseLeakageLoSidd = 254 + CONVERT_FROM_HOST_TO_SMC_US(lo_sidd); 255 + 256 + return 0; 257 + } 258 + 259 + int tonga_populate_pm_fuses(struct pp_hwmgr *hwmgr) 260 + { 261 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 262 + uint32_t pm_fuse_table_offset; 263 + 264 + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 265 + PHM_PlatformCaps_PowerContainment)) { 266 + if (tonga_read_smc_sram_dword(hwmgr->smumgr, 267 + SMU72_FIRMWARE_HEADER_LOCATION + 268 + offsetof(SMU72_Firmware_Header, PmFuseTable), 269 + &pm_fuse_table_offset, data->sram_end)) 270 + PP_ASSERT_WITH_CODE(false, 271 + "Attempt to get pm_fuse_table_offset Failed!", 272 + return -EINVAL); 273 + 274 + /* DW6 */ 275 + if (tonga_populate_svi_load_line(hwmgr)) 276 + PP_ASSERT_WITH_CODE(false, 277 + "Attempt to populate SviLoadLine Failed!", 278 + return -EINVAL); 279 + /* DW7 */ 280 + if (tonga_populate_tdc_limit(hwmgr)) 281 + PP_ASSERT_WITH_CODE(false, 282 + "Attempt to populate TDCLimit Failed!", return -EINVAL); 283 + /* DW8 */ 284 + if (tonga_populate_dw8(hwmgr, pm_fuse_table_offset)) 285 + PP_ASSERT_WITH_CODE(false, 286 + "Attempt to populate TdcWaterfallCtl Failed !", 287 + return -EINVAL); 288 + 289 + /* DW9-DW12 */ 290 + if (tonga_populate_temperature_scaler(hwmgr) != 0) 291 + PP_ASSERT_WITH_CODE(false, 292 + "Attempt to populate LPMLTemperatureScaler Failed!", 293 + return -EINVAL); 294 + 295 + /* DW13-DW14 */ 296 + if (tonga_populate_fuzzy_fan(hwmgr)) 297 + PP_ASSERT_WITH_CODE(false, 298 + "Attempt to populate Fuzzy Fan Control parameters Failed!", 299 + return -EINVAL); 300 + 301 + /* DW15-DW18 */ 302 + if (tonga_populate_gnb_lpml(hwmgr)) 303 + PP_ASSERT_WITH_CODE(false, 304 + "Attempt to populate GnbLPML Failed!", 305 + return -EINVAL); 306 + 307 + /* DW19 */ 308 + if (tonga_min_max_vgnb_lpml_id_from_bapm_vddc(hwmgr)) 309 + PP_ASSERT_WITH_CODE(false, 310 + "Attempt to populate GnbLPML Min and Max Vid Failed!", 311 + return -EINVAL); 312 + 313 + /* DW20 */ 314 + if (tonga_populate_bapm_vddc_base_leakage_sidd(hwmgr)) 315 + PP_ASSERT_WITH_CODE(false, 316 + "Attempt to populate BapmVddCBaseLeakage Hi and Lo Sidd Failed!", 317 + return -EINVAL); 318 + 319 + if (tonga_copy_bytes_to_smc(hwmgr->smumgr, pm_fuse_table_offset, 320 + (uint8_t *)&data->power_tune_table, 321 + sizeof(struct SMU72_Discrete_PmFuses), data->sram_end)) 322 + PP_ASSERT_WITH_CODE(false, 323 + "Attempt to download PmFuseTable Failed!", 324 + return -EINVAL); 325 + } 326 + return 0; 327 + } 328 + 329 + int tonga_enable_smc_cac(struct pp_hwmgr *hwmgr) 330 + { 331 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 332 + int result = 0; 333 + 334 + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 335 + PHM_PlatformCaps_CAC)) { 336 + int smc_result; 337 + 338 + smc_result = smum_send_msg_to_smc(hwmgr->smumgr, 339 + (uint16_t)(PPSMC_MSG_EnableCac)); 340 + PP_ASSERT_WITH_CODE((smc_result == 0), 341 + "Failed to enable CAC in SMC.", result = -1); 342 + 343 + data->cac_enabled = (smc_result == 0) ? true : false; 344 + } 345 + return result; 346 + } 347 + 348 + int tonga_disable_smc_cac(struct pp_hwmgr *hwmgr) 349 + { 350 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 351 + int result = 0; 352 + 353 + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 354 + PHM_PlatformCaps_CAC) && data->cac_enabled) { 355 + int smc_result = smum_send_msg_to_smc(hwmgr->smumgr, 356 + (uint16_t)(PPSMC_MSG_DisableCac)); 357 + PP_ASSERT_WITH_CODE((smc_result == 0), 358 + "Failed to disable CAC in SMC.", result = -1); 359 + 360 + data->cac_enabled = false; 361 + } 362 + return result; 363 + } 364 + 365 + int tonga_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n) 366 + { 367 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 368 + 369 + if (data->power_containment_features & 370 + POWERCONTAINMENT_FEATURE_PkgPwrLimit) 371 + return smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, 372 + PPSMC_MSG_PkgPwrSetLimit, n); 373 + return 0; 374 + } 375 + 376 + static int tonga_set_overdriver_target_tdp(struct pp_hwmgr *pHwMgr, uint32_t target_tdp) 377 + { 378 + return smum_send_msg_to_smc_with_parameter(pHwMgr->smumgr, 379 + PPSMC_MSG_OverDriveSetTargetTdp, target_tdp); 380 + } 381 + 382 + int tonga_enable_power_containment(struct pp_hwmgr *hwmgr) 383 + { 384 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 385 + struct phm_ppt_v1_information *table_info = 386 + (struct phm_ppt_v1_information *)(hwmgr->pptable); 387 + int smc_result; 388 + int result = 0; 389 + 390 + data->power_containment_features = 0; 391 + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 392 + PHM_PlatformCaps_PowerContainment)) { 393 + if (data->enable_dte_feature) { 394 + smc_result = smum_send_msg_to_smc(hwmgr->smumgr, 395 + (uint16_t)(PPSMC_MSG_EnableDTE)); 396 + PP_ASSERT_WITH_CODE((smc_result == 0), 397 + "Failed to enable DTE in SMC.", result = -1;); 398 + if (smc_result == 0) 399 + data->power_containment_features |= POWERCONTAINMENT_FEATURE_DTE; 400 + } 401 + 402 + if (data->enable_tdc_limit_feature) { 403 + smc_result = smum_send_msg_to_smc(hwmgr->smumgr, 404 + (uint16_t)(PPSMC_MSG_TDCLimitEnable)); 405 + PP_ASSERT_WITH_CODE((smc_result == 0), 406 + "Failed to enable TDCLimit in SMC.", result = -1;); 407 + if (smc_result == 0) 408 + data->power_containment_features |= 409 + POWERCONTAINMENT_FEATURE_TDCLimit; 410 + } 411 + 412 + if (data->enable_pkg_pwr_tracking_feature) { 413 + smc_result = smum_send_msg_to_smc(hwmgr->smumgr, 414 + (uint16_t)(PPSMC_MSG_PkgPwrLimitEnable)); 415 + PP_ASSERT_WITH_CODE((smc_result == 0), 416 + "Failed to enable PkgPwrTracking in SMC.", result = -1;); 417 + if (smc_result == 0) { 418 + struct phm_cac_tdp_table *cac_table = 419 + table_info->cac_dtp_table; 420 + uint32_t default_limit = 421 + (uint32_t)(cac_table->usMaximumPowerDeliveryLimit * 256); 422 + 423 + data->power_containment_features |= 424 + POWERCONTAINMENT_FEATURE_PkgPwrLimit; 425 + 426 + if (tonga_set_power_limit(hwmgr, default_limit)) 427 + printk(KERN_ERR "Failed to set Default Power Limit in SMC!"); 428 + } 429 + } 430 + } 431 + return result; 432 + } 433 + 434 + int tonga_disable_power_containment(struct pp_hwmgr *hwmgr) 435 + { 436 + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); 437 + int result = 0; 438 + 439 + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 440 + PHM_PlatformCaps_PowerContainment) && 441 + data->power_containment_features) { 442 + int smc_result; 443 + 444 + if (data->power_containment_features & 445 + POWERCONTAINMENT_FEATURE_TDCLimit) { 446 + smc_result = smum_send_msg_to_smc(hwmgr->smumgr, 447 + (uint16_t)(PPSMC_MSG_TDCLimitDisable)); 448 + PP_ASSERT_WITH_CODE((smc_result == 0), 449 + "Failed to disable TDCLimit in SMC.", 450 + result = smc_result); 451 + } 452 + 453 + if (data->power_containment_features & 454 + POWERCONTAINMENT_FEATURE_DTE) { 455 + smc_result = smum_send_msg_to_smc(hwmgr->smumgr, 456 + (uint16_t)(PPSMC_MSG_DisableDTE)); 457 + PP_ASSERT_WITH_CODE((smc_result == 0), 458 + "Failed to disable DTE in SMC.", 459 + result = smc_result); 460 + } 461 + 462 + if (data->power_containment_features & 463 + POWERCONTAINMENT_FEATURE_PkgPwrLimit) { 464 + smc_result = smum_send_msg_to_smc(hwmgr->smumgr, 465 + (uint16_t)(PPSMC_MSG_PkgPwrLimitDisable)); 466 + PP_ASSERT_WITH_CODE((smc_result == 0), 467 + "Failed to disable PkgPwrTracking in SMC.", 468 + result = smc_result); 469 + } 470 + data->power_containment_features = 0; 471 + } 472 + 473 + return result; 474 + } 475 + 476 + int tonga_power_control_set_level(struct pp_hwmgr *hwmgr) 477 + { 478 + struct phm_ppt_v1_information *table_info = 479 + (struct phm_ppt_v1_information *)(hwmgr->pptable); 480 + struct phm_cac_tdp_table *cac_table = table_info->cac_dtp_table; 481 + int adjust_percent, target_tdp; 482 + int result = 0; 483 + 484 + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 485 + PHM_PlatformCaps_PowerContainment)) { 486 + /* adjustment percentage has already been validated */ 487 + adjust_percent = hwmgr->platform_descriptor.TDPAdjustmentPolarity ? 488 + hwmgr->platform_descriptor.TDPAdjustment : 489 + (-1 * hwmgr->platform_descriptor.TDPAdjustment); 490 + /* SMC requested that target_tdp to be 7 bit fraction in DPM table 491 + * but message to be 8 bit fraction for messages 492 + */ 493 + target_tdp = ((100 + adjust_percent) * (int)(cac_table->usTDP * 256)) / 100; 494 + result = tonga_set_overdriver_target_tdp(hwmgr, (uint32_t)target_tdp); 495 + } 496 + 497 + return result; 498 + }
+18 -4
drivers/gpu/drm/amd/powerplay/hwmgr/tonga_powertune.h
··· 35 35 typedef enum _phw_tonga_ptc_config_reg_type phw_tonga_ptc_config_reg_type; 36 36 37 37 /* PowerContainment Features */ 38 + #define POWERCONTAINMENT_FEATURE_DTE 0x00000001 39 + 40 + 41 + /* PowerContainment Features */ 38 42 #define POWERCONTAINMENT_FEATURE_BAPM 0x00000001 39 43 #define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002 40 44 #define POWERCONTAINMENT_FEATURE_PkgPwrLimit 0x00000004 41 45 42 - struct _phw_tonga_pt_config_reg { 46 + struct tonga_pt_config_reg { 43 47 uint32_t Offset; 44 48 uint32_t Mask; 45 49 uint32_t Shift; 46 50 uint32_t Value; 47 51 phw_tonga_ptc_config_reg_type Type; 48 52 }; 49 - typedef struct _phw_tonga_pt_config_reg phw_tonga_pt_config_reg; 50 53 51 - struct _phw_tonga_pt_defaults { 54 + struct tonga_pt_defaults { 52 55 uint8_t svi_load_line_en; 53 56 uint8_t svi_load_line_vddC; 54 57 uint8_t tdc_vddc_throttle_release_limit_perc; ··· 63 60 uint16_t bapmti_r[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; 64 61 uint16_t bapmti_rc[SMU72_DTE_ITERATIONS * SMU72_DTE_SOURCES * SMU72_DTE_SINKS]; 65 62 }; 66 - typedef struct _phw_tonga_pt_defaults phw_tonga_pt_defaults; 63 + 64 + 65 + 66 + void tonga_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr); 67 + int tonga_populate_bapm_parameters_in_dpm_table(struct pp_hwmgr *hwmgr); 68 + int tonga_populate_pm_fuses(struct pp_hwmgr *hwmgr); 69 + int tonga_enable_smc_cac(struct pp_hwmgr *hwmgr); 70 + int tonga_disable_smc_cac(struct pp_hwmgr *hwmgr); 71 + int tonga_enable_power_containment(struct pp_hwmgr *hwmgr); 72 + int tonga_disable_power_containment(struct pp_hwmgr *hwmgr); 73 + int tonga_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n); 74 + int tonga_power_control_set_level(struct pp_hwmgr *hwmgr); 67 75 68 76 #endif 69 77