diff options
author | Dave Airlie <airlied@redhat.com> | 2014-12-04 20:08:31 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-12-04 20:08:31 -0500 |
commit | d58e0d903477f5a158d7d4901eb6f96f8f4b6289 (patch) | |
tree | 4f474568d94c74382b5a6fb5bcbed426e6b79cda | |
parent | d5b75dc01fa9c699aee5f82f5dbe508da438ff94 (diff) | |
parent | eb8d4d0d994aebe4ebb6bccd3637ab55eab3fa81 (diff) |
Merge branch 'drm-next-3.19-wip' of git://people.freedesktop.org/~agd5f/linux into drm-next
- More cursor and hotspot handling fixes
- Fix some typos in the new smc fan control code and enable on CI
- VM and CS cleanups
* 'drm-next-3.19-wip' of git://people.freedesktop.org/~agd5f/linux:
drm/radeon: enable smc fan control on CI
drm/radeon: use pointers instead of indexes for CS chunks
drm/radeon: remove duplicates check
drm/ttm: optionally move duplicates to a separate list
drm/radeon: check the right ring in radeon_evict_flags()
drm/radeon: fix copy paste typos in fan control for si/ci
drm/radeon: Hide cursor on CRTCs used by fbdev (v2)
drm/radeon: add spinlock for BO_VA status protection (v2)
drm/radeon: fence PT updates as shared
drm/radeon: rename radeon_cs_reloc to radeon_bo_list
drm/radeon: drop the handle from radeon_cs_reloc
drm/radeon drop gobj from radeon_cs_reloc
drm/radeon: fix typo in new fan control registers for SI/CI
drm/radeon: sync all BOs involved in a CS
drm/radeon: Move hotspot handling out of radeon_set_cursor
drm/radeon: Re-show the cursor after a modeset
28 files changed, 324 insertions, 226 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 446e71ca36cb..d9b25684ac98 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c | |||
@@ -264,7 +264,8 @@ int qxl_release_reserve_list(struct qxl_release *release, bool no_intr) | |||
264 | if (list_is_singular(&release->bos)) | 264 | if (list_is_singular(&release->bos)) |
265 | return 0; | 265 | return 0; |
266 | 266 | ||
267 | ret = ttm_eu_reserve_buffers(&release->ticket, &release->bos, !no_intr); | 267 | ret = ttm_eu_reserve_buffers(&release->ticket, &release->bos, |
268 | !no_intr, NULL); | ||
268 | if (ret) | 269 | if (ret) |
269 | return ret; | 270 | return ret; |
270 | 271 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 30d242b25078..d59ec491dbb9 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -2039,6 +2039,7 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
2039 | atombios_crtc_set_base(crtc, x, y, old_fb); | 2039 | atombios_crtc_set_base(crtc, x, y, old_fb); |
2040 | atombios_overscan_setup(crtc, mode, adjusted_mode); | 2040 | atombios_overscan_setup(crtc, mode, adjusted_mode); |
2041 | atombios_scaler_setup(crtc); | 2041 | atombios_scaler_setup(crtc); |
2042 | radeon_cursor_reset(crtc); | ||
2042 | /* update the hw version fpr dpm */ | 2043 | /* update the hw version fpr dpm */ |
2043 | radeon_crtc->hw_mode = *adjusted_mode; | 2044 | radeon_crtc->hw_mode = *adjusted_mode; |
2044 | 2045 | ||
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 3f898d020ae6..f373a81ba3d5 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c | |||
@@ -937,7 +937,7 @@ static void ci_fan_ctrl_set_static_mode(struct radeon_device *rdev, u32 mode) | |||
937 | tmp |= TMIN(0); | 937 | tmp |= TMIN(0); |
938 | WREG32_SMC(CG_FDO_CTRL2, tmp); | 938 | WREG32_SMC(CG_FDO_CTRL2, tmp); |
939 | 939 | ||
940 | tmp = RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK; | 940 | tmp = RREG32_SMC(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK; |
941 | tmp |= FDO_PWM_MODE(mode); | 941 | tmp |= FDO_PWM_MODE(mode); |
942 | WREG32_SMC(CG_FDO_CTRL2, tmp); | 942 | WREG32_SMC(CG_FDO_CTRL2, tmp); |
943 | } | 943 | } |
@@ -1162,7 +1162,7 @@ static int ci_fan_ctrl_set_fan_speed_rpm(struct radeon_device *rdev, | |||
1162 | tmp |= TARGET_PERIOD(tach_period); | 1162 | tmp |= TARGET_PERIOD(tach_period); |
1163 | WREG32_SMC(CG_TACH_CTRL, tmp); | 1163 | WREG32_SMC(CG_TACH_CTRL, tmp); |
1164 | 1164 | ||
1165 | ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); | 1165 | ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC_RPM); |
1166 | 1166 | ||
1167 | return 0; | 1167 | return 0; |
1168 | } | 1168 | } |
@@ -1178,7 +1178,7 @@ static void ci_fan_ctrl_set_default_mode(struct radeon_device *rdev) | |||
1178 | tmp |= FDO_PWM_MODE(pi->fan_ctrl_default_mode); | 1178 | tmp |= FDO_PWM_MODE(pi->fan_ctrl_default_mode); |
1179 | WREG32_SMC(CG_FDO_CTRL2, tmp); | 1179 | WREG32_SMC(CG_FDO_CTRL2, tmp); |
1180 | 1180 | ||
1181 | tmp = RREG32_SMC(CG_FDO_CTRL2) & TMIN_MASK; | 1181 | tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TMIN_MASK; |
1182 | tmp |= TMIN(pi->t_min); | 1182 | tmp |= TMIN(pi->t_min); |
1183 | WREG32_SMC(CG_FDO_CTRL2, tmp); | 1183 | WREG32_SMC(CG_FDO_CTRL2, tmp); |
1184 | pi->fan_ctrl_is_in_default_mode = true; | 1184 | pi->fan_ctrl_is_in_default_mode = true; |
@@ -5849,7 +5849,6 @@ int ci_dpm_init(struct radeon_device *rdev) | |||
5849 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; | 5849 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; |
5850 | 5850 | ||
5851 | pi->fan_ctrl_is_in_default_mode = true; | 5851 | pi->fan_ctrl_is_in_default_mode = true; |
5852 | rdev->pm.dpm.fan.ucode_fan_control = false; | ||
5853 | 5852 | ||
5854 | return 0; | 5853 | return 0; |
5855 | } | 5854 | } |
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index e4e88ca8b82e..ba85986febea 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h | |||
@@ -213,18 +213,18 @@ | |||
213 | 213 | ||
214 | #define CG_FDO_CTRL0 0xC0300064 | 214 | #define CG_FDO_CTRL0 0xC0300064 |
215 | #define FDO_STATIC_DUTY(x) ((x) << 0) | 215 | #define FDO_STATIC_DUTY(x) ((x) << 0) |
216 | #define FDO_STATIC_DUTY_MASK 0x0000000F | 216 | #define FDO_STATIC_DUTY_MASK 0x000000FF |
217 | #define FDO_STATIC_DUTY_SHIFT 0 | 217 | #define FDO_STATIC_DUTY_SHIFT 0 |
218 | #define CG_FDO_CTRL1 0xC0300068 | 218 | #define CG_FDO_CTRL1 0xC0300068 |
219 | #define FMAX_DUTY100(x) ((x) << 0) | 219 | #define FMAX_DUTY100(x) ((x) << 0) |
220 | #define FMAX_DUTY100_MASK 0x0000000F | 220 | #define FMAX_DUTY100_MASK 0x000000FF |
221 | #define FMAX_DUTY100_SHIFT 0 | 221 | #define FMAX_DUTY100_SHIFT 0 |
222 | #define CG_FDO_CTRL2 0xC030006C | 222 | #define CG_FDO_CTRL2 0xC030006C |
223 | #define TMIN(x) ((x) << 0) | 223 | #define TMIN(x) ((x) << 0) |
224 | #define TMIN_MASK 0x0000000F | 224 | #define TMIN_MASK 0x000000FF |
225 | #define TMIN_SHIFT 0 | 225 | #define TMIN_SHIFT 0 |
226 | #define FDO_PWM_MODE(x) ((x) << 11) | 226 | #define FDO_PWM_MODE(x) ((x) << 11) |
227 | #define FDO_PWM_MODE_MASK (3 << 11) | 227 | #define FDO_PWM_MODE_MASK (7 << 11) |
228 | #define FDO_PWM_MODE_SHIFT 11 | 228 | #define FDO_PWM_MODE_SHIFT 11 |
229 | #define TACH_PWM_RESP_RATE(x) ((x) << 25) | 229 | #define TACH_PWM_RESP_RATE(x) ((x) << 25) |
230 | #define TACH_PWM_RESP_RATE_MASK (0x7f << 25) | 230 | #define TACH_PWM_RESP_RATE_MASK (0x7f << 25) |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 5c8b358f9fba..924b1b7ab455 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #define MIN(a,b) (((a)<(b))?(a):(b)) | 35 | #define MIN(a,b) (((a)<(b))?(a):(b)) |
36 | 36 | ||
37 | int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, | 37 | int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, |
38 | struct radeon_cs_reloc **cs_reloc); | 38 | struct radeon_bo_list **cs_reloc); |
39 | struct evergreen_cs_track { | 39 | struct evergreen_cs_track { |
40 | u32 group_size; | 40 | u32 group_size; |
41 | u32 nbanks; | 41 | u32 nbanks; |
@@ -1094,7 +1094,7 @@ static int evergreen_cs_parse_packet0(struct radeon_cs_parser *p, | |||
1094 | static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | 1094 | static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) |
1095 | { | 1095 | { |
1096 | struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track; | 1096 | struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track; |
1097 | struct radeon_cs_reloc *reloc; | 1097 | struct radeon_bo_list *reloc; |
1098 | u32 last_reg; | 1098 | u32 last_reg; |
1099 | u32 m, i, tmp, *ib; | 1099 | u32 m, i, tmp, *ib; |
1100 | int r; | 1100 | int r; |
@@ -1792,7 +1792,7 @@ static bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1792 | static int evergreen_packet3_check(struct radeon_cs_parser *p, | 1792 | static int evergreen_packet3_check(struct radeon_cs_parser *p, |
1793 | struct radeon_cs_packet *pkt) | 1793 | struct radeon_cs_packet *pkt) |
1794 | { | 1794 | { |
1795 | struct radeon_cs_reloc *reloc; | 1795 | struct radeon_bo_list *reloc; |
1796 | struct evergreen_cs_track *track; | 1796 | struct evergreen_cs_track *track; |
1797 | volatile u32 *ib; | 1797 | volatile u32 *ib; |
1798 | unsigned idx; | 1798 | unsigned idx; |
@@ -2661,7 +2661,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) | |||
2661 | p->track = NULL; | 2661 | p->track = NULL; |
2662 | return r; | 2662 | return r; |
2663 | } | 2663 | } |
2664 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); | 2664 | } while (p->idx < p->chunk_ib->length_dw); |
2665 | #if 0 | 2665 | #if 0 |
2666 | for (r = 0; r < p->ib.length_dw; r++) { | 2666 | for (r = 0; r < p->ib.length_dw; r++) { |
2667 | printk(KERN_INFO "%05d 0x%08X\n", r, p->ib.ptr[r]); | 2667 | printk(KERN_INFO "%05d 0x%08X\n", r, p->ib.ptr[r]); |
@@ -2684,8 +2684,8 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) | |||
2684 | **/ | 2684 | **/ |
2685 | int evergreen_dma_cs_parse(struct radeon_cs_parser *p) | 2685 | int evergreen_dma_cs_parse(struct radeon_cs_parser *p) |
2686 | { | 2686 | { |
2687 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; | 2687 | struct radeon_cs_chunk *ib_chunk = p->chunk_ib; |
2688 | struct radeon_cs_reloc *src_reloc, *dst_reloc, *dst2_reloc; | 2688 | struct radeon_bo_list *src_reloc, *dst_reloc, *dst2_reloc; |
2689 | u32 header, cmd, count, sub_cmd; | 2689 | u32 header, cmd, count, sub_cmd; |
2690 | volatile u32 *ib = p->ib.ptr; | 2690 | volatile u32 *ib = p->ib.ptr; |
2691 | u32 idx; | 2691 | u32 idx; |
@@ -3100,7 +3100,7 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p) | |||
3100 | DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx); | 3100 | DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx); |
3101 | return -EINVAL; | 3101 | return -EINVAL; |
3102 | } | 3102 | } |
3103 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); | 3103 | } while (p->idx < p->chunk_ib->length_dw); |
3104 | #if 0 | 3104 | #if 0 |
3105 | for (r = 0; r < p->ib->length_dw; r++) { | 3105 | for (r = 0; r < p->ib->length_dw; r++) { |
3106 | printk(KERN_INFO "%05d 0x%08X\n", r, p->ib.ptr[r]); | 3106 | printk(KERN_INFO "%05d 0x%08X\n", r, p->ib.ptr[r]); |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index b53b31a7b76f..74f06d540591 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -1254,7 +1254,7 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p, | |||
1254 | int r; | 1254 | int r; |
1255 | u32 tile_flags = 0; | 1255 | u32 tile_flags = 0; |
1256 | u32 tmp; | 1256 | u32 tmp; |
1257 | struct radeon_cs_reloc *reloc; | 1257 | struct radeon_bo_list *reloc; |
1258 | u32 value; | 1258 | u32 value; |
1259 | 1259 | ||
1260 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); | 1260 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
@@ -1293,7 +1293,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, | |||
1293 | int idx) | 1293 | int idx) |
1294 | { | 1294 | { |
1295 | unsigned c, i; | 1295 | unsigned c, i; |
1296 | struct radeon_cs_reloc *reloc; | 1296 | struct radeon_bo_list *reloc; |
1297 | struct r100_cs_track *track; | 1297 | struct r100_cs_track *track; |
1298 | int r = 0; | 1298 | int r = 0; |
1299 | volatile uint32_t *ib; | 1299 | volatile uint32_t *ib; |
@@ -1542,7 +1542,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1542 | struct radeon_cs_packet *pkt, | 1542 | struct radeon_cs_packet *pkt, |
1543 | unsigned idx, unsigned reg) | 1543 | unsigned idx, unsigned reg) |
1544 | { | 1544 | { |
1545 | struct radeon_cs_reloc *reloc; | 1545 | struct radeon_bo_list *reloc; |
1546 | struct r100_cs_track *track; | 1546 | struct r100_cs_track *track; |
1547 | volatile uint32_t *ib; | 1547 | volatile uint32_t *ib; |
1548 | uint32_t tmp; | 1548 | uint32_t tmp; |
@@ -1901,7 +1901,7 @@ int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, | |||
1901 | static int r100_packet3_check(struct radeon_cs_parser *p, | 1901 | static int r100_packet3_check(struct radeon_cs_parser *p, |
1902 | struct radeon_cs_packet *pkt) | 1902 | struct radeon_cs_packet *pkt) |
1903 | { | 1903 | { |
1904 | struct radeon_cs_reloc *reloc; | 1904 | struct radeon_bo_list *reloc; |
1905 | struct r100_cs_track *track; | 1905 | struct r100_cs_track *track; |
1906 | unsigned idx; | 1906 | unsigned idx; |
1907 | volatile uint32_t *ib; | 1907 | volatile uint32_t *ib; |
@@ -2061,7 +2061,7 @@ int r100_cs_parse(struct radeon_cs_parser *p) | |||
2061 | } | 2061 | } |
2062 | if (r) | 2062 | if (r) |
2063 | return r; | 2063 | return r; |
2064 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); | 2064 | } while (p->idx < p->chunk_ib->length_dw); |
2065 | return 0; | 2065 | return 0; |
2066 | } | 2066 | } |
2067 | 2067 | ||
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 732d4938aab7..c70e6d5bcd19 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c | |||
@@ -146,7 +146,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
146 | struct radeon_cs_packet *pkt, | 146 | struct radeon_cs_packet *pkt, |
147 | unsigned idx, unsigned reg) | 147 | unsigned idx, unsigned reg) |
148 | { | 148 | { |
149 | struct radeon_cs_reloc *reloc; | 149 | struct radeon_bo_list *reloc; |
150 | struct r100_cs_track *track; | 150 | struct r100_cs_track *track; |
151 | volatile uint32_t *ib; | 151 | volatile uint32_t *ib; |
152 | uint32_t tmp; | 152 | uint32_t tmp; |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 1bc4704034ce..064ad5569cca 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -598,7 +598,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
598 | struct radeon_cs_packet *pkt, | 598 | struct radeon_cs_packet *pkt, |
599 | unsigned idx, unsigned reg) | 599 | unsigned idx, unsigned reg) |
600 | { | 600 | { |
601 | struct radeon_cs_reloc *reloc; | 601 | struct radeon_bo_list *reloc; |
602 | struct r100_cs_track *track; | 602 | struct r100_cs_track *track; |
603 | volatile uint32_t *ib; | 603 | volatile uint32_t *ib; |
604 | uint32_t tmp, tile_flags = 0; | 604 | uint32_t tmp, tile_flags = 0; |
@@ -1142,7 +1142,7 @@ fail: | |||
1142 | static int r300_packet3_check(struct radeon_cs_parser *p, | 1142 | static int r300_packet3_check(struct radeon_cs_parser *p, |
1143 | struct radeon_cs_packet *pkt) | 1143 | struct radeon_cs_packet *pkt) |
1144 | { | 1144 | { |
1145 | struct radeon_cs_reloc *reloc; | 1145 | struct radeon_bo_list *reloc; |
1146 | struct r100_cs_track *track; | 1146 | struct r100_cs_track *track; |
1147 | volatile uint32_t *ib; | 1147 | volatile uint32_t *ib; |
1148 | unsigned idx; | 1148 | unsigned idx; |
@@ -1283,7 +1283,7 @@ int r300_cs_parse(struct radeon_cs_parser *p) | |||
1283 | if (r) { | 1283 | if (r) { |
1284 | return r; | 1284 | return r; |
1285 | } | 1285 | } |
1286 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); | 1286 | } while (p->idx < p->chunk_ib->length_dw); |
1287 | return 0; | 1287 | return 0; |
1288 | } | 1288 | } |
1289 | 1289 | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index c47537a1ddba..acc1f99c84d9 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -969,7 +969,7 @@ static int r600_cs_parse_packet0(struct radeon_cs_parser *p, | |||
969 | static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | 969 | static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) |
970 | { | 970 | { |
971 | struct r600_cs_track *track = (struct r600_cs_track *)p->track; | 971 | struct r600_cs_track *track = (struct r600_cs_track *)p->track; |
972 | struct radeon_cs_reloc *reloc; | 972 | struct radeon_bo_list *reloc; |
973 | u32 m, i, tmp, *ib; | 973 | u32 m, i, tmp, *ib; |
974 | int r; | 974 | int r; |
975 | 975 | ||
@@ -1626,7 +1626,7 @@ static bool r600_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1626 | static int r600_packet3_check(struct radeon_cs_parser *p, | 1626 | static int r600_packet3_check(struct radeon_cs_parser *p, |
1627 | struct radeon_cs_packet *pkt) | 1627 | struct radeon_cs_packet *pkt) |
1628 | { | 1628 | { |
1629 | struct radeon_cs_reloc *reloc; | 1629 | struct radeon_bo_list *reloc; |
1630 | struct r600_cs_track *track; | 1630 | struct r600_cs_track *track; |
1631 | volatile u32 *ib; | 1631 | volatile u32 *ib; |
1632 | unsigned idx; | 1632 | unsigned idx; |
@@ -2316,7 +2316,7 @@ int r600_cs_parse(struct radeon_cs_parser *p) | |||
2316 | p->track = NULL; | 2316 | p->track = NULL; |
2317 | return r; | 2317 | return r; |
2318 | } | 2318 | } |
2319 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); | 2319 | } while (p->idx < p->chunk_ib->length_dw); |
2320 | #if 0 | 2320 | #if 0 |
2321 | for (r = 0; r < p->ib.length_dw; r++) { | 2321 | for (r = 0; r < p->ib.length_dw; r++) { |
2322 | printk(KERN_INFO "%05d 0x%08X\n", r, p->ib.ptr[r]); | 2322 | printk(KERN_INFO "%05d 0x%08X\n", r, p->ib.ptr[r]); |
@@ -2351,10 +2351,10 @@ static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
2351 | 2351 | ||
2352 | static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p) | 2352 | static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p) |
2353 | { | 2353 | { |
2354 | if (p->chunk_relocs_idx == -1) { | 2354 | if (p->chunk_relocs == NULL) { |
2355 | return 0; | 2355 | return 0; |
2356 | } | 2356 | } |
2357 | p->relocs = kzalloc(sizeof(struct radeon_cs_reloc), GFP_KERNEL); | 2357 | p->relocs = kzalloc(sizeof(struct radeon_bo_list), GFP_KERNEL); |
2358 | if (p->relocs == NULL) { | 2358 | if (p->relocs == NULL) { |
2359 | return -ENOMEM; | 2359 | return -ENOMEM; |
2360 | } | 2360 | } |
@@ -2398,7 +2398,7 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, | |||
2398 | /* Copy the packet into the IB, the parser will read from the | 2398 | /* Copy the packet into the IB, the parser will read from the |
2399 | * input memory (cached) and write to the IB (which can be | 2399 | * input memory (cached) and write to the IB (which can be |
2400 | * uncached). */ | 2400 | * uncached). */ |
2401 | ib_chunk = &parser.chunks[parser.chunk_ib_idx]; | 2401 | ib_chunk = parser.chunk_ib; |
2402 | parser.ib.length_dw = ib_chunk->length_dw; | 2402 | parser.ib.length_dw = ib_chunk->length_dw; |
2403 | *l = parser.ib.length_dw; | 2403 | *l = parser.ib.length_dw; |
2404 | if (copy_from_user(ib, ib_chunk->user_ptr, ib_chunk->length_dw * 4)) { | 2404 | if (copy_from_user(ib, ib_chunk->user_ptr, ib_chunk->length_dw * 4)) { |
@@ -2435,24 +2435,24 @@ void r600_cs_legacy_init(void) | |||
2435 | * GPU offset using the provided start. | 2435 | * GPU offset using the provided start. |
2436 | **/ | 2436 | **/ |
2437 | int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, | 2437 | int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, |
2438 | struct radeon_cs_reloc **cs_reloc) | 2438 | struct radeon_bo_list **cs_reloc) |
2439 | { | 2439 | { |
2440 | struct radeon_cs_chunk *relocs_chunk; | 2440 | struct radeon_cs_chunk *relocs_chunk; |
2441 | unsigned idx; | 2441 | unsigned idx; |
2442 | 2442 | ||
2443 | *cs_reloc = NULL; | 2443 | *cs_reloc = NULL; |
2444 | if (p->chunk_relocs_idx == -1) { | 2444 | if (p->chunk_relocs == NULL) { |
2445 | DRM_ERROR("No relocation chunk !\n"); | 2445 | DRM_ERROR("No relocation chunk !\n"); |
2446 | return -EINVAL; | 2446 | return -EINVAL; |
2447 | } | 2447 | } |
2448 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | 2448 | relocs_chunk = p->chunk_relocs; |
2449 | idx = p->dma_reloc_idx; | 2449 | idx = p->dma_reloc_idx; |
2450 | if (idx >= p->nrelocs) { | 2450 | if (idx >= p->nrelocs) { |
2451 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", | 2451 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", |
2452 | idx, p->nrelocs); | 2452 | idx, p->nrelocs); |
2453 | return -EINVAL; | 2453 | return -EINVAL; |
2454 | } | 2454 | } |
2455 | *cs_reloc = p->relocs_ptr[idx]; | 2455 | *cs_reloc = &p->relocs[idx]; |
2456 | p->dma_reloc_idx++; | 2456 | p->dma_reloc_idx++; |
2457 | return 0; | 2457 | return 0; |
2458 | } | 2458 | } |
@@ -2472,8 +2472,8 @@ int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, | |||
2472 | **/ | 2472 | **/ |
2473 | int r600_dma_cs_parse(struct radeon_cs_parser *p) | 2473 | int r600_dma_cs_parse(struct radeon_cs_parser *p) |
2474 | { | 2474 | { |
2475 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; | 2475 | struct radeon_cs_chunk *ib_chunk = p->chunk_ib; |
2476 | struct radeon_cs_reloc *src_reloc, *dst_reloc; | 2476 | struct radeon_bo_list *src_reloc, *dst_reloc; |
2477 | u32 header, cmd, count, tiled; | 2477 | u32 header, cmd, count, tiled; |
2478 | volatile u32 *ib = p->ib.ptr; | 2478 | volatile u32 *ib = p->ib.ptr; |
2479 | u32 idx, idx_value; | 2479 | u32 idx, idx_value; |
@@ -2619,7 +2619,7 @@ int r600_dma_cs_parse(struct radeon_cs_parser *p) | |||
2619 | DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx); | 2619 | DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx); |
2620 | return -EINVAL; | 2620 | return -EINVAL; |
2621 | } | 2621 | } |
2622 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); | 2622 | } while (p->idx < p->chunk_ib->length_dw); |
2623 | #if 0 | 2623 | #if 0 |
2624 | for (r = 0; r < p->ib->length_dw; r++) { | 2624 | for (r = 0; r < p->ib->length_dw; r++) { |
2625 | printk(KERN_INFO "%05d 0x%08X\n", r, p->ib.ptr[r]); | 2625 | printk(KERN_INFO "%05d 0x%08X\n", r, p->ib.ptr[r]); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3207bb60715e..54529b837afa 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -450,6 +450,15 @@ struct radeon_mman { | |||
450 | #endif | 450 | #endif |
451 | }; | 451 | }; |
452 | 452 | ||
453 | struct radeon_bo_list { | ||
454 | struct radeon_bo *robj; | ||
455 | struct ttm_validate_buffer tv; | ||
456 | uint64_t gpu_offset; | ||
457 | unsigned prefered_domains; | ||
458 | unsigned allowed_domains; | ||
459 | uint32_t tiling_flags; | ||
460 | }; | ||
461 | |||
453 | /* bo virtual address in a specific vm */ | 462 | /* bo virtual address in a specific vm */ |
454 | struct radeon_bo_va { | 463 | struct radeon_bo_va { |
455 | /* protected by bo being reserved */ | 464 | /* protected by bo being reserved */ |
@@ -920,6 +929,9 @@ struct radeon_vm { | |||
920 | 929 | ||
921 | struct rb_root va; | 930 | struct rb_root va; |
922 | 931 | ||
932 | /* protecting invalidated and freed */ | ||
933 | spinlock_t status_lock; | ||
934 | |||
923 | /* BOs moved, but not yet updated in the PT */ | 935 | /* BOs moved, but not yet updated in the PT */ |
924 | struct list_head invalidated; | 936 | struct list_head invalidated; |
925 | 937 | ||
@@ -1044,19 +1056,7 @@ void cayman_dma_fini(struct radeon_device *rdev); | |||
1044 | /* | 1056 | /* |
1045 | * CS. | 1057 | * CS. |
1046 | */ | 1058 | */ |
1047 | struct radeon_cs_reloc { | ||
1048 | struct drm_gem_object *gobj; | ||
1049 | struct radeon_bo *robj; | ||
1050 | struct ttm_validate_buffer tv; | ||
1051 | uint64_t gpu_offset; | ||
1052 | unsigned prefered_domains; | ||
1053 | unsigned allowed_domains; | ||
1054 | uint32_t tiling_flags; | ||
1055 | uint32_t handle; | ||
1056 | }; | ||
1057 | |||
1058 | struct radeon_cs_chunk { | 1059 | struct radeon_cs_chunk { |
1059 | uint32_t chunk_id; | ||
1060 | uint32_t length_dw; | 1060 | uint32_t length_dw; |
1061 | uint32_t *kdata; | 1061 | uint32_t *kdata; |
1062 | void __user *user_ptr; | 1062 | void __user *user_ptr; |
@@ -1074,16 +1074,15 @@ struct radeon_cs_parser { | |||
1074 | unsigned idx; | 1074 | unsigned idx; |
1075 | /* relocations */ | 1075 | /* relocations */ |
1076 | unsigned nrelocs; | 1076 | unsigned nrelocs; |
1077 | struct radeon_cs_reloc *relocs; | 1077 | struct radeon_bo_list *relocs; |
1078 | struct radeon_cs_reloc **relocs_ptr; | 1078 | struct radeon_bo_list *vm_bos; |
1079 | struct radeon_cs_reloc *vm_bos; | ||
1080 | struct list_head validated; | 1079 | struct list_head validated; |
1081 | unsigned dma_reloc_idx; | 1080 | unsigned dma_reloc_idx; |
1082 | /* indices of various chunks */ | 1081 | /* indices of various chunks */ |
1083 | int chunk_ib_idx; | 1082 | struct radeon_cs_chunk *chunk_ib; |
1084 | int chunk_relocs_idx; | 1083 | struct radeon_cs_chunk *chunk_relocs; |
1085 | int chunk_flags_idx; | 1084 | struct radeon_cs_chunk *chunk_flags; |
1086 | int chunk_const_ib_idx; | 1085 | struct radeon_cs_chunk *chunk_const_ib; |
1087 | struct radeon_ib ib; | 1086 | struct radeon_ib ib; |
1088 | struct radeon_ib const_ib; | 1087 | struct radeon_ib const_ib; |
1089 | void *track; | 1088 | void *track; |
@@ -1097,7 +1096,7 @@ struct radeon_cs_parser { | |||
1097 | 1096 | ||
1098 | static inline u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) | 1097 | static inline u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) |
1099 | { | 1098 | { |
1100 | struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; | 1099 | struct radeon_cs_chunk *ibc = p->chunk_ib; |
1101 | 1100 | ||
1102 | if (ibc->kdata) | 1101 | if (ibc->kdata) |
1103 | return ibc->kdata[idx]; | 1102 | return ibc->kdata[idx]; |
@@ -2975,7 +2974,7 @@ int radeon_vm_manager_init(struct radeon_device *rdev); | |||
2975 | void radeon_vm_manager_fini(struct radeon_device *rdev); | 2974 | void radeon_vm_manager_fini(struct radeon_device *rdev); |
2976 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); | 2975 | int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); |
2977 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); | 2976 | void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); |
2978 | struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, | 2977 | struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev, |
2979 | struct radeon_vm *vm, | 2978 | struct radeon_vm *vm, |
2980 | struct list_head *head); | 2979 | struct list_head *head); |
2981 | struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, | 2980 | struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, |
@@ -3089,7 +3088,7 @@ bool radeon_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p); | |||
3089 | void radeon_cs_dump_packet(struct radeon_cs_parser *p, | 3088 | void radeon_cs_dump_packet(struct radeon_cs_parser *p, |
3090 | struct radeon_cs_packet *pkt); | 3089 | struct radeon_cs_packet *pkt); |
3091 | int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, | 3090 | int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, |
3092 | struct radeon_cs_reloc **cs_reloc, | 3091 | struct radeon_bo_list **cs_reloc, |
3093 | int nomm); | 3092 | int nomm); |
3094 | int r600_cs_common_vline_parse(struct radeon_cs_parser *p, | 3093 | int r600_cs_common_vline_parse(struct radeon_cs_parser *p, |
3095 | uint32_t *vline_start_end, | 3094 | uint32_t *vline_start_end, |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 75f22e5e999f..9648e28c4501 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -77,22 +77,18 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) | |||
77 | struct drm_device *ddev = p->rdev->ddev; | 77 | struct drm_device *ddev = p->rdev->ddev; |
78 | struct radeon_cs_chunk *chunk; | 78 | struct radeon_cs_chunk *chunk; |
79 | struct radeon_cs_buckets buckets; | 79 | struct radeon_cs_buckets buckets; |
80 | unsigned i, j; | 80 | unsigned i; |
81 | bool duplicate, need_mmap_lock = false; | 81 | bool need_mmap_lock = false; |
82 | int r; | 82 | int r; |
83 | 83 | ||
84 | if (p->chunk_relocs_idx == -1) { | 84 | if (p->chunk_relocs == NULL) { |
85 | return 0; | 85 | return 0; |
86 | } | 86 | } |
87 | chunk = &p->chunks[p->chunk_relocs_idx]; | 87 | chunk = p->chunk_relocs; |
88 | p->dma_reloc_idx = 0; | 88 | p->dma_reloc_idx = 0; |
89 | /* FIXME: we assume that each relocs use 4 dwords */ | 89 | /* FIXME: we assume that each relocs use 4 dwords */ |
90 | p->nrelocs = chunk->length_dw / 4; | 90 | p->nrelocs = chunk->length_dw / 4; |
91 | p->relocs_ptr = kcalloc(p->nrelocs, sizeof(void *), GFP_KERNEL); | 91 | p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_bo_list), GFP_KERNEL); |
92 | if (p->relocs_ptr == NULL) { | ||
93 | return -ENOMEM; | ||
94 | } | ||
95 | p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_cs_reloc), GFP_KERNEL); | ||
96 | if (p->relocs == NULL) { | 92 | if (p->relocs == NULL) { |
97 | return -ENOMEM; | 93 | return -ENOMEM; |
98 | } | 94 | } |
@@ -101,31 +97,17 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) | |||
101 | 97 | ||
102 | for (i = 0; i < p->nrelocs; i++) { | 98 | for (i = 0; i < p->nrelocs; i++) { |
103 | struct drm_radeon_cs_reloc *r; | 99 | struct drm_radeon_cs_reloc *r; |
100 | struct drm_gem_object *gobj; | ||
104 | unsigned priority; | 101 | unsigned priority; |
105 | 102 | ||
106 | duplicate = false; | ||
107 | r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4]; | 103 | r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4]; |
108 | for (j = 0; j < i; j++) { | 104 | gobj = drm_gem_object_lookup(ddev, p->filp, r->handle); |
109 | if (r->handle == p->relocs[j].handle) { | 105 | if (gobj == NULL) { |
110 | p->relocs_ptr[i] = &p->relocs[j]; | ||
111 | duplicate = true; | ||
112 | break; | ||
113 | } | ||
114 | } | ||
115 | if (duplicate) { | ||
116 | p->relocs[i].handle = 0; | ||
117 | continue; | ||
118 | } | ||
119 | |||
120 | p->relocs[i].gobj = drm_gem_object_lookup(ddev, p->filp, | ||
121 | r->handle); | ||
122 | if (p->relocs[i].gobj == NULL) { | ||
123 | DRM_ERROR("gem object lookup failed 0x%x\n", | 106 | DRM_ERROR("gem object lookup failed 0x%x\n", |
124 | r->handle); | 107 | r->handle); |
125 | return -ENOENT; | 108 | return -ENOENT; |
126 | } | 109 | } |
127 | p->relocs_ptr[i] = &p->relocs[i]; | 110 | p->relocs[i].robj = gem_to_radeon_bo(gobj); |
128 | p->relocs[i].robj = gem_to_radeon_bo(p->relocs[i].gobj); | ||
129 | 111 | ||
130 | /* The userspace buffer priorities are from 0 to 15. A higher | 112 | /* The userspace buffer priorities are from 0 to 15. A higher |
131 | * number means the buffer is more important. | 113 | * number means the buffer is more important. |
@@ -184,7 +166,6 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) | |||
184 | 166 | ||
185 | p->relocs[i].tv.bo = &p->relocs[i].robj->tbo; | 167 | p->relocs[i].tv.bo = &p->relocs[i].robj->tbo; |
186 | p->relocs[i].tv.shared = !r->write_domain; | 168 | p->relocs[i].tv.shared = !r->write_domain; |
187 | p->relocs[i].handle = r->handle; | ||
188 | 169 | ||
189 | radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head, | 170 | radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head, |
190 | priority); | 171 | priority); |
@@ -251,22 +232,20 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority | |||
251 | 232 | ||
252 | static int radeon_cs_sync_rings(struct radeon_cs_parser *p) | 233 | static int radeon_cs_sync_rings(struct radeon_cs_parser *p) |
253 | { | 234 | { |
254 | int i, r = 0; | 235 | struct radeon_bo_list *reloc; |
236 | int r; | ||
255 | 237 | ||
256 | for (i = 0; i < p->nrelocs; i++) { | 238 | list_for_each_entry(reloc, &p->validated, tv.head) { |
257 | struct reservation_object *resv; | 239 | struct reservation_object *resv; |
258 | 240 | ||
259 | if (!p->relocs[i].robj) | 241 | resv = reloc->robj->tbo.resv; |
260 | continue; | ||
261 | |||
262 | resv = p->relocs[i].robj->tbo.resv; | ||
263 | r = radeon_sync_resv(p->rdev, &p->ib.sync, resv, | 242 | r = radeon_sync_resv(p->rdev, &p->ib.sync, resv, |
264 | p->relocs[i].tv.shared); | 243 | reloc->tv.shared); |
265 | 244 | ||
266 | if (r) | 245 | if (r) |
267 | break; | 246 | return r; |
268 | } | 247 | } |
269 | return r; | 248 | return 0; |
270 | } | 249 | } |
271 | 250 | ||
272 | /* XXX: note that this is called from the legacy UMS CS ioctl as well */ | 251 | /* XXX: note that this is called from the legacy UMS CS ioctl as well */ |
@@ -286,10 +265,10 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
286 | p->idx = 0; | 265 | p->idx = 0; |
287 | p->ib.sa_bo = NULL; | 266 | p->ib.sa_bo = NULL; |
288 | p->const_ib.sa_bo = NULL; | 267 | p->const_ib.sa_bo = NULL; |
289 | p->chunk_ib_idx = -1; | 268 | p->chunk_ib = NULL; |
290 | p->chunk_relocs_idx = -1; | 269 | p->chunk_relocs = NULL; |
291 | p->chunk_flags_idx = -1; | 270 | p->chunk_flags = NULL; |
292 | p->chunk_const_ib_idx = -1; | 271 | p->chunk_const_ib = NULL; |
293 | p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL); | 272 | p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL); |
294 | if (p->chunks_array == NULL) { | 273 | if (p->chunks_array == NULL) { |
295 | return -ENOMEM; | 274 | return -ENOMEM; |
@@ -316,24 +295,23 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
316 | return -EFAULT; | 295 | return -EFAULT; |
317 | } | 296 | } |
318 | p->chunks[i].length_dw = user_chunk.length_dw; | 297 | p->chunks[i].length_dw = user_chunk.length_dw; |
319 | p->chunks[i].chunk_id = user_chunk.chunk_id; | 298 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_RELOCS) { |
320 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) { | 299 | p->chunk_relocs = &p->chunks[i]; |
321 | p->chunk_relocs_idx = i; | ||
322 | } | 300 | } |
323 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_IB) { | 301 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_IB) { |
324 | p->chunk_ib_idx = i; | 302 | p->chunk_ib = &p->chunks[i]; |
325 | /* zero length IB isn't useful */ | 303 | /* zero length IB isn't useful */ |
326 | if (p->chunks[i].length_dw == 0) | 304 | if (p->chunks[i].length_dw == 0) |
327 | return -EINVAL; | 305 | return -EINVAL; |
328 | } | 306 | } |
329 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_CONST_IB) { | 307 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_CONST_IB) { |
330 | p->chunk_const_ib_idx = i; | 308 | p->chunk_const_ib = &p->chunks[i]; |
331 | /* zero length CONST IB isn't useful */ | 309 | /* zero length CONST IB isn't useful */ |
332 | if (p->chunks[i].length_dw == 0) | 310 | if (p->chunks[i].length_dw == 0) |
333 | return -EINVAL; | 311 | return -EINVAL; |
334 | } | 312 | } |
335 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { | 313 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_FLAGS) { |
336 | p->chunk_flags_idx = i; | 314 | p->chunk_flags = &p->chunks[i]; |
337 | /* zero length flags aren't useful */ | 315 | /* zero length flags aren't useful */ |
338 | if (p->chunks[i].length_dw == 0) | 316 | if (p->chunks[i].length_dw == 0) |
339 | return -EINVAL; | 317 | return -EINVAL; |
@@ -342,10 +320,10 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
342 | size = p->chunks[i].length_dw; | 320 | size = p->chunks[i].length_dw; |
343 | cdata = (void __user *)(unsigned long)user_chunk.chunk_data; | 321 | cdata = (void __user *)(unsigned long)user_chunk.chunk_data; |
344 | p->chunks[i].user_ptr = cdata; | 322 | p->chunks[i].user_ptr = cdata; |
345 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_CONST_IB) | 323 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_CONST_IB) |
346 | continue; | 324 | continue; |
347 | 325 | ||
348 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_IB) { | 326 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_IB) { |
349 | if (!p->rdev || !(p->rdev->flags & RADEON_IS_AGP)) | 327 | if (!p->rdev || !(p->rdev->flags & RADEON_IS_AGP)) |
350 | continue; | 328 | continue; |
351 | } | 329 | } |
@@ -358,7 +336,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
358 | if (copy_from_user(p->chunks[i].kdata, cdata, size)) { | 336 | if (copy_from_user(p->chunks[i].kdata, cdata, size)) { |
359 | return -EFAULT; | 337 | return -EFAULT; |
360 | } | 338 | } |
361 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { | 339 | if (user_chunk.chunk_id == RADEON_CHUNK_ID_FLAGS) { |
362 | p->cs_flags = p->chunks[i].kdata[0]; | 340 | p->cs_flags = p->chunks[i].kdata[0]; |
363 | if (p->chunks[i].length_dw > 1) | 341 | if (p->chunks[i].length_dw > 1) |
364 | ring = p->chunks[i].kdata[1]; | 342 | ring = p->chunks[i].kdata[1]; |
@@ -399,8 +377,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
399 | static int cmp_size_smaller_first(void *priv, struct list_head *a, | 377 | static int cmp_size_smaller_first(void *priv, struct list_head *a, |
400 | struct list_head *b) | 378 | struct list_head *b) |
401 | { | 379 | { |
402 | struct radeon_cs_reloc *la = list_entry(a, struct radeon_cs_reloc, tv.head); | 380 | struct radeon_bo_list *la = list_entry(a, struct radeon_bo_list, tv.head); |
403 | struct radeon_cs_reloc *lb = list_entry(b, struct radeon_cs_reloc, tv.head); | 381 | struct radeon_bo_list *lb = list_entry(b, struct radeon_bo_list, tv.head); |
404 | 382 | ||
405 | /* Sort A before B if A is smaller. */ | 383 | /* Sort A before B if A is smaller. */ |
406 | return (int)la->robj->tbo.num_pages - (int)lb->robj->tbo.num_pages; | 384 | return (int)la->robj->tbo.num_pages - (int)lb->robj->tbo.num_pages; |
@@ -441,13 +419,15 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo | |||
441 | 419 | ||
442 | if (parser->relocs != NULL) { | 420 | if (parser->relocs != NULL) { |
443 | for (i = 0; i < parser->nrelocs; i++) { | 421 | for (i = 0; i < parser->nrelocs; i++) { |
444 | if (parser->relocs[i].gobj) | 422 | struct radeon_bo *bo = parser->relocs[i].robj; |
445 | drm_gem_object_unreference_unlocked(parser->relocs[i].gobj); | 423 | if (bo == NULL) |
424 | continue; | ||
425 | |||
426 | drm_gem_object_unreference_unlocked(&bo->gem_base); | ||
446 | } | 427 | } |
447 | } | 428 | } |
448 | kfree(parser->track); | 429 | kfree(parser->track); |
449 | kfree(parser->relocs); | 430 | kfree(parser->relocs); |
450 | kfree(parser->relocs_ptr); | ||
451 | drm_free_large(parser->vm_bos); | 431 | drm_free_large(parser->vm_bos); |
452 | for (i = 0; i < parser->nchunks; i++) | 432 | for (i = 0; i < parser->nchunks; i++) |
453 | drm_free_large(parser->chunks[i].kdata); | 433 | drm_free_large(parser->chunks[i].kdata); |
@@ -462,7 +442,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, | |||
462 | { | 442 | { |
463 | int r; | 443 | int r; |
464 | 444 | ||
465 | if (parser->chunk_ib_idx == -1) | 445 | if (parser->chunk_ib == NULL) |
466 | return 0; | 446 | return 0; |
467 | 447 | ||
468 | if (parser->cs_flags & RADEON_CS_USE_VM) | 448 | if (parser->cs_flags & RADEON_CS_USE_VM) |
@@ -505,9 +485,6 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p, | |||
505 | if (r) | 485 | if (r) |
506 | return r; | 486 | return r; |
507 | 487 | ||
508 | radeon_sync_resv(p->rdev, &p->ib.sync, vm->page_directory->tbo.resv, | ||
509 | true); | ||
510 | |||
511 | r = radeon_vm_clear_freed(rdev, vm); | 488 | r = radeon_vm_clear_freed(rdev, vm); |
512 | if (r) | 489 | if (r) |
513 | return r; | 490 | return r; |
@@ -525,10 +502,6 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p, | |||
525 | for (i = 0; i < p->nrelocs; i++) { | 502 | for (i = 0; i < p->nrelocs; i++) { |
526 | struct radeon_bo *bo; | 503 | struct radeon_bo *bo; |
527 | 504 | ||
528 | /* ignore duplicates */ | ||
529 | if (p->relocs_ptr[i] != &p->relocs[i]) | ||
530 | continue; | ||
531 | |||
532 | bo = p->relocs[i].robj; | 505 | bo = p->relocs[i].robj; |
533 | bo_va = radeon_vm_bo_find(vm, bo); | 506 | bo_va = radeon_vm_bo_find(vm, bo); |
534 | if (bo_va == NULL) { | 507 | if (bo_va == NULL) { |
@@ -553,7 +526,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
553 | struct radeon_vm *vm = &fpriv->vm; | 526 | struct radeon_vm *vm = &fpriv->vm; |
554 | int r; | 527 | int r; |
555 | 528 | ||
556 | if (parser->chunk_ib_idx == -1) | 529 | if (parser->chunk_ib == NULL) |
557 | return 0; | 530 | return 0; |
558 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) | 531 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) |
559 | return 0; | 532 | return 0; |
@@ -587,7 +560,7 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
587 | } | 560 | } |
588 | 561 | ||
589 | if ((rdev->family >= CHIP_TAHITI) && | 562 | if ((rdev->family >= CHIP_TAHITI) && |
590 | (parser->chunk_const_ib_idx != -1)) { | 563 | (parser->chunk_const_ib != NULL)) { |
591 | r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib, true); | 564 | r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib, true); |
592 | } else { | 565 | } else { |
593 | r = radeon_ib_schedule(rdev, &parser->ib, NULL, true); | 566 | r = radeon_ib_schedule(rdev, &parser->ib, NULL, true); |
@@ -614,7 +587,7 @@ static int radeon_cs_ib_fill(struct radeon_device *rdev, struct radeon_cs_parser | |||
614 | struct radeon_vm *vm = NULL; | 587 | struct radeon_vm *vm = NULL; |
615 | int r; | 588 | int r; |
616 | 589 | ||
617 | if (parser->chunk_ib_idx == -1) | 590 | if (parser->chunk_ib == NULL) |
618 | return 0; | 591 | return 0; |
619 | 592 | ||
620 | if (parser->cs_flags & RADEON_CS_USE_VM) { | 593 | if (parser->cs_flags & RADEON_CS_USE_VM) { |
@@ -622,8 +595,8 @@ static int radeon_cs_ib_fill(struct radeon_device *rdev, struct radeon_cs_parser | |||
622 | vm = &fpriv->vm; | 595 | vm = &fpriv->vm; |
623 | 596 | ||
624 | if ((rdev->family >= CHIP_TAHITI) && | 597 | if ((rdev->family >= CHIP_TAHITI) && |
625 | (parser->chunk_const_ib_idx != -1)) { | 598 | (parser->chunk_const_ib != NULL)) { |
626 | ib_chunk = &parser->chunks[parser->chunk_const_ib_idx]; | 599 | ib_chunk = parser->chunk_const_ib; |
627 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { | 600 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { |
628 | DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw); | 601 | DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw); |
629 | return -EINVAL; | 602 | return -EINVAL; |
@@ -642,13 +615,13 @@ static int radeon_cs_ib_fill(struct radeon_device *rdev, struct radeon_cs_parser | |||
642 | return -EFAULT; | 615 | return -EFAULT; |
643 | } | 616 | } |
644 | 617 | ||
645 | ib_chunk = &parser->chunks[parser->chunk_ib_idx]; | 618 | ib_chunk = parser->chunk_ib; |
646 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { | 619 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { |
647 | DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw); | 620 | DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw); |
648 | return -EINVAL; | 621 | return -EINVAL; |
649 | } | 622 | } |
650 | } | 623 | } |
651 | ib_chunk = &parser->chunks[parser->chunk_ib_idx]; | 624 | ib_chunk = parser->chunk_ib; |
652 | 625 | ||
653 | r = radeon_ib_get(rdev, parser->ring, &parser->ib, | 626 | r = radeon_ib_get(rdev, parser->ring, &parser->ib, |
654 | vm, ib_chunk->length_dw * 4); | 627 | vm, ib_chunk->length_dw * 4); |
@@ -740,7 +713,7 @@ int radeon_cs_packet_parse(struct radeon_cs_parser *p, | |||
740 | struct radeon_cs_packet *pkt, | 713 | struct radeon_cs_packet *pkt, |
741 | unsigned idx) | 714 | unsigned idx) |
742 | { | 715 | { |
743 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; | 716 | struct radeon_cs_chunk *ib_chunk = p->chunk_ib; |
744 | struct radeon_device *rdev = p->rdev; | 717 | struct radeon_device *rdev = p->rdev; |
745 | uint32_t header; | 718 | uint32_t header; |
746 | 719 | ||
@@ -834,7 +807,7 @@ void radeon_cs_dump_packet(struct radeon_cs_parser *p, | |||
834 | * GPU offset using the provided start. | 807 | * GPU offset using the provided start. |
835 | **/ | 808 | **/ |
836 | int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, | 809 | int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, |
837 | struct radeon_cs_reloc **cs_reloc, | 810 | struct radeon_bo_list **cs_reloc, |
838 | int nomm) | 811 | int nomm) |
839 | { | 812 | { |
840 | struct radeon_cs_chunk *relocs_chunk; | 813 | struct radeon_cs_chunk *relocs_chunk; |
@@ -842,12 +815,12 @@ int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, | |||
842 | unsigned idx; | 815 | unsigned idx; |
843 | int r; | 816 | int r; |
844 | 817 | ||
845 | if (p->chunk_relocs_idx == -1) { | 818 | if (p->chunk_relocs == NULL) { |
846 | DRM_ERROR("No relocation chunk !\n"); | 819 | DRM_ERROR("No relocation chunk !\n"); |
847 | return -EINVAL; | 820 | return -EINVAL; |
848 | } | 821 | } |
849 | *cs_reloc = NULL; | 822 | *cs_reloc = NULL; |
850 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | 823 | relocs_chunk = p->chunk_relocs; |
851 | r = radeon_cs_packet_parse(p, &p3reloc, p->idx); | 824 | r = radeon_cs_packet_parse(p, &p3reloc, p->idx); |
852 | if (r) | 825 | if (r) |
853 | return r; | 826 | return r; |
@@ -873,6 +846,6 @@ int radeon_cs_packet_next_reloc(struct radeon_cs_parser *p, | |||
873 | (u64)relocs_chunk->kdata[idx + 3] << 32; | 846 | (u64)relocs_chunk->kdata[idx + 3] << 32; |
874 | (*cs_reloc)->gpu_offset |= relocs_chunk->kdata[idx + 0]; | 847 | (*cs_reloc)->gpu_offset |= relocs_chunk->kdata[idx + 0]; |
875 | } else | 848 | } else |
876 | *cs_reloc = p->relocs_ptr[(idx / 4)]; | 849 | *cs_reloc = &p->relocs[(idx / 4)]; |
877 | return 0; | 850 | return 0; |
878 | } | 851 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 85f38ee11888..45e54060ee97 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
@@ -227,11 +227,24 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, | |||
227 | return ret; | 227 | return ret; |
228 | } | 228 | } |
229 | 229 | ||
230 | static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, | 230 | static int radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj) |
231 | uint64_t gpu_addr, int hot_x, int hot_y) | ||
232 | { | 231 | { |
233 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 232 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
234 | struct radeon_device *rdev = crtc->dev->dev_private; | 233 | struct radeon_device *rdev = crtc->dev->dev_private; |
234 | struct radeon_bo *robj = gem_to_radeon_bo(obj); | ||
235 | uint64_t gpu_addr; | ||
236 | int ret; | ||
237 | |||
238 | ret = radeon_bo_reserve(robj, false); | ||
239 | if (unlikely(ret != 0)) | ||
240 | goto fail; | ||
241 | /* Only 27 bit offset for legacy cursor */ | ||
242 | ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, | ||
243 | ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, | ||
244 | &gpu_addr); | ||
245 | radeon_bo_unreserve(robj); | ||
246 | if (ret) | ||
247 | goto fail; | ||
235 | 248 | ||
236 | if (ASIC_IS_DCE4(rdev)) { | 249 | if (ASIC_IS_DCE4(rdev)) { |
237 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, | 250 | WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, |
@@ -253,18 +266,12 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, | |||
253 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); | 266 | WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); |
254 | } | 267 | } |
255 | 268 | ||
256 | if (hot_x != radeon_crtc->cursor_hot_x || | 269 | return 0; |
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 | 270 | ||
263 | radeon_cursor_move_locked(crtc, x, y); | 271 | fail: |
272 | drm_gem_object_unreference_unlocked(obj); | ||
264 | 273 | ||
265 | radeon_crtc->cursor_hot_x = hot_x; | 274 | return ret; |
266 | radeon_crtc->cursor_hot_y = hot_y; | ||
267 | } | ||
268 | } | 275 | } |
269 | 276 | ||
270 | int radeon_crtc_cursor_set2(struct drm_crtc *crtc, | 277 | int radeon_crtc_cursor_set2(struct drm_crtc *crtc, |
@@ -276,10 +283,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, | |||
276 | int32_t hot_y) | 283 | int32_t hot_y) |
277 | { | 284 | { |
278 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 285 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
279 | struct radeon_device *rdev = crtc->dev->dev_private; | ||
280 | struct drm_gem_object *obj; | 286 | struct drm_gem_object *obj; |
281 | struct radeon_bo *robj; | ||
282 | uint64_t gpu_addr; | ||
283 | int ret; | 287 | int ret; |
284 | 288 | ||
285 | if (!handle) { | 289 | if (!handle) { |
@@ -301,41 +305,76 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, | |||
301 | return -ENOENT; | 305 | return -ENOENT; |
302 | } | 306 | } |
303 | 307 | ||
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; | 308 | radeon_crtc->cursor_width = width; |
317 | radeon_crtc->cursor_height = height; | 309 | radeon_crtc->cursor_height = height; |
318 | 310 | ||
319 | radeon_lock_cursor(crtc, true); | 311 | radeon_lock_cursor(crtc, true); |
320 | radeon_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y); | 312 | |
321 | radeon_show_cursor(crtc); | 313 | if (hot_x != radeon_crtc->cursor_hot_x || |
314 | hot_y != radeon_crtc->cursor_hot_y) { | ||
315 | int x, y; | ||
316 | |||
317 | x = radeon_crtc->cursor_x + radeon_crtc->cursor_hot_x - hot_x; | ||
318 | y = radeon_crtc->cursor_y + radeon_crtc->cursor_hot_y - hot_y; | ||
319 | |||
320 | radeon_cursor_move_locked(crtc, x, y); | ||
321 | |||
322 | radeon_crtc->cursor_hot_x = hot_x; | ||
323 | radeon_crtc->cursor_hot_y = hot_y; | ||
324 | } | ||
325 | |||
326 | ret = radeon_set_cursor(crtc, obj); | ||
327 | |||
328 | if (ret) | ||
329 | DRM_ERROR("radeon_set_cursor returned %d, not changing cursor\n", | ||
330 | ret); | ||
331 | else | ||
332 | radeon_show_cursor(crtc); | ||
333 | |||
322 | radeon_lock_cursor(crtc, false); | 334 | radeon_lock_cursor(crtc, false); |
323 | 335 | ||
324 | unpin: | 336 | unpin: |
325 | if (radeon_crtc->cursor_bo) { | 337 | if (radeon_crtc->cursor_bo) { |
326 | robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); | 338 | struct radeon_bo *robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); |
327 | ret = radeon_bo_reserve(robj, false); | 339 | ret = radeon_bo_reserve(robj, false); |
328 | if (likely(ret == 0)) { | 340 | if (likely(ret == 0)) { |
329 | radeon_bo_unpin(robj); | 341 | radeon_bo_unpin(robj); |
330 | radeon_bo_unreserve(robj); | 342 | radeon_bo_unreserve(robj); |
331 | } | 343 | } |
332 | drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); | 344 | if (radeon_crtc->cursor_bo != obj) |
345 | drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); | ||
333 | } | 346 | } |
334 | 347 | ||
335 | radeon_crtc->cursor_bo = obj; | 348 | radeon_crtc->cursor_bo = obj; |
336 | return 0; | 349 | return 0; |
337 | fail: | 350 | } |
338 | drm_gem_object_unreference_unlocked(obj); | ||
339 | 351 | ||
340 | return ret; | 352 | /** |
353 | * radeon_cursor_reset - Re-set the current cursor, if any. | ||
354 | * | ||
355 | * @crtc: drm crtc | ||
356 | * | ||
357 | * If the CRTC passed in currently has a cursor assigned, this function | ||
358 | * makes sure it's visible. | ||
359 | */ | ||
360 | void radeon_cursor_reset(struct drm_crtc *crtc) | ||
361 | { | ||
362 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
363 | int ret; | ||
364 | |||
365 | if (radeon_crtc->cursor_bo) { | ||
366 | radeon_lock_cursor(crtc, true); | ||
367 | |||
368 | radeon_cursor_move_locked(crtc, radeon_crtc->cursor_x, | ||
369 | radeon_crtc->cursor_y); | ||
370 | |||
371 | ret = radeon_set_cursor(crtc, radeon_crtc->cursor_bo); | ||
372 | if (ret) | ||
373 | DRM_ERROR("radeon_set_cursor returned %d, not showing " | ||
374 | "cursor\n", ret); | ||
375 | else | ||
376 | radeon_show_cursor(crtc); | ||
377 | |||
378 | radeon_lock_cursor(crtc, false); | ||
379 | } | ||
341 | } | 380 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 0ea1db83d573..29b9220ec399 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -48,10 +48,40 @@ struct radeon_fbdev { | |||
48 | struct radeon_device *rdev; | 48 | struct radeon_device *rdev; |
49 | }; | 49 | }; |
50 | 50 | ||
51 | /** | ||
52 | * radeon_fb_helper_set_par - Hide cursor on CRTCs used by fbdev. | ||
53 | * | ||
54 | * @info: fbdev info | ||
55 | * | ||
56 | * This function hides the cursor on all CRTCs used by fbdev. | ||
57 | */ | ||
58 | static int radeon_fb_helper_set_par(struct fb_info *info) | ||
59 | { | ||
60 | int ret; | ||
61 | |||
62 | ret = drm_fb_helper_set_par(info); | ||
63 | |||
64 | /* XXX: with universal plane support fbdev will automatically disable | ||
65 | * all non-primary planes (including the cursor) | ||
66 | */ | ||
67 | if (ret == 0) { | ||
68 | struct drm_fb_helper *fb_helper = info->par; | ||
69 | int i; | ||
70 | |||
71 | for (i = 0; i < fb_helper->crtc_count; i++) { | ||
72 | struct drm_crtc *crtc = fb_helper->crtc_info[i].mode_set.crtc; | ||
73 | |||
74 | radeon_crtc_cursor_set2(crtc, NULL, 0, 0, 0, 0, 0); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | return ret; | ||
79 | } | ||
80 | |||
51 | static struct fb_ops radeonfb_ops = { | 81 | static struct fb_ops radeonfb_ops = { |
52 | .owner = THIS_MODULE, | 82 | .owner = THIS_MODULE, |
53 | .fb_check_var = drm_fb_helper_check_var, | 83 | .fb_check_var = drm_fb_helper_check_var, |
54 | .fb_set_par = drm_fb_helper_set_par, | 84 | .fb_set_par = radeon_fb_helper_set_par, |
55 | .fb_fillrect = cfb_fillrect, | 85 | .fb_fillrect = cfb_fillrect, |
56 | .fb_copyarea = cfb_copyarea, | 86 | .fb_copyarea = cfb_copyarea, |
57 | .fb_imageblit = cfb_imageblit, | 87 | .fb_imageblit = cfb_imageblit, |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 12cfaeac1205..fe48f229043e 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -548,7 +548,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, | |||
548 | struct radeon_bo_va *bo_va) | 548 | struct radeon_bo_va *bo_va) |
549 | { | 549 | { |
550 | struct ttm_validate_buffer tv, *entry; | 550 | struct ttm_validate_buffer tv, *entry; |
551 | struct radeon_cs_reloc *vm_bos; | 551 | struct radeon_bo_list *vm_bos; |
552 | struct ww_acquire_ctx ticket; | 552 | struct ww_acquire_ctx ticket; |
553 | struct list_head list; | 553 | struct list_head list; |
554 | unsigned domain; | 554 | unsigned domain; |
@@ -564,7 +564,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, | |||
564 | if (!vm_bos) | 564 | if (!vm_bos) |
565 | return; | 565 | return; |
566 | 566 | ||
567 | r = ttm_eu_reserve_buffers(&ticket, &list, true); | 567 | r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); |
568 | if (r) | 568 | if (r) |
569 | goto error_free; | 569 | goto error_free; |
570 | 570 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index cafb1ccf2ec3..678b4386540d 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -1054,6 +1054,7 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
1054 | DRM_ERROR("Mode need scaling but only first crtc can do that.\n"); | 1054 | DRM_ERROR("Mode need scaling but only first crtc can do that.\n"); |
1055 | } | 1055 | } |
1056 | } | 1056 | } |
1057 | radeon_cursor_reset(crtc); | ||
1057 | return 0; | 1058 | return 0; |
1058 | } | 1059 | } |
1059 | 1060 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index f3d87cdd5c9d..390db897f322 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -818,6 +818,7 @@ extern int radeon_crtc_cursor_set2(struct drm_crtc *crtc, | |||
818 | int32_t hot_y); | 818 | int32_t hot_y); |
819 | extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, | 819 | extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, |
820 | int x, int y); | 820 | int x, int y); |
821 | extern void radeon_cursor_reset(struct drm_crtc *crtc); | ||
821 | 822 | ||
822 | extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, | 823 | extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, |
823 | unsigned int flags, | 824 | unsigned int flags, |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 87b00d902bf7..0a8ef9ef1519 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -502,19 +502,20 @@ int radeon_bo_list_validate(struct radeon_device *rdev, | |||
502 | struct ww_acquire_ctx *ticket, | 502 | struct ww_acquire_ctx *ticket, |
503 | struct list_head *head, int ring) | 503 | struct list_head *head, int ring) |
504 | { | 504 | { |
505 | struct radeon_cs_reloc *lobj; | 505 | struct radeon_bo_list *lobj; |
506 | struct radeon_bo *bo; | 506 | struct list_head duplicates; |
507 | int r; | 507 | int r; |
508 | u64 bytes_moved = 0, initial_bytes_moved; | 508 | u64 bytes_moved = 0, initial_bytes_moved; |
509 | u64 bytes_moved_threshold = radeon_bo_get_threshold_for_moves(rdev); | 509 | u64 bytes_moved_threshold = radeon_bo_get_threshold_for_moves(rdev); |
510 | 510 | ||
511 | r = ttm_eu_reserve_buffers(ticket, head, true); | 511 | INIT_LIST_HEAD(&duplicates); |
512 | r = ttm_eu_reserve_buffers(ticket, head, true, &duplicates); | ||
512 | if (unlikely(r != 0)) { | 513 | if (unlikely(r != 0)) { |
513 | return r; | 514 | return r; |
514 | } | 515 | } |
515 | 516 | ||
516 | list_for_each_entry(lobj, head, tv.head) { | 517 | list_for_each_entry(lobj, head, tv.head) { |
517 | bo = lobj->robj; | 518 | struct radeon_bo *bo = lobj->robj; |
518 | if (!bo->pin_count) { | 519 | if (!bo->pin_count) { |
519 | u32 domain = lobj->prefered_domains; | 520 | u32 domain = lobj->prefered_domains; |
520 | u32 allowed = lobj->allowed_domains; | 521 | u32 allowed = lobj->allowed_domains; |
@@ -562,6 +563,12 @@ int radeon_bo_list_validate(struct radeon_device *rdev, | |||
562 | lobj->gpu_offset = radeon_bo_gpu_offset(bo); | 563 | lobj->gpu_offset = radeon_bo_gpu_offset(bo); |
563 | lobj->tiling_flags = bo->tiling_flags; | 564 | lobj->tiling_flags = bo->tiling_flags; |
564 | } | 565 | } |
566 | |||
567 | list_for_each_entry(lobj, &duplicates, tv.head) { | ||
568 | lobj->gpu_offset = radeon_bo_gpu_offset(lobj->robj); | ||
569 | lobj->tiling_flags = lobj->robj->tiling_flags; | ||
570 | } | ||
571 | |||
565 | return 0; | 572 | return 0; |
566 | } | 573 | } |
567 | 574 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h index 9db74a96ef61..ce075cb08cb2 100644 --- a/drivers/gpu/drm/radeon/radeon_trace.h +++ b/drivers/gpu/drm/radeon/radeon_trace.h | |||
@@ -38,7 +38,7 @@ TRACE_EVENT(radeon_cs, | |||
38 | 38 | ||
39 | TP_fast_assign( | 39 | TP_fast_assign( |
40 | __entry->ring = p->ring; | 40 | __entry->ring = p->ring; |
41 | __entry->dw = p->chunks[p->chunk_ib_idx].length_dw; | 41 | __entry->dw = p->chunk_ib->length_dw; |
42 | __entry->fences = radeon_fence_count_emitted( | 42 | __entry->fences = radeon_fence_count_emitted( |
43 | p->rdev, p->ring); | 43 | p->rdev, p->ring); |
44 | ), | 44 | ), |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index cbe7b32d181c..d02aa1d0f588 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -196,7 +196,7 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, | |||
196 | rbo = container_of(bo, struct radeon_bo, tbo); | 196 | rbo = container_of(bo, struct radeon_bo, tbo); |
197 | switch (bo->mem.mem_type) { | 197 | switch (bo->mem.mem_type) { |
198 | case TTM_PL_VRAM: | 198 | case TTM_PL_VRAM: |
199 | if (rbo->rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready == false) | 199 | if (rbo->rdev->ring[radeon_copy_ring_index(rbo->rdev)].ready == false) |
200 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); | 200 | radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); |
201 | else if (rbo->rdev->mc.visible_vram_size < rbo->rdev->mc.real_vram_size && | 201 | else if (rbo->rdev->mc.visible_vram_size < rbo->rdev->mc.real_vram_size && |
202 | bo->mem.start < (rbo->rdev->mc.visible_vram_size >> PAGE_SHIFT)) { | 202 | bo->mem.start < (rbo->rdev->mc.visible_vram_size >> PAGE_SHIFT)) { |
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 11b662469253..c10b2aec6450 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
@@ -488,12 +488,12 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | |||
488 | unsigned buf_sizes[], bool *has_msg_cmd) | 488 | unsigned buf_sizes[], bool *has_msg_cmd) |
489 | { | 489 | { |
490 | struct radeon_cs_chunk *relocs_chunk; | 490 | struct radeon_cs_chunk *relocs_chunk; |
491 | struct radeon_cs_reloc *reloc; | 491 | struct radeon_bo_list *reloc; |
492 | unsigned idx, cmd, offset; | 492 | unsigned idx, cmd, offset; |
493 | uint64_t start, end; | 493 | uint64_t start, end; |
494 | int r; | 494 | int r; |
495 | 495 | ||
496 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | 496 | relocs_chunk = p->chunk_relocs; |
497 | offset = radeon_get_ib_value(p, data0); | 497 | offset = radeon_get_ib_value(p, data0); |
498 | idx = radeon_get_ib_value(p, data1); | 498 | idx = radeon_get_ib_value(p, data1); |
499 | if (idx >= relocs_chunk->length_dw) { | 499 | if (idx >= relocs_chunk->length_dw) { |
@@ -502,7 +502,7 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | |||
502 | return -EINVAL; | 502 | return -EINVAL; |
503 | } | 503 | } |
504 | 504 | ||
505 | reloc = p->relocs_ptr[(idx / 4)]; | 505 | reloc = &p->relocs[(idx / 4)]; |
506 | start = reloc->gpu_offset; | 506 | start = reloc->gpu_offset; |
507 | end = start + radeon_bo_size(reloc->robj); | 507 | end = start + radeon_bo_size(reloc->robj); |
508 | start += offset; | 508 | start += offset; |
@@ -610,13 +610,13 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p) | |||
610 | [0x00000003] = 2048, | 610 | [0x00000003] = 2048, |
611 | }; | 611 | }; |
612 | 612 | ||
613 | if (p->chunks[p->chunk_ib_idx].length_dw % 16) { | 613 | if (p->chunk_ib->length_dw % 16) { |
614 | DRM_ERROR("UVD IB length (%d) not 16 dwords aligned!\n", | 614 | DRM_ERROR("UVD IB length (%d) not 16 dwords aligned!\n", |
615 | p->chunks[p->chunk_ib_idx].length_dw); | 615 | p->chunk_ib->length_dw); |
616 | return -EINVAL; | 616 | return -EINVAL; |
617 | } | 617 | } |
618 | 618 | ||
619 | if (p->chunk_relocs_idx == -1) { | 619 | if (p->chunk_relocs == NULL) { |
620 | DRM_ERROR("No relocation chunk !\n"); | 620 | DRM_ERROR("No relocation chunk !\n"); |
621 | return -EINVAL; | 621 | return -EINVAL; |
622 | } | 622 | } |
@@ -640,7 +640,7 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p) | |||
640 | DRM_ERROR("Unknown packet type %d !\n", pkt.type); | 640 | DRM_ERROR("Unknown packet type %d !\n", pkt.type); |
641 | return -EINVAL; | 641 | return -EINVAL; |
642 | } | 642 | } |
643 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); | 643 | } while (p->idx < p->chunk_ib->length_dw); |
644 | 644 | ||
645 | if (!has_msg_cmd) { | 645 | if (!has_msg_cmd) { |
646 | DRM_ERROR("UVD-IBs need a msg command!\n"); | 646 | DRM_ERROR("UVD-IBs need a msg command!\n"); |
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index 9e85757d5599..976fe432f4e2 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c | |||
@@ -453,11 +453,11 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi, | |||
453 | unsigned size) | 453 | unsigned size) |
454 | { | 454 | { |
455 | struct radeon_cs_chunk *relocs_chunk; | 455 | struct radeon_cs_chunk *relocs_chunk; |
456 | struct radeon_cs_reloc *reloc; | 456 | struct radeon_bo_list *reloc; |
457 | uint64_t start, end, offset; | 457 | uint64_t start, end, offset; |
458 | unsigned idx; | 458 | unsigned idx; |
459 | 459 | ||
460 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | 460 | relocs_chunk = p->chunk_relocs; |
461 | offset = radeon_get_ib_value(p, lo); | 461 | offset = radeon_get_ib_value(p, lo); |
462 | idx = radeon_get_ib_value(p, hi); | 462 | idx = radeon_get_ib_value(p, hi); |
463 | 463 | ||
@@ -467,7 +467,7 @@ int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi, | |||
467 | return -EINVAL; | 467 | return -EINVAL; |
468 | } | 468 | } |
469 | 469 | ||
470 | reloc = p->relocs_ptr[(idx / 4)]; | 470 | reloc = &p->relocs[(idx / 4)]; |
471 | start = reloc->gpu_offset; | 471 | start = reloc->gpu_offset; |
472 | end = start + radeon_bo_size(reloc->robj); | 472 | end = start + radeon_bo_size(reloc->robj); |
473 | start += offset; | 473 | start += offset; |
@@ -534,7 +534,7 @@ int radeon_vce_cs_parse(struct radeon_cs_parser *p) | |||
534 | uint32_t *size = &tmp; | 534 | uint32_t *size = &tmp; |
535 | int i, r; | 535 | int i, r; |
536 | 536 | ||
537 | while (p->idx < p->chunks[p->chunk_ib_idx].length_dw) { | 537 | while (p->idx < p->chunk_ib->length_dw) { |
538 | uint32_t len = radeon_get_ib_value(p, p->idx); | 538 | uint32_t len = radeon_get_ib_value(p, p->idx); |
539 | uint32_t cmd = radeon_get_ib_value(p, p->idx + 1); | 539 | uint32_t cmd = radeon_get_ib_value(p, p->idx + 1); |
540 | 540 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 0b10f3a03ce2..cde48c42b30a 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c | |||
@@ -125,41 +125,37 @@ void radeon_vm_manager_fini(struct radeon_device *rdev) | |||
125 | * Add the page directory to the list of BOs to | 125 | * Add the page directory to the list of BOs to |
126 | * validate for command submission (cayman+). | 126 | * validate for command submission (cayman+). |
127 | */ | 127 | */ |
128 | struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, | 128 | struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev, |
129 | struct radeon_vm *vm, | 129 | struct radeon_vm *vm, |
130 | struct list_head *head) | 130 | struct list_head *head) |
131 | { | 131 | { |
132 | struct radeon_cs_reloc *list; | 132 | struct radeon_bo_list *list; |
133 | unsigned i, idx; | 133 | unsigned i, idx; |
134 | 134 | ||
135 | list = drm_malloc_ab(vm->max_pde_used + 2, | 135 | list = drm_malloc_ab(vm->max_pde_used + 2, |
136 | sizeof(struct radeon_cs_reloc)); | 136 | sizeof(struct radeon_bo_list)); |
137 | if (!list) | 137 | if (!list) |
138 | return NULL; | 138 | return NULL; |
139 | 139 | ||
140 | /* add the vm page table to the list */ | 140 | /* add the vm page table to the list */ |
141 | list[0].gobj = NULL; | ||
142 | list[0].robj = vm->page_directory; | 141 | list[0].robj = vm->page_directory; |
143 | list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM; | 142 | list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM; |
144 | list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM; | 143 | list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM; |
145 | list[0].tv.bo = &vm->page_directory->tbo; | 144 | list[0].tv.bo = &vm->page_directory->tbo; |
146 | list[0].tv.shared = true; | 145 | list[0].tv.shared = true; |
147 | list[0].tiling_flags = 0; | 146 | list[0].tiling_flags = 0; |
148 | list[0].handle = 0; | ||
149 | list_add(&list[0].tv.head, head); | 147 | list_add(&list[0].tv.head, head); |
150 | 148 | ||
151 | for (i = 0, idx = 1; i <= vm->max_pde_used; i++) { | 149 | for (i = 0, idx = 1; i <= vm->max_pde_used; i++) { |
152 | if (!vm->page_tables[i].bo) | 150 | if (!vm->page_tables[i].bo) |
153 | continue; | 151 | continue; |
154 | 152 | ||
155 | list[idx].gobj = NULL; | ||
156 | list[idx].robj = vm->page_tables[i].bo; | 153 | list[idx].robj = vm->page_tables[i].bo; |
157 | list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM; | 154 | list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM; |
158 | list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM; | 155 | list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM; |
159 | list[idx].tv.bo = &list[idx].robj->tbo; | 156 | list[idx].tv.bo = &list[idx].robj->tbo; |
160 | list[idx].tv.shared = true; | 157 | list[idx].tv.shared = true; |
161 | list[idx].tiling_flags = 0; | 158 | list[idx].tiling_flags = 0; |
162 | list[idx].handle = 0; | ||
163 | list_add(&list[idx++].tv.head, head); | 159 | list_add(&list[idx++].tv.head, head); |
164 | } | 160 | } |
165 | 161 | ||
@@ -491,7 +487,9 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
491 | tmp->vm = vm; | 487 | tmp->vm = vm; |
492 | tmp->addr = bo_va->addr; | 488 | tmp->addr = bo_va->addr; |
493 | tmp->bo = radeon_bo_ref(bo_va->bo); | 489 | tmp->bo = radeon_bo_ref(bo_va->bo); |
490 | spin_lock(&vm->status_lock); | ||
494 | list_add(&tmp->vm_status, &vm->freed); | 491 | list_add(&tmp->vm_status, &vm->freed); |
492 | spin_unlock(&vm->status_lock); | ||
495 | } | 493 | } |
496 | 494 | ||
497 | interval_tree_remove(&bo_va->it, &vm->va); | 495 | interval_tree_remove(&bo_va->it, &vm->va); |
@@ -802,11 +800,11 @@ static void radeon_vm_frag_ptes(struct radeon_device *rdev, | |||
802 | * | 800 | * |
803 | * Global and local mutex must be locked! | 801 | * Global and local mutex must be locked! |
804 | */ | 802 | */ |
805 | static void radeon_vm_update_ptes(struct radeon_device *rdev, | 803 | static int radeon_vm_update_ptes(struct radeon_device *rdev, |
806 | struct radeon_vm *vm, | 804 | struct radeon_vm *vm, |
807 | struct radeon_ib *ib, | 805 | struct radeon_ib *ib, |
808 | uint64_t start, uint64_t end, | 806 | uint64_t start, uint64_t end, |
809 | uint64_t dst, uint32_t flags) | 807 | uint64_t dst, uint32_t flags) |
810 | { | 808 | { |
811 | uint64_t mask = RADEON_VM_PTE_COUNT - 1; | 809 | uint64_t mask = RADEON_VM_PTE_COUNT - 1; |
812 | uint64_t last_pte = ~0, last_dst = ~0; | 810 | uint64_t last_pte = ~0, last_dst = ~0; |
@@ -819,8 +817,12 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, | |||
819 | struct radeon_bo *pt = vm->page_tables[pt_idx].bo; | 817 | struct radeon_bo *pt = vm->page_tables[pt_idx].bo; |
820 | unsigned nptes; | 818 | unsigned nptes; |
821 | uint64_t pte; | 819 | uint64_t pte; |
820 | int r; | ||
822 | 821 | ||
823 | radeon_sync_resv(rdev, &ib->sync, pt->tbo.resv, true); | 822 | radeon_sync_resv(rdev, &ib->sync, pt->tbo.resv, true); |
823 | r = reservation_object_reserve_shared(pt->tbo.resv); | ||
824 | if (r) | ||
825 | return r; | ||
824 | 826 | ||
825 | if ((addr & ~mask) == (end & ~mask)) | 827 | if ((addr & ~mask) == (end & ~mask)) |
826 | nptes = end - addr; | 828 | nptes = end - addr; |
@@ -854,6 +856,8 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, | |||
854 | last_pte + 8 * count, | 856 | last_pte + 8 * count, |
855 | last_dst, flags); | 857 | last_dst, flags); |
856 | } | 858 | } |
859 | |||
860 | return 0; | ||
857 | } | 861 | } |
858 | 862 | ||
859 | /** | 863 | /** |
@@ -878,7 +882,7 @@ static void radeon_vm_fence_pts(struct radeon_vm *vm, | |||
878 | end >>= radeon_vm_block_size; | 882 | end >>= radeon_vm_block_size; |
879 | 883 | ||
880 | for (i = start; i <= end; ++i) | 884 | for (i = start; i <= end; ++i) |
881 | radeon_bo_fence(vm->page_tables[i].bo, fence, false); | 885 | radeon_bo_fence(vm->page_tables[i].bo, fence, true); |
882 | } | 886 | } |
883 | 887 | ||
884 | /** | 888 | /** |
@@ -911,7 +915,9 @@ int radeon_vm_bo_update(struct radeon_device *rdev, | |||
911 | return -EINVAL; | 915 | return -EINVAL; |
912 | } | 916 | } |
913 | 917 | ||
918 | spin_lock(&vm->status_lock); | ||
914 | list_del_init(&bo_va->vm_status); | 919 | list_del_init(&bo_va->vm_status); |
920 | spin_unlock(&vm->status_lock); | ||
915 | 921 | ||
916 | bo_va->flags &= ~RADEON_VM_PAGE_VALID; | 922 | bo_va->flags &= ~RADEON_VM_PAGE_VALID; |
917 | bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; | 923 | bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; |
@@ -987,9 +993,13 @@ int radeon_vm_bo_update(struct radeon_device *rdev, | |||
987 | radeon_sync_fence(&ib.sync, vm->ids[i].last_id_use); | 993 | radeon_sync_fence(&ib.sync, vm->ids[i].last_id_use); |
988 | } | 994 | } |
989 | 995 | ||
990 | radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start, | 996 | r = radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start, |
991 | bo_va->it.last + 1, addr, | 997 | bo_va->it.last + 1, addr, |
992 | radeon_vm_page_flags(bo_va->flags)); | 998 | radeon_vm_page_flags(bo_va->flags)); |
999 | if (r) { | ||
1000 | radeon_ib_free(rdev, &ib); | ||
1001 | return r; | ||
1002 | } | ||
993 | 1003 | ||
994 | radeon_asic_vm_pad_ib(rdev, &ib); | 1004 | radeon_asic_vm_pad_ib(rdev, &ib); |
995 | WARN_ON(ib.length_dw > ndw); | 1005 | WARN_ON(ib.length_dw > ndw); |
@@ -1022,17 +1032,25 @@ int radeon_vm_bo_update(struct radeon_device *rdev, | |||
1022 | int radeon_vm_clear_freed(struct radeon_device *rdev, | 1032 | int radeon_vm_clear_freed(struct radeon_device *rdev, |
1023 | struct radeon_vm *vm) | 1033 | struct radeon_vm *vm) |
1024 | { | 1034 | { |
1025 | struct radeon_bo_va *bo_va, *tmp; | 1035 | struct radeon_bo_va *bo_va; |
1026 | int r; | 1036 | int r; |
1027 | 1037 | ||
1028 | list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { | 1038 | spin_lock(&vm->status_lock); |
1039 | while (!list_empty(&vm->freed)) { | ||
1040 | bo_va = list_first_entry(&vm->freed, | ||
1041 | struct radeon_bo_va, vm_status); | ||
1042 | spin_unlock(&vm->status_lock); | ||
1043 | |||
1029 | r = radeon_vm_bo_update(rdev, bo_va, NULL); | 1044 | r = radeon_vm_bo_update(rdev, bo_va, NULL); |
1030 | radeon_bo_unref(&bo_va->bo); | 1045 | radeon_bo_unref(&bo_va->bo); |
1031 | radeon_fence_unref(&bo_va->last_pt_update); | 1046 | radeon_fence_unref(&bo_va->last_pt_update); |
1032 | kfree(bo_va); | 1047 | kfree(bo_va); |
1033 | if (r) | 1048 | if (r) |
1034 | return r; | 1049 | return r; |
1050 | |||
1051 | spin_lock(&vm->status_lock); | ||
1035 | } | 1052 | } |
1053 | spin_unlock(&vm->status_lock); | ||
1036 | return 0; | 1054 | return 0; |
1037 | 1055 | ||
1038 | } | 1056 | } |
@@ -1051,14 +1069,23 @@ int radeon_vm_clear_freed(struct radeon_device *rdev, | |||
1051 | int radeon_vm_clear_invalids(struct radeon_device *rdev, | 1069 | int radeon_vm_clear_invalids(struct radeon_device *rdev, |
1052 | struct radeon_vm *vm) | 1070 | struct radeon_vm *vm) |
1053 | { | 1071 | { |
1054 | struct radeon_bo_va *bo_va, *tmp; | 1072 | struct radeon_bo_va *bo_va; |
1055 | int r; | 1073 | int r; |
1056 | 1074 | ||
1057 | list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, vm_status) { | 1075 | spin_lock(&vm->status_lock); |
1076 | while (!list_empty(&vm->invalidated)) { | ||
1077 | bo_va = list_first_entry(&vm->invalidated, | ||
1078 | struct radeon_bo_va, vm_status); | ||
1079 | spin_unlock(&vm->status_lock); | ||
1080 | |||
1058 | r = radeon_vm_bo_update(rdev, bo_va, NULL); | 1081 | r = radeon_vm_bo_update(rdev, bo_va, NULL); |
1059 | if (r) | 1082 | if (r) |
1060 | return r; | 1083 | return r; |
1084 | |||
1085 | spin_lock(&vm->status_lock); | ||
1061 | } | 1086 | } |
1087 | spin_unlock(&vm->status_lock); | ||
1088 | |||
1062 | return 0; | 1089 | return 0; |
1063 | } | 1090 | } |
1064 | 1091 | ||
@@ -1081,6 +1108,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
1081 | 1108 | ||
1082 | mutex_lock(&vm->mutex); | 1109 | mutex_lock(&vm->mutex); |
1083 | interval_tree_remove(&bo_va->it, &vm->va); | 1110 | interval_tree_remove(&bo_va->it, &vm->va); |
1111 | spin_lock(&vm->status_lock); | ||
1084 | list_del(&bo_va->vm_status); | 1112 | list_del(&bo_va->vm_status); |
1085 | 1113 | ||
1086 | if (bo_va->addr) { | 1114 | if (bo_va->addr) { |
@@ -1090,6 +1118,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
1090 | radeon_fence_unref(&bo_va->last_pt_update); | 1118 | radeon_fence_unref(&bo_va->last_pt_update); |
1091 | kfree(bo_va); | 1119 | kfree(bo_va); |
1092 | } | 1120 | } |
1121 | spin_unlock(&vm->status_lock); | ||
1093 | 1122 | ||
1094 | mutex_unlock(&vm->mutex); | 1123 | mutex_unlock(&vm->mutex); |
1095 | } | 1124 | } |
@@ -1110,10 +1139,10 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev, | |||
1110 | 1139 | ||
1111 | list_for_each_entry(bo_va, &bo->va, bo_list) { | 1140 | list_for_each_entry(bo_va, &bo->va, bo_list) { |
1112 | if (bo_va->addr) { | 1141 | if (bo_va->addr) { |
1113 | mutex_lock(&bo_va->vm->mutex); | 1142 | spin_lock(&bo_va->vm->status_lock); |
1114 | list_del(&bo_va->vm_status); | 1143 | list_del(&bo_va->vm_status); |
1115 | list_add(&bo_va->vm_status, &bo_va->vm->invalidated); | 1144 | list_add(&bo_va->vm_status, &bo_va->vm->invalidated); |
1116 | mutex_unlock(&bo_va->vm->mutex); | 1145 | spin_unlock(&bo_va->vm->status_lock); |
1117 | } | 1146 | } |
1118 | } | 1147 | } |
1119 | } | 1148 | } |
@@ -1141,6 +1170,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
1141 | } | 1170 | } |
1142 | mutex_init(&vm->mutex); | 1171 | mutex_init(&vm->mutex); |
1143 | vm->va = RB_ROOT; | 1172 | vm->va = RB_ROOT; |
1173 | spin_lock_init(&vm->status_lock); | ||
1144 | INIT_LIST_HEAD(&vm->invalidated); | 1174 | INIT_LIST_HEAD(&vm->invalidated); |
1145 | INIT_LIST_HEAD(&vm->freed); | 1175 | INIT_LIST_HEAD(&vm->freed); |
1146 | 1176 | ||
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index cf4c420b5572..32e354b8b0ab 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -5893,7 +5893,7 @@ static void si_fan_ctrl_set_static_mode(struct radeon_device *rdev, u32 mode) | |||
5893 | tmp |= TMIN(0); | 5893 | tmp |= TMIN(0); |
5894 | WREG32(CG_FDO_CTRL2, tmp); | 5894 | WREG32(CG_FDO_CTRL2, tmp); |
5895 | 5895 | ||
5896 | tmp = RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK; | 5896 | tmp = RREG32(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK; |
5897 | tmp |= FDO_PWM_MODE(mode); | 5897 | tmp |= FDO_PWM_MODE(mode); |
5898 | WREG32(CG_FDO_CTRL2, tmp); | 5898 | WREG32(CG_FDO_CTRL2, tmp); |
5899 | } | 5899 | } |
@@ -6098,7 +6098,7 @@ static int si_fan_ctrl_set_fan_speed_rpm(struct radeon_device *rdev, | |||
6098 | tmp |= TARGET_PERIOD(tach_period); | 6098 | tmp |= TARGET_PERIOD(tach_period); |
6099 | WREG32(CG_TACH_CTRL, tmp); | 6099 | WREG32(CG_TACH_CTRL, tmp); |
6100 | 6100 | ||
6101 | si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC); | 6101 | si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC_RPM); |
6102 | 6102 | ||
6103 | return 0; | 6103 | return 0; |
6104 | } | 6104 | } |
@@ -6114,7 +6114,7 @@ static void si_fan_ctrl_set_default_mode(struct radeon_device *rdev) | |||
6114 | tmp |= FDO_PWM_MODE(si_pi->fan_ctrl_default_mode); | 6114 | tmp |= FDO_PWM_MODE(si_pi->fan_ctrl_default_mode); |
6115 | WREG32(CG_FDO_CTRL2, tmp); | 6115 | WREG32(CG_FDO_CTRL2, tmp); |
6116 | 6116 | ||
6117 | tmp = RREG32(CG_FDO_CTRL2) & TMIN_MASK; | 6117 | tmp = RREG32(CG_FDO_CTRL2) & ~TMIN_MASK; |
6118 | tmp |= TMIN(si_pi->t_min); | 6118 | tmp |= TMIN(si_pi->t_min); |
6119 | WREG32(CG_FDO_CTRL2, tmp); | 6119 | WREG32(CG_FDO_CTRL2, tmp); |
6120 | si_pi->fan_ctrl_is_in_default_mode = true; | 6120 | si_pi->fan_ctrl_is_in_default_mode = true; |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index c549c16a4fe4..4069be89e585 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -208,18 +208,18 @@ | |||
208 | 208 | ||
209 | #define CG_FDO_CTRL0 0x754 | 209 | #define CG_FDO_CTRL0 0x754 |
210 | #define FDO_STATIC_DUTY(x) ((x) << 0) | 210 | #define FDO_STATIC_DUTY(x) ((x) << 0) |
211 | #define FDO_STATIC_DUTY_MASK 0x0000000F | 211 | #define FDO_STATIC_DUTY_MASK 0x000000FF |
212 | #define FDO_STATIC_DUTY_SHIFT 0 | 212 | #define FDO_STATIC_DUTY_SHIFT 0 |
213 | #define CG_FDO_CTRL1 0x758 | 213 | #define CG_FDO_CTRL1 0x758 |
214 | #define FMAX_DUTY100(x) ((x) << 0) | 214 | #define FMAX_DUTY100(x) ((x) << 0) |
215 | #define FMAX_DUTY100_MASK 0x0000000F | 215 | #define FMAX_DUTY100_MASK 0x000000FF |
216 | #define FMAX_DUTY100_SHIFT 0 | 216 | #define FMAX_DUTY100_SHIFT 0 |
217 | #define CG_FDO_CTRL2 0x75C | 217 | #define CG_FDO_CTRL2 0x75C |
218 | #define TMIN(x) ((x) << 0) | 218 | #define TMIN(x) ((x) << 0) |
219 | #define TMIN_MASK 0x0000000F | 219 | #define TMIN_MASK 0x000000FF |
220 | #define TMIN_SHIFT 0 | 220 | #define TMIN_SHIFT 0 |
221 | #define FDO_PWM_MODE(x) ((x) << 11) | 221 | #define FDO_PWM_MODE(x) ((x) << 11) |
222 | #define FDO_PWM_MODE_MASK (3 << 11) | 222 | #define FDO_PWM_MODE_MASK (7 << 11) |
223 | #define FDO_PWM_MODE_SHIFT 11 | 223 | #define FDO_PWM_MODE_SHIFT 11 |
224 | #define TACH_PWM_RESP_RATE(x) ((x) << 25) | 224 | #define TACH_PWM_RESP_RATE(x) ((x) << 25) |
225 | #define TACH_PWM_RESP_RATE_MASK (0x7f << 25) | 225 | #define TACH_PWM_RESP_RATE_MASK (0x7f << 25) |
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index 8ce508e76208..3820ae97a030 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c | |||
@@ -93,7 +93,8 @@ EXPORT_SYMBOL(ttm_eu_backoff_reservation); | |||
93 | */ | 93 | */ |
94 | 94 | ||
95 | int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, | 95 | int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, |
96 | struct list_head *list, bool intr) | 96 | struct list_head *list, bool intr, |
97 | struct list_head *dups) | ||
97 | { | 98 | { |
98 | struct ttm_bo_global *glob; | 99 | struct ttm_bo_global *glob; |
99 | struct ttm_validate_buffer *entry; | 100 | struct ttm_validate_buffer *entry; |
@@ -117,6 +118,13 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, | |||
117 | __ttm_bo_unreserve(bo); | 118 | __ttm_bo_unreserve(bo); |
118 | 119 | ||
119 | ret = -EBUSY; | 120 | ret = -EBUSY; |
121 | |||
122 | } else if (ret == -EALREADY && dups) { | ||
123 | struct ttm_validate_buffer *safe = entry; | ||
124 | entry = list_prev_entry(entry, head); | ||
125 | list_del(&safe->head); | ||
126 | list_add(&safe->head, dups); | ||
127 | continue; | ||
120 | } | 128 | } |
121 | 129 | ||
122 | if (!ret) { | 130 | if (!ret) { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 596cd6dafd33..33176d05db35 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -2487,7 +2487,8 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2487 | if (unlikely(ret != 0)) | 2487 | if (unlikely(ret != 0)) |
2488 | goto out_err_nores; | 2488 | goto out_err_nores; |
2489 | 2489 | ||
2490 | ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes, true); | 2490 | ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes, |
2491 | true, NULL); | ||
2491 | if (unlikely(ret != 0)) | 2492 | if (unlikely(ret != 0)) |
2492 | goto out_err; | 2493 | goto out_err; |
2493 | 2494 | ||
@@ -2677,7 +2678,8 @@ void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, | |||
2677 | query_val.shared = false; | 2678 | query_val.shared = false; |
2678 | list_add_tail(&query_val.head, &validate_list); | 2679 | list_add_tail(&query_val.head, &validate_list); |
2679 | 2680 | ||
2680 | ret = ttm_eu_reserve_buffers(&ticket, &validate_list, false); | 2681 | ret = ttm_eu_reserve_buffers(&ticket, &validate_list, |
2682 | false, NULL); | ||
2681 | if (unlikely(ret != 0)) { | 2683 | if (unlikely(ret != 0)) { |
2682 | vmw_execbuf_unpin_panic(dev_priv); | 2684 | vmw_execbuf_unpin_panic(dev_priv); |
2683 | goto out_no_reserve; | 2685 | goto out_no_reserve; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 026de7cea0f6..210ef15b1d09 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -1222,7 +1222,7 @@ vmw_resource_check_buffer(struct vmw_resource *res, | |||
1222 | val_buf->bo = ttm_bo_reference(&res->backup->base); | 1222 | val_buf->bo = ttm_bo_reference(&res->backup->base); |
1223 | val_buf->shared = false; | 1223 | val_buf->shared = false; |
1224 | list_add_tail(&val_buf->head, &val_list); | 1224 | list_add_tail(&val_buf->head, &val_list); |
1225 | ret = ttm_eu_reserve_buffers(NULL, &val_list, interruptible); | 1225 | ret = ttm_eu_reserve_buffers(NULL, &val_list, interruptible, NULL); |
1226 | if (unlikely(ret != 0)) | 1226 | if (unlikely(ret != 0)) |
1227 | goto out_no_reserve; | 1227 | goto out_no_reserve; |
1228 | 1228 | ||
diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h index 460441714413..b620c317c772 100644 --- a/include/drm/ttm/ttm_execbuf_util.h +++ b/include/drm/ttm/ttm_execbuf_util.h | |||
@@ -68,6 +68,7 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket, | |||
68 | * non-blocking reserves should be tried. | 68 | * non-blocking reserves should be tried. |
69 | * @list: thread private list of ttm_validate_buffer structs. | 69 | * @list: thread private list of ttm_validate_buffer structs. |
70 | * @intr: should the wait be interruptible | 70 | * @intr: should the wait be interruptible |
71 | * @dups: [out] optional list of duplicates. | ||
71 | * | 72 | * |
72 | * Tries to reserve bos pointed to by the list entries for validation. | 73 | * Tries to reserve bos pointed to by the list entries for validation. |
73 | * If the function returns 0, all buffers are marked as "unfenced", | 74 | * If the function returns 0, all buffers are marked as "unfenced", |
@@ -83,6 +84,11 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket, | |||
83 | * calling process receives a signal while waiting. In that case, no | 84 | * calling process receives a signal while waiting. In that case, no |
84 | * buffers on the list will be reserved upon return. | 85 | * buffers on the list will be reserved upon return. |
85 | * | 86 | * |
87 | * If dups is non NULL all buffers already reserved by the current thread | ||
88 | * (e.g. duplicates) are added to this list, otherwise -EALREADY is returned | ||
89 | * on the first already reserved buffer and all buffers from the list are | ||
90 | * unreserved again. | ||
91 | * | ||
86 | * Buffers reserved by this function should be unreserved by | 92 | * Buffers reserved by this function should be unreserved by |
87 | * a call to either ttm_eu_backoff_reservation() or | 93 | * a call to either ttm_eu_backoff_reservation() or |
88 | * ttm_eu_fence_buffer_objects() when command submission is complete or | 94 | * ttm_eu_fence_buffer_objects() when command submission is complete or |
@@ -90,7 +96,8 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket, | |||
90 | */ | 96 | */ |
91 | 97 | ||
92 | extern int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, | 98 | extern int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, |
93 | struct list_head *list, bool intr); | 99 | struct list_head *list, bool intr, |
100 | struct list_head *dups); | ||
94 | 101 | ||
95 | /** | 102 | /** |
96 | * function ttm_eu_fence_buffer_objects. | 103 | * function ttm_eu_fence_buffer_objects. |