aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
diff options
context:
space:
mode:
authorEvan Quan <evan.quan@amd.com>2019-06-25 11:06:08 +0800
committerAlex Deucher <alexander.deucher@amd.com>2019-06-27 11:22:21 -0500
commit505ac3039a184b53ddb16f25cd10cab67af633f5 (patch)
treeb362a60f0eda2405a27d179d1bcb3a1f39a437c7 /drivers/gpu/drm/amd/powerplay/navi10_ppt.c
parentdrm/amd/powerplay: check prerequisite for VCN power gating (diff)
downloadlinux-dev-505ac3039a184b53ddb16f25cd10cab67af633f5.tar.xz
linux-dev-505ac3039a184b53ddb16f25cd10cab67af633f5.zip
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>
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/navi10_ppt.c')
-rw-r--r--drivers/gpu/drm/amd/powerplay/navi10_ppt.c165
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_
return 0;
}
+static int navi10_get_ppfeature_status(struct smu_context *smu,
+ char *buf)
+{
+ static const char *ppfeature_name[] = {
+ "DPM_PREFETCHER",
+ "DPM_GFXCLK",
+ "DPM_GFX_PACE",
+ "DPM_UCLK",
+ "DPM_SOCCLK",
+ "DPM_MP0CLK",
+ "DPM_LINK",
+ "DPM_DCEFCLK",
+ "MEM_VDDCI_SCALING",
+ "MEM_MVDD_SCALING",
+ "DS_GFXCLK",
+ "DS_SOCCLK",
+ "DS_LCLK",
+ "DS_DCEFCLK",
+ "DS_UCLK",
+ "GFX_ULV",
+ "FW_DSTATE",
+ "GFXOFF",
+ "BACO",
+ "VCN_PG",
+ "JPEG_PG",
+ "USB_PG",
+ "RSMU_SMN_CG",
+ "PPT",
+ "TDC",
+ "GFX_EDC",
+ "APCC_PLUS",
+ "GTHR",
+ "ACDC",
+ "VR0HOT",
+ "VR1HOT",
+ "FW_CTF",
+ "FAN_CONTROL",
+ "THERMAL",
+ "GFX_DCS",
+ "RM",
+ "LED_DISPLAY",
+ "GFX_SS",
+ "OUT_OF_BAND_MONITOR",
+ "TEMP_DEPENDENT_VMIN",
+ "MMHUB_PG",
+ "ATHUB_PG"};
+ static const char *output_title[] = {
+ "FEATURES",
+ "BITMASK",
+ "ENABLEMENT"};
+ uint64_t features_enabled;
+ uint32_t feature_mask[2];
+ int i;
+ int ret = 0;
+ int size = 0;
+
+ ret = smu_feature_get_enabled_mask(smu, feature_mask, 2);
+ PP_ASSERT_WITH_CODE(!ret,
+ "[GetPPfeatureStatus] Failed to get enabled smc features!",
+ return ret);
+ features_enabled = (uint64_t)feature_mask[0] |
+ (uint64_t)feature_mask[1] << 32;
+
+ size += sprintf(buf + size, "Current ppfeatures: 0x%016llx\n", features_enabled);
+ size += sprintf(buf + size, "%-19s %-22s %s\n",
+ output_title[0],
+ output_title[1],
+ output_title[2]);
+ for (i = 0; i < (sizeof(ppfeature_name) / sizeof(ppfeature_name[0])); i++) {
+ size += sprintf(buf + size, "%-19s 0x%016llx %6s\n",
+ ppfeature_name[i],
+ 1ULL << i,
+ (features_enabled & (1ULL << i)) ? "Y" : "N");
+ }
+
+ return size;
+}
+
+static int navi10_enable_smc_features(struct smu_context *smu,
+ bool enabled,
+ uint64_t feature_masks)
+{
+ struct smu_feature *feature = &smu->smu_feature;
+ uint32_t feature_low, feature_high;
+ uint32_t feature_mask[2];
+ int ret = 0;
+
+ feature_low = (uint32_t)(feature_masks & 0xFFFFFFFF);
+ feature_high = (uint32_t)((feature_masks & 0xFFFFFFFF00000000ULL) >> 32);
+
+ if (enabled) {
+ ret = smu_send_smc_msg_with_param(smu, SMU_MSG_EnableSmuFeaturesLow,
+ feature_low);
+ if (ret)
+ return ret;
+ ret = smu_send_smc_msg_with_param(smu, SMU_MSG_EnableSmuFeaturesHigh,
+ feature_high);
+ if (ret)
+ return ret;
+ } else {
+ ret = smu_send_smc_msg_with_param(smu, SMU_MSG_DisableSmuFeaturesLow,
+ feature_low);
+ if (ret)
+ return ret;
+ ret = smu_send_smc_msg_with_param(smu, SMU_MSG_DisableSmuFeaturesHigh,
+ feature_high);
+ if (ret)
+ return ret;
+ }
+
+ ret = smu_feature_get_enabled_mask(smu, feature_mask, 2);
+ if (ret)
+ return ret;
+
+ mutex_lock(&feature->mutex);
+ bitmap_copy(feature->enabled, (unsigned long *)&feature_mask,
+ feature->feature_num);
+ mutex_unlock(&feature->mutex);
+
+ return 0;
+}
+
+static int navi10_set_ppfeature_status(struct smu_context *smu,
+ uint64_t new_ppfeature_masks)
+{
+ uint64_t features_enabled;
+ uint32_t feature_mask[2];
+ uint64_t features_to_enable;
+ uint64_t features_to_disable;
+ int ret = 0;
+
+ ret = smu_feature_get_enabled_mask(smu, feature_mask, 2);
+ PP_ASSERT_WITH_CODE(!ret,
+ "[SetPPfeatureStatus] Failed to get enabled smc features!",
+ return ret);
+ features_enabled = (uint64_t)feature_mask[0] |
+ (uint64_t)feature_mask[1] << 32;
+
+ features_to_disable =
+ features_enabled & ~new_ppfeature_masks;
+ features_to_enable =
+ ~features_enabled & new_ppfeature_masks;
+
+ pr_debug("features_to_disable 0x%llx\n", features_to_disable);
+ pr_debug("features_to_enable 0x%llx\n", features_to_enable);
+
+ if (features_to_disable) {
+ ret = navi10_enable_smc_features(smu, false, features_to_disable);
+ PP_ASSERT_WITH_CODE(!ret,
+ "[SetPPfeatureStatus] Failed to disable smc features!",
+ return ret);
+ }
+
+ if (features_to_enable) {
+ ret = navi10_enable_smc_features(smu, true, features_to_enable);
+ PP_ASSERT_WITH_CODE(!ret,
+ "[SetPPfeatureStatus] Failed to enable smc features!",
+ return ret);
+ }
+
+ return 0;
+}
+
static const struct pptable_funcs navi10_ppt_funcs = {
.tables_init = navi10_tables_init,
.alloc_dpm_context = navi10_allocate_dpm_context,
@@ -1337,6 +1500,8 @@ static const struct pptable_funcs navi10_ppt_funcs = {
.set_watermarks_table = navi10_set_watermarks_table,
.read_sensor = navi10_read_sensor,
.get_uclk_dpm_states = navi10_get_uclk_dpm_states,
+ .get_ppfeature_status = navi10_get_ppfeature_status,
+ .set_ppfeature_status = navi10_set_ppfeature_status,
};
void navi10_set_ppt_funcs(struct smu_context *smu)