Reset the display hardware if video mode to command mode transition
has to be done in MIPI display. otherwise command mode will not work.

Signed-off-by: Yogesh Mohan Marimuthu <[email protected]>
Signed-off-by: Gaurav K Singh <[email protected]>
---
 drivers/gpu/drm/i915/i915_drv.h      |    1 +
 drivers/gpu/drm/i915/intel_display.c |   81 ++++++++++++++++++++++++++--------
 drivers/gpu/drm/i915/intel_dsi.c     |    4 ++
 3 files changed, 67 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6a66d6b..8c06377 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1854,6 +1854,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
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index fc84313..8dd0066 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6025,6 +6025,25 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
                encoder->enable(encoder);
 }
 
+/* Disable the VGA plane that we never use */
+static void i915_disable_vga(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u8 sr1;
+       u32 vga_reg = i915_vgacntrl_reg(dev);
+
+       /* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
+       vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
+       outb(SR01, VGA_SR_INDEX);
+       sr1 = inb(VGA_SR_DATA);
+       outb(sr1 | 1<<5, VGA_SR_DATA);
+       vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
+       udelay(300);
+
+       I915_WRITE(vga_reg, VGA_DISP_DISABLE);
+       POSTING_READ(vga_reg);
+}
+
 static void i9xx_pfit_disable(struct intel_crtc *crtc)
 {
        struct drm_device *dev = crtc->base.dev;
@@ -6047,6 +6066,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;
 
        if (!intel_crtc->active)
                return;
@@ -6091,6 +6112,47 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
        mutex_lock(&dev->struct_mutex);
        intel_fbc_update(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);
+       }
 }
 
 static void i9xx_crtc_off(struct drm_crtc *crtc)
@@ -14405,25 +14467,6 @@ static void intel_init_quirks(struct drm_device *dev)
        }
 }
 
-/* Disable the VGA plane that we never use */
-static void i915_disable_vga(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       u8 sr1;
-       u32 vga_reg = i915_vgacntrl_reg(dev);
-
-       /* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
-       vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
-       outb(SR01, VGA_SR_INDEX);
-       sr1 = inb(VGA_SR_DATA);
-       outb(sr1 | 1<<5, VGA_SR_DATA);
-       vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
-       udelay(300);
-
-       I915_WRITE(vga_reg, VGA_DISP_DISABLE);
-       POSTING_READ(vga_reg);
-}
-
 void intel_modeset_init_hw(struct drm_device *dev)
 {
        intel_prepare_ddi(dev);
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index fc552f1..e22c7ae 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -369,9 +369,13 @@ static void intel_dsi_port_disable(struct intel_encoder 
*encoder)
        enum port port;
        u32 temp;
 
+       dev_priv->video_disabled = false;
+
        for_each_dsi_port(port, intel_dsi->ports) {
                /* de-assert ip_tg_enable signal */
                if (is_cmd_mode(intel_dsi)) {
+                       if (I915_READ(MIPI_PORT_CTRL(port)) & DPI_ENABLE)
+                               dev_priv->video_disabled = true;
                        I915_WRITE(MIPI_PORT_CTRL(port), 0);
                } else {
                        temp = I915_READ(MIPI_PORT_CTRL(port));
-- 
1.7.9.5

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to