diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1958-drm-amd-powerplay-support-ppfeatures-sysfs-interface.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1958-drm-amd-powerplay-support-ppfeatures-sysfs-interface.patch | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1958-drm-amd-powerplay-support-ppfeatures-sysfs-interface.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1958-drm-amd-powerplay-support-ppfeatures-sysfs-interface.patch new file mode 100644 index 00000000..9e23bfae --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1958-drm-amd-powerplay-support-ppfeatures-sysfs-interface.patch @@ -0,0 +1,301 @@ +From a6efa41e69c39adf52cb27f2795ba756c4156b7d Mon Sep 17 00:00:00 2001 +From: Evan Quan <evan.quan@amd.com> +Date: Mon, 13 May 2019 15:32:21 +0800 +Subject: [PATCH 1958/2940] drm/amd/powerplay: support ppfeatures sysfs + interface on sw smu routine + +Support ppfeatures sysfs interface on Vega20 sw smu routine. + +Change-Id: If67f2d87e7d5aa09cfd61e86daaaaf88d5f2f4dd +Signed-off-by: Evan Quan <evan.quan@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Reviewed-by: Huang Rui <ray.huang@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 10 +- + .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 7 +- + drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 153 ++++++++++++++++++ + drivers/gpu/drm/amd/powerplay/vega20_ppt.h | 44 +++++ + 4 files changed, 211 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +index bd40d5d72508..adba9ea03e63 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +@@ -767,7 +767,11 @@ static ssize_t amdgpu_set_ppfeature_status(struct device *dev, + + pr_debug("featuremask = 0x%llx\n", featuremask); + +- if (adev->powerplay.pp_funcs->set_ppfeature_status) { ++ if (is_support_sw_smu(adev)) { ++ ret = smu_set_ppfeature_status(&adev->smu, featuremask); ++ if (ret) ++ return -EINVAL; ++ } else if (adev->powerplay.pp_funcs->set_ppfeature_status) { + ret = amdgpu_dpm_set_ppfeature_status(adev, featuremask); + if (ret) + return -EINVAL; +@@ -783,7 +787,9 @@ static ssize_t amdgpu_get_ppfeature_status(struct device *dev, + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + +- if (adev->powerplay.pp_funcs->get_ppfeature_status) ++ if (is_support_sw_smu(adev)) { ++ return smu_get_ppfeature_status(&adev->smu, buf); ++ } else if (adev->powerplay.pp_funcs->get_ppfeature_status) + return amdgpu_dpm_get_ppfeature_status(adev, buf); + + return snprintf(buf, PAGE_SIZE, "\n"); +diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +index 89052414e9f1..3a9c253759dc 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +@@ -458,6 +458,8 @@ 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); + }; + + struct smu_funcs +@@ -727,7 +729,10 @@ struct smu_funcs + ((smu)->funcs->get_mclk ? (smu)->funcs->get_mclk((smu), (low)) : 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) + + extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table, + uint16_t *size, uint8_t *frev, uint8_t *crev, +diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +index 8fafcbdb1dfd..b39f3d439332 100644 +--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c ++++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +@@ -2374,6 +2374,157 @@ static int vega20_odn_edit_dpm_table(struct smu_context *smu, + return ret; + } + ++static int vega20_get_enabled_smc_features(struct smu_context *smu, ++ uint64_t *features_enabled) ++{ ++ uint32_t feature_mask[2]; ++ 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 const struct pptable_funcs vega20_ppt_funcs = { + .alloc_dpm_context = vega20_allocate_dpm_context, + .store_powerplay_table = vega20_store_powerplay_table, +@@ -2404,6 +2555,8 @@ static const struct pptable_funcs vega20_ppt_funcs = { + .unforce_dpm_levels = vega20_unforce_dpm_levels, + .upload_dpm_level = vega20_upload_dpm_level, + .get_profiling_clk_mask = vega20_get_profiling_clk_mask, ++ .set_ppfeature_status = vega20_set_ppfeature_status, ++ .get_ppfeature_status = vega20_get_ppfeature_status, + }; + + void vega20_set_ppt_funcs(struct smu_context *smu) +diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.h b/drivers/gpu/drm/amd/powerplay/vega20_ppt.h +index 5a0d2af63173..87f3a8303645 100644 +--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.h ++++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.h +@@ -36,6 +36,50 @@ + #define AVFS_CURVE 0 + #define OD8_HOTCURVE_TEMPERATURE 85 + ++#define SMU_FEATURES_LOW_MASK 0x00000000FFFFFFFF ++#define SMU_FEATURES_LOW_SHIFT 0 ++#define SMU_FEATURES_HIGH_MASK 0xFFFFFFFF00000000 ++#define SMU_FEATURES_HIGH_SHIFT 32 ++ ++enum { ++ GNLD_DPM_PREFETCHER = 0, ++ GNLD_DPM_GFXCLK, ++ GNLD_DPM_UCLK, ++ GNLD_DPM_SOCCLK, ++ GNLD_DPM_UVD, ++ GNLD_DPM_VCE, ++ GNLD_ULV, ++ GNLD_DPM_MP0CLK, ++ GNLD_DPM_LINK, ++ GNLD_DPM_DCEFCLK, ++ GNLD_DS_GFXCLK, ++ GNLD_DS_SOCCLK, ++ GNLD_DS_LCLK, ++ GNLD_PPT, ++ GNLD_TDC, ++ GNLD_THERMAL, ++ GNLD_GFX_PER_CU_CG, ++ GNLD_RM, ++ GNLD_DS_DCEFCLK, ++ GNLD_ACDC, ++ GNLD_VR0HOT, ++ GNLD_VR1HOT, ++ GNLD_FW_CTF, ++ GNLD_LED_DISPLAY, ++ GNLD_FAN_CONTROL, ++ GNLD_DIDT, ++ GNLD_GFXOFF, ++ GNLD_CG, ++ GNLD_DPM_FCLK, ++ GNLD_DS_FCLK, ++ GNLD_DS_MP1CLK, ++ GNLD_DS_MP0CLK, ++ GNLD_XGMI, ++ GNLD_ECC, ++ ++ GNLD_FEATURES_MAX ++}; ++ + struct vega20_dpm_level { + bool enabled; + uint32_t value; +-- +2.17.1 + |