> -----Original Message----- > From: amd-gfx <amd-gfx-bounces@xxxxxxxxxxxxxxxxxxxxx> On Behalf Of Evan > Quan > Sent: Monday, May 13, 2019 3:53 PM > To: amd-gfx@xxxxxxxxxxxxxxxxxxxxx > Cc: Quan, Evan <Evan.Quan@xxxxxxx> > Subject: [PATCH 3/3] 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@xxxxxxx> Series are Reviewed-by: Huang Rui <ray.huang@xxxxxxx> > --- > 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.21.0 > > _______________________________________________ > amd-gfx mailing list > amd-gfx@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx