From 00acb3293670afc767fd6ca3456d466db0212c05 Mon Sep 17 00:00:00 2001 From: Vandita Kulkarni Date: Thu, 24 Sep 2020 18:12:07 +0530 Subject: drm/i915/dsi: Add TE handler for dsi cmd mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case of dual link, we get the TE on slave. So clear the TE on slave DSI IIR. If we are operating in TE_GATE mode, after we do a frame update, the transcoder will send the frame data to the panel, after it receives a TE. Whereas if we are operating in NO_GATE mode then the transcoder will immediately send the frame data to the panel. We are not dealing with the periodic command mode here. v2: Pass only relevant masked bits to the handler (Jani) v3: Fix the check for cmd mode in TE handler function. v4: Use intel_handle_vblank instead of drm_handle_vblank (Jani) v3: Use static on handler func (Jani) Acked-by: Ville Syrjälä Signed-off-by: Vandita Kulkarni Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20200924124209.17916-4-vandita.kulkarni@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 65 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'drivers/gpu/drm/i915/i915_irq.c') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 350ddf379eac..6835b35729bd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2254,6 +2254,63 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) drm_err(&dev_priv->drm, "Unexpected DE Misc interrupt\n"); } +static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, + u32 te_trigger) +{ + enum pipe pipe = INVALID_PIPE; + enum transcoder dsi_trans; + enum port port; + u32 val, tmp; + + /* + * Incase of dual link, TE comes from DSI_1 + * this is to check if dual link is enabled + */ + val = I915_READ(TRANS_DDI_FUNC_CTL2(TRANSCODER_DSI_0)); + val &= PORT_SYNC_MODE_ENABLE; + + /* + * if dual link is enabled, then read DSI_0 + * transcoder registers + */ + port = ((te_trigger & DSI1_TE && val) || (te_trigger & DSI0_TE)) ? + PORT_A : PORT_B; + dsi_trans = (port == PORT_A) ? TRANSCODER_DSI_0 : TRANSCODER_DSI_1; + + /* Check if DSI configured in command mode */ + val = I915_READ(DSI_TRANS_FUNC_CONF(dsi_trans)); + val = val & OP_MODE_MASK; + + if (val != CMD_MODE_NO_GATE && val != CMD_MODE_TE_GATE) { + drm_err(&dev_priv->drm, "DSI trancoder not configured in command mode\n"); + return; + } + + /* Get PIPE for handling VBLANK event */ + val = I915_READ(TRANS_DDI_FUNC_CTL(dsi_trans)); + switch (val & TRANS_DDI_EDP_INPUT_MASK) { + case TRANS_DDI_EDP_INPUT_A_ON: + pipe = PIPE_A; + break; + case TRANS_DDI_EDP_INPUT_B_ONOFF: + pipe = PIPE_B; + break; + case TRANS_DDI_EDP_INPUT_C_ONOFF: + pipe = PIPE_C; + break; + default: + drm_err(&dev_priv->drm, "Invalid PIPE\n"); + return; + } + + intel_handle_vblank(dev_priv, pipe); + + /* clear TE in dsi IIR */ + port = (te_trigger & DSI1_TE) ? PORT_B : PORT_A; + tmp = I915_READ(DSI_INTR_IDENT_REG(port)); + I915_WRITE(DSI_INTR_IDENT_REG(port), tmp); +} + static irqreturn_t gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) { @@ -2318,6 +2375,14 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) found = true; } + if (INTEL_GEN(dev_priv) >= 11) { + tmp_mask = iir & (DSI0_TE | DSI1_TE); + if (tmp_mask) { + gen11_dsi_te_interrupt_handler(dev_priv, tmp_mask); + found = true; + } + } + if (!found) drm_err(&dev_priv->drm, "Unexpected DE Port interrupt\n"); -- cgit v1.2.3