summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsg <jsg@openbsd.org>2014-02-15 09:56:08 +0000
committerjsg <jsg@openbsd.org>2014-02-15 09:56:08 +0000
commit653d1ed134a0d4659f572e953f3fac790d589f61 (patch)
tree2cda99e698d60b00afc2405c49510cd48de89e41
parentdrm/i915: Use the correct GMCH_CTRL register for Sandybridge+ (diff)
downloadwireguard-openbsd-653d1ed134a0d4659f572e953f3fac790d589f61.tar.xz
wireguard-openbsd-653d1ed134a0d4659f572e953f3fac790d589f61.zip
drm/i915: Don't deref pipe->cpu_transcoder in the hangcheck code
From Chris Wilson d280fd3cae523191525251159e3cf9e773fdcedb in ubuntu 3.8 63b66e5ba54b15a6592be00555d762db6db739ce in mainline linux
-rw-r--r--sys/dev/pci/drm/i915/intel_display.c85
1 files changed, 59 insertions, 26 deletions
diff --git a/sys/dev/pci/drm/i915/intel_display.c b/sys/dev/pci/drm/i915/intel_display.c
index b6656225f3a..bc562c0b23f 100644
--- a/sys/dev/pci/drm/i915/intel_display.c
+++ b/sys/dev/pci/drm/i915/intel_display.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intel_display.c,v 1.30 2014/02/15 09:47:15 jsg Exp $ */
+/* $OpenBSD: intel_display.c,v 1.31 2014/02/15 09:56:08 jsg Exp $ */
/*
* Copyright © 2006-2007 Intel Corporation
*
@@ -9568,6 +9568,9 @@ int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
#include <linux/seq_file.h>
struct intel_display_error_state {
+
+ int num_transcoders;
+
struct intel_cursor_error_state {
u32 control;
u32 position;
@@ -9576,15 +9579,7 @@ struct intel_display_error_state {
} cursor[I915_MAX_PIPES];
struct intel_pipe_error_state {
- u32 conf;
u32 source;
-
- u32 htotal;
- u32 hblank;
- u32 hsync;
- u32 vtotal;
- u32 vblank;
- u32 vsync;
} pipe[I915_MAX_PIPES];
struct intel_plane_error_state {
@@ -9596,6 +9591,19 @@ struct intel_display_error_state {
u32 surface;
u32 tile_offset;
} plane[I915_MAX_PIPES];
+
+ struct intel_transcoder_error_state {
+ enum transcoder cpu_transcoder;
+
+ u32 conf;
+
+ u32 htotal;
+ u32 hblank;
+ u32 hsync;
+ u32 vtotal;
+ u32 vblank;
+ u32 vsync;
+ } transcoder[4];
};
struct intel_display_error_state *
@@ -9603,16 +9611,22 @@ intel_display_capture_error_state(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_display_error_state *error;
- enum transcoder cpu_transcoder;
+ int transcoders[] = {
+ TRANSCODER_A,
+ TRANSCODER_B,
+ TRANSCODER_C,
+ TRANSCODER_EDP,
+ };
int i;
+ if (INTEL_INFO(dev)->num_pipes == 0)
+ return NULL;
+
error = kmalloc(sizeof(*error), GFP_ATOMIC);
if (error == NULL)
return NULL;
for_each_pipe(i) {
- cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, i);
-
error->cursor[i].control = I915_READ(CURCNTR(i));
error->cursor[i].position = I915_READ(CURPOS(i));
error->cursor[i].base = I915_READ(CURBASE(i));
@@ -9627,14 +9641,25 @@ intel_display_capture_error_state(struct drm_device *dev)
error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i));
}
- error->pipe[i].conf = I915_READ(PIPECONF(cpu_transcoder));
error->pipe[i].source = I915_READ(PIPESRC(i));
- error->pipe[i].htotal = I915_READ(HTOTAL(cpu_transcoder));
- error->pipe[i].hblank = I915_READ(HBLANK(cpu_transcoder));
- error->pipe[i].hsync = I915_READ(HSYNC(cpu_transcoder));
- error->pipe[i].vtotal = I915_READ(VTOTAL(cpu_transcoder));
- error->pipe[i].vblank = I915_READ(VBLANK(cpu_transcoder));
- error->pipe[i].vsync = I915_READ(VSYNC(cpu_transcoder));
+ }
+
+ error->num_transcoders = INTEL_INFO(dev)->num_pipes;
+ if (HAS_DDI(dev_priv->dev))
+ error->num_transcoders++; /* Account for eDP. */
+
+ for (i = 0; i < error->num_transcoders; i++) {
+ enum transcoder cpu_transcoder = transcoders[i];
+
+ error->transcoder[i].cpu_transcoder = cpu_transcoder;
+
+ error->transcoder[i].conf = I915_READ(PIPECONF(cpu_transcoder));
+ error->transcoder[i].htotal = I915_READ(HTOTAL(cpu_transcoder));
+ error->transcoder[i].hblank = I915_READ(HBLANK(cpu_transcoder));
+ error->transcoder[i].hsync = I915_READ(HSYNC(cpu_transcoder));
+ error->transcoder[i].vtotal = I915_READ(VTOTAL(cpu_transcoder));
+ error->transcoder[i].vblank = I915_READ(VBLANK(cpu_transcoder));
+ error->transcoder[i].vsync = I915_READ(VSYNC(cpu_transcoder));
}
return error;
@@ -9647,17 +9672,13 @@ intel_display_print_error_state(struct seq_file *m,
{
int i;
+ if (!error)
+ return;
+
seq_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes);
for_each_pipe(i) {
seq_printf(m, "Pipe [%d]:\n", i);
- seq_printf(m, " CONF: %08x\n", error->pipe[i].conf);
seq_printf(m, " SRC: %08x\n", error->pipe[i].source);
- seq_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal);
- seq_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank);
- seq_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync);
- seq_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal);
- seq_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank);
- seq_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync);
seq_printf(m, "Plane [%d]:\n", i);
seq_printf(m, " CNTR: %08x\n", error->plane[i].control);
@@ -9675,5 +9696,17 @@ intel_display_print_error_state(struct seq_file *m,
seq_printf(m, " POS: %08x\n", error->cursor[i].position);
seq_printf(m, " BASE: %08x\n", error->cursor[i].base);
}
+
+ for (i = 0; i < error->num_transcoders; i++) {
+ seq_printf(m, " CPU transcoder: %c\n",
+ transcoder_name(error->transcoder[i].cpu_transcoder));
+ seq_printf(m, " CONF: %08x\n", error->transcoder[i].conf);
+ seq_printf(m, " HTOTAL: %08x\n", error->transcoder[i].htotal);
+ seq_printf(m, " HBLANK: %08x\n", error->transcoder[i].hblank);
+ seq_printf(m, " HSYNC: %08x\n", error->transcoder[i].hsync);
+ seq_printf(m, " VTOTAL: %08x\n", error->transcoder[i].vtotal);
+ seq_printf(m, " VBLANK: %08x\n", error->transcoder[i].vblank);
+ seq_printf(m, " VSYNC: %08x\n", error->transcoder[i].vsync);
+ }
}
#endif