aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-11-21 08:12:35 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2010-11-22 03:08:19 -0500
commitc4a1d9e4dc5d5313cfec2cc0c9d630efe8a6f287 (patch)
tree6b8c839478c8cf8a8fb1a6b02f32a03878247a94
parentc724e8a9407683a8a2ee8eb00b972badf237bbe1 (diff)
drm/i915: Capture interesting display registers on error
When trying to diagnose mysterious errors on resume, capture the display register contents as well. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h8
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c1
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h6
-rw-r--r--drivers/gpu/drm/i915/intel_display.c110
5 files changed, 127 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 24a88ac63212..421b8414b577 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -729,6 +729,9 @@ static int i915_error_state(struct seq_file *m, void *unused)
729 if (error->overlay) 729 if (error->overlay)
730 intel_overlay_print_error_state(m, error->overlay); 730 intel_overlay_print_error_state(m, error->overlay);
731 731
732 if (error->display)
733 intel_display_print_error_state(m, dev, error->display);
734
732out: 735out:
733 spin_unlock_irqrestore(&dev_priv->error_lock, flags); 736 spin_unlock_irqrestore(&dev_priv->error_lock, flags);
734 737
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 826c7237409b..4c20ad92c0f3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -140,6 +140,8 @@ struct sdvo_device_mapping {
140 u8 ddc_pin; 140 u8 ddc_pin;
141}; 141};
142 142
143struct intel_display_error_state;
144
143struct drm_i915_error_state { 145struct drm_i915_error_state {
144 u32 eir; 146 u32 eir;
145 u32 pgtbl_er; 147 u32 pgtbl_er;
@@ -187,6 +189,7 @@ struct drm_i915_error_state {
187 } *active_bo, *pinned_bo; 189 } *active_bo, *pinned_bo;
188 u32 active_bo_count, pinned_bo_count; 190 u32 active_bo_count, pinned_bo_count;
189 struct intel_overlay_error_state *overlay; 191 struct intel_overlay_error_state *overlay;
192 struct intel_display_error_state *display;
190}; 193};
191 194
192struct drm_i915_display_funcs { 195struct drm_i915_display_funcs {
@@ -1223,6 +1226,11 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
1223#ifdef CONFIG_DEBUG_FS 1226#ifdef CONFIG_DEBUG_FS
1224extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); 1227extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
1225extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); 1228extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error);
1229
1230extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev);
1231extern void intel_display_print_error_state(struct seq_file *m,
1232 struct drm_device *dev,
1233 struct intel_display_error_state *error);
1226#endif 1234#endif
1227 1235
1228/** 1236/**
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index bbcd5da89ba5..0b6052abedd1 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -766,6 +766,7 @@ static void i915_capture_error_state(struct drm_device *dev)
766 do_gettimeofday(&error->time); 766 do_gettimeofday(&error->time);
767 767
768 error->overlay = intel_overlay_capture_error_state(dev); 768 error->overlay = intel_overlay_capture_error_state(dev);
769 error->display = intel_display_capture_error_state(dev);
769 770
770 spin_lock_irqsave(&dev_priv->error_lock, flags); 771 spin_lock_irqsave(&dev_priv->error_lock, flags);
771 if (dev_priv->first_error == NULL) { 772 if (dev_priv->first_error == NULL) {
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 886c0e072490..ec2a8b07ba5b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1193,7 +1193,6 @@
1193#define VTOTAL(pipe) _PIPE(pipe, VTOTAL_A, VTOTAL_B) 1193#define VTOTAL(pipe) _PIPE(pipe, VTOTAL_A, VTOTAL_B)
1194#define VBLANK(pipe) _PIPE(pipe, VBLANK_A, VBLANK_B) 1194#define VBLANK(pipe) _PIPE(pipe, VBLANK_A, VBLANK_B)
1195#define VSYNC(pipe) _PIPE(pipe, VSYNC_A, VSYNC_B) 1195#define VSYNC(pipe) _PIPE(pipe, VSYNC_A, VSYNC_B)
1196#define PIPESRC(pipe) _PIPE(pipe, PIPEASRC, PIPEBSRC)
1197#define BCLRPAT(pipe) _PIPE(pipe, BCLRPAT_A, BCLRPAT_B) 1196#define BCLRPAT(pipe) _PIPE(pipe, BCLRPAT_A, BCLRPAT_B)
1198 1197
1199/* VGA port control */ 1198/* VGA port control */
@@ -2207,6 +2206,7 @@
2207#define PIPE_6BPC (2 << 5) 2206#define PIPE_6BPC (2 << 5)
2208#define PIPE_12BPC (3 << 5) 2207#define PIPE_12BPC (3 << 5)
2209 2208
2209#define PIPESRC(pipe) _PIPE(pipe, PIPEASRC, PIPEBSRC)
2210#define PIPECONF(pipe) _PIPE(pipe, PIPEACONF, PIPEBCONF) 2210#define PIPECONF(pipe) _PIPE(pipe, PIPEACONF, PIPEBCONF)
2211#define PIPEDSL(pipe) _PIPE(pipe, PIPEADSL, PIPEBDSL) 2211#define PIPEDSL(pipe) _PIPE(pipe, PIPEADSL, PIPEBDSL)
2212 2212
@@ -2376,6 +2376,10 @@
2376#define CURBBASE 0x700c4 2376#define CURBBASE 0x700c4
2377#define CURBPOS 0x700c8 2377#define CURBPOS 0x700c8
2378 2378
2379#define CURCNTR(pipe) _PIPE(pipe, CURACNTR, CURBCNTR)
2380#define CURBASE(pipe) _PIPE(pipe, CURABASE, CURBBASE)
2381#define CURPOS(pipe) _PIPE(pipe, CURAPOS, CURBPOS)
2382
2379/* Display A control */ 2383/* Display A control */
2380#define DSPACNTR 0x70180 2384#define DSPACNTR 0x70180
2381#define DISPLAY_PLANE_ENABLE (1<<31) 2385#define DISPLAY_PLANE_ENABLE (1<<31)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3fa5aaa941d2..d4bc443f43fc 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6269,3 +6269,113 @@ int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
6269 pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl); 6269 pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl);
6270 return 0; 6270 return 0;
6271} 6271}
6272
6273#ifdef CONFIG_DEBUG_FS
6274#include <linux/seq_file.h>
6275
6276struct intel_display_error_state {
6277 struct intel_cursor_error_state {
6278 u32 control;
6279 u32 position;
6280 u32 base;
6281 u32 size;
6282 } cursor[2];
6283
6284 struct intel_pipe_error_state {
6285 u32 conf;
6286 u32 source;
6287
6288 u32 htotal;
6289 u32 hblank;
6290 u32 hsync;
6291 u32 vtotal;
6292 u32 vblank;
6293 u32 vsync;
6294 } pipe[2];
6295
6296 struct intel_plane_error_state {
6297 u32 control;
6298 u32 stride;
6299 u32 size;
6300 u32 pos;
6301 u32 addr;
6302 u32 surface;
6303 u32 tile_offset;
6304 } plane[2];
6305};
6306
6307struct intel_display_error_state *
6308intel_display_capture_error_state(struct drm_device *dev)
6309{
6310 drm_i915_private_t *dev_priv = dev->dev_private;
6311 struct intel_display_error_state *error;
6312 int i;
6313
6314 error = kmalloc(sizeof(*error), GFP_ATOMIC);
6315 if (error == NULL)
6316 return NULL;
6317
6318 for (i = 0; i < 2; i++) {
6319 error->cursor[i].control = I915_READ(CURCNTR(i));
6320 error->cursor[i].position = I915_READ(CURPOS(i));
6321 error->cursor[i].base = I915_READ(CURBASE(i));
6322
6323 error->plane[i].control = I915_READ(DSPCNTR(i));
6324 error->plane[i].stride = I915_READ(DSPSTRIDE(i));
6325 error->plane[i].size = I915_READ(DSPSIZE(i));
6326 error->plane[i].pos= I915_READ(DSPPOS(i));
6327 error->plane[i].addr = I915_READ(DSPADDR(i));
6328 if (INTEL_INFO(dev)->gen >= 4) {
6329 error->plane[i].surface = I915_READ(DSPSURF(i));
6330 error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i));
6331 }
6332
6333 error->pipe[i].conf = I915_READ(PIPECONF(i));
6334 error->pipe[i].source = I915_READ(PIPESRC(i));
6335 error->pipe[i].htotal = I915_READ(HTOTAL(i));
6336 error->pipe[i].hblank = I915_READ(HBLANK(i));
6337 error->pipe[i].hsync = I915_READ(HSYNC(i));
6338 error->pipe[i].vtotal = I915_READ(VTOTAL(i));
6339 error->pipe[i].vblank = I915_READ(VBLANK(i));
6340 error->pipe[i].vsync = I915_READ(VSYNC(i));
6341 }
6342
6343 return error;
6344}
6345
6346void
6347intel_display_print_error_state(struct seq_file *m,
6348 struct drm_device *dev,
6349 struct intel_display_error_state *error)
6350{
6351 int i;
6352
6353 for (i = 0; i < 2; i++) {
6354 seq_printf(m, "Pipe [%d]:\n", i);
6355 seq_printf(m, " CONF: %08x\n", error->pipe[i].conf);
6356 seq_printf(m, " SRC: %08x\n", error->pipe[i].source);
6357 seq_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal);
6358 seq_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank);
6359 seq_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync);
6360 seq_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal);
6361 seq_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank);
6362 seq_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync);
6363
6364 seq_printf(m, "Plane [%d]:\n", i);
6365 seq_printf(m, " CNTR: %08x\n", error->plane[i].control);
6366 seq_printf(m, " STRIDE: %08x\n", error->plane[i].stride);
6367 seq_printf(m, " SIZE: %08x\n", error->plane[i].size);
6368 seq_printf(m, " POS: %08x\n", error->plane[i].pos);
6369 seq_printf(m, " ADDR: %08x\n", error->plane[i].addr);
6370 if (INTEL_INFO(dev)->gen >= 4) {
6371 seq_printf(m, " SURF: %08x\n", error->plane[i].surface);
6372 seq_printf(m, " TILEOFF: %08x\n", error->plane[i].tile_offset);
6373 }
6374
6375 seq_printf(m, "Cursor [%d]:\n", i);
6376 seq_printf(m, " CNTR: %08x\n", error->cursor[i].control);
6377 seq_printf(m, " POS: %08x\n", error->cursor[i].position);
6378 seq_printf(m, " BASE: %08x\n", error->cursor[i].base);
6379 }
6380}
6381#endif