diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index aee83fa..9214119 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/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"); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 70e2527..ae859ae 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -216,6 +216,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 { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dfbdf88..0f0029d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1244,8 +1244,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; @@ -1263,10 +1267,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"); diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index c3c5052..866ad05 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -236,7 +236,7 @@ int intel_fbdev_destroy(struct drm_device *dev, drm_framebuffer_cleanup(&ifb->base); if (ifb->obj) - drm_gem_object_unreference_unlocked(ifb->obj); + drm_gem_object_unreference(ifb->obj); return 0; } diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 0eab8df..6bc313a 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -542,22 +542,14 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, /** * Detect the LVDS connection. * - * Since LVDS doesn't have hotlug, we use the lid as a proxy. Open means - * connected and closed means disconnected. We also send hotplug events as - * needed, using lid status notification from the input layer. + * Note: it would be nice to use lid state as a proxy here, but actual state is + * not widely available (either it doesn't exist or is broken on many platforms) + * so just return connector_status_connected at all times, since this function + * is only called if an LVDS display is detected at init time. */ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) { - struct drm_device *dev = connector->dev; - enum drm_connector_status status = connector_status_connected; - - /* ACPI lid methods were generally unreliable in this generation, so - * don't even bother. - */ - if (IS_GEN2(dev) || IS_GEN3(dev)) - return connector_status_connected; - - return status; + return connector_status_connected; } /**