Commit dc529a4f authored by Eric Anholt's avatar Eric Anholt

drm/i915: fix 945 fence register writes for fence 8 and above.

The last 8 fence registers sit at a different offset, so when we went to set
fence number 8 in the lower offset, we instead set PGETBL_CTL, and the GPU
got all sorts of angry at us.

fd.o bug #20567.  Easily reproducible by running glxgears and killing it about
6 times.
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent d7619c4b
...@@ -1476,7 +1476,7 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) ...@@ -1476,7 +1476,7 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
struct drm_i915_gem_object *obj_priv = obj->driver_private; struct drm_i915_gem_object *obj_priv = obj->driver_private;
int regnum = obj_priv->fence_reg; int regnum = obj_priv->fence_reg;
int tile_width; int tile_width;
uint32_t val; uint32_t fence_reg, val;
uint32_t pitch_val; uint32_t pitch_val;
if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
...@@ -1503,7 +1503,11 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) ...@@ -1503,7 +1503,11 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
val |= pitch_val << I830_FENCE_PITCH_SHIFT; val |= pitch_val << I830_FENCE_PITCH_SHIFT;
val |= I830_FENCE_REG_VALID; val |= I830_FENCE_REG_VALID;
I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); if (regnum < 8)
fence_reg = FENCE_REG_830_0 + (regnum * 4);
else
fence_reg = FENCE_REG_945_8 + ((regnum - 8) * 4);
I915_WRITE(fence_reg, val);
} }
static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
...@@ -1687,8 +1691,17 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) ...@@ -1687,8 +1691,17 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
if (IS_I965G(dev)) if (IS_I965G(dev))
I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0);
else {
uint32_t fence_reg;
if (obj_priv->fence_reg < 8)
fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4;
else else
I915_WRITE(FENCE_REG_830_0 + (obj_priv->fence_reg * 4), 0); fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg -
8) * 4;
I915_WRITE(fence_reg, 0);
}
dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL;
obj_priv->fence_reg = I915_FENCE_REG_NONE; obj_priv->fence_reg = I915_FENCE_REG_NONE;
......
...@@ -184,6 +184,7 @@ ...@@ -184,6 +184,7 @@
* Fence registers * Fence registers
*/ */
#define FENCE_REG_830_0 0x2000 #define FENCE_REG_830_0 0x2000
#define FENCE_REG_945_8 0x3000
#define I830_FENCE_START_MASK 0x07f80000 #define I830_FENCE_START_MASK 0x07f80000
#define I830_FENCE_TILING_Y_SHIFT 12 #define I830_FENCE_TILING_Y_SHIFT 12
#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment