drm/i915: Fix an overlay regression from 7e7d76c
When separating out the prepare/commit into its own separate functions
we overlooked that the intel_crtc->dpms_mode was being used elsewhere to
check on the actual status of the pipe.
Track that bit of logic separately from the actual dpms mode, so there
is no confusion should we be able to handle multiple dpms modes, nor
any semantic conflict between prepare/commit and dpms.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1e2a17d..a54b701 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1956,6 +1956,10 @@
int plane = intel_crtc->plane;
u32 reg, temp;
+ if (intel_crtc->active)
+ return;
+
+ intel_crtc->active = true;
intel_update_watermarks(dev);
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
@@ -2116,6 +2120,9 @@
int plane = intel_crtc->plane;
u32 reg, temp;
+ if (!intel_crtc->active)
+ return;
+
drm_vblank_off(dev, pipe);
intel_crtc_update_cursor(crtc, false);
@@ -2245,6 +2252,7 @@
POSTING_READ(reg);
udelay(100);
+ intel_crtc->active = false;
intel_update_watermarks(dev);
intel_update_fbc(dev);
intel_clear_scanline_wait(dev);
@@ -2298,6 +2306,10 @@
int plane = intel_crtc->plane;
u32 reg, temp;
+ if (intel_crtc->active)
+ return;
+
+ intel_crtc->active = true;
intel_update_watermarks(dev);
/* Enable the DPLL */
@@ -2354,6 +2366,9 @@
int plane = intel_crtc->plane;
u32 reg, temp;
+ if (!intel_crtc->active)
+ return;
+
/* Give the overlay scaler a chance to disable if it's on this pipe */
intel_crtc_dpms_overlay(intel_crtc, false);
intel_crtc_update_cursor(crtc, false);
@@ -2402,6 +2417,7 @@
}
done:
+ intel_crtc->active = false;
intel_update_fbc(dev);
intel_update_watermarks(dev);
intel_clear_scanline_wait(dev);
@@ -3463,7 +3479,7 @@
/* Get the clock config from both planes */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) {
+ if (intel_crtc->active) {
enabled++;
if (intel_crtc->plane == 0) {
DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n",
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c0891b1..5171b05 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -169,6 +169,7 @@
enum plane plane;
u8 lut_r[256], lut_g[256], lut_b[256];
int dpms_mode;
+ bool active; /* is the crtc on? independent of the dpms mode */
bool busy; /* is scanout buffer being updated frequently? */
struct timer_list idle_timer;
bool lowfreq_avail;
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 3dff161..c4699c9 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -875,15 +875,13 @@
struct intel_crtc *crtc)
{
drm_i915_private_t *dev_priv = overlay->dev->dev_private;
- u32 pipeconf;
- if (!crtc->base.enabled || crtc->dpms_mode != DRM_MODE_DPMS_ON)
+ if (!crtc->active)
return -EINVAL;
- pipeconf = I915_READ(PIPECONF(crtc->pipe));
-
/* can't use the overlay with double wide pipe */
- if (!IS_I965G(overlay->dev) && pipeconf & PIPECONF_DOUBLE_WIDE)
+ if (!IS_I965G(overlay->dev) &&
+ (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE)
return -EINVAL;
return 0;