diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2014-09-14 21:14:14 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2014-11-20 13:00:09 -0500 |
commit | 39471ad39de827657e6ab69da96496eb0943295e (patch) | |
tree | d3b65da5462d797edb86d2c785796bf355e2cf3b /drivers/gpu | |
parent | 4bb62c95a7e781a238b2ab374f34b1bf91e01ddc (diff) |
drm/radeon/dpm: add smc fan control for SI (v2)
Enable smc fan control for SI boards. Should
reduce the fan noise on systems with a higher
default fan profile.
v2: disable by default, add rpm controls
bug:
https://bugs.freedesktop.org/show_bug.cgi?id=73338
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/ppsmc.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600_dpm.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si_dpm.c | 330 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si_dpm.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/sid.h | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/sislands_smc.h | 25 |
6 files changed, 401 insertions, 7 deletions
diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h index 11c0e4d5c0bf..0c4eaa60b6ca 100644 --- a/drivers/gpu/drm/radeon/ppsmc.h +++ b/drivers/gpu/drm/radeon/ppsmc.h | |||
@@ -56,6 +56,9 @@ | |||
56 | #define PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE 0x20 | 56 | #define PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE 0x20 |
57 | #define PPSMC_STATEFLAG_DEEPSLEEP_BYPASS 0x40 | 57 | #define PPSMC_STATEFLAG_DEEPSLEEP_BYPASS 0x40 |
58 | 58 | ||
59 | #define FDO_MODE_HARDWARE 0 | ||
60 | #define FDO_MODE_PIECE_WISE_LINEAR 1 | ||
61 | |||
59 | #define PPSMC_Result_OK ((uint8_t)0x01) | 62 | #define PPSMC_Result_OK ((uint8_t)0x01) |
60 | #define PPSMC_Result_Failed ((uint8_t)0xFF) | 63 | #define PPSMC_Result_Failed ((uint8_t)0xFF) |
61 | 64 | ||
@@ -79,6 +82,8 @@ typedef uint8_t PPSMC_Result; | |||
79 | #define PPSMC_MSG_DisableCac ((uint8_t)0x54) | 82 | #define PPSMC_MSG_DisableCac ((uint8_t)0x54) |
80 | #define PPSMC_TDPClampingActive ((uint8_t)0x59) | 83 | #define PPSMC_TDPClampingActive ((uint8_t)0x59) |
81 | #define PPSMC_TDPClampingInactive ((uint8_t)0x5A) | 84 | #define PPSMC_TDPClampingInactive ((uint8_t)0x5A) |
85 | #define PPSMC_StartFanControl ((uint8_t)0x5B) | ||
86 | #define PPSMC_StopFanControl ((uint8_t)0x5C) | ||
82 | #define PPSMC_MSG_NoDisplay ((uint8_t)0x5D) | 87 | #define PPSMC_MSG_NoDisplay ((uint8_t)0x5D) |
83 | #define PPSMC_MSG_HasDisplay ((uint8_t)0x5E) | 88 | #define PPSMC_MSG_HasDisplay ((uint8_t)0x5E) |
84 | #define PPSMC_MSG_UVDPowerOFF ((uint8_t)0x60) | 89 | #define PPSMC_MSG_UVDPowerOFF ((uint8_t)0x60) |
diff --git a/drivers/gpu/drm/radeon/r600_dpm.h b/drivers/gpu/drm/radeon/r600_dpm.h index 46b9d2a03018..bd499d749bc9 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.h +++ b/drivers/gpu/drm/radeon/r600_dpm.h | |||
@@ -96,6 +96,9 @@ | |||
96 | #define R600_TEMP_RANGE_MIN (90 * 1000) | 96 | #define R600_TEMP_RANGE_MIN (90 * 1000) |
97 | #define R600_TEMP_RANGE_MAX (120 * 1000) | 97 | #define R600_TEMP_RANGE_MAX (120 * 1000) |
98 | 98 | ||
99 | #define FDO_PWM_MODE_STATIC 1 | ||
100 | #define FDO_PWM_MODE_STATIC_RPM 5 | ||
101 | |||
99 | enum r600_power_level { | 102 | enum r600_power_level { |
100 | R600_POWER_LEVEL_LOW = 0, | 103 | R600_POWER_LEVEL_LOW = 0, |
101 | R600_POWER_LEVEL_MEDIUM = 1, | 104 | R600_POWER_LEVEL_MEDIUM = 1, |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index b59e1d6b27ab..cf4c420b5572 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -3398,6 +3398,15 @@ static int si_process_firmware_header(struct radeon_device *rdev) | |||
3398 | 3398 | ||
3399 | ret = si_read_smc_sram_dword(rdev, | 3399 | ret = si_read_smc_sram_dword(rdev, |
3400 | SISLANDS_SMC_FIRMWARE_HEADER_LOCATION + | 3400 | SISLANDS_SMC_FIRMWARE_HEADER_LOCATION + |
3401 | SISLANDS_SMC_FIRMWARE_HEADER_fanTable, | ||
3402 | &tmp, si_pi->sram_end); | ||
3403 | if (ret) | ||
3404 | return ret; | ||
3405 | |||
3406 | si_pi->fan_table_start = tmp; | ||
3407 | |||
3408 | ret = si_read_smc_sram_dword(rdev, | ||
3409 | SISLANDS_SMC_FIRMWARE_HEADER_LOCATION + | ||
3401 | SISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable, | 3410 | SISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable, |
3402 | &tmp, si_pi->sram_end); | 3411 | &tmp, si_pi->sram_end); |
3403 | if (ret) | 3412 | if (ret) |
@@ -5825,20 +5834,20 @@ static int si_thermal_enable_alert(struct radeon_device *rdev, | |||
5825 | if (enable) { | 5834 | if (enable) { |
5826 | PPSMC_Result result; | 5835 | PPSMC_Result result; |
5827 | 5836 | ||
5828 | thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; | 5837 | thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); |
5829 | rdev->irq.dpm_thermal = true; | 5838 | WREG32(CG_THERMAL_INT, thermal_int); |
5839 | rdev->irq.dpm_thermal = false; | ||
5830 | result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); | 5840 | result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); |
5831 | if (result != PPSMC_Result_OK) { | 5841 | if (result != PPSMC_Result_OK) { |
5832 | DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); | 5842 | DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); |
5833 | return -EINVAL; | 5843 | return -EINVAL; |
5834 | } | 5844 | } |
5835 | } else { | 5845 | } else { |
5836 | thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); | 5846 | thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; |
5837 | rdev->irq.dpm_thermal = false; | 5847 | WREG32(CG_THERMAL_INT, thermal_int); |
5848 | rdev->irq.dpm_thermal = true; | ||
5838 | } | 5849 | } |
5839 | 5850 | ||
5840 | WREG32(CG_THERMAL_INT, thermal_int); | ||
5841 | |||
5842 | return 0; | 5851 | return 0; |
5843 | } | 5852 | } |
5844 | 5853 | ||
@@ -5867,6 +5876,309 @@ static int si_thermal_set_temperature_range(struct radeon_device *rdev, | |||
5867 | return 0; | 5876 | return 0; |
5868 | } | 5877 | } |
5869 | 5878 | ||
5879 | static void si_fan_ctrl_set_static_mode(struct radeon_device *rdev, u32 mode) | ||
5880 | { | ||
5881 | struct si_power_info *si_pi = si_get_pi(rdev); | ||
5882 | u32 tmp; | ||
5883 | |||
5884 | if (si_pi->fan_ctrl_is_in_default_mode) { | ||
5885 | tmp = (RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK) >> FDO_PWM_MODE_SHIFT; | ||
5886 | si_pi->fan_ctrl_default_mode = tmp; | ||
5887 | tmp = (RREG32(CG_FDO_CTRL2) & TMIN_MASK) >> TMIN_SHIFT; | ||
5888 | si_pi->t_min = tmp; | ||
5889 | si_pi->fan_ctrl_is_in_default_mode = false; | ||
5890 | } | ||
5891 | |||
5892 | tmp = RREG32(CG_FDO_CTRL2) & ~TMIN_MASK; | ||
5893 | tmp |= TMIN(0); | ||
5894 | WREG32(CG_FDO_CTRL2, tmp); | ||
5895 | |||
5896 | tmp = RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK; | ||
5897 | tmp |= FDO_PWM_MODE(mode); | ||
5898 | WREG32(CG_FDO_CTRL2, tmp); | ||
5899 | } | ||
5900 | |||
5901 | static int si_thermal_setup_fan_table(struct radeon_device *rdev) | ||
5902 | { | ||
5903 | struct si_power_info *si_pi = si_get_pi(rdev); | ||
5904 | PP_SIslands_FanTable fan_table = { FDO_MODE_HARDWARE }; | ||
5905 | u32 duty100; | ||
5906 | u32 t_diff1, t_diff2, pwm_diff1, pwm_diff2; | ||
5907 | u16 fdo_min, slope1, slope2; | ||
5908 | u32 reference_clock, tmp; | ||
5909 | int ret; | ||
5910 | u64 tmp64; | ||
5911 | |||
5912 | if (!si_pi->fan_table_start) { | ||
5913 | rdev->pm.dpm.fan.ucode_fan_control = false; | ||
5914 | return 0; | ||
5915 | } | ||
5916 | |||
5917 | duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; | ||
5918 | |||
5919 | if (duty100 == 0) { | ||
5920 | rdev->pm.dpm.fan.ucode_fan_control = false; | ||
5921 | return 0; | ||
5922 | } | ||
5923 | |||
5924 | tmp64 = (u64)rdev->pm.dpm.fan.pwm_min * duty100; | ||
5925 | do_div(tmp64, 10000); | ||
5926 | fdo_min = (u16)tmp64; | ||
5927 | |||
5928 | t_diff1 = rdev->pm.dpm.fan.t_med - rdev->pm.dpm.fan.t_min; | ||
5929 | t_diff2 = rdev->pm.dpm.fan.t_high - rdev->pm.dpm.fan.t_med; | ||
5930 | |||
5931 | pwm_diff1 = rdev->pm.dpm.fan.pwm_med - rdev->pm.dpm.fan.pwm_min; | ||
5932 | pwm_diff2 = rdev->pm.dpm.fan.pwm_high - rdev->pm.dpm.fan.pwm_med; | ||
5933 | |||
5934 | slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); | ||
5935 | slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); | ||
5936 | |||
5937 | fan_table.slope1 = cpu_to_be16(slope1); | ||
5938 | fan_table.slope2 = cpu_to_be16(slope2); | ||
5939 | |||
5940 | fan_table.fdo_min = cpu_to_be16(fdo_min); | ||
5941 | |||
5942 | fan_table.hys_down = cpu_to_be16(rdev->pm.dpm.fan.t_hyst); | ||
5943 | |||
5944 | fan_table.hys_up = cpu_to_be16(1); | ||
5945 | |||
5946 | fan_table.hys_slope = cpu_to_be16(1); | ||
5947 | |||
5948 | fan_table.temp_resp_lim = cpu_to_be16(5); | ||
5949 | |||
5950 | reference_clock = radeon_get_xclk(rdev); | ||
5951 | |||
5952 | fan_table.refresh_period = cpu_to_be32((rdev->pm.dpm.fan.cycle_delay * | ||
5953 | reference_clock) / 1600); | ||
5954 | |||
5955 | fan_table.fdo_max = cpu_to_be16((u16)duty100); | ||
5956 | |||
5957 | tmp = (RREG32(CG_MULT_THERMAL_CTRL) & TEMP_SEL_MASK) >> TEMP_SEL_SHIFT; | ||
5958 | fan_table.temp_src = (uint8_t)tmp; | ||
5959 | |||
5960 | ret = si_copy_bytes_to_smc(rdev, | ||
5961 | si_pi->fan_table_start, | ||
5962 | (u8 *)(&fan_table), | ||
5963 | sizeof(fan_table), | ||
5964 | si_pi->sram_end); | ||
5965 | |||
5966 | if (ret) { | ||
5967 | DRM_ERROR("Failed to load fan table to the SMC."); | ||
5968 | rdev->pm.dpm.fan.ucode_fan_control = false; | ||
5969 | } | ||
5970 | |||
5971 | return 0; | ||
5972 | } | ||
5973 | |||
5974 | static int si_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev) | ||
5975 | { | ||
5976 | PPSMC_Result ret; | ||
5977 | |||
5978 | ret = si_send_msg_to_smc(rdev, PPSMC_StartFanControl); | ||
5979 | if (ret == PPSMC_Result_OK) | ||
5980 | return 0; | ||
5981 | else | ||
5982 | return -EINVAL; | ||
5983 | } | ||
5984 | |||
5985 | static int si_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) | ||
5986 | { | ||
5987 | PPSMC_Result ret; | ||
5988 | |||
5989 | ret = si_send_msg_to_smc(rdev, PPSMC_StopFanControl); | ||
5990 | if (ret == PPSMC_Result_OK) | ||
5991 | return 0; | ||
5992 | else | ||
5993 | return -EINVAL; | ||
5994 | } | ||
5995 | |||
5996 | #if 0 | ||
5997 | static int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, | ||
5998 | u32 *speed) | ||
5999 | { | ||
6000 | u32 duty, duty100; | ||
6001 | u64 tmp64; | ||
6002 | |||
6003 | if (rdev->pm.no_fan) | ||
6004 | return -ENOENT; | ||
6005 | |||
6006 | duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; | ||
6007 | duty = (RREG32(CG_THERMAL_STATUS) & FDO_PWM_DUTY_MASK) >> FDO_PWM_DUTY_SHIFT; | ||
6008 | |||
6009 | if (duty100 == 0) | ||
6010 | return -EINVAL; | ||
6011 | |||
6012 | tmp64 = (u64)duty * 100; | ||
6013 | do_div(tmp64, duty100); | ||
6014 | *speed = (u32)tmp64; | ||
6015 | |||
6016 | if (*speed > 100) | ||
6017 | *speed = 100; | ||
6018 | |||
6019 | return 0; | ||
6020 | } | ||
6021 | |||
6022 | static int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, | ||
6023 | u32 speed) | ||
6024 | { | ||
6025 | u32 tmp; | ||
6026 | u32 duty, duty100; | ||
6027 | u64 tmp64; | ||
6028 | |||
6029 | if (rdev->pm.no_fan) | ||
6030 | return -ENOENT; | ||
6031 | |||
6032 | if (speed > 100) | ||
6033 | return -EINVAL; | ||
6034 | |||
6035 | if (rdev->pm.dpm.fan.ucode_fan_control) | ||
6036 | si_fan_ctrl_stop_smc_fan_control(rdev); | ||
6037 | |||
6038 | duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; | ||
6039 | |||
6040 | if (duty100 == 0) | ||
6041 | return -EINVAL; | ||
6042 | |||
6043 | tmp64 = (u64)speed * duty100; | ||
6044 | do_div(tmp64, 100); | ||
6045 | duty = (u32)tmp64; | ||
6046 | |||
6047 | tmp = RREG32(CG_FDO_CTRL0) & ~FDO_STATIC_DUTY_MASK; | ||
6048 | tmp |= FDO_STATIC_DUTY(duty); | ||
6049 | WREG32(CG_FDO_CTRL0, tmp); | ||
6050 | |||
6051 | si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); | ||
6052 | |||
6053 | return 0; | ||
6054 | } | ||
6055 | |||
6056 | static int si_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev, | ||
6057 | u32 *speed) | ||
6058 | { | ||
6059 | u32 tach_period; | ||
6060 | u32 xclk = radeon_get_xclk(rdev); | ||
6061 | |||
6062 | if (rdev->pm.no_fan) | ||
6063 | return -ENOENT; | ||
6064 | |||
6065 | if (rdev->pm.fan_pulses_per_revolution == 0) | ||
6066 | return -ENOENT; | ||
6067 | |||
6068 | tach_period = (RREG32(CG_TACH_STATUS) & TACH_PERIOD_MASK) >> TACH_PERIOD_SHIFT; | ||
6069 | if (tach_period == 0) | ||
6070 | return -ENOENT; | ||
6071 | |||
6072 | *speed = 60 * xclk * 10000 / tach_period; | ||
6073 | |||
6074 | return 0; | ||
6075 | } | ||
6076 | |||
6077 | static int si_fan_ctrl_set_fan_speed_rpm(struct radeon_device *rdev, | ||
6078 | u32 speed) | ||
6079 | { | ||
6080 | u32 tach_period, tmp; | ||
6081 | u32 xclk = radeon_get_xclk(rdev); | ||
6082 | |||
6083 | if (rdev->pm.no_fan) | ||
6084 | return -ENOENT; | ||
6085 | |||
6086 | if (rdev->pm.fan_pulses_per_revolution == 0) | ||
6087 | return -ENOENT; | ||
6088 | |||
6089 | if ((speed < rdev->pm.fan_min_rpm) || | ||
6090 | (speed > rdev->pm.fan_max_rpm)) | ||
6091 | return -EINVAL; | ||
6092 | |||
6093 | if (rdev->pm.dpm.fan.ucode_fan_control) | ||
6094 | si_fan_ctrl_stop_smc_fan_control(rdev); | ||
6095 | |||
6096 | tach_period = 60 * xclk * 10000 / (8 * speed); | ||
6097 | tmp = RREG32(CG_TACH_CTRL) & ~TARGET_PERIOD_MASK; | ||
6098 | tmp |= TARGET_PERIOD(tach_period); | ||
6099 | WREG32(CG_TACH_CTRL, tmp); | ||
6100 | |||
6101 | si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); | ||
6102 | |||
6103 | return 0; | ||
6104 | } | ||
6105 | #endif | ||
6106 | |||
6107 | static void si_fan_ctrl_set_default_mode(struct radeon_device *rdev) | ||
6108 | { | ||
6109 | struct si_power_info *si_pi = si_get_pi(rdev); | ||
6110 | u32 tmp; | ||
6111 | |||
6112 | if (!si_pi->fan_ctrl_is_in_default_mode) { | ||
6113 | tmp = RREG32(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK; | ||
6114 | tmp |= FDO_PWM_MODE(si_pi->fan_ctrl_default_mode); | ||
6115 | WREG32(CG_FDO_CTRL2, tmp); | ||
6116 | |||
6117 | tmp = RREG32(CG_FDO_CTRL2) & TMIN_MASK; | ||
6118 | tmp |= TMIN(si_pi->t_min); | ||
6119 | WREG32(CG_FDO_CTRL2, tmp); | ||
6120 | si_pi->fan_ctrl_is_in_default_mode = true; | ||
6121 | } | ||
6122 | } | ||
6123 | |||
6124 | static void si_thermal_start_smc_fan_control(struct radeon_device *rdev) | ||
6125 | { | ||
6126 | if (rdev->pm.dpm.fan.ucode_fan_control) { | ||
6127 | si_fan_ctrl_start_smc_fan_control(rdev); | ||
6128 | si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); | ||
6129 | } | ||
6130 | } | ||
6131 | |||
6132 | static void si_thermal_initialize(struct radeon_device *rdev) | ||
6133 | { | ||
6134 | u32 tmp; | ||
6135 | |||
6136 | if (rdev->pm.fan_pulses_per_revolution) { | ||
6137 | tmp = RREG32(CG_TACH_CTRL) & ~EDGE_PER_REV_MASK; | ||
6138 | tmp |= EDGE_PER_REV(rdev->pm.fan_pulses_per_revolution -1); | ||
6139 | WREG32(CG_TACH_CTRL, tmp); | ||
6140 | } | ||
6141 | |||
6142 | tmp = RREG32(CG_FDO_CTRL2) & ~TACH_PWM_RESP_RATE_MASK; | ||
6143 | tmp |= TACH_PWM_RESP_RATE(0x28); | ||
6144 | WREG32(CG_FDO_CTRL2, tmp); | ||
6145 | } | ||
6146 | |||
6147 | static int si_thermal_start_thermal_controller(struct radeon_device *rdev) | ||
6148 | { | ||
6149 | int ret; | ||
6150 | |||
6151 | si_thermal_initialize(rdev); | ||
6152 | ret = si_thermal_set_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); | ||
6153 | if (ret) | ||
6154 | return ret; | ||
6155 | ret = si_thermal_enable_alert(rdev, true); | ||
6156 | if (ret) | ||
6157 | return ret; | ||
6158 | if (rdev->pm.dpm.fan.ucode_fan_control) { | ||
6159 | ret = si_halt_smc(rdev); | ||
6160 | if (ret) | ||
6161 | return ret; | ||
6162 | ret = si_thermal_setup_fan_table(rdev); | ||
6163 | if (ret) | ||
6164 | return ret; | ||
6165 | ret = si_resume_smc(rdev); | ||
6166 | if (ret) | ||
6167 | return ret; | ||
6168 | si_thermal_start_smc_fan_control(rdev); | ||
6169 | } | ||
6170 | |||
6171 | return 0; | ||
6172 | } | ||
6173 | |||
6174 | static void si_thermal_stop_thermal_controller(struct radeon_device *rdev) | ||
6175 | { | ||
6176 | if (!rdev->pm.no_fan) { | ||
6177 | si_fan_ctrl_set_default_mode(rdev); | ||
6178 | si_fan_ctrl_stop_smc_fan_control(rdev); | ||
6179 | } | ||
6180 | } | ||
6181 | |||
5870 | int si_dpm_enable(struct radeon_device *rdev) | 6182 | int si_dpm_enable(struct radeon_device *rdev) |
5871 | { | 6183 | { |
5872 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | 6184 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
@@ -5979,6 +6291,8 @@ int si_dpm_enable(struct radeon_device *rdev) | |||
5979 | 6291 | ||
5980 | si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); | 6292 | si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); |
5981 | 6293 | ||
6294 | si_thermal_start_thermal_controller(rdev); | ||
6295 | |||
5982 | ni_update_current_ps(rdev, boot_ps); | 6296 | ni_update_current_ps(rdev, boot_ps); |
5983 | 6297 | ||
5984 | return 0; | 6298 | return 0; |
@@ -6019,6 +6333,7 @@ void si_dpm_disable(struct radeon_device *rdev) | |||
6019 | 6333 | ||
6020 | if (!si_is_smc_running(rdev)) | 6334 | if (!si_is_smc_running(rdev)) |
6021 | return; | 6335 | return; |
6336 | si_thermal_stop_thermal_controller(rdev); | ||
6022 | si_disable_ulv(rdev); | 6337 | si_disable_ulv(rdev); |
6023 | si_clear_vc(rdev); | 6338 | si_clear_vc(rdev); |
6024 | if (pi->thermal_protection) | 6339 | if (pi->thermal_protection) |
@@ -6557,6 +6872,9 @@ int si_dpm_init(struct radeon_device *rdev) | |||
6557 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc = | 6872 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc = |
6558 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; | 6873 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; |
6559 | 6874 | ||
6875 | si_pi->fan_ctrl_is_in_default_mode = true; | ||
6876 | rdev->pm.dpm.fan.ucode_fan_control = false; | ||
6877 | |||
6560 | return 0; | 6878 | return 0; |
6561 | } | 6879 | } |
6562 | 6880 | ||
diff --git a/drivers/gpu/drm/radeon/si_dpm.h b/drivers/gpu/drm/radeon/si_dpm.h index 8b5c06a0832d..d16bb1b5f10f 100644 --- a/drivers/gpu/drm/radeon/si_dpm.h +++ b/drivers/gpu/drm/radeon/si_dpm.h | |||
@@ -182,6 +182,7 @@ struct si_power_info { | |||
182 | u32 dte_table_start; | 182 | u32 dte_table_start; |
183 | u32 spll_table_start; | 183 | u32 spll_table_start; |
184 | u32 papm_cfg_table_start; | 184 | u32 papm_cfg_table_start; |
185 | u32 fan_table_start; | ||
185 | /* CAC stuff */ | 186 | /* CAC stuff */ |
186 | const struct si_cac_config_reg *cac_weights; | 187 | const struct si_cac_config_reg *cac_weights; |
187 | const struct si_cac_config_reg *lcac_config; | 188 | const struct si_cac_config_reg *lcac_config; |
@@ -197,6 +198,10 @@ struct si_power_info { | |||
197 | /* SVI2 */ | 198 | /* SVI2 */ |
198 | u8 svd_gpio_id; | 199 | u8 svd_gpio_id; |
199 | u8 svc_gpio_id; | 200 | u8 svc_gpio_id; |
201 | /* fan control */ | ||
202 | bool fan_ctrl_is_in_default_mode; | ||
203 | u32 t_min; | ||
204 | u32 fan_ctrl_default_mode; | ||
200 | }; | 205 | }; |
201 | 206 | ||
202 | #define SISLANDS_INITIAL_STATE_ARB_INDEX 0 | 207 | #define SISLANDS_INITIAL_STATE_ARB_INDEX 0 |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 6635da9ec986..c549c16a4fe4 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -180,7 +180,10 @@ | |||
180 | #define DIG_THERM_DPM(x) ((x) << 14) | 180 | #define DIG_THERM_DPM(x) ((x) << 14) |
181 | #define DIG_THERM_DPM_MASK 0x003FC000 | 181 | #define DIG_THERM_DPM_MASK 0x003FC000 |
182 | #define DIG_THERM_DPM_SHIFT 14 | 182 | #define DIG_THERM_DPM_SHIFT 14 |
183 | 183 | #define CG_THERMAL_STATUS 0x704 | |
184 | #define FDO_PWM_DUTY(x) ((x) << 9) | ||
185 | #define FDO_PWM_DUTY_MASK (0xff << 9) | ||
186 | #define FDO_PWM_DUTY_SHIFT 9 | ||
184 | #define CG_THERMAL_INT 0x708 | 187 | #define CG_THERMAL_INT 0x708 |
185 | #define DIG_THERM_INTH(x) ((x) << 8) | 188 | #define DIG_THERM_INTH(x) ((x) << 8) |
186 | #define DIG_THERM_INTH_MASK 0x0000FF00 | 189 | #define DIG_THERM_INTH_MASK 0x0000FF00 |
@@ -191,6 +194,10 @@ | |||
191 | #define THERM_INT_MASK_HIGH (1 << 24) | 194 | #define THERM_INT_MASK_HIGH (1 << 24) |
192 | #define THERM_INT_MASK_LOW (1 << 25) | 195 | #define THERM_INT_MASK_LOW (1 << 25) |
193 | 196 | ||
197 | #define CG_MULT_THERMAL_CTRL 0x710 | ||
198 | #define TEMP_SEL(x) ((x) << 20) | ||
199 | #define TEMP_SEL_MASK (0xff << 20) | ||
200 | #define TEMP_SEL_SHIFT 20 | ||
194 | #define CG_MULT_THERMAL_STATUS 0x714 | 201 | #define CG_MULT_THERMAL_STATUS 0x714 |
195 | #define ASIC_MAX_TEMP(x) ((x) << 0) | 202 | #define ASIC_MAX_TEMP(x) ((x) << 0) |
196 | #define ASIC_MAX_TEMP_MASK 0x000001ff | 203 | #define ASIC_MAX_TEMP_MASK 0x000001ff |
@@ -199,6 +206,37 @@ | |||
199 | #define CTF_TEMP_MASK 0x0003fe00 | 206 | #define CTF_TEMP_MASK 0x0003fe00 |
200 | #define CTF_TEMP_SHIFT 9 | 207 | #define CTF_TEMP_SHIFT 9 |
201 | 208 | ||
209 | #define CG_FDO_CTRL0 0x754 | ||
210 | #define FDO_STATIC_DUTY(x) ((x) << 0) | ||
211 | #define FDO_STATIC_DUTY_MASK 0x0000000F | ||
212 | #define FDO_STATIC_DUTY_SHIFT 0 | ||
213 | #define CG_FDO_CTRL1 0x758 | ||
214 | #define FMAX_DUTY100(x) ((x) << 0) | ||
215 | #define FMAX_DUTY100_MASK 0x0000000F | ||
216 | #define FMAX_DUTY100_SHIFT 0 | ||
217 | #define CG_FDO_CTRL2 0x75C | ||
218 | #define TMIN(x) ((x) << 0) | ||
219 | #define TMIN_MASK 0x0000000F | ||
220 | #define TMIN_SHIFT 0 | ||
221 | #define FDO_PWM_MODE(x) ((x) << 11) | ||
222 | #define FDO_PWM_MODE_MASK (3 << 11) | ||
223 | #define FDO_PWM_MODE_SHIFT 11 | ||
224 | #define TACH_PWM_RESP_RATE(x) ((x) << 25) | ||
225 | #define TACH_PWM_RESP_RATE_MASK (0x7f << 25) | ||
226 | #define TACH_PWM_RESP_RATE_SHIFT 25 | ||
227 | |||
228 | #define CG_TACH_CTRL 0x770 | ||
229 | # define EDGE_PER_REV(x) ((x) << 0) | ||
230 | # define EDGE_PER_REV_MASK (0x7 << 0) | ||
231 | # define EDGE_PER_REV_SHIFT 0 | ||
232 | # define TARGET_PERIOD(x) ((x) << 3) | ||
233 | # define TARGET_PERIOD_MASK 0xfffffff8 | ||
234 | # define TARGET_PERIOD_SHIFT 3 | ||
235 | #define CG_TACH_STATUS 0x774 | ||
236 | # define TACH_PERIOD(x) ((x) << 0) | ||
237 | # define TACH_PERIOD_MASK 0xffffffff | ||
238 | # define TACH_PERIOD_SHIFT 0 | ||
239 | |||
202 | #define GENERAL_PWRMGT 0x780 | 240 | #define GENERAL_PWRMGT 0x780 |
203 | # define GLOBAL_PWRMGT_EN (1 << 0) | 241 | # define GLOBAL_PWRMGT_EN (1 << 0) |
204 | # define STATIC_PM_EN (1 << 1) | 242 | # define STATIC_PM_EN (1 << 1) |
diff --git a/drivers/gpu/drm/radeon/sislands_smc.h b/drivers/gpu/drm/radeon/sislands_smc.h index 623a0b1e2d9d..3c779838d9ab 100644 --- a/drivers/gpu/drm/radeon/sislands_smc.h +++ b/drivers/gpu/drm/radeon/sislands_smc.h | |||
@@ -245,6 +245,31 @@ typedef struct SISLANDS_SMC_STATETABLE SISLANDS_SMC_STATETABLE; | |||
245 | #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd 0x11c | 245 | #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd 0x11c |
246 | #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc 0x120 | 246 | #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc 0x120 |
247 | 247 | ||
248 | struct PP_SIslands_FanTable | ||
249 | { | ||
250 | uint8_t fdo_mode; | ||
251 | uint8_t padding; | ||
252 | int16_t temp_min; | ||
253 | int16_t temp_med; | ||
254 | int16_t temp_max; | ||
255 | int16_t slope1; | ||
256 | int16_t slope2; | ||
257 | int16_t fdo_min; | ||
258 | int16_t hys_up; | ||
259 | int16_t hys_down; | ||
260 | int16_t hys_slope; | ||
261 | int16_t temp_resp_lim; | ||
262 | int16_t temp_curr; | ||
263 | int16_t slope_curr; | ||
264 | int16_t pwm_curr; | ||
265 | uint32_t refresh_period; | ||
266 | int16_t fdo_max; | ||
267 | uint8_t temp_src; | ||
268 | int8_t padding2; | ||
269 | }; | ||
270 | |||
271 | typedef struct PP_SIslands_FanTable PP_SIslands_FanTable; | ||
272 | |||
248 | #define SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16 | 273 | #define SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16 |
249 | #define SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES 32 | 274 | #define SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES 32 |
250 | 275 | ||