aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2010-10-01 04:21:49 -0400
committerDave Airlie <airlied@redhat.com>2010-10-01 07:08:51 -0400
commit7a1c2f6c8d8485af5ac6c2a313f6a7162207a4af (patch)
tree867f60ced7f7742dc2f4a2010d32b516e90ea411 /drivers/gpu
parent30c78bb838b26ec7997515844c0c734e454b3cba (diff)
vmwgfx: Enable use of the vblank system
This is to avoid accessing uninitialized data during drm_irq_uninstall and vblank ioctls. At the same time, enable error check from drm_kms_init which previously appeared to ignore all errors. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c47
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h1
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c5
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c27
4 files changed, 49 insertions, 31 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 23e29f3a0c33..6bbe703e7d97 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -374,17 +374,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
374 374
375 dev->dev_private = dev_priv; 375 dev->dev_private = dev_priv;
376 376
377 if (!dev->devname)
378 dev->devname = vmw_devname;
379
380 if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
381 ret = drm_irq_install(dev);
382 if (unlikely(ret != 0)) {
383 DRM_ERROR("Failed installing irq: %d\n", ret);
384 goto out_no_irq;
385 }
386 }
387
388 ret = pci_request_regions(dev->pdev, "vmwgfx probe"); 377 ret = pci_request_regions(dev->pdev, "vmwgfx probe");
389 dev_priv->stealth = (ret != 0); 378 dev_priv->stealth = (ret != 0);
390 if (dev_priv->stealth) { 379 if (dev_priv->stealth) {
@@ -400,7 +389,9 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
400 goto out_no_device; 389 goto out_no_device;
401 } 390 }
402 } 391 }
403 vmw_kms_init(dev_priv); 392 ret = vmw_kms_init(dev_priv);
393 if (unlikely(ret != 0))
394 goto out_no_kms;
404 vmw_overlay_init(dev_priv); 395 vmw_overlay_init(dev_priv);
405 if (dev_priv->enable_fb) { 396 if (dev_priv->enable_fb) {
406 ret = vmw_3d_resource_inc(dev_priv); 397 ret = vmw_3d_resource_inc(dev_priv);
@@ -416,24 +407,37 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
416 "running the device in SVGA mode yet.\n"); 407 "running the device in SVGA mode yet.\n");
417 } 408 }
418 409
410 if (!dev->devname)
411 dev->devname = vmw_devname;
412
413 if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
414 ret = drm_irq_install(dev);
415 if (unlikely(ret != 0)) {
416 DRM_ERROR("Failed installing irq: %d\n", ret);
417 goto out_no_irq;
418 }
419 }
420
419 dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; 421 dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier;
420 register_pm_notifier(&dev_priv->pm_nb); 422 register_pm_notifier(&dev_priv->pm_nb);
421 423
422 return 0; 424 return 0;
423 425
426out_no_irq:
427 if (dev_priv->enable_fb) {
428 vmw_fb_close(dev_priv);
429 vmw_kms_restore_vga(dev_priv);
430 vmw_3d_resource_dec(dev_priv);
431 }
424out_no_fifo: 432out_no_fifo:
425 vmw_overlay_close(dev_priv); 433 vmw_overlay_close(dev_priv);
426 vmw_kms_close(dev_priv); 434 vmw_kms_close(dev_priv);
435out_no_kms:
427 if (dev_priv->stealth) 436 if (dev_priv->stealth)
428 pci_release_region(dev->pdev, 2); 437 pci_release_region(dev->pdev, 2);
429 else 438 else
430 pci_release_regions(dev->pdev); 439 pci_release_regions(dev->pdev);
431out_no_device: 440out_no_device:
432 if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
433 drm_irq_uninstall(dev_priv->dev);
434 if (dev->devname == vmw_devname)
435 dev->devname = NULL;
436out_no_irq:
437 ttm_object_device_release(&dev_priv->tdev); 441 ttm_object_device_release(&dev_priv->tdev);
438out_err4: 442out_err4:
439 iounmap(dev_priv->mmio_virt); 443 iounmap(dev_priv->mmio_virt);
@@ -460,6 +464,10 @@ static int vmw_driver_unload(struct drm_device *dev)
460 464
461 unregister_pm_notifier(&dev_priv->pm_nb); 465 unregister_pm_notifier(&dev_priv->pm_nb);
462 466
467 if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
468 drm_irq_uninstall(dev_priv->dev);
469 if (dev->devname == vmw_devname)
470 dev->devname = NULL;
463 if (dev_priv->enable_fb) { 471 if (dev_priv->enable_fb) {
464 vmw_fb_close(dev_priv); 472 vmw_fb_close(dev_priv);
465 vmw_kms_restore_vga(dev_priv); 473 vmw_kms_restore_vga(dev_priv);
@@ -472,10 +480,6 @@ static int vmw_driver_unload(struct drm_device *dev)
472 else 480 else
473 pci_release_regions(dev->pdev); 481 pci_release_regions(dev->pdev);
474 482
475 if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
476 drm_irq_uninstall(dev_priv->dev);
477 if (dev->devname == vmw_devname)
478 dev->devname = NULL;
479 ttm_object_device_release(&dev_priv->tdev); 483 ttm_object_device_release(&dev_priv->tdev);
480 iounmap(dev_priv->mmio_virt); 484 iounmap(dev_priv->mmio_virt);
481 drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, 485 drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start,
@@ -798,6 +802,7 @@ static struct drm_driver driver = {
798 .irq_postinstall = vmw_irq_postinstall, 802 .irq_postinstall = vmw_irq_postinstall,
799 .irq_uninstall = vmw_irq_uninstall, 803 .irq_uninstall = vmw_irq_uninstall,
800 .irq_handler = vmw_irq_handler, 804 .irq_handler = vmw_irq_handler,
805 .get_vblank_counter = vmw_get_vblank_counter,
801 .reclaim_buffers_locked = NULL, 806 .reclaim_buffers_locked = NULL,
802 .get_map_ofs = drm_core_get_map_ofs, 807 .get_map_ofs = drm_core_get_map_ofs,
803 .get_reg_ofs = drm_core_get_reg_ofs, 808 .get_reg_ofs = drm_core_get_reg_ofs,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 9142454cc91e..58de6393f611 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -518,6 +518,7 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv,
518 unsigned bbp, unsigned depth); 518 unsigned bbp, unsigned depth);
519int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, 519int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
520 struct drm_file *file_priv); 520 struct drm_file *file_priv);
521u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc);
521 522
522/** 523/**
523 * Overlay control - vmwgfx_overlay.c 524 * Overlay control - vmwgfx_overlay.c
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 1636e9ba81a1..e882ba099f0c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -996,3 +996,8 @@ out_unlock:
996 ttm_read_unlock(&vmaster->lock); 996 ttm_read_unlock(&vmaster->lock);
997 return ret; 997 return ret;
998} 998}
999
1000u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc)
1001{
1002 return 0;
1003}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index 7083b1a24df3..11cb39e3accb 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -27,6 +27,8 @@
27 27
28#include "vmwgfx_kms.h" 28#include "vmwgfx_kms.h"
29 29
30#define VMWGFX_LDU_NUM_DU 8
31
30#define vmw_crtc_to_ldu(x) \ 32#define vmw_crtc_to_ldu(x) \
31 container_of(x, struct vmw_legacy_display_unit, base.crtc) 33 container_of(x, struct vmw_legacy_display_unit, base.crtc)
32#define vmw_encoder_to_ldu(x) \ 34#define vmw_encoder_to_ldu(x) \
@@ -536,6 +538,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
536 538
537int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) 539int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
538{ 540{
541 struct drm_device *dev = dev_priv->dev;
542 int i;
543 int ret;
544
539 if (dev_priv->ldu_priv) { 545 if (dev_priv->ldu_priv) {
540 DRM_INFO("ldu system already on\n"); 546 DRM_INFO("ldu system already on\n");
541 return -EINVAL; 547 return -EINVAL;
@@ -553,23 +559,24 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
553 559
554 drm_mode_create_dirty_info_property(dev_priv->dev); 560 drm_mode_create_dirty_info_property(dev_priv->dev);
555 561
556 vmw_ldu_init(dev_priv, 0);
557 /* for old hardware without multimon only enable one display */
558 if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { 562 if (dev_priv->capabilities & SVGA_CAP_MULTIMON) {
559 vmw_ldu_init(dev_priv, 1); 563 for (i = 0; i < VMWGFX_LDU_NUM_DU; ++i)
560 vmw_ldu_init(dev_priv, 2); 564 vmw_ldu_init(dev_priv, i);
561 vmw_ldu_init(dev_priv, 3); 565 ret = drm_vblank_init(dev, VMWGFX_LDU_NUM_DU);
562 vmw_ldu_init(dev_priv, 4); 566 } else {
563 vmw_ldu_init(dev_priv, 5); 567 /* for old hardware without multimon only enable one display */
564 vmw_ldu_init(dev_priv, 6); 568 vmw_ldu_init(dev_priv, 0);
565 vmw_ldu_init(dev_priv, 7); 569 ret = drm_vblank_init(dev, 1);
566 } 570 }
567 571
568 return 0; 572 return ret;
569} 573}
570 574
571int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) 575int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv)
572{ 576{
577 struct drm_device *dev = dev_priv->dev;
578
579 drm_vblank_cleanup(dev);
573 if (!dev_priv->ldu_priv) 580 if (!dev_priv->ldu_priv)
574 return -ENOSYS; 581 return -ENOSYS;
575 582