drm/i915: remove do_retire from i915_wait_request
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_ringbuffer.c
index ac05c749104a81739e50cd2ad2b22a65c3de3d07..a7d97d17b285a0774ac3a586e35b909251cc6602 100644 (file)
@@ -53,9 +53,35 @@ static inline int ring_space(struct intel_ring_buffer *ring)
 }
 
 static int
-render_ring_flush(struct intel_ring_buffer *ring,
-                 u32   invalidate_domains,
-                 u32   flush_domains)
+gen2_render_ring_flush(struct intel_ring_buffer *ring,
+                      u32      invalidate_domains,
+                      u32      flush_domains)
+{
+       u32 cmd;
+       int ret;
+
+       cmd = MI_FLUSH;
+       if (((invalidate_domains|flush_domains) & I915_GEM_DOMAIN_RENDER) == 0)
+               cmd |= MI_NO_WRITE_FLUSH;
+
+       if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
+               cmd |= MI_READ_FLUSH;
+
+       ret = intel_ring_begin(ring, 2);
+       if (ret)
+               return ret;
+
+       intel_ring_emit(ring, cmd);
+       intel_ring_emit(ring, MI_NOOP);
+       intel_ring_advance(ring);
+
+       return 0;
+}
+
+static int
+gen4_render_ring_flush(struct intel_ring_buffer *ring,
+                      u32      invalidate_domains,
+                      u32      flush_domains)
 {
        struct drm_device *dev = ring->dev;
        u32 cmd;
@@ -90,17 +116,8 @@ render_ring_flush(struct intel_ring_buffer *ring,
         */
 
        cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
-       if ((invalidate_domains|flush_domains) &
-           I915_GEM_DOMAIN_RENDER)
+       if ((invalidate_domains|flush_domains) & I915_GEM_DOMAIN_RENDER)
                cmd &= ~MI_NO_WRITE_FLUSH;
-       if (INTEL_INFO(dev)->gen < 4) {
-               /*
-                * On the 965, the sampler cache always gets flushed
-                * and this bit is reserved.
-                */
-               if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
-                       cmd |= MI_READ_FLUSH;
-       }
        if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
                cmd |= MI_EXE_FLUSH;
 
@@ -384,12 +401,11 @@ static int init_render_ring(struct intel_ring_buffer *ring)
        int ret = init_ring_common(ring);
 
        if (INTEL_INFO(dev)->gen > 3) {
-               int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH;
-               I915_WRITE(MI_MODE, mode);
+               I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH));
                if (IS_GEN7(dev))
                        I915_WRITE(GFX_MODE_GEN7,
-                                  GFX_MODE_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) |
-                                  GFX_MODE_ENABLE(GFX_REPLAY_MODE));
+                                  _MASKED_BIT_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) |
+                                  _MASKED_BIT_ENABLE(GFX_REPLAY_MODE));
        }
 
        if (INTEL_INFO(dev)->gen >= 5) {
@@ -398,10 +414,8 @@ static int init_render_ring(struct intel_ring_buffer *ring)
                        return ret;
        }
 
-       if (INTEL_INFO(dev)->gen >= 6) {
-               I915_WRITE(INSTPM,
-                          INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING);
-       }
+       if (INTEL_INFO(dev)->gen >= 6)
+               I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
 
        return ret;
 }
@@ -591,94 +605,115 @@ pc_render_get_seqno(struct intel_ring_buffer *ring)
        return pc->cpu_page[0];
 }
 
-static void
-ironlake_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
+static bool
+gen5_ring_get_irq(struct intel_ring_buffer *ring)
 {
-       dev_priv->gt_irq_mask &= ~mask;
-       I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
-       POSTING_READ(GTIMR);
-}
+       struct drm_device *dev = ring->dev;
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       unsigned long flags;
 
-static void
-ironlake_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
-{
-       dev_priv->gt_irq_mask |= mask;
-       I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
-       POSTING_READ(GTIMR);
-}
+       if (!dev->irq_enabled)
+               return false;
 
-static void
-i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
-{
-       dev_priv->irq_mask &= ~mask;
-       I915_WRITE(IMR, dev_priv->irq_mask);
-       POSTING_READ(IMR);
+       spin_lock_irqsave(&dev_priv->irq_lock, flags);
+       if (ring->irq_refcount++ == 0) {
+               dev_priv->gt_irq_mask &= ~ring->irq_enable_mask;
+               I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
+               POSTING_READ(GTIMR);
+       }
+       spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+
+       return true;
 }
 
 static void
-i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
+gen5_ring_put_irq(struct intel_ring_buffer *ring)
 {
-       dev_priv->irq_mask |= mask;
-       I915_WRITE(IMR, dev_priv->irq_mask);
-       POSTING_READ(IMR);
+       struct drm_device *dev = ring->dev;
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev_priv->irq_lock, flags);
+       if (--ring->irq_refcount == 0) {
+               dev_priv->gt_irq_mask |= ring->irq_enable_mask;
+               I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
+               POSTING_READ(GTIMR);
+       }
+       spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
 }
 
 static bool
-gen5_ring_get_irq(struct intel_ring_buffer *ring)
+i9xx_ring_get_irq(struct intel_ring_buffer *ring)
 {
        struct drm_device *dev = ring->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
+       unsigned long flags;
 
        if (!dev->irq_enabled)
                return false;
 
-       spin_lock(&ring->irq_lock);
-       if (ring->irq_refcount++ == 0)
-               ironlake_enable_irq(dev_priv, ring->irq_enable_mask);
-       spin_unlock(&ring->irq_lock);
+       spin_lock_irqsave(&dev_priv->irq_lock, flags);
+       if (ring->irq_refcount++ == 0) {
+               dev_priv->irq_mask &= ~ring->irq_enable_mask;
+               I915_WRITE(IMR, dev_priv->irq_mask);
+               POSTING_READ(IMR);
+       }
+       spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
 
        return true;
 }
 
 static void
-gen5_ring_put_irq(struct intel_ring_buffer *ring)
+i9xx_ring_put_irq(struct intel_ring_buffer *ring)
 {
        struct drm_device *dev = ring->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
+       unsigned long flags;
 
-       spin_lock(&ring->irq_lock);
-       if (--ring->irq_refcount == 0)
-               ironlake_disable_irq(dev_priv, ring->irq_enable_mask);
-       spin_unlock(&ring->irq_lock);
+       spin_lock_irqsave(&dev_priv->irq_lock, flags);
+       if (--ring->irq_refcount == 0) {
+               dev_priv->irq_mask |= ring->irq_enable_mask;
+               I915_WRITE(IMR, dev_priv->irq_mask);
+               POSTING_READ(IMR);
+       }
+       spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
 }
 
 static bool
-i9xx_ring_get_irq(struct intel_ring_buffer *ring)
+i8xx_ring_get_irq(struct intel_ring_buffer *ring)
 {
        struct drm_device *dev = ring->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
+       unsigned long flags;
 
        if (!dev->irq_enabled)
                return false;
 
-       spin_lock(&ring->irq_lock);
-       if (ring->irq_refcount++ == 0)
-               i915_enable_irq(dev_priv, ring->irq_enable_mask);
-       spin_unlock(&ring->irq_lock);
+       spin_lock_irqsave(&dev_priv->irq_lock, flags);
+       if (ring->irq_refcount++ == 0) {
+               dev_priv->irq_mask &= ~ring->irq_enable_mask;
+               I915_WRITE16(IMR, dev_priv->irq_mask);
+               POSTING_READ16(IMR);
+       }
+       spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
 
        return true;
 }
 
 static void
-i9xx_ring_put_irq(struct intel_ring_buffer *ring)
+i8xx_ring_put_irq(struct intel_ring_buffer *ring)
 {
        struct drm_device *dev = ring->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
+       unsigned long flags;
 
-       spin_lock(&ring->irq_lock);
-       if (--ring->irq_refcount == 0)
-               i915_disable_irq(dev_priv, ring->irq_enable_mask);
-       spin_unlock(&ring->irq_lock);
+       spin_lock_irqsave(&dev_priv->irq_lock, flags);
+       if (--ring->irq_refcount == 0) {
+               dev_priv->irq_mask |= ring->irq_enable_mask;
+               I915_WRITE16(IMR, dev_priv->irq_mask);
+               POSTING_READ16(IMR);
+       }
+       spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
 }
 
 void intel_ring_setup_status_page(struct intel_ring_buffer *ring)
@@ -757,6 +792,7 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring)
 {
        struct drm_device *dev = ring->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
+       unsigned long flags;
 
        if (!dev->irq_enabled)
               return false;
@@ -766,12 +802,14 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring)
         * blt/bsd rings on ivb. */
        gen6_gt_force_wake_get(dev_priv);
 
-       spin_lock(&ring->irq_lock);
+       spin_lock_irqsave(&dev_priv->irq_lock, flags);
        if (ring->irq_refcount++ == 0) {
                I915_WRITE_IMR(ring, ~ring->irq_enable_mask);
-               ironlake_enable_irq(dev_priv, ring->irq_enable_mask);
+               dev_priv->gt_irq_mask &= ~ring->irq_enable_mask;
+               I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
+               POSTING_READ(GTIMR);
        }
-       spin_unlock(&ring->irq_lock);
+       spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
 
        return true;
 }
@@ -781,13 +819,16 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring)
 {
        struct drm_device *dev = ring->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
+       unsigned long flags;
 
-       spin_lock(&ring->irq_lock);
+       spin_lock_irqsave(&dev_priv->irq_lock, flags);
        if (--ring->irq_refcount == 0) {
                I915_WRITE_IMR(ring, ~0);
-               ironlake_disable_irq(dev_priv, ring->irq_enable_mask);
+               dev_priv->gt_irq_mask |= ring->irq_enable_mask;
+               I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
+               POSTING_READ(GTIMR);
        }
-       spin_unlock(&ring->irq_lock);
+       spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
 
        gen6_gt_force_wake_put(dev_priv);
 }
@@ -802,7 +843,8 @@ i965_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length)
                return ret;
 
        intel_ring_emit(ring,
-                       MI_BATCH_BUFFER_START | (2 << 6) |
+                       MI_BATCH_BUFFER_START |
+                       MI_BATCH_GTT |
                        MI_BATCH_NON_SECURE_I965);
        intel_ring_emit(ring, offset);
        intel_ring_advance(ring);
@@ -839,7 +881,7 @@ i915_dispatch_execbuffer(struct intel_ring_buffer *ring,
        if (ret)
                return ret;
 
-       intel_ring_emit(ring, MI_BATCH_BUFFER_START | (2 << 6));
+       intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_GTT);
        intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE);
        intel_ring_advance(ring);
 
@@ -907,8 +949,8 @@ err:
        return ret;
 }
 
-int intel_init_ring_buffer(struct drm_device *dev,
-                          struct intel_ring_buffer *ring)
+static int intel_init_ring_buffer(struct drm_device *dev,
+                                 struct intel_ring_buffer *ring)
 {
        struct drm_i915_gem_object *obj;
        int ret;
@@ -920,7 +962,6 @@ int intel_init_ring_buffer(struct drm_device *dev,
        ring->size = 32 * PAGE_SIZE;
 
        init_waitqueue_head(&ring->irq_queue);
-       spin_lock_init(&ring->irq_lock);
 
        if (I915_NEED_GFX_HWS(dev)) {
                ret = init_status_page(ring);
@@ -964,7 +1005,7 @@ int intel_init_ring_buffer(struct drm_device *dev,
         * of the buffer.
         */
        ring->effective_size = ring->size;
-       if (IS_I830(ring->dev))
+       if (IS_I830(ring->dev) || IS_845G(ring->dev))
                ring->effective_size -= 128;
 
        return 0;
@@ -1047,9 +1088,11 @@ static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno)
        was_interruptible = dev_priv->mm.interruptible;
        dev_priv->mm.interruptible = false;
 
-       ret = i915_wait_request(ring, seqno, true);
+       ret = i915_wait_request(ring, seqno);
 
        dev_priv->mm.interruptible = was_interruptible;
+       if (!ret)
+               i915_gem_retire_requests_ring(ring);
 
        return ret;
 }
@@ -1123,15 +1166,12 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
                return ret;
 
        trace_i915_ring_wait_begin(ring);
-       if (drm_core_check_feature(dev, DRIVER_GEM))
-               /* With GEM the hangcheck timer should kick us out of the loop,
-                * leaving it early runs the risk of corrupting GEM state (due
-                * to running on almost untested codepaths). But on resume
-                * timers don't work yet, so prevent a complete hang in that
-                * case by choosing an insanely large timeout. */
-               end = jiffies + 60 * HZ;
-       else
-               end = jiffies + 3 * HZ;
+       /* With GEM the hangcheck timer should kick us out of the loop,
+        * leaving it early runs the risk of corrupting GEM state (due
+        * to running on almost untested codepaths). But on resume
+        * timers don't work yet, so prevent a complete hang in that
+        * case by choosing an insanely large timeout. */
+       end = jiffies + 60 * HZ;
 
        do {
                ring->head = I915_READ_HEAD(ring);
@@ -1296,17 +1336,25 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
                ring->signal_mbox[1] = GEN6_BRSYNC;
        } else if (IS_GEN5(dev)) {
                ring->add_request = pc_render_add_request;
-               ring->flush = render_ring_flush;
+               ring->flush = gen4_render_ring_flush;
                ring->get_seqno = pc_render_get_seqno;
                ring->irq_get = gen5_ring_get_irq;
                ring->irq_put = gen5_ring_put_irq;
                ring->irq_enable_mask = GT_USER_INTERRUPT | GT_PIPE_NOTIFY;
        } else {
                ring->add_request = i9xx_add_request;
-               ring->flush = render_ring_flush;
+               if (INTEL_INFO(dev)->gen < 4)
+                       ring->flush = gen2_render_ring_flush;
+               else
+                       ring->flush = gen4_render_ring_flush;
                ring->get_seqno = ring_get_seqno;
-               ring->irq_get = i9xx_ring_get_irq;
-               ring->irq_put = i9xx_ring_put_irq;
+               if (IS_GEN2(dev)) {
+                       ring->irq_get = i8xx_ring_get_irq;
+                       ring->irq_put = i8xx_ring_put_irq;
+               } else {
+                       ring->irq_get = i9xx_ring_get_irq;
+                       ring->irq_put = i9xx_ring_put_irq;
+               }
                ring->irq_enable_mask = I915_USER_INTERRUPT;
        }
        ring->write_tail = ring_write_tail;
@@ -1342,21 +1390,25 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size)
        if (INTEL_INFO(dev)->gen >= 6) {
                /* non-kms not supported on gen6+ */
                return -ENODEV;
-       } else if (IS_GEN5(dev)) {
-               ring->add_request = pc_render_add_request;
-               ring->flush = render_ring_flush;
-               ring->get_seqno = pc_render_get_seqno;
-               ring->irq_get = gen5_ring_get_irq;
-               ring->irq_put = gen5_ring_put_irq;
-               ring->irq_enable_mask = GT_USER_INTERRUPT | GT_PIPE_NOTIFY;
+       }
+
+       /* Note: gem is not supported on gen5/ilk without kms (the corresponding
+        * gem_init ioctl returns with -ENODEV). Hence we do not need to set up
+        * the special gen5 functions. */
+       ring->add_request = i9xx_add_request;
+       if (INTEL_INFO(dev)->gen < 4)
+               ring->flush = gen2_render_ring_flush;
+       else
+               ring->flush = gen4_render_ring_flush;
+       ring->get_seqno = ring_get_seqno;
+       if (IS_GEN2(dev)) {
+               ring->irq_get = i8xx_ring_get_irq;
+               ring->irq_put = i8xx_ring_put_irq;
        } else {
-               ring->add_request = i9xx_add_request;
-               ring->flush = render_ring_flush;
-               ring->get_seqno = ring_get_seqno;
                ring->irq_get = i9xx_ring_get_irq;
                ring->irq_put = i9xx_ring_put_irq;
-               ring->irq_enable_mask = I915_USER_INTERRUPT;
        }
+       ring->irq_enable_mask = I915_USER_INTERRUPT;
        ring->write_tail = ring_write_tail;
        if (INTEL_INFO(dev)->gen >= 4)
                ring->dispatch_execbuffer = i965_dispatch_execbuffer;
This page took 0.033212 seconds and 5 git commands to generate.