diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_drv.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 138 |
1 files changed, 110 insertions, 28 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 22a2874116c9..4904100ef492 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -50,7 +50,7 @@ #define VMWGFX_VALIDATION_MEM_GRAN (16*PAGE_SIZE) -/** +/* * Fully encoded drm commands. Might move to vmw_drm.h */ @@ -246,6 +246,7 @@ static const struct drm_ioctl_desc vmw_ioctls[] = { static const struct pci_device_id vmw_pci_id_list[] = { { PCI_DEVICE(0x15ad, VMWGFX_PCI_ID_SVGA2) }, + { PCI_DEVICE(0x15ad, VMWGFX_PCI_ID_SVGA3) }, { } }; MODULE_DEVICE_TABLE(pci, vmw_pci_id_list); @@ -393,6 +394,60 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) return ret; } +static int vmw_device_init(struct vmw_private *dev_priv) +{ + bool uses_fb_traces = false; + + DRM_INFO("width %d\n", vmw_read(dev_priv, SVGA_REG_WIDTH)); + DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT)); + DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL)); + + dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); + dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); + dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); + + vmw_write(dev_priv, SVGA_REG_ENABLE, SVGA_REG_ENABLE_ENABLE | + SVGA_REG_ENABLE_HIDE); + + uses_fb_traces = !vmw_cmd_supported(dev_priv) && + (dev_priv->capabilities & SVGA_CAP_TRACES) != 0; + + vmw_write(dev_priv, SVGA_REG_TRACES, uses_fb_traces); + dev_priv->fifo = vmw_fifo_create(dev_priv); + if (IS_ERR(dev_priv->fifo)) { + int err = PTR_ERR(dev_priv->fifo); + dev_priv->fifo = NULL; + return err; + } else if (!dev_priv->fifo) { + vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1); + } + + dev_priv->last_read_seqno = vmw_fence_read(dev_priv); + atomic_set(&dev_priv->marker_seq, dev_priv->last_read_seqno); + return 0; +} + +static void vmw_device_fini(struct vmw_private *vmw) +{ + /* + * Legacy sync + */ + vmw_write(vmw, SVGA_REG_SYNC, SVGA_SYNC_GENERIC); + while (vmw_read(vmw, SVGA_REG_BUSY) != 0) + ; + + vmw->last_read_seqno = vmw_fence_read(vmw); + + vmw_write(vmw, SVGA_REG_CONFIG_DONE, + vmw->config_done_state); + vmw_write(vmw, SVGA_REG_ENABLE, + vmw->enable_state); + vmw_write(vmw, SVGA_REG_TRACES, + vmw->traces_state); + + vmw_fifo_destroy(vmw); +} + /** * vmw_request_device_late - Perform late device setup * @@ -433,9 +488,9 @@ static int vmw_request_device(struct vmw_private *dev_priv) { int ret; - ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); + ret = vmw_device_init(dev_priv); if (unlikely(ret != 0)) { - DRM_ERROR("Unable to initialize FIFO.\n"); + DRM_ERROR("Unable to initialize the device.\n"); return ret; } vmw_fence_fifo_up(dev_priv->fman); @@ -469,7 +524,7 @@ out_no_query_bo: vmw_cmdbuf_man_destroy(dev_priv->cman); out_no_mob: vmw_fence_fifo_down(dev_priv->fman); - vmw_fifo_release(dev_priv, &dev_priv->fifo); + vmw_device_fini(dev_priv); return ret; } @@ -517,7 +572,7 @@ static void vmw_release_device_late(struct vmw_private *dev_priv) if (dev_priv->cman) vmw_cmdbuf_man_destroy(dev_priv->cman); - vmw_fifo_release(dev_priv, &dev_priv->fifo); + vmw_device_fini(dev_priv); } /* @@ -638,6 +693,8 @@ static void vmw_vram_manager_fini(struct vmw_private *dev_priv) static int vmw_setup_pci_resources(struct vmw_private *dev, unsigned long pci_id) { + resource_size_t rmmio_start; + resource_size_t rmmio_size; resource_size_t fifo_start; resource_size_t fifo_size; int ret; @@ -649,23 +706,45 @@ static int vmw_setup_pci_resources(struct vmw_private *dev, if (ret) return ret; - dev->io_start = pci_resource_start(pdev, 0); - dev->vram_start = pci_resource_start(pdev, 1); - dev->vram_size = pci_resource_len(pdev, 1); - fifo_start = pci_resource_start(pdev, 2); - fifo_size = pci_resource_len(pdev, 2); - - DRM_INFO("FIFO at %pa size is %llu kiB\n", - &fifo_start, (uint64_t)fifo_size / 1024); - dev->fifo_mem = devm_memremap(dev->drm.dev, - fifo_start, - fifo_size, - MEMREMAP_WB); - - if (IS_ERR(dev->fifo_mem)) { - DRM_ERROR("Failed mapping FIFO memory.\n"); + dev->pci_id = pci_id; + if (pci_id == VMWGFX_PCI_ID_SVGA3) { + rmmio_start = pci_resource_start(pdev, 0); + rmmio_size = pci_resource_len(pdev, 0); + dev->vram_start = pci_resource_start(pdev, 2); + dev->vram_size = pci_resource_len(pdev, 2); + + DRM_INFO("Register MMIO at 0x%pa size is %llu kiB\n", + &rmmio_start, (uint64_t)rmmio_size / 1024); + dev->rmmio = devm_ioremap(dev->drm.dev, + rmmio_start, + rmmio_size); + if (IS_ERR(dev->rmmio)) { + DRM_ERROR("Failed mapping registers mmio memory.\n"); + pci_release_regions(pdev); + return PTR_ERR(dev->rmmio); + } + } else if (pci_id == VMWGFX_PCI_ID_SVGA2) { + dev->io_start = pci_resource_start(pdev, 0); + dev->vram_start = pci_resource_start(pdev, 1); + dev->vram_size = pci_resource_len(pdev, 1); + fifo_start = pci_resource_start(pdev, 2); + fifo_size = pci_resource_len(pdev, 2); + + DRM_INFO("FIFO at %pa size is %llu kiB\n", + &fifo_start, (uint64_t)fifo_size / 1024); + dev->fifo_mem = devm_memremap(dev->drm.dev, + fifo_start, + fifo_size, + MEMREMAP_WB); + + if (IS_ERR(dev->fifo_mem)) { + DRM_ERROR("Failed mapping FIFO memory.\n"); + pci_release_regions(pdev); + return PTR_ERR(dev->fifo_mem); + } + } else { pci_release_regions(pdev); - return PTR_ERR(dev->fifo_mem); + return -EINVAL; } /* @@ -684,13 +763,16 @@ static int vmw_detect_version(struct vmw_private *dev) { uint32_t svga_id; - vmw_write(dev, SVGA_REG_ID, SVGA_ID_2); + vmw_write(dev, SVGA_REG_ID, vmw_is_svga_v3(dev) ? + SVGA_ID_3 : SVGA_ID_2); svga_id = vmw_read(dev, SVGA_REG_ID); - if (svga_id != SVGA_ID_2) { + if (svga_id != SVGA_ID_2 && svga_id != SVGA_ID_3) { DRM_ERROR("Unsupported SVGA ID 0x%x on chipset 0x%x\n", svga_id, dev->vmw_chipset); return -ENOSYS; } + BUG_ON(vmw_is_svga_v3(dev) && (svga_id != SVGA_ID_3)); + DRM_INFO("Running on SVGA version %d.\n", (svga_id & 0xff)); return 0; } @@ -703,7 +785,6 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); dev_priv->vmw_chipset = pci_id; - dev_priv->last_read_seqno = (uint32_t) -100; dev_priv->drm.dev_private = dev_priv; mutex_init(&dev_priv->cmdbuf_mutex); @@ -824,6 +905,8 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) vmw_print_capabilities(dev_priv->capabilities); if (dev_priv->capabilities & SVGA_CAP_CAP2_REGISTER) vmw_print_capabilities2(dev_priv->capabilities2); + DRM_INFO("Supports command queues = %d\n", + vmw_cmd_supported((dev_priv))); ret = vmw_dma_masks(dev_priv); if (unlikely(ret != 0)) @@ -1390,8 +1473,7 @@ static int vmw_pm_restore(struct device *kdev) struct vmw_private *dev_priv = vmw_priv(dev); int ret; - vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); - (void) vmw_read(dev_priv, SVGA_REG_ID); + vmw_detect_version(dev_priv); if (dev_priv->enable_fb) vmw_fifo_resource_inc(dev_priv); @@ -1428,8 +1510,8 @@ static const struct file_operations vmwgfx_driver_fops = { .release = drm_release, .unlocked_ioctl = vmw_unlocked_ioctl, .mmap = vmw_mmap, - .poll = vmw_fops_poll, - .read = vmw_fops_read, + .poll = drm_poll, + .read = drm_read, #if defined(CONFIG_COMPAT) .compat_ioctl = vmw_compat_ioctl, #endif |