diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_drv.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 138 |
1 files changed, 116 insertions, 22 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index a96ed6d9d010..96949b93d920 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -260,13 +260,11 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
260 | idr_init(&dev_priv->context_idr); | 260 | idr_init(&dev_priv->context_idr); |
261 | idr_init(&dev_priv->surface_idr); | 261 | idr_init(&dev_priv->surface_idr); |
262 | idr_init(&dev_priv->stream_idr); | 262 | idr_init(&dev_priv->stream_idr); |
263 | ida_init(&dev_priv->gmr_ida); | ||
264 | mutex_init(&dev_priv->init_mutex); | 263 | mutex_init(&dev_priv->init_mutex); |
265 | init_waitqueue_head(&dev_priv->fence_queue); | 264 | init_waitqueue_head(&dev_priv->fence_queue); |
266 | init_waitqueue_head(&dev_priv->fifo_queue); | 265 | init_waitqueue_head(&dev_priv->fifo_queue); |
267 | atomic_set(&dev_priv->fence_queue_waiters, 0); | 266 | atomic_set(&dev_priv->fence_queue_waiters, 0); |
268 | atomic_set(&dev_priv->fifo_queue_waiters, 0); | 267 | atomic_set(&dev_priv->fifo_queue_waiters, 0); |
269 | INIT_LIST_HEAD(&dev_priv->gmr_lru); | ||
270 | 268 | ||
271 | dev_priv->io_start = pci_resource_start(dev->pdev, 0); | 269 | dev_priv->io_start = pci_resource_start(dev->pdev, 0); |
272 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); | 270 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); |
@@ -341,6 +339,14 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
341 | goto out_err2; | 339 | goto out_err2; |
342 | } | 340 | } |
343 | 341 | ||
342 | dev_priv->has_gmr = true; | ||
343 | if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR, | ||
344 | dev_priv->max_gmr_ids) != 0) { | ||
345 | DRM_INFO("No GMR memory available. " | ||
346 | "Graphics memory resources are very limited.\n"); | ||
347 | dev_priv->has_gmr = false; | ||
348 | } | ||
349 | |||
344 | dev_priv->mmio_mtrr = drm_mtrr_add(dev_priv->mmio_start, | 350 | dev_priv->mmio_mtrr = drm_mtrr_add(dev_priv->mmio_start, |
345 | dev_priv->mmio_size, DRM_MTRR_WC); | 351 | dev_priv->mmio_size, DRM_MTRR_WC); |
346 | 352 | ||
@@ -440,13 +446,14 @@ out_err4: | |||
440 | out_err3: | 446 | out_err3: |
441 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, | 447 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, |
442 | dev_priv->mmio_size, DRM_MTRR_WC); | 448 | dev_priv->mmio_size, DRM_MTRR_WC); |
449 | if (dev_priv->has_gmr) | ||
450 | (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); | ||
443 | (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); | 451 | (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); |
444 | out_err2: | 452 | out_err2: |
445 | (void)ttm_bo_device_release(&dev_priv->bdev); | 453 | (void)ttm_bo_device_release(&dev_priv->bdev); |
446 | out_err1: | 454 | out_err1: |
447 | vmw_ttm_global_release(dev_priv); | 455 | vmw_ttm_global_release(dev_priv); |
448 | out_err0: | 456 | out_err0: |
449 | ida_destroy(&dev_priv->gmr_ida); | ||
450 | idr_destroy(&dev_priv->surface_idr); | 457 | idr_destroy(&dev_priv->surface_idr); |
451 | idr_destroy(&dev_priv->context_idr); | 458 | idr_destroy(&dev_priv->context_idr); |
452 | idr_destroy(&dev_priv->stream_idr); | 459 | idr_destroy(&dev_priv->stream_idr); |
@@ -478,10 +485,11 @@ static int vmw_driver_unload(struct drm_device *dev) | |||
478 | iounmap(dev_priv->mmio_virt); | 485 | iounmap(dev_priv->mmio_virt); |
479 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, | 486 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, |
480 | dev_priv->mmio_size, DRM_MTRR_WC); | 487 | dev_priv->mmio_size, DRM_MTRR_WC); |
488 | if (dev_priv->has_gmr) | ||
489 | (void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); | ||
481 | (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); | 490 | (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); |
482 | (void)ttm_bo_device_release(&dev_priv->bdev); | 491 | (void)ttm_bo_device_release(&dev_priv->bdev); |
483 | vmw_ttm_global_release(dev_priv); | 492 | vmw_ttm_global_release(dev_priv); |
484 | ida_destroy(&dev_priv->gmr_ida); | ||
485 | idr_destroy(&dev_priv->surface_idr); | 493 | idr_destroy(&dev_priv->surface_idr); |
486 | idr_destroy(&dev_priv->context_idr); | 494 | idr_destroy(&dev_priv->context_idr); |
487 | idr_destroy(&dev_priv->stream_idr); | 495 | idr_destroy(&dev_priv->stream_idr); |
@@ -597,6 +605,8 @@ static void vmw_lastclose(struct drm_device *dev) | |||
597 | static void vmw_master_init(struct vmw_master *vmaster) | 605 | static void vmw_master_init(struct vmw_master *vmaster) |
598 | { | 606 | { |
599 | ttm_lock_init(&vmaster->lock); | 607 | ttm_lock_init(&vmaster->lock); |
608 | INIT_LIST_HEAD(&vmaster->fb_surf); | ||
609 | mutex_init(&vmaster->fb_surf_mutex); | ||
600 | } | 610 | } |
601 | 611 | ||
602 | static int vmw_master_create(struct drm_device *dev, | 612 | static int vmw_master_create(struct drm_device *dev, |
@@ -608,7 +618,7 @@ static int vmw_master_create(struct drm_device *dev, | |||
608 | if (unlikely(vmaster == NULL)) | 618 | if (unlikely(vmaster == NULL)) |
609 | return -ENOMEM; | 619 | return -ENOMEM; |
610 | 620 | ||
611 | ttm_lock_init(&vmaster->lock); | 621 | vmw_master_init(vmaster); |
612 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); | 622 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); |
613 | master->driver_priv = vmaster; | 623 | master->driver_priv = vmaster; |
614 | 624 | ||
@@ -699,6 +709,7 @@ static void vmw_master_drop(struct drm_device *dev, | |||
699 | 709 | ||
700 | vmw_fp->locked_master = drm_master_get(file_priv->master); | 710 | vmw_fp->locked_master = drm_master_get(file_priv->master); |
701 | ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile); | 711 | ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile); |
712 | vmw_kms_idle_workqueues(vmaster); | ||
702 | 713 | ||
703 | if (unlikely((ret != 0))) { | 714 | if (unlikely((ret != 0))) { |
704 | DRM_ERROR("Unable to lock TTM at VT switch.\n"); | 715 | DRM_ERROR("Unable to lock TTM at VT switch.\n"); |
@@ -751,15 +762,16 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, | |||
751 | * Buffer contents is moved to swappable memory. | 762 | * Buffer contents is moved to swappable memory. |
752 | */ | 763 | */ |
753 | ttm_bo_swapout_all(&dev_priv->bdev); | 764 | ttm_bo_swapout_all(&dev_priv->bdev); |
765 | |||
754 | break; | 766 | break; |
755 | case PM_POST_HIBERNATION: | 767 | case PM_POST_HIBERNATION: |
756 | case PM_POST_SUSPEND: | 768 | case PM_POST_SUSPEND: |
769 | case PM_POST_RESTORE: | ||
757 | ttm_suspend_unlock(&vmaster->lock); | 770 | ttm_suspend_unlock(&vmaster->lock); |
771 | |||
758 | break; | 772 | break; |
759 | case PM_RESTORE_PREPARE: | 773 | case PM_RESTORE_PREPARE: |
760 | break; | 774 | break; |
761 | case PM_POST_RESTORE: | ||
762 | break; | ||
763 | default: | 775 | default: |
764 | break; | 776 | break; |
765 | } | 777 | } |
@@ -770,21 +782,98 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, | |||
770 | * These might not be needed with the virtual SVGA device. | 782 | * These might not be needed with the virtual SVGA device. |
771 | */ | 783 | */ |
772 | 784 | ||
773 | int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 785 | static int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
774 | { | 786 | { |
787 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
788 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
789 | |||
790 | if (dev_priv->num_3d_resources != 0) { | ||
791 | DRM_INFO("Can't suspend or hibernate " | ||
792 | "while 3D resources are active.\n"); | ||
793 | return -EBUSY; | ||
794 | } | ||
795 | |||
775 | pci_save_state(pdev); | 796 | pci_save_state(pdev); |
776 | pci_disable_device(pdev); | 797 | pci_disable_device(pdev); |
777 | pci_set_power_state(pdev, PCI_D3hot); | 798 | pci_set_power_state(pdev, PCI_D3hot); |
778 | return 0; | 799 | return 0; |
779 | } | 800 | } |
780 | 801 | ||
781 | int vmw_pci_resume(struct pci_dev *pdev) | 802 | static int vmw_pci_resume(struct pci_dev *pdev) |
782 | { | 803 | { |
783 | pci_set_power_state(pdev, PCI_D0); | 804 | pci_set_power_state(pdev, PCI_D0); |
784 | pci_restore_state(pdev); | 805 | pci_restore_state(pdev); |
785 | return pci_enable_device(pdev); | 806 | return pci_enable_device(pdev); |
786 | } | 807 | } |
787 | 808 | ||
809 | static int vmw_pm_suspend(struct device *kdev) | ||
810 | { | ||
811 | struct pci_dev *pdev = to_pci_dev(kdev); | ||
812 | struct pm_message dummy; | ||
813 | |||
814 | dummy.event = 0; | ||
815 | |||
816 | return vmw_pci_suspend(pdev, dummy); | ||
817 | } | ||
818 | |||
819 | static int vmw_pm_resume(struct device *kdev) | ||
820 | { | ||
821 | struct pci_dev *pdev = to_pci_dev(kdev); | ||
822 | |||
823 | return vmw_pci_resume(pdev); | ||
824 | } | ||
825 | |||
826 | static int vmw_pm_prepare(struct device *kdev) | ||
827 | { | ||
828 | struct pci_dev *pdev = to_pci_dev(kdev); | ||
829 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
830 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
831 | |||
832 | /** | ||
833 | * Release 3d reference held by fbdev and potentially | ||
834 | * stop fifo. | ||
835 | */ | ||
836 | dev_priv->suspended = true; | ||
837 | if (dev_priv->enable_fb) | ||
838 | vmw_3d_resource_dec(dev_priv); | ||
839 | |||
840 | if (dev_priv->num_3d_resources != 0) { | ||
841 | |||
842 | DRM_INFO("Can't suspend or hibernate " | ||
843 | "while 3D resources are active.\n"); | ||
844 | |||
845 | if (dev_priv->enable_fb) | ||
846 | vmw_3d_resource_inc(dev_priv); | ||
847 | dev_priv->suspended = false; | ||
848 | return -EBUSY; | ||
849 | } | ||
850 | |||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static void vmw_pm_complete(struct device *kdev) | ||
855 | { | ||
856 | struct pci_dev *pdev = to_pci_dev(kdev); | ||
857 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
858 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
859 | |||
860 | /** | ||
861 | * Reclaim 3d reference held by fbdev and potentially | ||
862 | * start fifo. | ||
863 | */ | ||
864 | if (dev_priv->enable_fb) | ||
865 | vmw_3d_resource_inc(dev_priv); | ||
866 | |||
867 | dev_priv->suspended = false; | ||
868 | } | ||
869 | |||
870 | static const struct dev_pm_ops vmw_pm_ops = { | ||
871 | .prepare = vmw_pm_prepare, | ||
872 | .complete = vmw_pm_complete, | ||
873 | .suspend = vmw_pm_suspend, | ||
874 | .resume = vmw_pm_resume, | ||
875 | }; | ||
876 | |||
788 | static struct drm_driver driver = { | 877 | static struct drm_driver driver = { |
789 | .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | | 878 | .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | |
790 | DRIVER_MODESET, | 879 | DRIVER_MODESET, |
@@ -798,8 +887,6 @@ static struct drm_driver driver = { | |||
798 | .irq_handler = vmw_irq_handler, | 887 | .irq_handler = vmw_irq_handler, |
799 | .get_vblank_counter = vmw_get_vblank_counter, | 888 | .get_vblank_counter = vmw_get_vblank_counter, |
800 | .reclaim_buffers_locked = NULL, | 889 | .reclaim_buffers_locked = NULL, |
801 | .get_map_ofs = drm_core_get_map_ofs, | ||
802 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
803 | .ioctls = vmw_ioctls, | 890 | .ioctls = vmw_ioctls, |
804 | .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls), | 891 | .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls), |
805 | .dma_quiescent = NULL, /*vmw_dma_quiescent, */ | 892 | .dma_quiescent = NULL, /*vmw_dma_quiescent, */ |
@@ -820,15 +907,8 @@ static struct drm_driver driver = { | |||
820 | #if defined(CONFIG_COMPAT) | 907 | #if defined(CONFIG_COMPAT) |
821 | .compat_ioctl = drm_compat_ioctl, | 908 | .compat_ioctl = drm_compat_ioctl, |
822 | #endif | 909 | #endif |
823 | }, | 910 | .llseek = noop_llseek, |
824 | .pci_driver = { | 911 | }, |
825 | .name = VMWGFX_DRIVER_NAME, | ||
826 | .id_table = vmw_pci_id_list, | ||
827 | .probe = vmw_probe, | ||
828 | .remove = vmw_remove, | ||
829 | .suspend = vmw_pci_suspend, | ||
830 | .resume = vmw_pci_resume | ||
831 | }, | ||
832 | .name = VMWGFX_DRIVER_NAME, | 912 | .name = VMWGFX_DRIVER_NAME, |
833 | .desc = VMWGFX_DRIVER_DESC, | 913 | .desc = VMWGFX_DRIVER_DESC, |
834 | .date = VMWGFX_DRIVER_DATE, | 914 | .date = VMWGFX_DRIVER_DATE, |
@@ -837,6 +917,16 @@ static struct drm_driver driver = { | |||
837 | .patchlevel = VMWGFX_DRIVER_PATCHLEVEL | 917 | .patchlevel = VMWGFX_DRIVER_PATCHLEVEL |
838 | }; | 918 | }; |
839 | 919 | ||
920 | static struct pci_driver vmw_pci_driver = { | ||
921 | .name = VMWGFX_DRIVER_NAME, | ||
922 | .id_table = vmw_pci_id_list, | ||
923 | .probe = vmw_probe, | ||
924 | .remove = vmw_remove, | ||
925 | .driver = { | ||
926 | .pm = &vmw_pm_ops | ||
927 | } | ||
928 | }; | ||
929 | |||
840 | static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 930 | static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
841 | { | 931 | { |
842 | return drm_get_pci_dev(pdev, ent, &driver); | 932 | return drm_get_pci_dev(pdev, ent, &driver); |
@@ -845,7 +935,7 @@ static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
845 | static int __init vmwgfx_init(void) | 935 | static int __init vmwgfx_init(void) |
846 | { | 936 | { |
847 | int ret; | 937 | int ret; |
848 | ret = drm_init(&driver); | 938 | ret = drm_pci_init(&driver, &vmw_pci_driver); |
849 | if (ret) | 939 | if (ret) |
850 | DRM_ERROR("Failed initializing DRM.\n"); | 940 | DRM_ERROR("Failed initializing DRM.\n"); |
851 | return ret; | 941 | return ret; |
@@ -853,7 +943,7 @@ static int __init vmwgfx_init(void) | |||
853 | 943 | ||
854 | static void __exit vmwgfx_exit(void) | 944 | static void __exit vmwgfx_exit(void) |
855 | { | 945 | { |
856 | drm_exit(&driver); | 946 | drm_pci_exit(&driver, &vmw_pci_driver); |
857 | } | 947 | } |
858 | 948 | ||
859 | module_init(vmwgfx_init); | 949 | module_init(vmwgfx_init); |
@@ -862,3 +952,7 @@ module_exit(vmwgfx_exit); | |||
862 | MODULE_AUTHOR("VMware Inc. and others"); | 952 | MODULE_AUTHOR("VMware Inc. and others"); |
863 | MODULE_DESCRIPTION("Standalone drm driver for the VMware SVGA device"); | 953 | MODULE_DESCRIPTION("Standalone drm driver for the VMware SVGA device"); |
864 | MODULE_LICENSE("GPL and additional rights"); | 954 | MODULE_LICENSE("GPL and additional rights"); |
955 | MODULE_VERSION(__stringify(VMWGFX_DRIVER_MAJOR) "." | ||
956 | __stringify(VMWGFX_DRIVER_MINOR) "." | ||
957 | __stringify(VMWGFX_DRIVER_PATCHLEVEL) "." | ||
958 | "0"); | ||