/* Is the current GTT allocation valid for the change in tiling? */ static bool i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode) { u32 size; if (tiling_mode == I915_TILING_NONE) return true; if (INTEL_INFO(obj->base.dev)->gen >= 4) return true; if (INTEL_INFO(obj->base.dev)->gen == 3) { if (i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK) return false; } else { if (i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) return false; } size = i915_gem_get_gtt_size(obj->base.dev, obj->base.size, tiling_mode); if (i915_gem_obj_ggtt_size(obj) != size) return false; if (i915_gem_obj_ggtt_offset(obj) & (size - 1)) return false; return true; }
static void i965_write_fence_reg(struct drm_device *dev, int reg, struct drm_i915_gem_object *obj) { struct drm_i915_private *dev_priv = dev->dev_private; i915_reg_t fence_reg_lo, fence_reg_hi; int fence_pitch_shift; if (INTEL_INFO(dev)->gen >= 6) { fence_reg_lo = FENCE_REG_GEN6_LO(reg); fence_reg_hi = FENCE_REG_GEN6_HI(reg); fence_pitch_shift = GEN6_FENCE_PITCH_SHIFT; } else { fence_reg_lo = FENCE_REG_965_LO(reg); fence_reg_hi = FENCE_REG_965_HI(reg); fence_pitch_shift = I965_FENCE_PITCH_SHIFT; } /* To w/a incoherency with non-atomic 64-bit register updates, * we split the 64-bit update into two 32-bit writes. In order * for a partial fence not to be evaluated between writes, we * precede the update with write to turn off the fence register, * and only enable the fence as the last step. * * For extra levels of paranoia, we make sure each step lands * before applying the next step. */ I915_WRITE(fence_reg_lo, 0); POSTING_READ(fence_reg_lo); if (obj) { u32 size = i915_gem_obj_ggtt_size(obj); uint64_t val; /* Adjust fence size to match tiled area */ if (obj->tiling_mode != I915_TILING_NONE) { uint32_t row_size = obj->stride * (obj->tiling_mode == I915_TILING_Y ? 32 : 8); size = (size / row_size) * row_size; } val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) & 0xfffff000) << 32; val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000; val |= (uint64_t)((obj->stride / 128) - 1) << fence_pitch_shift; if (obj->tiling_mode == I915_TILING_Y) val |= 1 << I965_FENCE_TILING_Y_SHIFT; val |= I965_FENCE_REG_VALID; I915_WRITE(fence_reg_hi, val >> 32); POSTING_READ(fence_reg_hi); I915_WRITE(fence_reg_lo, val); POSTING_READ(fence_reg_lo); } else {