drm/i915: Fix Sandybridge fence registers

With 5 places to update when adding handling for fence registers, it is
easy to overlook one or two. Correct that oversight, but fence
management should be improved before a new set of registers is added.

Bugzilla: https://bugs.freedesktop.org/show_bug?id=30199
Original patch by: Yuanhan Liu <yuanhan.liu@intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: stable@kernel.org
This commit is contained in:
Chris Wilson 2010-09-17 00:32:02 +01:00
parent 79077319d7
commit e259befd90
2 changed files with 51 additions and 22 deletions

View File

@ -2351,14 +2351,21 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
reg->obj = obj; reg->obj = obj;
if (IS_GEN6(dev)) switch (INTEL_INFO(dev)->gen) {
case 6:
sandybridge_write_fence_reg(reg); sandybridge_write_fence_reg(reg);
else if (IS_I965G(dev)) break;
case 5:
case 4:
i965_write_fence_reg(reg); i965_write_fence_reg(reg);
else if (IS_I9XX(dev)) break;
case 3:
i915_write_fence_reg(reg); i915_write_fence_reg(reg);
else break;
case 2:
i830_write_fence_reg(reg); i830_write_fence_reg(reg);
break;
}
trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg,
obj_priv->tiling_mode); obj_priv->tiling_mode);
@ -2381,22 +2388,26 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
struct drm_i915_fence_reg *reg = struct drm_i915_fence_reg *reg =
&dev_priv->fence_regs[obj_priv->fence_reg]; &dev_priv->fence_regs[obj_priv->fence_reg];
uint32_t fence_reg;
if (IS_GEN6(dev)) { switch (INTEL_INFO(dev)->gen) {
case 6:
I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 +
(obj_priv->fence_reg * 8), 0); (obj_priv->fence_reg * 8), 0);
} else if (IS_I965G(dev)) { break;
case 5:
case 4:
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 { break;
uint32_t fence_reg; case 3:
if (obj_priv->fence_reg > 8)
if (obj_priv->fence_reg < 8) fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4;
fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4;
else else
fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - case 2:
8) * 4; fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4;
I915_WRITE(fence_reg, 0); I915_WRITE(fence_reg, 0);
break;
} }
reg->obj = NULL; reg->obj = NULL;

View File

@ -789,16 +789,25 @@ int i915_save_state(struct drm_device *dev)
dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
/* Fences */ /* Fences */
if (IS_I965G(dev)) { switch (INTEL_INFO(dev)->gen) {
case 6:
for (i = 0; i < 16; i++)
dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8));
break;
case 5:
case 4:
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8));
} else { break;
for (i = 0; i < 8; i++) case 3:
dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4));
case 2:
for (i = 0; i < 8; i++)
dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
break;
} }
return 0; return 0;
@ -815,15 +824,24 @@ int i915_restore_state(struct drm_device *dev)
I915_WRITE(HWS_PGA, dev_priv->saveHWS); I915_WRITE(HWS_PGA, dev_priv->saveHWS);
/* Fences */ /* Fences */
if (IS_I965G(dev)) { switch (INTEL_INFO(dev)->gen) {
case 6:
for (i = 0; i < 16; i++)
I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]);
break;
case 5:
case 4:
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]);
} else { break;
for (i = 0; i < 8; i++) case 3:
I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); case 2:
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]);
for (i = 0; i < 8; i++)
I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]);
break;
} }
i915_restore_display(dev); i915_restore_display(dev);