[PATCH 06/18] drm/amd/pm: set powergating by smu by instance
boyuan.zhang at amd.com
boyuan.zhang at amd.com
Wed Oct 2 04:36:15 UTC 2024
From: Boyuan Zhang <boyuan.zhang at amd.com>
Add a new function to set powergating_by_smu for the given instance
Signed-off-by: Boyuan Zhang <boyuan.zhang at amd.com>
---
.../gpu/drm/amd/include/kgd_pp_interface.h | 2 +
drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 67 +++++++++++++++++++
drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 4 ++
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 1 +
4 files changed, 74 insertions(+)
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 2fa71f68205e..cdd891f51422 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -406,6 +406,8 @@ struct amd_pm_funcs {
int (*wait_for_fw_loading_complete)(void *handle);
int (*set_powergating_by_smu)(void *handle,
uint32_t block_type, bool gate);
+ int (*set_powergating_by_smu_instance)(void *handle,
+ uint32_t block_type, bool gate, int inst);
int (*set_clockgating_by_smu)(void *handle, uint32_t msg_id);
int (*set_power_limit)(void *handle, uint32_t n);
int (*get_power_limit)(void *handle, uint32_t *limit,
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
index 9dc82f4d7c93..f2d2f85476dc 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
@@ -110,6 +110,49 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
return ret;
}
+int amdgpu_dpm_set_powergating_by_smu_instance(struct amdgpu_device *adev, uint32_t block_type, bool gate, int inst)
+{
+ int ret = 0;
+ const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+ enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON;
+ bool is_vcn = (block_type == AMD_IP_BLOCK_TYPE_UVD || block_type == AMD_IP_BLOCK_TYPE_VCN);
+
+ if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state &&
+ (!is_vcn || adev->vcn.num_vcn_inst == 1)) {
+ dev_dbg(adev->dev, "IP block%d already in the target %s state!",
+ block_type, gate ? "gate" : "ungate");
+ return 0;
+ }
+
+ mutex_lock(&adev->pm.mutex);
+
+ switch (block_type) {
+ case AMD_IP_BLOCK_TYPE_UVD:
+ case AMD_IP_BLOCK_TYPE_VCE:
+ case AMD_IP_BLOCK_TYPE_GFX:
+ case AMD_IP_BLOCK_TYPE_VCN:
+ case AMD_IP_BLOCK_TYPE_SDMA:
+ case AMD_IP_BLOCK_TYPE_JPEG:
+ case AMD_IP_BLOCK_TYPE_GMC:
+ case AMD_IP_BLOCK_TYPE_ACP:
+ case AMD_IP_BLOCK_TYPE_VPE:
+ if (pp_funcs && pp_funcs->set_powergating_by_smu_instance) {
+ ret = (pp_funcs->set_powergating_by_smu_instance(
+ (adev)->powerplay.pp_handle, block_type, gate, inst));
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!ret)
+ atomic_set(&adev->pm.pwr_state[block_type], pwr_state);
+
+ mutex_unlock(&adev->pm.mutex);
+
+ return ret;
+}
+
int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev)
{
struct smu_context *smu = adev->powerplay.pp_handle;
@@ -572,6 +615,30 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
enable ? "enable" : "disable", ret);
}
+void amdgpu_dpm_enable_vcn(struct amdgpu_device *adev, bool enable, int inst)
+{
+ int ret = 0;
+
+ if (adev->family == AMDGPU_FAMILY_SI) {
+ mutex_lock(&adev->pm.mutex);
+ if (enable) {
+ adev->pm.dpm.uvd_active = true;
+ adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
+ } else {
+ adev->pm.dpm.uvd_active = false;
+ }
+ mutex_unlock(&adev->pm.mutex);
+
+ amdgpu_dpm_compute_clocks(adev);
+ return;
+ }
+
+ ret = amdgpu_dpm_set_powergating_by_smu_instance(adev, AMD_IP_BLOCK_TYPE_UVD, !enable, inst);
+ if (ret)
+ DRM_ERROR("Dpm %s uvd failed, ret = %d. \n",
+ enable ? "enable" : "disable", ret);
+}
+
void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
{
int ret = 0;
diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
index f5bf41f21c41..f4cd60ffba47 100644
--- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h
@@ -395,6 +395,9 @@ int amdgpu_dpm_set_apu_thermal_limit(struct amdgpu_device *adev, uint32_t limit)
int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev,
uint32_t block_type, bool gate);
+int amdgpu_dpm_set_powergating_by_smu_instance(struct amdgpu_device *adev,
+ uint32_t block_type, bool gate, int inst);
+
extern int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low);
extern int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low);
@@ -442,6 +445,7 @@ void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev);
void amdgpu_dpm_compute_clocks(struct amdgpu_device *adev);
void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable);
+void amdgpu_dpm_enable_vcn(struct amdgpu_device *adev, bool enable, int inst);
void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable);
void amdgpu_dpm_enable_jpeg(struct amdgpu_device *adev, bool enable);
void amdgpu_dpm_enable_vpe(struct amdgpu_device *adev, bool enable);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index ddfed7189708..449925105889 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -3744,6 +3744,7 @@ static const struct amd_pm_funcs swsmu_pm_funcs = {
.dispatch_tasks = smu_handle_dpm_task,
.load_firmware = smu_load_microcode,
.set_powergating_by_smu = smu_dpm_set_power_gate,
+ .set_powergating_by_smu_instance = smu_dpm_set_power_gate_instance,
.set_power_limit = smu_set_power_limit,
.get_power_limit = smu_get_power_limit,
.get_power_profile_mode = smu_get_power_profile_mode,
--
2.34.1
More information about the amd-gfx
mailing list