mirror of
https://github.com/torvalds/linux.git
synced 2024-12-15 23:51:46 +00:00
drm/i915: Capture the overlay status upon a GPU hang.
v2: Add the interrupt status and address. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
dbd7ac9661
commit
6ef3d42780
@ -467,6 +467,9 @@ static int i915_error_state(struct seq_file *m, void *unused)
|
||||
}
|
||||
}
|
||||
|
||||
if (error->overlay)
|
||||
intel_overlay_print_error_state(m, error->overlay);
|
||||
|
||||
out:
|
||||
spin_unlock_irqrestore(&dev_priv->error_lock, flags);
|
||||
|
||||
|
@ -113,6 +113,9 @@ struct intel_opregion {
|
||||
int enabled;
|
||||
};
|
||||
|
||||
struct intel_overlay;
|
||||
struct intel_overlay_error_state;
|
||||
|
||||
struct drm_i915_master_private {
|
||||
drm_local_map_t *sarea;
|
||||
struct _drm_i915_sarea *sarea_priv;
|
||||
@ -166,6 +169,7 @@ struct drm_i915_error_state {
|
||||
u32 purgeable:1;
|
||||
} *active_bo;
|
||||
u32 active_bo_count;
|
||||
struct intel_overlay_error_state *overlay;
|
||||
};
|
||||
|
||||
struct drm_i915_display_funcs {
|
||||
@ -186,8 +190,6 @@ struct drm_i915_display_funcs {
|
||||
/* clock gating init */
|
||||
};
|
||||
|
||||
struct intel_overlay;
|
||||
|
||||
struct intel_device_info {
|
||||
u8 is_mobile : 1;
|
||||
u8 is_i8xx : 1;
|
||||
@ -1069,6 +1071,10 @@ extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
|
||||
extern void intel_detect_pch (struct drm_device *dev);
|
||||
extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
|
||||
|
||||
/* overlay */
|
||||
extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
|
||||
extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error);
|
||||
|
||||
/**
|
||||
* Lock test for when it's just for synchronization of ring access.
|
||||
*
|
||||
|
@ -489,6 +489,7 @@ i915_error_state_free(struct drm_device *dev,
|
||||
i915_error_object_free(error->batchbuffer[1]);
|
||||
i915_error_object_free(error->ringbuffer);
|
||||
kfree(error->active_bo);
|
||||
kfree(error->overlay);
|
||||
kfree(error);
|
||||
}
|
||||
|
||||
@ -667,6 +668,8 @@ static void i915_capture_error_state(struct drm_device *dev)
|
||||
|
||||
do_gettimeofday(&error->time);
|
||||
|
||||
error->overlay = intel_overlay_capture_error_state(dev);
|
||||
|
||||
spin_lock_irqsave(&dev_priv->error_lock, flags);
|
||||
if (dev_priv->first_error == NULL) {
|
||||
dev_priv->first_error = error;
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user