diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-04-26 17:28:08 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-05-03 05:18:27 -0400 |
commit | 9488867a67fda2310448e44a906f1a54faa72fb4 (patch) | |
tree | 83e322bf1a81fafd1ab180fa5593aa84da66d3b7 /drivers/gpu/drm/i915/i915_dma.c | |
parent | 647a3fb2f31298ad9d062cbb8019b5dc26e4ca69 (diff) |
drm/i915: move dri1 irq ioctl code to i915_dma.c
Let's just get this out of the way.
v2: Rebase against ENODEV changes.
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 4f1a9e864e03..6f6c4bda689c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -721,6 +721,116 @@ fail_batch_free: | |||
721 | return ret; | 721 | return ret; |
722 | } | 722 | } |
723 | 723 | ||
724 | static int i915_emit_irq(struct drm_device * dev) | ||
725 | { | ||
726 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
727 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | ||
728 | |||
729 | i915_kernel_lost_context(dev); | ||
730 | |||
731 | DRM_DEBUG_DRIVER("\n"); | ||
732 | |||
733 | dev_priv->counter++; | ||
734 | if (dev_priv->counter > 0x7FFFFFFFUL) | ||
735 | dev_priv->counter = 1; | ||
736 | if (master_priv->sarea_priv) | ||
737 | master_priv->sarea_priv->last_enqueue = dev_priv->counter; | ||
738 | |||
739 | if (BEGIN_LP_RING(4) == 0) { | ||
740 | OUT_RING(MI_STORE_DWORD_INDEX); | ||
741 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
742 | OUT_RING(dev_priv->counter); | ||
743 | OUT_RING(MI_USER_INTERRUPT); | ||
744 | ADVANCE_LP_RING(); | ||
745 | } | ||
746 | |||
747 | return dev_priv->counter; | ||
748 | } | ||
749 | |||
750 | static int i915_wait_irq(struct drm_device * dev, int irq_nr) | ||
751 | { | ||
752 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
753 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | ||
754 | int ret = 0; | ||
755 | struct intel_ring_buffer *ring = LP_RING(dev_priv); | ||
756 | |||
757 | DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr, | ||
758 | READ_BREADCRUMB(dev_priv)); | ||
759 | |||
760 | if (READ_BREADCRUMB(dev_priv) >= irq_nr) { | ||
761 | if (master_priv->sarea_priv) | ||
762 | master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | ||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | if (master_priv->sarea_priv) | ||
767 | master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | ||
768 | |||
769 | if (ring->irq_get(ring)) { | ||
770 | DRM_WAIT_ON(ret, ring->irq_queue, 3 * DRM_HZ, | ||
771 | READ_BREADCRUMB(dev_priv) >= irq_nr); | ||
772 | ring->irq_put(ring); | ||
773 | } else if (wait_for(READ_BREADCRUMB(dev_priv) >= irq_nr, 3000)) | ||
774 | ret = -EBUSY; | ||
775 | |||
776 | if (ret == -EBUSY) { | ||
777 | DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", | ||
778 | READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); | ||
779 | } | ||
780 | |||
781 | return ret; | ||
782 | } | ||
783 | |||
784 | /* Needs the lock as it touches the ring. | ||
785 | */ | ||
786 | static int i915_irq_emit(struct drm_device *dev, void *data, | ||
787 | struct drm_file *file_priv) | ||
788 | { | ||
789 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
790 | drm_i915_irq_emit_t *emit = data; | ||
791 | int result; | ||
792 | |||
793 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
794 | return -ENODEV; | ||
795 | |||
796 | if (!dev_priv || !LP_RING(dev_priv)->virtual_start) { | ||
797 | DRM_ERROR("called with no initialization\n"); | ||
798 | return -EINVAL; | ||
799 | } | ||
800 | |||
801 | RING_LOCK_TEST_WITH_RETURN(dev, file_priv); | ||
802 | |||
803 | mutex_lock(&dev->struct_mutex); | ||
804 | result = i915_emit_irq(dev); | ||
805 | mutex_unlock(&dev->struct_mutex); | ||
806 | |||
807 | if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { | ||
808 | DRM_ERROR("copy_to_user\n"); | ||
809 | return -EFAULT; | ||
810 | } | ||
811 | |||
812 | return 0; | ||
813 | } | ||
814 | |||
815 | /* Doesn't need the hardware lock. | ||
816 | */ | ||
817 | static int i915_irq_wait(struct drm_device *dev, void *data, | ||
818 | struct drm_file *file_priv) | ||
819 | { | ||
820 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
821 | drm_i915_irq_wait_t *irqwait = data; | ||
822 | |||
823 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
824 | return -ENODEV; | ||
825 | |||
826 | if (!dev_priv) { | ||
827 | DRM_ERROR("called with no initialization\n"); | ||
828 | return -EINVAL; | ||
829 | } | ||
830 | |||
831 | return i915_wait_irq(dev, irqwait->irq_seq); | ||
832 | } | ||
833 | |||
724 | static int i915_vblank_pipe_get(struct drm_device *dev, void *data, | 834 | static int i915_vblank_pipe_get(struct drm_device *dev, void *data, |
725 | struct drm_file *file_priv) | 835 | struct drm_file *file_priv) |
726 | { | 836 | { |