浏览代码

drm/i915: disable FBC when more than one pipe is active

We're really supposed to do this to avoid trouble with underflows when
multiple planes are active.

Fixes https://bugs.freedesktop.org/show_bug.cgi?id=26987.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Tested-by: fangxun <xunx.fang@intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Jesse Barnes 15 年之前
父节点
当前提交
9c928d168d
共有 3 个文件被更改,包括 19 次插入0 次删除
  1. 3 0
      drivers/gpu/drm/i915/i915_debugfs.c
  2. 1 0
      drivers/gpu/drm/i915/i915_drv.h
  3. 15 0
      drivers/gpu/drm/i915/intel_display.c

+ 3 - 0
drivers/gpu/drm/i915/i915_debugfs.c

@@ -605,6 +605,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused)
 		case FBC_NOT_TILED:
 			seq_printf(m, "scanout buffer not tiled");
 			break;
+		case FBC_MULTIPLE_PIPES:
+			seq_printf(m, "multiple pipes are enabled");
+			break;
 		default:
 			seq_printf(m, "unknown reason");
 		}

+ 1 - 0
drivers/gpu/drm/i915/i915_drv.h

@@ -215,6 +215,7 @@ enum no_fbc_reason {
 	FBC_MODE_TOO_LARGE, /* mode too large for compression */
 	FBC_BAD_PLANE, /* fbc not supported on plane */
 	FBC_NOT_TILED, /* buffer not tiled */
+	FBC_MULTIPLE_PIPES, /* more than one pipe active */
 };
 
 enum intel_pch {

+ 15 - 0
drivers/gpu/drm/i915/intel_display.c

@@ -1180,8 +1180,12 @@ static void intel_update_fbc(struct drm_crtc *crtc,
 	struct drm_framebuffer *fb = crtc->fb;
 	struct intel_framebuffer *intel_fb;
 	struct drm_i915_gem_object *obj_priv;
+	struct drm_crtc *tmp_crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int plane = intel_crtc->plane;
+	int crtcs_enabled = 0;
+
+	DRM_DEBUG_KMS("\n");
 
 	if (!i915_powersave)
 		return;
@@ -1199,10 +1203,21 @@ static void intel_update_fbc(struct drm_crtc *crtc,
 	 * If FBC is already on, we just have to verify that we can
 	 * keep it that way...
 	 * Need to disable if:
+	 *   - more than one pipe is active
 	 *   - changing FBC params (stride, fence, mode)
 	 *   - new fb is too large to fit in compressed buffer
 	 *   - going to an unsupported config (interlace, pixel multiply, etc.)
 	 */
+	list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) {
+		if (tmp_crtc->enabled)
+			crtcs_enabled++;
+	}
+	DRM_DEBUG_KMS("%d pipes active\n", crtcs_enabled);
+	if (crtcs_enabled > 1) {
+		DRM_DEBUG_KMS("more than one pipe active, disabling compression\n");
+		dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES;
+		goto out_disable;
+	}
 	if (intel_fb->obj->size > dev_priv->cfb_size) {
 		DRM_DEBUG_KMS("framebuffer too large, disabling "
 				"compression\n");