diff options
| -rw-r--r-- | drivers/gpu/drm/qxl/qxl_cmd.c | 22 | ||||
| -rw-r--r-- | drivers/gpu/drm/qxl/qxl_display.c | 49 | ||||
| -rw-r--r-- | drivers/gpu/drm/qxl/qxl_drv.h | 28 | ||||
| -rw-r--r-- | drivers/gpu/drm/qxl/qxl_dumb.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/qxl/qxl_fb.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/qxl/qxl_release.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/qxl/qxl_ttm.c | 4 |
7 files changed, 71 insertions, 51 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index 74fc9362ecf9..c0fb52c6d4ca 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c | |||
| @@ -219,7 +219,7 @@ int qxl_garbage_collect(struct qxl_device *qdev) | |||
| 219 | union qxl_release_info *info; | 219 | union qxl_release_info *info; |
| 220 | 220 | ||
| 221 | while (qxl_ring_pop(qdev->release_ring, &id)) { | 221 | while (qxl_ring_pop(qdev->release_ring, &id)) { |
| 222 | QXL_INFO(qdev, "popped %lld\n", id); | 222 | DRM_DEBUG_DRIVER("popped %lld\n", id); |
| 223 | while (id) { | 223 | while (id) { |
| 224 | release = qxl_release_from_id_locked(qdev, id); | 224 | release = qxl_release_from_id_locked(qdev, id); |
| 225 | if (release == NULL) | 225 | if (release == NULL) |
| @@ -229,8 +229,8 @@ int qxl_garbage_collect(struct qxl_device *qdev) | |||
| 229 | next_id = info->next; | 229 | next_id = info->next; |
| 230 | qxl_release_unmap(qdev, release, info); | 230 | qxl_release_unmap(qdev, release, info); |
| 231 | 231 | ||
| 232 | QXL_INFO(qdev, "popped %lld, next %lld\n", id, | 232 | DRM_DEBUG_DRIVER("popped %lld, next %lld\n", id, |
| 233 | next_id); | 233 | next_id); |
| 234 | 234 | ||
| 235 | switch (release->type) { | 235 | switch (release->type) { |
| 236 | case QXL_RELEASE_DRAWABLE: | 236 | case QXL_RELEASE_DRAWABLE: |
| @@ -248,7 +248,7 @@ int qxl_garbage_collect(struct qxl_device *qdev) | |||
| 248 | } | 248 | } |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | QXL_INFO(qdev, "%s: %d\n", __func__, i); | 251 | DRM_DEBUG_DRIVER("%d\n", i); |
| 252 | 252 | ||
| 253 | return i; | 253 | return i; |
| 254 | } | 254 | } |
| @@ -381,17 +381,19 @@ void qxl_io_create_primary(struct qxl_device *qdev, | |||
| 381 | { | 381 | { |
| 382 | struct qxl_surface_create *create; | 382 | struct qxl_surface_create *create; |
| 383 | 383 | ||
| 384 | QXL_INFO(qdev, "%s: qdev %p, ram_header %p\n", __func__, qdev, | 384 | DRM_DEBUG_DRIVER("qdev %p, ram_header %p\n", qdev, qdev->ram_header); |
| 385 | qdev->ram_header); | ||
| 386 | create = &qdev->ram_header->create_surface; | 385 | create = &qdev->ram_header->create_surface; |
| 387 | create->format = bo->surf.format; | 386 | create->format = bo->surf.format; |
| 388 | create->width = bo->surf.width; | 387 | create->width = bo->surf.width; |
| 389 | create->height = bo->surf.height; | 388 | create->height = bo->surf.height; |
| 390 | create->stride = bo->surf.stride; | 389 | create->stride = bo->surf.stride; |
| 391 | create->mem = qxl_bo_physical_address(qdev, bo, offset); | 390 | if (bo->shadow) { |
| 391 | create->mem = qxl_bo_physical_address(qdev, bo->shadow, offset); | ||
| 392 | } else { | ||
| 393 | create->mem = qxl_bo_physical_address(qdev, bo, offset); | ||
| 394 | } | ||
| 392 | 395 | ||
| 393 | QXL_INFO(qdev, "%s: mem = %llx, from %p\n", __func__, create->mem, | 396 | DRM_DEBUG_DRIVER("mem = %llx, from %p\n", create->mem, bo->kptr); |
| 394 | bo->kptr); | ||
| 395 | 397 | ||
| 396 | create->flags = QXL_SURF_FLAG_KEEP_DATA; | 398 | create->flags = QXL_SURF_FLAG_KEEP_DATA; |
| 397 | create->type = QXL_SURF_TYPE_PRIMARY; | 399 | create->type = QXL_SURF_TYPE_PRIMARY; |
| @@ -401,7 +403,7 @@ void qxl_io_create_primary(struct qxl_device *qdev, | |||
| 401 | 403 | ||
| 402 | void qxl_io_memslot_add(struct qxl_device *qdev, uint8_t id) | 404 | void qxl_io_memslot_add(struct qxl_device *qdev, uint8_t id) |
| 403 | { | 405 | { |
| 404 | QXL_INFO(qdev, "qxl_memslot_add %d\n", id); | 406 | DRM_DEBUG_DRIVER("qxl_memslot_add %d\n", id); |
| 405 | wait_for_io_cmd(qdev, id, QXL_IO_MEMSLOT_ADD_ASYNC); | 407 | wait_for_io_cmd(qdev, id, QXL_IO_MEMSLOT_ADD_ASYNC); |
| 406 | } | 408 | } |
| 407 | 409 | ||
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index afbf50d0c08f..4756b3c9bf2c 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c | |||
| @@ -305,7 +305,9 @@ static const struct drm_crtc_funcs qxl_crtc_funcs = { | |||
| 305 | void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) | 305 | void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) |
| 306 | { | 306 | { |
| 307 | struct qxl_framebuffer *qxl_fb = to_qxl_framebuffer(fb); | 307 | struct qxl_framebuffer *qxl_fb = to_qxl_framebuffer(fb); |
| 308 | struct qxl_bo *bo = gem_to_qxl_bo(qxl_fb->obj); | ||
| 308 | 309 | ||
| 310 | WARN_ON(bo->shadow); | ||
| 309 | drm_gem_object_unreference_unlocked(qxl_fb->obj); | 311 | drm_gem_object_unreference_unlocked(qxl_fb->obj); |
| 310 | drm_framebuffer_cleanup(fb); | 312 | drm_framebuffer_cleanup(fb); |
| 311 | kfree(qxl_fb); | 313 | kfree(qxl_fb); |
| @@ -508,6 +510,7 @@ static void qxl_primary_atomic_update(struct drm_plane *plane, | |||
| 508 | .x2 = qfb->base.width, | 510 | .x2 = qfb->base.width, |
| 509 | .y2 = qfb->base.height | 511 | .y2 = qfb->base.height |
| 510 | }; | 512 | }; |
| 513 | bool same_shadow = false; | ||
| 511 | 514 | ||
| 512 | if (old_state->fb) { | 515 | if (old_state->fb) { |
| 513 | qfb_old = to_qxl_framebuffer(old_state->fb); | 516 | qfb_old = to_qxl_framebuffer(old_state->fb); |
| @@ -519,15 +522,23 @@ static void qxl_primary_atomic_update(struct drm_plane *plane, | |||
| 519 | if (bo == bo_old) | 522 | if (bo == bo_old) |
| 520 | return; | 523 | return; |
| 521 | 524 | ||
| 525 | if (bo_old && bo_old->shadow && bo->shadow && | ||
| 526 | bo_old->shadow == bo->shadow) { | ||
| 527 | same_shadow = true; | ||
| 528 | } | ||
| 529 | |||
| 522 | if (bo_old && bo_old->is_primary) { | 530 | if (bo_old && bo_old->is_primary) { |
| 523 | qxl_io_destroy_primary(qdev); | 531 | if (!same_shadow) |
| 532 | qxl_io_destroy_primary(qdev); | ||
| 524 | bo_old->is_primary = false; | 533 | bo_old->is_primary = false; |
| 525 | } | 534 | } |
| 526 | 535 | ||
| 527 | if (!bo->is_primary) { | 536 | if (!bo->is_primary) { |
| 528 | qxl_io_create_primary(qdev, 0, bo); | 537 | if (!same_shadow) |
| 538 | qxl_io_create_primary(qdev, 0, bo); | ||
| 529 | bo->is_primary = true; | 539 | bo->is_primary = true; |
| 530 | } | 540 | } |
| 541 | |||
| 531 | qxl_draw_dirty_fb(qdev, qfb, bo, 0, 0, &norect, 1, 1); | 542 | qxl_draw_dirty_fb(qdev, qfb, bo, 0, 0, &norect, 1, 1); |
| 532 | } | 543 | } |
| 533 | 544 | ||
| @@ -679,8 +690,9 @@ static void qxl_cursor_atomic_disable(struct drm_plane *plane, | |||
| 679 | static int qxl_plane_prepare_fb(struct drm_plane *plane, | 690 | static int qxl_plane_prepare_fb(struct drm_plane *plane, |
| 680 | struct drm_plane_state *new_state) | 691 | struct drm_plane_state *new_state) |
| 681 | { | 692 | { |
| 693 | struct qxl_device *qdev = plane->dev->dev_private; | ||
| 682 | struct drm_gem_object *obj; | 694 | struct drm_gem_object *obj; |
| 683 | struct qxl_bo *user_bo; | 695 | struct qxl_bo *user_bo, *old_bo = NULL; |
| 684 | int ret; | 696 | int ret; |
| 685 | 697 | ||
| 686 | if (!new_state->fb) | 698 | if (!new_state->fb) |
| @@ -689,6 +701,32 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, | |||
| 689 | obj = to_qxl_framebuffer(new_state->fb)->obj; | 701 | obj = to_qxl_framebuffer(new_state->fb)->obj; |
| 690 | user_bo = gem_to_qxl_bo(obj); | 702 | user_bo = gem_to_qxl_bo(obj); |
| 691 | 703 | ||
| 704 | if (plane->type == DRM_PLANE_TYPE_PRIMARY && | ||
| 705 | user_bo->is_dumb && !user_bo->shadow) { | ||
| 706 | if (plane->state->fb) { | ||
| 707 | obj = to_qxl_framebuffer(plane->state->fb)->obj; | ||
| 708 | old_bo = gem_to_qxl_bo(obj); | ||
| 709 | } | ||
| 710 | if (old_bo && old_bo->shadow && | ||
| 711 | user_bo->gem_base.size == old_bo->gem_base.size && | ||
| 712 | plane->state->crtc == new_state->crtc && | ||
| 713 | plane->state->crtc_w == new_state->crtc_w && | ||
| 714 | plane->state->crtc_h == new_state->crtc_h && | ||
| 715 | plane->state->src_x == new_state->src_x && | ||
| 716 | plane->state->src_y == new_state->src_y && | ||
| 717 | plane->state->src_w == new_state->src_w && | ||
| 718 | plane->state->src_h == new_state->src_h && | ||
| 719 | plane->state->rotation == new_state->rotation && | ||
| 720 | plane->state->zpos == new_state->zpos) { | ||
| 721 | drm_gem_object_get(&old_bo->shadow->gem_base); | ||
| 722 | user_bo->shadow = old_bo->shadow; | ||
| 723 | } else { | ||
| 724 | qxl_bo_create(qdev, user_bo->gem_base.size, | ||
| 725 | true, true, QXL_GEM_DOMAIN_VRAM, NULL, | ||
| 726 | &user_bo->shadow); | ||
| 727 | } | ||
| 728 | } | ||
| 729 | |||
| 692 | ret = qxl_bo_pin(user_bo, QXL_GEM_DOMAIN_CPU, NULL); | 730 | ret = qxl_bo_pin(user_bo, QXL_GEM_DOMAIN_CPU, NULL); |
| 693 | if (ret) | 731 | if (ret) |
| 694 | return ret; | 732 | return ret; |
| @@ -713,6 +751,11 @@ static void qxl_plane_cleanup_fb(struct drm_plane *plane, | |||
| 713 | obj = to_qxl_framebuffer(old_state->fb)->obj; | 751 | obj = to_qxl_framebuffer(old_state->fb)->obj; |
| 714 | user_bo = gem_to_qxl_bo(obj); | 752 | user_bo = gem_to_qxl_bo(obj); |
| 715 | qxl_bo_unpin(user_bo); | 753 | qxl_bo_unpin(user_bo); |
| 754 | |||
| 755 | if (user_bo->shadow && !user_bo->is_primary) { | ||
| 756 | drm_gem_object_put_unlocked(&user_bo->shadow->gem_base); | ||
| 757 | user_bo->shadow = NULL; | ||
| 758 | } | ||
| 716 | } | 759 | } |
| 717 | 760 | ||
| 718 | static const uint32_t qxl_cursor_plane_formats[] = { | 761 | static const uint32_t qxl_cursor_plane_formats[] = { |
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 3397a1907336..08752c0ffb35 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h | |||
| @@ -62,33 +62,9 @@ | |||
| 62 | 62 | ||
| 63 | #define QXL_DEBUGFS_MAX_COMPONENTS 32 | 63 | #define QXL_DEBUGFS_MAX_COMPONENTS 32 |
| 64 | 64 | ||
| 65 | extern int qxl_log_level; | ||
| 66 | extern int qxl_num_crtc; | 65 | extern int qxl_num_crtc; |
| 67 | extern int qxl_max_ioctls; | 66 | extern int qxl_max_ioctls; |
| 68 | 67 | ||
| 69 | enum { | ||
| 70 | QXL_INFO_LEVEL = 1, | ||
| 71 | QXL_DEBUG_LEVEL = 2, | ||
| 72 | }; | ||
| 73 | |||
| 74 | #define QXL_INFO(qdev, fmt, ...) do { \ | ||
| 75 | if (qxl_log_level >= QXL_INFO_LEVEL) { \ | ||
| 76 | qxl_io_log(qdev, fmt, __VA_ARGS__); \ | ||
| 77 | } \ | ||
| 78 | } while (0) | ||
| 79 | #define QXL_DEBUG(qdev, fmt, ...) do { \ | ||
| 80 | if (qxl_log_level >= QXL_DEBUG_LEVEL) { \ | ||
| 81 | qxl_io_log(qdev, fmt, __VA_ARGS__); \ | ||
| 82 | } \ | ||
| 83 | } while (0) | ||
| 84 | #define QXL_INFO_ONCE(qdev, fmt, ...) do { \ | ||
| 85 | static int done; \ | ||
| 86 | if (!done) { \ | ||
| 87 | done = 1; \ | ||
| 88 | QXL_INFO(qdev, fmt, __VA_ARGS__); \ | ||
| 89 | } \ | ||
| 90 | } while (0) | ||
| 91 | |||
| 92 | #define DRM_FILE_OFFSET 0x100000000ULL | 68 | #define DRM_FILE_OFFSET 0x100000000ULL |
| 93 | #define DRM_FILE_PAGE_OFFSET (DRM_FILE_OFFSET >> PAGE_SHIFT) | 69 | #define DRM_FILE_PAGE_OFFSET (DRM_FILE_OFFSET >> PAGE_SHIFT) |
| 94 | 70 | ||
| @@ -113,6 +89,8 @@ struct qxl_bo { | |||
| 113 | /* Constant after initialization */ | 89 | /* Constant after initialization */ |
| 114 | struct drm_gem_object gem_base; | 90 | struct drm_gem_object gem_base; |
| 115 | bool is_primary; /* is this now a primary surface */ | 91 | bool is_primary; /* is this now a primary surface */ |
| 92 | bool is_dumb; | ||
| 93 | struct qxl_bo *shadow; | ||
| 116 | bool hw_surf_alloc; | 94 | bool hw_surf_alloc; |
| 117 | struct qxl_surface surf; | 95 | struct qxl_surface surf; |
| 118 | uint32_t surface_id; | 96 | uint32_t surface_id; |
| @@ -351,7 +329,7 @@ int qxl_check_idle(struct qxl_ring *ring); | |||
| 351 | static inline void * | 329 | static inline void * |
| 352 | qxl_fb_virtual_address(struct qxl_device *qdev, unsigned long physical) | 330 | qxl_fb_virtual_address(struct qxl_device *qdev, unsigned long physical) |
| 353 | { | 331 | { |
| 354 | QXL_INFO(qdev, "not implemented (%lu)\n", physical); | 332 | DRM_DEBUG_DRIVER("not implemented (%lu)\n", physical); |
| 355 | return 0; | 333 | return 0; |
| 356 | } | 334 | } |
| 357 | 335 | ||
diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c index 5e65d5d2d937..11085ab01374 100644 --- a/drivers/gpu/drm/qxl/qxl_dumb.c +++ b/drivers/gpu/drm/qxl/qxl_dumb.c | |||
| @@ -63,6 +63,7 @@ int qxl_mode_dumb_create(struct drm_file *file_priv, | |||
| 63 | &handle); | 63 | &handle); |
| 64 | if (r) | 64 | if (r) |
| 65 | return r; | 65 | return r; |
| 66 | qobj->is_dumb = true; | ||
| 66 | args->pitch = pitch; | 67 | args->pitch = pitch; |
| 67 | args->handle = handle; | 68 | args->handle = handle; |
| 68 | return 0; | 69 | return 0; |
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index 844c4a31ca13..23af3e352673 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c | |||
| @@ -240,18 +240,15 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, | |||
| 240 | return ret; | 240 | return ret; |
| 241 | 241 | ||
| 242 | qbo = gem_to_qxl_bo(gobj); | 242 | qbo = gem_to_qxl_bo(gobj); |
| 243 | QXL_INFO(qdev, "%s: %dx%d %d\n", __func__, mode_cmd.width, | 243 | DRM_DEBUG_DRIVER("%dx%d %d\n", mode_cmd.width, |
| 244 | mode_cmd.height, mode_cmd.pitches[0]); | 244 | mode_cmd.height, mode_cmd.pitches[0]); |
| 245 | 245 | ||
| 246 | shadow = vmalloc(mode_cmd.pitches[0] * mode_cmd.height); | 246 | shadow = vmalloc(mode_cmd.pitches[0] * mode_cmd.height); |
| 247 | /* TODO: what's the usual response to memory allocation errors? */ | 247 | /* TODO: what's the usual response to memory allocation errors? */ |
| 248 | BUG_ON(!shadow); | 248 | BUG_ON(!shadow); |
| 249 | QXL_INFO(qdev, | 249 | DRM_DEBUG_DRIVER("surface0 at gpu offset %lld, mmap_offset %lld (virt %p, shadow %p)\n", |
| 250 | "surface0 at gpu offset %lld, mmap_offset %lld (virt %p, shadow %p)\n", | 250 | qxl_bo_gpu_offset(qbo), qxl_bo_mmap_offset(qbo), |
| 251 | qxl_bo_gpu_offset(qbo), | 251 | qbo->kptr, shadow); |
| 252 | qxl_bo_mmap_offset(qbo), | ||
| 253 | qbo->kptr, | ||
| 254 | shadow); | ||
| 255 | size = mode_cmd.pitches[0] * mode_cmd.height; | 252 | size = mode_cmd.pitches[0] * mode_cmd.height; |
| 256 | 253 | ||
| 257 | info = drm_fb_helper_alloc_fbi(&qfbdev->helper); | 254 | info = drm_fb_helper_alloc_fbi(&qfbdev->helper); |
diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index e6ec845b5be0..a6da6fa6ad58 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c | |||
| @@ -154,7 +154,7 @@ qxl_release_alloc(struct qxl_device *qdev, int type, | |||
| 154 | return handle; | 154 | return handle; |
| 155 | } | 155 | } |
| 156 | *ret = release; | 156 | *ret = release; |
| 157 | QXL_INFO(qdev, "allocated release %d\n", handle); | 157 | DRM_DEBUG_DRIVER("allocated release %d\n", handle); |
| 158 | release->id = handle; | 158 | release->id = handle; |
| 159 | return handle; | 159 | return handle; |
| 160 | } | 160 | } |
| @@ -179,8 +179,7 @@ void | |||
| 179 | qxl_release_free(struct qxl_device *qdev, | 179 | qxl_release_free(struct qxl_device *qdev, |
| 180 | struct qxl_release *release) | 180 | struct qxl_release *release) |
| 181 | { | 181 | { |
| 182 | QXL_INFO(qdev, "release %d, type %d\n", release->id, | 182 | DRM_DEBUG_DRIVER("release %d, type %d\n", release->id, release->type); |
| 183 | release->type); | ||
| 184 | 183 | ||
| 185 | if (release->surface_release_id) | 184 | if (release->surface_release_id) |
| 186 | qxl_surface_id_dealloc(qdev, release->surface_release_id); | 185 | qxl_surface_id_dealloc(qdev, release->surface_release_id); |
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 7ecf8a4b9fe6..ab4823875311 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c | |||
| @@ -136,8 +136,8 @@ int qxl_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 136 | "filp->private_data->minor->dev->dev_private == NULL\n"); | 136 | "filp->private_data->minor->dev->dev_private == NULL\n"); |
| 137 | return -EINVAL; | 137 | return -EINVAL; |
| 138 | } | 138 | } |
| 139 | QXL_INFO(qdev, "%s: filp->private_data = 0x%p, vma->vm_pgoff = %lx\n", | 139 | DRM_DEBUG_DRIVER("filp->private_data = 0x%p, vma->vm_pgoff = %lx\n", |
| 140 | __func__, filp->private_data, vma->vm_pgoff); | 140 | filp->private_data, vma->vm_pgoff); |
| 141 | 141 | ||
| 142 | r = ttm_bo_mmap(filp, vma, &qdev->mman.bdev); | 142 | r = ttm_bo_mmap(filp, vma, &qdev->mman.bdev); |
| 143 | if (unlikely(r != 0)) | 143 | if (unlikely(r != 0)) |
