aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c102
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h7
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c3
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c12
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_resource.c4
5 files changed, 115 insertions, 13 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 292aeba385e0..23e29f3a0c33 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -149,12 +149,16 @@ static struct pci_device_id vmw_pci_id_list[] = {
149}; 149};
150 150
151static char *vmw_devname = "vmwgfx"; 151static char *vmw_devname = "vmwgfx";
152static int enable_fbdev;
152 153
153static int vmw_probe(struct pci_dev *, const struct pci_device_id *); 154static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
154static void vmw_master_init(struct vmw_master *); 155static void vmw_master_init(struct vmw_master *);
155static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, 156static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
156 void *ptr); 157 void *ptr);
157 158
159MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev");
160module_param_named(enable_fbdev, enable_fbdev, int, 0600);
161
158static void vmw_print_capabilities(uint32_t capabilities) 162static void vmw_print_capabilities(uint32_t capabilities)
159{ 163{
160 DRM_INFO("Capabilities:\n"); 164 DRM_INFO("Capabilities:\n");
@@ -192,8 +196,6 @@ static int vmw_request_device(struct vmw_private *dev_priv)
192{ 196{
193 int ret; 197 int ret;
194 198
195 vmw_kms_save_vga(dev_priv);
196
197 ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); 199 ret = vmw_fifo_init(dev_priv, &dev_priv->fifo);
198 if (unlikely(ret != 0)) { 200 if (unlikely(ret != 0)) {
199 DRM_ERROR("Unable to initialize FIFO.\n"); 201 DRM_ERROR("Unable to initialize FIFO.\n");
@@ -206,10 +208,36 @@ static int vmw_request_device(struct vmw_private *dev_priv)
206static void vmw_release_device(struct vmw_private *dev_priv) 208static void vmw_release_device(struct vmw_private *dev_priv)
207{ 209{
208 vmw_fifo_release(dev_priv, &dev_priv->fifo); 210 vmw_fifo_release(dev_priv, &dev_priv->fifo);
209 vmw_kms_restore_vga(dev_priv); 211}
212
213int vmw_3d_resource_inc(struct vmw_private *dev_priv)
214{
215 int ret = 0;
216
217 mutex_lock(&dev_priv->release_mutex);
218 if (unlikely(dev_priv->num_3d_resources++ == 0)) {
219 ret = vmw_request_device(dev_priv);
220 if (unlikely(ret != 0))
221 --dev_priv->num_3d_resources;
222 }
223 mutex_unlock(&dev_priv->release_mutex);
224 return ret;
210} 225}
211 226
212 227
228void vmw_3d_resource_dec(struct vmw_private *dev_priv)
229{
230 int32_t n3d;
231
232 mutex_lock(&dev_priv->release_mutex);
233 if (unlikely(--dev_priv->num_3d_resources == 0))
234 vmw_release_device(dev_priv);
235 n3d = (int32_t) dev_priv->num_3d_resources;
236 mutex_unlock(&dev_priv->release_mutex);
237
238 BUG_ON(n3d < 0);
239}
240
213static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) 241static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
214{ 242{
215 struct vmw_private *dev_priv; 243 struct vmw_private *dev_priv;
@@ -228,6 +256,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
228 dev_priv->last_read_sequence = (uint32_t) -100; 256 dev_priv->last_read_sequence = (uint32_t) -100;
229 mutex_init(&dev_priv->hw_mutex); 257 mutex_init(&dev_priv->hw_mutex);
230 mutex_init(&dev_priv->cmdbuf_mutex); 258 mutex_init(&dev_priv->cmdbuf_mutex);
259 mutex_init(&dev_priv->release_mutex);
231 rwlock_init(&dev_priv->resource_lock); 260 rwlock_init(&dev_priv->resource_lock);
232 idr_init(&dev_priv->context_idr); 261 idr_init(&dev_priv->context_idr);
233 idr_init(&dev_priv->surface_idr); 262 idr_init(&dev_priv->surface_idr);
@@ -244,6 +273,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
244 dev_priv->vram_start = pci_resource_start(dev->pdev, 1); 273 dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
245 dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); 274 dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
246 275
276 dev_priv->enable_fb = enable_fbdev;
277
247 mutex_lock(&dev_priv->hw_mutex); 278 mutex_lock(&dev_priv->hw_mutex);
248 279
249 vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); 280 vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
@@ -369,20 +400,34 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
369 goto out_no_device; 400 goto out_no_device;
370 } 401 }
371 } 402 }
372 ret = vmw_request_device(dev_priv);
373 if (unlikely(ret != 0))
374 goto out_no_device;
375 vmw_kms_init(dev_priv); 403 vmw_kms_init(dev_priv);
376 vmw_overlay_init(dev_priv); 404 vmw_overlay_init(dev_priv);
377 vmw_fb_init(dev_priv); 405 if (dev_priv->enable_fb) {
406 ret = vmw_3d_resource_inc(dev_priv);
407 if (unlikely(ret != 0))
408 goto out_no_fifo;
409 vmw_kms_save_vga(dev_priv);
410 vmw_fb_init(dev_priv);
411 DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ?
412 "Detected device 3D availability.\n" :
413 "Detected no device 3D availability.\n");
414 } else {
415 DRM_INFO("Delayed 3D detection since we're not "
416 "running the device in SVGA mode yet.\n");
417 }
378 418
379 dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; 419 dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier;
380 register_pm_notifier(&dev_priv->pm_nb); 420 register_pm_notifier(&dev_priv->pm_nb);
381 421
382 DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? "Have 3D\n" : "No 3D\n");
383
384 return 0; 422 return 0;
385 423
424out_no_fifo:
425 vmw_overlay_close(dev_priv);
426 vmw_kms_close(dev_priv);
427 if (dev_priv->stealth)
428 pci_release_region(dev->pdev, 2);
429 else
430 pci_release_regions(dev->pdev);
386out_no_device: 431out_no_device:
387 if (dev_priv->capabilities & SVGA_CAP_IRQMASK) 432 if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
388 drm_irq_uninstall(dev_priv->dev); 433 drm_irq_uninstall(dev_priv->dev);
@@ -415,10 +460,13 @@ static int vmw_driver_unload(struct drm_device *dev)
415 460
416 unregister_pm_notifier(&dev_priv->pm_nb); 461 unregister_pm_notifier(&dev_priv->pm_nb);
417 462
418 vmw_fb_close(dev_priv); 463 if (dev_priv->enable_fb) {
464 vmw_fb_close(dev_priv);
465 vmw_kms_restore_vga(dev_priv);
466 vmw_3d_resource_dec(dev_priv);
467 }
419 vmw_kms_close(dev_priv); 468 vmw_kms_close(dev_priv);
420 vmw_overlay_close(dev_priv); 469 vmw_overlay_close(dev_priv);
421 vmw_release_device(dev_priv);
422 if (dev_priv->stealth) 470 if (dev_priv->stealth)
423 pci_release_region(dev->pdev, 2); 471 pci_release_region(dev->pdev, 2);
424 else 472 else
@@ -589,6 +637,16 @@ static int vmw_master_set(struct drm_device *dev,
589 struct vmw_master *vmaster = vmw_master(file_priv->master); 637 struct vmw_master *vmaster = vmw_master(file_priv->master);
590 int ret = 0; 638 int ret = 0;
591 639
640 if (!dev_priv->enable_fb) {
641 ret = vmw_3d_resource_inc(dev_priv);
642 if (unlikely(ret != 0))
643 return ret;
644 vmw_kms_save_vga(dev_priv);
645 mutex_lock(&dev_priv->hw_mutex);
646 vmw_write(dev_priv, SVGA_REG_TRACES, 0);
647 mutex_unlock(&dev_priv->hw_mutex);
648 }
649
592 if (active) { 650 if (active) {
593 BUG_ON(active != &dev_priv->fbdev_master); 651 BUG_ON(active != &dev_priv->fbdev_master);
594 ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); 652 ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile);
@@ -617,7 +675,13 @@ static int vmw_master_set(struct drm_device *dev,
617 return 0; 675 return 0;
618 676
619out_no_active_lock: 677out_no_active_lock:
620 vmw_release_device(dev_priv); 678 if (!dev_priv->enable_fb) {
679 mutex_lock(&dev_priv->hw_mutex);
680 vmw_write(dev_priv, SVGA_REG_TRACES, 1);
681 mutex_unlock(&dev_priv->hw_mutex);
682 vmw_kms_restore_vga(dev_priv);
683 vmw_3d_resource_dec(dev_priv);
684 }
621 return ret; 685 return ret;
622} 686}
623 687
@@ -645,11 +709,23 @@ static void vmw_master_drop(struct drm_device *dev,
645 709
646 ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); 710 ttm_lock_set_kill(&vmaster->lock, true, SIGTERM);
647 711
712 if (!dev_priv->enable_fb) {
713 ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM);
714 if (unlikely(ret != 0))
715 DRM_ERROR("Unable to clean VRAM on master drop.\n");
716 mutex_lock(&dev_priv->hw_mutex);
717 vmw_write(dev_priv, SVGA_REG_TRACES, 1);
718 mutex_unlock(&dev_priv->hw_mutex);
719 vmw_kms_restore_vga(dev_priv);
720 vmw_3d_resource_dec(dev_priv);
721 }
722
648 dev_priv->active_master = &dev_priv->fbdev_master; 723 dev_priv->active_master = &dev_priv->fbdev_master;
649 ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); 724 ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
650 ttm_vt_unlock(&dev_priv->fbdev_master.lock); 725 ttm_vt_unlock(&dev_priv->fbdev_master.lock);
651 726
652 vmw_fb_on(dev_priv); 727 if (dev_priv->enable_fb)
728 vmw_fb_on(dev_priv);
653} 729}
654 730
655 731
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 429f917b60bf..9142454cc91e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -277,6 +277,7 @@ struct vmw_private {
277 277
278 bool stealth; 278 bool stealth;
279 bool is_opened; 279 bool is_opened;
280 bool enable_fb;
280 281
281 /** 282 /**
282 * Master management. 283 * Master management.
@@ -285,6 +286,9 @@ struct vmw_private {
285 struct vmw_master *active_master; 286 struct vmw_master *active_master;
286 struct vmw_master fbdev_master; 287 struct vmw_master fbdev_master;
287 struct notifier_block pm_nb; 288 struct notifier_block pm_nb;
289
290 struct mutex release_mutex;
291 uint32_t num_3d_resources;
288}; 292};
289 293
290static inline struct vmw_private *vmw_priv(struct drm_device *dev) 294static inline struct vmw_private *vmw_priv(struct drm_device *dev)
@@ -319,6 +323,9 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv,
319 return val; 323 return val;
320} 324}
321 325
326int vmw_3d_resource_inc(struct vmw_private *dev_priv);
327void vmw_3d_resource_dec(struct vmw_private *dev_priv);
328
322/** 329/**
323 * GMR utilities - vmwgfx_gmr.c 330 * GMR utilities - vmwgfx_gmr.c
324 */ 331 */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
index e6a1eb7ea954..0fe31766e4cf 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
@@ -106,6 +106,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
106 mutex_lock(&dev_priv->hw_mutex); 106 mutex_lock(&dev_priv->hw_mutex);
107 dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); 107 dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE);
108 dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); 108 dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE);
109 dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES);
109 vmw_write(dev_priv, SVGA_REG_ENABLE, 1); 110 vmw_write(dev_priv, SVGA_REG_ENABLE, 1);
110 111
111 min = 4; 112 min = 4;
@@ -175,6 +176,8 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
175 dev_priv->config_done_state); 176 dev_priv->config_done_state);
176 vmw_write(dev_priv, SVGA_REG_ENABLE, 177 vmw_write(dev_priv, SVGA_REG_ENABLE,
177 dev_priv->enable_state); 178 dev_priv->enable_state);
179 vmw_write(dev_priv, SVGA_REG_TRACES,
180 dev_priv->traces_state);
178 181
179 mutex_unlock(&dev_priv->hw_mutex); 182 mutex_unlock(&dev_priv->hw_mutex);
180 vmw_fence_queue_takedown(&fifo->fence_queue); 183 vmw_fence_queue_takedown(&fifo->fence_queue);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 64d7f47df868..1636e9ba81a1 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -898,7 +898,19 @@ int vmw_kms_save_vga(struct vmw_private *vmw_priv)
898 save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); 898 save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH);
899 save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); 899 save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT);
900 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); 900 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
901 if (i == 0 && vmw_priv->num_displays == 1 &&
902 save->width == 0 && save->height == 0) {
903
904 /*
905 * It should be fairly safe to assume that these
906 * values are uninitialized.
907 */
908
909 save->width = vmw_priv->vga_width - save->pos_x;
910 save->height = vmw_priv->vga_height - save->pos_y;
911 }
901 } 912 }
913
902 return 0; 914 return 0;
903} 915}
904 916
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 5f2d5df01e5c..c8c40e9979db 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -211,6 +211,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res)
211 cmd->body.cid = cpu_to_le32(res->id); 211 cmd->body.cid = cpu_to_le32(res->id);
212 212
213 vmw_fifo_commit(dev_priv, sizeof(*cmd)); 213 vmw_fifo_commit(dev_priv, sizeof(*cmd));
214 vmw_3d_resource_dec(dev_priv);
214} 215}
215 216
216static int vmw_context_init(struct vmw_private *dev_priv, 217static int vmw_context_init(struct vmw_private *dev_priv,
@@ -247,6 +248,7 @@ static int vmw_context_init(struct vmw_private *dev_priv,
247 cmd->body.cid = cpu_to_le32(res->id); 248 cmd->body.cid = cpu_to_le32(res->id);
248 249
249 vmw_fifo_commit(dev_priv, sizeof(*cmd)); 250 vmw_fifo_commit(dev_priv, sizeof(*cmd));
251 (void) vmw_3d_resource_inc(dev_priv);
250 vmw_resource_activate(res, vmw_hw_context_destroy); 252 vmw_resource_activate(res, vmw_hw_context_destroy);
251 return 0; 253 return 0;
252} 254}
@@ -406,6 +408,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res)
406 cmd->body.sid = cpu_to_le32(res->id); 408 cmd->body.sid = cpu_to_le32(res->id);
407 409
408 vmw_fifo_commit(dev_priv, sizeof(*cmd)); 410 vmw_fifo_commit(dev_priv, sizeof(*cmd));
411 vmw_3d_resource_dec(dev_priv);
409} 412}
410 413
411void vmw_surface_res_free(struct vmw_resource *res) 414void vmw_surface_res_free(struct vmw_resource *res)
@@ -473,6 +476,7 @@ int vmw_surface_init(struct vmw_private *dev_priv,
473 } 476 }
474 477
475 vmw_fifo_commit(dev_priv, submit_size); 478 vmw_fifo_commit(dev_priv, submit_size);
479 (void) vmw_3d_resource_inc(dev_priv);
476 vmw_resource_activate(res, vmw_hw_surface_destroy); 480 vmw_resource_activate(res, vmw_hw_surface_destroy);
477 return 0; 481 return 0;
478} 482}