]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/gpu/drm/i915/intel_overlay.c
drm/i915: Capture the overlay status upon a GPU hang.
[net-next-2.6.git] / drivers / gpu / drm / i915 / intel_overlay.c
index d39aea24eabe3b2d0bc9bf42bc6344d6457bd3ec..9ae61aa05a1f29cf265a3f4c9a3f33435540728f 100644 (file)
@@ -1416,3 +1416,99 @@ void intel_cleanup_overlay(struct drm_device *dev)
                kfree(dev_priv->overlay);
        }
 }
+
+struct intel_overlay_error_state {
+       struct overlay_registers regs;
+       unsigned long base;
+       u32 dovsta;
+       u32 isr;
+};
+
+struct intel_overlay_error_state *
+intel_overlay_capture_error_state(struct drm_device *dev)
+{
+        drm_i915_private_t *dev_priv = dev->dev_private;
+       struct intel_overlay *overlay = dev_priv->overlay;
+       struct intel_overlay_error_state *error;
+       struct overlay_registers __iomem *regs;
+
+       if (!overlay || !overlay->active)
+               return NULL;
+
+       error = kmalloc(sizeof(*error), GFP_ATOMIC);
+       if (error == NULL)
+               return NULL;
+
+       error->dovsta = I915_READ(DOVSTA);
+       error->isr = I915_READ(ISR);
+       if (OVERLAY_NONPHYSICAL(overlay->dev))
+               error->base = (long) overlay->reg_bo->gtt_offset;
+       else
+               error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
+
+       regs = intel_overlay_map_regs_atomic(overlay);
+       if (!regs)
+               goto err;
+
+       memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
+       intel_overlay_unmap_regs_atomic(overlay);
+
+       return error;
+
+err:
+       kfree(error);
+       return NULL;
+}
+
+void
+intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
+{
+       seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
+                  error->dovsta, error->isr);
+       seq_printf(m, "  Register file at 0x%08lx:\n",
+                  error->base);
+
+#define P(x) seq_printf(m, "    " #x ":        0x%08x\n", error->regs.x)
+       P(OBUF_0Y);
+       P(OBUF_1Y);
+       P(OBUF_0U);
+       P(OBUF_0V);
+       P(OBUF_1U);
+       P(OBUF_1V);
+       P(OSTRIDE);
+       P(YRGB_VPH);
+       P(UV_VPH);
+       P(HORZ_PH);
+       P(INIT_PHS);
+       P(DWINPOS);
+       P(DWINSZ);
+       P(SWIDTH);
+       P(SWIDTHSW);
+       P(SHEIGHT);
+       P(YRGBSCALE);
+       P(UVSCALE);
+       P(OCLRC0);
+       P(OCLRC1);
+       P(DCLRKV);
+       P(DCLRKM);
+       P(SCLRKVH);
+       P(SCLRKVL);
+       P(SCLRKEN);
+       P(OCONFIG);
+       P(OCMD);
+       P(OSTART_0Y);
+       P(OSTART_1Y);
+       P(OSTART_0U);
+       P(OSTART_0V);
+       P(OSTART_1U);
+       P(OSTART_1V);
+       P(OTILEOFF_0Y);
+       P(OTILEOFF_1Y);
+       P(OTILEOFF_0U);
+       P(OTILEOFF_0V);
+       P(OTILEOFF_1U);
+       P(OTILEOFF_1V);
+       P(FASTHSCALE);
+       P(UVSCALEV);
+#undef P
+}