aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/ci_dpm.c345
-rw-r--r--drivers/gpu/drm/radeon/ci_dpm.h5
-rw-r--r--drivers/gpu/drm/radeon/cikd.h40
-rw-r--r--drivers/gpu/drm/radeon/ppsmc.h6
-rw-r--r--drivers/gpu/drm/radeon/pptable.h8
-rw-r--r--drivers/gpu/drm/radeon/r600_dpm.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon.h4
-rw-r--r--drivers/gpu/drm/radeon/smu7_discrete.h30
8 files changed, 443 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c
index 9dbc52f3c4d1..4581d6cf90e8 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.c
+++ b/drivers/gpu/drm/radeon/ci_dpm.c
@@ -184,6 +184,9 @@ static int ci_set_overdrive_target_tdp(struct radeon_device *rdev,
184 u32 target_tdp); 184 u32 target_tdp);
185static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate); 185static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate);
186 186
187static PPSMC_Result ci_send_msg_to_smc_with_parameter(struct radeon_device *rdev,
188 PPSMC_Msg msg, u32 parameter);
189
187static struct ci_power_info *ci_get_pi(struct radeon_device *rdev) 190static struct ci_power_info *ci_get_pi(struct radeon_device *rdev)
188{ 191{
189 struct ci_power_info *pi = rdev->pm.dpm.priv; 192 struct ci_power_info *pi = rdev->pm.dpm.priv;
@@ -355,6 +358,21 @@ static int ci_populate_dw8(struct radeon_device *rdev)
355 return 0; 358 return 0;
356} 359}
357 360
361static int ci_populate_fuzzy_fan(struct radeon_device *rdev)
362{
363 struct ci_power_info *pi = ci_get_pi(rdev);
364
365 if ((rdev->pm.dpm.fan.fan_output_sensitivity & (1 << 15)) ||
366 (rdev->pm.dpm.fan.fan_output_sensitivity == 0))
367 rdev->pm.dpm.fan.fan_output_sensitivity =
368 rdev->pm.dpm.fan.default_fan_output_sensitivity;
369
370 pi->smc_powertune_table.FuzzyFan_PwmSetDelta =
371 cpu_to_be16(rdev->pm.dpm.fan.fan_output_sensitivity);
372
373 return 0;
374}
375
358static int ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(struct radeon_device *rdev) 376static int ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(struct radeon_device *rdev)
359{ 377{
360 struct ci_power_info *pi = ci_get_pi(rdev); 378 struct ci_power_info *pi = ci_get_pi(rdev);
@@ -480,6 +498,9 @@ static int ci_populate_pm_base(struct radeon_device *rdev)
480 ret = ci_populate_dw8(rdev); 498 ret = ci_populate_dw8(rdev);
481 if (ret) 499 if (ret)
482 return ret; 500 return ret;
501 ret = ci_populate_fuzzy_fan(rdev);
502 if (ret)
503 return ret;
483 ret = ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(rdev); 504 ret = ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(rdev);
484 if (ret) 505 if (ret)
485 return ret; 506 return ret;
@@ -859,6 +880,7 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev,
859 880
860 if (enable) { 881 if (enable) {
861 thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); 882 thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
883 WREG32_SMC(CG_THERMAL_INT, thermal_int);
862 rdev->irq.dpm_thermal = false; 884 rdev->irq.dpm_thermal = false;
863 result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Enable); 885 result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Enable);
864 if (result != PPSMC_Result_OK) { 886 if (result != PPSMC_Result_OK) {
@@ -867,6 +889,7 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev,
867 } 889 }
868 } else { 890 } else {
869 thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; 891 thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
892 WREG32_SMC(CG_THERMAL_INT, thermal_int);
870 rdev->irq.dpm_thermal = true; 893 rdev->irq.dpm_thermal = true;
871 result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Disable); 894 result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Disable);
872 if (result != PPSMC_Result_OK) { 895 if (result != PPSMC_Result_OK) {
@@ -875,12 +898,325 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev,
875 } 898 }
876 } 899 }
877 900
878 WREG32_SMC(CG_THERMAL_INT, thermal_int); 901 return 0;
902}
903
904static void ci_fan_ctrl_set_static_mode(struct radeon_device *rdev, u32 mode)
905{
906 struct ci_power_info *pi = ci_get_pi(rdev);
907 u32 tmp;
908
909 if (pi->fan_ctrl_is_in_default_mode) {
910 tmp = (RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK) >> FDO_PWM_MODE_SHIFT;
911 pi->fan_ctrl_default_mode = tmp;
912 tmp = (RREG32_SMC(CG_FDO_CTRL2) & TMIN_MASK) >> TMIN_SHIFT;
913 pi->t_min = tmp;
914 pi->fan_ctrl_is_in_default_mode = false;
915 }
916
917 tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TMIN_MASK;
918 tmp |= TMIN(0);
919 WREG32_SMC(CG_FDO_CTRL2, tmp);
920
921 tmp = RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK;
922 tmp |= FDO_PWM_MODE(mode);
923 WREG32_SMC(CG_FDO_CTRL2, tmp);
924}
925
926static int ci_thermal_setup_fan_table(struct radeon_device *rdev)
927{
928 struct ci_power_info *pi = ci_get_pi(rdev);
929 SMU7_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE };
930 u32 duty100;
931 u32 t_diff1, t_diff2, pwm_diff1, pwm_diff2;
932 u16 fdo_min, slope1, slope2;
933 u32 reference_clock, tmp;
934 int ret;
935 u64 tmp64;
936
937 if (!pi->fan_table_start) {
938 rdev->pm.dpm.fan.ucode_fan_control = false;
939 return 0;
940 }
941
942 duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
943
944 if (duty100 == 0) {
945 rdev->pm.dpm.fan.ucode_fan_control = false;
946 return 0;
947 }
948
949 tmp64 = (u64)rdev->pm.dpm.fan.pwm_min * duty100;
950 do_div(tmp64, 10000);
951 fdo_min = (u16)tmp64;
952
953 t_diff1 = rdev->pm.dpm.fan.t_med - rdev->pm.dpm.fan.t_min;
954 t_diff2 = rdev->pm.dpm.fan.t_high - rdev->pm.dpm.fan.t_med;
955
956 pwm_diff1 = rdev->pm.dpm.fan.pwm_med - rdev->pm.dpm.fan.pwm_min;
957 pwm_diff2 = rdev->pm.dpm.fan.pwm_high - rdev->pm.dpm.fan.pwm_med;
958
959 slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);
960 slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);
961
962 fan_table.TempMin = cpu_to_be16((50 + rdev->pm.dpm.fan.t_min) / 100);
963 fan_table.TempMed = cpu_to_be16((50 + rdev->pm.dpm.fan.t_med) / 100);
964 fan_table.TempMax = cpu_to_be16((50 + rdev->pm.dpm.fan.t_max) / 100);
965
966 fan_table.Slope1 = cpu_to_be16(slope1);
967 fan_table.Slope2 = cpu_to_be16(slope2);
968
969 fan_table.FdoMin = cpu_to_be16(fdo_min);
970
971 fan_table.HystDown = cpu_to_be16(rdev->pm.dpm.fan.t_hyst);
972
973 fan_table.HystUp = cpu_to_be16(1);
974
975 fan_table.HystSlope = cpu_to_be16(1);
976
977 fan_table.TempRespLim = cpu_to_be16(5);
978
979 reference_clock = radeon_get_xclk(rdev);
980
981 fan_table.RefreshPeriod = cpu_to_be32((rdev->pm.dpm.fan.cycle_delay *
982 reference_clock) / 1600);
983
984 fan_table.FdoMax = cpu_to_be16((u16)duty100);
985
986 tmp = (RREG32_SMC(CG_MULT_THERMAL_CTRL) & TEMP_SEL_MASK) >> TEMP_SEL_SHIFT;
987 fan_table.TempSrc = (uint8_t)tmp;
988
989 ret = ci_copy_bytes_to_smc(rdev,
990 pi->fan_table_start,
991 (u8 *)(&fan_table),
992 sizeof(fan_table),
993 pi->sram_end);
994
995 if (ret) {
996 DRM_ERROR("Failed to load fan table to the SMC.");
997 rdev->pm.dpm.fan.ucode_fan_control = false;
998 }
999
1000 return 0;
1001}
1002
1003static int ci_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev)
1004{
1005 struct ci_power_info *pi = ci_get_pi(rdev);
1006 PPSMC_Result ret;
1007
1008 if (pi->caps_od_fuzzy_fan_control_support) {
1009 ret = ci_send_msg_to_smc_with_parameter(rdev,
1010 PPSMC_StartFanControl,
1011 FAN_CONTROL_FUZZY);
1012 if (ret != PPSMC_Result_OK)
1013 return -EINVAL;
1014 ret = ci_send_msg_to_smc_with_parameter(rdev,
1015 PPSMC_MSG_SetFanPwmMax,
1016 rdev->pm.dpm.fan.default_max_fan_pwm);
1017 if (ret != PPSMC_Result_OK)
1018 return -EINVAL;
1019 } else {
1020 ret = ci_send_msg_to_smc_with_parameter(rdev,
1021 PPSMC_StartFanControl,
1022 FAN_CONTROL_TABLE);
1023 if (ret != PPSMC_Result_OK)
1024 return -EINVAL;
1025 }
879 1026
880 return 0; 1027 return 0;
881} 1028}
882 1029
883#if 0 1030#if 0
1031static int ci_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev)
1032{
1033 PPSMC_Result ret;
1034
1035 ret = ci_send_msg_to_smc(rdev, PPSMC_StopFanControl);
1036 if (ret == PPSMC_Result_OK)
1037 return 0;
1038 else
1039 return -EINVAL;
1040}
1041
1042static int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
1043 u32 *speed)
1044{
1045 u32 duty, duty100;
1046 u64 tmp64;
1047
1048 if (rdev->pm.no_fan)
1049 return -ENOENT;
1050
1051 duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
1052 duty = (RREG32_SMC(CG_THERMAL_STATUS) & FDO_PWM_DUTY_MASK) >> FDO_PWM_DUTY_SHIFT;
1053
1054 if (duty100 == 0)
1055 return -EINVAL;
1056
1057 tmp64 = (u64)duty * 100;
1058 do_div(tmp64, duty100);
1059 *speed = (u32)tmp64;
1060
1061 if (*speed > 100)
1062 *speed = 100;
1063
1064 return 0;
1065}
1066
1067static int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
1068 u32 speed)
1069{
1070 u32 tmp;
1071 u32 duty, duty100;
1072 u64 tmp64;
1073
1074 if (rdev->pm.no_fan)
1075 return -ENOENT;
1076
1077 if (speed > 100)
1078 return -EINVAL;
1079
1080 if (rdev->pm.dpm.fan.ucode_fan_control)
1081 ci_fan_ctrl_stop_smc_fan_control(rdev);
1082
1083 duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
1084
1085 if (duty100 == 0)
1086 return -EINVAL;
1087
1088 tmp64 = (u64)speed * duty100;
1089 do_div(tmp64, 100);
1090 duty = (u32)tmp64;
1091
1092 tmp = RREG32_SMC(CG_FDO_CTRL0) & ~FDO_STATIC_DUTY_MASK;
1093 tmp |= FDO_STATIC_DUTY(duty);
1094 WREG32_SMC(CG_FDO_CTRL0, tmp);
1095
1096 ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC);
1097
1098 return 0;
1099}
1100
1101static int ci_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev,
1102 u32 *speed)
1103{
1104 u32 tach_period;
1105 u32 xclk = radeon_get_xclk(rdev);
1106
1107 if (rdev->pm.no_fan)
1108 return -ENOENT;
1109
1110 if (rdev->pm.fan_pulses_per_revolution == 0)
1111 return -ENOENT;
1112
1113 tach_period = (RREG32_SMC(CG_TACH_STATUS) & TACH_PERIOD_MASK) >> TACH_PERIOD_SHIFT;
1114 if (tach_period == 0)
1115 return -ENOENT;
1116
1117 *speed = 60 * xclk * 10000 / tach_period;
1118
1119 return 0;
1120}
1121
1122static int ci_fan_ctrl_set_fan_speed_rpm(struct radeon_device *rdev,
1123 u32 speed)
1124{
1125 u32 tach_period, tmp;
1126 u32 xclk = radeon_get_xclk(rdev);
1127
1128 if (rdev->pm.no_fan)
1129 return -ENOENT;
1130
1131 if (rdev->pm.fan_pulses_per_revolution == 0)
1132 return -ENOENT;
1133
1134 if ((speed < rdev->pm.fan_min_rpm) ||
1135 (speed > rdev->pm.fan_max_rpm))
1136 return -EINVAL;
1137
1138 if (rdev->pm.dpm.fan.ucode_fan_control)
1139 ci_fan_ctrl_stop_smc_fan_control(rdev);
1140
1141 tach_period = 60 * xclk * 10000 / (8 * speed);
1142 tmp = RREG32_SMC(CG_TACH_CTRL) & ~TARGET_PERIOD_MASK;
1143 tmp |= TARGET_PERIOD(tach_period);
1144 WREG32_SMC(CG_TACH_CTRL, tmp);
1145
1146 ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC);
1147
1148 return 0;
1149}
1150#endif
1151
1152static void ci_fan_ctrl_set_default_mode(struct radeon_device *rdev)
1153{
1154 struct ci_power_info *pi = ci_get_pi(rdev);
1155 u32 tmp;
1156
1157 if (!pi->fan_ctrl_is_in_default_mode) {
1158 tmp = RREG32_SMC(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK;
1159 tmp |= FDO_PWM_MODE(pi->fan_ctrl_default_mode);
1160 WREG32_SMC(CG_FDO_CTRL2, tmp);
1161
1162 tmp = RREG32_SMC(CG_FDO_CTRL2) & TMIN_MASK;
1163 tmp |= TMIN(pi->t_min);
1164 WREG32_SMC(CG_FDO_CTRL2, tmp);
1165 pi->fan_ctrl_is_in_default_mode = true;
1166 }
1167}
1168
1169static void ci_thermal_start_smc_fan_control(struct radeon_device *rdev)
1170{
1171 if (rdev->pm.dpm.fan.ucode_fan_control) {
1172 ci_fan_ctrl_start_smc_fan_control(rdev);
1173 ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC);
1174 }
1175}
1176
1177static void ci_thermal_initialize(struct radeon_device *rdev)
1178{
1179 u32 tmp;
1180
1181 if (rdev->pm.fan_pulses_per_revolution) {
1182 tmp = RREG32_SMC(CG_TACH_CTRL) & ~EDGE_PER_REV_MASK;
1183 tmp |= EDGE_PER_REV(rdev->pm.fan_pulses_per_revolution -1);
1184 WREG32_SMC(CG_TACH_CTRL, tmp);
1185 }
1186
1187 tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TACH_PWM_RESP_RATE_MASK;
1188 tmp |= TACH_PWM_RESP_RATE(0x28);
1189 WREG32_SMC(CG_FDO_CTRL2, tmp);
1190}
1191
1192static int ci_thermal_start_thermal_controller(struct radeon_device *rdev)
1193{
1194 int ret;
1195
1196 ci_thermal_initialize(rdev);
1197 ret = ci_thermal_set_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
1198 if (ret)
1199 return ret;
1200 ret = ci_thermal_enable_alert(rdev, true);
1201 if (ret)
1202 return ret;
1203 if (rdev->pm.dpm.fan.ucode_fan_control) {
1204 ret = ci_thermal_setup_fan_table(rdev);
1205 if (ret)
1206 return ret;
1207 ci_thermal_start_smc_fan_control(rdev);
1208 }
1209
1210 return 0;
1211}
1212
1213static void ci_thermal_stop_thermal_controller(struct radeon_device *rdev)
1214{
1215 if (!rdev->pm.no_fan)
1216 ci_fan_ctrl_set_default_mode(rdev);
1217}
1218
1219#if 0
884static int ci_read_smc_soft_register(struct radeon_device *rdev, 1220static int ci_read_smc_soft_register(struct radeon_device *rdev,
885 u16 reg_offset, u32 *value) 1221 u16 reg_offset, u32 *value)
886{ 1222{
@@ -4841,6 +5177,8 @@ int ci_dpm_enable(struct radeon_device *rdev)
4841 5177
4842 ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); 5178 ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
4843 5179
5180 ci_thermal_start_thermal_controller(rdev);
5181
4844 ci_update_current_ps(rdev, boot_ps); 5182 ci_update_current_ps(rdev, boot_ps);
4845 5183
4846 return 0; 5184 return 0;
@@ -4886,6 +5224,8 @@ void ci_dpm_disable(struct radeon_device *rdev)
4886 if (!ci_is_smc_running(rdev)) 5224 if (!ci_is_smc_running(rdev))
4887 return; 5225 return;
4888 5226
5227 ci_thermal_stop_thermal_controller(rdev);
5228
4889 if (pi->thermal_protection) 5229 if (pi->thermal_protection)
4890 ci_enable_thermal_protection(rdev, false); 5230 ci_enable_thermal_protection(rdev, false);
4891 ci_enable_power_containment(rdev, false); 5231 ci_enable_power_containment(rdev, false);
@@ -5473,6 +5813,9 @@ int ci_dpm_init(struct radeon_device *rdev)
5473 rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc = 5813 rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc =
5474 rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; 5814 rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
5475 5815
5816 pi->fan_ctrl_is_in_default_mode = true;
5817 rdev->pm.dpm.fan.ucode_fan_control = false;
5818
5476 return 0; 5819 return 0;
5477} 5820}
5478 5821
diff --git a/drivers/gpu/drm/radeon/ci_dpm.h b/drivers/gpu/drm/radeon/ci_dpm.h
index 615cb2cacf2c..bb19fbf3ab8a 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.h
+++ b/drivers/gpu/drm/radeon/ci_dpm.h
@@ -266,6 +266,7 @@ struct ci_power_info {
266 bool caps_automatic_dc_transition; 266 bool caps_automatic_dc_transition;
267 bool caps_sclk_throttle_low_notification; 267 bool caps_sclk_throttle_low_notification;
268 bool caps_dynamic_ac_timing; 268 bool caps_dynamic_ac_timing;
269 bool caps_od_fuzzy_fan_control_support;
269 /* flags */ 270 /* flags */
270 bool thermal_protection; 271 bool thermal_protection;
271 bool pcie_performance_request; 272 bool pcie_performance_request;
@@ -287,6 +288,10 @@ struct ci_power_info {
287 struct ci_ps current_ps; 288 struct ci_ps current_ps;
288 struct radeon_ps requested_rps; 289 struct radeon_ps requested_rps;
289 struct ci_ps requested_ps; 290 struct ci_ps requested_ps;
291 /* fan control */
292 bool fan_ctrl_is_in_default_mode;
293 u32 t_min;
294 u32 fan_ctrl_default_mode;
290}; 295};
291 296
292#define CISLANDS_VOLTAGE_CONTROL_NONE 0x0 297#define CISLANDS_VOLTAGE_CONTROL_NONE 0x0
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h
index 068cbb019326..e4e88ca8b82e 100644
--- a/drivers/gpu/drm/radeon/cikd.h
+++ b/drivers/gpu/drm/radeon/cikd.h
@@ -186,7 +186,10 @@
186#define DIG_THERM_DPM(x) ((x) << 14) 186#define DIG_THERM_DPM(x) ((x) << 14)
187#define DIG_THERM_DPM_MASK 0x003FC000 187#define DIG_THERM_DPM_MASK 0x003FC000
188#define DIG_THERM_DPM_SHIFT 14 188#define DIG_THERM_DPM_SHIFT 14
189 189#define CG_THERMAL_STATUS 0xC0300008
190#define FDO_PWM_DUTY(x) ((x) << 9)
191#define FDO_PWM_DUTY_MASK (0xff << 9)
192#define FDO_PWM_DUTY_SHIFT 9
190#define CG_THERMAL_INT 0xC030000C 193#define CG_THERMAL_INT 0xC030000C
191#define CI_DIG_THERM_INTH(x) ((x) << 8) 194#define CI_DIG_THERM_INTH(x) ((x) << 8)
192#define CI_DIG_THERM_INTH_MASK 0x0000FF00 195#define CI_DIG_THERM_INTH_MASK 0x0000FF00
@@ -196,7 +199,10 @@
196#define CI_DIG_THERM_INTL_SHIFT 16 199#define CI_DIG_THERM_INTL_SHIFT 16
197#define THERM_INT_MASK_HIGH (1 << 24) 200#define THERM_INT_MASK_HIGH (1 << 24)
198#define THERM_INT_MASK_LOW (1 << 25) 201#define THERM_INT_MASK_LOW (1 << 25)
199 202#define CG_MULT_THERMAL_CTRL 0xC0300010
203#define TEMP_SEL(x) ((x) << 20)
204#define TEMP_SEL_MASK (0xff << 20)
205#define TEMP_SEL_SHIFT 20
200#define CG_MULT_THERMAL_STATUS 0xC0300014 206#define CG_MULT_THERMAL_STATUS 0xC0300014
201#define ASIC_MAX_TEMP(x) ((x) << 0) 207#define ASIC_MAX_TEMP(x) ((x) << 0)
202#define ASIC_MAX_TEMP_MASK 0x000001ff 208#define ASIC_MAX_TEMP_MASK 0x000001ff
@@ -205,6 +211,36 @@
205#define CTF_TEMP_MASK 0x0003fe00 211#define CTF_TEMP_MASK 0x0003fe00
206#define CTF_TEMP_SHIFT 9 212#define CTF_TEMP_SHIFT 9
207 213
214#define CG_FDO_CTRL0 0xC0300064
215#define FDO_STATIC_DUTY(x) ((x) << 0)
216#define FDO_STATIC_DUTY_MASK 0x0000000F
217#define FDO_STATIC_DUTY_SHIFT 0
218#define CG_FDO_CTRL1 0xC0300068
219#define FMAX_DUTY100(x) ((x) << 0)
220#define FMAX_DUTY100_MASK 0x0000000F
221#define FMAX_DUTY100_SHIFT 0
222#define CG_FDO_CTRL2 0xC030006C
223#define TMIN(x) ((x) << 0)
224#define TMIN_MASK 0x0000000F
225#define TMIN_SHIFT 0
226#define FDO_PWM_MODE(x) ((x) << 11)
227#define FDO_PWM_MODE_MASK (3 << 11)
228#define FDO_PWM_MODE_SHIFT 11
229#define TACH_PWM_RESP_RATE(x) ((x) << 25)
230#define TACH_PWM_RESP_RATE_MASK (0x7f << 25)
231#define TACH_PWM_RESP_RATE_SHIFT 25
232#define CG_TACH_CTRL 0xC0300070
233# define EDGE_PER_REV(x) ((x) << 0)
234# define EDGE_PER_REV_MASK (0x7 << 0)
235# define EDGE_PER_REV_SHIFT 0
236# define TARGET_PERIOD(x) ((x) << 3)
237# define TARGET_PERIOD_MASK 0xfffffff8
238# define TARGET_PERIOD_SHIFT 3
239#define CG_TACH_STATUS 0xC0300074
240# define TACH_PERIOD(x) ((x) << 0)
241# define TACH_PERIOD_MASK 0xffffffff
242# define TACH_PERIOD_SHIFT 0
243
208#define CG_ECLK_CNTL 0xC05000AC 244#define CG_ECLK_CNTL 0xC05000AC
209# define ECLK_DIVIDER_MASK 0x7f 245# define ECLK_DIVIDER_MASK 0x7f
210# define ECLK_DIR_CNTL_EN (1 << 8) 246# define ECLK_DIR_CNTL_EN (1 << 8)
diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h
index 0c4eaa60b6ca..ff698b05bdf5 100644
--- a/drivers/gpu/drm/radeon/ppsmc.h
+++ b/drivers/gpu/drm/radeon/ppsmc.h
@@ -59,6 +59,11 @@
59#define FDO_MODE_HARDWARE 0 59#define FDO_MODE_HARDWARE 0
60#define FDO_MODE_PIECE_WISE_LINEAR 1 60#define FDO_MODE_PIECE_WISE_LINEAR 1
61 61
62enum FAN_CONTROL {
63 FAN_CONTROL_FUZZY,
64 FAN_CONTROL_TABLE
65};
66
62#define PPSMC_Result_OK ((uint8_t)0x01) 67#define PPSMC_Result_OK ((uint8_t)0x01)
63#define PPSMC_Result_Failed ((uint8_t)0xFF) 68#define PPSMC_Result_Failed ((uint8_t)0xFF)
64 69
@@ -155,6 +160,7 @@ typedef uint8_t PPSMC_Result;
155#define PPSMC_MSG_MASTER_DeepSleep_ON ((uint16_t) 0x18F) 160#define PPSMC_MSG_MASTER_DeepSleep_ON ((uint16_t) 0x18F)
156#define PPSMC_MSG_MASTER_DeepSleep_OFF ((uint16_t) 0x190) 161#define PPSMC_MSG_MASTER_DeepSleep_OFF ((uint16_t) 0x190)
157#define PPSMC_MSG_Remove_DC_Clamp ((uint16_t) 0x191) 162#define PPSMC_MSG_Remove_DC_Clamp ((uint16_t) 0x191)
163#define PPSMC_MSG_SetFanPwmMax ((uint16_t) 0x19A)
158 164
159#define PPSMC_MSG_API_GetSclkFrequency ((uint16_t) 0x200) 165#define PPSMC_MSG_API_GetSclkFrequency ((uint16_t) 0x200)
160#define PPSMC_MSG_API_GetMclkFrequency ((uint16_t) 0x201) 166#define PPSMC_MSG_API_GetMclkFrequency ((uint16_t) 0x201)
diff --git a/drivers/gpu/drm/radeon/pptable.h b/drivers/gpu/drm/radeon/pptable.h
index 2d532996c697..4c2eec49dadc 100644
--- a/drivers/gpu/drm/radeon/pptable.h
+++ b/drivers/gpu/drm/radeon/pptable.h
@@ -96,6 +96,14 @@ typedef struct _ATOM_PPLIB_FANTABLE2
96 USHORT usTMax; // The max temperature 96 USHORT usTMax; // The max temperature
97} ATOM_PPLIB_FANTABLE2; 97} ATOM_PPLIB_FANTABLE2;
98 98
99typedef struct _ATOM_PPLIB_FANTABLE3
100{
101 ATOM_PPLIB_FANTABLE2 basicTable2;
102 UCHAR ucFanControlMode;
103 USHORT usFanPWMMax;
104 USHORT usFanOutputSensitivity;
105} ATOM_PPLIB_FANTABLE3;
106
99typedef struct _ATOM_PPLIB_EXTENDEDHEADER 107typedef struct _ATOM_PPLIB_EXTENDEDHEADER
100{ 108{
101 USHORT usSize; 109 USHORT usSize;
diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c
index f6309bd23e01..76c6a17eeb2d 100644
--- a/drivers/gpu/drm/radeon/r600_dpm.c
+++ b/drivers/gpu/drm/radeon/r600_dpm.c
@@ -811,6 +811,7 @@ union power_info {
811union fan_info { 811union fan_info {
812 struct _ATOM_PPLIB_FANTABLE fan; 812 struct _ATOM_PPLIB_FANTABLE fan;
813 struct _ATOM_PPLIB_FANTABLE2 fan2; 813 struct _ATOM_PPLIB_FANTABLE2 fan2;
814 struct _ATOM_PPLIB_FANTABLE3 fan3;
814}; 815};
815 816
816static int r600_parse_clk_voltage_dep_table(struct radeon_clock_voltage_dependency_table *radeon_table, 817static int r600_parse_clk_voltage_dep_table(struct radeon_clock_voltage_dependency_table *radeon_table,
@@ -900,6 +901,14 @@ int r600_parse_extended_power_table(struct radeon_device *rdev)
900 else 901 else
901 rdev->pm.dpm.fan.t_max = 10900; 902 rdev->pm.dpm.fan.t_max = 10900;
902 rdev->pm.dpm.fan.cycle_delay = 100000; 903 rdev->pm.dpm.fan.cycle_delay = 100000;
904 if (fan_info->fan.ucFanTableFormat >= 3) {
905 rdev->pm.dpm.fan.control_mode = fan_info->fan3.ucFanControlMode;
906 rdev->pm.dpm.fan.default_max_fan_pwm =
907 le16_to_cpu(fan_info->fan3.usFanPWMMax);
908 rdev->pm.dpm.fan.default_fan_output_sensitivity = 4836;
909 rdev->pm.dpm.fan.fan_output_sensitivity =
910 le16_to_cpu(fan_info->fan3.usFanOutputSensitivity);
911 }
903 rdev->pm.dpm.fan.ucode_fan_control = true; 912 rdev->pm.dpm.fan.ucode_fan_control = true;
904 } 913 }
905 } 914 }
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 1f61ff089c9e..5aabbe0a43f5 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1494,6 +1494,10 @@ struct radeon_dpm_fan {
1494 u8 t_hyst; 1494 u8 t_hyst;
1495 u32 cycle_delay; 1495 u32 cycle_delay;
1496 u16 t_max; 1496 u16 t_max;
1497 u8 control_mode;
1498 u16 default_max_fan_pwm;
1499 u16 default_fan_output_sensitivity;
1500 u16 fan_output_sensitivity;
1497 bool ucode_fan_control; 1501 bool ucode_fan_control;
1498}; 1502};
1499 1503
diff --git a/drivers/gpu/drm/radeon/smu7_discrete.h b/drivers/gpu/drm/radeon/smu7_discrete.h
index 82f70c90a9ee..0b0b404ff091 100644
--- a/drivers/gpu/drm/radeon/smu7_discrete.h
+++ b/drivers/gpu/drm/radeon/smu7_discrete.h
@@ -431,6 +431,31 @@ struct SMU7_Discrete_MCRegisters
431 431
432typedef struct SMU7_Discrete_MCRegisters SMU7_Discrete_MCRegisters; 432typedef struct SMU7_Discrete_MCRegisters SMU7_Discrete_MCRegisters;
433 433
434struct SMU7_Discrete_FanTable
435{
436 uint16_t FdoMode;
437 int16_t TempMin;
438 int16_t TempMed;
439 int16_t TempMax;
440 int16_t Slope1;
441 int16_t Slope2;
442 int16_t FdoMin;
443 int16_t HystUp;
444 int16_t HystDown;
445 int16_t HystSlope;
446 int16_t TempRespLim;
447 int16_t TempCurr;
448 int16_t SlopeCurr;
449 int16_t PwmCurr;
450 uint32_t RefreshPeriod;
451 int16_t FdoMax;
452 uint8_t TempSrc;
453 int8_t Padding;
454};
455
456typedef struct SMU7_Discrete_FanTable SMU7_Discrete_FanTable;
457
458
434struct SMU7_Discrete_PmFuses { 459struct SMU7_Discrete_PmFuses {
435 // dw0-dw1 460 // dw0-dw1
436 uint8_t BapmVddCVidHiSidd[8]; 461 uint8_t BapmVddCVidHiSidd[8];
@@ -462,7 +487,10 @@ struct SMU7_Discrete_PmFuses {
462 uint8_t BapmVddCVidHiSidd2[8]; 487 uint8_t BapmVddCVidHiSidd2[8];
463 488
464 // dw11-dw12 489 // dw11-dw12
465 uint32_t Reserved6[2]; 490 int16_t FuzzyFan_ErrorSetDelta;
491 int16_t FuzzyFan_ErrorRateSetDelta;
492 int16_t FuzzyFan_PwmSetDelta;
493 uint16_t CalcMeasPowerBlend;
466 494
467 // dw13-dw16 495 // dw13-dw16
468 uint8_t GnbLPML[16]; 496 uint8_t GnbLPML[16];