[PATCH 7/8] amdgpu/pm: Powerplay API for smu , changed 4 dpm functions to use API
Darren Powell
darren.powell at amd.com
Wed Jan 13 03:27:25 UTC 2021
v2: fix errors and warnings flagged by checkpatch
New Functions
smu_get_mclk - implementation of the Powerplay API function get_mclk
smu_get_sclk - implementation of the Powerplay API function get_sclk
smu_handle_dpm_task - implementation of the Powerplay API function dispatch_tasks
Modified Functions
smu_dpm_set_power_gate - - modifed arg0 to match Powerplay API set_powergating_by_smu
Other Changes
removed special smu handling in dpm functions and called through Powerplay API
call to smu_dpm_set_power_gate via Powerplay API now locks mutex for UVD and VCE
Signed-off-by: Darren Powell <darren.powell at amd.com>
---
drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 96 ++++++++---------------
drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h | 7 +-
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 49 +++++++++++-
3 files changed, 86 insertions(+), 66 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
index 8ae2df82addc..0a6bb3311f0f 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
@@ -911,50 +911,28 @@ amdgpu_get_vce_clock_state(void *handle, u32 idx)
int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low)
{
- uint32_t clk_freq;
- int ret = 0;
- if (is_support_sw_smu(adev)) {
- ret = smu_get_dpm_freq_range(&adev->smu, SMU_GFXCLK,
- low ? &clk_freq : NULL,
- !low ? &clk_freq : NULL);
- if (ret)
- return 0;
- return clk_freq * 100;
+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
- } else {
- return (adev)->powerplay.pp_funcs->get_sclk((adev)->powerplay.pp_handle, (low));
- }
+ return pp_funcs->get_sclk((adev)->powerplay.pp_handle, (low));
}
int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low)
{
- uint32_t clk_freq;
- int ret = 0;
- if (is_support_sw_smu(adev)) {
- ret = smu_get_dpm_freq_range(&adev->smu, SMU_UCLK,
- low ? &clk_freq : NULL,
- !low ? &clk_freq : NULL);
- if (ret)
- return 0;
- return clk_freq * 100;
+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
- } else {
- return (adev)->powerplay.pp_funcs->get_mclk((adev)->powerplay.pp_handle, (low));
- }
+ return pp_funcs->get_mclk((adev)->powerplay.pp_handle, (low));
}
int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block_type, bool gate)
{
int ret = 0;
+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
bool swsmu = is_support_sw_smu(adev);
switch (block_type) {
case AMD_IP_BLOCK_TYPE_UVD:
case AMD_IP_BLOCK_TYPE_VCE:
- if (swsmu) {
- ret = smu_dpm_set_power_gate(&adev->smu, block_type, gate);
- } else if (adev->powerplay.pp_funcs &&
- adev->powerplay.pp_funcs->set_powergating_by_smu) {
+ if (pp_funcs && pp_funcs->set_powergating_by_smu) {
/*
* TODO: need a better lock mechanism
*
@@ -982,7 +960,7 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
* amdgpu_set_dpm_forced_performance_level+0x129/0x330 [amdgpu]
*/
mutex_lock(&adev->pm.mutex);
- ret = ((adev)->powerplay.pp_funcs->set_powergating_by_smu(
+ ret = (pp_funcs->set_powergating_by_smu(
(adev)->powerplay.pp_handle, block_type, gate));
mutex_unlock(&adev->pm.mutex);
}
@@ -990,12 +968,10 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
case AMD_IP_BLOCK_TYPE_GFX:
case AMD_IP_BLOCK_TYPE_VCN:
case AMD_IP_BLOCK_TYPE_SDMA:
- if (swsmu)
- ret = smu_dpm_set_power_gate(&adev->smu, block_type, gate);
- else if (adev->powerplay.pp_funcs &&
- adev->powerplay.pp_funcs->set_powergating_by_smu)
- ret = ((adev)->powerplay.pp_funcs->set_powergating_by_smu(
+ if (pp_funcs && pp_funcs->set_powergating_by_smu) {
+ ret = (pp_funcs->set_powergating_by_smu(
(adev)->powerplay.pp_handle, block_type, gate));
+ }
break;
case AMD_IP_BLOCK_TYPE_JPEG:
if (swsmu)
@@ -1003,10 +979,10 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
break;
case AMD_IP_BLOCK_TYPE_GMC:
case AMD_IP_BLOCK_TYPE_ACP:
- if (adev->powerplay.pp_funcs &&
- adev->powerplay.pp_funcs->set_powergating_by_smu)
- ret = ((adev)->powerplay.pp_funcs->set_powergating_by_smu(
+ if (pp_funcs && pp_funcs->set_powergating_by_smu) {
+ ret = (pp_funcs->set_powergating_by_smu(
(adev)->powerplay.pp_handle, block_type, gate));
+ }
break;
default:
break;
@@ -1512,36 +1488,30 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
amdgpu_fence_wait_empty(ring);
}
- if (is_support_sw_smu(adev)) {
- struct smu_dpm_context *smu_dpm = &adev->smu.smu_dpm;
- smu_handle_task(&adev->smu,
- smu_dpm->dpm_level,
- AMD_PP_TASK_DISPLAY_CONFIG_CHANGE,
- true);
- } else {
- if (adev->powerplay.pp_funcs->dispatch_tasks) {
- if (!amdgpu_device_has_dc_support(adev)) {
- mutex_lock(&adev->pm.mutex);
- amdgpu_dpm_get_active_displays(adev);
- adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtc_count;
- adev->pm.pm_display_cfg.vrefresh = amdgpu_dpm_get_vrefresh(adev);
- adev->pm.pm_display_cfg.min_vblank_time = amdgpu_dpm_get_vblank_time(adev);
- /* we have issues with mclk switching with refresh rates over 120 hz on the non-DC code. */
- if (adev->pm.pm_display_cfg.vrefresh > 120)
- adev->pm.pm_display_cfg.min_vblank_time = 0;
- if (adev->powerplay.pp_funcs->display_configuration_change)
- adev->powerplay.pp_funcs->display_configuration_change(
- adev->powerplay.pp_handle,
- &adev->pm.pm_display_cfg);
- mutex_unlock(&adev->pm.mutex);
- }
- amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_DISPLAY_CONFIG_CHANGE, NULL);
- } else {
+ if (adev->powerplay.pp_funcs->dispatch_tasks) {
+ if (!amdgpu_device_has_dc_support(adev)) {
mutex_lock(&adev->pm.mutex);
amdgpu_dpm_get_active_displays(adev);
- amdgpu_dpm_change_power_state_locked(adev);
+ adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtc_count;
+ adev->pm.pm_display_cfg.vrefresh = amdgpu_dpm_get_vrefresh(adev);
+ adev->pm.pm_display_cfg.min_vblank_time = amdgpu_dpm_get_vblank_time(adev);
+ /* we have issues with mclk switching with
+ * refresh rates over 120 hz on the non-DC code.
+ */
+ if (adev->pm.pm_display_cfg.vrefresh > 120)
+ adev->pm.pm_display_cfg.min_vblank_time = 0;
+ if (adev->powerplay.pp_funcs->display_configuration_change)
+ adev->powerplay.pp_funcs->display_configuration_change(
+ adev->powerplay.pp_handle,
+ &adev->pm.pm_display_cfg);
mutex_unlock(&adev->pm.mutex);
}
+ amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_DISPLAY_CONFIG_CHANGE, NULL);
+ } else {
+ mutex_lock(&adev->pm.mutex);
+ amdgpu_dpm_get_active_displays(adev);
+ amdgpu_dpm_change_power_state_locked(adev);
+ mutex_unlock(&adev->pm.mutex);
}
}
diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
index 3c0b6209ab6a..edd911ac8e5a 100644
--- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
@@ -727,16 +727,21 @@ int smu_set_watermarks_for_clock_ranges(
extern int smu_display_configuration_change(struct smu_context *smu, const
struct amd_pp_display_configuration
*display_config);
-extern int smu_dpm_set_power_gate(struct smu_context *smu,uint32_t block_type, bool gate);
+extern int smu_dpm_set_power_gate(void *handle, uint32_t block_type, bool gate);
extern int smu_handle_task(struct smu_context *smu,
enum amd_dpm_forced_level level,
enum amd_pp_task task_id,
bool lock_needed);
+extern int smu_handle_dpm_task(void *handle,
+ enum amd_pp_task task_id,
+ enum amd_pm_state_type *user_state);
int smu_switch_power_profile(void *handle,
enum PP_SMC_POWER_PROFILE type,
bool en);
int smu_get_dpm_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
uint32_t *min, uint32_t *max);
+u32 smu_get_mclk(void *handle, bool low);
+u32 smu_get_sclk(void *handle, bool low);
int smu_set_soft_freq_range(struct smu_context *smu, enum smu_clk_type clk_type,
uint32_t min, uint32_t max);
enum amd_dpm_forced_level smu_get_performance_level(void *handle);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index dbcf853abb47..e846a9c6617f 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -138,6 +138,34 @@ int smu_get_dpm_freq_range(struct smu_context *smu,
return ret;
}
+u32 smu_get_mclk(void *handle, bool low)
+{
+ struct smu_context *smu = handle;
+ uint32_t clk_freq;
+ int ret = 0;
+
+ ret = smu_get_dpm_freq_range(smu, SMU_UCLK,
+ low ? &clk_freq : NULL,
+ !low ? &clk_freq : NULL);
+ if (ret)
+ return 0;
+ return clk_freq * 100;
+}
+
+u32 smu_get_sclk(void *handle, bool low)
+{
+ struct smu_context *smu = handle;
+ uint32_t clk_freq;
+ int ret = 0;
+
+ ret = smu_get_dpm_freq_range(smu, SMU_GFXCLK,
+ low ? &clk_freq : NULL,
+ !low ? &clk_freq : NULL);
+ if (ret)
+ return 0;
+ return clk_freq * 100;
+}
+
static int smu_dpm_set_vcn_enable_locked(struct smu_context *smu,
bool enable)
{
@@ -213,7 +241,7 @@ static int smu_dpm_set_jpeg_enable(struct smu_context *smu,
/**
* smu_dpm_set_power_gate - power gate/ungate the specific IP block
*
- * @smu: smu_context pointer
+ * @handle: smu_context pointer
* @block_type: the IP block to power gate/ungate
* @gate: to power gate if true, ungate otherwise
*
@@ -224,9 +252,10 @@ static int smu_dpm_set_jpeg_enable(struct smu_context *smu,
* Under this case, the smu->mutex lock protection is already enforced on
* the parent API smu_force_performance_level of the call path.
*/
-int smu_dpm_set_power_gate(struct smu_context *smu, uint32_t block_type,
+int smu_dpm_set_power_gate(void *handle, uint32_t block_type,
bool gate)
{
+ struct smu_context *smu = handle;
int ret = 0;
if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
@@ -1553,6 +1582,18 @@ int smu_handle_task(struct smu_context *smu,
return ret;
}
+int smu_handle_dpm_task(void *handle,
+ enum amd_pp_task task_id,
+ enum amd_pm_state_type *user_state)
+{
+ struct smu_context *smu = handle;
+ struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
+
+ return smu_handle_task(smu, smu_dpm->dpm_level, task_id, true);
+
+}
+
+
int smu_switch_power_profile(void *handle,
enum PP_SMC_POWER_PROFILE type,
bool en)
@@ -2721,10 +2762,14 @@ static const struct amd_pm_funcs swsmu_pm_funcs = {
.get_pp_table = smu_sys_get_pp_table,
.switch_power_profile = smu_switch_power_profile,
/* export to amdgpu */
+ .dispatch_tasks = smu_handle_dpm_task,
+ .set_powergating_by_smu = smu_dpm_set_power_gate,
.set_power_limit = smu_set_power_limit,
.get_power_limit = smu_get_power_limit,
.set_mp1_state = smu_set_mp1_state,
/* export to DC */
+ .get_sclk = smu_get_sclk,
+ .get_mclk = smu_get_mclk,
.enable_mgpu_fan_boost = smu_enable_mgpu_fan_boost,
.get_asic_baco_capability = smu_get_baco_capability,
.set_asic_baco_state = smu_baco_set_state,
--
2.25.1
More information about the amd-gfx
mailing list