From: Paulo Zanoni <paulo.r.zan...@intel.com>

This solves many "unclaimed register" messages when the power well is
down and we get a GPU hang.

Also print the power well register and each pipe's CPU transcoder on
the error state to allow proper interpratation of the registers. And
kzalloc the error state structure since we may not read some of the
registers (to avoid the "unclaimed register" messages).

Signed-off-by: Paulo Zanoni <paulo.r.zan...@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   42 ++++++++++++++++++++++++++--------
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index b319cd3..835bec2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9290,6 +9290,9 @@ int intel_modeset_vga_set_state(struct drm_device *dev, 
bool state)
 #include <linux/seq_file.h>
 
 struct intel_display_error_state {
+
+       u32 power_well_driver;
+
        struct intel_cursor_error_state {
                u32 control;
                u32 position;
@@ -9298,6 +9301,7 @@ struct intel_display_error_state {
        } cursor[I915_MAX_PIPES];
 
        struct intel_pipe_error_state {
+               enum transcoder cpu_transcoder;
                u32 conf;
                u32 source;
 
@@ -9324,15 +9328,35 @@ 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;
+       enum transcoder transcoder;
+       bool power_well_is_down;
        int i;
 
-       error = kmalloc(sizeof(*error), GFP_ATOMIC);
+       error = kzalloc(sizeof(*error), GFP_ATOMIC);
        if (error == NULL)
                return NULL;
 
+       power_well_is_down = intel_power_well_is_down(dev);
+
+       if (IS_HASWELL(dev))
+               error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER);
+
        for_each_pipe(i) {
-               cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, i);
+               transcoder = intel_pipe_to_cpu_transcoder(dev_priv, i);
+               error->pipe[i].cpu_transcoder = transcoder;
+
+               if (transcoder == TRANSCODER_EDP || !power_well_is_down) {
+                       error->pipe[i].conf = I915_READ(PIPECONF(transcoder));
+                       error->pipe[i].htotal = I915_READ(HTOTAL(transcoder));
+                       error->pipe[i].hblank = I915_READ(HBLANK(transcoder));
+                       error->pipe[i].hsync = I915_READ(HSYNC(transcoder));
+                       error->pipe[i].vtotal = I915_READ(VTOTAL(transcoder));
+                       error->pipe[i].vblank = I915_READ(VBLANK(transcoder));
+                       error->pipe[i].vsync = I915_READ(VSYNC(transcoder));
+               }
+
+               if (power_well_is_down)
+                       continue;
 
                if (INTEL_INFO(dev)->gen <= 6) {
                        error->cursor[i].control = I915_READ(CURCNTR(i));
@@ -9355,14 +9379,7 @@ 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));
        }
 
        return error;
@@ -9377,8 +9394,13 @@ intel_display_print_error_state(struct seq_file *m,
        int i;
 
        seq_printf(m, "Num Pipes: %d\n", dev_priv->num_pipe);
+       if (IS_HASWELL(dev))
+               seq_printf(m, "PWR_WELL_CTL2: %08x\n",
+                          error->power_well_driver);
        for_each_pipe(i) {
                seq_printf(m, "Pipe [%d]:\n", i);
+               seq_printf(m, "  CPU transcoder: %c\n",
+                          transcoder_name(error->pipe[i].cpu_transcoder));
                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);
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to