aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1106-drm-amd-powerplay-support-enabled-ppfeatures-retriev.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1106-drm-amd-powerplay-support-enabled-ppfeatures-retriev.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/1106-drm-amd-powerplay-support-enabled-ppfeatures-retriev.patch355
1 files changed, 355 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1106-drm-amd-powerplay-support-enabled-ppfeatures-retriev.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1106-drm-amd-powerplay-support-enabled-ppfeatures-retriev.patch
new file mode 100644
index 00000000..a8fec787
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1106-drm-amd-powerplay-support-enabled-ppfeatures-retriev.patch
@@ -0,0 +1,355 @@
+From a6654e6b8f6a72f89d6278b628f33f2755a48cc6 Mon Sep 17 00:00:00 2001
+From: Evan Quan <evan.quan@amd.com>
+Date: Mon, 14 Jan 2019 14:06:54 +0800
+Subject: [PATCH 1106/2940] drm/amd/powerplay: support enabled ppfeatures
+ retrieving and setting V3
+
+User can use "ppfeatures" sysfs interface to retrieve and set enabled
+powerplay features.
+
+V2: expose this feature for Vega10 and later dGPUs
+V3: squash in removal of unused variable (Alex)
+
+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>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h | 8 ++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 71 ++++++++++++
+ .../gpu/drm/amd/include/kgd_pp_interface.h | 2 +
+ drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 42 +++++++
+ .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 104 ++++++++++++++++++
+ drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 2 +
+ 6 files changed, 229 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
+index f972cd156795..2f61e9edb1c1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
+@@ -364,6 +364,14 @@ enum amdgpu_pcie_gen {
+ ((adev)->powerplay.pp_funcs->enable_mgpu_fan_boost(\
+ (adev)->powerplay.pp_handle))
+
++#define amdgpu_dpm_get_ppfeature_status(adev, buf) \
++ ((adev)->powerplay.pp_funcs->get_ppfeature_status(\
++ (adev)->powerplay.pp_handle, (buf)))
++
++#define amdgpu_dpm_set_ppfeature_status(adev, ppfeatures) \
++ ((adev)->powerplay.pp_funcs->set_ppfeature_status(\
++ (adev)->powerplay.pp_handle, (ppfeatures)))
++
+ struct amdgpu_dpm {
+ struct amdgpu_ps *ps;
+ /* number of valid power states */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+index 51eb2cf42b81..f21f294e6735 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+@@ -625,6 +625,60 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
+
+ }
+
++/**
++ * DOC: ppfeatures
++ *
++ * The amdgpu driver provides a sysfs API for adjusting what powerplay
++ * features to be enabled. The file ppfeatures is used for this. And
++ * this is only available for Vega10 and later dGPUs.
++ *
++ * Reading back the file will show you the followings:
++ * - Current ppfeature masks
++ * - List of the all supported powerplay features with their naming,
++ * bitmasks and enablement status('Y'/'N' means "enabled"/"disabled").
++ *
++ * To manually enable or disable a specific feature, just set or clear
++ * the corresponding bit from original ppfeature masks and input the
++ * new ppfeature masks.
++ */
++static ssize_t amdgpu_set_ppfeature_status(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf,
++ size_t count)
++{
++ struct drm_device *ddev = dev_get_drvdata(dev);
++ struct amdgpu_device *adev = ddev->dev_private;
++ uint64_t featuremask;
++ int ret;
++
++ ret = kstrtou64(buf, 0, &featuremask);
++ if (ret)
++ return -EINVAL;
++
++ pr_debug("featuremask = 0x%llx\n", featuremask);
++
++ if (adev->powerplay.pp_funcs->set_ppfeature_status) {
++ ret = amdgpu_dpm_set_ppfeature_status(adev, featuremask);
++ if (ret)
++ return -EINVAL;
++ }
++
++ return count;
++}
++
++static ssize_t amdgpu_get_ppfeature_status(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct drm_device *ddev = dev_get_drvdata(dev);
++ struct amdgpu_device *adev = ddev->dev_private;
++
++ if (adev->powerplay.pp_funcs->get_ppfeature_status)
++ return amdgpu_dpm_get_ppfeature_status(adev, buf);
++
++ return snprintf(buf, PAGE_SIZE, "\n");
++}
++
+ /**
+ * DOC: pp_dpm_sclk pp_dpm_mclk pp_dpm_pcie
+ *
+@@ -1051,6 +1105,9 @@ static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR,
+ static DEVICE_ATTR(gpu_busy_percent, S_IRUGO,
+ amdgpu_get_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 ssize_t amdgpu_hwmon_show_temp(struct device *dev,
+ struct device_attribute *attr,
+@@ -2241,6 +2298,17 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
+ return ret;
+ }
+
++ if ((adev->asic_type >= CHIP_VEGA10) &&
++ !(adev->flags & AMD_IS_APU)) {
++ ret = device_create_file(adev->dev,
++ &dev_attr_ppfeatures);
++ if (ret) {
++ DRM_ERROR("failed to create device file "
++ "ppfeatures\n");
++ return ret;
++ }
++ }
++
+ adev->pm.sysfs_initialized = true;
+
+ return 0;
+@@ -2276,6 +2344,9 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
+ device_remove_file(adev->dev, &dev_attr_gpu_busy_percent);
+ if (adev->flags & !AMD_IS_APU)
+ device_remove_file(adev->dev, &dev_attr_pcie_bw);
++ if ((adev->asic_type >= CHIP_VEGA10) &&
++ !(adev->flags & AMD_IS_APU))
++ device_remove_file(adev->dev, &dev_attr_ppfeatures);
+ }
+
+ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
+diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+index a2ea4c933360..1130f293c4ee 100644
+--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
++++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+@@ -284,6 +284,8 @@ struct amd_pm_funcs {
+ int (*get_asic_baco_capability)(void *handle, bool *cap);
+ int (*get_asic_baco_state)(void *handle, int *state);
+ int (*set_asic_baco_state)(void *handle, int state);
++ int (*get_ppfeature_status)(void *handle, char *buf);
++ int (*set_ppfeature_status)(void *handle, uint64_t ppfeature_masks);
+ };
+
+ #endif
+diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+index 5d8b5d3c2453..3f73f7cd18b9 100644
+--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
++++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+@@ -1455,6 +1455,46 @@ static int pp_set_asic_baco_state(void *handle, int state)
+ return 0;
+ }
+
++static int pp_get_ppfeature_status(void *handle, char *buf)
++{
++ struct pp_hwmgr *hwmgr = handle;
++ int ret = 0;
++
++ if (!hwmgr || !hwmgr->pm_en || !buf)
++ return -EINVAL;
++
++ if (hwmgr->hwmgr_func->get_ppfeature_status == NULL) {
++ pr_info_ratelimited("%s was not implemented.\n", __func__);
++ return -EINVAL;
++ }
++
++ mutex_lock(&hwmgr->smu_lock);
++ ret = hwmgr->hwmgr_func->get_ppfeature_status(hwmgr, buf);
++ mutex_unlock(&hwmgr->smu_lock);
++
++ return ret;
++}
++
++static int pp_set_ppfeature_status(void *handle, uint64_t ppfeature_masks)
++{
++ struct pp_hwmgr *hwmgr = handle;
++ int ret = 0;
++
++ if (!hwmgr || !hwmgr->pm_en)
++ return -EINVAL;
++
++ if (hwmgr->hwmgr_func->set_ppfeature_status == NULL) {
++ pr_info_ratelimited("%s was not implemented.\n", __func__);
++ return -EINVAL;
++ }
++
++ mutex_lock(&hwmgr->smu_lock);
++ ret = hwmgr->hwmgr_func->set_ppfeature_status(hwmgr, ppfeature_masks);
++ mutex_unlock(&hwmgr->smu_lock);
++
++ return ret;
++}
++
+ static const struct amd_pm_funcs pp_dpm_funcs = {
+ .load_firmware = pp_dpm_load_fw,
+ .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete,
+@@ -1508,4 +1548,6 @@ static const struct amd_pm_funcs pp_dpm_funcs = {
+ .get_asic_baco_capability = pp_get_asic_baco_capability,
+ .get_asic_baco_state = pp_get_asic_baco_state,
+ .set_asic_baco_state = pp_set_asic_baco_state,
++ .get_ppfeature_status = pp_get_ppfeature_status,
++ .set_ppfeature_status = pp_set_ppfeature_status,
+ };
+diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+index 2ba387b0f27c..3e97b9d6f450 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+@@ -2776,6 +2776,108 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
+ return 0;
+ }
+
++static int vega20_get_ppfeature_status(struct pp_hwmgr *hwmgr, 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"};
++ 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(hwmgr, &features_enabled);
++ PP_ASSERT_WITH_CODE(!ret,
++ "[EnableAllSmuFeatures] Failed to get enabled smc features!",
++ 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 pp_hwmgr *hwmgr, 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(hwmgr, &features_enabled);
++ if (ret)
++ return ret;
++
++ features_to_disable =
++ (features_enabled ^ new_ppfeature_masks) & features_enabled;
++ features_to_enable =
++ (features_enabled ^ new_ppfeature_masks) ^ features_to_disable;
++
++ 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(hwmgr, false, features_to_disable);
++ if (ret)
++ return ret;
++ }
++
++ if (features_to_enable) {
++ ret = vega20_enable_smc_features(hwmgr, true, features_to_enable);
++ if (ret)
++ return ret;
++ }
++
++ return 0;
++}
++
+ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
+ enum pp_clock_type type, char *buf)
+ {
+@@ -3572,6 +3674,8 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = {
+ .force_clock_level = vega20_force_clock_level,
+ .print_clock_levels = vega20_print_clock_levels,
+ .read_sensor = vega20_read_sensor,
++ .get_ppfeature_status = vega20_get_ppfeature_status,
++ .set_ppfeature_status = vega20_set_ppfeature_status,
+ /* powergate related */
+ .powergate_uvd = vega20_power_gate_uvd,
+ .powergate_vce = vega20_power_gate_vce,
+diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+index 577cec90aef1..b1cd70dcd6e7 100644
+--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
++++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+@@ -341,6 +341,8 @@ struct pp_hwmgr_func {
+ int (*get_asic_baco_capability)(struct pp_hwmgr *hwmgr, bool *cap);
+ int (*get_asic_baco_state)(struct pp_hwmgr *hwmgr, enum BACO_STATE *state);
+ int (*set_asic_baco_state)(struct pp_hwmgr *hwmgr, enum BACO_STATE state);
++ int (*get_ppfeature_status)(struct pp_hwmgr *hwmgr, char *buf);
++ int (*set_ppfeature_status)(struct pp_hwmgr *hwmgr, uint64_t ppfeature_masks);
+ };
+
+ struct pp_table_func {
+--
+2.17.1
+