diff mbox series

[10/12] drm/i915/icl: Unmask/Clear DSI TE interrupts

Message ID 1533730559-461-11-git-send-email-madhav.chauhan@intel.com (mailing list archive)
State New, archived
Headers show
Series ICL DSI CMD MODE | expand

Commit Message

Chauhan, Madhav Aug. 8, 2018, 12:15 p.m. UTC
While enabling DSI transcoder, TE interrupts need to
be unmasked also they need to be cleared when TE interrupts
are received. This patch does same by programming DSI interrupt
specific registers.

Signed-off-by: Madhav Chauhan <madhav.chauhan@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c |  2 ++
 drivers/gpu/drm/i915/icl_dsi.c  | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 8ca2396..b1e836a 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1897,6 +1897,8 @@  void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv,
 		DRM_ERROR("Invalid PIPE\n");
 	}
 
+	//TODO: Clear DSI interrupt here
+
 	drm_handle_vblank(&dev_priv->drm, pipe);
 }
 
diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c
index 0ae62a1..bd3cdde 100644
--- a/drivers/gpu/drm/i915/icl_dsi.c
+++ b/drivers/gpu/drm/i915/icl_dsi.c
@@ -66,6 +66,7 @@  void gen11_dsi_configure_te_interrupt(struct intel_encoder *encoder,
 	}
 }
 
+
 static void wait_for_dsi_hdr_credit_release(struct intel_dsi *intel_dsi,
 					    enum transcoder dsi_trans)
 {
@@ -96,6 +97,26 @@  static enum transcoder dsi_port_to_transcoder(enum port port)
 		return TRANSCODER_DSI_1;
 }
 
+static void gen11_dsi_clear_te_interrupt(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	u32 tmp;
+	enum port port;
+	enum transcoder dsi_trans;
+
+	for_each_dsi_port(port, intel_dsi->ports) {
+		dsi_trans = dsi_port_to_transcoder(port);
+		tmp = I915_READ(DSI_INTR_IDENT_REG(dsi_trans));
+		if (tmp & TE_EVENT) {
+			/* TE event received, clear it */
+			tmp |= TE_EVENT;
+			I915_WRITE(DSI_INTR_IDENT_REG(dsi_trans), tmp);
+		}
+	}
+
+}
+
 static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -666,11 +687,24 @@  static void gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
 			tmp &= ~OP_MODE_MASK;
 			tmp |= OP_MODE(CMD_MODE_TE_GATE);
 			tmp |= TE_SOURCE_GPIO;
+
 		}
 
 		I915_WRITE(DSI_TRANS_FUNC_CONF(dsi_trans), tmp);
 	}
 
+	if (intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) {
+
+		/* unmask and clear DSI TE interrupt */
+		for_each_dsi_port(port, intel_dsi->ports) {
+			dsi_trans = dsi_port_to_transcoder(port);
+			tmp = I915_READ(DSI_INTR_MASK_REG(dsi_trans));
+			tmp &= ~TE_EVENT;
+			I915_WRITE(DSI_INTR_MASK_REG(dsi_trans), tmp);
+		}
+		gen11_dsi_clear_te_interrupt(encoder);
+	}
+
 	/* enable port sync mode if dual link */
 	if (intel_dsi->dual_link) {
 		for_each_dsi_port(port, intel_dsi->ports) {