diff options
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 118 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 5 |
6 files changed, 94 insertions, 37 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c index 7776e6f0aef6..0489c6152482 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c | |||
| @@ -150,6 +150,8 @@ struct vmw_ttm_tt { | |||
| 150 | bool mapped; | 150 | bool mapped; |
| 151 | }; | 151 | }; |
| 152 | 152 | ||
| 153 | const size_t vmw_tt_size = sizeof(struct vmw_ttm_tt); | ||
| 154 | |||
| 153 | /** | 155 | /** |
| 154 | * Helper functions to advance a struct vmw_piter iterator. | 156 | * Helper functions to advance a struct vmw_piter iterator. |
| 155 | * | 157 | * |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index db85985c7086..20890ad8408b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
| @@ -615,6 +615,7 @@ extern int vmw_mmap(struct file *filp, struct vm_area_struct *vma); | |||
| 615 | * TTM buffer object driver - vmwgfx_buffer.c | 615 | * TTM buffer object driver - vmwgfx_buffer.c |
| 616 | */ | 616 | */ |
| 617 | 617 | ||
| 618 | extern const size_t vmw_tt_size; | ||
| 618 | extern struct ttm_placement vmw_vram_placement; | 619 | extern struct ttm_placement vmw_vram_placement; |
| 619 | extern struct ttm_placement vmw_vram_ne_placement; | 620 | extern struct ttm_placement vmw_vram_ne_placement; |
| 620 | extern struct ttm_placement vmw_vram_sys_placement; | 621 | extern struct ttm_placement vmw_vram_sys_placement; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index ecb3d867b426..03f1c2038631 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -75,6 +75,7 @@ void vmw_display_unit_cleanup(struct vmw_display_unit *du) | |||
| 75 | vmw_surface_unreference(&du->cursor_surface); | 75 | vmw_surface_unreference(&du->cursor_surface); |
| 76 | if (du->cursor_dmabuf) | 76 | if (du->cursor_dmabuf) |
| 77 | vmw_dmabuf_unreference(&du->cursor_dmabuf); | 77 | vmw_dmabuf_unreference(&du->cursor_dmabuf); |
| 78 | drm_sysfs_connector_remove(&du->connector); | ||
| 78 | drm_crtc_cleanup(&du->crtc); | 79 | drm_crtc_cleanup(&du->crtc); |
| 79 | drm_encoder_cleanup(&du->encoder); | 80 | drm_encoder_cleanup(&du->encoder); |
| 80 | drm_connector_cleanup(&du->connector); | 81 | drm_connector_cleanup(&du->connector); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 79f7e8e60529..a055a26819c2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
| @@ -260,6 +260,7 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set) | |||
| 260 | connector->encoder = NULL; | 260 | connector->encoder = NULL; |
| 261 | encoder->crtc = NULL; | 261 | encoder->crtc = NULL; |
| 262 | crtc->fb = NULL; | 262 | crtc->fb = NULL; |
| 263 | crtc->enabled = false; | ||
| 263 | 264 | ||
| 264 | vmw_ldu_del_active(dev_priv, ldu); | 265 | vmw_ldu_del_active(dev_priv, ldu); |
| 265 | 266 | ||
| @@ -285,6 +286,7 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set) | |||
| 285 | crtc->x = set->x; | 286 | crtc->x = set->x; |
| 286 | crtc->y = set->y; | 287 | crtc->y = set->y; |
| 287 | crtc->mode = *mode; | 288 | crtc->mode = *mode; |
| 289 | crtc->enabled = true; | ||
| 288 | 290 | ||
| 289 | vmw_ldu_add_active(dev_priv, ldu, vfb); | 291 | vmw_ldu_add_active(dev_priv, ldu, vfb); |
| 290 | 292 | ||
| @@ -369,6 +371,8 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
| 369 | encoder->possible_crtcs = (1 << unit); | 371 | encoder->possible_crtcs = (1 << unit); |
| 370 | encoder->possible_clones = 0; | 372 | encoder->possible_clones = 0; |
| 371 | 373 | ||
| 374 | (void) drm_sysfs_connector_add(connector); | ||
| 375 | |||
| 372 | drm_crtc_init(dev, crtc, &vmw_legacy_crtc_funcs); | 376 | drm_crtc_init(dev, crtc, &vmw_legacy_crtc_funcs); |
| 373 | 377 | ||
| 374 | drm_mode_crtc_set_gamma_size(crtc, 256); | 378 | drm_mode_crtc_set_gamma_size(crtc, 256); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index efe2b74c5eb1..9b5ea2ac7ddf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
| @@ -352,6 +352,38 @@ int vmw_user_lookup_handle(struct vmw_private *dev_priv, | |||
| 352 | /** | 352 | /** |
| 353 | * Buffer management. | 353 | * Buffer management. |
| 354 | */ | 354 | */ |
| 355 | |||
| 356 | /** | ||
| 357 | * vmw_dmabuf_acc_size - Calculate the pinned memory usage of buffers | ||
| 358 | * | ||
| 359 | * @dev_priv: Pointer to a struct vmw_private identifying the device. | ||
| 360 | * @size: The requested buffer size. | ||
| 361 | * @user: Whether this is an ordinary dma buffer or a user dma buffer. | ||
| 362 | */ | ||
| 363 | static size_t vmw_dmabuf_acc_size(struct vmw_private *dev_priv, size_t size, | ||
| 364 | bool user) | ||
| 365 | { | ||
| 366 | static size_t struct_size, user_struct_size; | ||
| 367 | size_t num_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; | ||
| 368 | size_t page_array_size = ttm_round_pot(num_pages * sizeof(void *)); | ||
| 369 | |||
| 370 | if (unlikely(struct_size == 0)) { | ||
| 371 | size_t backend_size = ttm_round_pot(vmw_tt_size); | ||
| 372 | |||
| 373 | struct_size = backend_size + | ||
| 374 | ttm_round_pot(sizeof(struct vmw_dma_buffer)); | ||
| 375 | user_struct_size = backend_size + | ||
| 376 | ttm_round_pot(sizeof(struct vmw_user_dma_buffer)); | ||
| 377 | } | ||
| 378 | |||
| 379 | if (dev_priv->map_mode == vmw_dma_alloc_coherent) | ||
| 380 | page_array_size += | ||
| 381 | ttm_round_pot(num_pages * sizeof(dma_addr_t)); | ||
| 382 | |||
| 383 | return ((user) ? user_struct_size : struct_size) + | ||
| 384 | page_array_size; | ||
| 385 | } | ||
| 386 | |||
| 355 | void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo) | 387 | void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo) |
| 356 | { | 388 | { |
| 357 | struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo); | 389 | struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo); |
| @@ -359,6 +391,13 @@ void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo) | |||
| 359 | kfree(vmw_bo); | 391 | kfree(vmw_bo); |
| 360 | } | 392 | } |
| 361 | 393 | ||
| 394 | static void vmw_user_dmabuf_destroy(struct ttm_buffer_object *bo) | ||
| 395 | { | ||
| 396 | struct vmw_user_dma_buffer *vmw_user_bo = vmw_user_dma_buffer(bo); | ||
| 397 | |||
| 398 | ttm_prime_object_kfree(vmw_user_bo, prime); | ||
| 399 | } | ||
| 400 | |||
| 362 | int vmw_dmabuf_init(struct vmw_private *dev_priv, | 401 | int vmw_dmabuf_init(struct vmw_private *dev_priv, |
| 363 | struct vmw_dma_buffer *vmw_bo, | 402 | struct vmw_dma_buffer *vmw_bo, |
| 364 | size_t size, struct ttm_placement *placement, | 403 | size_t size, struct ttm_placement *placement, |
| @@ -368,28 +407,23 @@ int vmw_dmabuf_init(struct vmw_private *dev_priv, | |||
| 368 | struct ttm_bo_device *bdev = &dev_priv->bdev; | 407 | struct ttm_bo_device *bdev = &dev_priv->bdev; |
| 369 | size_t acc_size; | 408 | size_t acc_size; |
| 370 | int ret; | 409 | int ret; |
| 410 | bool user = (bo_free == &vmw_user_dmabuf_destroy); | ||
| 371 | 411 | ||
| 372 | BUG_ON(!bo_free); | 412 | BUG_ON(!bo_free && (!user && (bo_free != vmw_dmabuf_bo_free))); |
| 373 | 413 | ||
| 374 | acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct vmw_dma_buffer)); | 414 | acc_size = vmw_dmabuf_acc_size(dev_priv, size, user); |
| 375 | memset(vmw_bo, 0, sizeof(*vmw_bo)); | 415 | memset(vmw_bo, 0, sizeof(*vmw_bo)); |
| 376 | 416 | ||
| 377 | INIT_LIST_HEAD(&vmw_bo->res_list); | 417 | INIT_LIST_HEAD(&vmw_bo->res_list); |
| 378 | 418 | ||
| 379 | ret = ttm_bo_init(bdev, &vmw_bo->base, size, | 419 | ret = ttm_bo_init(bdev, &vmw_bo->base, size, |
| 380 | ttm_bo_type_device, placement, | 420 | (user) ? ttm_bo_type_device : |
| 421 | ttm_bo_type_kernel, placement, | ||
| 381 | 0, interruptible, | 422 | 0, interruptible, |
| 382 | NULL, acc_size, NULL, bo_free); | 423 | NULL, acc_size, NULL, bo_free); |
| 383 | return ret; | 424 | return ret; |
| 384 | } | 425 | } |
| 385 | 426 | ||
| 386 | static void vmw_user_dmabuf_destroy(struct ttm_buffer_object *bo) | ||
| 387 | { | ||
| 388 | struct vmw_user_dma_buffer *vmw_user_bo = vmw_user_dma_buffer(bo); | ||
| 389 | |||
| 390 | ttm_prime_object_kfree(vmw_user_bo, prime); | ||
| 391 | } | ||
| 392 | |||
| 393 | static void vmw_user_dmabuf_release(struct ttm_base_object **p_base) | 427 | static void vmw_user_dmabuf_release(struct ttm_base_object **p_base) |
| 394 | { | 428 | { |
| 395 | struct vmw_user_dma_buffer *vmw_user_bo; | 429 | struct vmw_user_dma_buffer *vmw_user_bo; |
| @@ -781,54 +815,55 @@ err_ref: | |||
| 781 | } | 815 | } |
| 782 | 816 | ||
| 783 | 817 | ||
| 818 | /** | ||
| 819 | * vmw_dumb_create - Create a dumb kms buffer | ||
| 820 | * | ||
| 821 | * @file_priv: Pointer to a struct drm_file identifying the caller. | ||
| 822 | * @dev: Pointer to the drm device. | ||
| 823 | * @args: Pointer to a struct drm_mode_create_dumb structure | ||
| 824 | * | ||
| 825 | * This is a driver callback for the core drm create_dumb functionality. | ||
| 826 | * Note that this is very similar to the vmw_dmabuf_alloc ioctl, except | ||
| 827 | * that the arguments have a different format. | ||
| 828 | */ | ||
| 784 | int vmw_dumb_create(struct drm_file *file_priv, | 829 | int vmw_dumb_create(struct drm_file *file_priv, |
| 785 | struct drm_device *dev, | 830 | struct drm_device *dev, |
| 786 | struct drm_mode_create_dumb *args) | 831 | struct drm_mode_create_dumb *args) |
| 787 | { | 832 | { |
| 788 | struct vmw_private *dev_priv = vmw_priv(dev); | 833 | struct vmw_private *dev_priv = vmw_priv(dev); |
| 789 | struct vmw_master *vmaster = vmw_master(file_priv->master); | 834 | struct vmw_master *vmaster = vmw_master(file_priv->master); |
| 790 | struct vmw_user_dma_buffer *vmw_user_bo; | 835 | struct vmw_dma_buffer *dma_buf; |
| 791 | struct ttm_buffer_object *tmp; | ||
| 792 | int ret; | 836 | int ret; |
| 793 | 837 | ||
| 794 | args->pitch = args->width * ((args->bpp + 7) / 8); | 838 | args->pitch = args->width * ((args->bpp + 7) / 8); |
| 795 | args->size = args->pitch * args->height; | 839 | args->size = args->pitch * args->height; |
| 796 | 840 | ||
| 797 | vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL); | ||
| 798 | if (vmw_user_bo == NULL) | ||
| 799 | return -ENOMEM; | ||
| 800 | |||
| 801 | ret = ttm_read_lock(&vmaster->lock, true); | 841 | ret = ttm_read_lock(&vmaster->lock, true); |
| 802 | if (ret != 0) { | 842 | if (unlikely(ret != 0)) |
| 803 | kfree(vmw_user_bo); | ||
| 804 | return ret; | 843 | return ret; |
| 805 | } | ||
| 806 | 844 | ||
| 807 | ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size, | 845 | ret = vmw_user_dmabuf_alloc(dev_priv, vmw_fpriv(file_priv)->tfile, |
| 808 | &vmw_vram_sys_placement, true, | 846 | args->size, false, &args->handle, |
| 809 | &vmw_user_dmabuf_destroy); | 847 | &dma_buf); |
| 810 | if (ret != 0) | ||
| 811 | goto out_no_dmabuf; | ||
| 812 | |||
| 813 | tmp = ttm_bo_reference(&vmw_user_bo->dma.base); | ||
| 814 | ret = ttm_prime_object_init(vmw_fpriv(file_priv)->tfile, | ||
| 815 | args->size, | ||
| 816 | &vmw_user_bo->prime, | ||
| 817 | false, | ||
| 818 | ttm_buffer_type, | ||
| 819 | &vmw_user_dmabuf_release, NULL); | ||
| 820 | if (unlikely(ret != 0)) | 848 | if (unlikely(ret != 0)) |
| 821 | goto out_no_base_object; | 849 | goto out_no_dmabuf; |
| 822 | |||
| 823 | args->handle = vmw_user_bo->prime.base.hash.key; | ||
| 824 | 850 | ||
| 825 | out_no_base_object: | 851 | vmw_dmabuf_unreference(&dma_buf); |
| 826 | ttm_bo_unref(&tmp); | ||
| 827 | out_no_dmabuf: | 852 | out_no_dmabuf: |
| 828 | ttm_read_unlock(&vmaster->lock); | 853 | ttm_read_unlock(&vmaster->lock); |
| 829 | return ret; | 854 | return ret; |
| 830 | } | 855 | } |
| 831 | 856 | ||
| 857 | /** | ||
| 858 | * vmw_dumb_map_offset - Return the address space offset of a dumb buffer | ||
| 859 | * | ||
| 860 | * @file_priv: Pointer to a struct drm_file identifying the caller. | ||
| 861 | * @dev: Pointer to the drm device. | ||
| 862 | * @handle: Handle identifying the dumb buffer. | ||
| 863 | * @offset: The address space offset returned. | ||
| 864 | * | ||
| 865 | * This is a driver callback for the core drm dumb_map_offset functionality. | ||
| 866 | */ | ||
| 832 | int vmw_dumb_map_offset(struct drm_file *file_priv, | 867 | int vmw_dumb_map_offset(struct drm_file *file_priv, |
| 833 | struct drm_device *dev, uint32_t handle, | 868 | struct drm_device *dev, uint32_t handle, |
| 834 | uint64_t *offset) | 869 | uint64_t *offset) |
| @@ -846,6 +881,15 @@ int vmw_dumb_map_offset(struct drm_file *file_priv, | |||
| 846 | return 0; | 881 | return 0; |
| 847 | } | 882 | } |
| 848 | 883 | ||
| 884 | /** | ||
| 885 | * vmw_dumb_destroy - Destroy a dumb boffer | ||
| 886 | * | ||
| 887 | * @file_priv: Pointer to a struct drm_file identifying the caller. | ||
| 888 | * @dev: Pointer to the drm device. | ||
| 889 | * @handle: Handle identifying the dumb buffer. | ||
| 890 | * | ||
| 891 | * This is a driver callback for the core drm dumb_destroy functionality. | ||
| 892 | */ | ||
| 849 | int vmw_dumb_destroy(struct drm_file *file_priv, | 893 | int vmw_dumb_destroy(struct drm_file *file_priv, |
| 850 | struct drm_device *dev, | 894 | struct drm_device *dev, |
| 851 | uint32_t handle) | 895 | uint32_t handle) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 26387c3d5a21..22406c8651ea 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | |||
| @@ -310,6 +310,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) | |||
| 310 | crtc->fb = NULL; | 310 | crtc->fb = NULL; |
| 311 | crtc->x = 0; | 311 | crtc->x = 0; |
| 312 | crtc->y = 0; | 312 | crtc->y = 0; |
| 313 | crtc->enabled = false; | ||
| 313 | 314 | ||
| 314 | vmw_sou_del_active(dev_priv, sou); | 315 | vmw_sou_del_active(dev_priv, sou); |
| 315 | 316 | ||
| @@ -370,6 +371,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) | |||
| 370 | crtc->fb = NULL; | 371 | crtc->fb = NULL; |
| 371 | crtc->x = 0; | 372 | crtc->x = 0; |
| 372 | crtc->y = 0; | 373 | crtc->y = 0; |
| 374 | crtc->enabled = false; | ||
| 373 | 375 | ||
| 374 | return ret; | 376 | return ret; |
| 375 | } | 377 | } |
| @@ -382,6 +384,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) | |||
| 382 | crtc->fb = fb; | 384 | crtc->fb = fb; |
| 383 | crtc->x = set->x; | 385 | crtc->x = set->x; |
| 384 | crtc->y = set->y; | 386 | crtc->y = set->y; |
| 387 | crtc->enabled = true; | ||
| 385 | 388 | ||
| 386 | return 0; | 389 | return 0; |
| 387 | } | 390 | } |
| @@ -464,6 +467,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) | |||
| 464 | encoder->possible_crtcs = (1 << unit); | 467 | encoder->possible_crtcs = (1 << unit); |
| 465 | encoder->possible_clones = 0; | 468 | encoder->possible_clones = 0; |
| 466 | 469 | ||
| 470 | (void) drm_sysfs_connector_add(connector); | ||
| 471 | |||
| 467 | drm_crtc_init(dev, crtc, &vmw_screen_object_crtc_funcs); | 472 | drm_crtc_init(dev, crtc, &vmw_screen_object_crtc_funcs); |
| 468 | 473 | ||
| 469 | drm_mode_crtc_set_gamma_size(crtc, 256); | 474 | drm_mode_crtc_set_gamma_size(crtc, 256); |
