diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-11-21 08:12:35 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-11-22 03:08:19 -0500 |
commit | c4a1d9e4dc5d5313cfec2cc0c9d630efe8a6f287 (patch) | |
tree | 6b8c839478c8cf8a8fb1a6b02f32a03878247a94 | |
parent | c724e8a9407683a8a2ee8eb00b972badf237bbe1 (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.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 110 |
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 | |||
732 | out: | 735 | out: |
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 | ||
143 | struct intel_display_error_state; | ||
144 | |||
143 | struct drm_i915_error_state { | 145 | struct 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 | ||
192 | struct drm_i915_display_funcs { | 195 | struct 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 |
1224 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); | 1227 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); |
1225 | extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); | 1228 | extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); |
1229 | |||
1230 | extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev); | ||
1231 | extern 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 | |||
6276 | struct 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 | |||
6307 | struct intel_display_error_state * | ||
6308 | intel_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 | |||
6346 | void | ||
6347 | intel_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 | ||