diff options
Diffstat (limited to 'drivers/gpu/drm/qxl')
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_display.c | 63 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_ioctl.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_object.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_release.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_ttm.c | 21 |
6 files changed, 81 insertions, 21 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 4756b3c9bf2c..9a9214ae0fb5 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -289,6 +289,7 @@ static void qxl_crtc_destroy(struct drm_crtc *crtc) { struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc); + qxl_bo_unref(&qxl_crtc->cursor_bo); drm_crtc_cleanup(crtc); kfree(qxl_crtc); } @@ -495,6 +496,53 @@ static int qxl_primary_atomic_check(struct drm_plane *plane, return 0; } +static int qxl_primary_apply_cursor(struct drm_plane *plane) +{ + struct drm_device *dev = plane->dev; + struct qxl_device *qdev = dev->dev_private; + struct drm_framebuffer *fb = plane->state->fb; + struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc); + struct qxl_cursor_cmd *cmd; + struct qxl_release *release; + int ret = 0; + + if (!qcrtc->cursor_bo) + return 0; + + ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), + QXL_RELEASE_CURSOR_CMD, + &release, NULL); + if (ret) + return ret; + + ret = qxl_release_list_add(release, qcrtc->cursor_bo); + if (ret) + goto out_free_release; + + ret = qxl_release_reserve_list(release, false); + if (ret) + goto out_free_release; + + cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); + cmd->type = QXL_CURSOR_SET; + cmd->u.set.position.x = plane->state->crtc_x + fb->hot_x; + cmd->u.set.position.y = plane->state->crtc_y + fb->hot_y; + + cmd->u.set.shape = qxl_bo_physical_address(qdev, qcrtc->cursor_bo, 0); + + cmd->u.set.visible = 1; + qxl_release_unmap(qdev, release, &cmd->release_info); + + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); + qxl_release_fence_buffer_objects(release); + + return ret; + +out_free_release: + qxl_release_free(qdev, release); + return ret; +} + static void qxl_primary_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { @@ -510,6 +558,7 @@ static void qxl_primary_atomic_update(struct drm_plane *plane, .x2 = qfb->base.width, .y2 = qfb->base.height }; + int ret; bool same_shadow = false; if (old_state->fb) { @@ -531,6 +580,11 @@ static void qxl_primary_atomic_update(struct drm_plane *plane, if (!same_shadow) qxl_io_destroy_primary(qdev); bo_old->is_primary = false; + + ret = qxl_primary_apply_cursor(plane); + if (ret) + DRM_ERROR( + "could not set cursor after creating primary"); } if (!bo->is_primary) { @@ -571,11 +625,12 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, struct drm_device *dev = plane->dev; struct qxl_device *qdev = dev->dev_private; struct drm_framebuffer *fb = plane->state->fb; + struct qxl_crtc *qcrtc = to_qxl_crtc(plane->state->crtc); struct qxl_release *release; struct qxl_cursor_cmd *cmd; struct qxl_cursor *cursor; struct drm_gem_object *obj; - struct qxl_bo *cursor_bo, *user_bo = NULL; + struct qxl_bo *cursor_bo = NULL, *user_bo = NULL; int ret; void *user_ptr; int size = 64*64*4; @@ -628,6 +683,10 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0); cmd->type = QXL_CURSOR_SET; + + qxl_bo_unref(&qcrtc->cursor_bo); + qcrtc->cursor_bo = cursor_bo; + cursor_bo = NULL; } else { ret = qxl_release_reserve_list(release, true); @@ -645,6 +704,8 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); qxl_release_fence_buffer_objects(release); + qxl_bo_unref(&cursor_bo); + return; out_backoff: diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 08752c0ffb35..00a1a66b052a 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -111,6 +111,8 @@ struct qxl_bo_list { struct qxl_crtc { struct drm_crtc base; int index; + + struct qxl_bo *cursor_bo; }; struct qxl_output { diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c index 31effed4a3c8..e8c0b1037230 100644 --- a/drivers/gpu/drm/qxl/qxl_ioctl.c +++ b/drivers/gpu/drm/qxl/qxl_ioctl.c @@ -309,6 +309,7 @@ static int qxl_update_area_ioctl(struct drm_device *dev, void *data, int ret; struct drm_gem_object *gobj = NULL; struct qxl_bo *qobj = NULL; + struct ttm_operation_ctx ctx = { true, false }; if (update_area->left >= update_area->right || update_area->top >= update_area->bottom) @@ -326,8 +327,7 @@ static int qxl_update_area_ioctl(struct drm_device *dev, void *data, if (!qobj->pin_count) { qxl_ttm_placement_from_domain(qobj, qobj->type, false); - ret = ttm_bo_validate(&qobj->tbo, &qobj->placement, - true, false); + ret = ttm_bo_validate(&qobj->tbo, &qobj->placement, &ctx); if (unlikely(ret)) goto out; } diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index 0a67ddf19c3d..f6b80fe47d1f 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -223,6 +223,7 @@ struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo) static int __qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr) { + struct ttm_operation_ctx ctx = { false, false }; struct drm_device *ddev = bo->gem_base.dev; int r; @@ -233,7 +234,7 @@ static int __qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr) return 0; } qxl_ttm_placement_from_domain(bo, domain, true); - r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); + r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); if (likely(r == 0)) { bo->pin_count = 1; if (gpu_addr != NULL) @@ -246,6 +247,7 @@ static int __qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr) static int __qxl_bo_unpin(struct qxl_bo *bo) { + struct ttm_operation_ctx ctx = { false, false }; struct drm_device *ddev = bo->gem_base.dev; int r, i; @@ -258,7 +260,7 @@ static int __qxl_bo_unpin(struct qxl_bo *bo) return 0; for (i = 0; i < bo->placement.num_placement; i++) bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; - r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); + r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); if (unlikely(r != 0)) dev_err(ddev->dev, "%p validate failed for unpin\n", bo); return r; diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index a6da6fa6ad58..b223c8d0a491 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -230,12 +230,12 @@ int qxl_release_list_add(struct qxl_release *release, struct qxl_bo *bo) static int qxl_release_validate_bo(struct qxl_bo *bo) { + struct ttm_operation_ctx ctx = { true, false }; int ret; if (!bo->pin_count) { qxl_ttm_placement_from_domain(bo, bo->type, false); - ret = ttm_bo_validate(&bo->tbo, &bo->placement, - true, false); + ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); if (ret) return ret; } @@ -468,7 +468,7 @@ void qxl_release_fence_buffer_objects(struct qxl_release *release) reservation_object_add_shared_fence(bo->resv, &release->base); ttm_bo_add_to_lru(bo); - __ttm_bo_unreserve(bo); + reservation_object_unlock(bo->resv); } spin_unlock(&glob->lru_lock); ww_acquire_fini(&release->ticket); diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index ab4823875311..59cd74c3f3af 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -123,11 +123,8 @@ int qxl_mmap(struct file *filp, struct vm_area_struct *vma) struct qxl_device *qdev; int r; - if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) { - pr_info("%s: vma->vm_pgoff (%ld) < DRM_FILE_PAGE_OFFSET\n", - __func__, vma->vm_pgoff); + if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) return -EINVAL; - } file_priv = filp->private_data; qdev = file_priv->minor->dev->dev_private; @@ -294,14 +291,15 @@ static struct ttm_backend_func qxl_backend_func = { .destroy = &qxl_ttm_backend_destroy, }; -static int qxl_ttm_tt_populate(struct ttm_tt *ttm) +static int qxl_ttm_tt_populate(struct ttm_tt *ttm, + struct ttm_operation_ctx *ctx) { int r; if (ttm->state != tt_unpopulated) return 0; - r = ttm_pool_populate(ttm); + r = ttm_pool_populate(ttm, ctx); if (r) return r; @@ -344,15 +342,14 @@ static void qxl_move_null(struct ttm_buffer_object *bo, new_mem->mm_node = NULL; } -static int qxl_bo_move(struct ttm_buffer_object *bo, - bool evict, bool interruptible, - bool no_wait_gpu, +static int qxl_bo_move(struct ttm_buffer_object *bo, bool evict, + struct ttm_operation_ctx *ctx, struct ttm_mem_reg *new_mem) { struct ttm_mem_reg *old_mem = &bo->mem; int ret; - ret = ttm_bo_wait(bo, interruptible, no_wait_gpu); + ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); if (ret) return ret; @@ -361,8 +358,7 @@ static int qxl_bo_move(struct ttm_buffer_object *bo, qxl_move_null(bo, new_mem); return 0; } - return ttm_bo_move_memcpy(bo, interruptible, no_wait_gpu, - new_mem); + return ttm_bo_move_memcpy(bo, ctx, new_mem); } static void qxl_bo_move_notify(struct ttm_buffer_object *bo, @@ -393,7 +389,6 @@ static struct ttm_bo_driver qxl_bo_driver = { .verify_access = &qxl_verify_access, .io_mem_reserve = &qxl_ttm_io_mem_reserve, .io_mem_free = &qxl_ttm_io_mem_free, - .io_mem_pfn = ttm_bo_default_io_mem_pfn, .move_notify = &qxl_bo_move_notify, }; |