diff options
Diffstat (limited to 'drivers/gpu/drm/qxl/qxl_cmd.c')
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_cmd.c | 42 |
1 files changed, 18 insertions, 24 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index 93c2f2cceb51..eb89653a7a17 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c | |||
@@ -179,9 +179,10 @@ qxl_push_command_ring_release(struct qxl_device *qdev, struct qxl_release *relea | |||
179 | uint32_t type, bool interruptible) | 179 | uint32_t type, bool interruptible) |
180 | { | 180 | { |
181 | struct qxl_command cmd; | 181 | struct qxl_command cmd; |
182 | struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head); | ||
182 | 183 | ||
183 | cmd.type = type; | 184 | cmd.type = type; |
184 | cmd.data = qxl_bo_physical_address(qdev, release->bos[0], release->release_offset); | 185 | cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset); |
185 | 186 | ||
186 | return qxl_ring_push(qdev->command_ring, &cmd, interruptible); | 187 | return qxl_ring_push(qdev->command_ring, &cmd, interruptible); |
187 | } | 188 | } |
@@ -191,9 +192,10 @@ qxl_push_cursor_ring_release(struct qxl_device *qdev, struct qxl_release *releas | |||
191 | uint32_t type, bool interruptible) | 192 | uint32_t type, bool interruptible) |
192 | { | 193 | { |
193 | struct qxl_command cmd; | 194 | struct qxl_command cmd; |
195 | struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head); | ||
194 | 196 | ||
195 | cmd.type = type; | 197 | cmd.type = type; |
196 | cmd.data = qxl_bo_physical_address(qdev, release->bos[0], release->release_offset); | 198 | cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset); |
197 | 199 | ||
198 | return qxl_ring_push(qdev->cursor_ring, &cmd, interruptible); | 200 | return qxl_ring_push(qdev->cursor_ring, &cmd, interruptible); |
199 | } | 201 | } |
@@ -214,7 +216,6 @@ int qxl_garbage_collect(struct qxl_device *qdev) | |||
214 | struct qxl_release *release; | 216 | struct qxl_release *release; |
215 | uint64_t id, next_id; | 217 | uint64_t id, next_id; |
216 | int i = 0; | 218 | int i = 0; |
217 | int ret; | ||
218 | union qxl_release_info *info; | 219 | union qxl_release_info *info; |
219 | 220 | ||
220 | while (qxl_ring_pop(qdev->release_ring, &id)) { | 221 | while (qxl_ring_pop(qdev->release_ring, &id)) { |
@@ -224,17 +225,10 @@ int qxl_garbage_collect(struct qxl_device *qdev) | |||
224 | if (release == NULL) | 225 | if (release == NULL) |
225 | break; | 226 | break; |
226 | 227 | ||
227 | ret = qxl_release_reserve(qdev, release, false); | ||
228 | if (ret) { | ||
229 | qxl_io_log(qdev, "failed to reserve release on garbage collect %lld\n", id); | ||
230 | DRM_ERROR("failed to reserve release %lld\n", id); | ||
231 | } | ||
232 | |||
233 | info = qxl_release_map(qdev, release); | 228 | info = qxl_release_map(qdev, release); |
234 | next_id = info->next; | 229 | next_id = info->next; |
235 | qxl_release_unmap(qdev, release, info); | 230 | qxl_release_unmap(qdev, release, info); |
236 | 231 | ||
237 | qxl_release_unreserve(qdev, release); | ||
238 | QXL_INFO(qdev, "popped %lld, next %lld\n", id, | 232 | QXL_INFO(qdev, "popped %lld, next %lld\n", id, |
239 | next_id); | 233 | next_id); |
240 | 234 | ||
@@ -259,27 +253,29 @@ int qxl_garbage_collect(struct qxl_device *qdev) | |||
259 | return i; | 253 | return i; |
260 | } | 254 | } |
261 | 255 | ||
262 | int qxl_alloc_bo_reserved(struct qxl_device *qdev, unsigned long size, | 256 | int qxl_alloc_bo_reserved(struct qxl_device *qdev, |
257 | struct qxl_release *release, | ||
258 | unsigned long size, | ||
263 | struct qxl_bo **_bo) | 259 | struct qxl_bo **_bo) |
264 | { | 260 | { |
265 | struct qxl_bo *bo; | 261 | struct qxl_bo *bo; |
266 | int ret; | 262 | int ret; |
267 | 263 | ||
268 | ret = qxl_bo_create(qdev, size, false /* not kernel - device */, | 264 | ret = qxl_bo_create(qdev, size, false /* not kernel - device */, |
269 | QXL_GEM_DOMAIN_VRAM, NULL, &bo); | 265 | false, QXL_GEM_DOMAIN_VRAM, NULL, &bo); |
270 | if (ret) { | 266 | if (ret) { |
271 | DRM_ERROR("failed to allocate VRAM BO\n"); | 267 | DRM_ERROR("failed to allocate VRAM BO\n"); |
272 | return ret; | 268 | return ret; |
273 | } | 269 | } |
274 | ret = qxl_bo_reserve(bo, false); | 270 | ret = qxl_release_list_add(release, bo); |
275 | if (unlikely(ret != 0)) | 271 | if (ret) |
276 | goto out_unref; | 272 | goto out_unref; |
277 | 273 | ||
278 | *_bo = bo; | 274 | *_bo = bo; |
279 | return 0; | 275 | return 0; |
280 | out_unref: | 276 | out_unref: |
281 | qxl_bo_unref(&bo); | 277 | qxl_bo_unref(&bo); |
282 | return 0; | 278 | return ret; |
283 | } | 279 | } |
284 | 280 | ||
285 | static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port, bool intr) | 281 | static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port, bool intr) |
@@ -503,6 +499,10 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev, | |||
503 | if (ret) | 499 | if (ret) |
504 | return ret; | 500 | return ret; |
505 | 501 | ||
502 | ret = qxl_release_reserve_list(release, true); | ||
503 | if (ret) | ||
504 | return ret; | ||
505 | |||
506 | cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release); | 506 | cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release); |
507 | cmd->type = QXL_SURFACE_CMD_CREATE; | 507 | cmd->type = QXL_SURFACE_CMD_CREATE; |
508 | cmd->u.surface_create.format = surf->surf.format; | 508 | cmd->u.surface_create.format = surf->surf.format; |
@@ -524,14 +524,11 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev, | |||
524 | 524 | ||
525 | surf->surf_create = release; | 525 | surf->surf_create = release; |
526 | 526 | ||
527 | /* no need to add a release to the fence for this bo, | 527 | /* no need to add a release to the fence for this surface bo, |
528 | since it is only released when we ask to destroy the surface | 528 | since it is only released when we ask to destroy the surface |
529 | and it would never signal otherwise */ | 529 | and it would never signal otherwise */ |
530 | qxl_fence_releaseable(qdev, release); | ||
531 | |||
532 | qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | 530 | qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); |
533 | 531 | qxl_release_fence_buffer_objects(release); | |
534 | qxl_release_unreserve(qdev, release); | ||
535 | 532 | ||
536 | surf->hw_surf_alloc = true; | 533 | surf->hw_surf_alloc = true; |
537 | spin_lock(&qdev->surf_id_idr_lock); | 534 | spin_lock(&qdev->surf_id_idr_lock); |
@@ -573,12 +570,9 @@ int qxl_hw_surface_dealloc(struct qxl_device *qdev, | |||
573 | cmd->surface_id = id; | 570 | cmd->surface_id = id; |
574 | qxl_release_unmap(qdev, release, &cmd->release_info); | 571 | qxl_release_unmap(qdev, release, &cmd->release_info); |
575 | 572 | ||
576 | qxl_fence_releaseable(qdev, release); | ||
577 | |||
578 | qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | 573 | qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); |
579 | 574 | ||
580 | qxl_release_unreserve(qdev, release); | 575 | qxl_release_fence_buffer_objects(release); |
581 | |||
582 | 576 | ||
583 | return 0; | 577 | return 0; |
584 | } | 578 | } |