[Intel-gfx] [PATCH 40/41] drm/i915: prepare HDMI link for Haswell
Eugeni Dodonov
eugeni.dodonov at intel.com
Thu Mar 29 17:32:56 CEST 2012
On Haswell, we need to properly train the DDI buffers prior to enabling
HDMI.
Note that we do enable the DDI Function for the corresponding pipe, in a
similar fashion as we do with FDI. This ensures that the pipe DDI
transport is left in a almost-ready state, and we only need to enable the
pipe afterwards to get a working modesetting.
Signed-off-by: Eugeni Dodonov <eugeni.dodonov at intel.com>
---
drivers/gpu/drm/i915/intel_hdmi.c | 63 ++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 6921756..480f54b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -324,6 +324,67 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
return true;
}
+static void intel_hdmi_prepare(struct drm_encoder *encoder)
+{
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = encoder->crtc;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+ int port = intel_hdmi->ddi_port;
+ int pipe = intel_crtc->pipe;
+ u32 reg, temp;
+
+ /* On Haswell, we need to enable the clocks and prepare DDI function to
+ * work in HDMI mode for this pipe.
+ */
+ if (IS_HASWELL(encoder->dev)) {
+ DRM_DEBUG_KMS("Preparing HDMI DDI mode for Haswell on port %c, pipe %c\n", port_name(port), pipe_name(pipe));
+
+ /* Enable LCPLL if disabled */
+ reg = I915_READ(LCPLL_CTL);
+ if (reg & LCPLL_PLL_DISABLE)
+ I915_WRITE(LCPLL_CTL,
+ reg & ~LCPLL_PLL_DISABLE);
+
+ /* Configure CPU PLL, wait for warmup */
+ I915_WRITE(WRPLL_CTL1,
+ WRPLL_PLL_ENABLE |
+ WRPLL_PLL_SELECT_LCPLL_2700);
+
+ udelay(20);
+
+ /* Use WRPLL1 clock to drive the output to the port, and tell the pipe to use
+ * this port for connection.
+ */
+ I915_WRITE(PORT_CLK_SEL(port),
+ PORT_CLK_SEL_WRPLL1);
+ I915_WRITE(PIPE_CLK_SEL(pipe),
+ PIPE_CLK_SEL_PORT(port));
+
+ udelay(20);
+
+ /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in HDMI mode */
+ temp = I915_READ(DDI_FUNC_CTL(pipe));
+ temp &= ~PIPE_DDI_PORT_MASK;
+ temp |= PIPE_DDI_SELECT_PORT(port) |
+ PIPE_DDI_MODE_SELECT_HDMI |
+ PIPE_DDI_FUNC_ENABLE;
+ I915_WRITE(DDI_FUNC_CTL(pipe),
+ temp);
+
+ /* Enable DDI_BUF_CTL. In HDMI/DVI mode, the port width,
+ * and swing/emphasis values are ignored so nothing special needs
+ * to be done besides enabling the port.
+ */
+ I915_WRITE(DDI_BUF_CTL(port),
+ I915_READ(DDI_BUF_CTL(port)) |
+ DDI_BUF_CTL_ENABLE);
+ }
+
+ return intel_encoder_prepare(encoder);
+}
+
static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector, bool force)
{
@@ -457,7 +518,7 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
.dpms = intel_hdmi_dpms,
.mode_fixup = intel_hdmi_mode_fixup,
- .prepare = intel_encoder_prepare,
+ .prepare = intel_hdmi_prepare,
.mode_set = intel_hdmi_mode_set,
.commit = intel_encoder_commit,
};
--
1.7.9.5
More information about the Intel-gfx
mailing list