|
@@ -15202,23 +15202,26 @@ static int intel_framebuffer_init(struct drm_device *dev,
|
|
|
struct drm_i915_gem_object *obj)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
|
|
+ unsigned int tiling = i915_gem_object_get_tiling(obj);
|
|
|
int ret;
|
|
|
u32 pitch_limit, stride_alignment;
|
|
|
|
|
|
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
|
|
|
|
|
|
if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) {
|
|
|
- /* Enforce that fb modifier and tiling mode match, but only for
|
|
|
- * X-tiled. This is needed for FBC. */
|
|
|
- if (!!(i915_gem_object_get_tiling(obj) == I915_TILING_X) !=
|
|
|
- !!(mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED)) {
|
|
|
+ /*
|
|
|
+ * If there's a fence, enforce that
|
|
|
+ * the fb modifier and tiling mode match.
|
|
|
+ */
|
|
|
+ if (tiling != I915_TILING_NONE &&
|
|
|
+ tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
|
|
|
DRM_DEBUG("tiling_mode doesn't match fb modifier\n");
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
} else {
|
|
|
- if (i915_gem_object_get_tiling(obj) == I915_TILING_X)
|
|
|
+ if (tiling == I915_TILING_X) {
|
|
|
mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED;
|
|
|
- else if (i915_gem_object_get_tiling(obj) == I915_TILING_Y) {
|
|
|
+ } else if (tiling == I915_TILING_Y) {
|
|
|
DRM_DEBUG("No Y tiling for legacy addfb\n");
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -15242,6 +15245,16 @@ static int intel_framebuffer_init(struct drm_device *dev,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * gen2/3 display engine uses the fence if present,
|
|
|
+ * so the tiling mode must match the fb modifier exactly.
|
|
|
+ */
|
|
|
+ if (INTEL_INFO(dev_priv)->gen < 4 &&
|
|
|
+ tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
|
|
|
+ DRM_DEBUG("tiling_mode must match fb modifier exactly on gen2/3\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
stride_alignment = intel_fb_stride_alignment(dev_priv,
|
|
|
mode_cmd->modifier[0],
|
|
|
mode_cmd->pixel_format);
|
|
@@ -15261,7 +15274,11 @@ static int intel_framebuffer_init(struct drm_device *dev,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- if (mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED &&
|
|
|
+ /*
|
|
|
+ * If there's a fence, enforce that
|
|
|
+ * the fb pitch and fence stride match.
|
|
|
+ */
|
|
|
+ if (tiling != I915_TILING_NONE &&
|
|
|
mode_cmd->pitches[0] != i915_gem_object_get_stride(obj)) {
|
|
|
DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n",
|
|
|
mode_cmd->pitches[0],
|