[Intel-gfx] [PATCH 14/14] drm/i915: send one frame after enabling mipi cmd mode

Gaurav K Singh gaurav.k.singh at intel.com
Tue Sep 29 14:54:11 PDT 2015


If MIPI is operated in command mode, and after display reset. if
not even one frame is sent after enabling the pipe and then if it
is disabled, pipe is getting stuck. This patch will fix this issue
by sending one frame after enabling the pipe.

Ideally,there should not be a case where there is mode set and no frames
are sent.

Signed-off-by: Gaurav K Singh <gaurav.k.singh at intel.com>
Signed-off-by: Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu at intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   47 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h     |    6 +++++
 2 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5911a333..37757bb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -44,6 +44,7 @@
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_rect.h>
 #include <linux/dma_remapping.h>
+#include "intel_dsi.h"
 
 /* Primary plane formats for gen <= 3 */
 static const uint32_t i8xx_primary_formats[] = {
@@ -6016,6 +6017,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_encoder *encoder;
+	struct intel_dsi *intel_dsi;
 	int pipe = intel_crtc->pipe;
 	bool is_dsi;
 
@@ -6071,6 +6073,25 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		encoder->enable(encoder);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder) {
+		if (encoder->type != INTEL_OUTPUT_DSI)
+			continue;
+
+		intel_dsi = enc_to_intel_dsi(&encoder->base);
+		if (intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) {
+			/*
+			 * save the current pipe counter. During disable use
+			 * this variable to check if at least one frame has
+			 * been sent. If no frame is sent and MIPI is disabled
+			 * in command mode, then pipe gets stuck.
+			 */
+			intel_crtc->hw_frm_cnt_at_enable =
+						I915_READ(PIPEFRAME(pipe));
+		}
+		break;
+	}
+
 }
 
 static void i9xx_set_pll_dividers(struct intel_crtc *crtc)
@@ -6148,10 +6169,36 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_encoder *encoder;
+	struct intel_dsi *intel_dsi;
 	int pipe = intel_crtc->pipe;
 	bool all_pipe_disabled;
 	u32 val;
 
+	for_each_encoder_on_crtc(dev, crtc, encoder) {
+		if (encoder->type != INTEL_OUTPUT_DSI)
+			continue;
+
+		intel_dsi = enc_to_intel_dsi(&encoder->base);
+		if ((intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) &&
+				(intel_crtc->hw_frm_cnt_at_enable ==
+						I915_READ(PIPEFRAME(pipe)))) {
+
+			intel_dsi_update_panel_fb(encoder);
+
+			/*
+			 * wait for ~2 frames for TE interrupt and sending one
+			 * frame.
+			 */
+			msleep(40);
+
+			if (intel_crtc->hw_frm_cnt_at_enable ==
+						I915_READ(PIPEFRAME(pipe)))
+				DRM_ERROR("Pipe is stuck for DSI cmd mode.");
+		}
+
+		break;
+	}
+
 	/*
 	 * On gen2 planes are double buffered but the pipe isn't, so we must
 	 * wait for planes to fully turn off before disabling the pipe.
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 58fcd7d..9013f93 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -576,6 +576,12 @@ struct intel_crtc {
 	/* scalers available on this crtc */
 	int num_scalers;
 
+	/*
+	 * save the frame counter at enable sequence to make sure one frame has
+	 * been sent before disable sequence.
+	 */
+	u32 hw_frm_cnt_at_enable;
+
 	struct vlv_wm_state wm_state;
 };
 
-- 
1.7.9.5



More information about the Intel-gfx mailing list