diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_overlay.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 101 | 
1 files changed, 100 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d39aea24eab..1d306a458be 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -25,6 +25,8 @@   *   * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c   */ + +#include <linux/seq_file.h>  #include "drmP.h"  #include "drm.h"  #include "i915_drm.h" @@ -1367,7 +1369,8 @@ void intel_setup_overlay(struct drm_device *dev)  		overlay->flip_addr = overlay->reg_bo->gtt_offset;  	} else {  		ret = i915_gem_attach_phys_object(dev, reg_bo, -				I915_GEM_PHYS_OVERLAY_REGS); +						  I915_GEM_PHYS_OVERLAY_REGS, +						  0);                  if (ret) {                          DRM_ERROR("failed to attach phys overlay regs\n");                          goto out_free_bo; @@ -1416,3 +1419,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 +}  |