aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-10-16 16:55:52 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-10-18 09:05:35 -0400
commit5a69b89f853fb35adf51b8b45c026bad0934bf97 (patch)
treeff07c0fb13a8160528351f5fc985c4e2c068d80a
parente309a9977087fa0f2cb16d0a0790f7c05ccb5171 (diff)
drm/i915: crc support for hsw
hw designers decided to change the CRC registers and coalesce them all into one. Otherwise nothing changed. I've opted for a new hsw_ version to grab the crc sample since hsw+1 will have the same crc registers, but different interrupt source registers. So this little helper function will come handy there. Also refactor the display error handler with a neat pipe loop. v2: Use for_each_pipe. Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c2
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c44
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
3 files changed, 27 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 649c00ebf6e0..061182a0ce1b 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1997,7 +1997,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
1997 u32 val; 1997 u32 val;
1998 int ret; 1998 int ret;
1999 1999
2000 if (!(IS_IVYBRIDGE(dev) || IS_GEN5(dev) || IS_GEN6(dev))) 2000 if (!(INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev)))
2001 return -ENODEV; 2001 return -ENODEV;
2002 2002
2003 if (pipe_crc->source == source) 2003 if (pipe_crc->source == source)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index eaf12680c2ea..156a1a4d8e51 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1228,6 +1228,15 @@ static void display_pipe_crc_update(struct drm_device *dev, enum pipe pipe,
1228 wake_up_interruptible(&pipe_crc->wq); 1228 wake_up_interruptible(&pipe_crc->wq);
1229} 1229}
1230 1230
1231static void hsw_pipe_crc_update(struct drm_device *dev, enum pipe pipe)
1232{
1233 struct drm_i915_private *dev_priv = dev->dev_private;
1234
1235 display_pipe_crc_update(dev, pipe,
1236 I915_READ(PIPE_CRC_RES_1_IVB(pipe)),
1237 0, 0, 0, 0);
1238}
1239
1231static void ivb_pipe_crc_update(struct drm_device *dev, enum pipe pipe) 1240static void ivb_pipe_crc_update(struct drm_device *dev, enum pipe pipe)
1232{ 1241{
1233 struct drm_i915_private *dev_priv = dev->dev_private; 1242 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1252,6 +1261,7 @@ static void ilk_pipe_crc_update(struct drm_device *dev, enum pipe pipe)
1252 I915_READ(PIPE_CRC_RES_RES2_ILK(pipe))); 1261 I915_READ(PIPE_CRC_RES_RES2_ILK(pipe)));
1253} 1262}
1254#else 1263#else
1264static inline void hsw_pipe_crc_update(struct drm_device *dev, int pipe) {}
1255static inline void ivb_pipe_crc_update(struct drm_device *dev, int pipe) {} 1265static inline void ivb_pipe_crc_update(struct drm_device *dev, int pipe) {}
1256static inline void ilk_pipe_crc_update(struct drm_device *dev, int pipe) {} 1266static inline void ilk_pipe_crc_update(struct drm_device *dev, int pipe) {}
1257#endif 1267#endif
@@ -1418,30 +1428,26 @@ static void ivb_err_int_handler(struct drm_device *dev)
1418{ 1428{
1419 struct drm_i915_private *dev_priv = dev->dev_private; 1429 struct drm_i915_private *dev_priv = dev->dev_private;
1420 u32 err_int = I915_READ(GEN7_ERR_INT); 1430 u32 err_int = I915_READ(GEN7_ERR_INT);
1431 enum pipe pipe;
1421 1432
1422 if (err_int & ERR_INT_POISON) 1433 if (err_int & ERR_INT_POISON)
1423 DRM_ERROR("Poison interrupt\n"); 1434 DRM_ERROR("Poison interrupt\n");
1424 1435
1425 if (err_int & ERR_INT_FIFO_UNDERRUN_A) 1436 for_each_pipe(pipe) {
1426 if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false)) 1437 if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) {
1427 DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n"); 1438 if (intel_set_cpu_fifo_underrun_reporting(dev, pipe,
1428 1439 false))
1429 if (err_int & ERR_INT_FIFO_UNDERRUN_B) 1440 DRM_DEBUG_DRIVER("Pipe %c FIFO underrun\n",
1430 if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_B, false)) 1441 pipe_name(pipe));
1431 DRM_DEBUG_DRIVER("Pipe B FIFO underrun\n"); 1442 }
1432
1433 if (err_int & ERR_INT_FIFO_UNDERRUN_C)
1434 if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_C, false))
1435 DRM_DEBUG_DRIVER("Pipe C FIFO underrun\n");
1436
1437 if (err_int & ERR_INT_PIPE_CRC_DONE_A)
1438 ivb_pipe_crc_update(dev, PIPE_A);
1439
1440 if (err_int & ERR_INT_PIPE_CRC_DONE_B)
1441 ivb_pipe_crc_update(dev, PIPE_B);
1442 1443
1443 if (err_int & ERR_INT_PIPE_CRC_DONE_C) 1444 if (err_int & ERR_INT_PIPE_CRC_DONE(pipe)) {
1444 ivb_pipe_crc_update(dev, PIPE_C); 1445 if (IS_IVYBRIDGE(dev))
1446 ivb_pipe_crc_update(dev, pipe);
1447 else
1448 hsw_pipe_crc_update(dev, pipe);
1449 }
1450 }
1445 1451
1446 I915_WRITE(GEN7_ERR_INT, err_int); 1452 I915_WRITE(GEN7_ERR_INT, err_int);
1447} 1453}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8b1f2dbc6009..0e7488b64965 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -728,6 +728,7 @@
728#define ERR_INT_PIPE_CRC_DONE_B (1<<5) 728#define ERR_INT_PIPE_CRC_DONE_B (1<<5)
729#define ERR_INT_FIFO_UNDERRUN_B (1<<3) 729#define ERR_INT_FIFO_UNDERRUN_B (1<<3)
730#define ERR_INT_PIPE_CRC_DONE_A (1<<2) 730#define ERR_INT_PIPE_CRC_DONE_A (1<<2)
731#define ERR_INT_PIPE_CRC_DONE(pipe) (1<<(2 + pipe*3))
731#define ERR_INT_FIFO_UNDERRUN_A (1<<0) 732#define ERR_INT_FIFO_UNDERRUN_A (1<<0)
732#define ERR_INT_FIFO_UNDERRUN(pipe) (1<<(pipe*3)) 733#define ERR_INT_FIFO_UNDERRUN(pipe) (1<<(pipe*3))
733 734