Commit 9c822141 authored by Huang Rui's avatar Huang Rui Committed by Alex Deucher

drm/amd/powerplay: add gfx off control function

gfx_off_control is used to be called for sending enabling/disabling gfxoff
message.
Signed-off-by: default avatarHuang Rui <ray.huang@amd.com>
Reviewed-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 917d8614
...@@ -42,6 +42,13 @@ ...@@ -42,6 +42,13 @@
#define SMU10_DISPCLK_BYPASS_THRESHOLD 10000 /* 100Mhz */ #define SMU10_DISPCLK_BYPASS_THRESHOLD 10000 /* 100Mhz */
#define SMC_RAM_END 0x40000 #define SMC_RAM_END 0x40000
#define mmPWR_MISC_CNTL_STATUS 0x0183
#define mmPWR_MISC_CNTL_STATUS_BASE_IDX 0
#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN__SHIFT 0x0
#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT 0x1
#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK 0x00000001L
#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK 0x00000006L
static const unsigned long SMU10_Magic = (unsigned long) PHM_Rv_Magic; static const unsigned long SMU10_Magic = (unsigned long) PHM_Rv_Magic;
...@@ -243,13 +250,31 @@ static int smu10_power_off_asic(struct pp_hwmgr *hwmgr) ...@@ -243,13 +250,31 @@ static int smu10_power_off_asic(struct pp_hwmgr *hwmgr)
return smu10_reset_cc6_data(hwmgr); return smu10_reset_cc6_data(hwmgr);
} }
static bool smu10_is_gfx_on(struct pp_hwmgr *hwmgr)
{
uint32_t reg;
struct amdgpu_device *adev = hwmgr->adev;
reg = RREG32_SOC15(PWR, 0, mmPWR_MISC_CNTL_STATUS);
if ((reg & PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK) ==
(0x2 << PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT))
return true;
return false;
}
static int smu10_disable_gfx_off(struct pp_hwmgr *hwmgr) static int smu10_disable_gfx_off(struct pp_hwmgr *hwmgr)
{ {
struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
if (smu10_data->gfx_off_controled_by_driver) if (smu10_data->gfx_off_controled_by_driver) {
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableGfxOff); smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableGfxOff);
/* confirm gfx is back to "on" state */
while (!smu10_is_gfx_on(hwmgr))
msleep(1);
}
return 0; return 0;
} }
...@@ -273,6 +298,14 @@ static int smu10_enable_dpm_tasks(struct pp_hwmgr *hwmgr) ...@@ -273,6 +298,14 @@ static int smu10_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
return smu10_enable_gfx_off(hwmgr); return smu10_enable_gfx_off(hwmgr);
} }
static int smu10_gfx_off_control(struct pp_hwmgr *hwmgr, bool enable)
{
if (enable)
return smu10_enable_gfx_off(hwmgr);
else
return smu10_disable_gfx_off(hwmgr);
}
static int smu10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, static int smu10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
struct pp_power_state *prequest_ps, struct pp_power_state *prequest_ps,
const struct pp_power_state *pcurrent_ps) const struct pp_power_state *pcurrent_ps)
...@@ -1060,6 +1093,7 @@ static const struct pp_hwmgr_func smu10_hwmgr_funcs = { ...@@ -1060,6 +1093,7 @@ static const struct pp_hwmgr_func smu10_hwmgr_funcs = {
.power_state_set = smu10_set_power_state_tasks, .power_state_set = smu10_set_power_state_tasks,
.dynamic_state_management_disable = smu10_disable_dpm_tasks, .dynamic_state_management_disable = smu10_disable_dpm_tasks,
.set_mmhub_powergating_by_smu = smu10_set_mmhub_powergating_by_smu, .set_mmhub_powergating_by_smu = smu10_set_mmhub_powergating_by_smu,
.gfx_off_control = smu10_gfx_off_control,
}; };
int smu10_init_function_pointers(struct pp_hwmgr *hwmgr) int smu10_init_function_pointers(struct pp_hwmgr *hwmgr)
......
...@@ -296,6 +296,7 @@ struct pp_hwmgr_func { ...@@ -296,6 +296,7 @@ struct pp_hwmgr_func {
int (*display_clock_voltage_request)(struct pp_hwmgr *hwmgr, int (*display_clock_voltage_request)(struct pp_hwmgr *hwmgr,
struct pp_display_clock_request *clock); struct pp_display_clock_request *clock);
int (*get_max_high_clocks)(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks); int (*get_max_high_clocks)(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks);
int (*gfx_off_control)(struct pp_hwmgr *hwmgr, bool enable);
int (*power_off_asic)(struct pp_hwmgr *hwmgr); int (*power_off_asic)(struct pp_hwmgr *hwmgr);
int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask); int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, uint32_t mask);
int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf); int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment