| .. | .. |
|---|
| 25 | 25 | |
|---|
| 26 | 26 | /* QXL cmd/ring handling */ |
|---|
| 27 | 27 | |
|---|
| 28 | +#include <linux/delay.h> |
|---|
| 29 | + |
|---|
| 30 | +#include <drm/drm_util.h> |
|---|
| 31 | + |
|---|
| 28 | 32 | #include "qxl_drv.h" |
|---|
| 29 | 33 | #include "qxl_object.h" |
|---|
| 30 | 34 | |
|---|
| .. | .. |
|---|
| 32 | 36 | |
|---|
| 33 | 37 | struct ring { |
|---|
| 34 | 38 | struct qxl_ring_header header; |
|---|
| 35 | | - uint8_t elements[0]; |
|---|
| 39 | + uint8_t elements[]; |
|---|
| 36 | 40 | }; |
|---|
| 37 | 41 | |
|---|
| 38 | 42 | struct qxl_ring { |
|---|
| .. | .. |
|---|
| 84 | 88 | int ret; |
|---|
| 85 | 89 | struct qxl_ring_header *header = &(ring->ring->header); |
|---|
| 86 | 90 | unsigned long flags; |
|---|
| 91 | + |
|---|
| 87 | 92 | spin_lock_irqsave(&ring->lock, flags); |
|---|
| 88 | 93 | ret = header->prod - header->cons < header->num_items; |
|---|
| 89 | 94 | if (ret == 0) |
|---|
| .. | .. |
|---|
| 97 | 102 | int ret; |
|---|
| 98 | 103 | struct qxl_ring_header *header = &(ring->ring->header); |
|---|
| 99 | 104 | unsigned long flags; |
|---|
| 105 | + |
|---|
| 100 | 106 | spin_lock_irqsave(&ring->lock, flags); |
|---|
| 101 | 107 | ret = header->prod == header->cons; |
|---|
| 102 | 108 | spin_unlock_irqrestore(&ring->lock, flags); |
|---|
| .. | .. |
|---|
| 110 | 116 | uint8_t *elt; |
|---|
| 111 | 117 | int idx, ret; |
|---|
| 112 | 118 | unsigned long flags; |
|---|
| 119 | + |
|---|
| 113 | 120 | spin_lock_irqsave(&ring->lock, flags); |
|---|
| 114 | 121 | if (header->prod - header->cons == header->num_items) { |
|---|
| 115 | 122 | header->notify_on_cons = header->cons + 1; |
|---|
| .. | .. |
|---|
| 156 | 163 | volatile uint8_t *ring_elt; |
|---|
| 157 | 164 | int idx; |
|---|
| 158 | 165 | unsigned long flags; |
|---|
| 166 | + |
|---|
| 159 | 167 | spin_lock_irqsave(&ring->lock, flags); |
|---|
| 160 | 168 | if (header->cons == header->prod) { |
|---|
| 161 | 169 | header->notify_on_prod = header->cons + 1; |
|---|
| .. | .. |
|---|
| 260 | 268 | int ret; |
|---|
| 261 | 269 | |
|---|
| 262 | 270 | ret = qxl_bo_create(qdev, size, false /* not kernel - device */, |
|---|
| 263 | | - false, QXL_GEM_DOMAIN_VRAM, NULL, &bo); |
|---|
| 271 | + false, QXL_GEM_DOMAIN_VRAM, 0, NULL, &bo); |
|---|
| 264 | 272 | if (ret) { |
|---|
| 265 | 273 | DRM_ERROR("failed to allocate VRAM BO\n"); |
|---|
| 266 | 274 | return ret; |
|---|
| .. | .. |
|---|
| 365 | 373 | wait_for_io_cmd(qdev, 0, QXL_IO_FLUSH_SURFACES_ASYNC); |
|---|
| 366 | 374 | } |
|---|
| 367 | 375 | |
|---|
| 368 | | - |
|---|
| 369 | 376 | void qxl_io_destroy_primary(struct qxl_device *qdev) |
|---|
| 370 | 377 | { |
|---|
| 371 | 378 | wait_for_io_cmd(qdev, 0, QXL_IO_DESTROY_PRIMARY_ASYNC); |
|---|
| 372 | | - qdev->primary_created = false; |
|---|
| 379 | + qdev->primary_bo->is_primary = false; |
|---|
| 380 | + drm_gem_object_put(&qdev->primary_bo->tbo.base); |
|---|
| 381 | + qdev->primary_bo = NULL; |
|---|
| 373 | 382 | } |
|---|
| 374 | 383 | |
|---|
| 375 | | -void qxl_io_create_primary(struct qxl_device *qdev, |
|---|
| 376 | | - unsigned offset, struct qxl_bo *bo) |
|---|
| 384 | +void qxl_io_create_primary(struct qxl_device *qdev, struct qxl_bo *bo) |
|---|
| 377 | 385 | { |
|---|
| 378 | 386 | struct qxl_surface_create *create; |
|---|
| 387 | + |
|---|
| 388 | + if (WARN_ON(qdev->primary_bo)) |
|---|
| 389 | + return; |
|---|
| 379 | 390 | |
|---|
| 380 | 391 | DRM_DEBUG_DRIVER("qdev %p, ram_header %p\n", qdev, qdev->ram_header); |
|---|
| 381 | 392 | create = &qdev->ram_header->create_surface; |
|---|
| .. | .. |
|---|
| 383 | 394 | create->width = bo->surf.width; |
|---|
| 384 | 395 | create->height = bo->surf.height; |
|---|
| 385 | 396 | create->stride = bo->surf.stride; |
|---|
| 386 | | - if (bo->shadow) { |
|---|
| 387 | | - create->mem = qxl_bo_physical_address(qdev, bo->shadow, offset); |
|---|
| 388 | | - } else { |
|---|
| 389 | | - create->mem = qxl_bo_physical_address(qdev, bo, offset); |
|---|
| 390 | | - } |
|---|
| 397 | + create->mem = qxl_bo_physical_address(qdev, bo, 0); |
|---|
| 391 | 398 | |
|---|
| 392 | 399 | DRM_DEBUG_DRIVER("mem = %llx, from %p\n", create->mem, bo->kptr); |
|---|
| 393 | 400 | |
|---|
| .. | .. |
|---|
| 395 | 402 | create->type = QXL_SURF_TYPE_PRIMARY; |
|---|
| 396 | 403 | |
|---|
| 397 | 404 | wait_for_io_cmd(qdev, 0, QXL_IO_CREATE_PRIMARY_ASYNC); |
|---|
| 398 | | - qdev->primary_created = true; |
|---|
| 405 | + qdev->primary_bo = bo; |
|---|
| 406 | + qdev->primary_bo->is_primary = true; |
|---|
| 407 | + drm_gem_object_get(&qdev->primary_bo->tbo.base); |
|---|
| 399 | 408 | } |
|---|
| 400 | 409 | |
|---|
| 401 | 410 | void qxl_io_memslot_add(struct qxl_device *qdev, uint8_t id) |
|---|
| .. | .. |
|---|
| 455 | 464 | } |
|---|
| 456 | 465 | |
|---|
| 457 | 466 | int qxl_hw_surface_alloc(struct qxl_device *qdev, |
|---|
| 458 | | - struct qxl_bo *surf, |
|---|
| 459 | | - struct ttm_mem_reg *new_mem) |
|---|
| 467 | + struct qxl_bo *surf) |
|---|
| 460 | 468 | { |
|---|
| 461 | 469 | struct qxl_surface_cmd *cmd; |
|---|
| 462 | 470 | struct qxl_release *release; |
|---|
| .. | .. |
|---|
| 483 | 491 | cmd->u.surface_create.width = surf->surf.width; |
|---|
| 484 | 492 | cmd->u.surface_create.height = surf->surf.height; |
|---|
| 485 | 493 | cmd->u.surface_create.stride = surf->surf.stride; |
|---|
| 486 | | - if (new_mem) { |
|---|
| 487 | | - int slot_id = surf->type == QXL_GEM_DOMAIN_VRAM ? qdev->main_mem_slot : qdev->surfaces_mem_slot; |
|---|
| 488 | | - struct qxl_memslot *slot = &(qdev->mem_slots[slot_id]); |
|---|
| 489 | | - |
|---|
| 490 | | - /* TODO - need to hold one of the locks to read tbo.offset */ |
|---|
| 491 | | - cmd->u.surface_create.data = slot->high_bits; |
|---|
| 492 | | - |
|---|
| 493 | | - cmd->u.surface_create.data |= (new_mem->start << PAGE_SHIFT) + surf->tbo.bdev->man[new_mem->mem_type].gpu_offset; |
|---|
| 494 | | - } else |
|---|
| 495 | | - cmd->u.surface_create.data = qxl_bo_physical_address(qdev, surf, 0); |
|---|
| 494 | + cmd->u.surface_create.data = qxl_bo_physical_address(qdev, surf, 0); |
|---|
| 496 | 495 | cmd->surface_id = surf->surface_id; |
|---|
| 497 | 496 | qxl_release_unmap(qdev, release, &cmd->release_info); |
|---|
| 498 | 497 | |
|---|
| .. | .. |
|---|
| 589 | 588 | { |
|---|
| 590 | 589 | int ret; |
|---|
| 591 | 590 | |
|---|
| 592 | | - ret = qxl_bo_reserve(surf, false); |
|---|
| 591 | + ret = qxl_bo_reserve(surf); |
|---|
| 593 | 592 | if (ret) |
|---|
| 594 | 593 | return ret; |
|---|
| 595 | 594 | |
|---|