forked from Minki/linux
drm/amd/powerplay: add SMU mode1 reset
From PM FW 58.26.0 for sienna cichlid, SMU mode1 reset is support, driver sends PPSMC_MSG_Mode1Reset message to PM FW could trigger this reset. v2: add mode1 reset dpm interface v3: change maro name Signed-off-by: Likun Gao <Likun.Gao@amd.com> Signed-off-by: Wenhui Sheng <Wenhui.Sheng@amd.com> Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
a4497974ed
commit
ea8139d8d5
@ -1139,6 +1139,26 @@ int amdgpu_dpm_baco_reset(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev)
|
||||
{
|
||||
struct smu_context *smu = &adev->smu;
|
||||
|
||||
if (is_support_sw_smu(adev))
|
||||
return smu_mode1_reset_is_support(smu);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
struct smu_context *smu = &adev->smu;
|
||||
|
||||
if (is_support_sw_smu(adev))
|
||||
return smu_mode1_reset(smu);
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
|
||||
enum PP_SMC_POWER_PROFILE type,
|
||||
bool en)
|
||||
|
@ -529,6 +529,9 @@ int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev);
|
||||
|
||||
bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev);
|
||||
|
||||
bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev);
|
||||
int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev);
|
||||
|
||||
int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
|
||||
enum pp_mp1_state mp1_state);
|
||||
|
||||
|
@ -2616,6 +2616,40 @@ int smu_baco_exit(struct smu_context *smu)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool smu_mode1_reset_is_support(struct smu_context *smu)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (!smu->pm_enabled)
|
||||
return false;
|
||||
|
||||
mutex_lock(&smu->mutex);
|
||||
|
||||
if (smu->ppt_funcs && smu->ppt_funcs->mode1_reset_is_support)
|
||||
ret = smu->ppt_funcs->mode1_reset_is_support(smu);
|
||||
|
||||
mutex_unlock(&smu->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int smu_mode1_reset(struct smu_context *smu)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!smu->pm_enabled)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mutex_lock(&smu->mutex);
|
||||
|
||||
if (smu->ppt_funcs->mode1_reset)
|
||||
ret = smu->ppt_funcs->mode1_reset(smu);
|
||||
|
||||
mutex_unlock(&smu->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int smu_mode2_reset(struct smu_context *smu)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -557,6 +557,8 @@ struct pptable_funcs {
|
||||
int (*baco_set_state)(struct smu_context *smu, enum smu_baco_state state);
|
||||
int (*baco_enter)(struct smu_context *smu);
|
||||
int (*baco_exit)(struct smu_context *smu);
|
||||
bool (*mode1_reset_is_support)(struct smu_context *smu);
|
||||
int (*mode1_reset)(struct smu_context *smu);
|
||||
int (*mode2_reset)(struct smu_context *smu);
|
||||
int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max);
|
||||
int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max);
|
||||
@ -668,6 +670,8 @@ int smu_baco_get_state(struct smu_context *smu, enum smu_baco_state *state);
|
||||
int smu_baco_enter(struct smu_context *smu);
|
||||
int smu_baco_exit(struct smu_context *smu);
|
||||
|
||||
bool smu_mode1_reset_is_support(struct smu_context *smu);
|
||||
int smu_mode1_reset(struct smu_context *smu);
|
||||
int smu_mode2_reset(struct smu_context *smu);
|
||||
|
||||
extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
|
||||
|
@ -173,6 +173,7 @@
|
||||
__SMU_DUMMY_MAP(GmiPwrDnControl), \
|
||||
__SMU_DUMMY_MAP(DAL_DISABLE_DUMMY_PSTATE_CHANGE), \
|
||||
__SMU_DUMMY_MAP(DAL_ENABLE_DUMMY_PSTATE_CHANGE), \
|
||||
__SMU_DUMMY_MAP(Mode1Reset), \
|
||||
|
||||
#undef __SMU_DUMMY_MAP
|
||||
#define __SMU_DUMMY_MAP(type) SMU_MSG_##type
|
||||
|
@ -246,6 +246,8 @@ int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state)
|
||||
int smu_v11_0_baco_enter(struct smu_context *smu);
|
||||
int smu_v11_0_baco_exit(struct smu_context *smu);
|
||||
|
||||
int smu_v11_0_mode1_reset(struct smu_context *smu);
|
||||
|
||||
int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||
uint32_t *min, uint32_t *max);
|
||||
|
||||
|
@ -39,8 +39,8 @@
|
||||
#include "nbio/nbio_2_3_sh_mask.h"
|
||||
#include "thm/thm_11_0_2_offset.h"
|
||||
#include "thm/thm_11_0_2_sh_mask.h"
|
||||
|
||||
#include "asic_reg/mp/mp_11_0_sh_mask.h"
|
||||
#include "mp/mp_11_0_offset.h"
|
||||
#include "mp/mp_11_0_sh_mask.h"
|
||||
|
||||
/*
|
||||
* DO NOT use these for err/warn/info/debug messages.
|
||||
@ -116,6 +116,7 @@ static struct smu_11_0_cmn2aisc_mapping sienna_cichlid_message_map[SMU_MSG_MAX_C
|
||||
MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg),
|
||||
MSG_MAP(BacoAudioD3PME, PPSMC_MSG_BacoAudioD3PME),
|
||||
MSG_MAP(ArmD3, PPSMC_MSG_ArmD3),
|
||||
MSG_MAP(Mode1Reset, PPSMC_MSG_Mode1Reset),
|
||||
};
|
||||
|
||||
static struct smu_11_0_cmn2aisc_mapping sienna_cichlid_clk_map[SMU_CLK_COUNT] = {
|
||||
@ -1779,6 +1780,28 @@ static bool sienna_cichlid_is_baco_supported(struct smu_context *smu)
|
||||
return (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true : false;
|
||||
}
|
||||
|
||||
static bool sienna_cichlid_is_mode1_reset_supported(struct smu_context *smu)
|
||||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
uint32_t val;
|
||||
u32 smu_version;
|
||||
|
||||
/**
|
||||
* SRIOV env will not support SMU mode1 reset
|
||||
* PM FW support mode1 reset from 58.26
|
||||
*/
|
||||
smu_get_smc_version(smu, NULL, &smu_version);
|
||||
if (amdgpu_sriov_vf(adev) || (smu_version < 0x003a1a00))
|
||||
return false;
|
||||
|
||||
/**
|
||||
* mode1 reset relies on PSP, so we should check if
|
||||
* PSP is alive.
|
||||
*/
|
||||
val = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
|
||||
return val != 0x0;
|
||||
}
|
||||
|
||||
static int sienna_cichlid_set_thermal_range(struct smu_context *smu,
|
||||
struct smu_temperature_range range)
|
||||
{
|
||||
@ -2547,6 +2570,8 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = {
|
||||
.baco_set_state = smu_v11_0_baco_set_state,
|
||||
.baco_enter = smu_v11_0_baco_enter,
|
||||
.baco_exit = smu_v11_0_baco_exit,
|
||||
.mode1_reset_is_support = sienna_cichlid_is_mode1_reset_supported,
|
||||
.mode1_reset = smu_v11_0_mode1_reset,
|
||||
.get_dpm_ultimate_freq = sienna_cichlid_get_dpm_ultimate_freq,
|
||||
.set_soft_freq_limited_range = sienna_cichlid_set_soft_freq_limited_range,
|
||||
.override_pcie_parameters = smu_v11_0_override_pcie_parameters,
|
||||
|
@ -63,6 +63,8 @@ MODULE_FIRMWARE("amdgpu/sienna_cichlid_smc.bin");
|
||||
|
||||
#define SMU11_VOLTAGE_SCALE 4
|
||||
|
||||
#define SMU11_MODE1_RESET_WAIT_TIME_IN_MS 500 //500ms
|
||||
|
||||
static int smu_v11_0_send_msg_without_waiting(struct smu_context *smu,
|
||||
uint16_t msg)
|
||||
{
|
||||
@ -1694,6 +1696,17 @@ int smu_v11_0_baco_exit(struct smu_context *smu)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int smu_v11_0_mode1_reset(struct smu_context *smu)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = smu_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL);
|
||||
if (!ret)
|
||||
msleep(SMU11_MODE1_RESET_WAIT_TIME_IN_MS);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
|
||||
uint32_t *min, uint32_t *max)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user