diff options
-rw-r--r-- | drivers/gpu/drm/radeon/ci_dpm.c | 345 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/ci_dpm.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/cikd.h | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/ppsmc.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/pptable.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600_dpm.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/smu7_discrete.h | 30 |
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); |
185 | static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate); | 185 | static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate); |
186 | 186 | ||
187 | static PPSMC_Result ci_send_msg_to_smc_with_parameter(struct radeon_device *rdev, | ||
188 | PPSMC_Msg msg, u32 parameter); | ||
189 | |||
187 | static struct ci_power_info *ci_get_pi(struct radeon_device *rdev) | 190 | static 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 | ||
361 | static 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 | |||
358 | static int ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(struct radeon_device *rdev) | 376 | static 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 | |||
904 | static 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 | |||
926 | static 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 | |||
1003 | static 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 |
1031 | static 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 | |||
1042 | static 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 | |||
1067 | static 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 | |||
1101 | static 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 | |||
1122 | static 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 | |||
1152 | static 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 | |||
1169 | static 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 | |||
1177 | static 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 | |||
1192 | static 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 | |||
1213 | static 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 | ||
884 | static int ci_read_smc_soft_register(struct radeon_device *rdev, | 1220 | static 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 | ||
62 | enum 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 | ||
99 | typedef struct _ATOM_PPLIB_FANTABLE3 | ||
100 | { | ||
101 | ATOM_PPLIB_FANTABLE2 basicTable2; | ||
102 | UCHAR ucFanControlMode; | ||
103 | USHORT usFanPWMMax; | ||
104 | USHORT usFanOutputSensitivity; | ||
105 | } ATOM_PPLIB_FANTABLE3; | ||
106 | |||
99 | typedef struct _ATOM_PPLIB_EXTENDEDHEADER | 107 | typedef 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 { | |||
811 | union fan_info { | 811 | union 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 | ||
816 | static int r600_parse_clk_voltage_dep_table(struct radeon_clock_voltage_dependency_table *radeon_table, | 817 | static 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 | ||
432 | typedef struct SMU7_Discrete_MCRegisters SMU7_Discrete_MCRegisters; | 432 | typedef struct SMU7_Discrete_MCRegisters SMU7_Discrete_MCRegisters; |
433 | 433 | ||
434 | struct 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 | |||
456 | typedef struct SMU7_Discrete_FanTable SMU7_Discrete_FanTable; | ||
457 | |||
458 | |||
434 | struct SMU7_Discrete_PmFuses { | 459 | struct 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]; |