diff options
author | Evan Quan <evan.quan@amd.com> | 2019-06-24 23:06:08 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-06-27 12:22:21 -0400 |
commit | 505ac3039a184b53ddb16f25cd10cab67af633f5 (patch) | |
tree | b362a60f0eda2405a27d179d1bcb3a1f39a437c7 | |
parent | b213646519f4988ac1f40468e3fba81f7de7ccd7 (diff) |
drm/amd/powerplay: support runtime ppfeatures setting on Navi10
Implement Navi10 backend for runtime ppfeatures status retrieving
and setting support.
Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c index 137c2a34a606..27e5c8088f1b 100644 --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c | |||
@@ -1304,6 +1304,169 @@ static int navi10_get_uclk_dpm_states(struct smu_context *smu, uint32_t *clocks_ | |||
1304 | return 0; | 1304 | return 0; |
1305 | } | 1305 | } |
1306 | 1306 | ||
1307 | static int navi10_get_ppfeature_status(struct smu_context *smu, | ||
1308 | char *buf) | ||
1309 | { | ||
1310 | static const char *ppfeature_name[] = { | ||
1311 | "DPM_PREFETCHER", | ||
1312 | "DPM_GFXCLK", | ||
1313 | "DPM_GFX_PACE", | ||
1314 | "DPM_UCLK", | ||
1315 | "DPM_SOCCLK", | ||
1316 | "DPM_MP0CLK", | ||
1317 | "DPM_LINK", | ||
1318 | "DPM_DCEFCLK", | ||
1319 | "MEM_VDDCI_SCALING", | ||
1320 | "MEM_MVDD_SCALING", | ||
1321 | "DS_GFXCLK", | ||
1322 | "DS_SOCCLK", | ||
1323 | "DS_LCLK", | ||
1324 | "DS_DCEFCLK", | ||
1325 | "DS_UCLK", | ||
1326 | "GFX_ULV", | ||
1327 | "FW_DSTATE", | ||
1328 | "GFXOFF", | ||
1329 | "BACO", | ||
1330 | "VCN_PG", | ||
1331 | "JPEG_PG", | ||
1332 | "USB_PG", | ||
1333 | "RSMU_SMN_CG", | ||
1334 | "PPT", | ||
1335 | "TDC", | ||
1336 | "GFX_EDC", | ||
1337 | "APCC_PLUS", | ||
1338 | "GTHR", | ||
1339 | "ACDC", | ||
1340 | "VR0HOT", | ||
1341 | "VR1HOT", | ||
1342 | "FW_CTF", | ||
1343 | "FAN_CONTROL", | ||
1344 | "THERMAL", | ||
1345 | "GFX_DCS", | ||
1346 | "RM", | ||
1347 | "LED_DISPLAY", | ||
1348 | "GFX_SS", | ||
1349 | "OUT_OF_BAND_MONITOR", | ||
1350 | "TEMP_DEPENDENT_VMIN", | ||
1351 | "MMHUB_PG", | ||
1352 | "ATHUB_PG"}; | ||
1353 | static const char *output_title[] = { | ||
1354 | "FEATURES", | ||
1355 | "BITMASK", | ||
1356 | "ENABLEMENT"}; | ||
1357 | uint64_t features_enabled; | ||
1358 | uint32_t feature_mask[2]; | ||
1359 | int i; | ||
1360 | int ret = 0; | ||
1361 | int size = 0; | ||
1362 | |||
1363 | ret = smu_feature_get_enabled_mask(smu, feature_mask, 2); | ||
1364 | PP_ASSERT_WITH_CODE(!ret, | ||
1365 | "[GetPPfeatureStatus] Failed to get enabled smc features!", | ||
1366 | return ret); | ||
1367 | features_enabled = (uint64_t)feature_mask[0] | | ||
1368 | (uint64_t)feature_mask[1] << 32; | ||
1369 | |||
1370 | size += sprintf(buf + size, "Current ppfeatures: 0x%016llx\n", features_enabled); | ||
1371 | size += sprintf(buf + size, "%-19s %-22s %s\n", | ||
1372 | output_title[0], | ||
1373 | output_title[1], | ||
1374 | output_title[2]); | ||
1375 | for (i = 0; i < (sizeof(ppfeature_name) / sizeof(ppfeature_name[0])); i++) { | ||
1376 | size += sprintf(buf + size, "%-19s 0x%016llx %6s\n", | ||
1377 | ppfeature_name[i], | ||
1378 | 1ULL << i, | ||
1379 | (features_enabled & (1ULL << i)) ? "Y" : "N"); | ||
1380 | } | ||
1381 | |||
1382 | return size; | ||
1383 | } | ||
1384 | |||
1385 | static int navi10_enable_smc_features(struct smu_context *smu, | ||
1386 | bool enabled, | ||
1387 | uint64_t feature_masks) | ||
1388 | { | ||
1389 | struct smu_feature *feature = &smu->smu_feature; | ||
1390 | uint32_t feature_low, feature_high; | ||
1391 | uint32_t feature_mask[2]; | ||
1392 | int ret = 0; | ||
1393 | |||
1394 | feature_low = (uint32_t)(feature_masks & 0xFFFFFFFF); | ||
1395 | feature_high = (uint32_t)((feature_masks & 0xFFFFFFFF00000000ULL) >> 32); | ||
1396 | |||
1397 | if (enabled) { | ||
1398 | ret = smu_send_smc_msg_with_param(smu, SMU_MSG_EnableSmuFeaturesLow, | ||
1399 | feature_low); | ||
1400 | if (ret) | ||
1401 | return ret; | ||
1402 | ret = smu_send_smc_msg_with_param(smu, SMU_MSG_EnableSmuFeaturesHigh, | ||
1403 | feature_high); | ||
1404 | if (ret) | ||
1405 | return ret; | ||
1406 | } else { | ||
1407 | ret = smu_send_smc_msg_with_param(smu, SMU_MSG_DisableSmuFeaturesLow, | ||
1408 | feature_low); | ||
1409 | if (ret) | ||
1410 | return ret; | ||
1411 | ret = smu_send_smc_msg_with_param(smu, SMU_MSG_DisableSmuFeaturesHigh, | ||
1412 | feature_high); | ||
1413 | if (ret) | ||
1414 | return ret; | ||
1415 | } | ||
1416 | |||
1417 | ret = smu_feature_get_enabled_mask(smu, feature_mask, 2); | ||
1418 | if (ret) | ||
1419 | return ret; | ||
1420 | |||
1421 | mutex_lock(&feature->mutex); | ||
1422 | bitmap_copy(feature->enabled, (unsigned long *)&feature_mask, | ||
1423 | feature->feature_num); | ||
1424 | mutex_unlock(&feature->mutex); | ||
1425 | |||
1426 | return 0; | ||
1427 | } | ||
1428 | |||
1429 | static int navi10_set_ppfeature_status(struct smu_context *smu, | ||
1430 | uint64_t new_ppfeature_masks) | ||
1431 | { | ||
1432 | uint64_t features_enabled; | ||
1433 | uint32_t feature_mask[2]; | ||
1434 | uint64_t features_to_enable; | ||
1435 | uint64_t features_to_disable; | ||
1436 | int ret = 0; | ||
1437 | |||
1438 | ret = smu_feature_get_enabled_mask(smu, feature_mask, 2); | ||
1439 | PP_ASSERT_WITH_CODE(!ret, | ||
1440 | "[SetPPfeatureStatus] Failed to get enabled smc features!", | ||
1441 | return ret); | ||
1442 | features_enabled = (uint64_t)feature_mask[0] | | ||
1443 | (uint64_t)feature_mask[1] << 32; | ||
1444 | |||
1445 | features_to_disable = | ||
1446 | features_enabled & ~new_ppfeature_masks; | ||
1447 | features_to_enable = | ||
1448 | ~features_enabled & new_ppfeature_masks; | ||
1449 | |||
1450 | pr_debug("features_to_disable 0x%llx\n", features_to_disable); | ||
1451 | pr_debug("features_to_enable 0x%llx\n", features_to_enable); | ||
1452 | |||
1453 | if (features_to_disable) { | ||
1454 | ret = navi10_enable_smc_features(smu, false, features_to_disable); | ||
1455 | PP_ASSERT_WITH_CODE(!ret, | ||
1456 | "[SetPPfeatureStatus] Failed to disable smc features!", | ||
1457 | return ret); | ||
1458 | } | ||
1459 | |||
1460 | if (features_to_enable) { | ||
1461 | ret = navi10_enable_smc_features(smu, true, features_to_enable); | ||
1462 | PP_ASSERT_WITH_CODE(!ret, | ||
1463 | "[SetPPfeatureStatus] Failed to enable smc features!", | ||
1464 | return ret); | ||
1465 | } | ||
1466 | |||
1467 | return 0; | ||
1468 | } | ||
1469 | |||
1307 | static const struct pptable_funcs navi10_ppt_funcs = { | 1470 | static const struct pptable_funcs navi10_ppt_funcs = { |
1308 | .tables_init = navi10_tables_init, | 1471 | .tables_init = navi10_tables_init, |
1309 | .alloc_dpm_context = navi10_allocate_dpm_context, | 1472 | .alloc_dpm_context = navi10_allocate_dpm_context, |
@@ -1337,6 +1500,8 @@ static const struct pptable_funcs navi10_ppt_funcs = { | |||
1337 | .set_watermarks_table = navi10_set_watermarks_table, | 1500 | .set_watermarks_table = navi10_set_watermarks_table, |
1338 | .read_sensor = navi10_read_sensor, | 1501 | .read_sensor = navi10_read_sensor, |
1339 | .get_uclk_dpm_states = navi10_get_uclk_dpm_states, | 1502 | .get_uclk_dpm_states = navi10_get_uclk_dpm_states, |
1503 | .get_ppfeature_status = navi10_get_ppfeature_status, | ||
1504 | .set_ppfeature_status = navi10_set_ppfeature_status, | ||
1340 | }; | 1505 | }; |
1341 | 1506 | ||
1342 | void navi10_set_ppt_funcs(struct smu_context *smu) | 1507 | void navi10_set_ppt_funcs(struct smu_context *smu) |