From 6d6780efd48311e04a1a13544c5d1fa315b7d056 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Thu, 25 Jul 2019 11:47:44 +0800 Subject: [PATCH 3149/4256] drm/amd/powerplay: implment sysfs feature status function in smu 1. Unified feature enable status format in sysfs 2. Rename ppfeature to pp_features to adapt other pp sysfs node name 3. this function support all asic, not asic related function. Signed-off-by: Kevin Wang Reviewed-by: Kenneth Feng Acked-by: Rui Huang --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 24 +-- drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 61 +++++++ .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 8 +- drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 165 ------------------ drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 153 ---------------- 5 files changed, 75 insertions(+), 336 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index d9d1a7dd6514..783cd0192d33 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -742,10 +742,10 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev, } /** - * DOC: ppfeatures + * DOC: pp_features * * The amdgpu driver provides a sysfs API for adjusting what powerplay - * features to be enabled. The file ppfeatures is used for this. And + * features to be enabled. The file pp_features is used for this. And * this is only available for Vega10 and later dGPUs. * * Reading back the file will show you the followings: @@ -757,7 +757,7 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev, * the corresponding bit from original ppfeature masks and input the * new ppfeature masks. */ -static ssize_t amdgpu_set_ppfeature_status(struct device *dev, +static ssize_t amdgpu_set_pp_feature_status(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -774,7 +774,7 @@ static ssize_t amdgpu_set_ppfeature_status(struct device *dev, pr_debug("featuremask = 0x%llx\n", featuremask); if (is_support_sw_smu(adev)) { - ret = smu_set_ppfeature_status(&adev->smu, featuremask); + ret = smu_sys_set_pp_feature_mask(&adev->smu, featuremask); if (ret) return -EINVAL; } else if (adev->powerplay.pp_funcs->set_ppfeature_status) { @@ -786,7 +786,7 @@ static ssize_t amdgpu_set_ppfeature_status(struct device *dev, return count; } -static ssize_t amdgpu_get_ppfeature_status(struct device *dev, +static ssize_t amdgpu_get_pp_feature_status(struct device *dev, struct device_attribute *attr, char *buf) { @@ -794,7 +794,7 @@ static ssize_t amdgpu_get_ppfeature_status(struct device *dev, struct amdgpu_device *adev = ddev->dev_private; if (is_support_sw_smu(adev)) { - return smu_get_ppfeature_status(&adev->smu, buf); + return smu_sys_get_pp_feature_mask(&adev->smu, buf); } else if (adev->powerplay.pp_funcs->get_ppfeature_status) return amdgpu_dpm_get_ppfeature_status(adev, buf); @@ -1454,9 +1454,9 @@ static DEVICE_ATTR(gpu_busy_percent, S_IRUGO, static DEVICE_ATTR(mem_busy_percent, S_IRUGO, amdgpu_get_memory_busy_percent, NULL); static DEVICE_ATTR(pcie_bw, S_IRUGO, amdgpu_get_pcie_bw, NULL); -static DEVICE_ATTR(ppfeatures, S_IRUGO | S_IWUSR, - amdgpu_get_ppfeature_status, - amdgpu_set_ppfeature_status); +static DEVICE_ATTR(pp_features, S_IRUGO | S_IWUSR, + amdgpu_get_pp_feature_status, + amdgpu_set_pp_feature_status); static DEVICE_ATTR(unique_id, S_IRUGO, amdgpu_get_unique_id, NULL); static ssize_t amdgpu_hwmon_show_temp(struct device *dev, @@ -2912,10 +2912,10 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) if ((adev->asic_type >= CHIP_VEGA10) && !(adev->flags & AMD_IS_APU)) { ret = device_create_file(adev->dev, - &dev_attr_ppfeatures); + &dev_attr_pp_features); if (ret) { DRM_ERROR("failed to create device file " - "ppfeatures\n"); + "pp_features\n"); return ret; } } @@ -2969,7 +2969,7 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) device_remove_file(adev->dev, &dev_attr_unique_id); if ((adev->asic_type >= CHIP_VEGA10) && !(adev->flags & AMD_IS_APU)) - device_remove_file(adev->dev, &dev_attr_ppfeatures); + device_remove_file(adev->dev, &dev_attr_pp_features); } void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 1863a71d3d8d..974472015487 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -56,6 +56,67 @@ const char *smu_get_feature_name(struct smu_context *smu, enum smu_feature_mask return __smu_feature_names[feature]; } +size_t smu_sys_get_pp_feature_mask(struct smu_context *smu, char *buf) +{ + size_t size = 0; + int ret = 0, i = 0; + uint32_t feature_mask[2] = { 0 }; + int32_t feature_index = 0; + uint32_t count = 0; + + ret = smu_feature_get_enabled_mask(smu, feature_mask, 2); + if (ret) + goto failed; + + size = sprintf(buf + size, "features high: 0x%08x low: 0x%08x\n", + feature_mask[1], feature_mask[0]); + + for (i = 0; i < SMU_FEATURE_COUNT; i++) { + feature_index = smu_feature_get_index(smu, i); + if (feature_index < 0) + continue; + size += sprintf(buf + size, "%02d. %-20s (%2d) : %s\n", + count++, + smu_get_feature_name(smu, i), + feature_index, + !!smu_feature_is_enabled(smu, i) ? "enabeld" : "disabled"); + } + +failed: + return size; +} + +int smu_sys_set_pp_feature_mask(struct smu_context *smu, uint64_t new_mask) +{ + int ret = 0; + uint32_t feature_mask[2] = { 0 }; + uint64_t feature_2_enabled = 0; + uint64_t feature_2_disabled = 0; + uint64_t feature_enables = 0; + + ret = smu_feature_get_enabled_mask(smu, feature_mask, 2); + if (ret) + return ret; + + feature_enables = ((uint64_t)feature_mask[1] << 32 | (uint64_t)feature_mask[0]); + + feature_2_enabled = ~feature_enables & new_mask; + feature_2_disabled = feature_enables & ~new_mask; + + if (feature_2_enabled) { + ret = smu_feature_update_enable_state(smu, feature_2_enabled, true); + if (ret) + return ret; + } + if (feature_2_disabled) { + ret = smu_feature_update_enable_state(smu, feature_2_disabled, false); + if (ret) + return ret; + } + + return ret; +} + int smu_get_smc_version(struct smu_context *smu, uint32_t *if_version, uint32_t *smu_version) { int ret = 0; diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index abc2644b4c07..ac9e9d5d8a5c 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -432,8 +432,6 @@ struct pptable_funcs { uint32_t *mclk_mask, uint32_t *soc_mask); int (*set_cpu_power_state)(struct smu_context *smu); - int (*set_ppfeature_status)(struct smu_context *smu, uint64_t ppfeatures); - int (*get_ppfeature_status)(struct smu_context *smu, char *buf); bool (*is_dpm_running)(struct smu_context *smu); int (*tables_init)(struct smu_context *smu, struct smu_table *tables); int (*set_thermal_fan_table)(struct smu_context *smu); @@ -713,10 +711,6 @@ struct smu_funcs ((smu)->ppt_funcs->dpm_set_vce_enable ? (smu)->ppt_funcs->dpm_set_vce_enable((smu), (enable)) : 0) #define smu_set_xgmi_pstate(smu, pstate) \ ((smu)->funcs->set_xgmi_pstate ? (smu)->funcs->set_xgmi_pstate((smu), (pstate)) : 0) -#define smu_set_ppfeature_status(smu, ppfeatures) \ - ((smu)->ppt_funcs->set_ppfeature_status ? (smu)->ppt_funcs->set_ppfeature_status((smu), (ppfeatures)) : -EINVAL) -#define smu_get_ppfeature_status(smu, buf) \ - ((smu)->ppt_funcs->get_ppfeature_status ? (smu)->ppt_funcs->get_ppfeature_status((smu), (buf)) : -EINVAL) #define smu_set_watermarks_table(smu, tab, clock_ranges) \ ((smu)->ppt_funcs->set_watermarks_table ? (smu)->ppt_funcs->set_watermarks_table((smu), (tab), (clock_ranges)) : 0) #define smu_get_current_clk_freq_by_table(smu, clk_type, value) \ @@ -804,5 +798,7 @@ bool smu_clk_dpm_is_enabled(struct smu_context *smu, enum smu_clk_type clk_type) int smu_feature_update_enable_state(struct smu_context *smu, uint64_t feature_mask, bool enabled); const char *smu_get_message_name(struct smu_context *smu, enum smu_message_type type); const char *smu_get_feature_name(struct smu_context *smu, enum smu_feature_mask feature); +size_t smu_sys_get_pp_feature_mask(struct smu_context *smu, char *buf); +int smu_sys_set_pp_feature_mask(struct smu_context *smu, uint64_t new_mask); #endif diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c index dbac24e44174..9dd96d8b8dd5 100644 --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c @@ -1422,169 +1422,6 @@ 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 int navi10_set_peak_clock_by_device(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; @@ -1689,8 +1526,6 @@ 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, .set_performance_level = navi10_set_performance_level, .get_thermal_temperature_range = navi10_get_thermal_temperature_range, }; diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c index c06a9472c3b2..52c8fc9f1ff4 100644 --- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c @@ -2858,157 +2858,6 @@ static int vega20_dpm_set_vce_enable(struct smu_context *smu, bool enable) return smu_feature_set_enabled(smu, SMU_FEATURE_DPM_VCE_BIT, enable); } -static int vega20_get_enabled_smc_features(struct smu_context *smu, - uint64_t *features_enabled) -{ - uint32_t feature_mask[2] = {0, 0}; - int ret = 0; - - ret = smu_feature_get_enabled_mask(smu, feature_mask, 2); - if (ret) - return ret; - - *features_enabled = ((((uint64_t)feature_mask[0] << SMU_FEATURES_LOW_SHIFT) & SMU_FEATURES_LOW_MASK) | - (((uint64_t)feature_mask[1] << SMU_FEATURES_HIGH_SHIFT) & SMU_FEATURES_HIGH_MASK)); - - return ret; -} - -static int vega20_enable_smc_features(struct smu_context *smu, - bool enable, uint64_t feature_mask) -{ - uint32_t smu_features_low, smu_features_high; - int ret = 0; - - smu_features_low = (uint32_t)((feature_mask & SMU_FEATURES_LOW_MASK) >> SMU_FEATURES_LOW_SHIFT); - smu_features_high = (uint32_t)((feature_mask & SMU_FEATURES_HIGH_MASK) >> SMU_FEATURES_HIGH_SHIFT); - - if (enable) { - ret = smu_send_smc_msg_with_param(smu, SMU_MSG_EnableSmuFeaturesLow, - smu_features_low); - if (ret) - return ret; - ret = smu_send_smc_msg_with_param(smu, SMU_MSG_EnableSmuFeaturesHigh, - smu_features_high); - if (ret) - return ret; - } else { - ret = smu_send_smc_msg_with_param(smu, SMU_MSG_DisableSmuFeaturesLow, - smu_features_low); - if (ret) - return ret; - ret = smu_send_smc_msg_with_param(smu, SMU_MSG_DisableSmuFeaturesHigh, - smu_features_high); - if (ret) - return ret; - } - - return 0; - -} - -static int vega20_get_ppfeature_status(struct smu_context *smu, char *buf) -{ - static const char *ppfeature_name[] = { - "DPM_PREFETCHER", - "GFXCLK_DPM", - "UCLK_DPM", - "SOCCLK_DPM", - "UVD_DPM", - "VCE_DPM", - "ULV", - "MP0CLK_DPM", - "LINK_DPM", - "DCEFCLK_DPM", - "GFXCLK_DS", - "SOCCLK_DS", - "LCLK_DS", - "PPT", - "TDC", - "THERMAL", - "GFX_PER_CU_CG", - "RM", - "DCEFCLK_DS", - "ACDC", - "VR0HOT", - "VR1HOT", - "FW_CTF", - "LED_DISPLAY", - "FAN_CONTROL", - "GFX_EDC", - "GFXOFF", - "CG", - "FCLK_DPM", - "FCLK_DS", - "MP1CLK_DS", - "MP0CLK_DS", - "XGMI", - "ECC"}; - static const char *output_title[] = { - "FEATURES", - "BITMASK", - "ENABLEMENT"}; - uint64_t features_enabled; - int i; - int ret = 0; - int size = 0; - - ret = vega20_get_enabled_smc_features(smu, &features_enabled); - if (ret) - return ret; - - 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 < GNLD_FEATURES_MAX; 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 vega20_set_ppfeature_status(struct smu_context *smu, uint64_t new_ppfeature_masks) -{ - uint64_t features_enabled; - uint64_t features_to_enable; - uint64_t features_to_disable; - int ret = 0; - - if (new_ppfeature_masks >= (1ULL << GNLD_FEATURES_MAX)) - return -EINVAL; - - ret = vega20_get_enabled_smc_features(smu, &features_enabled); - if (ret) - return ret; - - 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 = vega20_enable_smc_features(smu, false, features_to_disable); - if (ret) - return ret; - } - - if (features_to_enable) { - ret = vega20_enable_smc_features(smu, true, features_to_enable); - if (ret) - return ret; - } - - return 0; -} - static bool vega20_is_dpm_running(struct smu_context *smu) { int ret = 0; @@ -3311,8 +3160,6 @@ static const struct pptable_funcs vega20_ppt_funcs = { .force_dpm_limit_value = vega20_force_dpm_limit_value, .unforce_dpm_levels = vega20_unforce_dpm_levels, .get_profiling_clk_mask = vega20_get_profiling_clk_mask, - .set_ppfeature_status = vega20_set_ppfeature_status, - .get_ppfeature_status = vega20_get_ppfeature_status, .is_dpm_running = vega20_is_dpm_running, .set_thermal_fan_table = vega20_set_thermal_fan_table, .get_fan_speed_percent = vega20_get_fan_speed_percent, -- 2.17.1