提交 f7abfe8b 编写于 作者: C Chris Wilson

drm/i915: Fix an overlay regression from 7e7d76c3

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: NChris Wilson <chris@chris-wilson.co.uk>
上级 6b383a7f
...@@ -1956,6 +1956,10 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) ...@@ -1956,6 +1956,10 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
int plane = intel_crtc->plane; int plane = intel_crtc->plane;
u32 reg, temp; u32 reg, temp;
if (intel_crtc->active)
return;
intel_crtc->active = true;
intel_update_watermarks(dev); intel_update_watermarks(dev);
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
...@@ -2116,6 +2120,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) ...@@ -2116,6 +2120,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
int plane = intel_crtc->plane; int plane = intel_crtc->plane;
u32 reg, temp; u32 reg, temp;
if (!intel_crtc->active)
return;
drm_vblank_off(dev, pipe); drm_vblank_off(dev, pipe);
intel_crtc_update_cursor(crtc, false); intel_crtc_update_cursor(crtc, false);
...@@ -2245,6 +2252,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) ...@@ -2245,6 +2252,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
POSTING_READ(reg); POSTING_READ(reg);
udelay(100); udelay(100);
intel_crtc->active = false;
intel_update_watermarks(dev); intel_update_watermarks(dev);
intel_update_fbc(dev); intel_update_fbc(dev);
intel_clear_scanline_wait(dev); intel_clear_scanline_wait(dev);
...@@ -2298,6 +2306,10 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) ...@@ -2298,6 +2306,10 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
int plane = intel_crtc->plane; int plane = intel_crtc->plane;
u32 reg, temp; u32 reg, temp;
if (intel_crtc->active)
return;
intel_crtc->active = true;
intel_update_watermarks(dev); intel_update_watermarks(dev);
/* Enable the DPLL */ /* Enable the DPLL */
...@@ -2354,6 +2366,9 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) ...@@ -2354,6 +2366,9 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
int plane = intel_crtc->plane; int plane = intel_crtc->plane;
u32 reg, temp; u32 reg, temp;
if (!intel_crtc->active)
return;
/* Give the overlay scaler a chance to disable if it's on this pipe */ /* Give the overlay scaler a chance to disable if it's on this pipe */
intel_crtc_dpms_overlay(intel_crtc, false); intel_crtc_dpms_overlay(intel_crtc, false);
intel_crtc_update_cursor(crtc, false); intel_crtc_update_cursor(crtc, false);
...@@ -2402,6 +2417,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) ...@@ -2402,6 +2417,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
} }
done: done:
intel_crtc->active = false;
intel_update_fbc(dev); intel_update_fbc(dev);
intel_update_watermarks(dev); intel_update_watermarks(dev);
intel_clear_scanline_wait(dev); intel_clear_scanline_wait(dev);
...@@ -3463,7 +3479,7 @@ static void intel_update_watermarks(struct drm_device *dev) ...@@ -3463,7 +3479,7 @@ static void intel_update_watermarks(struct drm_device *dev)
/* Get the clock config from both planes */ /* Get the clock config from both planes */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { if (intel_crtc->active) {
enabled++; enabled++;
if (intel_crtc->plane == 0) { if (intel_crtc->plane == 0) {
DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n",
......
...@@ -169,6 +169,7 @@ struct intel_crtc { ...@@ -169,6 +169,7 @@ struct intel_crtc {
enum plane plane; enum plane plane;
u8 lut_r[256], lut_g[256], lut_b[256]; u8 lut_r[256], lut_g[256], lut_b[256];
int dpms_mode; int dpms_mode;
bool active; /* is the crtc on? independent of the dpms mode */
bool busy; /* is scanout buffer being updated frequently? */ bool busy; /* is scanout buffer being updated frequently? */
struct timer_list idle_timer; struct timer_list idle_timer;
bool lowfreq_avail; bool lowfreq_avail;
......
...@@ -875,15 +875,13 @@ static int check_overlay_possible_on_crtc(struct intel_overlay *overlay, ...@@ -875,15 +875,13 @@ static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
struct intel_crtc *crtc) struct intel_crtc *crtc)
{ {
drm_i915_private_t *dev_priv = overlay->dev->dev_private; 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; return -EINVAL;
pipeconf = I915_READ(PIPECONF(crtc->pipe));
/* can't use the overlay with double wide 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 -EINVAL;
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册