0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include "smumgr.h"
0025 #include "vega20_inc.h"
0026 #include "soc15_common.h"
0027 #include "vega20_smumgr.h"
0028 #include "vega20_ppsmc.h"
0029 #include "smu11_driver_if.h"
0030 #include "ppatomctrl.h"
0031 #include "pp_debug.h"
0032 #include "smu_ucode_xfer_vi.h"
0033 #include "smu7_smumgr.h"
0034 #include "vega20_hwmgr.h"
0035
0036 #include "smu_v11_0_i2c.h"
0037
0038
0039 #define MP0_Public 0x03800000
0040 #define MP0_SRAM 0x03900000
0041 #define MP1_Public 0x03b00000
0042 #define MP1_SRAM 0x03c00004
0043
0044
0045 #define smnMP1_FIRMWARE_FLAGS 0x3010024
0046 #define smnMP0_FW_INTF 0x30101c0
0047 #define smnMP1_PUB_CTRL 0x3010b14
0048
0049 bool vega20_is_smc_ram_running(struct pp_hwmgr *hwmgr)
0050 {
0051 struct amdgpu_device *adev = hwmgr->adev;
0052 uint32_t mp1_fw_flags;
0053
0054 mp1_fw_flags = RREG32_PCIE(MP1_Public |
0055 (smnMP1_FIRMWARE_FLAGS & 0xffffffff));
0056
0057 if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
0058 MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)
0059 return true;
0060
0061 return false;
0062 }
0063
0064
0065
0066
0067
0068
0069
0070 static uint32_t vega20_wait_for_response(struct pp_hwmgr *hwmgr)
0071 {
0072 struct amdgpu_device *adev = hwmgr->adev;
0073 uint32_t reg;
0074
0075 reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
0076
0077 phm_wait_for_register_unequal(hwmgr, reg,
0078 0, MP1_C2PMSG_90__CONTENT_MASK);
0079
0080 return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
0081 }
0082
0083
0084
0085
0086
0087
0088
0089 static int vega20_send_msg_to_smc_without_waiting(struct pp_hwmgr *hwmgr,
0090 uint16_t msg)
0091 {
0092 struct amdgpu_device *adev = hwmgr->adev;
0093
0094 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg);
0095
0096 return 0;
0097 }
0098
0099
0100
0101
0102
0103
0104
0105 static int vega20_send_msg_to_smc(struct pp_hwmgr *hwmgr, uint16_t msg)
0106 {
0107 struct amdgpu_device *adev = hwmgr->adev;
0108 int ret = 0;
0109
0110 vega20_wait_for_response(hwmgr);
0111
0112 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
0113
0114 vega20_send_msg_to_smc_without_waiting(hwmgr, msg);
0115
0116 ret = vega20_wait_for_response(hwmgr);
0117 if (ret != PPSMC_Result_OK)
0118 dev_err(adev->dev, "Failed to send message 0x%x, response 0x%x\n", msg, ret);
0119
0120 return (ret == PPSMC_Result_OK) ? 0 : -EIO;
0121 }
0122
0123
0124
0125
0126
0127
0128
0129
0130 static int vega20_send_msg_to_smc_with_parameter(struct pp_hwmgr *hwmgr,
0131 uint16_t msg, uint32_t parameter)
0132 {
0133 struct amdgpu_device *adev = hwmgr->adev;
0134 int ret = 0;
0135
0136 vega20_wait_for_response(hwmgr);
0137
0138 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
0139
0140 WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, parameter);
0141
0142 vega20_send_msg_to_smc_without_waiting(hwmgr, msg);
0143
0144 ret = vega20_wait_for_response(hwmgr);
0145 if (ret != PPSMC_Result_OK)
0146 dev_err(adev->dev, "Failed to send message 0x%x, response 0x%x\n", msg, ret);
0147
0148 return (ret == PPSMC_Result_OK) ? 0 : -EIO;
0149 }
0150
0151 static uint32_t vega20_get_argument(struct pp_hwmgr *hwmgr)
0152 {
0153 struct amdgpu_device *adev = hwmgr->adev;
0154
0155 return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82);
0156 }
0157
0158
0159
0160
0161
0162
0163 static int vega20_copy_table_from_smc(struct pp_hwmgr *hwmgr,
0164 uint8_t *table, int16_t table_id)
0165 {
0166 struct vega20_smumgr *priv =
0167 (struct vega20_smumgr *)(hwmgr->smu_backend);
0168 struct amdgpu_device *adev = hwmgr->adev;
0169 int ret = 0;
0170
0171 PP_ASSERT_WITH_CODE(table_id < TABLE_COUNT,
0172 "Invalid SMU Table ID!", return -EINVAL);
0173 PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
0174 "Invalid SMU Table version!", return -EINVAL);
0175 PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
0176 "Invalid SMU Table Length!", return -EINVAL);
0177
0178 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0179 PPSMC_MSG_SetDriverDramAddrHigh,
0180 upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
0181 NULL)) == 0,
0182 "[CopyTableFromSMC] Attempt to Set Dram Addr High Failed!",
0183 return ret);
0184 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0185 PPSMC_MSG_SetDriverDramAddrLow,
0186 lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
0187 NULL)) == 0,
0188 "[CopyTableFromSMC] Attempt to Set Dram Addr Low Failed!",
0189 return ret);
0190 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0191 PPSMC_MSG_TransferTableSmu2Dram, table_id, NULL)) == 0,
0192 "[CopyTableFromSMC] Attempt to Transfer Table From SMU Failed!",
0193 return ret);
0194
0195 amdgpu_asic_invalidate_hdp(adev, NULL);
0196
0197 memcpy(table, priv->smu_tables.entry[table_id].table,
0198 priv->smu_tables.entry[table_id].size);
0199
0200 return 0;
0201 }
0202
0203
0204
0205
0206
0207
0208 static int vega20_copy_table_to_smc(struct pp_hwmgr *hwmgr,
0209 uint8_t *table, int16_t table_id)
0210 {
0211 struct vega20_smumgr *priv =
0212 (struct vega20_smumgr *)(hwmgr->smu_backend);
0213 struct amdgpu_device *adev = hwmgr->adev;
0214 int ret = 0;
0215
0216 PP_ASSERT_WITH_CODE(table_id < TABLE_COUNT,
0217 "Invalid SMU Table ID!", return -EINVAL);
0218 PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].version != 0,
0219 "Invalid SMU Table version!", return -EINVAL);
0220 PP_ASSERT_WITH_CODE(priv->smu_tables.entry[table_id].size != 0,
0221 "Invalid SMU Table Length!", return -EINVAL);
0222
0223 memcpy(priv->smu_tables.entry[table_id].table, table,
0224 priv->smu_tables.entry[table_id].size);
0225
0226 amdgpu_asic_flush_hdp(adev, NULL);
0227
0228 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0229 PPSMC_MSG_SetDriverDramAddrHigh,
0230 upper_32_bits(priv->smu_tables.entry[table_id].mc_addr),
0231 NULL)) == 0,
0232 "[CopyTableToSMC] Attempt to Set Dram Addr High Failed!",
0233 return ret);
0234 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0235 PPSMC_MSG_SetDriverDramAddrLow,
0236 lower_32_bits(priv->smu_tables.entry[table_id].mc_addr),
0237 NULL)) == 0,
0238 "[CopyTableToSMC] Attempt to Set Dram Addr Low Failed!",
0239 return ret);
0240 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0241 PPSMC_MSG_TransferTableDram2Smu, table_id, NULL)) == 0,
0242 "[CopyTableToSMC] Attempt to Transfer Table To SMU Failed!",
0243 return ret);
0244
0245 return 0;
0246 }
0247
0248 int vega20_set_activity_monitor_coeff(struct pp_hwmgr *hwmgr,
0249 uint8_t *table, uint16_t workload_type)
0250 {
0251 struct vega20_smumgr *priv =
0252 (struct vega20_smumgr *)(hwmgr->smu_backend);
0253 struct amdgpu_device *adev = hwmgr->adev;
0254 int ret = 0;
0255
0256 memcpy(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].table, table,
0257 priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].size);
0258
0259 amdgpu_asic_flush_hdp(adev, NULL);
0260
0261 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0262 PPSMC_MSG_SetDriverDramAddrHigh,
0263 upper_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr),
0264 NULL)) == 0,
0265 "[SetActivityMonitor] Attempt to Set Dram Addr High Failed!",
0266 return ret);
0267 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0268 PPSMC_MSG_SetDriverDramAddrLow,
0269 lower_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr),
0270 NULL)) == 0,
0271 "[SetActivityMonitor] Attempt to Set Dram Addr Low Failed!",
0272 return ret);
0273 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0274 PPSMC_MSG_TransferTableDram2Smu,
0275 TABLE_ACTIVITY_MONITOR_COEFF | (workload_type << 16),
0276 NULL)) == 0,
0277 "[SetActivityMonitor] Attempt to Transfer Table To SMU Failed!",
0278 return ret);
0279
0280 return 0;
0281 }
0282
0283 int vega20_get_activity_monitor_coeff(struct pp_hwmgr *hwmgr,
0284 uint8_t *table, uint16_t workload_type)
0285 {
0286 struct vega20_smumgr *priv =
0287 (struct vega20_smumgr *)(hwmgr->smu_backend);
0288 struct amdgpu_device *adev = hwmgr->adev;
0289 int ret = 0;
0290
0291 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0292 PPSMC_MSG_SetDriverDramAddrHigh,
0293 upper_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr),
0294 NULL)) == 0,
0295 "[GetActivityMonitor] Attempt to Set Dram Addr High Failed!",
0296 return ret);
0297 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0298 PPSMC_MSG_SetDriverDramAddrLow,
0299 lower_32_bits(priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr),
0300 NULL)) == 0,
0301 "[GetActivityMonitor] Attempt to Set Dram Addr Low Failed!",
0302 return ret);
0303 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0304 PPSMC_MSG_TransferTableSmu2Dram,
0305 TABLE_ACTIVITY_MONITOR_COEFF | (workload_type << 16), NULL)) == 0,
0306 "[GetActivityMonitor] Attempt to Transfer Table From SMU Failed!",
0307 return ret);
0308
0309 amdgpu_asic_invalidate_hdp(adev, NULL);
0310
0311 memcpy(table, priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].table,
0312 priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].size);
0313
0314 return 0;
0315 }
0316
0317 int vega20_enable_smc_features(struct pp_hwmgr *hwmgr,
0318 bool enable, uint64_t feature_mask)
0319 {
0320 uint32_t smu_features_low, smu_features_high;
0321 int ret = 0;
0322
0323 smu_features_low = (uint32_t)((feature_mask & SMU_FEATURES_LOW_MASK) >> SMU_FEATURES_LOW_SHIFT);
0324 smu_features_high = (uint32_t)((feature_mask & SMU_FEATURES_HIGH_MASK) >> SMU_FEATURES_HIGH_SHIFT);
0325
0326 if (enable) {
0327 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0328 PPSMC_MSG_EnableSmuFeaturesLow, smu_features_low, NULL)) == 0,
0329 "[EnableDisableSMCFeatures] Attempt to enable SMU features Low failed!",
0330 return ret);
0331 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0332 PPSMC_MSG_EnableSmuFeaturesHigh, smu_features_high, NULL)) == 0,
0333 "[EnableDisableSMCFeatures] Attempt to enable SMU features High failed!",
0334 return ret);
0335 } else {
0336 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0337 PPSMC_MSG_DisableSmuFeaturesLow, smu_features_low, NULL)) == 0,
0338 "[EnableDisableSMCFeatures] Attempt to disable SMU features Low failed!",
0339 return ret);
0340 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0341 PPSMC_MSG_DisableSmuFeaturesHigh, smu_features_high, NULL)) == 0,
0342 "[EnableDisableSMCFeatures] Attempt to disable SMU features High failed!",
0343 return ret);
0344 }
0345
0346 return 0;
0347 }
0348
0349 int vega20_get_enabled_smc_features(struct pp_hwmgr *hwmgr,
0350 uint64_t *features_enabled)
0351 {
0352 uint32_t smc_features_low, smc_features_high;
0353 int ret = 0;
0354
0355 if (features_enabled == NULL)
0356 return -EINVAL;
0357
0358 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr,
0359 PPSMC_MSG_GetEnabledSmuFeaturesLow,
0360 &smc_features_low)) == 0,
0361 "[GetEnabledSMCFeatures] Attempt to get SMU features Low failed!",
0362 return ret);
0363 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr,
0364 PPSMC_MSG_GetEnabledSmuFeaturesHigh,
0365 &smc_features_high)) == 0,
0366 "[GetEnabledSMCFeatures] Attempt to get SMU features High failed!",
0367 return ret);
0368
0369 *features_enabled = ((((uint64_t)smc_features_low << SMU_FEATURES_LOW_SHIFT) & SMU_FEATURES_LOW_MASK) |
0370 (((uint64_t)smc_features_high << SMU_FEATURES_HIGH_SHIFT) & SMU_FEATURES_HIGH_MASK));
0371
0372 return 0;
0373 }
0374
0375 static int vega20_set_tools_address(struct pp_hwmgr *hwmgr)
0376 {
0377 struct vega20_smumgr *priv =
0378 (struct vega20_smumgr *)(hwmgr->smu_backend);
0379 int ret = 0;
0380
0381 if (priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr) {
0382 ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0383 PPSMC_MSG_SetToolsDramAddrHigh,
0384 upper_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr),
0385 NULL);
0386 if (!ret)
0387 ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0388 PPSMC_MSG_SetToolsDramAddrLow,
0389 lower_32_bits(priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr),
0390 NULL);
0391 }
0392
0393 return ret;
0394 }
0395
0396 int vega20_set_pptable_driver_address(struct pp_hwmgr *hwmgr)
0397 {
0398 struct vega20_smumgr *priv =
0399 (struct vega20_smumgr *)(hwmgr->smu_backend);
0400 int ret = 0;
0401
0402 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0403 PPSMC_MSG_SetDriverDramAddrHigh,
0404 upper_32_bits(priv->smu_tables.entry[TABLE_PPTABLE].mc_addr),
0405 NULL)) == 0,
0406 "[SetPPtabeDriverAddress] Attempt to Set Dram Addr High Failed!",
0407 return ret);
0408 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc_with_parameter(hwmgr,
0409 PPSMC_MSG_SetDriverDramAddrLow,
0410 lower_32_bits(priv->smu_tables.entry[TABLE_PPTABLE].mc_addr),
0411 NULL)) == 0,
0412 "[SetPPtabeDriverAddress] Attempt to Set Dram Addr Low Failed!",
0413 return ret);
0414
0415 return ret;
0416 }
0417
0418 static int vega20_smu_init(struct pp_hwmgr *hwmgr)
0419 {
0420 struct vega20_smumgr *priv;
0421 unsigned long tools_size = 0x19000;
0422 int ret = 0;
0423 struct amdgpu_device *adev = hwmgr->adev;
0424
0425 struct cgs_firmware_info info = {0};
0426
0427 ret = cgs_get_firmware_info(hwmgr->device,
0428 smu7_convert_fw_type_to_cgs(UCODE_ID_SMU),
0429 &info);
0430 if (ret || !info.kptr)
0431 return -EINVAL;
0432
0433 priv = kzalloc(sizeof(struct vega20_smumgr), GFP_KERNEL);
0434 if (!priv)
0435 return -ENOMEM;
0436
0437 hwmgr->smu_backend = priv;
0438
0439
0440 ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
0441 sizeof(PPTable_t),
0442 PAGE_SIZE,
0443 AMDGPU_GEM_DOMAIN_VRAM,
0444 &priv->smu_tables.entry[TABLE_PPTABLE].handle,
0445 &priv->smu_tables.entry[TABLE_PPTABLE].mc_addr,
0446 &priv->smu_tables.entry[TABLE_PPTABLE].table);
0447 if (ret)
0448 goto free_backend;
0449
0450 priv->smu_tables.entry[TABLE_PPTABLE].version = 0x01;
0451 priv->smu_tables.entry[TABLE_PPTABLE].size = sizeof(PPTable_t);
0452
0453
0454 ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
0455 sizeof(Watermarks_t),
0456 PAGE_SIZE,
0457 AMDGPU_GEM_DOMAIN_VRAM,
0458 &priv->smu_tables.entry[TABLE_WATERMARKS].handle,
0459 &priv->smu_tables.entry[TABLE_WATERMARKS].mc_addr,
0460 &priv->smu_tables.entry[TABLE_WATERMARKS].table);
0461 if (ret)
0462 goto err0;
0463
0464 priv->smu_tables.entry[TABLE_WATERMARKS].version = 0x01;
0465 priv->smu_tables.entry[TABLE_WATERMARKS].size = sizeof(Watermarks_t);
0466
0467
0468 ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
0469 tools_size,
0470 PAGE_SIZE,
0471 AMDGPU_GEM_DOMAIN_VRAM,
0472 &priv->smu_tables.entry[TABLE_PMSTATUSLOG].handle,
0473 &priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr,
0474 &priv->smu_tables.entry[TABLE_PMSTATUSLOG].table);
0475 if (ret)
0476 goto err1;
0477
0478 priv->smu_tables.entry[TABLE_PMSTATUSLOG].version = 0x01;
0479 priv->smu_tables.entry[TABLE_PMSTATUSLOG].size = tools_size;
0480
0481
0482 ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
0483 sizeof(OverDriveTable_t),
0484 PAGE_SIZE,
0485 AMDGPU_GEM_DOMAIN_VRAM,
0486 &priv->smu_tables.entry[TABLE_OVERDRIVE].handle,
0487 &priv->smu_tables.entry[TABLE_OVERDRIVE].mc_addr,
0488 &priv->smu_tables.entry[TABLE_OVERDRIVE].table);
0489 if (ret)
0490 goto err2;
0491
0492 priv->smu_tables.entry[TABLE_OVERDRIVE].version = 0x01;
0493 priv->smu_tables.entry[TABLE_OVERDRIVE].size = sizeof(OverDriveTable_t);
0494
0495
0496 ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
0497 sizeof(SmuMetrics_t),
0498 PAGE_SIZE,
0499 AMDGPU_GEM_DOMAIN_VRAM,
0500 &priv->smu_tables.entry[TABLE_SMU_METRICS].handle,
0501 &priv->smu_tables.entry[TABLE_SMU_METRICS].mc_addr,
0502 &priv->smu_tables.entry[TABLE_SMU_METRICS].table);
0503 if (ret)
0504 goto err3;
0505
0506 priv->smu_tables.entry[TABLE_SMU_METRICS].version = 0x01;
0507 priv->smu_tables.entry[TABLE_SMU_METRICS].size = sizeof(SmuMetrics_t);
0508
0509
0510 ret = amdgpu_bo_create_kernel((struct amdgpu_device *)hwmgr->adev,
0511 sizeof(DpmActivityMonitorCoeffInt_t),
0512 PAGE_SIZE,
0513 AMDGPU_GEM_DOMAIN_VRAM,
0514 &priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].handle,
0515 &priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr,
0516 &priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].table);
0517 if (ret)
0518 goto err4;
0519
0520 priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].version = 0x01;
0521 priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].size = sizeof(DpmActivityMonitorCoeffInt_t);
0522
0523 ret = smu_v11_0_i2c_control_init(adev);
0524 if (ret)
0525 goto err4;
0526
0527 return 0;
0528
0529 err4:
0530 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_SMU_METRICS].handle,
0531 &priv->smu_tables.entry[TABLE_SMU_METRICS].mc_addr,
0532 &priv->smu_tables.entry[TABLE_SMU_METRICS].table);
0533 err3:
0534 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_OVERDRIVE].handle,
0535 &priv->smu_tables.entry[TABLE_OVERDRIVE].mc_addr,
0536 &priv->smu_tables.entry[TABLE_OVERDRIVE].table);
0537 err2:
0538 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PMSTATUSLOG].handle,
0539 &priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr,
0540 &priv->smu_tables.entry[TABLE_PMSTATUSLOG].table);
0541 err1:
0542 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_WATERMARKS].handle,
0543 &priv->smu_tables.entry[TABLE_WATERMARKS].mc_addr,
0544 &priv->smu_tables.entry[TABLE_WATERMARKS].table);
0545 err0:
0546 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PPTABLE].handle,
0547 &priv->smu_tables.entry[TABLE_PPTABLE].mc_addr,
0548 &priv->smu_tables.entry[TABLE_PPTABLE].table);
0549 free_backend:
0550 kfree(hwmgr->smu_backend);
0551
0552 return -EINVAL;
0553 }
0554
0555 static int vega20_smu_fini(struct pp_hwmgr *hwmgr)
0556 {
0557 struct vega20_smumgr *priv =
0558 (struct vega20_smumgr *)(hwmgr->smu_backend);
0559 struct amdgpu_device *adev = hwmgr->adev;
0560
0561 smu_v11_0_i2c_control_fini(adev);
0562
0563 if (priv) {
0564 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PPTABLE].handle,
0565 &priv->smu_tables.entry[TABLE_PPTABLE].mc_addr,
0566 &priv->smu_tables.entry[TABLE_PPTABLE].table);
0567 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_WATERMARKS].handle,
0568 &priv->smu_tables.entry[TABLE_WATERMARKS].mc_addr,
0569 &priv->smu_tables.entry[TABLE_WATERMARKS].table);
0570 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_PMSTATUSLOG].handle,
0571 &priv->smu_tables.entry[TABLE_PMSTATUSLOG].mc_addr,
0572 &priv->smu_tables.entry[TABLE_PMSTATUSLOG].table);
0573 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_OVERDRIVE].handle,
0574 &priv->smu_tables.entry[TABLE_OVERDRIVE].mc_addr,
0575 &priv->smu_tables.entry[TABLE_OVERDRIVE].table);
0576 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_SMU_METRICS].handle,
0577 &priv->smu_tables.entry[TABLE_SMU_METRICS].mc_addr,
0578 &priv->smu_tables.entry[TABLE_SMU_METRICS].table);
0579 amdgpu_bo_free_kernel(&priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].handle,
0580 &priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].mc_addr,
0581 &priv->smu_tables.entry[TABLE_ACTIVITY_MONITOR_COEFF].table);
0582 kfree(hwmgr->smu_backend);
0583 hwmgr->smu_backend = NULL;
0584 }
0585
0586 return 0;
0587 }
0588
0589 static int vega20_start_smu(struct pp_hwmgr *hwmgr)
0590 {
0591 int ret;
0592
0593 ret = vega20_is_smc_ram_running(hwmgr);
0594 PP_ASSERT_WITH_CODE(ret,
0595 "[Vega20StartSmu] SMC is not running!",
0596 return -EINVAL);
0597
0598 ret = vega20_set_tools_address(hwmgr);
0599 PP_ASSERT_WITH_CODE(!ret,
0600 "[Vega20StartSmu] Failed to set tools address!",
0601 return ret);
0602
0603 return 0;
0604 }
0605
0606 static bool vega20_is_dpm_running(struct pp_hwmgr *hwmgr)
0607 {
0608 uint64_t features_enabled = 0;
0609
0610 vega20_get_enabled_smc_features(hwmgr, &features_enabled);
0611
0612 if (features_enabled & SMC_DPM_FEATURES)
0613 return true;
0614 else
0615 return false;
0616 }
0617
0618 static int vega20_smc_table_manager(struct pp_hwmgr *hwmgr, uint8_t *table,
0619 uint16_t table_id, bool rw)
0620 {
0621 int ret;
0622
0623 if (rw)
0624 ret = vega20_copy_table_from_smc(hwmgr, table, table_id);
0625 else
0626 ret = vega20_copy_table_to_smc(hwmgr, table, table_id);
0627
0628 return ret;
0629 }
0630
0631 const struct pp_smumgr_func vega20_smu_funcs = {
0632 .name = "vega20_smu",
0633 .smu_init = &vega20_smu_init,
0634 .smu_fini = &vega20_smu_fini,
0635 .start_smu = &vega20_start_smu,
0636 .request_smu_load_specific_fw = NULL,
0637 .send_msg_to_smc = &vega20_send_msg_to_smc,
0638 .send_msg_to_smc_with_parameter = &vega20_send_msg_to_smc_with_parameter,
0639 .download_pptable_settings = NULL,
0640 .upload_pptable_settings = NULL,
0641 .is_dpm_running = vega20_is_dpm_running,
0642 .get_argument = vega20_get_argument,
0643 .smc_table_manager = vega20_smc_table_manager,
0644 };