These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / gpu / drm / i915 / i915_gpu_error.c
index 1d4e60d..2f04e4f 100644 (file)
 #include <generated/utsrelease.h>
 #include "i915_drv.h"
 
-static const char *yesno(int v)
-{
-       return v ? "yes" : "no";
-}
-
 static const char *ring_str(int ring)
 {
        switch (ring) {
@@ -192,15 +187,21 @@ static void print_error_buffers(struct drm_i915_error_state_buf *m,
                                struct drm_i915_error_buffer *err,
                                int count)
 {
+       int i;
+
        err_printf(m, "  %s [%d]:\n", name, count);
 
        while (count--) {
-               err_printf(m, "    %08x %8u %02x %02x %x %x",
-                          err->gtt_offset,
+               err_printf(m, "    %08x_%08x %8u %02x %02x [ ",
+                          upper_32_bits(err->gtt_offset),
+                          lower_32_bits(err->gtt_offset),
                           err->size,
                           err->read_domains,
-                          err->write_domain,
-                          err->rseqno, err->wseqno);
+                          err->write_domain);
+               for (i = 0; i < I915_NUM_RINGS; i++)
+                       err_printf(m, "%02x ", err->rseqno[i]);
+
+               err_printf(m, "] %02x", err->wseqno);
                err_puts(m, pin_flag(err->pinned));
                err_puts(m, tiling_flag(err->tiling));
                err_puts(m, dirty_flag(err->dirty));
@@ -251,10 +252,11 @@ static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
                return;
 
        err_printf(m, "%s command stream:\n", ring_str(ring_idx));
-       err_printf(m, "  HEAD: 0x%08x\n", ring->head);
-       err_printf(m, "  TAIL: 0x%08x\n", ring->tail);
-       err_printf(m, "  CTL: 0x%08x\n", ring->ctl);
-       err_printf(m, "  HWS: 0x%08x\n", ring->hws);
+       err_printf(m, "  START: 0x%08x\n", ring->start);
+       err_printf(m, "  HEAD:  0x%08x\n", ring->head);
+       err_printf(m, "  TAIL:  0x%08x\n", ring->tail);
+       err_printf(m, "  CTL:   0x%08x\n", ring->ctl);
+       err_printf(m, "  HWS:   0x%08x\n", ring->hws);
        err_printf(m, "  ACTHD: 0x%08x %08x\n", (u32)(ring->acthd>>32), (u32)ring->acthd);
        err_printf(m, "  IPEIR: 0x%08x\n", ring->ipeir);
        err_printf(m, "  IPEHR: 0x%08x\n", ring->ipehr);
@@ -363,6 +365,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
        err_printf(m, "Reset count: %u\n", error->reset_count);
        err_printf(m, "Suspend count: %u\n", error->suspend_count);
        err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device);
+       err_printf(m, "IOMMU enabled?: %d\n", error->iommu);
        err_printf(m, "EIR: 0x%08x\n", error->eir);
        err_printf(m, "IER: 0x%08x\n", error->ier);
        if (INTEL_INFO(dev)->gen >= 8) {
@@ -420,15 +423,17 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
                                err_printf(m, " (submitted by %s [%d])",
                                           error->ring[i].comm,
                                           error->ring[i].pid);
-                       err_printf(m, " --- gtt_offset = 0x%08x\n",
-                                  obj->gtt_offset);
+                       err_printf(m, " --- gtt_offset = 0x%08x %08x\n",
+                                  upper_32_bits(obj->gtt_offset),
+                                  lower_32_bits(obj->gtt_offset));
                        print_error_obj(m, obj);
                }
 
                obj = error->ring[i].wa_batchbuffer;
                if (obj) {
                        err_printf(m, "%s (w/a) --- gtt_offset = 0x%08x\n",
-                                  dev_priv->ring[i].name, obj->gtt_offset);
+                                  dev_priv->ring[i].name,
+                                  lower_32_bits(obj->gtt_offset));
                        print_error_obj(m, obj);
                }
 
@@ -447,22 +452,28 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
                if ((obj = error->ring[i].ringbuffer)) {
                        err_printf(m, "%s --- ringbuffer = 0x%08x\n",
                                   dev_priv->ring[i].name,
-                                  obj->gtt_offset);
+                                  lower_32_bits(obj->gtt_offset));
                        print_error_obj(m, obj);
                }
 
                if ((obj = error->ring[i].hws_page)) {
-                       err_printf(m, "%s --- HW Status = 0x%08x\n",
-                                  dev_priv->ring[i].name,
-                                  obj->gtt_offset);
+                       u64 hws_offset = obj->gtt_offset;
+                       u32 *hws_page = &obj->pages[0][0];
+
+                       if (i915.enable_execlists) {
+                               hws_offset += LRC_PPHWSP_PN * PAGE_SIZE;
+                               hws_page = &obj->pages[LRC_PPHWSP_PN][0];
+                       }
+                       err_printf(m, "%s --- HW Status = 0x%08llx\n",
+                                  dev_priv->ring[i].name, hws_offset);
                        offset = 0;
                        for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
                                err_printf(m, "[%04x] %08x %08x %08x %08x\n",
                                           offset,
-                                          obj->pages[0][elt],
-                                          obj->pages[0][elt+1],
-                                          obj->pages[0][elt+2],
-                                          obj->pages[0][elt+3]);
+                                          hws_page[elt],
+                                          hws_page[elt+1],
+                                          hws_page[elt+2],
+                                          hws_page[elt+3]);
                                        offset += 16;
                        }
                }
@@ -470,13 +481,14 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
                if ((obj = error->ring[i].ctx)) {
                        err_printf(m, "%s --- HW Context = 0x%08x\n",
                                   dev_priv->ring[i].name,
-                                  obj->gtt_offset);
+                                  lower_32_bits(obj->gtt_offset));
                        print_error_obj(m, obj);
                }
        }
 
        if ((obj = error->semaphore_obj)) {
-               err_printf(m, "Semaphore page = 0x%08x\n", obj->gtt_offset);
+               err_printf(m, "Semaphore page = 0x%08x\n",
+                          lower_32_bits(obj->gtt_offset));
                for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
                        err_printf(m, "[%04x] %08x %08x %08x %08x\n",
                                   elt * 4,
@@ -553,6 +565,7 @@ static void i915_error_state_free(struct kref *error_ref)
 
        for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
                i915_error_object_free(error->ring[i].batchbuffer);
+               i915_error_object_free(error->ring[i].wa_batchbuffer);
                i915_error_object_free(error->ring[i].ringbuffer);
                i915_error_object_free(error->ring[i].hws_page);
                i915_error_object_free(error->ring[i].ctx);
@@ -583,7 +596,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
        int num_pages;
        bool use_ggtt;
        int i = 0;
-       u32 reloc_offset;
+       u64 reloc_offset;
 
        if (src == NULL || src->pages == NULL)
                return NULL;
@@ -679,10 +692,12 @@ static void capture_bo(struct drm_i915_error_buffer *err,
                       struct i915_vma *vma)
 {
        struct drm_i915_gem_object *obj = vma->obj;
+       int i;
 
        err->size = obj->base.size;
        err->name = obj->base.name;
-       err->rseqno = i915_gem_request_get_seqno(obj->last_read_req);
+       for (i = 0; i < I915_NUM_RINGS; i++)
+               err->rseqno[i] = i915_gem_request_get_seqno(obj->last_read_req[i]);
        err->wseqno = i915_gem_request_get_seqno(obj->last_write_req);
        err->gtt_offset = vma->node.start;
        err->read_domains = obj->base.read_domains;
@@ -695,8 +710,8 @@ static void capture_bo(struct drm_i915_error_buffer *err,
        err->dirty = obj->dirty;
        err->purgeable = obj->madv != I915_MADV_WILLNEED;
        err->userptr = obj->userptr.mm != NULL;
-       err->ring = obj->last_read_req ?
-                       i915_gem_request_get_ring(obj->last_read_req)->id : -1;
+       err->ring = obj->last_write_req ?
+                       i915_gem_request_get_ring(obj->last_write_req)->id : -1;
        err->cache_level = obj->cache_level;
 }
 
@@ -777,20 +792,15 @@ static void i915_gem_record_fences(struct drm_device *dev,
        int i;
 
        if (IS_GEN3(dev) || IS_GEN2(dev)) {
-               for (i = 0; i < 8; i++)
-                       error->fence[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
-               if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
-                       for (i = 0; i < 8; i++)
-                               error->fence[i+8] = I915_READ(FENCE_REG_945_8 +
-                                                             (i * 4));
-       } else if (IS_GEN5(dev) || IS_GEN4(dev))
-               for (i = 0; i < 16; i++)
-                       error->fence[i] = I915_READ64(FENCE_REG_965_0 +
-                                                     (i * 8));
-       else if (INTEL_INFO(dev)->gen >= 6)
                for (i = 0; i < dev_priv->num_fence_regs; i++)
-                       error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 +
-                                                     (i * 8));
+                       error->fence[i] = I915_READ(FENCE_REG(i));
+       } else if (IS_GEN5(dev) || IS_GEN4(dev)) {
+               for (i = 0; i < dev_priv->num_fence_regs; i++)
+                       error->fence[i] = I915_READ64(FENCE_REG_965_LO(i));
+       } else if (INTEL_INFO(dev)->gen >= 6) {
+               for (i = 0; i < dev_priv->num_fence_regs; i++)
+                       error->fence[i] = I915_READ64(FENCE_REG_GEN6_LO(i));
+       }
 }
 
 
@@ -876,13 +886,14 @@ static void i915_record_ring_state(struct drm_device *dev,
                ering->faddr = I915_READ(DMA_FADD_I8XX);
                ering->ipeir = I915_READ(IPEIR);
                ering->ipehr = I915_READ(IPEHR);
-               ering->instdone = I915_READ(INSTDONE);
+               ering->instdone = I915_READ(GEN2_INSTDONE);
        }
 
        ering->waiting = waitqueue_active(&ring->irq_queue);
        ering->instpm = I915_READ(RING_INSTPM(ring->mmio_base));
        ering->seqno = ring->get_seqno(ring, false);
        ering->acthd = intel_ring_get_active_head(ring);
+       ering->start = I915_READ_START(ring);
        ering->head = I915_READ_HEAD(ring);
        ering->tail = I915_READ_TAIL(ring);
        ering->ctl = I915_READ_CTL(ring);
@@ -1256,6 +1267,10 @@ static void i915_error_capture_msg(struct drm_device *dev,
 static void i915_capture_gen_state(struct drm_i915_private *dev_priv,
                                   struct drm_i915_error_state *error)
 {
+       error->iommu = -1;
+#ifdef CONFIG_INTEL_IOMMU
+       error->iommu = intel_iommu_gfx_mapped;
+#endif
        error->reset_count = i915_reset_count(&dev_priv->gpu_error);
        error->suspend_count = dev_priv->suspend_count;
 }
@@ -1373,12 +1388,12 @@ void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone)
        memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG);
 
        if (IS_GEN2(dev) || IS_GEN3(dev))
-               instdone[0] = I915_READ(INSTDONE);
+               instdone[0] = I915_READ(GEN2_INSTDONE);
        else if (IS_GEN4(dev) || IS_GEN5(dev) || IS_GEN6(dev)) {
-               instdone[0] = I915_READ(INSTDONE_I965);
-               instdone[1] = I915_READ(INSTDONE1);
+               instdone[0] = I915_READ(RING_INSTDONE(RENDER_RING_BASE));
+               instdone[1] = I915_READ(GEN4_INSTDONE1);
        } else if (INTEL_INFO(dev)->gen >= 7) {
-               instdone[0] = I915_READ(GEN7_INSTDONE_1);
+               instdone[0] = I915_READ(RING_INSTDONE(RENDER_RING_BASE));
                instdone[1] = I915_READ(GEN7_SC_INSTDONE);
                instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE);
                instdone[3] = I915_READ(GEN7_ROW_INSTDONE);