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:
parent
79077319d7
commit
e259befd90
|
@ -2351,14 +2351,21 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
|
|||
|
||||
reg->obj = obj;
|
||||
|
||||
if (IS_GEN6(dev))
|
||||
switch (INTEL_INFO(dev)->gen) {
|
||||
case 6:
|
||||
sandybridge_write_fence_reg(reg);
|
||||
else if (IS_I965G(dev))
|
||||
break;
|
||||
case 5:
|
||||
case 4:
|
||||
i965_write_fence_reg(reg);
|
||||
else if (IS_I9XX(dev))
|
||||
break;
|
||||
case 3:
|
||||
i915_write_fence_reg(reg);
|
||||
else
|
||||
break;
|
||||
case 2:
|
||||
i830_write_fence_reg(reg);
|
||||
break;
|
||||
}
|
||||
|
||||
trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg,
|
||||
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_fence_reg *reg =
|
||||
&dev_priv->fence_regs[obj_priv->fence_reg];
|
||||
|
||||
if (IS_GEN6(dev)) {
|
||||
I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 +
|
||||
(obj_priv->fence_reg * 8), 0);
|
||||
} else if (IS_I965G(dev)) {
|
||||
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;
|
||||
switch (INTEL_INFO(dev)->gen) {
|
||||
case 6:
|
||||
I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 +
|
||||
(obj_priv->fence_reg * 8), 0);
|
||||
break;
|
||||
case 5:
|
||||
case 4:
|
||||
I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0);
|
||||
break;
|
||||
case 3:
|
||||
if (obj_priv->fence_reg > 8)
|
||||
fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4;
|
||||
else
|
||||
fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg -
|
||||
8) * 4;
|
||||
case 2:
|
||||
fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4;
|
||||
|
||||
I915_WRITE(fence_reg, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
reg->obj = NULL;
|
||||
|
|
|
@ -789,16 +789,25 @@ int i915_save_state(struct drm_device *dev)
|
|||
dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
|
||||
|
||||
/* 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++)
|
||||
dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8));
|
||||
} else {
|
||||
for (i = 0; i < 8; i++)
|
||||
dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4));
|
||||
|
||||
break;
|
||||
case 3:
|
||||
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
|
||||
for (i = 0; i < 8; i++)
|
||||
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;
|
||||
|
@ -815,15 +824,24 @@ int i915_restore_state(struct drm_device *dev)
|
|||
I915_WRITE(HWS_PGA, dev_priv->saveHWS);
|
||||
|
||||
/* 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++)
|
||||
I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]);
|
||||
} else {
|
||||
for (i = 0; i < 8; i++)
|
||||
I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]);
|
||||
break;
|
||||
case 3:
|
||||
case 2:
|
||||
if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
|
||||
for (i = 0; i < 8; i++)
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue