diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 53be78e..c9363de 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -252,6 +252,11 @@ static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs, struct drm_i915_private *dev_priv = to_i915(dev); u32 mask; + if (WARN_ON((I915_READ(MIPI_INTR_EN(port)) & (1 << 30)) == 0)) { + I915_WRITE(MIPI_INTR_STAT(port), 0xffffffff); + I915_WRITE(MIPI_INTR_EN(port), 0xffffffff); + } + /* XXX: pipe, hs */ if (hs) cmd &= ~DPI_LP_MODE; @@ -346,12 +351,13 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, return true; } -static void glk_dsi_device_ready(struct intel_encoder *encoder) +static bool glk_dsi_device_ready_pre(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; - u32 tmp, val; + u32 tmp; + bool ret = false; /* Set the MIPI mode * If MIPI_Mode is off, then writing to LP_Wake bit is not reflecting. @@ -362,11 +368,13 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder) I915_WRITE(MIPI_CTRL(port), tmp | GLK_MIPIIO_ENABLE); } + /* Put the IO into reset */ tmp = I915_READ(MIPI_CTRL(PORT_A)); tmp &= ~GLK_MIPIIO_RESET_RELEASED; I915_WRITE(MIPI_CTRL(PORT_A), tmp); + /* Program LP Wake */ for_each_dsi_port(port, intel_dsi->ports) { tmp = I915_READ(MIPI_CTRL(port)); @@ -374,14 +382,27 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder) I915_WRITE(MIPI_CTRL(port), tmp); } + /* Wait for Pwr ACK */ for_each_dsi_port(port, intel_dsi->ports) { if (intel_wait_for_register(dev_priv, MIPI_CTRL(port), GLK_MIPIIO_PORT_POWERED, GLK_MIPIIO_PORT_POWERED, 20)) DRM_ERROR("MIPIO port is powergated\n"); + + ret |= !(I915_READ(MIPI_DEVICE_READY(port)) & DEVICE_READY); } + return ret; +} + +static void glk_dsi_device_ready_post(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; + u32 tmp, val; + /* Wait for MIPI PHY status bit to set */ for_each_dsi_port(port, intel_dsi->ports) { if (intel_wait_for_register(dev_priv, @@ -399,6 +420,7 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder) tmp |= HS_OVR_EN | HS_OVR_VALUE(0xa); I915_WRITE(DSI_PHY_DW6, val); + /* Get IO out of Low power state*/ for_each_dsi_port(port, intel_dsi->ports) { if (!(I915_READ(MIPI_DEVICE_READY(port)) & DEVICE_READY)) { @@ -437,6 +459,7 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder) I915_WRITE(MIPI_CTRL(port), tmp); } + /* Wait for Stop state */ for_each_dsi_port(port, intel_dsi->ports) { if (intel_wait_for_register(dev_priv, @@ -454,6 +477,12 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder) } } +static void glk_dsi_device_ready(struct intel_encoder *encoder) +{ + glk_dsi_device_ready_pre(encoder); + glk_dsi_device_ready_post(encoder); +} + static void bxt_dsi_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -805,6 +834,8 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, I915_WRITE(DSPCLK_GATE_D, val); } + DRM_DEBUG_KMS("calling dsi prepare\n"); + intel_dsi_prepare(encoder, pipe_config); /* Power on, try both CRC pmic gpio and VBT */ @@ -817,7 +848,13 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder, intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); /* Put device in ready state (LP-11) */ - intel_dsi_device_ready(encoder); + if(IS_GEMINILAKE(dev_priv)) { + if (glk_dsi_device_ready_pre(encoder)) + intel_dsi_prepare(encoder, pipe_config); + glk_dsi_device_ready_post(encoder); + } else { + intel_dsi_device_ready(encoder); + } /* Send initialization commands in LP mode */ intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); @@ -1401,10 +1438,14 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder, I915_WRITE(MIPI_CTRL(port), tmp); } + DRM_DEBUG_KMS("Enabling weird interrupts\n"); + /* XXX: why here, why like this? handling in irq handler?! */ I915_WRITE(MIPI_INTR_STAT(port), 0xffffffff); I915_WRITE(MIPI_INTR_EN(port), 0xffffffff); + WARN(I915_READ(MIPI_INTR_EN(port)) == 0, " DSI irq enabling didn't take!\n"); + I915_WRITE(MIPI_DPHY_PARAM(port), intel_dsi->dphy_reg); I915_WRITE(MIPI_DPI_RESOLUTION(port),