Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e259befd authored by Chris Wilson's avatar Chris Wilson
Browse files

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: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: stable@kernel.org
parent 79077319
Loading
Loading
Loading
Loading
+24 −13
Original line number Diff line number Diff line
@@ -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];
	uint32_t fence_reg;

	if (IS_GEN6(dev)) {
	switch (INTEL_INFO(dev)->gen) {
	case 6:
		I915_WRITE64(FENCE_REG_SANDYBRIDGE_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);
	} else {
		uint32_t fence_reg;

		if (obj_priv->fence_reg < 8)
			fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4;
		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;
+27 −9
Original line number Diff line number Diff line
@@ -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);