@@ -1954,6 +1954,7 @@ struct drm_i915_private {
} gt;
bool edp_low_vswing;
+ bool video_disabled;
/*
* NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
@@ -6149,6 +6149,8 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *encoder;
int pipe = intel_crtc->pipe;
+ bool all_pipe_disabled;
+ u32 val;
/*
* On gen2 planes are double buffered but the pipe isn't, so we must
@@ -15444,6 +15446,47 @@ void intel_modeset_cleanup(struct drm_device *dev)
mutex_lock(&dev->struct_mutex);
intel_cleanup_gt_powersave(dev);
mutex_unlock(&dev->struct_mutex);
+
+ all_pipe_disabled = true;
+ for_each_pipe(dev_priv, pipe) {
+ if ((I915_READ(PIPECONF(pipe)) &
+ PIPECONF_ENABLE) == PIPECONF_ENABLE)
+ all_pipe_disabled = false;
+ }
+
+ if ((all_pipe_disabled == true) &&
+ (dev_priv->video_disabled == true)) {
+
+ /*
+ * to switch from video mode to command mode, need to reset
+ * the display.
+ * FIXME: Even after resetting the display, the first modeset
+ * works sporadically(2 out of 3 times). Need to fix this.
+ * FIXME: Need to find a better way of doing this, because
+ * resetting the display resets all the registers in the
+ * display controller. Need to save and restore some of these
+ * required registers.
+ */
+ DRM_DEBUG_KMS("vid mode to cmd mode, reset display\n");
+ if (IS_CHERRYVIEW(dev)) {
+ val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+ val = val | DP_SSC_PWR_GATE(0);
+ vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
+
+ /* delay to power gate display controller */
+ mdelay(5);
+
+ val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+ val = val & ~((u32)DP_SSC_MASK(0));
+ vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
+
+ /* delay to power on display controller */
+ mdelay(10);
+ } else
+ DRM_ERROR("vid mode to cmd mode reset is not done.\n");
+
+ i915_disable_vga(dev_priv->dev);
+ }
}
/*
@@ -462,11 +462,15 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder)
u32 temp;
u32 port_ctrl;
+ dev_priv->video_disabled = false;
+
for_each_dsi_port(port, intel_dsi->ports) {
/* de-assert ip_tg_enable signal */
port_ctrl = IS_BROXTON(dev) ? BXT_MIPI_PORT_CTRL(port) :
MIPI_PORT_CTRL(port);
if (is_cmd_mode(intel_dsi)) {
+ if (I915_READ(MIPI_PORT_CTRL(port)) & DPI_ENABLE)
+ dev_priv->video_disabled = true;
I915_WRITE(port_ctrl, 0);
} else {
temp = I915_READ(port_ctrl);