drm/amdgpu: optimize RLC powerdown notification on Vangogh
The smu needs to get the rlc power down message to sync the rlc state with smu, the rlc state updating message need to be sent at while smu begin suspend sequence , otherwise SMU will crash while RLC state is not notified by driver, and rlc state probally changed after that notification, so it needs to notify rlc state to smu at the end of the suspend sequence in amdgpu_device_suspend() that can make sure the rlc state is correctly set to SMU. [ 101.000590] amdgpu 0000:03:00.0: amdgpu: SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x0000001E SMN_C2PMSG_82:0x00000000 [ 101.000598] amdgpu 0000:03:00.0: amdgpu: Failed to disable gfxoff! [ 110.838026] amdgpu 0000:03:00.0: amdgpu: SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x0000001E SMN_C2PMSG_82:0x00000000 [ 110.838035] amdgpu 0000:03:00.0: amdgpu: Failed to disable smu features. [ 110.838039] amdgpu 0000:03:00.0: amdgpu: Fail to disable dpm features! [ 110.838040] [drm:amdgpu_device_ip_suspend_phase2 [amdgpu]] *ERROR* suspend of IP block <smu> failed -62 [ 110.884394] PM: suspend of devices aborted after 21213.620 msecs [ 110.884402] PM: start suspend of devices aborted after 21213.882 msecs [ 110.884405] PM: Some devices failed to suspend, or early wake event detected Reviewed-by: Yifan Zhang <yifan1.zhang@amd.com> Signed-off-by: Perry Yuan <perry.yuan@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
dc9b0c2af0
commit
8c4e9105b2
@ -4538,6 +4538,10 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
|||||||
if (amdgpu_sriov_vf(adev))
|
if (amdgpu_sriov_vf(adev))
|
||||||
amdgpu_virt_release_full_gpu(adev, false);
|
amdgpu_virt_release_full_gpu(adev, false);
|
||||||
|
|
||||||
|
r = amdgpu_dpm_notify_rlc_state(adev, false);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,6 +444,7 @@ struct amd_pm_funcs {
|
|||||||
struct dpm_clocks *clock_table);
|
struct dpm_clocks *clock_table);
|
||||||
int (*get_smu_prv_buf_details)(void *handle, void **addr, size_t *size);
|
int (*get_smu_prv_buf_details)(void *handle, void **addr, size_t *size);
|
||||||
void (*pm_compute_clocks)(void *handle);
|
void (*pm_compute_clocks)(void *handle);
|
||||||
|
int (*notify_rlc_state)(void *handle, bool en);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct metrics_table_header {
|
struct metrics_table_header {
|
||||||
|
@ -181,6 +181,24 @@ int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||||
|
|
||||||
|
if (pp_funcs && pp_funcs->notify_rlc_state) {
|
||||||
|
mutex_lock(&adev->pm.mutex);
|
||||||
|
|
||||||
|
ret = pp_funcs->notify_rlc_state(
|
||||||
|
adev->powerplay.pp_handle,
|
||||||
|
en);
|
||||||
|
|
||||||
|
mutex_unlock(&adev->pm.mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
|
bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||||
|
@ -415,6 +415,8 @@ int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev);
|
|||||||
int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
|
int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
|
||||||
enum pp_mp1_state mp1_state);
|
enum pp_mp1_state mp1_state);
|
||||||
|
|
||||||
|
int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en);
|
||||||
|
|
||||||
int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev);
|
int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev);
|
||||||
|
|
||||||
int amdgpu_dpm_baco_exit(struct amdgpu_device *adev);
|
int amdgpu_dpm_baco_exit(struct amdgpu_device *adev);
|
||||||
|
@ -1710,6 +1710,16 @@ static int smu_disable_dpms(struct smu_context *smu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Notify SMU RLC is going to be off, stop RLC and SMU interaction.
|
||||||
|
* otherwise SMU will hang while interacting with RLC if RLC is halted
|
||||||
|
* this is a WA for Vangogh asic which fix the SMU hang issue.
|
||||||
|
*/
|
||||||
|
ret = smu_notify_rlc_state(smu, false);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(adev->dev, "Fail to notify rlc status!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 4, 2) &&
|
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 4, 2) &&
|
||||||
!((adev->flags & AMD_IS_APU) && adev->gfx.imu.funcs) &&
|
!((adev->flags & AMD_IS_APU) && adev->gfx.imu.funcs) &&
|
||||||
!amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs->stop)
|
!amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs->stop)
|
||||||
|
@ -1360,6 +1360,11 @@ struct pptable_funcs {
|
|||||||
* management.
|
* management.
|
||||||
*/
|
*/
|
||||||
int (*dpm_set_umsch_mm_enable)(struct smu_context *smu, bool enable);
|
int (*dpm_set_umsch_mm_enable)(struct smu_context *smu, bool enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notify_rlc_state: Notify RLC power state to SMU.
|
||||||
|
*/
|
||||||
|
int (*notify_rlc_state)(struct smu_context *smu, bool en);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -2193,8 +2193,7 @@ static int vangogh_get_dpm_clock_table(struct smu_context *smu, struct dpm_clock
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vangogh_notify_rlc_state(struct smu_context *smu, bool en)
|
||||||
static int vangogh_system_features_control(struct smu_context *smu, bool en)
|
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = smu->adev;
|
struct amdgpu_device *adev = smu->adev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -2523,7 +2522,7 @@ static const struct pptable_funcs vangogh_ppt_funcs = {
|
|||||||
.print_clk_levels = vangogh_common_print_clk_levels,
|
.print_clk_levels = vangogh_common_print_clk_levels,
|
||||||
.set_default_dpm_table = vangogh_set_default_dpm_tables,
|
.set_default_dpm_table = vangogh_set_default_dpm_tables,
|
||||||
.set_fine_grain_gfx_freq_parameters = vangogh_set_fine_grain_gfx_freq_parameters,
|
.set_fine_grain_gfx_freq_parameters = vangogh_set_fine_grain_gfx_freq_parameters,
|
||||||
.system_features_control = vangogh_system_features_control,
|
.notify_rlc_state = vangogh_notify_rlc_state,
|
||||||
.feature_is_enabled = smu_cmn_feature_is_enabled,
|
.feature_is_enabled = smu_cmn_feature_is_enabled,
|
||||||
.set_power_profile_mode = vangogh_set_power_profile_mode,
|
.set_power_profile_mode = vangogh_set_power_profile_mode,
|
||||||
.get_power_profile_mode = vangogh_get_power_profile_mode,
|
.get_power_profile_mode = vangogh_get_power_profile_mode,
|
||||||
|
@ -97,6 +97,7 @@
|
|||||||
#define smu_get_default_config_table_settings(smu, config_table) smu_ppt_funcs(get_default_config_table_settings, -EOPNOTSUPP, smu, config_table)
|
#define smu_get_default_config_table_settings(smu, config_table) smu_ppt_funcs(get_default_config_table_settings, -EOPNOTSUPP, smu, config_table)
|
||||||
#define smu_set_config_table(smu, config_table) smu_ppt_funcs(set_config_table, -EOPNOTSUPP, smu, config_table)
|
#define smu_set_config_table(smu, config_table) smu_ppt_funcs(set_config_table, -EOPNOTSUPP, smu, config_table)
|
||||||
#define smu_init_pptable_microcode(smu) smu_ppt_funcs(init_pptable_microcode, 0, smu)
|
#define smu_init_pptable_microcode(smu) smu_ppt_funcs(init_pptable_microcode, 0, smu)
|
||||||
|
#define smu_notify_rlc_state(smu, en) smu_ppt_funcs(notify_rlc_state, 0, smu, en)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user