diff options
author | Dave Airlie <airlied@redhat.com> | 2014-11-20 21:17:43 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-11-20 21:17:43 -0500 |
commit | ed1e8777a56f3523712506d608a29f57ed37b613 (patch) | |
tree | d008e646cf55242a0799b2e8d73fd27d8d73ab9e | |
parent | a3a1a6674f7fd6c0f7e673c4fc1b1aea3d8fce53 (diff) | |
parent | 2f2624c23511b4bf0dd3d4c5ae167715513f351d (diff) |
Merge branch 'drm-next-3.19' of git://people.freedesktop.org/~agd5f/linux into drm-next
- More CI dpm fixes
- Initial DPM fan control for SI/CI (disabled by default)
- GPUVM multi-ring efficiency improvements
- Some cursor fixes
* 'drm-next-3.19' of git://people.freedesktop.org/~agd5f/linux: (22 commits)
drm/radeon: update the VM after setting BO address v4
drm/radeon: sync PT updates as shared v2
drm/radeon: sync PD updates as shared
drm/radeon: fence BO_VAs manually
drm/radeon: use one VMID for each ring
drm/radeon: track VM update fences separately
drm/radeon: fence PT updates manually v2
drm/radeon: split semaphore and sync object handling v2
drm/radeon: remove unnecessary VM syncs
drm/radeon: stop re-reserving the BO in radeon_vm_bo_set_addr
drm/radeon: rework vm_flush parameters
drm/radeon/ci: disable needless sclk changes
drm/radeon/ci: force pcie level before sclk and mclk
drm/radeon/ci: use different smc command for pcie dpm
drm/radeon/ci: apply disp voltage changes before clk changes
drm/radeon: fix PCC debugging message for CI DPM
drm/radeon/dpm: add thermal dpm support for CI
drm/radeon/dpm: add smc fan control for CI (v2)
drm/radeon/dpm: add smc fan control for SI (v2)
drm/radeon: work around a hw bug in MGCG on CIK
...
38 files changed, 1646 insertions, 576 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index bad6caa0a727..12bc21219a0e 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -80,7 +80,8 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ | |||
80 | r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ | 80 | r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ |
81 | rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ | 81 | rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \ |
82 | trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ | 82 | trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \ |
83 | ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o | 83 | ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o \ |
84 | radeon_sync.o | ||
84 | 85 | ||
85 | # add async DMA block | 86 | # add async DMA block |
86 | radeon-y += \ | 87 | radeon-y += \ |
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 9dbc52f3c4d1..3f898d020ae6 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; |
@@ -693,6 +714,25 @@ static int ci_enable_smc_cac(struct radeon_device *rdev, bool enable) | |||
693 | return ret; | 714 | return ret; |
694 | } | 715 | } |
695 | 716 | ||
717 | static int ci_enable_thermal_based_sclk_dpm(struct radeon_device *rdev, | ||
718 | bool enable) | ||
719 | { | ||
720 | struct ci_power_info *pi = ci_get_pi(rdev); | ||
721 | PPSMC_Result smc_result = PPSMC_Result_OK; | ||
722 | |||
723 | if (pi->thermal_sclk_dpm_enabled) { | ||
724 | if (enable) | ||
725 | smc_result = ci_send_msg_to_smc(rdev, PPSMC_MSG_ENABLE_THERMAL_DPM); | ||
726 | else | ||
727 | smc_result = ci_send_msg_to_smc(rdev, PPSMC_MSG_DISABLE_THERMAL_DPM); | ||
728 | } | ||
729 | |||
730 | if (smc_result == PPSMC_Result_OK) | ||
731 | return 0; | ||
732 | else | ||
733 | return -EINVAL; | ||
734 | } | ||
735 | |||
696 | static int ci_power_control_set_level(struct radeon_device *rdev) | 736 | static int ci_power_control_set_level(struct radeon_device *rdev) |
697 | { | 737 | { |
698 | struct ci_power_info *pi = ci_get_pi(rdev); | 738 | struct ci_power_info *pi = ci_get_pi(rdev); |
@@ -859,6 +899,7 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev, | |||
859 | 899 | ||
860 | if (enable) { | 900 | if (enable) { |
861 | thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); | 901 | thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); |
902 | WREG32_SMC(CG_THERMAL_INT, thermal_int); | ||
862 | rdev->irq.dpm_thermal = false; | 903 | rdev->irq.dpm_thermal = false; |
863 | result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Enable); | 904 | result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Enable); |
864 | if (result != PPSMC_Result_OK) { | 905 | if (result != PPSMC_Result_OK) { |
@@ -867,6 +908,7 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev, | |||
867 | } | 908 | } |
868 | } else { | 909 | } else { |
869 | thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; | 910 | thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; |
911 | WREG32_SMC(CG_THERMAL_INT, thermal_int); | ||
870 | rdev->irq.dpm_thermal = true; | 912 | rdev->irq.dpm_thermal = true; |
871 | result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Disable); | 913 | result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Disable); |
872 | if (result != PPSMC_Result_OK) { | 914 | if (result != PPSMC_Result_OK) { |
@@ -875,12 +917,325 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev, | |||
875 | } | 917 | } |
876 | } | 918 | } |
877 | 919 | ||
878 | WREG32_SMC(CG_THERMAL_INT, thermal_int); | 920 | return 0; |
921 | } | ||
922 | |||
923 | static void ci_fan_ctrl_set_static_mode(struct radeon_device *rdev, u32 mode) | ||
924 | { | ||
925 | struct ci_power_info *pi = ci_get_pi(rdev); | ||
926 | u32 tmp; | ||
927 | |||
928 | if (pi->fan_ctrl_is_in_default_mode) { | ||
929 | tmp = (RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK) >> FDO_PWM_MODE_SHIFT; | ||
930 | pi->fan_ctrl_default_mode = tmp; | ||
931 | tmp = (RREG32_SMC(CG_FDO_CTRL2) & TMIN_MASK) >> TMIN_SHIFT; | ||
932 | pi->t_min = tmp; | ||
933 | pi->fan_ctrl_is_in_default_mode = false; | ||
934 | } | ||
935 | |||
936 | tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TMIN_MASK; | ||
937 | tmp |= TMIN(0); | ||
938 | WREG32_SMC(CG_FDO_CTRL2, tmp); | ||
939 | |||
940 | tmp = RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK; | ||
941 | tmp |= FDO_PWM_MODE(mode); | ||
942 | WREG32_SMC(CG_FDO_CTRL2, tmp); | ||
943 | } | ||
944 | |||
945 | static int ci_thermal_setup_fan_table(struct radeon_device *rdev) | ||
946 | { | ||
947 | struct ci_power_info *pi = ci_get_pi(rdev); | ||
948 | SMU7_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE }; | ||
949 | u32 duty100; | ||
950 | u32 t_diff1, t_diff2, pwm_diff1, pwm_diff2; | ||
951 | u16 fdo_min, slope1, slope2; | ||
952 | u32 reference_clock, tmp; | ||
953 | int ret; | ||
954 | u64 tmp64; | ||
955 | |||
956 | if (!pi->fan_table_start) { | ||
957 | rdev->pm.dpm.fan.ucode_fan_control = false; | ||
958 | return 0; | ||
959 | } | ||
960 | |||
961 | duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; | ||
962 | |||
963 | if (duty100 == 0) { | ||
964 | rdev->pm.dpm.fan.ucode_fan_control = false; | ||
965 | return 0; | ||
966 | } | ||
967 | |||
968 | tmp64 = (u64)rdev->pm.dpm.fan.pwm_min * duty100; | ||
969 | do_div(tmp64, 10000); | ||
970 | fdo_min = (u16)tmp64; | ||
971 | |||
972 | t_diff1 = rdev->pm.dpm.fan.t_med - rdev->pm.dpm.fan.t_min; | ||
973 | t_diff2 = rdev->pm.dpm.fan.t_high - rdev->pm.dpm.fan.t_med; | ||
974 | |||
975 | pwm_diff1 = rdev->pm.dpm.fan.pwm_med - rdev->pm.dpm.fan.pwm_min; | ||
976 | pwm_diff2 = rdev->pm.dpm.fan.pwm_high - rdev->pm.dpm.fan.pwm_med; | ||
977 | |||
978 | slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); | ||
979 | slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); | ||
980 | |||
981 | fan_table.TempMin = cpu_to_be16((50 + rdev->pm.dpm.fan.t_min) / 100); | ||
982 | fan_table.TempMed = cpu_to_be16((50 + rdev->pm.dpm.fan.t_med) / 100); | ||
983 | fan_table.TempMax = cpu_to_be16((50 + rdev->pm.dpm.fan.t_max) / 100); | ||
984 | |||
985 | fan_table.Slope1 = cpu_to_be16(slope1); | ||
986 | fan_table.Slope2 = cpu_to_be16(slope2); | ||
987 | |||
988 | fan_table.FdoMin = cpu_to_be16(fdo_min); | ||
989 | |||
990 | fan_table.HystDown = cpu_to_be16(rdev->pm.dpm.fan.t_hyst); | ||
991 | |||
992 | fan_table.HystUp = cpu_to_be16(1); | ||
993 | |||
994 | fan_table.HystSlope = cpu_to_be16(1); | ||
995 | |||
996 | fan_table.TempRespLim = cpu_to_be16(5); | ||
997 | |||
998 | reference_clock = radeon_get_xclk(rdev); | ||
999 | |||
1000 | fan_table.RefreshPeriod = cpu_to_be32((rdev->pm.dpm.fan.cycle_delay * | ||
1001 | reference_clock) / 1600); | ||
1002 | |||
1003 | fan_table.FdoMax = cpu_to_be16((u16)duty100); | ||
1004 | |||
1005 | tmp = (RREG32_SMC(CG_MULT_THERMAL_CTRL) & TEMP_SEL_MASK) >> TEMP_SEL_SHIFT; | ||
1006 | fan_table.TempSrc = (uint8_t)tmp; | ||
1007 | |||
1008 | ret = ci_copy_bytes_to_smc(rdev, | ||
1009 | pi->fan_table_start, | ||
1010 | (u8 *)(&fan_table), | ||
1011 | sizeof(fan_table), | ||
1012 | pi->sram_end); | ||
1013 | |||
1014 | if (ret) { | ||
1015 | DRM_ERROR("Failed to load fan table to the SMC."); | ||
1016 | rdev->pm.dpm.fan.ucode_fan_control = false; | ||
1017 | } | ||
1018 | |||
1019 | return 0; | ||
1020 | } | ||
1021 | |||
1022 | static int ci_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev) | ||
1023 | { | ||
1024 | struct ci_power_info *pi = ci_get_pi(rdev); | ||
1025 | PPSMC_Result ret; | ||
1026 | |||
1027 | if (pi->caps_od_fuzzy_fan_control_support) { | ||
1028 | ret = ci_send_msg_to_smc_with_parameter(rdev, | ||
1029 | PPSMC_StartFanControl, | ||
1030 | FAN_CONTROL_FUZZY); | ||
1031 | if (ret != PPSMC_Result_OK) | ||
1032 | return -EINVAL; | ||
1033 | ret = ci_send_msg_to_smc_with_parameter(rdev, | ||
1034 | PPSMC_MSG_SetFanPwmMax, | ||
1035 | rdev->pm.dpm.fan.default_max_fan_pwm); | ||
1036 | if (ret != PPSMC_Result_OK) | ||
1037 | return -EINVAL; | ||
1038 | } else { | ||
1039 | ret = ci_send_msg_to_smc_with_parameter(rdev, | ||
1040 | PPSMC_StartFanControl, | ||
1041 | FAN_CONTROL_TABLE); | ||
1042 | if (ret != PPSMC_Result_OK) | ||
1043 | return -EINVAL; | ||
1044 | } | ||
879 | 1045 | ||
880 | return 0; | 1046 | return 0; |
881 | } | 1047 | } |
882 | 1048 | ||
883 | #if 0 | 1049 | #if 0 |
1050 | static int ci_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev) | ||
1051 | { | ||
1052 | PPSMC_Result ret; | ||
1053 | |||
1054 | ret = ci_send_msg_to_smc(rdev, PPSMC_StopFanControl); | ||
1055 | if (ret == PPSMC_Result_OK) | ||
1056 | return 0; | ||
1057 | else | ||
1058 | return -EINVAL; | ||
1059 | } | ||
1060 | |||
1061 | static int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev, | ||
1062 | u32 *speed) | ||
1063 | { | ||
1064 | u32 duty, duty100; | ||
1065 | u64 tmp64; | ||
1066 | |||
1067 | if (rdev->pm.no_fan) | ||
1068 | return -ENOENT; | ||
1069 | |||
1070 | duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; | ||
1071 | duty = (RREG32_SMC(CG_THERMAL_STATUS) & FDO_PWM_DUTY_MASK) >> FDO_PWM_DUTY_SHIFT; | ||
1072 | |||
1073 | if (duty100 == 0) | ||
1074 | return -EINVAL; | ||
1075 | |||
1076 | tmp64 = (u64)duty * 100; | ||
1077 | do_div(tmp64, duty100); | ||
1078 | *speed = (u32)tmp64; | ||
1079 | |||
1080 | if (*speed > 100) | ||
1081 | *speed = 100; | ||
1082 | |||
1083 | return 0; | ||
1084 | } | ||
1085 | |||
1086 | static int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev, | ||
1087 | u32 speed) | ||
1088 | { | ||
1089 | u32 tmp; | ||
1090 | u32 duty, duty100; | ||
1091 | u64 tmp64; | ||
1092 | |||
1093 | if (rdev->pm.no_fan) | ||
1094 | return -ENOENT; | ||
1095 | |||
1096 | if (speed > 100) | ||
1097 | return -EINVAL; | ||
1098 | |||
1099 | if (rdev->pm.dpm.fan.ucode_fan_control) | ||
1100 | ci_fan_ctrl_stop_smc_fan_control(rdev); | ||
1101 | |||
1102 | duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT; | ||
1103 | |||
1104 | if (duty100 == 0) | ||
1105 | return -EINVAL; | ||
1106 | |||
1107 | tmp64 = (u64)speed * duty100; | ||
1108 | do_div(tmp64, 100); | ||
1109 | duty = (u32)tmp64; | ||
1110 | |||
1111 | tmp = RREG32_SMC(CG_FDO_CTRL0) & ~FDO_STATIC_DUTY_MASK; | ||
1112 | tmp |= FDO_STATIC_DUTY(duty); | ||
1113 | WREG32_SMC(CG_FDO_CTRL0, tmp); | ||
1114 | |||
1115 | ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); | ||
1116 | |||
1117 | return 0; | ||
1118 | } | ||
1119 | |||
1120 | static int ci_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev, | ||
1121 | u32 *speed) | ||
1122 | { | ||
1123 | u32 tach_period; | ||
1124 | u32 xclk = radeon_get_xclk(rdev); | ||
1125 | |||
1126 | if (rdev->pm.no_fan) | ||
1127 | return -ENOENT; | ||
1128 | |||
1129 | if (rdev->pm.fan_pulses_per_revolution == 0) | ||
1130 | return -ENOENT; | ||
1131 | |||
1132 | tach_period = (RREG32_SMC(CG_TACH_STATUS) & TACH_PERIOD_MASK) >> TACH_PERIOD_SHIFT; | ||
1133 | if (tach_period == 0) | ||
1134 | return -ENOENT; | ||
1135 | |||
1136 | *speed = 60 * xclk * 10000 / tach_period; | ||
1137 | |||
1138 | return 0; | ||
1139 | } | ||
1140 | |||
1141 | static int ci_fan_ctrl_set_fan_speed_rpm(struct radeon_device *rdev, | ||
1142 | u32 speed) | ||
1143 | { | ||
1144 | u32 tach_period, tmp; | ||
1145 | u32 xclk = radeon_get_xclk(rdev); | ||
1146 | |||
1147 | if (rdev->pm.no_fan) | ||
1148 | return -ENOENT; | ||
1149 | |||
1150 | if (rdev->pm.fan_pulses_per_revolution == 0) | ||
1151 | return -ENOENT; | ||
1152 | |||
1153 | if ((speed < rdev->pm.fan_min_rpm) || | ||
1154 | (speed > rdev->pm.fan_max_rpm)) | ||
1155 | return -EINVAL; | ||
1156 | |||
1157 | if (rdev->pm.dpm.fan.ucode_fan_control) | ||
1158 | ci_fan_ctrl_stop_smc_fan_control(rdev); | ||
1159 | |||
1160 | tach_period = 60 * xclk * 10000 / (8 * speed); | ||
1161 | tmp = RREG32_SMC(CG_TACH_CTRL) & ~TARGET_PERIOD_MASK; | ||
1162 | tmp |= TARGET_PERIOD(tach_period); | ||
1163 | WREG32_SMC(CG_TACH_CTRL, tmp); | ||
1164 | |||
1165 | ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); | ||
1166 | |||
1167 | return 0; | ||
1168 | } | ||
1169 | #endif | ||
1170 | |||
1171 | static void ci_fan_ctrl_set_default_mode(struct radeon_device *rdev) | ||
1172 | { | ||
1173 | struct ci_power_info *pi = ci_get_pi(rdev); | ||
1174 | u32 tmp; | ||
1175 | |||
1176 | if (!pi->fan_ctrl_is_in_default_mode) { | ||
1177 | tmp = RREG32_SMC(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK; | ||
1178 | tmp |= FDO_PWM_MODE(pi->fan_ctrl_default_mode); | ||
1179 | WREG32_SMC(CG_FDO_CTRL2, tmp); | ||
1180 | |||
1181 | tmp = RREG32_SMC(CG_FDO_CTRL2) & TMIN_MASK; | ||
1182 | tmp |= TMIN(pi->t_min); | ||
1183 | WREG32_SMC(CG_FDO_CTRL2, tmp); | ||
1184 | pi->fan_ctrl_is_in_default_mode = true; | ||
1185 | } | ||
1186 | } | ||
1187 | |||
1188 | static void ci_thermal_start_smc_fan_control(struct radeon_device *rdev) | ||
1189 | { | ||
1190 | if (rdev->pm.dpm.fan.ucode_fan_control) { | ||
1191 | ci_fan_ctrl_start_smc_fan_control(rdev); | ||
1192 | ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); | ||
1193 | } | ||
1194 | } | ||
1195 | |||
1196 | static void ci_thermal_initialize(struct radeon_device *rdev) | ||
1197 | { | ||
1198 | u32 tmp; | ||
1199 | |||
1200 | if (rdev->pm.fan_pulses_per_revolution) { | ||
1201 | tmp = RREG32_SMC(CG_TACH_CTRL) & ~EDGE_PER_REV_MASK; | ||
1202 | tmp |= EDGE_PER_REV(rdev->pm.fan_pulses_per_revolution -1); | ||
1203 | WREG32_SMC(CG_TACH_CTRL, tmp); | ||
1204 | } | ||
1205 | |||
1206 | tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TACH_PWM_RESP_RATE_MASK; | ||
1207 | tmp |= TACH_PWM_RESP_RATE(0x28); | ||
1208 | WREG32_SMC(CG_FDO_CTRL2, tmp); | ||
1209 | } | ||
1210 | |||
1211 | static int ci_thermal_start_thermal_controller(struct radeon_device *rdev) | ||
1212 | { | ||
1213 | int ret; | ||
1214 | |||
1215 | ci_thermal_initialize(rdev); | ||
1216 | ret = ci_thermal_set_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); | ||
1217 | if (ret) | ||
1218 | return ret; | ||
1219 | ret = ci_thermal_enable_alert(rdev, true); | ||
1220 | if (ret) | ||
1221 | return ret; | ||
1222 | if (rdev->pm.dpm.fan.ucode_fan_control) { | ||
1223 | ret = ci_thermal_setup_fan_table(rdev); | ||
1224 | if (ret) | ||
1225 | return ret; | ||
1226 | ci_thermal_start_smc_fan_control(rdev); | ||
1227 | } | ||
1228 | |||
1229 | return 0; | ||
1230 | } | ||
1231 | |||
1232 | static void ci_thermal_stop_thermal_controller(struct radeon_device *rdev) | ||
1233 | { | ||
1234 | if (!rdev->pm.no_fan) | ||
1235 | ci_fan_ctrl_set_default_mode(rdev); | ||
1236 | } | ||
1237 | |||
1238 | #if 0 | ||
884 | static int ci_read_smc_soft_register(struct radeon_device *rdev, | 1239 | static int ci_read_smc_soft_register(struct radeon_device *rdev, |
885 | u16 reg_offset, u32 *value) | 1240 | u16 reg_offset, u32 *value) |
886 | { | 1241 | { |
@@ -3397,6 +3752,8 @@ static int ci_upload_dpm_level_enable_mask(struct radeon_device *rdev) | |||
3397 | struct ci_power_info *pi = ci_get_pi(rdev); | 3752 | struct ci_power_info *pi = ci_get_pi(rdev); |
3398 | PPSMC_Result result; | 3753 | PPSMC_Result result; |
3399 | 3754 | ||
3755 | ci_apply_disp_minimum_voltage_request(rdev); | ||
3756 | |||
3400 | if (!pi->sclk_dpm_key_disabled) { | 3757 | if (!pi->sclk_dpm_key_disabled) { |
3401 | if (pi->dpm_level_enable_mask.sclk_dpm_enable_mask) { | 3758 | if (pi->dpm_level_enable_mask.sclk_dpm_enable_mask) { |
3402 | result = ci_send_msg_to_smc_with_parameter(rdev, | 3759 | result = ci_send_msg_to_smc_with_parameter(rdev, |
@@ -3416,7 +3773,7 @@ static int ci_upload_dpm_level_enable_mask(struct radeon_device *rdev) | |||
3416 | return -EINVAL; | 3773 | return -EINVAL; |
3417 | } | 3774 | } |
3418 | } | 3775 | } |
3419 | 3776 | #if 0 | |
3420 | if (!pi->pcie_dpm_key_disabled) { | 3777 | if (!pi->pcie_dpm_key_disabled) { |
3421 | if (pi->dpm_level_enable_mask.pcie_dpm_enable_mask) { | 3778 | if (pi->dpm_level_enable_mask.pcie_dpm_enable_mask) { |
3422 | result = ci_send_msg_to_smc_with_parameter(rdev, | 3779 | result = ci_send_msg_to_smc_with_parameter(rdev, |
@@ -3426,9 +3783,7 @@ static int ci_upload_dpm_level_enable_mask(struct radeon_device *rdev) | |||
3426 | return -EINVAL; | 3783 | return -EINVAL; |
3427 | } | 3784 | } |
3428 | } | 3785 | } |
3429 | 3786 | #endif | |
3430 | ci_apply_disp_minimum_voltage_request(rdev); | ||
3431 | |||
3432 | return 0; | 3787 | return 0; |
3433 | } | 3788 | } |
3434 | 3789 | ||
@@ -3454,7 +3809,7 @@ static void ci_find_dpm_states_clocks_in_dpm_table(struct radeon_device *rdev, | |||
3454 | pi->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; | 3809 | pi->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK; |
3455 | } else { | 3810 | } else { |
3456 | /* XXX check display min clock requirements */ | 3811 | /* XXX check display min clock requirements */ |
3457 | if (0 != CISLAND_MINIMUM_ENGINE_CLOCK) | 3812 | if (CISLAND_MINIMUM_ENGINE_CLOCK != CISLAND_MINIMUM_ENGINE_CLOCK) |
3458 | pi->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_SCLK; | 3813 | pi->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_SCLK; |
3459 | } | 3814 | } |
3460 | 3815 | ||
@@ -3788,57 +4143,57 @@ int ci_dpm_force_performance_level(struct radeon_device *rdev, | |||
3788 | int ret; | 4143 | int ret; |
3789 | 4144 | ||
3790 | if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { | 4145 | if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { |
3791 | if ((!pi->sclk_dpm_key_disabled) && | 4146 | if ((!pi->pcie_dpm_key_disabled) && |
3792 | pi->dpm_level_enable_mask.sclk_dpm_enable_mask) { | 4147 | pi->dpm_level_enable_mask.pcie_dpm_enable_mask) { |
3793 | levels = 0; | 4148 | levels = 0; |
3794 | tmp = pi->dpm_level_enable_mask.sclk_dpm_enable_mask; | 4149 | tmp = pi->dpm_level_enable_mask.pcie_dpm_enable_mask; |
3795 | while (tmp >>= 1) | 4150 | while (tmp >>= 1) |
3796 | levels++; | 4151 | levels++; |
3797 | if (levels) { | 4152 | if (levels) { |
3798 | ret = ci_dpm_force_state_sclk(rdev, levels); | 4153 | ret = ci_dpm_force_state_pcie(rdev, level); |
3799 | if (ret) | 4154 | if (ret) |
3800 | return ret; | 4155 | return ret; |
3801 | for (i = 0; i < rdev->usec_timeout; i++) { | 4156 | for (i = 0; i < rdev->usec_timeout; i++) { |
3802 | tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) & | 4157 | tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX_1) & |
3803 | CURR_SCLK_INDEX_MASK) >> CURR_SCLK_INDEX_SHIFT; | 4158 | CURR_PCIE_INDEX_MASK) >> CURR_PCIE_INDEX_SHIFT; |
3804 | if (tmp == levels) | 4159 | if (tmp == levels) |
3805 | break; | 4160 | break; |
3806 | udelay(1); | 4161 | udelay(1); |
3807 | } | 4162 | } |
3808 | } | 4163 | } |
3809 | } | 4164 | } |
3810 | if ((!pi->mclk_dpm_key_disabled) && | 4165 | if ((!pi->sclk_dpm_key_disabled) && |
3811 | pi->dpm_level_enable_mask.mclk_dpm_enable_mask) { | 4166 | pi->dpm_level_enable_mask.sclk_dpm_enable_mask) { |
3812 | levels = 0; | 4167 | levels = 0; |
3813 | tmp = pi->dpm_level_enable_mask.mclk_dpm_enable_mask; | 4168 | tmp = pi->dpm_level_enable_mask.sclk_dpm_enable_mask; |
3814 | while (tmp >>= 1) | 4169 | while (tmp >>= 1) |
3815 | levels++; | 4170 | levels++; |
3816 | if (levels) { | 4171 | if (levels) { |
3817 | ret = ci_dpm_force_state_mclk(rdev, levels); | 4172 | ret = ci_dpm_force_state_sclk(rdev, levels); |
3818 | if (ret) | 4173 | if (ret) |
3819 | return ret; | 4174 | return ret; |
3820 | for (i = 0; i < rdev->usec_timeout; i++) { | 4175 | for (i = 0; i < rdev->usec_timeout; i++) { |
3821 | tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) & | 4176 | tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) & |
3822 | CURR_MCLK_INDEX_MASK) >> CURR_MCLK_INDEX_SHIFT; | 4177 | CURR_SCLK_INDEX_MASK) >> CURR_SCLK_INDEX_SHIFT; |
3823 | if (tmp == levels) | 4178 | if (tmp == levels) |
3824 | break; | 4179 | break; |
3825 | udelay(1); | 4180 | udelay(1); |
3826 | } | 4181 | } |
3827 | } | 4182 | } |
3828 | } | 4183 | } |
3829 | if ((!pi->pcie_dpm_key_disabled) && | 4184 | if ((!pi->mclk_dpm_key_disabled) && |
3830 | pi->dpm_level_enable_mask.pcie_dpm_enable_mask) { | 4185 | pi->dpm_level_enable_mask.mclk_dpm_enable_mask) { |
3831 | levels = 0; | 4186 | levels = 0; |
3832 | tmp = pi->dpm_level_enable_mask.pcie_dpm_enable_mask; | 4187 | tmp = pi->dpm_level_enable_mask.mclk_dpm_enable_mask; |
3833 | while (tmp >>= 1) | 4188 | while (tmp >>= 1) |
3834 | levels++; | 4189 | levels++; |
3835 | if (levels) { | 4190 | if (levels) { |
3836 | ret = ci_dpm_force_state_pcie(rdev, level); | 4191 | ret = ci_dpm_force_state_mclk(rdev, levels); |
3837 | if (ret) | 4192 | if (ret) |
3838 | return ret; | 4193 | return ret; |
3839 | for (i = 0; i < rdev->usec_timeout; i++) { | 4194 | for (i = 0; i < rdev->usec_timeout; i++) { |
3840 | tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX_1) & | 4195 | tmp = (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) & |
3841 | CURR_PCIE_INDEX_MASK) >> CURR_PCIE_INDEX_SHIFT; | 4196 | CURR_MCLK_INDEX_MASK) >> CURR_MCLK_INDEX_SHIFT; |
3842 | if (tmp == levels) | 4197 | if (tmp == levels) |
3843 | break; | 4198 | break; |
3844 | udelay(1); | 4199 | udelay(1); |
@@ -3892,6 +4247,14 @@ int ci_dpm_force_performance_level(struct radeon_device *rdev, | |||
3892 | } | 4247 | } |
3893 | } | 4248 | } |
3894 | } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) { | 4249 | } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) { |
4250 | if (!pi->pcie_dpm_key_disabled) { | ||
4251 | PPSMC_Result smc_result; | ||
4252 | |||
4253 | smc_result = ci_send_msg_to_smc(rdev, | ||
4254 | PPSMC_MSG_PCIeDPM_UnForceLevel); | ||
4255 | if (smc_result != PPSMC_Result_OK) | ||
4256 | return -EINVAL; | ||
4257 | } | ||
3895 | ret = ci_upload_dpm_level_enable_mask(rdev); | 4258 | ret = ci_upload_dpm_level_enable_mask(rdev); |
3896 | if (ret) | 4259 | if (ret) |
3897 | return ret; | 4260 | return ret; |
@@ -4841,6 +5204,14 @@ int ci_dpm_enable(struct radeon_device *rdev) | |||
4841 | 5204 | ||
4842 | ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); | 5205 | ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); |
4843 | 5206 | ||
5207 | ret = ci_enable_thermal_based_sclk_dpm(rdev, true); | ||
5208 | if (ret) { | ||
5209 | DRM_ERROR("ci_enable_thermal_based_sclk_dpm failed\n"); | ||
5210 | return ret; | ||
5211 | } | ||
5212 | |||
5213 | ci_thermal_start_thermal_controller(rdev); | ||
5214 | |||
4844 | ci_update_current_ps(rdev, boot_ps); | 5215 | ci_update_current_ps(rdev, boot_ps); |
4845 | 5216 | ||
4846 | return 0; | 5217 | return 0; |
@@ -4886,6 +5257,8 @@ void ci_dpm_disable(struct radeon_device *rdev) | |||
4886 | if (!ci_is_smc_running(rdev)) | 5257 | if (!ci_is_smc_running(rdev)) |
4887 | return; | 5258 | return; |
4888 | 5259 | ||
5260 | ci_thermal_stop_thermal_controller(rdev); | ||
5261 | |||
4889 | if (pi->thermal_protection) | 5262 | if (pi->thermal_protection) |
4890 | ci_enable_thermal_protection(rdev, false); | 5263 | ci_enable_thermal_protection(rdev, false); |
4891 | ci_enable_power_containment(rdev, false); | 5264 | ci_enable_power_containment(rdev, false); |
@@ -4900,6 +5273,7 @@ void ci_dpm_disable(struct radeon_device *rdev) | |||
4900 | ci_reset_to_default(rdev); | 5273 | ci_reset_to_default(rdev); |
4901 | ci_dpm_stop_smc(rdev); | 5274 | ci_dpm_stop_smc(rdev); |
4902 | ci_force_switch_to_arb_f0(rdev); | 5275 | ci_force_switch_to_arb_f0(rdev); |
5276 | ci_enable_thermal_based_sclk_dpm(rdev, false); | ||
4903 | 5277 | ||
4904 | ci_update_current_ps(rdev, boot_ps); | 5278 | ci_update_current_ps(rdev, boot_ps); |
4905 | } | 5279 | } |
@@ -5299,6 +5673,7 @@ int ci_dpm_init(struct radeon_device *rdev) | |||
5299 | pi->sclk_dpm_key_disabled = 0; | 5673 | pi->sclk_dpm_key_disabled = 0; |
5300 | pi->mclk_dpm_key_disabled = 0; | 5674 | pi->mclk_dpm_key_disabled = 0; |
5301 | pi->pcie_dpm_key_disabled = 0; | 5675 | pi->pcie_dpm_key_disabled = 0; |
5676 | pi->thermal_sclk_dpm_enabled = 0; | ||
5302 | 5677 | ||
5303 | /* mclk dpm is unstable on some R7 260X cards with the old mc ucode */ | 5678 | /* mclk dpm is unstable on some R7 260X cards with the old mc ucode */ |
5304 | if ((rdev->pdev->device == 0x6658) && | 5679 | if ((rdev->pdev->device == 0x6658) && |
@@ -5406,7 +5781,7 @@ int ci_dpm_init(struct radeon_device *rdev) | |||
5406 | tmp |= DPM_ENABLED; | 5781 | tmp |= DPM_ENABLED; |
5407 | break; | 5782 | break; |
5408 | default: | 5783 | default: |
5409 | DRM_ERROR("Invalid PCC GPIO!"); | 5784 | DRM_ERROR("Invalid PCC GPIO: %u!\n", gpio.shift); |
5410 | break; | 5785 | break; |
5411 | } | 5786 | } |
5412 | WREG32_SMC(CNB_PWRMGT_CNTL, tmp); | 5787 | WREG32_SMC(CNB_PWRMGT_CNTL, tmp); |
@@ -5473,6 +5848,9 @@ int ci_dpm_init(struct radeon_device *rdev) | |||
5473 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc = | 5848 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc = |
5474 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; | 5849 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; |
5475 | 5850 | ||
5851 | pi->fan_ctrl_is_in_default_mode = true; | ||
5852 | rdev->pm.dpm.fan.ucode_fan_control = false; | ||
5853 | |||
5476 | return 0; | 5854 | return 0; |
5477 | } | 5855 | } |
5478 | 5856 | ||
diff --git a/drivers/gpu/drm/radeon/ci_dpm.h b/drivers/gpu/drm/radeon/ci_dpm.h index 615cb2cacf2c..84e3d3bcf9f3 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.h +++ b/drivers/gpu/drm/radeon/ci_dpm.h | |||
@@ -239,6 +239,7 @@ struct ci_power_info { | |||
239 | u32 sclk_dpm_key_disabled; | 239 | u32 sclk_dpm_key_disabled; |
240 | u32 mclk_dpm_key_disabled; | 240 | u32 mclk_dpm_key_disabled; |
241 | u32 pcie_dpm_key_disabled; | 241 | u32 pcie_dpm_key_disabled; |
242 | u32 thermal_sclk_dpm_enabled; | ||
242 | struct ci_pcie_perf_range pcie_gen_performance; | 243 | struct ci_pcie_perf_range pcie_gen_performance; |
243 | struct ci_pcie_perf_range pcie_lane_performance; | 244 | struct ci_pcie_perf_range pcie_lane_performance; |
244 | struct ci_pcie_perf_range pcie_gen_powersaving; | 245 | struct ci_pcie_perf_range pcie_gen_powersaving; |
@@ -266,6 +267,7 @@ struct ci_power_info { | |||
266 | bool caps_automatic_dc_transition; | 267 | bool caps_automatic_dc_transition; |
267 | bool caps_sclk_throttle_low_notification; | 268 | bool caps_sclk_throttle_low_notification; |
268 | bool caps_dynamic_ac_timing; | 269 | bool caps_dynamic_ac_timing; |
270 | bool caps_od_fuzzy_fan_control_support; | ||
269 | /* flags */ | 271 | /* flags */ |
270 | bool thermal_protection; | 272 | bool thermal_protection; |
271 | bool pcie_performance_request; | 273 | bool pcie_performance_request; |
@@ -287,6 +289,10 @@ struct ci_power_info { | |||
287 | struct ci_ps current_ps; | 289 | struct ci_ps current_ps; |
288 | struct radeon_ps requested_rps; | 290 | struct radeon_ps requested_rps; |
289 | struct ci_ps requested_ps; | 291 | struct ci_ps requested_ps; |
292 | /* fan control */ | ||
293 | bool fan_ctrl_is_in_default_mode; | ||
294 | u32 t_min; | ||
295 | u32 fan_ctrl_default_mode; | ||
290 | }; | 296 | }; |
291 | 297 | ||
292 | #define CISLANDS_VOLTAGE_CONTROL_NONE 0x0 | 298 | #define CISLANDS_VOLTAGE_CONTROL_NONE 0x0 |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index bce73b6203ac..3deeed33322f 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -3994,31 +3994,27 @@ struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, | |||
3994 | unsigned num_gpu_pages, | 3994 | unsigned num_gpu_pages, |
3995 | struct reservation_object *resv) | 3995 | struct reservation_object *resv) |
3996 | { | 3996 | { |
3997 | struct radeon_semaphore *sem = NULL; | ||
3998 | struct radeon_fence *fence; | 3997 | struct radeon_fence *fence; |
3998 | struct radeon_sync sync; | ||
3999 | int ring_index = rdev->asic->copy.blit_ring_index; | 3999 | int ring_index = rdev->asic->copy.blit_ring_index; |
4000 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 4000 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
4001 | u32 size_in_bytes, cur_size_in_bytes, control; | 4001 | u32 size_in_bytes, cur_size_in_bytes, control; |
4002 | int i, num_loops; | 4002 | int i, num_loops; |
4003 | int r = 0; | 4003 | int r = 0; |
4004 | 4004 | ||
4005 | r = radeon_semaphore_create(rdev, &sem); | 4005 | radeon_sync_create(&sync); |
4006 | if (r) { | ||
4007 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
4008 | return ERR_PTR(r); | ||
4009 | } | ||
4010 | 4006 | ||
4011 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); | 4007 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); |
4012 | num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); | 4008 | num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); |
4013 | r = radeon_ring_lock(rdev, ring, num_loops * 7 + 18); | 4009 | r = radeon_ring_lock(rdev, ring, num_loops * 7 + 18); |
4014 | if (r) { | 4010 | if (r) { |
4015 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 4011 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
4016 | radeon_semaphore_free(rdev, &sem, NULL); | 4012 | radeon_sync_free(rdev, &sync, NULL); |
4017 | return ERR_PTR(r); | 4013 | return ERR_PTR(r); |
4018 | } | 4014 | } |
4019 | 4015 | ||
4020 | radeon_semaphore_sync_resv(rdev, sem, resv, false); | 4016 | radeon_sync_resv(rdev, &sync, resv, false); |
4021 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 4017 | radeon_sync_rings(rdev, &sync, ring->idx); |
4022 | 4018 | ||
4023 | for (i = 0; i < num_loops; i++) { | 4019 | for (i = 0; i < num_loops; i++) { |
4024 | cur_size_in_bytes = size_in_bytes; | 4020 | cur_size_in_bytes = size_in_bytes; |
@@ -4042,12 +4038,12 @@ struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, | |||
4042 | r = radeon_fence_emit(rdev, &fence, ring->idx); | 4038 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
4043 | if (r) { | 4039 | if (r) { |
4044 | radeon_ring_unlock_undo(rdev, ring); | 4040 | radeon_ring_unlock_undo(rdev, ring); |
4045 | radeon_semaphore_free(rdev, &sem, NULL); | 4041 | radeon_sync_free(rdev, &sync, NULL); |
4046 | return ERR_PTR(r); | 4042 | return ERR_PTR(r); |
4047 | } | 4043 | } |
4048 | 4044 | ||
4049 | radeon_ring_unlock_commit(rdev, ring, false); | 4045 | radeon_ring_unlock_commit(rdev, ring, false); |
4050 | radeon_semaphore_free(rdev, &sem, fence); | 4046 | radeon_sync_free(rdev, &sync, fence); |
4051 | 4047 | ||
4052 | return fence; | 4048 | return fence; |
4053 | } | 4049 | } |
@@ -4070,6 +4066,7 @@ struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, | |||
4070 | void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 4066 | void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
4071 | { | 4067 | { |
4072 | struct radeon_ring *ring = &rdev->ring[ib->ring]; | 4068 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
4069 | unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0; | ||
4073 | u32 header, control = INDIRECT_BUFFER_VALID; | 4070 | u32 header, control = INDIRECT_BUFFER_VALID; |
4074 | 4071 | ||
4075 | if (ib->is_const_ib) { | 4072 | if (ib->is_const_ib) { |
@@ -4098,8 +4095,7 @@ void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
4098 | header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); | 4095 | header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); |
4099 | } | 4096 | } |
4100 | 4097 | ||
4101 | control |= ib->length_dw | | 4098 | control |= ib->length_dw | (vm_id << 24); |
4102 | (ib->vm ? (ib->vm->id << 24) : 0); | ||
4103 | 4099 | ||
4104 | radeon_ring_write(ring, header); | 4100 | radeon_ring_write(ring, header); |
4105 | radeon_ring_write(ring, | 4101 | radeon_ring_write(ring, |
@@ -5982,26 +5978,23 @@ static void cik_vm_decode_fault(struct radeon_device *rdev, | |||
5982 | * Update the page table base and flush the VM TLB | 5978 | * Update the page table base and flush the VM TLB |
5983 | * using the CP (CIK). | 5979 | * using the CP (CIK). |
5984 | */ | 5980 | */ |
5985 | void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | 5981 | void cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
5982 | unsigned vm_id, uint64_t pd_addr) | ||
5986 | { | 5983 | { |
5987 | struct radeon_ring *ring = &rdev->ring[ridx]; | 5984 | int usepfp = (ring->idx == RADEON_RING_TYPE_GFX_INDEX); |
5988 | int usepfp = (ridx == RADEON_RING_TYPE_GFX_INDEX); | ||
5989 | |||
5990 | if (vm == NULL) | ||
5991 | return; | ||
5992 | 5985 | ||
5993 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | 5986 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
5994 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | | 5987 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | |
5995 | WRITE_DATA_DST_SEL(0))); | 5988 | WRITE_DATA_DST_SEL(0))); |
5996 | if (vm->id < 8) { | 5989 | if (vm_id < 8) { |
5997 | radeon_ring_write(ring, | 5990 | radeon_ring_write(ring, |
5998 | (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2); | 5991 | (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); |
5999 | } else { | 5992 | } else { |
6000 | radeon_ring_write(ring, | 5993 | radeon_ring_write(ring, |
6001 | (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2); | 5994 | (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2); |
6002 | } | 5995 | } |
6003 | radeon_ring_write(ring, 0); | 5996 | radeon_ring_write(ring, 0); |
6004 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); | 5997 | radeon_ring_write(ring, pd_addr >> 12); |
6005 | 5998 | ||
6006 | /* update SH_MEM_* regs */ | 5999 | /* update SH_MEM_* regs */ |
6007 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | 6000 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
@@ -6009,7 +6002,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
6009 | WRITE_DATA_DST_SEL(0))); | 6002 | WRITE_DATA_DST_SEL(0))); |
6010 | radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); | 6003 | radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); |
6011 | radeon_ring_write(ring, 0); | 6004 | radeon_ring_write(ring, 0); |
6012 | radeon_ring_write(ring, VMID(vm->id)); | 6005 | radeon_ring_write(ring, VMID(vm_id)); |
6013 | 6006 | ||
6014 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 6)); | 6007 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 6)); |
6015 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | | 6008 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | |
@@ -6030,7 +6023,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
6030 | radeon_ring_write(ring, VMID(0)); | 6023 | radeon_ring_write(ring, VMID(0)); |
6031 | 6024 | ||
6032 | /* HDP flush */ | 6025 | /* HDP flush */ |
6033 | cik_hdp_flush_cp_ring_emit(rdev, ridx); | 6026 | cik_hdp_flush_cp_ring_emit(rdev, ring->idx); |
6034 | 6027 | ||
6035 | /* bits 0-15 are the VM contexts0-15 */ | 6028 | /* bits 0-15 are the VM contexts0-15 */ |
6036 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | 6029 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
@@ -6038,7 +6031,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
6038 | WRITE_DATA_DST_SEL(0))); | 6031 | WRITE_DATA_DST_SEL(0))); |
6039 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | 6032 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); |
6040 | radeon_ring_write(ring, 0); | 6033 | radeon_ring_write(ring, 0); |
6041 | radeon_ring_write(ring, 1 << vm->id); | 6034 | radeon_ring_write(ring, 1 << vm_id); |
6042 | 6035 | ||
6043 | /* compute doesn't have PFP */ | 6036 | /* compute doesn't have PFP */ |
6044 | if (usepfp) { | 6037 | if (usepfp) { |
@@ -6344,6 +6337,7 @@ static void cik_enable_mgcg(struct radeon_device *rdev, bool enable) | |||
6344 | } | 6337 | } |
6345 | 6338 | ||
6346 | orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); | 6339 | orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); |
6340 | data |= 0x00000001; | ||
6347 | data &= 0xfffffffd; | 6341 | data &= 0xfffffffd; |
6348 | if (orig != data) | 6342 | if (orig != data) |
6349 | WREG32(RLC_CGTT_MGCG_OVERRIDE, data); | 6343 | WREG32(RLC_CGTT_MGCG_OVERRIDE, data); |
@@ -6377,7 +6371,7 @@ static void cik_enable_mgcg(struct radeon_device *rdev, bool enable) | |||
6377 | } | 6371 | } |
6378 | } else { | 6372 | } else { |
6379 | orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); | 6373 | orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); |
6380 | data |= 0x00000002; | 6374 | data |= 0x00000003; |
6381 | if (orig != data) | 6375 | if (orig != data) |
6382 | WREG32(RLC_CGTT_MGCG_OVERRIDE, data); | 6376 | WREG32(RLC_CGTT_MGCG_OVERRIDE, data); |
6383 | 6377 | ||
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index 4e8432d07f15..54b98379188d 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c | |||
@@ -134,7 +134,7 @@ void cik_sdma_ring_ib_execute(struct radeon_device *rdev, | |||
134 | struct radeon_ib *ib) | 134 | struct radeon_ib *ib) |
135 | { | 135 | { |
136 | struct radeon_ring *ring = &rdev->ring[ib->ring]; | 136 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
137 | u32 extra_bits = (ib->vm ? ib->vm->id : 0) & 0xf; | 137 | u32 extra_bits = (ib->vm ? ib->vm->ids[ib->ring].id : 0) & 0xf; |
138 | 138 | ||
139 | if (rdev->wb.enabled) { | 139 | if (rdev->wb.enabled) { |
140 | u32 next_rptr = ring->wptr + 5; | 140 | u32 next_rptr = ring->wptr + 5; |
@@ -541,31 +541,27 @@ struct radeon_fence *cik_copy_dma(struct radeon_device *rdev, | |||
541 | unsigned num_gpu_pages, | 541 | unsigned num_gpu_pages, |
542 | struct reservation_object *resv) | 542 | struct reservation_object *resv) |
543 | { | 543 | { |
544 | struct radeon_semaphore *sem = NULL; | ||
545 | struct radeon_fence *fence; | 544 | struct radeon_fence *fence; |
545 | struct radeon_sync sync; | ||
546 | int ring_index = rdev->asic->copy.dma_ring_index; | 546 | int ring_index = rdev->asic->copy.dma_ring_index; |
547 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 547 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
548 | u32 size_in_bytes, cur_size_in_bytes; | 548 | u32 size_in_bytes, cur_size_in_bytes; |
549 | int i, num_loops; | 549 | int i, num_loops; |
550 | int r = 0; | 550 | int r = 0; |
551 | 551 | ||
552 | r = radeon_semaphore_create(rdev, &sem); | 552 | radeon_sync_create(&sync); |
553 | if (r) { | ||
554 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
555 | return ERR_PTR(r); | ||
556 | } | ||
557 | 553 | ||
558 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); | 554 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); |
559 | num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); | 555 | num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); |
560 | r = radeon_ring_lock(rdev, ring, num_loops * 7 + 14); | 556 | r = radeon_ring_lock(rdev, ring, num_loops * 7 + 14); |
561 | if (r) { | 557 | if (r) { |
562 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 558 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
563 | radeon_semaphore_free(rdev, &sem, NULL); | 559 | radeon_sync_free(rdev, &sync, NULL); |
564 | return ERR_PTR(r); | 560 | return ERR_PTR(r); |
565 | } | 561 | } |
566 | 562 | ||
567 | radeon_semaphore_sync_resv(rdev, sem, resv, false); | 563 | radeon_sync_resv(rdev, &sync, resv, false); |
568 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 564 | radeon_sync_rings(rdev, &sync, ring->idx); |
569 | 565 | ||
570 | for (i = 0; i < num_loops; i++) { | 566 | for (i = 0; i < num_loops; i++) { |
571 | cur_size_in_bytes = size_in_bytes; | 567 | cur_size_in_bytes = size_in_bytes; |
@@ -586,12 +582,12 @@ struct radeon_fence *cik_copy_dma(struct radeon_device *rdev, | |||
586 | r = radeon_fence_emit(rdev, &fence, ring->idx); | 582 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
587 | if (r) { | 583 | if (r) { |
588 | radeon_ring_unlock_undo(rdev, ring); | 584 | radeon_ring_unlock_undo(rdev, ring); |
589 | radeon_semaphore_free(rdev, &sem, NULL); | 585 | radeon_sync_free(rdev, &sync, NULL); |
590 | return ERR_PTR(r); | 586 | return ERR_PTR(r); |
591 | } | 587 | } |
592 | 588 | ||
593 | radeon_ring_unlock_commit(rdev, ring, false); | 589 | radeon_ring_unlock_commit(rdev, ring, false); |
594 | radeon_semaphore_free(rdev, &sem, fence); | 590 | radeon_sync_free(rdev, &sync, fence); |
595 | 591 | ||
596 | return fence; | 592 | return fence; |
597 | } | 593 | } |
@@ -901,25 +897,21 @@ void cik_sdma_vm_pad_ib(struct radeon_ib *ib) | |||
901 | * Update the page table base and flush the VM TLB | 897 | * Update the page table base and flush the VM TLB |
902 | * using sDMA (CIK). | 898 | * using sDMA (CIK). |
903 | */ | 899 | */ |
904 | void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | 900 | void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
901 | unsigned vm_id, uint64_t pd_addr) | ||
905 | { | 902 | { |
906 | struct radeon_ring *ring = &rdev->ring[ridx]; | ||
907 | |||
908 | if (vm == NULL) | ||
909 | return; | ||
910 | |||
911 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); | 903 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); |
912 | if (vm->id < 8) { | 904 | if (vm_id < 8) { |
913 | radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2); | 905 | radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); |
914 | } else { | 906 | } else { |
915 | radeon_ring_write(ring, (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2); | 907 | radeon_ring_write(ring, (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2); |
916 | } | 908 | } |
917 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); | 909 | radeon_ring_write(ring, pd_addr >> 12); |
918 | 910 | ||
919 | /* update SH_MEM_* regs */ | 911 | /* update SH_MEM_* regs */ |
920 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); | 912 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); |
921 | radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); | 913 | radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); |
922 | radeon_ring_write(ring, VMID(vm->id)); | 914 | radeon_ring_write(ring, VMID(vm_id)); |
923 | 915 | ||
924 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); | 916 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); |
925 | radeon_ring_write(ring, SH_MEM_BASES >> 2); | 917 | radeon_ring_write(ring, SH_MEM_BASES >> 2); |
@@ -942,11 +934,11 @@ void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm | |||
942 | radeon_ring_write(ring, VMID(0)); | 934 | radeon_ring_write(ring, VMID(0)); |
943 | 935 | ||
944 | /* flush HDP */ | 936 | /* flush HDP */ |
945 | cik_sdma_hdp_flush_ring_emit(rdev, ridx); | 937 | cik_sdma_hdp_flush_ring_emit(rdev, ring->idx); |
946 | 938 | ||
947 | /* flush TLB */ | 939 | /* flush TLB */ |
948 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); | 940 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); |
949 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | 941 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); |
950 | radeon_ring_write(ring, 1 << vm->id); | 942 | radeon_ring_write(ring, 1 << vm_id); |
951 | } | 943 | } |
952 | 944 | ||
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/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c index 66bcfadeedd1..96535aa8659c 100644 --- a/drivers/gpu/drm/radeon/evergreen_dma.c +++ b/drivers/gpu/drm/radeon/evergreen_dma.c | |||
@@ -110,31 +110,27 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, | |||
110 | unsigned num_gpu_pages, | 110 | unsigned num_gpu_pages, |
111 | struct reservation_object *resv) | 111 | struct reservation_object *resv) |
112 | { | 112 | { |
113 | struct radeon_semaphore *sem = NULL; | ||
114 | struct radeon_fence *fence; | 113 | struct radeon_fence *fence; |
114 | struct radeon_sync sync; | ||
115 | int ring_index = rdev->asic->copy.dma_ring_index; | 115 | int ring_index = rdev->asic->copy.dma_ring_index; |
116 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 116 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
117 | u32 size_in_dw, cur_size_in_dw; | 117 | u32 size_in_dw, cur_size_in_dw; |
118 | int i, num_loops; | 118 | int i, num_loops; |
119 | int r = 0; | 119 | int r = 0; |
120 | 120 | ||
121 | r = radeon_semaphore_create(rdev, &sem); | 121 | radeon_sync_create(&sync); |
122 | if (r) { | ||
123 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
124 | return ERR_PTR(r); | ||
125 | } | ||
126 | 122 | ||
127 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; | 123 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; |
128 | num_loops = DIV_ROUND_UP(size_in_dw, 0xfffff); | 124 | num_loops = DIV_ROUND_UP(size_in_dw, 0xfffff); |
129 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); | 125 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); |
130 | if (r) { | 126 | if (r) { |
131 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 127 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
132 | radeon_semaphore_free(rdev, &sem, NULL); | 128 | radeon_sync_free(rdev, &sync, NULL); |
133 | return ERR_PTR(r); | 129 | return ERR_PTR(r); |
134 | } | 130 | } |
135 | 131 | ||
136 | radeon_semaphore_sync_resv(rdev, sem, resv, false); | 132 | radeon_sync_resv(rdev, &sync, resv, false); |
137 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 133 | radeon_sync_rings(rdev, &sync, ring->idx); |
138 | 134 | ||
139 | for (i = 0; i < num_loops; i++) { | 135 | for (i = 0; i < num_loops; i++) { |
140 | cur_size_in_dw = size_in_dw; | 136 | cur_size_in_dw = size_in_dw; |
@@ -153,12 +149,12 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, | |||
153 | r = radeon_fence_emit(rdev, &fence, ring->idx); | 149 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
154 | if (r) { | 150 | if (r) { |
155 | radeon_ring_unlock_undo(rdev, ring); | 151 | radeon_ring_unlock_undo(rdev, ring); |
156 | radeon_semaphore_free(rdev, &sem, NULL); | 152 | radeon_sync_free(rdev, &sync, NULL); |
157 | return ERR_PTR(r); | 153 | return ERR_PTR(r); |
158 | } | 154 | } |
159 | 155 | ||
160 | radeon_ring_unlock_commit(rdev, ring, false); | 156 | radeon_ring_unlock_commit(rdev, ring, false); |
161 | radeon_semaphore_free(rdev, &sem, fence); | 157 | radeon_sync_free(rdev, &sync, fence); |
162 | 158 | ||
163 | return fence; | 159 | return fence; |
164 | } | 160 | } |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 3faee58946dd..360de9f1f491 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -1373,6 +1373,7 @@ void cayman_fence_ring_emit(struct radeon_device *rdev, | |||
1373 | void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 1373 | void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
1374 | { | 1374 | { |
1375 | struct radeon_ring *ring = &rdev->ring[ib->ring]; | 1375 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
1376 | unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0; | ||
1376 | u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA | | 1377 | u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA | |
1377 | PACKET3_SH_ACTION_ENA; | 1378 | PACKET3_SH_ACTION_ENA; |
1378 | 1379 | ||
@@ -1395,15 +1396,14 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
1395 | #endif | 1396 | #endif |
1396 | (ib->gpu_addr & 0xFFFFFFFC)); | 1397 | (ib->gpu_addr & 0xFFFFFFFC)); |
1397 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); | 1398 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); |
1398 | radeon_ring_write(ring, ib->length_dw | | 1399 | radeon_ring_write(ring, ib->length_dw | (vm_id << 24)); |
1399 | (ib->vm ? (ib->vm->id << 24) : 0)); | ||
1400 | 1400 | ||
1401 | /* flush read cache over gart for this vmid */ | 1401 | /* flush read cache over gart for this vmid */ |
1402 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); | 1402 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); |
1403 | radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl); | 1403 | radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl); |
1404 | radeon_ring_write(ring, 0xFFFFFFFF); | 1404 | radeon_ring_write(ring, 0xFFFFFFFF); |
1405 | radeon_ring_write(ring, 0); | 1405 | radeon_ring_write(ring, 0); |
1406 | radeon_ring_write(ring, ((ib->vm ? ib->vm->id : 0) << 24) | 10); /* poll interval */ | 1406 | radeon_ring_write(ring, (vm_id << 24) | 10); /* poll interval */ |
1407 | } | 1407 | } |
1408 | 1408 | ||
1409 | static void cayman_cp_enable(struct radeon_device *rdev, bool enable) | 1409 | static void cayman_cp_enable(struct radeon_device *rdev, bool enable) |
@@ -2502,15 +2502,11 @@ void cayman_vm_decode_fault(struct radeon_device *rdev, | |||
2502 | * Update the page table base and flush the VM TLB | 2502 | * Update the page table base and flush the VM TLB |
2503 | * using the CP (cayman-si). | 2503 | * using the CP (cayman-si). |
2504 | */ | 2504 | */ |
2505 | void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | 2505 | void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
2506 | unsigned vm_id, uint64_t pd_addr) | ||
2506 | { | 2507 | { |
2507 | struct radeon_ring *ring = &rdev->ring[ridx]; | 2508 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2), 0)); |
2508 | 2509 | radeon_ring_write(ring, pd_addr >> 12); | |
2509 | if (vm == NULL) | ||
2510 | return; | ||
2511 | |||
2512 | radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0)); | ||
2513 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); | ||
2514 | 2510 | ||
2515 | /* flush hdp cache */ | 2511 | /* flush hdp cache */ |
2516 | radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0)); | 2512 | radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0)); |
@@ -2518,7 +2514,7 @@ void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
2518 | 2514 | ||
2519 | /* bits 0-7 are the VM contexts0-7 */ | 2515 | /* bits 0-7 are the VM contexts0-7 */ |
2520 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); | 2516 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); |
2521 | radeon_ring_write(ring, 1 << vm->id); | 2517 | radeon_ring_write(ring, 1 << vm_id); |
2522 | 2518 | ||
2523 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | 2519 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ |
2524 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | 2520 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); |
diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c index f26f0a9fb522..50f88611ff60 100644 --- a/drivers/gpu/drm/radeon/ni_dma.c +++ b/drivers/gpu/drm/radeon/ni_dma.c | |||
@@ -123,6 +123,7 @@ void cayman_dma_ring_ib_execute(struct radeon_device *rdev, | |||
123 | struct radeon_ib *ib) | 123 | struct radeon_ib *ib) |
124 | { | 124 | { |
125 | struct radeon_ring *ring = &rdev->ring[ib->ring]; | 125 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
126 | unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0; | ||
126 | 127 | ||
127 | if (rdev->wb.enabled) { | 128 | if (rdev->wb.enabled) { |
128 | u32 next_rptr = ring->wptr + 4; | 129 | u32 next_rptr = ring->wptr + 4; |
@@ -140,7 +141,7 @@ void cayman_dma_ring_ib_execute(struct radeon_device *rdev, | |||
140 | */ | 141 | */ |
141 | while ((ring->wptr & 7) != 5) | 142 | while ((ring->wptr & 7) != 5) |
142 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); | 143 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); |
143 | radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, ib->vm ? ib->vm->id : 0, 0)); | 144 | radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, vm_id, 0)); |
144 | radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0)); | 145 | radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0)); |
145 | radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF)); | 146 | radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF)); |
146 | 147 | ||
@@ -446,16 +447,12 @@ void cayman_dma_vm_pad_ib(struct radeon_ib *ib) | |||
446 | ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0); | 447 | ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0); |
447 | } | 448 | } |
448 | 449 | ||
449 | void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | 450 | void cayman_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
451 | unsigned vm_id, uint64_t pd_addr) | ||
450 | { | 452 | { |
451 | struct radeon_ring *ring = &rdev->ring[ridx]; | ||
452 | |||
453 | if (vm == NULL) | ||
454 | return; | ||
455 | |||
456 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | 453 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); |
457 | radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2)); | 454 | radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2)); |
458 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); | 455 | radeon_ring_write(ring, pd_addr >> 12); |
459 | 456 | ||
460 | /* flush hdp cache */ | 457 | /* flush hdp cache */ |
461 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | 458 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); |
@@ -465,6 +462,6 @@ void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm | |||
465 | /* bits 0-7 are the VM contexts0-7 */ | 462 | /* bits 0-7 are the VM contexts0-7 */ |
466 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | 463 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); |
467 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); | 464 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); |
468 | radeon_ring_write(ring, 1 << vm->id); | 465 | radeon_ring_write(ring, 1 << vm_id); |
469 | } | 466 | } |
470 | 467 | ||
diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h index 11c0e4d5c0bf..7e5724a12f8b 100644 --- a/drivers/gpu/drm/radeon/ppsmc.h +++ b/drivers/gpu/drm/radeon/ppsmc.h | |||
@@ -56,6 +56,14 @@ | |||
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 | |||
62 | enum FAN_CONTROL { | ||
63 | FAN_CONTROL_FUZZY, | ||
64 | FAN_CONTROL_TABLE | ||
65 | }; | ||
66 | |||
59 | #define PPSMC_Result_OK ((uint8_t)0x01) | 67 | #define PPSMC_Result_OK ((uint8_t)0x01) |
60 | #define PPSMC_Result_Failed ((uint8_t)0xFF) | 68 | #define PPSMC_Result_Failed ((uint8_t)0xFF) |
61 | 69 | ||
@@ -79,6 +87,8 @@ typedef uint8_t PPSMC_Result; | |||
79 | #define PPSMC_MSG_DisableCac ((uint8_t)0x54) | 87 | #define PPSMC_MSG_DisableCac ((uint8_t)0x54) |
80 | #define PPSMC_TDPClampingActive ((uint8_t)0x59) | 88 | #define PPSMC_TDPClampingActive ((uint8_t)0x59) |
81 | #define PPSMC_TDPClampingInactive ((uint8_t)0x5A) | 89 | #define PPSMC_TDPClampingInactive ((uint8_t)0x5A) |
90 | #define PPSMC_StartFanControl ((uint8_t)0x5B) | ||
91 | #define PPSMC_StopFanControl ((uint8_t)0x5C) | ||
82 | #define PPSMC_MSG_NoDisplay ((uint8_t)0x5D) | 92 | #define PPSMC_MSG_NoDisplay ((uint8_t)0x5D) |
83 | #define PPSMC_MSG_HasDisplay ((uint8_t)0x5E) | 93 | #define PPSMC_MSG_HasDisplay ((uint8_t)0x5E) |
84 | #define PPSMC_MSG_UVDPowerOFF ((uint8_t)0x60) | 94 | #define PPSMC_MSG_UVDPowerOFF ((uint8_t)0x60) |
@@ -150,6 +160,10 @@ typedef uint8_t PPSMC_Result; | |||
150 | #define PPSMC_MSG_MASTER_DeepSleep_ON ((uint16_t) 0x18F) | 160 | #define PPSMC_MSG_MASTER_DeepSleep_ON ((uint16_t) 0x18F) |
151 | #define PPSMC_MSG_MASTER_DeepSleep_OFF ((uint16_t) 0x190) | 161 | #define PPSMC_MSG_MASTER_DeepSleep_OFF ((uint16_t) 0x190) |
152 | #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) | ||
164 | |||
165 | #define PPSMC_MSG_ENABLE_THERMAL_DPM ((uint16_t) 0x19C) | ||
166 | #define PPSMC_MSG_DISABLE_THERMAL_DPM ((uint16_t) 0x19D) | ||
153 | 167 | ||
154 | #define PPSMC_MSG_API_GetSclkFrequency ((uint16_t) 0x200) | 168 | #define PPSMC_MSG_API_GetSclkFrequency ((uint16_t) 0x200) |
155 | #define PPSMC_MSG_API_GetMclkFrequency ((uint16_t) 0x201) | 169 | #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.c b/drivers/gpu/drm/radeon/r600.c index 56b02927cd3d..ef5d6066fa5b 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2889,31 +2889,27 @@ struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev, | |||
2889 | unsigned num_gpu_pages, | 2889 | unsigned num_gpu_pages, |
2890 | struct reservation_object *resv) | 2890 | struct reservation_object *resv) |
2891 | { | 2891 | { |
2892 | struct radeon_semaphore *sem = NULL; | ||
2893 | struct radeon_fence *fence; | 2892 | struct radeon_fence *fence; |
2893 | struct radeon_sync sync; | ||
2894 | int ring_index = rdev->asic->copy.blit_ring_index; | 2894 | int ring_index = rdev->asic->copy.blit_ring_index; |
2895 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 2895 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
2896 | u32 size_in_bytes, cur_size_in_bytes, tmp; | 2896 | u32 size_in_bytes, cur_size_in_bytes, tmp; |
2897 | int i, num_loops; | 2897 | int i, num_loops; |
2898 | int r = 0; | 2898 | int r = 0; |
2899 | 2899 | ||
2900 | r = radeon_semaphore_create(rdev, &sem); | 2900 | radeon_sync_create(&sync); |
2901 | if (r) { | ||
2902 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
2903 | return ERR_PTR(r); | ||
2904 | } | ||
2905 | 2901 | ||
2906 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); | 2902 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); |
2907 | num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); | 2903 | num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); |
2908 | r = radeon_ring_lock(rdev, ring, num_loops * 6 + 24); | 2904 | r = radeon_ring_lock(rdev, ring, num_loops * 6 + 24); |
2909 | if (r) { | 2905 | if (r) { |
2910 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 2906 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
2911 | radeon_semaphore_free(rdev, &sem, NULL); | 2907 | radeon_sync_free(rdev, &sync, NULL); |
2912 | return ERR_PTR(r); | 2908 | return ERR_PTR(r); |
2913 | } | 2909 | } |
2914 | 2910 | ||
2915 | radeon_semaphore_sync_resv(rdev, sem, resv, false); | 2911 | radeon_sync_resv(rdev, &sync, resv, false); |
2916 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 2912 | radeon_sync_rings(rdev, &sync, ring->idx); |
2917 | 2913 | ||
2918 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 2914 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
2919 | radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | 2915 | radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); |
@@ -2942,12 +2938,12 @@ struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev, | |||
2942 | r = radeon_fence_emit(rdev, &fence, ring->idx); | 2938 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
2943 | if (r) { | 2939 | if (r) { |
2944 | radeon_ring_unlock_undo(rdev, ring); | 2940 | radeon_ring_unlock_undo(rdev, ring); |
2945 | radeon_semaphore_free(rdev, &sem, NULL); | 2941 | radeon_sync_free(rdev, &sync, NULL); |
2946 | return ERR_PTR(r); | 2942 | return ERR_PTR(r); |
2947 | } | 2943 | } |
2948 | 2944 | ||
2949 | radeon_ring_unlock_commit(rdev, ring, false); | 2945 | radeon_ring_unlock_commit(rdev, ring, false); |
2950 | radeon_semaphore_free(rdev, &sem, fence); | 2946 | radeon_sync_free(rdev, &sync, fence); |
2951 | 2947 | ||
2952 | return fence; | 2948 | return fence; |
2953 | } | 2949 | } |
diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c index aabc343b9a8f..3a58b8073f49 100644 --- a/drivers/gpu/drm/radeon/r600_dma.c +++ b/drivers/gpu/drm/radeon/r600_dma.c | |||
@@ -441,31 +441,27 @@ struct radeon_fence *r600_copy_dma(struct radeon_device *rdev, | |||
441 | unsigned num_gpu_pages, | 441 | unsigned num_gpu_pages, |
442 | struct reservation_object *resv) | 442 | struct reservation_object *resv) |
443 | { | 443 | { |
444 | struct radeon_semaphore *sem = NULL; | ||
445 | struct radeon_fence *fence; | 444 | struct radeon_fence *fence; |
445 | struct radeon_sync sync; | ||
446 | int ring_index = rdev->asic->copy.dma_ring_index; | 446 | int ring_index = rdev->asic->copy.dma_ring_index; |
447 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 447 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
448 | u32 size_in_dw, cur_size_in_dw; | 448 | u32 size_in_dw, cur_size_in_dw; |
449 | int i, num_loops; | 449 | int i, num_loops; |
450 | int r = 0; | 450 | int r = 0; |
451 | 451 | ||
452 | r = radeon_semaphore_create(rdev, &sem); | 452 | radeon_sync_create(&sync); |
453 | if (r) { | ||
454 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
455 | return ERR_PTR(r); | ||
456 | } | ||
457 | 453 | ||
458 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; | 454 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; |
459 | num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFE); | 455 | num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFE); |
460 | r = radeon_ring_lock(rdev, ring, num_loops * 4 + 8); | 456 | r = radeon_ring_lock(rdev, ring, num_loops * 4 + 8); |
461 | if (r) { | 457 | if (r) { |
462 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 458 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
463 | radeon_semaphore_free(rdev, &sem, NULL); | 459 | radeon_sync_free(rdev, &sync, NULL); |
464 | return ERR_PTR(r); | 460 | return ERR_PTR(r); |
465 | } | 461 | } |
466 | 462 | ||
467 | radeon_semaphore_sync_resv(rdev, sem, resv, false); | 463 | radeon_sync_resv(rdev, &sync, resv, false); |
468 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 464 | radeon_sync_rings(rdev, &sync, ring->idx); |
469 | 465 | ||
470 | for (i = 0; i < num_loops; i++) { | 466 | for (i = 0; i < num_loops; i++) { |
471 | cur_size_in_dw = size_in_dw; | 467 | cur_size_in_dw = size_in_dw; |
@@ -484,12 +480,12 @@ struct radeon_fence *r600_copy_dma(struct radeon_device *rdev, | |||
484 | r = radeon_fence_emit(rdev, &fence, ring->idx); | 480 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
485 | if (r) { | 481 | if (r) { |
486 | radeon_ring_unlock_undo(rdev, ring); | 482 | radeon_ring_unlock_undo(rdev, ring); |
487 | radeon_semaphore_free(rdev, &sem, NULL); | 483 | radeon_sync_free(rdev, &sync, NULL); |
488 | return ERR_PTR(r); | 484 | return ERR_PTR(r); |
489 | } | 485 | } |
490 | 486 | ||
491 | radeon_ring_unlock_commit(rdev, ring, false); | 487 | radeon_ring_unlock_commit(rdev, ring, false); |
492 | radeon_semaphore_free(rdev, &sem, fence); | 488 | radeon_sync_free(rdev, &sync, fence); |
493 | 489 | ||
494 | return fence; | 490 | return fence; |
495 | } | 491 | } |
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/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/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 1f61ff089c9e..3207bb60715e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -150,9 +150,6 @@ extern int radeon_backlight; | |||
150 | /* number of hw syncs before falling back on blocking */ | 150 | /* number of hw syncs before falling back on blocking */ |
151 | #define RADEON_NUM_SYNCS 4 | 151 | #define RADEON_NUM_SYNCS 4 |
152 | 152 | ||
153 | /* number of hw syncs before falling back on blocking */ | ||
154 | #define RADEON_NUM_SYNCS 4 | ||
155 | |||
156 | /* hardcode those limit for now */ | 153 | /* hardcode those limit for now */ |
157 | #define RADEON_VA_IB_OFFSET (1 << 20) | 154 | #define RADEON_VA_IB_OFFSET (1 << 20) |
158 | #define RADEON_VA_RESERVED_SIZE (8 << 20) | 155 | #define RADEON_VA_RESERVED_SIZE (8 << 20) |
@@ -363,14 +360,15 @@ struct radeon_fence_driver { | |||
363 | }; | 360 | }; |
364 | 361 | ||
365 | struct radeon_fence { | 362 | struct radeon_fence { |
366 | struct fence base; | 363 | struct fence base; |
367 | 364 | ||
368 | struct radeon_device *rdev; | 365 | struct radeon_device *rdev; |
369 | uint64_t seq; | 366 | uint64_t seq; |
370 | /* RB, DMA, etc. */ | 367 | /* RB, DMA, etc. */ |
371 | unsigned ring; | 368 | unsigned ring; |
369 | bool is_vm_update; | ||
372 | 370 | ||
373 | wait_queue_t fence_wake; | 371 | wait_queue_t fence_wake; |
374 | }; | 372 | }; |
375 | 373 | ||
376 | int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); | 374 | int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); |
@@ -458,6 +456,7 @@ struct radeon_bo_va { | |||
458 | struct list_head bo_list; | 456 | struct list_head bo_list; |
459 | uint32_t flags; | 457 | uint32_t flags; |
460 | uint64_t addr; | 458 | uint64_t addr; |
459 | struct radeon_fence *last_pt_update; | ||
461 | unsigned ref_count; | 460 | unsigned ref_count; |
462 | 461 | ||
463 | /* protected by vm mutex */ | 462 | /* protected by vm mutex */ |
@@ -576,10 +575,9 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, | |||
576 | * Semaphores. | 575 | * Semaphores. |
577 | */ | 576 | */ |
578 | struct radeon_semaphore { | 577 | struct radeon_semaphore { |
579 | struct radeon_sa_bo *sa_bo; | 578 | struct radeon_sa_bo *sa_bo; |
580 | signed waiters; | 579 | signed waiters; |
581 | uint64_t gpu_addr; | 580 | uint64_t gpu_addr; |
582 | struct radeon_fence *sync_to[RADEON_NUM_RINGS]; | ||
583 | }; | 581 | }; |
584 | 582 | ||
585 | int radeon_semaphore_create(struct radeon_device *rdev, | 583 | int radeon_semaphore_create(struct radeon_device *rdev, |
@@ -588,20 +586,33 @@ bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, | |||
588 | struct radeon_semaphore *semaphore); | 586 | struct radeon_semaphore *semaphore); |
589 | bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, | 587 | bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, |
590 | struct radeon_semaphore *semaphore); | 588 | struct radeon_semaphore *semaphore); |
591 | void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, | ||
592 | struct radeon_fence *fence); | ||
593 | int radeon_semaphore_sync_resv(struct radeon_device *rdev, | ||
594 | struct radeon_semaphore *semaphore, | ||
595 | struct reservation_object *resv, | ||
596 | bool shared); | ||
597 | int radeon_semaphore_sync_rings(struct radeon_device *rdev, | ||
598 | struct radeon_semaphore *semaphore, | ||
599 | int waiting_ring); | ||
600 | void radeon_semaphore_free(struct radeon_device *rdev, | 589 | void radeon_semaphore_free(struct radeon_device *rdev, |
601 | struct radeon_semaphore **semaphore, | 590 | struct radeon_semaphore **semaphore, |
602 | struct radeon_fence *fence); | 591 | struct radeon_fence *fence); |
603 | 592 | ||
604 | /* | 593 | /* |
594 | * Synchronization | ||
595 | */ | ||
596 | struct radeon_sync { | ||
597 | struct radeon_semaphore *semaphores[RADEON_NUM_SYNCS]; | ||
598 | struct radeon_fence *sync_to[RADEON_NUM_RINGS]; | ||
599 | struct radeon_fence *last_vm_update; | ||
600 | }; | ||
601 | |||
602 | void radeon_sync_create(struct radeon_sync *sync); | ||
603 | void radeon_sync_fence(struct radeon_sync *sync, | ||
604 | struct radeon_fence *fence); | ||
605 | int radeon_sync_resv(struct radeon_device *rdev, | ||
606 | struct radeon_sync *sync, | ||
607 | struct reservation_object *resv, | ||
608 | bool shared); | ||
609 | int radeon_sync_rings(struct radeon_device *rdev, | ||
610 | struct radeon_sync *sync, | ||
611 | int waiting_ring); | ||
612 | void radeon_sync_free(struct radeon_device *rdev, struct radeon_sync *sync, | ||
613 | struct radeon_fence *fence); | ||
614 | |||
615 | /* | ||
605 | * GART structures, functions & helpers | 616 | * GART structures, functions & helpers |
606 | */ | 617 | */ |
607 | struct radeon_mc; | 618 | struct radeon_mc; |
@@ -818,7 +829,7 @@ struct radeon_ib { | |||
818 | struct radeon_fence *fence; | 829 | struct radeon_fence *fence; |
819 | struct radeon_vm *vm; | 830 | struct radeon_vm *vm; |
820 | bool is_const_ib; | 831 | bool is_const_ib; |
821 | struct radeon_semaphore *semaphore; | 832 | struct radeon_sync sync; |
822 | }; | 833 | }; |
823 | 834 | ||
824 | struct radeon_ring { | 835 | struct radeon_ring { |
@@ -895,33 +906,37 @@ struct radeon_vm_pt { | |||
895 | uint64_t addr; | 906 | uint64_t addr; |
896 | }; | 907 | }; |
897 | 908 | ||
909 | struct radeon_vm_id { | ||
910 | unsigned id; | ||
911 | uint64_t pd_gpu_addr; | ||
912 | /* last flushed PD/PT update */ | ||
913 | struct radeon_fence *flushed_updates; | ||
914 | /* last use of vmid */ | ||
915 | struct radeon_fence *last_id_use; | ||
916 | }; | ||
917 | |||
898 | struct radeon_vm { | 918 | struct radeon_vm { |
899 | struct rb_root va; | 919 | struct mutex mutex; |
900 | unsigned id; | 920 | |
921 | struct rb_root va; | ||
901 | 922 | ||
902 | /* BOs moved, but not yet updated in the PT */ | 923 | /* BOs moved, but not yet updated in the PT */ |
903 | struct list_head invalidated; | 924 | struct list_head invalidated; |
904 | 925 | ||
905 | /* BOs freed, but not yet updated in the PT */ | 926 | /* BOs freed, but not yet updated in the PT */ |
906 | struct list_head freed; | 927 | struct list_head freed; |
907 | 928 | ||
908 | /* contains the page directory */ | 929 | /* contains the page directory */ |
909 | struct radeon_bo *page_directory; | 930 | struct radeon_bo *page_directory; |
910 | uint64_t pd_gpu_addr; | 931 | unsigned max_pde_used; |
911 | unsigned max_pde_used; | ||
912 | 932 | ||
913 | /* array of page tables, one for each page directory entry */ | 933 | /* array of page tables, one for each page directory entry */ |
914 | struct radeon_vm_pt *page_tables; | 934 | struct radeon_vm_pt *page_tables; |
915 | 935 | ||
916 | struct radeon_bo_va *ib_bo_va; | 936 | struct radeon_bo_va *ib_bo_va; |
917 | 937 | ||
918 | struct mutex mutex; | 938 | /* for id and flush management per ring */ |
919 | /* last fence for cs using this vm */ | 939 | struct radeon_vm_id ids[RADEON_NUM_RINGS]; |
920 | struct radeon_fence *fence; | ||
921 | /* last flush or NULL if we still need to flush */ | ||
922 | struct radeon_fence *last_flush; | ||
923 | /* last use of vmid */ | ||
924 | struct radeon_fence *last_id_use; | ||
925 | }; | 940 | }; |
926 | 941 | ||
927 | struct radeon_vm_manager { | 942 | struct radeon_vm_manager { |
@@ -1494,6 +1509,10 @@ struct radeon_dpm_fan { | |||
1494 | u8 t_hyst; | 1509 | u8 t_hyst; |
1495 | u32 cycle_delay; | 1510 | u32 cycle_delay; |
1496 | u16 t_max; | 1511 | u16 t_max; |
1512 | u8 control_mode; | ||
1513 | u16 default_max_fan_pwm; | ||
1514 | u16 default_fan_output_sensitivity; | ||
1515 | u16 fan_output_sensitivity; | ||
1497 | bool ucode_fan_control; | 1516 | bool ucode_fan_control; |
1498 | }; | 1517 | }; |
1499 | 1518 | ||
@@ -1794,7 +1813,8 @@ struct radeon_asic_ring { | |||
1794 | void (*hdp_flush)(struct radeon_device *rdev, struct radeon_ring *ring); | 1813 | void (*hdp_flush)(struct radeon_device *rdev, struct radeon_ring *ring); |
1795 | bool (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp, | 1814 | bool (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp, |
1796 | struct radeon_semaphore *semaphore, bool emit_wait); | 1815 | struct radeon_semaphore *semaphore, bool emit_wait); |
1797 | void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 1816 | void (*vm_flush)(struct radeon_device *rdev, struct radeon_ring *ring, |
1817 | unsigned vm_id, uint64_t pd_addr); | ||
1798 | 1818 | ||
1799 | /* testing functions */ | 1819 | /* testing functions */ |
1800 | int (*ring_test)(struct radeon_device *rdev, struct radeon_ring *cp); | 1820 | int (*ring_test)(struct radeon_device *rdev, struct radeon_ring *cp); |
@@ -2846,7 +2866,7 @@ static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v) | |||
2846 | #define radeon_ring_ib_execute(rdev, r, ib) (rdev)->asic->ring[(r)]->ib_execute((rdev), (ib)) | 2866 | #define radeon_ring_ib_execute(rdev, r, ib) (rdev)->asic->ring[(r)]->ib_execute((rdev), (ib)) |
2847 | #define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)]->ib_parse((rdev), (ib)) | 2867 | #define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)]->ib_parse((rdev), (ib)) |
2848 | #define radeon_ring_is_lockup(rdev, r, cp) (rdev)->asic->ring[(r)]->is_lockup((rdev), (cp)) | 2868 | #define radeon_ring_is_lockup(rdev, r, cp) (rdev)->asic->ring[(r)]->is_lockup((rdev), (cp)) |
2849 | #define radeon_ring_vm_flush(rdev, r, vm) (rdev)->asic->ring[(r)]->vm_flush((rdev), (r), (vm)) | 2869 | #define radeon_ring_vm_flush(rdev, r, vm_id, pd_addr) (rdev)->asic->ring[(r)->idx]->vm_flush((rdev), (r), (vm_id), (pd_addr)) |
2850 | #define radeon_ring_get_rptr(rdev, r) (rdev)->asic->ring[(r)->idx]->get_rptr((rdev), (r)) | 2870 | #define radeon_ring_get_rptr(rdev, r) (rdev)->asic->ring[(r)->idx]->get_rptr((rdev), (r)) |
2851 | #define radeon_ring_get_wptr(rdev, r) (rdev)->asic->ring[(r)->idx]->get_wptr((rdev), (r)) | 2871 | #define radeon_ring_get_wptr(rdev, r) (rdev)->asic->ring[(r)->idx]->get_wptr((rdev), (r)) |
2852 | #define radeon_ring_set_wptr(rdev, r) (rdev)->asic->ring[(r)->idx]->set_wptr((rdev), (r)) | 2872 | #define radeon_ring_set_wptr(rdev, r) (rdev)->asic->ring[(r)->idx]->set_wptr((rdev), (r)) |
@@ -2962,7 +2982,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, | |||
2962 | struct radeon_vm *vm, int ring); | 2982 | struct radeon_vm *vm, int ring); |
2963 | void radeon_vm_flush(struct radeon_device *rdev, | 2983 | void radeon_vm_flush(struct radeon_device *rdev, |
2964 | struct radeon_vm *vm, | 2984 | struct radeon_vm *vm, |
2965 | int ring); | 2985 | int ring, struct radeon_fence *fence); |
2966 | void radeon_vm_fence(struct radeon_device *rdev, | 2986 | void radeon_vm_fence(struct radeon_device *rdev, |
2967 | struct radeon_vm *vm, | 2987 | struct radeon_vm *vm, |
2968 | struct radeon_fence *fence); | 2988 | struct radeon_fence *fence); |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index d8ace5b28a5b..2a45d548d5ec 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -599,7 +599,8 @@ int cayman_asic_reset(struct radeon_device *rdev); | |||
599 | void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | 599 | void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); |
600 | int cayman_vm_init(struct radeon_device *rdev); | 600 | int cayman_vm_init(struct radeon_device *rdev); |
601 | void cayman_vm_fini(struct radeon_device *rdev); | 601 | void cayman_vm_fini(struct radeon_device *rdev); |
602 | void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 602 | void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
603 | unsigned vm_id, uint64_t pd_addr); | ||
603 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags); | 604 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags); |
604 | int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 605 | int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
605 | int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 606 | int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
@@ -624,7 +625,8 @@ void cayman_dma_vm_set_pages(struct radeon_device *rdev, | |||
624 | uint32_t incr, uint32_t flags); | 625 | uint32_t incr, uint32_t flags); |
625 | void cayman_dma_vm_pad_ib(struct radeon_ib *ib); | 626 | void cayman_dma_vm_pad_ib(struct radeon_ib *ib); |
626 | 627 | ||
627 | void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 628 | void cayman_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
629 | unsigned vm_id, uint64_t pd_addr); | ||
628 | 630 | ||
629 | u32 cayman_gfx_get_rptr(struct radeon_device *rdev, | 631 | u32 cayman_gfx_get_rptr(struct radeon_device *rdev, |
630 | struct radeon_ring *ring); | 632 | struct radeon_ring *ring); |
@@ -699,7 +701,8 @@ int si_irq_set(struct radeon_device *rdev); | |||
699 | int si_irq_process(struct radeon_device *rdev); | 701 | int si_irq_process(struct radeon_device *rdev); |
700 | int si_vm_init(struct radeon_device *rdev); | 702 | int si_vm_init(struct radeon_device *rdev); |
701 | void si_vm_fini(struct radeon_device *rdev); | 703 | void si_vm_fini(struct radeon_device *rdev); |
702 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 704 | void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
705 | unsigned vm_id, uint64_t pd_addr); | ||
703 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 706 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
704 | struct radeon_fence *si_copy_dma(struct radeon_device *rdev, | 707 | struct radeon_fence *si_copy_dma(struct radeon_device *rdev, |
705 | uint64_t src_offset, uint64_t dst_offset, | 708 | uint64_t src_offset, uint64_t dst_offset, |
@@ -721,7 +724,8 @@ void si_dma_vm_set_pages(struct radeon_device *rdev, | |||
721 | uint64_t addr, unsigned count, | 724 | uint64_t addr, unsigned count, |
722 | uint32_t incr, uint32_t flags); | 725 | uint32_t incr, uint32_t flags); |
723 | 726 | ||
724 | void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 727 | void si_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
728 | unsigned vm_id, uint64_t pd_addr); | ||
725 | u32 si_get_xclk(struct radeon_device *rdev); | 729 | u32 si_get_xclk(struct radeon_device *rdev); |
726 | uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev); | 730 | uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev); |
727 | int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); | 731 | int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); |
@@ -793,7 +797,8 @@ int cik_irq_set(struct radeon_device *rdev); | |||
793 | int cik_irq_process(struct radeon_device *rdev); | 797 | int cik_irq_process(struct radeon_device *rdev); |
794 | int cik_vm_init(struct radeon_device *rdev); | 798 | int cik_vm_init(struct radeon_device *rdev); |
795 | void cik_vm_fini(struct radeon_device *rdev); | 799 | void cik_vm_fini(struct radeon_device *rdev); |
796 | void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 800 | void cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
801 | unsigned vm_id, uint64_t pd_addr); | ||
797 | 802 | ||
798 | void cik_sdma_vm_copy_pages(struct radeon_device *rdev, | 803 | void cik_sdma_vm_copy_pages(struct radeon_device *rdev, |
799 | struct radeon_ib *ib, | 804 | struct radeon_ib *ib, |
@@ -811,7 +816,8 @@ void cik_sdma_vm_set_pages(struct radeon_device *rdev, | |||
811 | uint32_t incr, uint32_t flags); | 816 | uint32_t incr, uint32_t flags); |
812 | void cik_sdma_vm_pad_ib(struct radeon_ib *ib); | 817 | void cik_sdma_vm_pad_ib(struct radeon_ib *ib); |
813 | 818 | ||
814 | void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 819 | void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
820 | unsigned vm_id, uint64_t pd_addr); | ||
815 | int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 821 | int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
816 | u32 cik_gfx_get_rptr(struct radeon_device *rdev, | 822 | u32 cik_gfx_get_rptr(struct radeon_device *rdev, |
817 | struct radeon_ring *ring); | 823 | struct radeon_ring *ring); |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index a3e7aed7e680..75f22e5e999f 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -260,8 +260,8 @@ static int radeon_cs_sync_rings(struct radeon_cs_parser *p) | |||
260 | continue; | 260 | continue; |
261 | 261 | ||
262 | resv = p->relocs[i].robj->tbo.resv; | 262 | resv = p->relocs[i].robj->tbo.resv; |
263 | r = radeon_semaphore_sync_resv(p->rdev, p->ib.semaphore, resv, | 263 | r = radeon_sync_resv(p->rdev, &p->ib.sync, resv, |
264 | p->relocs[i].tv.shared); | 264 | p->relocs[i].tv.shared); |
265 | 265 | ||
266 | if (r) | 266 | if (r) |
267 | break; | 267 | break; |
@@ -285,9 +285,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
285 | INIT_LIST_HEAD(&p->validated); | 285 | INIT_LIST_HEAD(&p->validated); |
286 | p->idx = 0; | 286 | p->idx = 0; |
287 | p->ib.sa_bo = NULL; | 287 | p->ib.sa_bo = NULL; |
288 | p->ib.semaphore = NULL; | ||
289 | p->const_ib.sa_bo = NULL; | 288 | p->const_ib.sa_bo = NULL; |
290 | p->const_ib.semaphore = NULL; | ||
291 | p->chunk_ib_idx = -1; | 289 | p->chunk_ib_idx = -1; |
292 | p->chunk_relocs_idx = -1; | 290 | p->chunk_relocs_idx = -1; |
293 | p->chunk_flags_idx = -1; | 291 | p->chunk_flags_idx = -1; |
@@ -507,6 +505,9 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p, | |||
507 | if (r) | 505 | if (r) |
508 | return r; | 506 | return r; |
509 | 507 | ||
508 | radeon_sync_resv(p->rdev, &p->ib.sync, vm->page_directory->tbo.resv, | ||
509 | true); | ||
510 | |||
510 | r = radeon_vm_clear_freed(rdev, vm); | 511 | r = radeon_vm_clear_freed(rdev, vm); |
511 | if (r) | 512 | if (r) |
512 | return r; | 513 | return r; |
@@ -538,6 +539,8 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p, | |||
538 | r = radeon_vm_bo_update(rdev, bo_va, &bo->tbo.mem); | 539 | r = radeon_vm_bo_update(rdev, bo_va, &bo->tbo.mem); |
539 | if (r) | 540 | if (r) |
540 | return r; | 541 | return r; |
542 | |||
543 | radeon_sync_fence(&p->ib.sync, bo_va->last_pt_update); | ||
541 | } | 544 | } |
542 | 545 | ||
543 | return radeon_vm_clear_invalids(rdev, vm); | 546 | return radeon_vm_clear_invalids(rdev, vm); |
@@ -582,7 +585,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
582 | DRM_ERROR("Failed to sync rings: %i\n", r); | 585 | DRM_ERROR("Failed to sync rings: %i\n", r); |
583 | goto out; | 586 | goto out; |
584 | } | 587 | } |
585 | radeon_semaphore_sync_fence(parser->ib.semaphore, vm->fence); | ||
586 | 588 | ||
587 | if ((rdev->family >= CHIP_TAHITI) && | 589 | if ((rdev->family >= CHIP_TAHITI) && |
588 | (parser->chunk_const_ib_idx != -1)) { | 590 | (parser->chunk_const_ib_idx != -1)) { |
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 9630e8d95fb4..85f38ee11888 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
@@ -117,106 +117,7 @@ static void radeon_show_cursor(struct drm_crtc *crtc) | |||
117 | } | 117 | } |
118 | } | 118 | } |
119 | 119 | ||
120 | static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, | 120 | static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y) |
121 | uint64_t gpu_addr) | ||
122 | { | ||
123 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
124 | struct radeon_device *rdev = crtc->dev->dev_private; | ||
125 | |||
126 | if (ASIC_IS_DCE4(rdev)) { | ||
127 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, | ||
128 | upper_32_bits(gpu_addr)); | ||
129 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
130 | gpu_addr & 0xffffffff); | ||
131 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
132 | if (rdev->family >= CHIP_RV770) { | ||
133 | if (radeon_crtc->crtc_id) | ||
134 | WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr)); | ||
135 | else | ||
136 | WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr)); | ||
137 | } | ||
138 | WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
139 | gpu_addr & 0xffffffff); | ||
140 | } else { | ||
141 | radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr; | ||
142 | /* offset is from DISP(2)_BASE_ADDRESS */ | ||
143 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | int radeon_crtc_cursor_set(struct drm_crtc *crtc, | ||
148 | struct drm_file *file_priv, | ||
149 | uint32_t handle, | ||
150 | uint32_t width, | ||
151 | uint32_t height) | ||
152 | { | ||
153 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
154 | struct radeon_device *rdev = crtc->dev->dev_private; | ||
155 | struct drm_gem_object *obj; | ||
156 | struct radeon_bo *robj; | ||
157 | uint64_t gpu_addr; | ||
158 | int ret; | ||
159 | |||
160 | if (!handle) { | ||
161 | /* turn off cursor */ | ||
162 | radeon_hide_cursor(crtc); | ||
163 | obj = NULL; | ||
164 | goto unpin; | ||
165 | } | ||
166 | |||
167 | if ((width > radeon_crtc->max_cursor_width) || | ||
168 | (height > radeon_crtc->max_cursor_height)) { | ||
169 | DRM_ERROR("bad cursor width or height %d x %d\n", width, height); | ||
170 | return -EINVAL; | ||
171 | } | ||
172 | |||
173 | obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); | ||
174 | if (!obj) { | ||
175 | DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); | ||
176 | return -ENOENT; | ||
177 | } | ||
178 | |||
179 | robj = gem_to_radeon_bo(obj); | ||
180 | ret = radeon_bo_reserve(robj, false); | ||
181 | if (unlikely(ret != 0)) | ||
182 | goto fail; | ||
183 | /* Only 27 bit offset for legacy cursor */ | ||
184 | ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, | ||
185 | ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, | ||
186 | &gpu_addr); | ||
187 | radeon_bo_unreserve(robj); | ||
188 | if (ret) | ||
189 | goto fail; | ||
190 | |||
191 | radeon_crtc->cursor_width = width; | ||
192 | radeon_crtc->cursor_height = height; | ||
193 | |||
194 | radeon_lock_cursor(crtc, true); | ||
195 | radeon_set_cursor(crtc, obj, gpu_addr); | ||
196 | radeon_show_cursor(crtc); | ||
197 | radeon_lock_cursor(crtc, false); | ||
198 | |||
199 | unpin: | ||
200 | if (radeon_crtc->cursor_bo) { | ||
201 | robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); | ||
202 | ret = radeon_bo_reserve(robj, false); | ||
203 | if (likely(ret == 0)) { | ||
204 | radeon_bo_unpin(robj); | ||
205 | radeon_bo_unreserve(robj); | ||
206 | } | ||
207 | drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); | ||
208 | } | ||
209 | |||
210 | radeon_crtc->cursor_bo = obj; | ||
211 | return 0; | ||
212 | fail: | ||
213 | drm_gem_object_unreference_unlocked(obj); | ||
214 | |||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | int radeon_crtc_cursor_move(struct drm_crtc *crtc, | ||
219 | int x, int y) | ||
220 | { | 121 | { |
221 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 122 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
222 | struct radeon_device *rdev = crtc->dev->dev_private; | 123 | struct radeon_device *rdev = crtc->dev->dev_private; |
@@ -281,7 +182,6 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, | |||
281 | } | 182 | } |
282 | } | 183 | } |
283 | 184 | ||
284 | radeon_lock_cursor(crtc, true); | ||
285 | if (ASIC_IS_DCE4(rdev)) { | 185 | if (ASIC_IS_DCE4(rdev)) { |
286 | WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); | 186 | WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); |
287 | WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); | 187 | WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); |
@@ -308,7 +208,134 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, | |||
308 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset + | 208 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset + |
309 | (yorigin * 256))); | 209 | (yorigin * 256))); |
310 | } | 210 | } |
211 | |||
212 | radeon_crtc->cursor_x = x; | ||
213 | radeon_crtc->cursor_y = y; | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | int radeon_crtc_cursor_move(struct drm_crtc *crtc, | ||
219 | int x, int y) | ||
220 | { | ||
221 | int ret; | ||
222 | |||
223 | radeon_lock_cursor(crtc, true); | ||
224 | ret = radeon_cursor_move_locked(crtc, x, y); | ||
225 | radeon_lock_cursor(crtc, false); | ||
226 | |||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, | ||
231 | uint64_t gpu_addr, int hot_x, int hot_y) | ||
232 | { | ||
233 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
234 | struct radeon_device *rdev = crtc->dev->dev_private; | ||
235 | |||
236 | if (ASIC_IS_DCE4(rdev)) { | ||
237 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, | ||
238 | upper_32_bits(gpu_addr)); | ||
239 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
240 | gpu_addr & 0xffffffff); | ||
241 | } else if (ASIC_IS_AVIVO(rdev)) { | ||
242 | if (rdev->family >= CHIP_RV770) { | ||
243 | if (radeon_crtc->crtc_id) | ||
244 | WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr)); | ||
245 | else | ||
246 | WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr)); | ||
247 | } | ||
248 | WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
249 | gpu_addr & 0xffffffff); | ||
250 | } else { | ||
251 | radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr; | ||
252 | /* offset is from DISP(2)_BASE_ADDRESS */ | ||
253 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); | ||
254 | } | ||
255 | |||
256 | if (hot_x != radeon_crtc->cursor_hot_x || | ||
257 | hot_y != radeon_crtc->cursor_hot_y) { | ||
258 | int x, y; | ||
259 | |||
260 | x = radeon_crtc->cursor_x + radeon_crtc->cursor_hot_x - hot_x; | ||
261 | y = radeon_crtc->cursor_y + radeon_crtc->cursor_hot_y - hot_y; | ||
262 | |||
263 | radeon_cursor_move_locked(crtc, x, y); | ||
264 | |||
265 | radeon_crtc->cursor_hot_x = hot_x; | ||
266 | radeon_crtc->cursor_hot_y = hot_y; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | int radeon_crtc_cursor_set2(struct drm_crtc *crtc, | ||
271 | struct drm_file *file_priv, | ||
272 | uint32_t handle, | ||
273 | uint32_t width, | ||
274 | uint32_t height, | ||
275 | int32_t hot_x, | ||
276 | int32_t hot_y) | ||
277 | { | ||
278 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
279 | struct radeon_device *rdev = crtc->dev->dev_private; | ||
280 | struct drm_gem_object *obj; | ||
281 | struct radeon_bo *robj; | ||
282 | uint64_t gpu_addr; | ||
283 | int ret; | ||
284 | |||
285 | if (!handle) { | ||
286 | /* turn off cursor */ | ||
287 | radeon_hide_cursor(crtc); | ||
288 | obj = NULL; | ||
289 | goto unpin; | ||
290 | } | ||
291 | |||
292 | if ((width > radeon_crtc->max_cursor_width) || | ||
293 | (height > radeon_crtc->max_cursor_height)) { | ||
294 | DRM_ERROR("bad cursor width or height %d x %d\n", width, height); | ||
295 | return -EINVAL; | ||
296 | } | ||
297 | |||
298 | obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); | ||
299 | if (!obj) { | ||
300 | DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); | ||
301 | return -ENOENT; | ||
302 | } | ||
303 | |||
304 | robj = gem_to_radeon_bo(obj); | ||
305 | ret = radeon_bo_reserve(robj, false); | ||
306 | if (unlikely(ret != 0)) | ||
307 | goto fail; | ||
308 | /* Only 27 bit offset for legacy cursor */ | ||
309 | ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, | ||
310 | ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, | ||
311 | &gpu_addr); | ||
312 | radeon_bo_unreserve(robj); | ||
313 | if (ret) | ||
314 | goto fail; | ||
315 | |||
316 | radeon_crtc->cursor_width = width; | ||
317 | radeon_crtc->cursor_height = height; | ||
318 | |||
319 | radeon_lock_cursor(crtc, true); | ||
320 | radeon_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y); | ||
321 | radeon_show_cursor(crtc); | ||
311 | radeon_lock_cursor(crtc, false); | 322 | radeon_lock_cursor(crtc, false); |
312 | 323 | ||
324 | unpin: | ||
325 | if (radeon_crtc->cursor_bo) { | ||
326 | robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); | ||
327 | ret = radeon_bo_reserve(robj, false); | ||
328 | if (likely(ret == 0)) { | ||
329 | radeon_bo_unpin(robj); | ||
330 | radeon_bo_unreserve(robj); | ||
331 | } | ||
332 | drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); | ||
333 | } | ||
334 | |||
335 | radeon_crtc->cursor_bo = obj; | ||
313 | return 0; | 336 | return 0; |
337 | fail: | ||
338 | drm_gem_object_unreference_unlocked(obj); | ||
339 | |||
340 | return ret; | ||
314 | } | 341 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index f1b0fa1285bb..102116902a07 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -635,7 +635,7 @@ radeon_crtc_set_config(struct drm_mode_set *set) | |||
635 | return ret; | 635 | return ret; |
636 | } | 636 | } |
637 | static const struct drm_crtc_funcs radeon_crtc_funcs = { | 637 | static const struct drm_crtc_funcs radeon_crtc_funcs = { |
638 | .cursor_set = radeon_crtc_cursor_set, | 638 | .cursor_set2 = radeon_crtc_cursor_set2, |
639 | .cursor_move = radeon_crtc_cursor_move, | 639 | .cursor_move = radeon_crtc_cursor_move, |
640 | .gamma_set = radeon_crtc_gamma_set, | 640 | .gamma_set = radeon_crtc_gamma_set, |
641 | .set_config = radeon_crtc_set_config, | 641 | .set_config = radeon_crtc_set_config, |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 995167025282..d13d1b5a859f 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -140,6 +140,7 @@ int radeon_fence_emit(struct radeon_device *rdev, | |||
140 | (*fence)->rdev = rdev; | 140 | (*fence)->rdev = rdev; |
141 | (*fence)->seq = seq; | 141 | (*fence)->seq = seq; |
142 | (*fence)->ring = ring; | 142 | (*fence)->ring = ring; |
143 | (*fence)->is_vm_update = false; | ||
143 | fence_init(&(*fence)->base, &radeon_fence_ops, | 144 | fence_init(&(*fence)->base, &radeon_fence_ops, |
144 | &rdev->fence_queue.lock, rdev->fence_context + ring, seq); | 145 | &rdev->fence_queue.lock, rdev->fence_context + ring, seq); |
145 | radeon_fence_ring_emit(rdev, ring, *fence); | 146 | radeon_fence_ring_emit(rdev, ring, *fence); |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 429213b6ed0f..12cfaeac1205 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -535,6 +535,68 @@ out: | |||
535 | return r; | 535 | return r; |
536 | } | 536 | } |
537 | 537 | ||
538 | /** | ||
539 | * radeon_gem_va_update_vm -update the bo_va in its VM | ||
540 | * | ||
541 | * @rdev: radeon_device pointer | ||
542 | * @bo_va: bo_va to update | ||
543 | * | ||
544 | * Update the bo_va directly after setting it's address. Errors are not | ||
545 | * vital here, so they are not reported back to userspace. | ||
546 | */ | ||
547 | static void radeon_gem_va_update_vm(struct radeon_device *rdev, | ||
548 | struct radeon_bo_va *bo_va) | ||
549 | { | ||
550 | struct ttm_validate_buffer tv, *entry; | ||
551 | struct radeon_cs_reloc *vm_bos; | ||
552 | struct ww_acquire_ctx ticket; | ||
553 | struct list_head list; | ||
554 | unsigned domain; | ||
555 | int r; | ||
556 | |||
557 | INIT_LIST_HEAD(&list); | ||
558 | |||
559 | tv.bo = &bo_va->bo->tbo; | ||
560 | tv.shared = true; | ||
561 | list_add(&tv.head, &list); | ||
562 | |||
563 | vm_bos = radeon_vm_get_bos(rdev, bo_va->vm, &list); | ||
564 | if (!vm_bos) | ||
565 | return; | ||
566 | |||
567 | r = ttm_eu_reserve_buffers(&ticket, &list, true); | ||
568 | if (r) | ||
569 | goto error_free; | ||
570 | |||
571 | list_for_each_entry(entry, &list, head) { | ||
572 | domain = radeon_mem_type_to_domain(entry->bo->mem.mem_type); | ||
573 | /* if anything is swapped out don't swap it in here, | ||
574 | just abort and wait for the next CS */ | ||
575 | if (domain == RADEON_GEM_DOMAIN_CPU) | ||
576 | goto error_unreserve; | ||
577 | } | ||
578 | |||
579 | mutex_lock(&bo_va->vm->mutex); | ||
580 | r = radeon_vm_clear_freed(rdev, bo_va->vm); | ||
581 | if (r) | ||
582 | goto error_unlock; | ||
583 | |||
584 | if (bo_va->it.start) | ||
585 | r = radeon_vm_bo_update(rdev, bo_va, &bo_va->bo->tbo.mem); | ||
586 | |||
587 | error_unlock: | ||
588 | mutex_unlock(&bo_va->vm->mutex); | ||
589 | |||
590 | error_unreserve: | ||
591 | ttm_eu_backoff_reservation(&ticket, &list); | ||
592 | |||
593 | error_free: | ||
594 | drm_free_large(vm_bos); | ||
595 | |||
596 | if (r) | ||
597 | DRM_ERROR("Couldn't update BO_VA (%d)\n", r); | ||
598 | } | ||
599 | |||
538 | int radeon_gem_va_ioctl(struct drm_device *dev, void *data, | 600 | int radeon_gem_va_ioctl(struct drm_device *dev, void *data, |
539 | struct drm_file *filp) | 601 | struct drm_file *filp) |
540 | { | 602 | { |
@@ -618,6 +680,7 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, | |||
618 | if (bo_va->it.start) { | 680 | if (bo_va->it.start) { |
619 | args->operation = RADEON_VA_RESULT_VA_EXIST; | 681 | args->operation = RADEON_VA_RESULT_VA_EXIST; |
620 | args->offset = bo_va->it.start * RADEON_GPU_PAGE_SIZE; | 682 | args->offset = bo_va->it.start * RADEON_GPU_PAGE_SIZE; |
683 | radeon_bo_unreserve(rbo); | ||
621 | goto out; | 684 | goto out; |
622 | } | 685 | } |
623 | r = radeon_vm_bo_set_addr(rdev, bo_va, args->offset, args->flags); | 686 | r = radeon_vm_bo_set_addr(rdev, bo_va, args->offset, args->flags); |
@@ -628,12 +691,13 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data, | |||
628 | default: | 691 | default: |
629 | break; | 692 | break; |
630 | } | 693 | } |
694 | if (!r) | ||
695 | radeon_gem_va_update_vm(rdev, bo_va); | ||
631 | args->operation = RADEON_VA_RESULT_OK; | 696 | args->operation = RADEON_VA_RESULT_OK; |
632 | if (r) { | 697 | if (r) { |
633 | args->operation = RADEON_VA_RESULT_ERROR; | 698 | args->operation = RADEON_VA_RESULT_ERROR; |
634 | } | 699 | } |
635 | out: | 700 | out: |
636 | radeon_bo_unreserve(rbo); | ||
637 | drm_gem_object_unreference_unlocked(gobj); | 701 | drm_gem_object_unreference_unlocked(gobj); |
638 | return r; | 702 | return r; |
639 | } | 703 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_ib.c b/drivers/gpu/drm/radeon/radeon_ib.c index 3f39fcca4d07..c39ce1f05703 100644 --- a/drivers/gpu/drm/radeon/radeon_ib.c +++ b/drivers/gpu/drm/radeon/radeon_ib.c | |||
@@ -64,10 +64,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, | |||
64 | return r; | 64 | return r; |
65 | } | 65 | } |
66 | 66 | ||
67 | r = radeon_semaphore_create(rdev, &ib->semaphore); | 67 | radeon_sync_create(&ib->sync); |
68 | if (r) { | ||
69 | return r; | ||
70 | } | ||
71 | 68 | ||
72 | ib->ring = ring; | 69 | ib->ring = ring; |
73 | ib->fence = NULL; | 70 | ib->fence = NULL; |
@@ -96,7 +93,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, | |||
96 | */ | 93 | */ |
97 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) | 94 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) |
98 | { | 95 | { |
99 | radeon_semaphore_free(rdev, &ib->semaphore, ib->fence); | 96 | radeon_sync_free(rdev, &ib->sync, ib->fence); |
100 | radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence); | 97 | radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence); |
101 | radeon_fence_unref(&ib->fence); | 98 | radeon_fence_unref(&ib->fence); |
102 | } | 99 | } |
@@ -145,11 +142,11 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | |||
145 | if (ib->vm) { | 142 | if (ib->vm) { |
146 | struct radeon_fence *vm_id_fence; | 143 | struct radeon_fence *vm_id_fence; |
147 | vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring); | 144 | vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring); |
148 | radeon_semaphore_sync_fence(ib->semaphore, vm_id_fence); | 145 | radeon_sync_fence(&ib->sync, vm_id_fence); |
149 | } | 146 | } |
150 | 147 | ||
151 | /* sync with other rings */ | 148 | /* sync with other rings */ |
152 | r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring); | 149 | r = radeon_sync_rings(rdev, &ib->sync, ib->ring); |
153 | if (r) { | 150 | if (r) { |
154 | dev_err(rdev->dev, "failed to sync rings (%d)\n", r); | 151 | dev_err(rdev->dev, "failed to sync rings (%d)\n", r); |
155 | radeon_ring_unlock_undo(rdev, ring); | 152 | radeon_ring_unlock_undo(rdev, ring); |
@@ -157,11 +154,12 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | |||
157 | } | 154 | } |
158 | 155 | ||
159 | if (ib->vm) | 156 | if (ib->vm) |
160 | radeon_vm_flush(rdev, ib->vm, ib->ring); | 157 | radeon_vm_flush(rdev, ib->vm, ib->ring, |
158 | ib->sync.last_vm_update); | ||
161 | 159 | ||
162 | if (const_ib) { | 160 | if (const_ib) { |
163 | radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); | 161 | radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); |
164 | radeon_semaphore_free(rdev, &const_ib->semaphore, NULL); | 162 | radeon_sync_free(rdev, &const_ib->sync, NULL); |
165 | } | 163 | } |
166 | radeon_ring_ib_execute(rdev, ib->ring, ib); | 164 | radeon_ring_ib_execute(rdev, ib->ring, ib); |
167 | r = radeon_fence_emit(rdev, &ib->fence, ib->ring); | 165 | r = radeon_fence_emit(rdev, &ib->fence, ib->ring); |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 6eb561d33eba..f4dd26ae33e5 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -628,8 +628,6 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
628 | RADEON_VA_IB_OFFSET, | 628 | RADEON_VA_IB_OFFSET, |
629 | RADEON_VM_PAGE_READABLE | | 629 | RADEON_VM_PAGE_READABLE | |
630 | RADEON_VM_PAGE_SNOOPED); | 630 | RADEON_VM_PAGE_SNOOPED); |
631 | |||
632 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | ||
633 | if (r) { | 631 | if (r) { |
634 | radeon_vm_fini(rdev, vm); | 632 | radeon_vm_fini(rdev, vm); |
635 | kfree(fpriv); | 633 | kfree(fpriv); |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 64eba7ebb354..f3d87cdd5c9d 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -321,6 +321,10 @@ struct radeon_crtc { | |||
321 | uint32_t crtc_offset; | 321 | uint32_t crtc_offset; |
322 | struct drm_gem_object *cursor_bo; | 322 | struct drm_gem_object *cursor_bo; |
323 | uint64_t cursor_addr; | 323 | uint64_t cursor_addr; |
324 | int cursor_x; | ||
325 | int cursor_y; | ||
326 | int cursor_hot_x; | ||
327 | int cursor_hot_y; | ||
324 | int cursor_width; | 328 | int cursor_width; |
325 | int cursor_height; | 329 | int cursor_height; |
326 | int max_cursor_width; | 330 | int max_cursor_width; |
@@ -805,11 +809,13 @@ extern int radeon_crtc_set_base_atomic(struct drm_crtc *crtc, | |||
805 | extern int radeon_crtc_do_set_base(struct drm_crtc *crtc, | 809 | extern int radeon_crtc_do_set_base(struct drm_crtc *crtc, |
806 | struct drm_framebuffer *fb, | 810 | struct drm_framebuffer *fb, |
807 | int x, int y, int atomic); | 811 | int x, int y, int atomic); |
808 | extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, | 812 | extern int radeon_crtc_cursor_set2(struct drm_crtc *crtc, |
809 | struct drm_file *file_priv, | 813 | struct drm_file *file_priv, |
810 | uint32_t handle, | 814 | uint32_t handle, |
811 | uint32_t width, | 815 | uint32_t width, |
812 | uint32_t height); | 816 | uint32_t height, |
817 | int32_t hot_x, | ||
818 | int32_t hot_y); | ||
813 | extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, | 819 | extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, |
814 | int x, int y); | 820 | int x, int y); |
815 | 821 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 76eedd6a34f0..87b00d902bf7 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -821,3 +821,22 @@ int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, bool no_wait) | |||
821 | ttm_bo_unreserve(&bo->tbo); | 821 | ttm_bo_unreserve(&bo->tbo); |
822 | return r; | 822 | return r; |
823 | } | 823 | } |
824 | |||
825 | /** | ||
826 | * radeon_bo_fence - add fence to buffer object | ||
827 | * | ||
828 | * @bo: buffer object in question | ||
829 | * @fence: fence to add | ||
830 | * @shared: true if fence should be added shared | ||
831 | * | ||
832 | */ | ||
833 | void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence, | ||
834 | bool shared) | ||
835 | { | ||
836 | struct reservation_object *resv = bo->tbo.resv; | ||
837 | |||
838 | if (shared) | ||
839 | reservation_object_add_shared_fence(resv, &fence->base); | ||
840 | else | ||
841 | reservation_object_add_excl_fence(resv, &fence->base); | ||
842 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 1b8ec7917154..3b0b377f76cb 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h | |||
@@ -155,6 +155,8 @@ extern void radeon_bo_move_notify(struct ttm_buffer_object *bo, | |||
155 | struct ttm_mem_reg *new_mem); | 155 | struct ttm_mem_reg *new_mem); |
156 | extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); | 156 | extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); |
157 | extern int radeon_bo_get_surface_reg(struct radeon_bo *bo); | 157 | extern int radeon_bo_get_surface_reg(struct radeon_bo *bo); |
158 | extern void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence, | ||
159 | bool shared); | ||
158 | 160 | ||
159 | /* | 161 | /* |
160 | * sub allocation | 162 | * sub allocation |
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index 6deb08f045b7..e6ad54cdfa62 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c | |||
@@ -34,15 +34,14 @@ | |||
34 | int radeon_semaphore_create(struct radeon_device *rdev, | 34 | int radeon_semaphore_create(struct radeon_device *rdev, |
35 | struct radeon_semaphore **semaphore) | 35 | struct radeon_semaphore **semaphore) |
36 | { | 36 | { |
37 | uint64_t *cpu_addr; | 37 | int r; |
38 | int i, r; | ||
39 | 38 | ||
40 | *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); | 39 | *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); |
41 | if (*semaphore == NULL) { | 40 | if (*semaphore == NULL) { |
42 | return -ENOMEM; | 41 | return -ENOMEM; |
43 | } | 42 | } |
44 | r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &(*semaphore)->sa_bo, | 43 | r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, |
45 | 8 * RADEON_NUM_SYNCS, 8); | 44 | &(*semaphore)->sa_bo, 8, 8); |
46 | if (r) { | 45 | if (r) { |
47 | kfree(*semaphore); | 46 | kfree(*semaphore); |
48 | *semaphore = NULL; | 47 | *semaphore = NULL; |
@@ -51,12 +50,7 @@ int radeon_semaphore_create(struct radeon_device *rdev, | |||
51 | (*semaphore)->waiters = 0; | 50 | (*semaphore)->waiters = 0; |
52 | (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); | 51 | (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); |
53 | 52 | ||
54 | cpu_addr = radeon_sa_bo_cpu_addr((*semaphore)->sa_bo); | 53 | *((uint64_t *)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0; |
55 | for (i = 0; i < RADEON_NUM_SYNCS; ++i) | ||
56 | cpu_addr[i] = 0; | ||
57 | |||
58 | for (i = 0; i < RADEON_NUM_RINGS; ++i) | ||
59 | (*semaphore)->sync_to[i] = NULL; | ||
60 | 54 | ||
61 | return 0; | 55 | return 0; |
62 | } | 56 | } |
@@ -95,146 +89,6 @@ bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx, | |||
95 | return false; | 89 | return false; |
96 | } | 90 | } |
97 | 91 | ||
98 | /** | ||
99 | * radeon_semaphore_sync_fence - use the semaphore to sync to a fence | ||
100 | * | ||
101 | * @semaphore: semaphore object to add fence to | ||
102 | * @fence: fence to sync to | ||
103 | * | ||
104 | * Sync to the fence using this semaphore object | ||
105 | */ | ||
106 | void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, | ||
107 | struct radeon_fence *fence) | ||
108 | { | ||
109 | struct radeon_fence *other; | ||
110 | |||
111 | if (!fence) | ||
112 | return; | ||
113 | |||
114 | other = semaphore->sync_to[fence->ring]; | ||
115 | semaphore->sync_to[fence->ring] = radeon_fence_later(fence, other); | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * radeon_semaphore_sync_to - use the semaphore to sync to a reservation object | ||
120 | * | ||
121 | * @sema: semaphore object to add fence from reservation object to | ||
122 | * @resv: reservation object with embedded fence | ||
123 | * @shared: true if we should onyl sync to the exclusive fence | ||
124 | * | ||
125 | * Sync to the fence using this semaphore object | ||
126 | */ | ||
127 | int radeon_semaphore_sync_resv(struct radeon_device *rdev, | ||
128 | struct radeon_semaphore *sema, | ||
129 | struct reservation_object *resv, | ||
130 | bool shared) | ||
131 | { | ||
132 | struct reservation_object_list *flist; | ||
133 | struct fence *f; | ||
134 | struct radeon_fence *fence; | ||
135 | unsigned i; | ||
136 | int r = 0; | ||
137 | |||
138 | /* always sync to the exclusive fence */ | ||
139 | f = reservation_object_get_excl(resv); | ||
140 | fence = f ? to_radeon_fence(f) : NULL; | ||
141 | if (fence && fence->rdev == rdev) | ||
142 | radeon_semaphore_sync_fence(sema, fence); | ||
143 | else if (f) | ||
144 | r = fence_wait(f, true); | ||
145 | |||
146 | flist = reservation_object_get_list(resv); | ||
147 | if (shared || !flist || r) | ||
148 | return r; | ||
149 | |||
150 | for (i = 0; i < flist->shared_count; ++i) { | ||
151 | f = rcu_dereference_protected(flist->shared[i], | ||
152 | reservation_object_held(resv)); | ||
153 | fence = to_radeon_fence(f); | ||
154 | if (fence && fence->rdev == rdev) | ||
155 | radeon_semaphore_sync_fence(sema, fence); | ||
156 | else | ||
157 | r = fence_wait(f, true); | ||
158 | |||
159 | if (r) | ||
160 | break; | ||
161 | } | ||
162 | return r; | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * radeon_semaphore_sync_rings - sync ring to all registered fences | ||
167 | * | ||
168 | * @rdev: radeon_device pointer | ||
169 | * @semaphore: semaphore object to use for sync | ||
170 | * @ring: ring that needs sync | ||
171 | * | ||
172 | * Ensure that all registered fences are signaled before letting | ||
173 | * the ring continue. The caller must hold the ring lock. | ||
174 | */ | ||
175 | int radeon_semaphore_sync_rings(struct radeon_device *rdev, | ||
176 | struct radeon_semaphore *semaphore, | ||
177 | int ring) | ||
178 | { | ||
179 | unsigned count = 0; | ||
180 | int i, r; | ||
181 | |||
182 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
183 | struct radeon_fence *fence = semaphore->sync_to[i]; | ||
184 | |||
185 | /* check if we really need to sync */ | ||
186 | if (!radeon_fence_need_sync(fence, ring)) | ||
187 | continue; | ||
188 | |||
189 | /* prevent GPU deadlocks */ | ||
190 | if (!rdev->ring[i].ready) { | ||
191 | dev_err(rdev->dev, "Syncing to a disabled ring!"); | ||
192 | return -EINVAL; | ||
193 | } | ||
194 | |||
195 | if (++count > RADEON_NUM_SYNCS) { | ||
196 | /* not enough room, wait manually */ | ||
197 | r = radeon_fence_wait(fence, false); | ||
198 | if (r) | ||
199 | return r; | ||
200 | continue; | ||
201 | } | ||
202 | |||
203 | /* allocate enough space for sync command */ | ||
204 | r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); | ||
205 | if (r) { | ||
206 | return r; | ||
207 | } | ||
208 | |||
209 | /* emit the signal semaphore */ | ||
210 | if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) { | ||
211 | /* signaling wasn't successful wait manually */ | ||
212 | radeon_ring_undo(&rdev->ring[i]); | ||
213 | r = radeon_fence_wait(fence, false); | ||
214 | if (r) | ||
215 | return r; | ||
216 | continue; | ||
217 | } | ||
218 | |||
219 | /* we assume caller has already allocated space on waiters ring */ | ||
220 | if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) { | ||
221 | /* waiting wasn't successful wait manually */ | ||
222 | radeon_ring_undo(&rdev->ring[i]); | ||
223 | r = radeon_fence_wait(fence, false); | ||
224 | if (r) | ||
225 | return r; | ||
226 | continue; | ||
227 | } | ||
228 | |||
229 | radeon_ring_commit(rdev, &rdev->ring[i], false); | ||
230 | radeon_fence_note_sync(fence, ring); | ||
231 | |||
232 | semaphore->gpu_addr += 8; | ||
233 | } | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | void radeon_semaphore_free(struct radeon_device *rdev, | 92 | void radeon_semaphore_free(struct radeon_device *rdev, |
239 | struct radeon_semaphore **semaphore, | 93 | struct radeon_semaphore **semaphore, |
240 | struct radeon_fence *fence) | 94 | struct radeon_fence *fence) |
diff --git a/drivers/gpu/drm/radeon/radeon_sync.c b/drivers/gpu/drm/radeon/radeon_sync.c new file mode 100644 index 000000000000..02ac8a1de4ff --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_sync.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Advanced Micro Devices, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the | ||
7 | * "Software"), to deal in the Software without restriction, including | ||
8 | * without limitation the rights to use, copy, modify, merge, publish, | ||
9 | * distribute, sub license, and/or sell copies of the Software, and to | ||
10 | * permit persons to whom the Software is furnished to do so, subject to | ||
11 | * the following conditions: | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
16 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, | ||
17 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
18 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
19 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
20 | * | ||
21 | * The above copyright notice and this permission notice (including the | ||
22 | * next paragraph) shall be included in all copies or substantial portions | ||
23 | * of the Software. | ||
24 | * | ||
25 | */ | ||
26 | /* | ||
27 | * Authors: | ||
28 | * Christian König <christian.koenig@amd.com> | ||
29 | */ | ||
30 | |||
31 | #include <drm/drmP.h> | ||
32 | #include "radeon.h" | ||
33 | #include "radeon_trace.h" | ||
34 | |||
35 | /** | ||
36 | * radeon_sync_create - zero init sync object | ||
37 | * | ||
38 | * @sync: sync object to initialize | ||
39 | * | ||
40 | * Just clear the sync object for now. | ||
41 | */ | ||
42 | void radeon_sync_create(struct radeon_sync *sync) | ||
43 | { | ||
44 | unsigned i; | ||
45 | |||
46 | for (i = 0; i < RADEON_NUM_SYNCS; ++i) | ||
47 | sync->semaphores[i] = NULL; | ||
48 | |||
49 | for (i = 0; i < RADEON_NUM_RINGS; ++i) | ||
50 | sync->sync_to[i] = NULL; | ||
51 | |||
52 | sync->last_vm_update = NULL; | ||
53 | } | ||
54 | |||
55 | /** | ||
56 | * radeon_sync_fence - use the semaphore to sync to a fence | ||
57 | * | ||
58 | * @sync: sync object to add fence to | ||
59 | * @fence: fence to sync to | ||
60 | * | ||
61 | * Sync to the fence using the semaphore objects | ||
62 | */ | ||
63 | void radeon_sync_fence(struct radeon_sync *sync, | ||
64 | struct radeon_fence *fence) | ||
65 | { | ||
66 | struct radeon_fence *other; | ||
67 | |||
68 | if (!fence) | ||
69 | return; | ||
70 | |||
71 | other = sync->sync_to[fence->ring]; | ||
72 | sync->sync_to[fence->ring] = radeon_fence_later(fence, other); | ||
73 | |||
74 | if (fence->is_vm_update) { | ||
75 | other = sync->last_vm_update; | ||
76 | sync->last_vm_update = radeon_fence_later(fence, other); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | /** | ||
81 | * radeon_sync_resv - use the semaphores to sync to a reservation object | ||
82 | * | ||
83 | * @sync: sync object to add fences from reservation object to | ||
84 | * @resv: reservation object with embedded fence | ||
85 | * @shared: true if we should only sync to the exclusive fence | ||
86 | * | ||
87 | * Sync to the fence using the semaphore objects | ||
88 | */ | ||
89 | int radeon_sync_resv(struct radeon_device *rdev, | ||
90 | struct radeon_sync *sync, | ||
91 | struct reservation_object *resv, | ||
92 | bool shared) | ||
93 | { | ||
94 | struct reservation_object_list *flist; | ||
95 | struct fence *f; | ||
96 | struct radeon_fence *fence; | ||
97 | unsigned i; | ||
98 | int r = 0; | ||
99 | |||
100 | /* always sync to the exclusive fence */ | ||
101 | f = reservation_object_get_excl(resv); | ||
102 | fence = f ? to_radeon_fence(f) : NULL; | ||
103 | if (fence && fence->rdev == rdev) | ||
104 | radeon_sync_fence(sync, fence); | ||
105 | else if (f) | ||
106 | r = fence_wait(f, true); | ||
107 | |||
108 | flist = reservation_object_get_list(resv); | ||
109 | if (shared || !flist || r) | ||
110 | return r; | ||
111 | |||
112 | for (i = 0; i < flist->shared_count; ++i) { | ||
113 | f = rcu_dereference_protected(flist->shared[i], | ||
114 | reservation_object_held(resv)); | ||
115 | fence = to_radeon_fence(f); | ||
116 | if (fence && fence->rdev == rdev) | ||
117 | radeon_sync_fence(sync, fence); | ||
118 | else | ||
119 | r = fence_wait(f, true); | ||
120 | |||
121 | if (r) | ||
122 | break; | ||
123 | } | ||
124 | return r; | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * radeon_sync_rings - sync ring to all registered fences | ||
129 | * | ||
130 | * @rdev: radeon_device pointer | ||
131 | * @sync: sync object to use | ||
132 | * @ring: ring that needs sync | ||
133 | * | ||
134 | * Ensure that all registered fences are signaled before letting | ||
135 | * the ring continue. The caller must hold the ring lock. | ||
136 | */ | ||
137 | int radeon_sync_rings(struct radeon_device *rdev, | ||
138 | struct radeon_sync *sync, | ||
139 | int ring) | ||
140 | { | ||
141 | unsigned count = 0; | ||
142 | int i, r; | ||
143 | |||
144 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
145 | struct radeon_fence *fence = sync->sync_to[i]; | ||
146 | struct radeon_semaphore *semaphore; | ||
147 | |||
148 | /* check if we really need to sync */ | ||
149 | if (!radeon_fence_need_sync(fence, ring)) | ||
150 | continue; | ||
151 | |||
152 | /* prevent GPU deadlocks */ | ||
153 | if (!rdev->ring[i].ready) { | ||
154 | dev_err(rdev->dev, "Syncing to a disabled ring!"); | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | if (count >= RADEON_NUM_SYNCS) { | ||
159 | /* not enough room, wait manually */ | ||
160 | r = radeon_fence_wait(fence, false); | ||
161 | if (r) | ||
162 | return r; | ||
163 | continue; | ||
164 | } | ||
165 | r = radeon_semaphore_create(rdev, &semaphore); | ||
166 | if (r) | ||
167 | return r; | ||
168 | |||
169 | sync->semaphores[count++] = semaphore; | ||
170 | |||
171 | /* allocate enough space for sync command */ | ||
172 | r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); | ||
173 | if (r) | ||
174 | return r; | ||
175 | |||
176 | /* emit the signal semaphore */ | ||
177 | if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) { | ||
178 | /* signaling wasn't successful wait manually */ | ||
179 | radeon_ring_undo(&rdev->ring[i]); | ||
180 | r = radeon_fence_wait(fence, false); | ||
181 | if (r) | ||
182 | return r; | ||
183 | continue; | ||
184 | } | ||
185 | |||
186 | /* we assume caller has already allocated space on waiters ring */ | ||
187 | if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) { | ||
188 | /* waiting wasn't successful wait manually */ | ||
189 | radeon_ring_undo(&rdev->ring[i]); | ||
190 | r = radeon_fence_wait(fence, false); | ||
191 | if (r) | ||
192 | return r; | ||
193 | continue; | ||
194 | } | ||
195 | |||
196 | radeon_ring_commit(rdev, &rdev->ring[i], false); | ||
197 | radeon_fence_note_sync(fence, ring); | ||
198 | } | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | /** | ||
204 | * radeon_sync_free - free the sync object | ||
205 | * | ||
206 | * @rdev: radeon_device pointer | ||
207 | * @sync: sync object to use | ||
208 | * @fence: fence to use for the free | ||
209 | * | ||
210 | * Free the sync object by freeing all semaphores in it. | ||
211 | */ | ||
212 | void radeon_sync_free(struct radeon_device *rdev, | ||
213 | struct radeon_sync *sync, | ||
214 | struct radeon_fence *fence) | ||
215 | { | ||
216 | unsigned i; | ||
217 | |||
218 | for (i = 0; i < RADEON_NUM_SYNCS; ++i) | ||
219 | radeon_semaphore_free(rdev, &sync->semaphores[i], fence); | ||
220 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index dfde266529e2..0b10f3a03ce2 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c | |||
@@ -143,7 +143,7 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, | |||
143 | list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM; | 143 | list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM; |
144 | list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM; | 144 | list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM; |
145 | list[0].tv.bo = &vm->page_directory->tbo; | 145 | list[0].tv.bo = &vm->page_directory->tbo; |
146 | list[0].tv.shared = false; | 146 | list[0].tv.shared = true; |
147 | list[0].tiling_flags = 0; | 147 | list[0].tiling_flags = 0; |
148 | list[0].handle = 0; | 148 | list[0].handle = 0; |
149 | list_add(&list[0].tv.head, head); | 149 | list_add(&list[0].tv.head, head); |
@@ -157,7 +157,7 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, | |||
157 | list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM; | 157 | list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM; |
158 | list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM; | 158 | list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM; |
159 | list[idx].tv.bo = &list[idx].robj->tbo; | 159 | list[idx].tv.bo = &list[idx].robj->tbo; |
160 | list[idx].tv.shared = false; | 160 | list[idx].tv.shared = true; |
161 | list[idx].tiling_flags = 0; | 161 | list[idx].tiling_flags = 0; |
162 | list[idx].handle = 0; | 162 | list[idx].handle = 0; |
163 | list_add(&list[idx++].tv.head, head); | 163 | list_add(&list[idx++].tv.head, head); |
@@ -182,15 +182,18 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, | |||
182 | struct radeon_vm *vm, int ring) | 182 | struct radeon_vm *vm, int ring) |
183 | { | 183 | { |
184 | struct radeon_fence *best[RADEON_NUM_RINGS] = {}; | 184 | struct radeon_fence *best[RADEON_NUM_RINGS] = {}; |
185 | struct radeon_vm_id *vm_id = &vm->ids[ring]; | ||
186 | |||
185 | unsigned choices[2] = {}; | 187 | unsigned choices[2] = {}; |
186 | unsigned i; | 188 | unsigned i; |
187 | 189 | ||
188 | /* check if the id is still valid */ | 190 | /* check if the id is still valid */ |
189 | if (vm->last_id_use && vm->last_id_use == rdev->vm_manager.active[vm->id]) | 191 | if (vm_id->id && vm_id->last_id_use && |
192 | vm_id->last_id_use == rdev->vm_manager.active[vm_id->id]) | ||
190 | return NULL; | 193 | return NULL; |
191 | 194 | ||
192 | /* we definately need to flush */ | 195 | /* we definately need to flush */ |
193 | radeon_fence_unref(&vm->last_flush); | 196 | vm_id->pd_gpu_addr = ~0ll; |
194 | 197 | ||
195 | /* skip over VMID 0, since it is the system VM */ | 198 | /* skip over VMID 0, since it is the system VM */ |
196 | for (i = 1; i < rdev->vm_manager.nvm; ++i) { | 199 | for (i = 1; i < rdev->vm_manager.nvm; ++i) { |
@@ -198,8 +201,8 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, | |||
198 | 201 | ||
199 | if (fence == NULL) { | 202 | if (fence == NULL) { |
200 | /* found a free one */ | 203 | /* found a free one */ |
201 | vm->id = i; | 204 | vm_id->id = i; |
202 | trace_radeon_vm_grab_id(vm->id, ring); | 205 | trace_radeon_vm_grab_id(i, ring); |
203 | return NULL; | 206 | return NULL; |
204 | } | 207 | } |
205 | 208 | ||
@@ -211,8 +214,8 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, | |||
211 | 214 | ||
212 | for (i = 0; i < 2; ++i) { | 215 | for (i = 0; i < 2; ++i) { |
213 | if (choices[i]) { | 216 | if (choices[i]) { |
214 | vm->id = choices[i]; | 217 | vm_id->id = choices[i]; |
215 | trace_radeon_vm_grab_id(vm->id, ring); | 218 | trace_radeon_vm_grab_id(choices[i], ring); |
216 | return rdev->vm_manager.active[choices[i]]; | 219 | return rdev->vm_manager.active[choices[i]]; |
217 | } | 220 | } |
218 | } | 221 | } |
@@ -228,6 +231,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, | |||
228 | * @rdev: radeon_device pointer | 231 | * @rdev: radeon_device pointer |
229 | * @vm: vm we want to flush | 232 | * @vm: vm we want to flush |
230 | * @ring: ring to use for flush | 233 | * @ring: ring to use for flush |
234 | * @updates: last vm update that is waited for | ||
231 | * | 235 | * |
232 | * Flush the vm (cayman+). | 236 | * Flush the vm (cayman+). |
233 | * | 237 | * |
@@ -235,15 +239,21 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, | |||
235 | */ | 239 | */ |
236 | void radeon_vm_flush(struct radeon_device *rdev, | 240 | void radeon_vm_flush(struct radeon_device *rdev, |
237 | struct radeon_vm *vm, | 241 | struct radeon_vm *vm, |
238 | int ring) | 242 | int ring, struct radeon_fence *updates) |
239 | { | 243 | { |
240 | uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory); | 244 | uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory); |
245 | struct radeon_vm_id *vm_id = &vm->ids[ring]; | ||
246 | |||
247 | if (pd_addr != vm_id->pd_gpu_addr || !vm_id->flushed_updates || | ||
248 | radeon_fence_is_earlier(vm_id->flushed_updates, updates)) { | ||
249 | |||
250 | trace_radeon_vm_flush(pd_addr, ring, vm->ids[ring].id); | ||
251 | radeon_fence_unref(&vm_id->flushed_updates); | ||
252 | vm_id->flushed_updates = radeon_fence_ref(updates); | ||
253 | vm_id->pd_gpu_addr = pd_addr; | ||
254 | radeon_ring_vm_flush(rdev, &rdev->ring[ring], | ||
255 | vm_id->id, vm_id->pd_gpu_addr); | ||
241 | 256 | ||
242 | /* if we can't remember our last VM flush then flush now! */ | ||
243 | if (!vm->last_flush || pd_addr != vm->pd_gpu_addr) { | ||
244 | trace_radeon_vm_flush(pd_addr, ring, vm->id); | ||
245 | vm->pd_gpu_addr = pd_addr; | ||
246 | radeon_ring_vm_flush(rdev, ring, vm); | ||
247 | } | 257 | } |
248 | } | 258 | } |
249 | 259 | ||
@@ -263,18 +273,13 @@ void radeon_vm_fence(struct radeon_device *rdev, | |||
263 | struct radeon_vm *vm, | 273 | struct radeon_vm *vm, |
264 | struct radeon_fence *fence) | 274 | struct radeon_fence *fence) |
265 | { | 275 | { |
266 | radeon_fence_unref(&vm->fence); | 276 | unsigned vm_id = vm->ids[fence->ring].id; |
267 | vm->fence = radeon_fence_ref(fence); | ||
268 | 277 | ||
269 | radeon_fence_unref(&rdev->vm_manager.active[vm->id]); | 278 | radeon_fence_unref(&rdev->vm_manager.active[vm_id]); |
270 | rdev->vm_manager.active[vm->id] = radeon_fence_ref(fence); | 279 | rdev->vm_manager.active[vm_id] = radeon_fence_ref(fence); |
271 | 280 | ||
272 | radeon_fence_unref(&vm->last_id_use); | 281 | radeon_fence_unref(&vm->ids[fence->ring].last_id_use); |
273 | vm->last_id_use = radeon_fence_ref(fence); | 282 | vm->ids[fence->ring].last_id_use = radeon_fence_ref(fence); |
274 | |||
275 | /* we just flushed the VM, remember that */ | ||
276 | if (!vm->last_flush) | ||
277 | vm->last_flush = radeon_fence_ref(fence); | ||
278 | } | 283 | } |
279 | 284 | ||
280 | /** | 285 | /** |
@@ -387,35 +392,25 @@ static void radeon_vm_set_pages(struct radeon_device *rdev, | |||
387 | static int radeon_vm_clear_bo(struct radeon_device *rdev, | 392 | static int radeon_vm_clear_bo(struct radeon_device *rdev, |
388 | struct radeon_bo *bo) | 393 | struct radeon_bo *bo) |
389 | { | 394 | { |
390 | struct ttm_validate_buffer tv; | ||
391 | struct ww_acquire_ctx ticket; | ||
392 | struct list_head head; | ||
393 | struct radeon_ib ib; | 395 | struct radeon_ib ib; |
394 | unsigned entries; | 396 | unsigned entries; |
395 | uint64_t addr; | 397 | uint64_t addr; |
396 | int r; | 398 | int r; |
397 | 399 | ||
398 | memset(&tv, 0, sizeof(tv)); | 400 | r = radeon_bo_reserve(bo, false); |
399 | tv.bo = &bo->tbo; | 401 | if (r) |
400 | tv.shared = false; | ||
401 | |||
402 | INIT_LIST_HEAD(&head); | ||
403 | list_add(&tv.head, &head); | ||
404 | |||
405 | r = ttm_eu_reserve_buffers(&ticket, &head, true); | ||
406 | if (r) | ||
407 | return r; | 402 | return r; |
408 | 403 | ||
409 | r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); | 404 | r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); |
410 | if (r) | 405 | if (r) |
411 | goto error; | 406 | goto error_unreserve; |
412 | 407 | ||
413 | addr = radeon_bo_gpu_offset(bo); | 408 | addr = radeon_bo_gpu_offset(bo); |
414 | entries = radeon_bo_size(bo) / 8; | 409 | entries = radeon_bo_size(bo) / 8; |
415 | 410 | ||
416 | r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, 256); | 411 | r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, 256); |
417 | if (r) | 412 | if (r) |
418 | goto error; | 413 | goto error_unreserve; |
419 | 414 | ||
420 | ib.length_dw = 0; | 415 | ib.length_dw = 0; |
421 | 416 | ||
@@ -425,15 +420,16 @@ static int radeon_vm_clear_bo(struct radeon_device *rdev, | |||
425 | 420 | ||
426 | r = radeon_ib_schedule(rdev, &ib, NULL, false); | 421 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
427 | if (r) | 422 | if (r) |
428 | goto error; | 423 | goto error_free; |
429 | 424 | ||
430 | ttm_eu_fence_buffer_objects(&ticket, &head, &ib.fence->base); | 425 | ib.fence->is_vm_update = true; |
431 | radeon_ib_free(rdev, &ib); | 426 | radeon_bo_fence(bo, ib.fence, false); |
432 | 427 | ||
433 | return 0; | 428 | error_free: |
429 | radeon_ib_free(rdev, &ib); | ||
434 | 430 | ||
435 | error: | 431 | error_unreserve: |
436 | ttm_eu_backoff_reservation(&ticket, &head); | 432 | radeon_bo_unreserve(bo); |
437 | return r; | 433 | return r; |
438 | } | 434 | } |
439 | 435 | ||
@@ -449,7 +445,7 @@ error: | |||
449 | * Validate and set the offset requested within the vm address space. | 445 | * Validate and set the offset requested within the vm address space. |
450 | * Returns 0 for success, error for failure. | 446 | * Returns 0 for success, error for failure. |
451 | * | 447 | * |
452 | * Object has to be reserved! | 448 | * Object has to be reserved and gets unreserved by this function! |
453 | */ | 449 | */ |
454 | int radeon_vm_bo_set_addr(struct radeon_device *rdev, | 450 | int radeon_vm_bo_set_addr(struct radeon_device *rdev, |
455 | struct radeon_bo_va *bo_va, | 451 | struct radeon_bo_va *bo_va, |
@@ -575,7 +571,7 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
575 | } | 571 | } |
576 | 572 | ||
577 | mutex_unlock(&vm->mutex); | 573 | mutex_unlock(&vm->mutex); |
578 | return radeon_bo_reserve(bo_va->bo, false); | 574 | return 0; |
579 | } | 575 | } |
580 | 576 | ||
581 | /** | 577 | /** |
@@ -699,17 +695,15 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, | |||
699 | if (ib.length_dw != 0) { | 695 | if (ib.length_dw != 0) { |
700 | radeon_asic_vm_pad_ib(rdev, &ib); | 696 | radeon_asic_vm_pad_ib(rdev, &ib); |
701 | 697 | ||
702 | radeon_semaphore_sync_resv(rdev, ib.semaphore, pd->tbo.resv, false); | 698 | radeon_sync_resv(rdev, &ib.sync, pd->tbo.resv, true); |
703 | radeon_semaphore_sync_fence(ib.semaphore, vm->last_id_use); | ||
704 | WARN_ON(ib.length_dw > ndw); | 699 | WARN_ON(ib.length_dw > ndw); |
705 | r = radeon_ib_schedule(rdev, &ib, NULL, false); | 700 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
706 | if (r) { | 701 | if (r) { |
707 | radeon_ib_free(rdev, &ib); | 702 | radeon_ib_free(rdev, &ib); |
708 | return r; | 703 | return r; |
709 | } | 704 | } |
710 | radeon_fence_unref(&vm->fence); | 705 | ib.fence->is_vm_update = true; |
711 | vm->fence = radeon_fence_ref(ib.fence); | 706 | radeon_bo_fence(pd, ib.fence, false); |
712 | radeon_fence_unref(&vm->last_flush); | ||
713 | } | 707 | } |
714 | radeon_ib_free(rdev, &ib); | 708 | radeon_ib_free(rdev, &ib); |
715 | 709 | ||
@@ -826,7 +820,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, | |||
826 | unsigned nptes; | 820 | unsigned nptes; |
827 | uint64_t pte; | 821 | uint64_t pte; |
828 | 822 | ||
829 | radeon_semaphore_sync_resv(rdev, ib->semaphore, pt->tbo.resv, false); | 823 | radeon_sync_resv(rdev, &ib->sync, pt->tbo.resv, true); |
830 | 824 | ||
831 | if ((addr & ~mask) == (end & ~mask)) | 825 | if ((addr & ~mask) == (end & ~mask)) |
832 | nptes = end - addr; | 826 | nptes = end - addr; |
@@ -863,6 +857,31 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, | |||
863 | } | 857 | } |
864 | 858 | ||
865 | /** | 859 | /** |
860 | * radeon_vm_fence_pts - fence page tables after an update | ||
861 | * | ||
862 | * @vm: requested vm | ||
863 | * @start: start of GPU address range | ||
864 | * @end: end of GPU address range | ||
865 | * @fence: fence to use | ||
866 | * | ||
867 | * Fence the page tables in the range @start - @end (cayman+). | ||
868 | * | ||
869 | * Global and local mutex must be locked! | ||
870 | */ | ||
871 | static void radeon_vm_fence_pts(struct radeon_vm *vm, | ||
872 | uint64_t start, uint64_t end, | ||
873 | struct radeon_fence *fence) | ||
874 | { | ||
875 | unsigned i; | ||
876 | |||
877 | start >>= radeon_vm_block_size; | ||
878 | end >>= radeon_vm_block_size; | ||
879 | |||
880 | for (i = start; i <= end; ++i) | ||
881 | radeon_bo_fence(vm->page_tables[i].bo, fence, false); | ||
882 | } | ||
883 | |||
884 | /** | ||
866 | * radeon_vm_bo_update - map a bo into the vm page table | 885 | * radeon_vm_bo_update - map a bo into the vm page table |
867 | * | 886 | * |
868 | * @rdev: radeon_device pointer | 887 | * @rdev: radeon_device pointer |
@@ -961,6 +980,13 @@ int radeon_vm_bo_update(struct radeon_device *rdev, | |||
961 | return r; | 980 | return r; |
962 | ib.length_dw = 0; | 981 | ib.length_dw = 0; |
963 | 982 | ||
983 | if (!(bo_va->flags & RADEON_VM_PAGE_VALID)) { | ||
984 | unsigned i; | ||
985 | |||
986 | for (i = 0; i < RADEON_NUM_RINGS; ++i) | ||
987 | radeon_sync_fence(&ib.sync, vm->ids[i].last_id_use); | ||
988 | } | ||
989 | |||
964 | radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start, | 990 | radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start, |
965 | bo_va->it.last + 1, addr, | 991 | bo_va->it.last + 1, addr, |
966 | radeon_vm_page_flags(bo_va->flags)); | 992 | radeon_vm_page_flags(bo_va->flags)); |
@@ -968,16 +994,16 @@ int radeon_vm_bo_update(struct radeon_device *rdev, | |||
968 | radeon_asic_vm_pad_ib(rdev, &ib); | 994 | radeon_asic_vm_pad_ib(rdev, &ib); |
969 | WARN_ON(ib.length_dw > ndw); | 995 | WARN_ON(ib.length_dw > ndw); |
970 | 996 | ||
971 | radeon_semaphore_sync_fence(ib.semaphore, vm->fence); | ||
972 | r = radeon_ib_schedule(rdev, &ib, NULL, false); | 997 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
973 | if (r) { | 998 | if (r) { |
974 | radeon_ib_free(rdev, &ib); | 999 | radeon_ib_free(rdev, &ib); |
975 | return r; | 1000 | return r; |
976 | } | 1001 | } |
977 | radeon_fence_unref(&vm->fence); | 1002 | ib.fence->is_vm_update = true; |
978 | vm->fence = radeon_fence_ref(ib.fence); | 1003 | radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1, ib.fence); |
1004 | radeon_fence_unref(&bo_va->last_pt_update); | ||
1005 | bo_va->last_pt_update = radeon_fence_ref(ib.fence); | ||
979 | radeon_ib_free(rdev, &ib); | 1006 | radeon_ib_free(rdev, &ib); |
980 | radeon_fence_unref(&vm->last_flush); | ||
981 | 1007 | ||
982 | return 0; | 1008 | return 0; |
983 | } | 1009 | } |
@@ -1002,6 +1028,7 @@ int radeon_vm_clear_freed(struct radeon_device *rdev, | |||
1002 | list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { | 1028 | list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { |
1003 | r = radeon_vm_bo_update(rdev, bo_va, NULL); | 1029 | r = radeon_vm_bo_update(rdev, bo_va, NULL); |
1004 | radeon_bo_unref(&bo_va->bo); | 1030 | radeon_bo_unref(&bo_va->bo); |
1031 | radeon_fence_unref(&bo_va->last_pt_update); | ||
1005 | kfree(bo_va); | 1032 | kfree(bo_va); |
1006 | if (r) | 1033 | if (r) |
1007 | return r; | 1034 | return r; |
@@ -1060,6 +1087,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
1060 | bo_va->bo = radeon_bo_ref(bo_va->bo); | 1087 | bo_va->bo = radeon_bo_ref(bo_va->bo); |
1061 | list_add(&bo_va->vm_status, &vm->freed); | 1088 | list_add(&bo_va->vm_status, &vm->freed); |
1062 | } else { | 1089 | } else { |
1090 | radeon_fence_unref(&bo_va->last_pt_update); | ||
1063 | kfree(bo_va); | 1091 | kfree(bo_va); |
1064 | } | 1092 | } |
1065 | 1093 | ||
@@ -1103,13 +1131,14 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
1103 | const unsigned align = min(RADEON_VM_PTB_ALIGN_SIZE, | 1131 | const unsigned align = min(RADEON_VM_PTB_ALIGN_SIZE, |
1104 | RADEON_VM_PTE_COUNT * 8); | 1132 | RADEON_VM_PTE_COUNT * 8); |
1105 | unsigned pd_size, pd_entries, pts_size; | 1133 | unsigned pd_size, pd_entries, pts_size; |
1106 | int r; | 1134 | int i, r; |
1107 | 1135 | ||
1108 | vm->id = 0; | ||
1109 | vm->ib_bo_va = NULL; | 1136 | vm->ib_bo_va = NULL; |
1110 | vm->fence = NULL; | 1137 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
1111 | vm->last_flush = NULL; | 1138 | vm->ids[i].id = 0; |
1112 | vm->last_id_use = NULL; | 1139 | vm->ids[i].flushed_updates = NULL; |
1140 | vm->ids[i].last_id_use = NULL; | ||
1141 | } | ||
1113 | mutex_init(&vm->mutex); | 1142 | mutex_init(&vm->mutex); |
1114 | vm->va = RB_ROOT; | 1143 | vm->va = RB_ROOT; |
1115 | INIT_LIST_HEAD(&vm->invalidated); | 1144 | INIT_LIST_HEAD(&vm->invalidated); |
@@ -1165,11 +1194,13 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
1165 | if (!r) { | 1194 | if (!r) { |
1166 | list_del_init(&bo_va->bo_list); | 1195 | list_del_init(&bo_va->bo_list); |
1167 | radeon_bo_unreserve(bo_va->bo); | 1196 | radeon_bo_unreserve(bo_va->bo); |
1197 | radeon_fence_unref(&bo_va->last_pt_update); | ||
1168 | kfree(bo_va); | 1198 | kfree(bo_va); |
1169 | } | 1199 | } |
1170 | } | 1200 | } |
1171 | list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { | 1201 | list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { |
1172 | radeon_bo_unref(&bo_va->bo); | 1202 | radeon_bo_unref(&bo_va->bo); |
1203 | radeon_fence_unref(&bo_va->last_pt_update); | ||
1173 | kfree(bo_va); | 1204 | kfree(bo_va); |
1174 | } | 1205 | } |
1175 | 1206 | ||
@@ -1179,9 +1210,10 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
1179 | 1210 | ||
1180 | radeon_bo_unref(&vm->page_directory); | 1211 | radeon_bo_unref(&vm->page_directory); |
1181 | 1212 | ||
1182 | radeon_fence_unref(&vm->fence); | 1213 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
1183 | radeon_fence_unref(&vm->last_flush); | 1214 | radeon_fence_unref(&vm->ids[i].flushed_updates); |
1184 | radeon_fence_unref(&vm->last_id_use); | 1215 | radeon_fence_unref(&vm->ids[i].last_id_use); |
1216 | } | ||
1185 | 1217 | ||
1186 | mutex_destroy(&vm->mutex); | 1218 | mutex_destroy(&vm->mutex); |
1187 | } | 1219 | } |
diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c index 7f34bad2e724..acff6e09cc40 100644 --- a/drivers/gpu/drm/radeon/rv770_dma.c +++ b/drivers/gpu/drm/radeon/rv770_dma.c | |||
@@ -44,31 +44,27 @@ struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev, | |||
44 | unsigned num_gpu_pages, | 44 | unsigned num_gpu_pages, |
45 | struct reservation_object *resv) | 45 | struct reservation_object *resv) |
46 | { | 46 | { |
47 | struct radeon_semaphore *sem = NULL; | ||
48 | struct radeon_fence *fence; | 47 | struct radeon_fence *fence; |
48 | struct radeon_sync sync; | ||
49 | int ring_index = rdev->asic->copy.dma_ring_index; | 49 | int ring_index = rdev->asic->copy.dma_ring_index; |
50 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 50 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
51 | u32 size_in_dw, cur_size_in_dw; | 51 | u32 size_in_dw, cur_size_in_dw; |
52 | int i, num_loops; | 52 | int i, num_loops; |
53 | int r = 0; | 53 | int r = 0; |
54 | 54 | ||
55 | r = radeon_semaphore_create(rdev, &sem); | 55 | radeon_sync_create(&sync); |
56 | if (r) { | ||
57 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
58 | return ERR_PTR(r); | ||
59 | } | ||
60 | 56 | ||
61 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; | 57 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; |
62 | num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFF); | 58 | num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFF); |
63 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8); | 59 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8); |
64 | if (r) { | 60 | if (r) { |
65 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 61 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
66 | radeon_semaphore_free(rdev, &sem, NULL); | 62 | radeon_sync_free(rdev, &sync, NULL); |
67 | return ERR_PTR(r); | 63 | return ERR_PTR(r); |
68 | } | 64 | } |
69 | 65 | ||
70 | radeon_semaphore_sync_resv(rdev, sem, resv, false); | 66 | radeon_sync_resv(rdev, &sync, resv, false); |
71 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 67 | radeon_sync_rings(rdev, &sync, ring->idx); |
72 | 68 | ||
73 | for (i = 0; i < num_loops; i++) { | 69 | for (i = 0; i < num_loops; i++) { |
74 | cur_size_in_dw = size_in_dw; | 70 | cur_size_in_dw = size_in_dw; |
@@ -87,12 +83,12 @@ struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev, | |||
87 | r = radeon_fence_emit(rdev, &fence, ring->idx); | 83 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
88 | if (r) { | 84 | if (r) { |
89 | radeon_ring_unlock_undo(rdev, ring); | 85 | radeon_ring_unlock_undo(rdev, ring); |
90 | radeon_semaphore_free(rdev, &sem, NULL); | 86 | radeon_sync_free(rdev, &sync, NULL); |
91 | return ERR_PTR(r); | 87 | return ERR_PTR(r); |
92 | } | 88 | } |
93 | 89 | ||
94 | radeon_ring_unlock_commit(rdev, ring, false); | 90 | radeon_ring_unlock_commit(rdev, ring, false); |
95 | radeon_semaphore_free(rdev, &sem, fence); | 91 | radeon_sync_free(rdev, &sync, fence); |
96 | 92 | ||
97 | return fence; | 93 | return fence; |
98 | } | 94 | } |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index eeea5b6a1775..14896ce76324 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -3362,6 +3362,7 @@ void si_fence_ring_emit(struct radeon_device *rdev, | |||
3362 | void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | 3362 | void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
3363 | { | 3363 | { |
3364 | struct radeon_ring *ring = &rdev->ring[ib->ring]; | 3364 | struct radeon_ring *ring = &rdev->ring[ib->ring]; |
3365 | unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0; | ||
3365 | u32 header; | 3366 | u32 header; |
3366 | 3367 | ||
3367 | if (ib->is_const_ib) { | 3368 | if (ib->is_const_ib) { |
@@ -3397,14 +3398,13 @@ void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | |||
3397 | #endif | 3398 | #endif |
3398 | (ib->gpu_addr & 0xFFFFFFFC)); | 3399 | (ib->gpu_addr & 0xFFFFFFFC)); |
3399 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); | 3400 | radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); |
3400 | radeon_ring_write(ring, ib->length_dw | | 3401 | radeon_ring_write(ring, ib->length_dw | (vm_id << 24)); |
3401 | (ib->vm ? (ib->vm->id << 24) : 0)); | ||
3402 | 3402 | ||
3403 | if (!ib->is_const_ib) { | 3403 | if (!ib->is_const_ib) { |
3404 | /* flush read cache over gart for this vmid */ | 3404 | /* flush read cache over gart for this vmid */ |
3405 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 3405 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
3406 | radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); | 3406 | radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); |
3407 | radeon_ring_write(ring, ib->vm ? ib->vm->id : 0); | 3407 | radeon_ring_write(ring, vm_id); |
3408 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); | 3408 | radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); |
3409 | radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA | | 3409 | radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA | |
3410 | PACKET3_TC_ACTION_ENA | | 3410 | PACKET3_TC_ACTION_ENA | |
@@ -5020,27 +5020,23 @@ static void si_vm_decode_fault(struct radeon_device *rdev, | |||
5020 | block, mc_id); | 5020 | block, mc_id); |
5021 | } | 5021 | } |
5022 | 5022 | ||
5023 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | 5023 | void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
5024 | unsigned vm_id, uint64_t pd_addr) | ||
5024 | { | 5025 | { |
5025 | struct radeon_ring *ring = &rdev->ring[ridx]; | ||
5026 | |||
5027 | if (vm == NULL) | ||
5028 | return; | ||
5029 | |||
5030 | /* write new base address */ | 5026 | /* write new base address */ |
5031 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | 5027 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
5032 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) | | 5028 | radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) | |
5033 | WRITE_DATA_DST_SEL(0))); | 5029 | WRITE_DATA_DST_SEL(0))); |
5034 | 5030 | ||
5035 | if (vm->id < 8) { | 5031 | if (vm_id < 8) { |
5036 | radeon_ring_write(ring, | 5032 | radeon_ring_write(ring, |
5037 | (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2); | 5033 | (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); |
5038 | } else { | 5034 | } else { |
5039 | radeon_ring_write(ring, | 5035 | radeon_ring_write(ring, |
5040 | (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2); | 5036 | (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2); |
5041 | } | 5037 | } |
5042 | radeon_ring_write(ring, 0); | 5038 | radeon_ring_write(ring, 0); |
5043 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); | 5039 | radeon_ring_write(ring, pd_addr >> 12); |
5044 | 5040 | ||
5045 | /* flush hdp cache */ | 5041 | /* flush hdp cache */ |
5046 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); | 5042 | radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); |
@@ -5056,7 +5052,7 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
5056 | WRITE_DATA_DST_SEL(0))); | 5052 | WRITE_DATA_DST_SEL(0))); |
5057 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | 5053 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); |
5058 | radeon_ring_write(ring, 0); | 5054 | radeon_ring_write(ring, 0); |
5059 | radeon_ring_write(ring, 1 << vm->id); | 5055 | radeon_ring_write(ring, 1 << vm_id); |
5060 | 5056 | ||
5061 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | 5057 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ |
5062 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | 5058 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); |
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index b58f12b762d7..f5cc777e1c5f 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c | |||
@@ -185,20 +185,17 @@ void si_dma_vm_set_pages(struct radeon_device *rdev, | |||
185 | } | 185 | } |
186 | } | 186 | } |
187 | 187 | ||
188 | void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | 188 | void si_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
189 | { | 189 | unsigned vm_id, uint64_t pd_addr) |
190 | struct radeon_ring *ring = &rdev->ring[ridx]; | ||
191 | |||
192 | if (vm == NULL) | ||
193 | return; | ||
194 | 190 | ||
191 | { | ||
195 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); | 192 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); |
196 | if (vm->id < 8) { | 193 | if (vm_id < 8) { |
197 | radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2)); | 194 | radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2)); |
198 | } else { | 195 | } else { |
199 | radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2)); | 196 | radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2)); |
200 | } | 197 | } |
201 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); | 198 | radeon_ring_write(ring, pd_addr >> 12); |
202 | 199 | ||
203 | /* flush hdp cache */ | 200 | /* flush hdp cache */ |
204 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); | 201 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); |
@@ -208,7 +205,7 @@ void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
208 | /* bits 0-7 are the VM contexts0-7 */ | 205 | /* bits 0-7 are the VM contexts0-7 */ |
209 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); | 206 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); |
210 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); | 207 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); |
211 | radeon_ring_write(ring, 1 << vm->id); | 208 | radeon_ring_write(ring, 1 << vm_id); |
212 | } | 209 | } |
213 | 210 | ||
214 | /** | 211 | /** |
@@ -229,31 +226,27 @@ struct radeon_fence *si_copy_dma(struct radeon_device *rdev, | |||
229 | unsigned num_gpu_pages, | 226 | unsigned num_gpu_pages, |
230 | struct reservation_object *resv) | 227 | struct reservation_object *resv) |
231 | { | 228 | { |
232 | struct radeon_semaphore *sem = NULL; | ||
233 | struct radeon_fence *fence; | 229 | struct radeon_fence *fence; |
230 | struct radeon_sync sync; | ||
234 | int ring_index = rdev->asic->copy.dma_ring_index; | 231 | int ring_index = rdev->asic->copy.dma_ring_index; |
235 | struct radeon_ring *ring = &rdev->ring[ring_index]; | 232 | struct radeon_ring *ring = &rdev->ring[ring_index]; |
236 | u32 size_in_bytes, cur_size_in_bytes; | 233 | u32 size_in_bytes, cur_size_in_bytes; |
237 | int i, num_loops; | 234 | int i, num_loops; |
238 | int r = 0; | 235 | int r = 0; |
239 | 236 | ||
240 | r = radeon_semaphore_create(rdev, &sem); | 237 | radeon_sync_create(&sync); |
241 | if (r) { | ||
242 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
243 | return ERR_PTR(r); | ||
244 | } | ||
245 | 238 | ||
246 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); | 239 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); |
247 | num_loops = DIV_ROUND_UP(size_in_bytes, 0xfffff); | 240 | num_loops = DIV_ROUND_UP(size_in_bytes, 0xfffff); |
248 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); | 241 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); |
249 | if (r) { | 242 | if (r) { |
250 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 243 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
251 | radeon_semaphore_free(rdev, &sem, NULL); | 244 | radeon_sync_free(rdev, &sync, NULL); |
252 | return ERR_PTR(r); | 245 | return ERR_PTR(r); |
253 | } | 246 | } |
254 | 247 | ||
255 | radeon_semaphore_sync_resv(rdev, sem, resv, false); | 248 | radeon_sync_resv(rdev, &sync, resv, false); |
256 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 249 | radeon_sync_rings(rdev, &sync, ring->idx); |
257 | 250 | ||
258 | for (i = 0; i < num_loops; i++) { | 251 | for (i = 0; i < num_loops; i++) { |
259 | cur_size_in_bytes = size_in_bytes; | 252 | cur_size_in_bytes = size_in_bytes; |
@@ -272,12 +265,12 @@ struct radeon_fence *si_copy_dma(struct radeon_device *rdev, | |||
272 | r = radeon_fence_emit(rdev, &fence, ring->idx); | 265 | r = radeon_fence_emit(rdev, &fence, ring->idx); |
273 | if (r) { | 266 | if (r) { |
274 | radeon_ring_unlock_undo(rdev, ring); | 267 | radeon_ring_unlock_undo(rdev, ring); |
275 | radeon_semaphore_free(rdev, &sem, NULL); | 268 | radeon_sync_free(rdev, &sync, NULL); |
276 | return ERR_PTR(r); | 269 | return ERR_PTR(r); |
277 | } | 270 | } |
278 | 271 | ||
279 | radeon_ring_unlock_commit(rdev, ring, false); | 272 | radeon_ring_unlock_commit(rdev, ring, false); |
280 | radeon_semaphore_free(rdev, &sem, fence); | 273 | radeon_sync_free(rdev, &sync, fence); |
281 | 274 | ||
282 | return fence; | 275 | return fence; |
283 | } | 276 | } |
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 | ||
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]; |