diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/si_dpm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/si_dpm.c | 75 |
1 files changed, 59 insertions, 16 deletions
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index eff8a6444956..7be11651b7e6 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -1756,6 +1756,9 @@ static int si_calculate_sclk_params(struct radeon_device *rdev, u32 engine_clock, SISLANDS_SMC_SCLK_VALUE *sclk); +static void si_thermal_start_smc_fan_control(struct radeon_device *rdev); +static void si_fan_ctrl_set_default_mode(struct radeon_device *rdev); + static struct si_power_info *si_get_pi(struct radeon_device *rdev) { struct si_power_info *pi = rdev->pm.dpm.priv; @@ -3359,11 +3362,13 @@ int si_dpm_force_performance_level(struct radeon_device *rdev, return 0; } +#if 0 static int si_set_boot_state(struct radeon_device *rdev) { return (si_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToInitialState) == PPSMC_Result_OK) ? 0 : -EINVAL; } +#endif static int si_set_sw_state(struct radeon_device *rdev) { @@ -5973,6 +5978,10 @@ static int si_thermal_setup_fan_table(struct radeon_device *rdev) slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); + fan_table.temp_min = cpu_to_be16((50 + rdev->pm.dpm.fan.t_min) / 100); + fan_table.temp_med = cpu_to_be16((50 + rdev->pm.dpm.fan.t_med) / 100); + fan_table.temp_max = cpu_to_be16((50 + rdev->pm.dpm.fan.t_max) / 100); + fan_table.slope1 = cpu_to_be16(slope1); fan_table.slope2 = cpu_to_be16(slope2); @@ -6012,29 +6021,35 @@ static int si_thermal_setup_fan_table(struct radeon_device *rdev) static int si_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev) { + struct si_power_info *si_pi = si_get_pi(rdev); PPSMC_Result ret; ret = si_send_msg_to_smc(rdev, PPSMC_StartFanControl); - if (ret == PPSMC_Result_OK) + if (ret == PPSMC_Result_OK) { + si_pi->fan_is_controlled_by_smc = true; return 0; - else + } else { return -EINVAL; + } } static int si_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) { + struct si_power_info *si_pi = si_get_pi(rdev); PPSMC_Result ret; ret = si_send_msg_to_smc(rdev, PPSMC_StopFanControl); - if (ret == PPSMC_Result_OK) + + if (ret == PPSMC_Result_OK) { + si_pi->fan_is_controlled_by_smc = false; return 0; - else + } else { return -EINVAL; + } } -#if 0 -static int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, - u32 *speed) +int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, + u32 *speed) { u32 duty, duty100; u64 tmp64; @@ -6058,9 +6073,10 @@ static int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, return 0; } -static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, - u32 speed) +int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, + u32 speed) { + struct si_power_info *si_pi = si_get_pi(rdev); u32 tmp; u32 duty, duty100; u64 tmp64; @@ -6068,11 +6084,11 @@ static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, if (rdev->pm.no_fan) return -ENOENT; - if (speed > 100) + if (si_pi->fan_is_controlled_by_smc) return -EINVAL; - if (rdev->pm.dpm.fan.ucode_fan_control) - si_fan_ctrl_stop_smc_fan_control(rdev); + if (speed > 100) + return -EINVAL; duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; @@ -6087,11 +6103,38 @@ static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, tmp |= FDO_STATIC_DUTY(duty); WREG32(CG_FDO_CTRL0, tmp); - si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); - return 0; } +void si_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode) +{ + if (mode) { + /* stop auto-manage */ + if (rdev->pm.dpm.fan.ucode_fan_control) + si_fan_ctrl_stop_smc_fan_control(rdev); + si_fan_ctrl_set_static_mode(rdev, mode); + } else { + /* restart auto-manage */ + if (rdev->pm.dpm.fan.ucode_fan_control) + si_thermal_start_smc_fan_control(rdev); + else + si_fan_ctrl_set_default_mode(rdev); + } +} + +u32 si_fan_ctrl_get_mode(struct radeon_device *rdev) +{ + struct si_power_info *si_pi = si_get_pi(rdev); + u32 tmp; + + if (si_pi->fan_is_controlled_by_smc) + return 0; + + tmp = RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK; + return (tmp >> FDO_PWM_MODE_SHIFT); +} + +#if 0 static int si_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev, u32 *speed) { @@ -6538,13 +6581,14 @@ void si_dpm_post_set_power_state(struct radeon_device *rdev) ni_update_current_ps(rdev, new_ps); } - +#if 0 void si_dpm_reset_asic(struct radeon_device *rdev) { si_restrict_performance_levels_before_switch(rdev); si_disable_ulv(rdev); si_set_boot_state(rdev); } +#endif void si_dpm_display_configuration_changed(struct radeon_device *rdev) { @@ -6912,7 +6956,6 @@ int si_dpm_init(struct radeon_device *rdev) rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; si_pi->fan_ctrl_is_in_default_mode = true; - rdev->pm.dpm.fan.ucode_fan_control = false; return 0; } |