Skip to content

Commit

Permalink
drm/i915: crc support for hsw
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Daniel Vetter committed Oct 18, 2013
1 parent e309a99 commit 5a69b89
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 20 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1997,7 +1997,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
u32 val;
int ret;

if (!(IS_IVYBRIDGE(dev) || IS_GEN5(dev) || IS_GEN6(dev)))
if (!(INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev)))
return -ENODEV;

if (pipe_crc->source == source)
Expand Down
44 changes: 25 additions & 19 deletions drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,15 @@ static void display_pipe_crc_update(struct drm_device *dev, enum pipe pipe,
wake_up_interruptible(&pipe_crc->wq);
}

static void hsw_pipe_crc_update(struct drm_device *dev, enum pipe pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;

display_pipe_crc_update(dev, pipe,
I915_READ(PIPE_CRC_RES_1_IVB(pipe)),
0, 0, 0, 0);
}

static void ivb_pipe_crc_update(struct drm_device *dev, enum pipe pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
Expand All @@ -1252,6 +1261,7 @@ static void ilk_pipe_crc_update(struct drm_device *dev, enum pipe pipe)
I915_READ(PIPE_CRC_RES_RES2_ILK(pipe)));
}
#else
static inline void hsw_pipe_crc_update(struct drm_device *dev, int pipe) {}
static inline void ivb_pipe_crc_update(struct drm_device *dev, int pipe) {}
static inline void ilk_pipe_crc_update(struct drm_device *dev, int pipe) {}
#endif
Expand Down Expand Up @@ -1418,30 +1428,26 @@ static void ivb_err_int_handler(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 err_int = I915_READ(GEN7_ERR_INT);
enum pipe pipe;

if (err_int & ERR_INT_POISON)
DRM_ERROR("Poison interrupt\n");

if (err_int & ERR_INT_FIFO_UNDERRUN_A)
if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false))
DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n");

if (err_int & ERR_INT_FIFO_UNDERRUN_B)
if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_B, false))
DRM_DEBUG_DRIVER("Pipe B FIFO underrun\n");

if (err_int & ERR_INT_FIFO_UNDERRUN_C)
if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_C, false))
DRM_DEBUG_DRIVER("Pipe C FIFO underrun\n");

if (err_int & ERR_INT_PIPE_CRC_DONE_A)
ivb_pipe_crc_update(dev, PIPE_A);

if (err_int & ERR_INT_PIPE_CRC_DONE_B)
ivb_pipe_crc_update(dev, PIPE_B);
for_each_pipe(pipe) {
if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) {
if (intel_set_cpu_fifo_underrun_reporting(dev, pipe,
false))
DRM_DEBUG_DRIVER("Pipe %c FIFO underrun\n",
pipe_name(pipe));
}

if (err_int & ERR_INT_PIPE_CRC_DONE_C)
ivb_pipe_crc_update(dev, PIPE_C);
if (err_int & ERR_INT_PIPE_CRC_DONE(pipe)) {
if (IS_IVYBRIDGE(dev))
ivb_pipe_crc_update(dev, pipe);
else
hsw_pipe_crc_update(dev, pipe);
}
}

I915_WRITE(GEN7_ERR_INT, err_int);
}
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,7 @@
#define ERR_INT_PIPE_CRC_DONE_B (1<<5)
#define ERR_INT_FIFO_UNDERRUN_B (1<<3)
#define ERR_INT_PIPE_CRC_DONE_A (1<<2)
#define ERR_INT_PIPE_CRC_DONE(pipe) (1<<(2 + pipe*3))
#define ERR_INT_FIFO_UNDERRUN_A (1<<0)
#define ERR_INT_FIFO_UNDERRUN(pipe) (1<<(pipe*3))

Expand Down

0 comments on commit 5a69b89

Please sign in to comment.