aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_drv.c')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c138
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