mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 18:39:59 +00:00
drm/i915: fix up tiling/fence reg setup on i8xx class hw
This fixes all the tiling problems with the 2d ddx. glxgears still doesn't work. Changes: - fix a copy&paste error in i8xx fence reg setup. It resulted in an at most a 512KB offset of the fence reg window, so was only visible sometimes. - add tests for stride and object size constrains (also for i915 and 1965 class hw). Userspace seems to have an of-by-one bug there, which changes the fence size by at most 512KB due to an overflow. - because i8xx hw is quite old (and therefore not as well-tested) I left 2 debug WARN_ONs in the i8xx fence reg setup code to hopefully catch any further overflows in the bit-fields. Lastly there's one small change to make the alignment checks more consistent. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=20289 Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
c09bca786f
commit
8d7773a32d
3 changed files with 27 additions and 5 deletions
|
@ -1990,20 +1990,23 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
|
|||
int regnum = obj_priv->fence_reg;
|
||||
uint32_t val;
|
||||
uint32_t pitch_val;
|
||||
uint32_t fence_size_bits;
|
||||
|
||||
if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
|
||||
if ((obj_priv->gtt_offset & ~I830_FENCE_START_MASK) ||
|
||||
(obj_priv->gtt_offset & (obj->size - 1))) {
|
||||
WARN(1, "%s: object 0x%08x not 1M or size aligned\n",
|
||||
WARN(1, "%s: object 0x%08x not 512K or size aligned\n",
|
||||
__func__, obj_priv->gtt_offset);
|
||||
return;
|
||||
}
|
||||
|
||||
pitch_val = (obj_priv->stride / 128) - 1;
|
||||
|
||||
WARN_ON(pitch_val & ~0x0000000f);
|
||||
val = obj_priv->gtt_offset;
|
||||
if (obj_priv->tiling_mode == I915_TILING_Y)
|
||||
val |= 1 << I830_FENCE_TILING_Y_SHIFT;
|
||||
val |= I830_FENCE_SIZE_BITS(obj->size);
|
||||
fence_size_bits = I830_FENCE_SIZE_BITS(obj->size);
|
||||
WARN_ON(fence_size_bits & ~0x00000f00);
|
||||
val |= fence_size_bits;
|
||||
val |= pitch_val << I830_FENCE_PITCH_SHIFT;
|
||||
val |= I830_FENCE_REG_VALID;
|
||||
|
||||
|
@ -2194,7 +2197,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
|
|||
return -EBUSY;
|
||||
if (alignment == 0)
|
||||
alignment = i915_gem_get_gtt_alignment(obj);
|
||||
if (alignment & (PAGE_SIZE - 1)) {
|
||||
if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) {
|
||||
DRM_ERROR("Invalid object alignment requested %u\n", alignment);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -216,6 +216,22 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
|
|||
else
|
||||
tile_width = 512;
|
||||
|
||||
/* check maximum stride & object size */
|
||||
if (IS_I965G(dev)) {
|
||||
/* i965 stores the end address of the gtt mapping in the fence
|
||||
* reg, so dont bother to check the size */
|
||||
if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
|
||||
return false;
|
||||
} else if (IS_I9XX(dev)) {
|
||||
if (stride / tile_width > I830_FENCE_MAX_PITCH_VAL ||
|
||||
size > (I830_FENCE_MAX_SIZE_VAL << 20))
|
||||
return false;
|
||||
} else {
|
||||
if (stride / 128 > I830_FENCE_MAX_PITCH_VAL ||
|
||||
size > (I830_FENCE_MAX_SIZE_VAL << 19))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 965+ just needs multiples of tile width */
|
||||
if (IS_I965G(dev)) {
|
||||
if (stride & (tile_width - 1))
|
||||
|
|
|
@ -190,6 +190,8 @@
|
|||
#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8)
|
||||
#define I830_FENCE_PITCH_SHIFT 4
|
||||
#define I830_FENCE_REG_VALID (1<<0)
|
||||
#define I830_FENCE_MAX_PITCH_VAL 0x10
|
||||
#define I830_FENCE_MAX_SIZE_VAL (1<<8)
|
||||
|
||||
#define I915_FENCE_START_MASK 0x0ff00000
|
||||
#define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8)
|
||||
|
@ -198,6 +200,7 @@
|
|||
#define I965_FENCE_PITCH_SHIFT 2
|
||||
#define I965_FENCE_TILING_Y_SHIFT 1
|
||||
#define I965_FENCE_REG_VALID (1<<0)
|
||||
#define I965_FENCE_MAX_PITCH_VAL 0x0400
|
||||
|
||||
/*
|
||||
* Instruction and interrupt control regs
|
||||
|
|
Loading…
Reference in a new issue