@@ -937,6 +937,7 @@ struct i915_fbc {
FBC_CHIP_DEFAULT, /* disabled by default on this chip */
FBC_ROTATION, /* rotation is not supported */
FBC_IN_DBG_MASTER, /* kernel debugger is active */
+ FBC_BAD_STRIDE, /* stride is not supported */
} no_fbc_reason;
bool (*fbc_enabled)(struct drm_i915_private *dev_priv);
@@ -501,6 +501,8 @@ const char *intel_no_fbc_reason_str(enum no_fbc_reason reason)
return "rotation unsupported";
case FBC_IN_DBG_MASTER:
return "Kernel debugger is active";
+ case FBC_BAD_STRIDE:
+ return "framebuffer stride not supported";
default:
MISSING_CASE(reason);
return "unknown reason";
@@ -694,6 +696,22 @@ static int intel_fbc_setup_cfb(struct drm_i915_private *dev_priv, int size,
return intel_fbc_alloc_cfb(dev_priv, size, fb_cpp);
}
+static bool stride_is_valid(unsigned int stride)
+{
+ /* TODO: we need to figure out what are the stride restrictions for the
+ * older platforms. */
+
+ /* These should have been caught earlier. */
+ WARN_ON(stride < 512);
+ WARN_ON((stride & (64 - 1)) != 0);
+
+ /* These are additional FBC restrictions. */
+ if (stride > 16385)
+ return false;
+
+ return true;
+}
+
/**
* __intel_fbc_update - enable/disable FBC as needed, unlocked
* @dev_priv: i915 device instance
@@ -804,6 +822,11 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
goto out_disable;
}
+ if (!stride_is_valid(fb->pitches[0])) {
+ set_no_fbc_reason(dev_priv, FBC_BAD_STRIDE);
+ goto out_disable;
+ }
+
/* If the kernel debugger is active, always disable compression */
if (in_dbg_master()) {
set_no_fbc_reason(dev_priv, FBC_IN_DBG_MASTER);