| .. | .. |
|---|
| 24 | 24 | * USE OR OTHER DEALINGS IN THE SOFTWARE. |
|---|
| 25 | 25 | * |
|---|
| 26 | 26 | **************************************************************************/ |
|---|
| 27 | | -#include <linux/module.h> |
|---|
| 28 | | -#include <linux/console.h> |
|---|
| 29 | 27 | |
|---|
| 30 | | -#include <drm/drmP.h> |
|---|
| 31 | | -#include "vmwgfx_drv.h" |
|---|
| 32 | | -#include "vmwgfx_binding.h" |
|---|
| 33 | | -#include <drm/ttm/ttm_placement.h> |
|---|
| 28 | +#include <linux/console.h> |
|---|
| 29 | +#include <linux/dma-mapping.h> |
|---|
| 30 | +#include <linux/module.h> |
|---|
| 31 | +#include <linux/pci.h> |
|---|
| 32 | +#include <linux/mem_encrypt.h> |
|---|
| 33 | + |
|---|
| 34 | +#include <drm/drm_drv.h> |
|---|
| 35 | +#include <drm/drm_ioctl.h> |
|---|
| 36 | +#include <drm/drm_sysfs.h> |
|---|
| 34 | 37 | #include <drm/ttm/ttm_bo_driver.h> |
|---|
| 35 | | -#include <drm/ttm/ttm_object.h> |
|---|
| 36 | 38 | #include <drm/ttm/ttm_module.h> |
|---|
| 37 | | -#include <linux/dma_remapping.h> |
|---|
| 39 | +#include <drm/ttm/ttm_placement.h> |
|---|
| 40 | + |
|---|
| 41 | +#include "ttm_object.h" |
|---|
| 42 | +#include "vmwgfx_binding.h" |
|---|
| 43 | +#include "vmwgfx_drv.h" |
|---|
| 38 | 44 | |
|---|
| 39 | 45 | #define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices" |
|---|
| 40 | 46 | #define VMWGFX_CHIP_SVGAII 0 |
|---|
| .. | .. |
|---|
| 48 | 54 | #endif |
|---|
| 49 | 55 | |
|---|
| 50 | 56 | #define VMWGFX_REPO "In Tree" |
|---|
| 57 | + |
|---|
| 58 | +#define VMWGFX_VALIDATION_MEM_GRAN (16*PAGE_SIZE) |
|---|
| 51 | 59 | |
|---|
| 52 | 60 | |
|---|
| 53 | 61 | /** |
|---|
| .. | .. |
|---|
| 143 | 151 | #define DRM_IOCTL_VMW_GB_SURFACE_REF_EXT \ |
|---|
| 144 | 152 | DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_GB_SURFACE_REF_EXT, \ |
|---|
| 145 | 153 | union drm_vmw_gb_surface_reference_ext_arg) |
|---|
| 154 | +#define DRM_IOCTL_VMW_MSG \ |
|---|
| 155 | + DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_MSG, \ |
|---|
| 156 | + struct drm_vmw_msg_arg) |
|---|
| 146 | 157 | |
|---|
| 147 | 158 | /** |
|---|
| 148 | 159 | * The core DRM version of this macro doesn't account for |
|---|
| .. | .. |
|---|
| 158 | 169 | |
|---|
| 159 | 170 | static const struct drm_ioctl_desc vmw_ioctls[] = { |
|---|
| 160 | 171 | VMW_IOCTL_DEF(VMW_GET_PARAM, vmw_getparam_ioctl, |
|---|
| 161 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 172 | + DRM_RENDER_ALLOW), |
|---|
| 162 | 173 | VMW_IOCTL_DEF(VMW_ALLOC_DMABUF, vmw_bo_alloc_ioctl, |
|---|
| 163 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 174 | + DRM_RENDER_ALLOW), |
|---|
| 164 | 175 | VMW_IOCTL_DEF(VMW_UNREF_DMABUF, vmw_bo_unref_ioctl, |
|---|
| 165 | 176 | DRM_RENDER_ALLOW), |
|---|
| 166 | 177 | VMW_IOCTL_DEF(VMW_CURSOR_BYPASS, |
|---|
| .. | .. |
|---|
| 175 | 186 | DRM_MASTER), |
|---|
| 176 | 187 | |
|---|
| 177 | 188 | VMW_IOCTL_DEF(VMW_CREATE_CONTEXT, vmw_context_define_ioctl, |
|---|
| 178 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 189 | + DRM_RENDER_ALLOW), |
|---|
| 179 | 190 | VMW_IOCTL_DEF(VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, |
|---|
| 180 | 191 | DRM_RENDER_ALLOW), |
|---|
| 181 | 192 | VMW_IOCTL_DEF(VMW_CREATE_SURFACE, vmw_surface_define_ioctl, |
|---|
| 182 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 193 | + DRM_RENDER_ALLOW), |
|---|
| 183 | 194 | VMW_IOCTL_DEF(VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, |
|---|
| 184 | 195 | DRM_RENDER_ALLOW), |
|---|
| 185 | 196 | VMW_IOCTL_DEF(VMW_REF_SURFACE, vmw_surface_reference_ioctl, |
|---|
| 186 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 187 | | - VMW_IOCTL_DEF(VMW_EXECBUF, NULL, DRM_AUTH | |
|---|
| 197 | + DRM_RENDER_ALLOW), |
|---|
| 198 | + VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl, |
|---|
| 188 | 199 | DRM_RENDER_ALLOW), |
|---|
| 189 | 200 | VMW_IOCTL_DEF(VMW_FENCE_WAIT, vmw_fence_obj_wait_ioctl, |
|---|
| 190 | 201 | DRM_RENDER_ALLOW), |
|---|
| .. | .. |
|---|
| 194 | 205 | VMW_IOCTL_DEF(VMW_FENCE_UNREF, vmw_fence_obj_unref_ioctl, |
|---|
| 195 | 206 | DRM_RENDER_ALLOW), |
|---|
| 196 | 207 | VMW_IOCTL_DEF(VMW_FENCE_EVENT, vmw_fence_event_ioctl, |
|---|
| 197 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 208 | + DRM_RENDER_ALLOW), |
|---|
| 198 | 209 | VMW_IOCTL_DEF(VMW_GET_3D_CAP, vmw_get_cap_3d_ioctl, |
|---|
| 199 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 210 | + DRM_RENDER_ALLOW), |
|---|
| 200 | 211 | |
|---|
| 201 | 212 | /* these allow direct access to the framebuffers mark as master only */ |
|---|
| 202 | 213 | VMW_IOCTL_DEF(VMW_PRESENT, vmw_present_ioctl, |
|---|
| .. | .. |
|---|
| 214 | 225 | DRM_RENDER_ALLOW), |
|---|
| 215 | 226 | VMW_IOCTL_DEF(VMW_CREATE_SHADER, |
|---|
| 216 | 227 | vmw_shader_define_ioctl, |
|---|
| 217 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 228 | + DRM_RENDER_ALLOW), |
|---|
| 218 | 229 | VMW_IOCTL_DEF(VMW_UNREF_SHADER, |
|---|
| 219 | 230 | vmw_shader_destroy_ioctl, |
|---|
| 220 | 231 | DRM_RENDER_ALLOW), |
|---|
| 221 | 232 | VMW_IOCTL_DEF(VMW_GB_SURFACE_CREATE, |
|---|
| 222 | 233 | vmw_gb_surface_define_ioctl, |
|---|
| 223 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 234 | + DRM_RENDER_ALLOW), |
|---|
| 224 | 235 | VMW_IOCTL_DEF(VMW_GB_SURFACE_REF, |
|---|
| 225 | 236 | vmw_gb_surface_reference_ioctl, |
|---|
| 226 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 237 | + DRM_RENDER_ALLOW), |
|---|
| 227 | 238 | VMW_IOCTL_DEF(VMW_SYNCCPU, |
|---|
| 228 | 239 | vmw_user_bo_synccpu_ioctl, |
|---|
| 229 | 240 | DRM_RENDER_ALLOW), |
|---|
| 230 | 241 | VMW_IOCTL_DEF(VMW_CREATE_EXTENDED_CONTEXT, |
|---|
| 231 | 242 | vmw_extended_context_define_ioctl, |
|---|
| 232 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 243 | + DRM_RENDER_ALLOW), |
|---|
| 233 | 244 | VMW_IOCTL_DEF(VMW_GB_SURFACE_CREATE_EXT, |
|---|
| 234 | 245 | vmw_gb_surface_define_ext_ioctl, |
|---|
| 235 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 246 | + DRM_RENDER_ALLOW), |
|---|
| 236 | 247 | VMW_IOCTL_DEF(VMW_GB_SURFACE_REF_EXT, |
|---|
| 237 | 248 | vmw_gb_surface_reference_ext_ioctl, |
|---|
| 238 | | - DRM_AUTH | DRM_RENDER_ALLOW), |
|---|
| 249 | + DRM_RENDER_ALLOW), |
|---|
| 250 | + VMW_IOCTL_DEF(VMW_MSG, |
|---|
| 251 | + vmw_msg_ioctl, |
|---|
| 252 | + DRM_RENDER_ALLOW), |
|---|
| 239 | 253 | }; |
|---|
| 240 | 254 | |
|---|
| 241 | 255 | static const struct pci_device_id vmw_pci_id_list[] = { |
|---|
| .. | .. |
|---|
| 252 | 266 | static int vmw_assume_16bpp; |
|---|
| 253 | 267 | |
|---|
| 254 | 268 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); |
|---|
| 255 | | -static void vmw_master_init(struct vmw_master *); |
|---|
| 256 | 269 | static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, |
|---|
| 257 | 270 | void *ptr); |
|---|
| 258 | 271 | |
|---|
| .. | .. |
|---|
| 277 | 290 | DRM_INFO(" Grow oTable.\n"); |
|---|
| 278 | 291 | if (capabilities2 & SVGA_CAP2_INTRA_SURFACE_COPY) |
|---|
| 279 | 292 | DRM_INFO(" IntraSurface copy.\n"); |
|---|
| 293 | + if (capabilities2 & SVGA_CAP2_DX3) |
|---|
| 294 | + DRM_INFO(" DX3.\n"); |
|---|
| 280 | 295 | } |
|---|
| 281 | 296 | |
|---|
| 282 | 297 | static void vmw_print_capabilities(uint32_t capabilities) |
|---|
| .. | .. |
|---|
| 436 | 451 | dev_priv->cman = vmw_cmdbuf_man_create(dev_priv); |
|---|
| 437 | 452 | if (IS_ERR(dev_priv->cman)) { |
|---|
| 438 | 453 | dev_priv->cman = NULL; |
|---|
| 439 | | - dev_priv->has_dx = false; |
|---|
| 454 | + dev_priv->sm_type = VMW_SM_LEGACY; |
|---|
| 440 | 455 | } |
|---|
| 441 | 456 | |
|---|
| 442 | 457 | ret = vmw_request_device_late(dev_priv); |
|---|
| .. | .. |
|---|
| 549 | 564 | * |
|---|
| 550 | 565 | * @dev_priv: Pointer to a struct vmw_private |
|---|
| 551 | 566 | * |
|---|
| 552 | | - * This functions tries to determine the IOMMU setup and what actions |
|---|
| 553 | | - * need to be taken by the driver to make system pages visible to the |
|---|
| 554 | | - * device. |
|---|
| 567 | + * This functions tries to determine what actions need to be taken by the |
|---|
| 568 | + * driver to make system pages visible to the device. |
|---|
| 555 | 569 | * If this function decides that DMA is not possible, it returns -EINVAL. |
|---|
| 556 | 570 | * The driver may then try to disable features of the device that require |
|---|
| 557 | 571 | * DMA. |
|---|
| .. | .. |
|---|
| 561 | 575 | static const char *names[vmw_dma_map_max] = { |
|---|
| 562 | 576 | [vmw_dma_phys] = "Using physical TTM page addresses.", |
|---|
| 563 | 577 | [vmw_dma_alloc_coherent] = "Using coherent TTM pages.", |
|---|
| 564 | | - [vmw_dma_map_populate] = "Keeping DMA mappings.", |
|---|
| 578 | + [vmw_dma_map_populate] = "Caching DMA mappings.", |
|---|
| 565 | 579 | [vmw_dma_map_bind] = "Giving up DMA mappings early."}; |
|---|
| 566 | | -#ifdef CONFIG_X86 |
|---|
| 567 | | - const struct dma_map_ops *dma_ops = get_dma_ops(dev_priv->dev->dev); |
|---|
| 568 | 580 | |
|---|
| 569 | | -#ifdef CONFIG_INTEL_IOMMU |
|---|
| 570 | | - if (intel_iommu_enabled) { |
|---|
| 571 | | - dev_priv->map_mode = vmw_dma_map_populate; |
|---|
| 572 | | - goto out_fixup; |
|---|
| 573 | | - } |
|---|
| 574 | | -#endif |
|---|
| 575 | | - |
|---|
| 576 | | - if (!(vmw_force_iommu || vmw_force_coherent)) { |
|---|
| 577 | | - dev_priv->map_mode = vmw_dma_phys; |
|---|
| 578 | | - DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]); |
|---|
| 579 | | - return 0; |
|---|
| 580 | | - } |
|---|
| 581 | | - |
|---|
| 582 | | - dev_priv->map_mode = vmw_dma_map_populate; |
|---|
| 583 | | - |
|---|
| 584 | | - if (dma_ops->sync_single_for_cpu) |
|---|
| 585 | | - dev_priv->map_mode = vmw_dma_alloc_coherent; |
|---|
| 586 | | -#ifdef CONFIG_SWIOTLB |
|---|
| 587 | | - if (swiotlb_nr_tbl() == 0) |
|---|
| 588 | | - dev_priv->map_mode = vmw_dma_map_populate; |
|---|
| 589 | | -#endif |
|---|
| 590 | | - |
|---|
| 591 | | -#ifdef CONFIG_INTEL_IOMMU |
|---|
| 592 | | -out_fixup: |
|---|
| 593 | | -#endif |
|---|
| 594 | | - if (dev_priv->map_mode == vmw_dma_map_populate && |
|---|
| 595 | | - vmw_restrict_iommu) |
|---|
| 596 | | - dev_priv->map_mode = vmw_dma_map_bind; |
|---|
| 581 | + /* TTM currently doesn't fully support SEV encryption. */ |
|---|
| 582 | + if (mem_encrypt_active()) |
|---|
| 583 | + return -EINVAL; |
|---|
| 597 | 584 | |
|---|
| 598 | 585 | if (vmw_force_coherent) |
|---|
| 599 | 586 | dev_priv->map_mode = vmw_dma_alloc_coherent; |
|---|
| 587 | + else if (vmw_restrict_iommu) |
|---|
| 588 | + dev_priv->map_mode = vmw_dma_map_bind; |
|---|
| 589 | + else |
|---|
| 590 | + dev_priv->map_mode = vmw_dma_map_populate; |
|---|
| 600 | 591 | |
|---|
| 601 | | -#if !defined(CONFIG_SWIOTLB) && !defined(CONFIG_INTEL_IOMMU) |
|---|
| 602 | | - /* |
|---|
| 603 | | - * No coherent page pool |
|---|
| 604 | | - */ |
|---|
| 605 | | - if (dev_priv->map_mode == vmw_dma_alloc_coherent) |
|---|
| 592 | + if (!IS_ENABLED(CONFIG_DRM_TTM_DMA_PAGE_POOL) && |
|---|
| 593 | + (dev_priv->map_mode == vmw_dma_alloc_coherent)) |
|---|
| 606 | 594 | return -EINVAL; |
|---|
| 607 | | -#endif |
|---|
| 608 | | - |
|---|
| 609 | | -#else /* CONFIG_X86 */ |
|---|
| 610 | | - dev_priv->map_mode = vmw_dma_map_populate; |
|---|
| 611 | | -#endif /* CONFIG_X86 */ |
|---|
| 612 | 595 | |
|---|
| 613 | 596 | DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]); |
|---|
| 614 | | - |
|---|
| 615 | 597 | return 0; |
|---|
| 616 | 598 | } |
|---|
| 617 | 599 | |
|---|
| .. | .. |
|---|
| 623 | 605 | * With 32-bit we can only handle 32 bit PFNs. Optionally set that |
|---|
| 624 | 606 | * restriction also for 64-bit systems. |
|---|
| 625 | 607 | */ |
|---|
| 626 | | -#ifdef CONFIG_INTEL_IOMMU |
|---|
| 627 | 608 | static int vmw_dma_masks(struct vmw_private *dev_priv) |
|---|
| 628 | 609 | { |
|---|
| 629 | 610 | struct drm_device *dev = dev_priv->dev; |
|---|
| .. | .. |
|---|
| 638 | 619 | |
|---|
| 639 | 620 | return ret; |
|---|
| 640 | 621 | } |
|---|
| 641 | | -#else |
|---|
| 642 | | -static int vmw_dma_masks(struct vmw_private *dev_priv) |
|---|
| 622 | + |
|---|
| 623 | +static int vmw_vram_manager_init(struct vmw_private *dev_priv) |
|---|
| 643 | 624 | { |
|---|
| 644 | | - return 0; |
|---|
| 645 | | -} |
|---|
| 625 | + int ret; |
|---|
| 626 | +#ifdef CONFIG_TRANSPARENT_HUGEPAGE |
|---|
| 627 | + ret = vmw_thp_init(dev_priv); |
|---|
| 628 | +#else |
|---|
| 629 | + ret = ttm_range_man_init(&dev_priv->bdev, TTM_PL_VRAM, false, |
|---|
| 630 | + dev_priv->vram_size >> PAGE_SHIFT); |
|---|
| 646 | 631 | #endif |
|---|
| 632 | + ttm_resource_manager_set_used(ttm_manager_type(&dev_priv->bdev, TTM_PL_VRAM), false); |
|---|
| 633 | + return ret; |
|---|
| 634 | +} |
|---|
| 635 | + |
|---|
| 636 | +static void vmw_vram_manager_fini(struct vmw_private *dev_priv) |
|---|
| 637 | +{ |
|---|
| 638 | +#ifdef CONFIG_TRANSPARENT_HUGEPAGE |
|---|
| 639 | + vmw_thp_fini(dev_priv); |
|---|
| 640 | +#else |
|---|
| 641 | + ttm_range_man_fini(&dev_priv->bdev, TTM_PL_VRAM); |
|---|
| 642 | +#endif |
|---|
| 643 | +} |
|---|
| 647 | 644 | |
|---|
| 648 | 645 | static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) |
|---|
| 649 | 646 | { |
|---|
| .. | .. |
|---|
| 668 | 665 | mutex_init(&dev_priv->cmdbuf_mutex); |
|---|
| 669 | 666 | mutex_init(&dev_priv->release_mutex); |
|---|
| 670 | 667 | mutex_init(&dev_priv->binding_mutex); |
|---|
| 671 | | - mutex_init(&dev_priv->requested_layout_mutex); |
|---|
| 672 | 668 | mutex_init(&dev_priv->global_kms_state_mutex); |
|---|
| 673 | | - rwlock_init(&dev_priv->resource_lock); |
|---|
| 674 | 669 | ttm_lock_init(&dev_priv->reservation_sem); |
|---|
| 670 | + spin_lock_init(&dev_priv->resource_lock); |
|---|
| 675 | 671 | spin_lock_init(&dev_priv->hw_lock); |
|---|
| 676 | 672 | spin_lock_init(&dev_priv->waiter_lock); |
|---|
| 677 | 673 | spin_lock_init(&dev_priv->cap_lock); |
|---|
| .. | .. |
|---|
| 683 | 679 | INIT_LIST_HEAD(&dev_priv->res_lru[i]); |
|---|
| 684 | 680 | } |
|---|
| 685 | 681 | |
|---|
| 686 | | - mutex_init(&dev_priv->init_mutex); |
|---|
| 687 | 682 | init_waitqueue_head(&dev_priv->fence_queue); |
|---|
| 688 | 683 | init_waitqueue_head(&dev_priv->fifo_queue); |
|---|
| 689 | 684 | dev_priv->fence_queue_waiters = 0; |
|---|
| .. | .. |
|---|
| 716 | 711 | |
|---|
| 717 | 712 | ret = vmw_dma_select_mode(dev_priv); |
|---|
| 718 | 713 | if (unlikely(ret != 0)) { |
|---|
| 719 | | - DRM_INFO("Restricting capabilities due to IOMMU setup.\n"); |
|---|
| 714 | + DRM_INFO("Restricting capabilities since DMA not available.\n"); |
|---|
| 720 | 715 | refuse_dma = true; |
|---|
| 716 | + if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) |
|---|
| 717 | + DRM_INFO("Disabling 3D acceleration.\n"); |
|---|
| 721 | 718 | } |
|---|
| 722 | 719 | |
|---|
| 723 | 720 | dev_priv->vram_size = vmw_read(dev_priv, SVGA_REG_VRAM_SIZE); |
|---|
| .. | .. |
|---|
| 745 | 742 | dev_priv->max_mob_pages = 0; |
|---|
| 746 | 743 | dev_priv->max_mob_size = 0; |
|---|
| 747 | 744 | if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { |
|---|
| 748 | | - uint64_t mem_size = |
|---|
| 749 | | - vmw_read(dev_priv, |
|---|
| 750 | | - SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB); |
|---|
| 745 | + uint64_t mem_size; |
|---|
| 746 | + |
|---|
| 747 | + if (dev_priv->capabilities2 & SVGA_CAP2_GB_MEMSIZE_2) |
|---|
| 748 | + mem_size = vmw_read(dev_priv, |
|---|
| 749 | + SVGA_REG_GBOBJECT_MEM_SIZE_KB); |
|---|
| 750 | + else |
|---|
| 751 | + mem_size = |
|---|
| 752 | + vmw_read(dev_priv, |
|---|
| 753 | + SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB); |
|---|
| 751 | 754 | |
|---|
| 752 | 755 | /* |
|---|
| 753 | 756 | * Workaround for low memory 2D VMs to compensate for the |
|---|
| .. | .. |
|---|
| 807 | 810 | DRM_INFO("MMIO at 0x%08x size is %u kiB\n", |
|---|
| 808 | 811 | dev_priv->mmio_start, dev_priv->mmio_size / 1024); |
|---|
| 809 | 812 | |
|---|
| 810 | | - ret = vmw_ttm_global_init(dev_priv); |
|---|
| 811 | | - if (unlikely(ret != 0)) |
|---|
| 812 | | - goto out_err0; |
|---|
| 813 | | - |
|---|
| 814 | | - |
|---|
| 815 | | - vmw_master_init(&dev_priv->fbdev_master); |
|---|
| 816 | | - ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); |
|---|
| 817 | | - dev_priv->active_master = &dev_priv->fbdev_master; |
|---|
| 818 | | - |
|---|
| 819 | 813 | dev_priv->mmio_virt = memremap(dev_priv->mmio_start, |
|---|
| 820 | 814 | dev_priv->mmio_size, MEMREMAP_WB); |
|---|
| 821 | 815 | |
|---|
| 822 | 816 | if (unlikely(dev_priv->mmio_virt == NULL)) { |
|---|
| 823 | 817 | ret = -ENOMEM; |
|---|
| 824 | 818 | DRM_ERROR("Failed mapping MMIO.\n"); |
|---|
| 825 | | - goto out_err3; |
|---|
| 819 | + goto out_err0; |
|---|
| 826 | 820 | } |
|---|
| 827 | 821 | |
|---|
| 828 | 822 | /* Need mmio memory to check for fifo pitchlock cap. */ |
|---|
| .. | .. |
|---|
| 834 | 828 | goto out_err4; |
|---|
| 835 | 829 | } |
|---|
| 836 | 830 | |
|---|
| 837 | | - dev_priv->tdev = ttm_object_device_init |
|---|
| 838 | | - (dev_priv->mem_global_ref.object, 12, &vmw_prime_dmabuf_ops); |
|---|
| 831 | + dev_priv->tdev = ttm_object_device_init(&ttm_mem_glob, 12, |
|---|
| 832 | + &vmw_prime_dmabuf_ops); |
|---|
| 839 | 833 | |
|---|
| 840 | 834 | if (unlikely(dev_priv->tdev == NULL)) { |
|---|
| 841 | 835 | DRM_ERROR("Unable to initialize TTM object management.\n"); |
|---|
| .. | .. |
|---|
| 875 | 869 | goto out_no_fman; |
|---|
| 876 | 870 | } |
|---|
| 877 | 871 | |
|---|
| 872 | + drm_vma_offset_manager_init(&dev_priv->vma_manager, |
|---|
| 873 | + DRM_FILE_PAGE_OFFSET_START, |
|---|
| 874 | + DRM_FILE_PAGE_OFFSET_SIZE); |
|---|
| 878 | 875 | ret = ttm_bo_device_init(&dev_priv->bdev, |
|---|
| 879 | | - dev_priv->bo_global_ref.ref.object, |
|---|
| 880 | 876 | &vmw_bo_driver, |
|---|
| 881 | 877 | dev->anon_inode->i_mapping, |
|---|
| 882 | | - VMWGFX_FILE_PAGE_OFFSET, |
|---|
| 878 | + &dev_priv->vma_manager, |
|---|
| 883 | 879 | false); |
|---|
| 884 | 880 | if (unlikely(ret != 0)) { |
|---|
| 885 | 881 | DRM_ERROR("Failed initializing TTM buffer object driver.\n"); |
|---|
| .. | .. |
|---|
| 890 | 886 | * Enable VRAM, but initially don't use it until SVGA is enabled and |
|---|
| 891 | 887 | * unhidden. |
|---|
| 892 | 888 | */ |
|---|
| 893 | | - ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM, |
|---|
| 894 | | - (dev_priv->vram_size >> PAGE_SHIFT)); |
|---|
| 889 | + |
|---|
| 890 | + ret = vmw_vram_manager_init(dev_priv); |
|---|
| 895 | 891 | if (unlikely(ret != 0)) { |
|---|
| 896 | 892 | DRM_ERROR("Failed initializing memory manager for VRAM.\n"); |
|---|
| 897 | 893 | goto out_no_vram; |
|---|
| 898 | 894 | } |
|---|
| 899 | | - dev_priv->bdev.man[TTM_PL_VRAM].use_type = false; |
|---|
| 900 | 895 | |
|---|
| 896 | + /* |
|---|
| 897 | + * "Guest Memory Regions" is an aperture like feature with |
|---|
| 898 | + * one slot per bo. There is an upper limit of the number of |
|---|
| 899 | + * slots as well as the bo size. |
|---|
| 900 | + */ |
|---|
| 901 | 901 | dev_priv->has_gmr = true; |
|---|
| 902 | + /* TODO: This is most likely not correct */ |
|---|
| 902 | 903 | if (((dev_priv->capabilities & (SVGA_CAP_GMR | SVGA_CAP_GMR2)) == 0) || |
|---|
| 903 | | - refuse_dma || ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR, |
|---|
| 904 | | - VMW_PL_GMR) != 0) { |
|---|
| 904 | + refuse_dma || |
|---|
| 905 | + vmw_gmrid_man_init(dev_priv, VMW_PL_GMR) != 0) { |
|---|
| 905 | 906 | DRM_INFO("No GMR memory available. " |
|---|
| 906 | 907 | "Graphics memory resources are very limited.\n"); |
|---|
| 907 | 908 | dev_priv->has_gmr = false; |
|---|
| 908 | 909 | } |
|---|
| 909 | 910 | |
|---|
| 910 | | - if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { |
|---|
| 911 | + if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS && !refuse_dma) { |
|---|
| 911 | 912 | dev_priv->has_mob = true; |
|---|
| 912 | | - if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_MOB, |
|---|
| 913 | | - VMW_PL_MOB) != 0) { |
|---|
| 913 | + |
|---|
| 914 | + if (vmw_gmrid_man_init(dev_priv, VMW_PL_MOB) != 0) { |
|---|
| 914 | 915 | DRM_INFO("No MOB memory available. " |
|---|
| 915 | 916 | "3D will be disabled.\n"); |
|---|
| 916 | 917 | dev_priv->has_mob = false; |
|---|
| 917 | 918 | } |
|---|
| 918 | 919 | } |
|---|
| 919 | 920 | |
|---|
| 920 | | - if (dev_priv->has_mob) { |
|---|
| 921 | + if (dev_priv->has_mob && (dev_priv->capabilities & SVGA_CAP_DX)) { |
|---|
| 921 | 922 | spin_lock(&dev_priv->cap_lock); |
|---|
| 922 | 923 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_DXCONTEXT); |
|---|
| 923 | | - dev_priv->has_dx = !!vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
|---|
| 924 | + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) |
|---|
| 925 | + dev_priv->sm_type = VMW_SM_4; |
|---|
| 924 | 926 | spin_unlock(&dev_priv->cap_lock); |
|---|
| 925 | 927 | } |
|---|
| 926 | 928 | |
|---|
| 929 | + vmw_validation_mem_init_ttm(dev_priv, VMWGFX_VALIDATION_MEM_GRAN); |
|---|
| 930 | + |
|---|
| 931 | + /* SVGA_CAP2_DX2 (DefineGBSurface_v3) is needed for SM4_1 support */ |
|---|
| 932 | + if (has_sm4_context(dev_priv) && |
|---|
| 933 | + (dev_priv->capabilities2 & SVGA_CAP2_DX2)) { |
|---|
| 934 | + vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_SM41); |
|---|
| 935 | + |
|---|
| 936 | + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) |
|---|
| 937 | + dev_priv->sm_type = VMW_SM_4_1; |
|---|
| 938 | + |
|---|
| 939 | + if (has_sm4_1_context(dev_priv) && |
|---|
| 940 | + (dev_priv->capabilities2 & SVGA_CAP2_DX3)) { |
|---|
| 941 | + vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_SM5); |
|---|
| 942 | + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) |
|---|
| 943 | + dev_priv->sm_type = VMW_SM_5; |
|---|
| 944 | + } |
|---|
| 945 | + } |
|---|
| 927 | 946 | |
|---|
| 928 | 947 | ret = vmw_kms_init(dev_priv); |
|---|
| 929 | 948 | if (unlikely(ret != 0)) |
|---|
| .. | .. |
|---|
| 934 | 953 | if (ret) |
|---|
| 935 | 954 | goto out_no_fifo; |
|---|
| 936 | 955 | |
|---|
| 937 | | - if (dev_priv->has_dx) { |
|---|
| 938 | | - /* |
|---|
| 939 | | - * SVGA_CAP2_DX2 (DefineGBSurface_v3) is needed for SM4_1 |
|---|
| 940 | | - * support |
|---|
| 941 | | - */ |
|---|
| 942 | | - if ((dev_priv->capabilities2 & SVGA_CAP2_DX2) != 0) { |
|---|
| 943 | | - vmw_write(dev_priv, SVGA_REG_DEV_CAP, |
|---|
| 944 | | - SVGA3D_DEVCAP_SM41); |
|---|
| 945 | | - dev_priv->has_sm4_1 = vmw_read(dev_priv, |
|---|
| 946 | | - SVGA_REG_DEV_CAP); |
|---|
| 947 | | - } |
|---|
| 948 | | - } |
|---|
| 949 | | - |
|---|
| 950 | | - DRM_INFO("DX: %s\n", dev_priv->has_dx ? "yes." : "no."); |
|---|
| 951 | 956 | DRM_INFO("Atomic: %s\n", (dev->driver->driver_features & DRIVER_ATOMIC) |
|---|
| 952 | 957 | ? "yes." : "no."); |
|---|
| 953 | | - DRM_INFO("SM4_1: %s\n", dev_priv->has_sm4_1 ? "yes." : "no."); |
|---|
| 958 | + if (dev_priv->sm_type == VMW_SM_5) |
|---|
| 959 | + DRM_INFO("SM5 support available.\n"); |
|---|
| 960 | + if (dev_priv->sm_type == VMW_SM_4_1) |
|---|
| 961 | + DRM_INFO("SM4_1 support available.\n"); |
|---|
| 962 | + if (dev_priv->sm_type == VMW_SM_4) |
|---|
| 963 | + DRM_INFO("SM4 support available.\n"); |
|---|
| 954 | 964 | |
|---|
| 955 | 965 | snprintf(host_log, sizeof(host_log), "vmwgfx: %s-%s", |
|---|
| 956 | 966 | VMWGFX_REPO, VMWGFX_GIT_VERSION); |
|---|
| .. | .. |
|---|
| 978 | 988 | vmw_kms_close(dev_priv); |
|---|
| 979 | 989 | out_no_kms: |
|---|
| 980 | 990 | if (dev_priv->has_mob) |
|---|
| 981 | | - (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB); |
|---|
| 991 | + vmw_gmrid_man_fini(dev_priv, VMW_PL_MOB); |
|---|
| 982 | 992 | if (dev_priv->has_gmr) |
|---|
| 983 | | - (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); |
|---|
| 984 | | - (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); |
|---|
| 993 | + vmw_gmrid_man_fini(dev_priv, VMW_PL_GMR); |
|---|
| 994 | + vmw_vram_manager_fini(dev_priv); |
|---|
| 985 | 995 | out_no_vram: |
|---|
| 986 | 996 | (void)ttm_bo_device_release(&dev_priv->bdev); |
|---|
| 987 | 997 | out_no_bdev: |
|---|
| .. | .. |
|---|
| 998 | 1008 | ttm_object_device_release(&dev_priv->tdev); |
|---|
| 999 | 1009 | out_err4: |
|---|
| 1000 | 1010 | memunmap(dev_priv->mmio_virt); |
|---|
| 1001 | | -out_err3: |
|---|
| 1002 | | - vmw_ttm_global_release(dev_priv); |
|---|
| 1003 | 1011 | out_err0: |
|---|
| 1004 | 1012 | for (i = vmw_res_context; i < vmw_res_max; ++i) |
|---|
| 1005 | 1013 | idr_destroy(&dev_priv->res_idr[i]); |
|---|
| .. | .. |
|---|
| 1031 | 1039 | vmw_overlay_close(dev_priv); |
|---|
| 1032 | 1040 | |
|---|
| 1033 | 1041 | if (dev_priv->has_gmr) |
|---|
| 1034 | | - (void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); |
|---|
| 1035 | | - (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); |
|---|
| 1042 | + vmw_gmrid_man_fini(dev_priv, VMW_PL_GMR); |
|---|
| 1036 | 1043 | |
|---|
| 1037 | 1044 | vmw_release_device_early(dev_priv); |
|---|
| 1038 | 1045 | if (dev_priv->has_mob) |
|---|
| 1039 | | - (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB); |
|---|
| 1046 | + vmw_gmrid_man_fini(dev_priv, VMW_PL_MOB); |
|---|
| 1047 | + vmw_vram_manager_fini(dev_priv); |
|---|
| 1040 | 1048 | (void) ttm_bo_device_release(&dev_priv->bdev); |
|---|
| 1049 | + drm_vma_offset_manager_destroy(&dev_priv->vma_manager); |
|---|
| 1041 | 1050 | vmw_release_device_late(dev_priv); |
|---|
| 1042 | 1051 | vmw_fence_manager_takedown(dev_priv->fman); |
|---|
| 1043 | 1052 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) |
|---|
| .. | .. |
|---|
| 1051 | 1060 | memunmap(dev_priv->mmio_virt); |
|---|
| 1052 | 1061 | if (dev_priv->ctx.staged_bindings) |
|---|
| 1053 | 1062 | vmw_binding_state_free(dev_priv->ctx.staged_bindings); |
|---|
| 1054 | | - vmw_ttm_global_release(dev_priv); |
|---|
| 1055 | 1063 | |
|---|
| 1056 | 1064 | for (i = vmw_res_context; i < vmw_res_max; ++i) |
|---|
| 1057 | 1065 | idr_destroy(&dev_priv->res_idr[i]); |
|---|
| .. | .. |
|---|
| 1062 | 1070 | static void vmw_postclose(struct drm_device *dev, |
|---|
| 1063 | 1071 | struct drm_file *file_priv) |
|---|
| 1064 | 1072 | { |
|---|
| 1065 | | - struct vmw_fpriv *vmw_fp; |
|---|
| 1066 | | - |
|---|
| 1067 | | - vmw_fp = vmw_fpriv(file_priv); |
|---|
| 1068 | | - |
|---|
| 1069 | | - if (vmw_fp->locked_master) { |
|---|
| 1070 | | - struct vmw_master *vmaster = |
|---|
| 1071 | | - vmw_master(vmw_fp->locked_master); |
|---|
| 1072 | | - |
|---|
| 1073 | | - ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); |
|---|
| 1074 | | - ttm_vt_unlock(&vmaster->lock); |
|---|
| 1075 | | - drm_master_put(&vmw_fp->locked_master); |
|---|
| 1076 | | - } |
|---|
| 1073 | + struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); |
|---|
| 1077 | 1074 | |
|---|
| 1078 | 1075 | ttm_object_file_release(&vmw_fp->tfile); |
|---|
| 1079 | 1076 | kfree(vmw_fp); |
|---|
| .. | .. |
|---|
| 1102 | 1099 | return ret; |
|---|
| 1103 | 1100 | } |
|---|
| 1104 | 1101 | |
|---|
| 1105 | | -static struct vmw_master *vmw_master_check(struct drm_device *dev, |
|---|
| 1106 | | - struct drm_file *file_priv, |
|---|
| 1107 | | - unsigned int flags) |
|---|
| 1108 | | -{ |
|---|
| 1109 | | - int ret; |
|---|
| 1110 | | - struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); |
|---|
| 1111 | | - struct vmw_master *vmaster; |
|---|
| 1112 | | - |
|---|
| 1113 | | - if (!drm_is_primary_client(file_priv) || !(flags & DRM_AUTH)) |
|---|
| 1114 | | - return NULL; |
|---|
| 1115 | | - |
|---|
| 1116 | | - ret = mutex_lock_interruptible(&dev->master_mutex); |
|---|
| 1117 | | - if (unlikely(ret != 0)) |
|---|
| 1118 | | - return ERR_PTR(-ERESTARTSYS); |
|---|
| 1119 | | - |
|---|
| 1120 | | - if (drm_is_current_master(file_priv)) { |
|---|
| 1121 | | - mutex_unlock(&dev->master_mutex); |
|---|
| 1122 | | - return NULL; |
|---|
| 1123 | | - } |
|---|
| 1124 | | - |
|---|
| 1125 | | - /* |
|---|
| 1126 | | - * Check if we were previously master, but now dropped. In that |
|---|
| 1127 | | - * case, allow at least render node functionality. |
|---|
| 1128 | | - */ |
|---|
| 1129 | | - if (vmw_fp->locked_master) { |
|---|
| 1130 | | - mutex_unlock(&dev->master_mutex); |
|---|
| 1131 | | - |
|---|
| 1132 | | - if (flags & DRM_RENDER_ALLOW) |
|---|
| 1133 | | - return NULL; |
|---|
| 1134 | | - |
|---|
| 1135 | | - DRM_ERROR("Dropped master trying to access ioctl that " |
|---|
| 1136 | | - "requires authentication.\n"); |
|---|
| 1137 | | - return ERR_PTR(-EACCES); |
|---|
| 1138 | | - } |
|---|
| 1139 | | - mutex_unlock(&dev->master_mutex); |
|---|
| 1140 | | - |
|---|
| 1141 | | - /* |
|---|
| 1142 | | - * Take the TTM lock. Possibly sleep waiting for the authenticating |
|---|
| 1143 | | - * master to become master again, or for a SIGTERM if the |
|---|
| 1144 | | - * authenticating master exits. |
|---|
| 1145 | | - */ |
|---|
| 1146 | | - vmaster = vmw_master(file_priv->master); |
|---|
| 1147 | | - ret = ttm_read_lock(&vmaster->lock, true); |
|---|
| 1148 | | - if (unlikely(ret != 0)) |
|---|
| 1149 | | - vmaster = ERR_PTR(ret); |
|---|
| 1150 | | - |
|---|
| 1151 | | - return vmaster; |
|---|
| 1152 | | -} |
|---|
| 1153 | | - |
|---|
| 1154 | 1102 | static long vmw_generic_ioctl(struct file *filp, unsigned int cmd, |
|---|
| 1155 | 1103 | unsigned long arg, |
|---|
| 1156 | 1104 | long (*ioctl_func)(struct file *, unsigned int, |
|---|
| .. | .. |
|---|
| 1159 | 1107 | struct drm_file *file_priv = filp->private_data; |
|---|
| 1160 | 1108 | struct drm_device *dev = file_priv->minor->dev; |
|---|
| 1161 | 1109 | unsigned int nr = DRM_IOCTL_NR(cmd); |
|---|
| 1162 | | - struct vmw_master *vmaster; |
|---|
| 1163 | 1110 | unsigned int flags; |
|---|
| 1164 | | - long ret; |
|---|
| 1165 | 1111 | |
|---|
| 1166 | 1112 | /* |
|---|
| 1167 | 1113 | * Do extra checking on driver private ioctls. |
|---|
| .. | .. |
|---|
| 1173 | 1119 | &vmw_ioctls[nr - DRM_COMMAND_BASE]; |
|---|
| 1174 | 1120 | |
|---|
| 1175 | 1121 | if (nr == DRM_COMMAND_BASE + DRM_VMW_EXECBUF) { |
|---|
| 1176 | | - ret = (long) drm_ioctl_permit(ioctl->flags, file_priv); |
|---|
| 1177 | | - if (unlikely(ret != 0)) |
|---|
| 1178 | | - return ret; |
|---|
| 1179 | | - |
|---|
| 1180 | | - if (unlikely((cmd & (IOC_IN | IOC_OUT)) != IOC_IN)) |
|---|
| 1181 | | - goto out_io_encoding; |
|---|
| 1182 | | - |
|---|
| 1183 | | - return (long) vmw_execbuf_ioctl(dev, arg, file_priv, |
|---|
| 1184 | | - _IOC_SIZE(cmd)); |
|---|
| 1122 | + return ioctl_func(filp, cmd, arg); |
|---|
| 1185 | 1123 | } else if (nr == DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT) { |
|---|
| 1186 | 1124 | if (!drm_is_current_master(file_priv) && |
|---|
| 1187 | 1125 | !capable(CAP_SYS_ADMIN)) |
|---|
| .. | .. |
|---|
| 1195 | 1133 | } else if (!drm_ioctl_flags(nr, &flags)) |
|---|
| 1196 | 1134 | return -EINVAL; |
|---|
| 1197 | 1135 | |
|---|
| 1198 | | - vmaster = vmw_master_check(dev, file_priv, flags); |
|---|
| 1199 | | - if (IS_ERR(vmaster)) { |
|---|
| 1200 | | - ret = PTR_ERR(vmaster); |
|---|
| 1201 | | - |
|---|
| 1202 | | - if (ret != -ERESTARTSYS) |
|---|
| 1203 | | - DRM_INFO("IOCTL ERROR Command %d, Error %ld.\n", |
|---|
| 1204 | | - nr, ret); |
|---|
| 1205 | | - return ret; |
|---|
| 1206 | | - } |
|---|
| 1207 | | - |
|---|
| 1208 | | - ret = ioctl_func(filp, cmd, arg); |
|---|
| 1209 | | - if (vmaster) |
|---|
| 1210 | | - ttm_read_unlock(&vmaster->lock); |
|---|
| 1211 | | - |
|---|
| 1212 | | - return ret; |
|---|
| 1136 | + return ioctl_func(filp, cmd, arg); |
|---|
| 1213 | 1137 | |
|---|
| 1214 | 1138 | out_io_encoding: |
|---|
| 1215 | 1139 | DRM_ERROR("Invalid command format, ioctl %d\n", |
|---|
| .. | .. |
|---|
| 1232 | 1156 | } |
|---|
| 1233 | 1157 | #endif |
|---|
| 1234 | 1158 | |
|---|
| 1235 | | -static void vmw_lastclose(struct drm_device *dev) |
|---|
| 1159 | +static void vmw_master_set(struct drm_device *dev, |
|---|
| 1160 | + struct drm_file *file_priv, |
|---|
| 1161 | + bool from_open) |
|---|
| 1236 | 1162 | { |
|---|
| 1237 | | -} |
|---|
| 1238 | | - |
|---|
| 1239 | | -static void vmw_master_init(struct vmw_master *vmaster) |
|---|
| 1240 | | -{ |
|---|
| 1241 | | - ttm_lock_init(&vmaster->lock); |
|---|
| 1242 | | -} |
|---|
| 1243 | | - |
|---|
| 1244 | | -static int vmw_master_create(struct drm_device *dev, |
|---|
| 1245 | | - struct drm_master *master) |
|---|
| 1246 | | -{ |
|---|
| 1247 | | - struct vmw_master *vmaster; |
|---|
| 1248 | | - |
|---|
| 1249 | | - vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL); |
|---|
| 1250 | | - if (unlikely(!vmaster)) |
|---|
| 1251 | | - return -ENOMEM; |
|---|
| 1252 | | - |
|---|
| 1253 | | - vmw_master_init(vmaster); |
|---|
| 1254 | | - ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); |
|---|
| 1255 | | - master->driver_priv = vmaster; |
|---|
| 1256 | | - |
|---|
| 1257 | | - return 0; |
|---|
| 1258 | | -} |
|---|
| 1259 | | - |
|---|
| 1260 | | -static void vmw_master_destroy(struct drm_device *dev, |
|---|
| 1261 | | - struct drm_master *master) |
|---|
| 1262 | | -{ |
|---|
| 1263 | | - struct vmw_master *vmaster = vmw_master(master); |
|---|
| 1264 | | - |
|---|
| 1265 | | - master->driver_priv = NULL; |
|---|
| 1266 | | - kfree(vmaster); |
|---|
| 1267 | | -} |
|---|
| 1268 | | - |
|---|
| 1269 | | -static int vmw_master_set(struct drm_device *dev, |
|---|
| 1270 | | - struct drm_file *file_priv, |
|---|
| 1271 | | - bool from_open) |
|---|
| 1272 | | -{ |
|---|
| 1273 | | - struct vmw_private *dev_priv = vmw_priv(dev); |
|---|
| 1274 | | - struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); |
|---|
| 1275 | | - struct vmw_master *active = dev_priv->active_master; |
|---|
| 1276 | | - struct vmw_master *vmaster = vmw_master(file_priv->master); |
|---|
| 1277 | | - int ret = 0; |
|---|
| 1278 | | - |
|---|
| 1279 | | - if (active) { |
|---|
| 1280 | | - BUG_ON(active != &dev_priv->fbdev_master); |
|---|
| 1281 | | - ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); |
|---|
| 1282 | | - if (unlikely(ret != 0)) |
|---|
| 1283 | | - return ret; |
|---|
| 1284 | | - |
|---|
| 1285 | | - ttm_lock_set_kill(&active->lock, true, SIGTERM); |
|---|
| 1286 | | - dev_priv->active_master = NULL; |
|---|
| 1287 | | - } |
|---|
| 1288 | | - |
|---|
| 1289 | | - ttm_lock_set_kill(&vmaster->lock, false, SIGTERM); |
|---|
| 1290 | | - if (!from_open) { |
|---|
| 1291 | | - ttm_vt_unlock(&vmaster->lock); |
|---|
| 1292 | | - BUG_ON(vmw_fp->locked_master != file_priv->master); |
|---|
| 1293 | | - drm_master_put(&vmw_fp->locked_master); |
|---|
| 1294 | | - } |
|---|
| 1295 | | - |
|---|
| 1296 | | - dev_priv->active_master = vmaster; |
|---|
| 1297 | | - |
|---|
| 1298 | 1163 | /* |
|---|
| 1299 | 1164 | * Inform a new master that the layout may have changed while |
|---|
| 1300 | 1165 | * it was gone. |
|---|
| 1301 | 1166 | */ |
|---|
| 1302 | 1167 | if (!from_open) |
|---|
| 1303 | 1168 | drm_sysfs_hotplug_event(dev); |
|---|
| 1304 | | - |
|---|
| 1305 | | - return 0; |
|---|
| 1306 | 1169 | } |
|---|
| 1307 | 1170 | |
|---|
| 1308 | 1171 | static void vmw_master_drop(struct drm_device *dev, |
|---|
| 1309 | 1172 | struct drm_file *file_priv) |
|---|
| 1310 | 1173 | { |
|---|
| 1311 | 1174 | struct vmw_private *dev_priv = vmw_priv(dev); |
|---|
| 1312 | | - struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); |
|---|
| 1313 | | - struct vmw_master *vmaster = vmw_master(file_priv->master); |
|---|
| 1314 | | - int ret; |
|---|
| 1315 | 1175 | |
|---|
| 1316 | | - /** |
|---|
| 1317 | | - * Make sure the master doesn't disappear while we have |
|---|
| 1318 | | - * it locked. |
|---|
| 1319 | | - */ |
|---|
| 1320 | | - |
|---|
| 1321 | | - vmw_fp->locked_master = drm_master_get(file_priv->master); |
|---|
| 1322 | | - ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile); |
|---|
| 1323 | 1176 | vmw_kms_legacy_hotspot_clear(dev_priv); |
|---|
| 1324 | | - if (unlikely((ret != 0))) { |
|---|
| 1325 | | - DRM_ERROR("Unable to lock TTM at VT switch.\n"); |
|---|
| 1326 | | - drm_master_put(&vmw_fp->locked_master); |
|---|
| 1327 | | - } |
|---|
| 1328 | | - |
|---|
| 1329 | | - ttm_lock_set_kill(&vmaster->lock, false, SIGTERM); |
|---|
| 1330 | | - |
|---|
| 1331 | 1177 | if (!dev_priv->enable_fb) |
|---|
| 1332 | 1178 | vmw_svga_disable(dev_priv); |
|---|
| 1333 | | - |
|---|
| 1334 | | - dev_priv->active_master = &dev_priv->fbdev_master; |
|---|
| 1335 | | - ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); |
|---|
| 1336 | | - ttm_vt_unlock(&dev_priv->fbdev_master.lock); |
|---|
| 1337 | 1179 | } |
|---|
| 1338 | 1180 | |
|---|
| 1339 | 1181 | /** |
|---|
| .. | .. |
|---|
| 1344 | 1186 | */ |
|---|
| 1345 | 1187 | static void __vmw_svga_enable(struct vmw_private *dev_priv) |
|---|
| 1346 | 1188 | { |
|---|
| 1189 | + struct ttm_resource_manager *man = ttm_manager_type(&dev_priv->bdev, TTM_PL_VRAM); |
|---|
| 1190 | + |
|---|
| 1347 | 1191 | spin_lock(&dev_priv->svga_lock); |
|---|
| 1348 | | - if (!dev_priv->bdev.man[TTM_PL_VRAM].use_type) { |
|---|
| 1192 | + if (!ttm_resource_manager_used(man)) { |
|---|
| 1349 | 1193 | vmw_write(dev_priv, SVGA_REG_ENABLE, SVGA_REG_ENABLE); |
|---|
| 1350 | | - dev_priv->bdev.man[TTM_PL_VRAM].use_type = true; |
|---|
| 1194 | + ttm_resource_manager_set_used(man, true); |
|---|
| 1351 | 1195 | } |
|---|
| 1352 | 1196 | spin_unlock(&dev_priv->svga_lock); |
|---|
| 1353 | 1197 | } |
|---|
| .. | .. |
|---|
| 1373 | 1217 | */ |
|---|
| 1374 | 1218 | static void __vmw_svga_disable(struct vmw_private *dev_priv) |
|---|
| 1375 | 1219 | { |
|---|
| 1220 | + struct ttm_resource_manager *man = ttm_manager_type(&dev_priv->bdev, TTM_PL_VRAM); |
|---|
| 1221 | + |
|---|
| 1376 | 1222 | spin_lock(&dev_priv->svga_lock); |
|---|
| 1377 | | - if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) { |
|---|
| 1378 | | - dev_priv->bdev.man[TTM_PL_VRAM].use_type = false; |
|---|
| 1223 | + if (ttm_resource_manager_used(man)) { |
|---|
| 1224 | + ttm_resource_manager_set_used(man, false); |
|---|
| 1379 | 1225 | vmw_write(dev_priv, SVGA_REG_ENABLE, |
|---|
| 1380 | 1226 | SVGA_REG_ENABLE_HIDE | |
|---|
| 1381 | 1227 | SVGA_REG_ENABLE_ENABLE); |
|---|
| .. | .. |
|---|
| 1392 | 1238 | */ |
|---|
| 1393 | 1239 | void vmw_svga_disable(struct vmw_private *dev_priv) |
|---|
| 1394 | 1240 | { |
|---|
| 1241 | + struct ttm_resource_manager *man = ttm_manager_type(&dev_priv->bdev, TTM_PL_VRAM); |
|---|
| 1395 | 1242 | /* |
|---|
| 1396 | 1243 | * Disabling SVGA will turn off device modesetting capabilities, so |
|---|
| 1397 | 1244 | * notify KMS about that so that it doesn't cache atomic state that |
|---|
| .. | .. |
|---|
| 1407 | 1254 | vmw_kms_lost_device(dev_priv->dev); |
|---|
| 1408 | 1255 | ttm_write_lock(&dev_priv->reservation_sem, false); |
|---|
| 1409 | 1256 | spin_lock(&dev_priv->svga_lock); |
|---|
| 1410 | | - if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) { |
|---|
| 1411 | | - dev_priv->bdev.man[TTM_PL_VRAM].use_type = false; |
|---|
| 1257 | + if (ttm_resource_manager_used(man)) { |
|---|
| 1258 | + ttm_resource_manager_set_used(man, false); |
|---|
| 1412 | 1259 | spin_unlock(&dev_priv->svga_lock); |
|---|
| 1413 | 1260 | if (ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM)) |
|---|
| 1414 | 1261 | DRM_ERROR("Failed evicting VRAM buffers.\n"); |
|---|
| .. | .. |
|---|
| 1424 | 1271 | { |
|---|
| 1425 | 1272 | struct drm_device *dev = pci_get_drvdata(pdev); |
|---|
| 1426 | 1273 | |
|---|
| 1274 | + drm_dev_unregister(dev); |
|---|
| 1275 | + vmw_driver_unload(dev); |
|---|
| 1276 | + drm_dev_put(dev); |
|---|
| 1427 | 1277 | pci_disable_device(pdev); |
|---|
| 1428 | | - drm_put_dev(dev); |
|---|
| 1278 | +} |
|---|
| 1279 | + |
|---|
| 1280 | +static unsigned long |
|---|
| 1281 | +vmw_get_unmapped_area(struct file *file, unsigned long uaddr, |
|---|
| 1282 | + unsigned long len, unsigned long pgoff, |
|---|
| 1283 | + unsigned long flags) |
|---|
| 1284 | +{ |
|---|
| 1285 | + struct drm_file *file_priv = file->private_data; |
|---|
| 1286 | + struct vmw_private *dev_priv = vmw_priv(file_priv->minor->dev); |
|---|
| 1287 | + |
|---|
| 1288 | + return drm_get_unmapped_area(file, uaddr, len, pgoff, flags, |
|---|
| 1289 | + &dev_priv->vma_manager); |
|---|
| 1429 | 1290 | } |
|---|
| 1430 | 1291 | |
|---|
| 1431 | 1292 | static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, |
|---|
| .. | .. |
|---|
| 1523 | 1384 | vmw_execbuf_release_pinned_bo(dev_priv); |
|---|
| 1524 | 1385 | vmw_resource_evict_all(dev_priv); |
|---|
| 1525 | 1386 | vmw_release_device_early(dev_priv); |
|---|
| 1526 | | - ttm_bo_swapout_all(&dev_priv->bdev); |
|---|
| 1387 | + ttm_bo_swapout_all(); |
|---|
| 1527 | 1388 | if (dev_priv->enable_fb) |
|---|
| 1528 | 1389 | vmw_fifo_resource_dec(dev_priv); |
|---|
| 1529 | 1390 | if (atomic_read(&dev_priv->num_fifo_resources) != 0) { |
|---|
| .. | .. |
|---|
| 1599 | 1460 | .compat_ioctl = vmw_compat_ioctl, |
|---|
| 1600 | 1461 | #endif |
|---|
| 1601 | 1462 | .llseek = noop_llseek, |
|---|
| 1463 | + .get_unmapped_area = vmw_get_unmapped_area, |
|---|
| 1602 | 1464 | }; |
|---|
| 1603 | 1465 | |
|---|
| 1604 | 1466 | static struct drm_driver driver = { |
|---|
| 1605 | | - .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | |
|---|
| 1606 | | - DRIVER_MODESET | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC, |
|---|
| 1607 | | - .load = vmw_driver_load, |
|---|
| 1608 | | - .unload = vmw_driver_unload, |
|---|
| 1609 | | - .lastclose = vmw_lastclose, |
|---|
| 1610 | | - .get_vblank_counter = vmw_get_vblank_counter, |
|---|
| 1611 | | - .enable_vblank = vmw_enable_vblank, |
|---|
| 1612 | | - .disable_vblank = vmw_disable_vblank, |
|---|
| 1467 | + .driver_features = |
|---|
| 1468 | + DRIVER_MODESET | DRIVER_RENDER | DRIVER_ATOMIC, |
|---|
| 1613 | 1469 | .ioctls = vmw_ioctls, |
|---|
| 1614 | 1470 | .num_ioctls = ARRAY_SIZE(vmw_ioctls), |
|---|
| 1615 | | - .master_create = vmw_master_create, |
|---|
| 1616 | | - .master_destroy = vmw_master_destroy, |
|---|
| 1617 | 1471 | .master_set = vmw_master_set, |
|---|
| 1618 | 1472 | .master_drop = vmw_master_drop, |
|---|
| 1619 | 1473 | .open = vmw_driver_open, |
|---|
| .. | .. |
|---|
| 1647 | 1501 | |
|---|
| 1648 | 1502 | static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
|---|
| 1649 | 1503 | { |
|---|
| 1650 | | - return drm_get_pci_dev(pdev, ent, &driver); |
|---|
| 1504 | + struct drm_device *dev; |
|---|
| 1505 | + int ret; |
|---|
| 1506 | + |
|---|
| 1507 | + ret = pci_enable_device(pdev); |
|---|
| 1508 | + if (ret) |
|---|
| 1509 | + return ret; |
|---|
| 1510 | + |
|---|
| 1511 | + dev = drm_dev_alloc(&driver, &pdev->dev); |
|---|
| 1512 | + if (IS_ERR(dev)) { |
|---|
| 1513 | + ret = PTR_ERR(dev); |
|---|
| 1514 | + goto err_pci_disable_device; |
|---|
| 1515 | + } |
|---|
| 1516 | + |
|---|
| 1517 | + dev->pdev = pdev; |
|---|
| 1518 | + pci_set_drvdata(pdev, dev); |
|---|
| 1519 | + |
|---|
| 1520 | + ret = vmw_driver_load(dev, ent->driver_data); |
|---|
| 1521 | + if (ret) |
|---|
| 1522 | + goto err_drm_dev_put; |
|---|
| 1523 | + |
|---|
| 1524 | + ret = drm_dev_register(dev, ent->driver_data); |
|---|
| 1525 | + if (ret) |
|---|
| 1526 | + goto err_vmw_driver_unload; |
|---|
| 1527 | + |
|---|
| 1528 | + return 0; |
|---|
| 1529 | + |
|---|
| 1530 | +err_vmw_driver_unload: |
|---|
| 1531 | + vmw_driver_unload(dev); |
|---|
| 1532 | +err_drm_dev_put: |
|---|
| 1533 | + drm_dev_put(dev); |
|---|
| 1534 | +err_pci_disable_device: |
|---|
| 1535 | + pci_disable_device(pdev); |
|---|
| 1536 | + return ret; |
|---|
| 1651 | 1537 | } |
|---|
| 1652 | 1538 | |
|---|
| 1653 | 1539 | static int __init vmwgfx_init(void) |
|---|