diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_drv.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b3a2f1629041..86537692e45c 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
@@ -187,6 +187,7 @@ static int msm_load(struct drm_device *dev, unsigned long flags) | |||
187 | init_waitqueue_head(&priv->fence_event); | 187 | init_waitqueue_head(&priv->fence_event); |
188 | 188 | ||
189 | INIT_LIST_HEAD(&priv->inactive_list); | 189 | INIT_LIST_HEAD(&priv->inactive_list); |
190 | INIT_LIST_HEAD(&priv->fence_cbs); | ||
190 | 191 | ||
191 | drm_mode_config_init(dev); | 192 | drm_mode_config_init(dev); |
192 | 193 | ||
@@ -539,15 +540,36 @@ int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence, | |||
539 | return ret; | 540 | return ret; |
540 | } | 541 | } |
541 | 542 | ||
542 | /* call under struct_mutex */ | 543 | /* called from workqueue */ |
543 | void msm_update_fence(struct drm_device *dev, uint32_t fence) | 544 | void msm_update_fence(struct drm_device *dev, uint32_t fence) |
544 | { | 545 | { |
545 | struct msm_drm_private *priv = dev->dev_private; | 546 | struct msm_drm_private *priv = dev->dev_private; |
546 | 547 | ||
547 | if (fence > priv->completed_fence) { | 548 | mutex_lock(&dev->struct_mutex); |
548 | priv->completed_fence = fence; | 549 | priv->completed_fence = max(fence, priv->completed_fence); |
549 | wake_up_all(&priv->fence_event); | 550 | |
551 | while (!list_empty(&priv->fence_cbs)) { | ||
552 | struct msm_fence_cb *cb; | ||
553 | |||
554 | cb = list_first_entry(&priv->fence_cbs, | ||
555 | struct msm_fence_cb, work.entry); | ||
556 | |||
557 | if (cb->fence > priv->completed_fence) | ||
558 | break; | ||
559 | |||
560 | list_del_init(&cb->work.entry); | ||
561 | queue_work(priv->wq, &cb->work); | ||
550 | } | 562 | } |
563 | |||
564 | mutex_unlock(&dev->struct_mutex); | ||
565 | |||
566 | wake_up_all(&priv->fence_event); | ||
567 | } | ||
568 | |||
569 | void __msm_fence_worker(struct work_struct *work) | ||
570 | { | ||
571 | struct msm_fence_cb *cb = container_of(work, struct msm_fence_cb, work); | ||
572 | cb->func(cb); | ||
551 | } | 573 | } |
552 | 574 | ||
553 | /* | 575 | /* |
@@ -650,13 +672,13 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, | |||
650 | } | 672 | } |
651 | 673 | ||
652 | static const struct drm_ioctl_desc msm_ioctls[] = { | 674 | static const struct drm_ioctl_desc msm_ioctls[] = { |
653 | DRM_IOCTL_DEF_DRV(MSM_GET_PARAM, msm_ioctl_get_param, DRM_UNLOCKED|DRM_AUTH), | 675 | DRM_IOCTL_DEF_DRV(MSM_GET_PARAM, msm_ioctl_get_param, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), |
654 | DRM_IOCTL_DEF_DRV(MSM_GEM_NEW, msm_ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH), | 676 | DRM_IOCTL_DEF_DRV(MSM_GEM_NEW, msm_ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), |
655 | DRM_IOCTL_DEF_DRV(MSM_GEM_INFO, msm_ioctl_gem_info, DRM_UNLOCKED|DRM_AUTH), | 677 | DRM_IOCTL_DEF_DRV(MSM_GEM_INFO, msm_ioctl_gem_info, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), |
656 | DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_UNLOCKED|DRM_AUTH), | 678 | DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), |
657 | DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_FINI, msm_ioctl_gem_cpu_fini, DRM_UNLOCKED|DRM_AUTH), | 679 | DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_FINI, msm_ioctl_gem_cpu_fini, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), |
658 | DRM_IOCTL_DEF_DRV(MSM_GEM_SUBMIT, msm_ioctl_gem_submit, DRM_UNLOCKED|DRM_AUTH), | 680 | DRM_IOCTL_DEF_DRV(MSM_GEM_SUBMIT, msm_ioctl_gem_submit, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), |
659 | DRM_IOCTL_DEF_DRV(MSM_WAIT_FENCE, msm_ioctl_wait_fence, DRM_UNLOCKED|DRM_AUTH), | 681 | DRM_IOCTL_DEF_DRV(MSM_WAIT_FENCE, msm_ioctl_wait_fence, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), |
660 | }; | 682 | }; |
661 | 683 | ||
662 | static const struct vm_operations_struct vm_ops = { | 684 | static const struct vm_operations_struct vm_ops = { |
@@ -680,7 +702,11 @@ static const struct file_operations fops = { | |||
680 | }; | 702 | }; |
681 | 703 | ||
682 | static struct drm_driver msm_driver = { | 704 | static struct drm_driver msm_driver = { |
683 | .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET, | 705 | .driver_features = DRIVER_HAVE_IRQ | |
706 | DRIVER_GEM | | ||
707 | DRIVER_PRIME | | ||
708 | DRIVER_RENDER | | ||
709 | DRIVER_MODESET, | ||
684 | .load = msm_load, | 710 | .load = msm_load, |
685 | .unload = msm_unload, | 711 | .unload = msm_unload, |
686 | .open = msm_open, | 712 | .open = msm_open, |
@@ -698,6 +724,16 @@ static struct drm_driver msm_driver = { | |||
698 | .dumb_create = msm_gem_dumb_create, | 724 | .dumb_create = msm_gem_dumb_create, |
699 | .dumb_map_offset = msm_gem_dumb_map_offset, | 725 | .dumb_map_offset = msm_gem_dumb_map_offset, |
700 | .dumb_destroy = drm_gem_dumb_destroy, | 726 | .dumb_destroy = drm_gem_dumb_destroy, |
727 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, | ||
728 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, | ||
729 | .gem_prime_export = drm_gem_prime_export, | ||
730 | .gem_prime_import = drm_gem_prime_import, | ||
731 | .gem_prime_pin = msm_gem_prime_pin, | ||
732 | .gem_prime_unpin = msm_gem_prime_unpin, | ||
733 | .gem_prime_get_sg_table = msm_gem_prime_get_sg_table, | ||
734 | .gem_prime_import_sg_table = msm_gem_prime_import_sg_table, | ||
735 | .gem_prime_vmap = msm_gem_prime_vmap, | ||
736 | .gem_prime_vunmap = msm_gem_prime_vunmap, | ||
701 | #ifdef CONFIG_DEBUG_FS | 737 | #ifdef CONFIG_DEBUG_FS |
702 | .debugfs_init = msm_debugfs_init, | 738 | .debugfs_init = msm_debugfs_init, |
703 | .debugfs_cleanup = msm_debugfs_cleanup, | 739 | .debugfs_cleanup = msm_debugfs_cleanup, |