All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eugeni Dodonov <eugeni.dodonov@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: Eugeni Dodonov <eugeni.dodonov@intel.com>
Subject: [PATCH 34/41] drm/i915: perform Haswell DDI link training in FDI mode
Date: Thu, 29 Mar 2012 12:32:50 -0300	[thread overview]
Message-ID: <1333035177-19607-35-git-send-email-eugeni.dodonov@intel.com> (raw)
In-Reply-To: <1333035177-19607-1-git-send-email-eugeni.dodonov@intel.com>

This patch attempts at following the modeset sequence closely, retrying
with different voltages if the DP_TP_STATUS reports a failed training.

For training, we add a table of recommended settings for FDI, HDMI and DP
connections. For FDI and DP modes, we also add the HDMI buffer
translation as the last item. Those are ignored in such modes, so there is
no harm in having them set.

Initially, we use DDI E for FDI connectivity.  This is the suggested
configuration, and this seems to be what should work the best with FDI.

Note that we leave the DDI Function for corresponding pipe active when we
are done with the training. This ensures that we only need to enable pipe
afterwards to get a working modesetting, in a similar fashion as on
pre-HSW hardware. The modeset disabling sequence mentions a correct order
of disabling things, but this is out of scope of this patch and is being
done separately, for clearer distinction of what happens when.

v2: improve comments a bit, use PORT enums instead of hardcoded PORT_E
registers, split DDI buffers programming into a separate patch.

v1 Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com>
Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |  118 ++++++++++++++++++++++++++++++++++
 1 file changed, 118 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1fdcd56..09c18f8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2808,6 +2808,113 @@ static void intel_hsw_prepare_ddi_buffers(struct drm_device *dev)
 	hsw_prepare_ddi_buffers(dev, PORT_E, true);
 }
 
+static const long hsw_ddi_buf_ctl_values[] = {
+	DDI_BUF_EMP_400MV_0DB_HSW,
+	DDI_BUF_EMP_400MV_3_5DB_HSW,
+	DDI_BUF_EMP_400MV_6DB_HSW,
+	DDI_BUF_EMP_400MV_9_5DB_HSW,
+	DDI_BUF_EMP_600MV_0DB_HSW,
+	DDI_BUF_EMP_600MV_3_5DB_HSW,
+	DDI_BUF_EMP_600MV_6DB_HSW,
+	DDI_BUF_EMP_800MV_0DB_HSW,
+	DDI_BUF_EMP_800MV_3_5DB_HSW
+};
+
+
+/* Link training for HSW parts */
+static void hsw_fdi_link_train(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	u32 reg, temp, i;
+
+	/* Configure CPU PLL, wait for warmup */
+	I915_WRITE(SPLL_CTL,
+			SPLL_PLL_ENABLE |
+			SPLL_PLL_FREQ_1350MHz |
+			SPLL_PLL_SCC);
+
+	/* Use SPLL to drive the output when in FDI mode */
+	I915_WRITE(PORT_CLK_SEL(PORT_E),
+			PORT_CLK_SEL_SPLL);
+	I915_WRITE(PIPE_CLK_SEL(pipe),
+			PIPE_CLK_SEL_PORT(PORT_E));
+
+	udelay(20);
+
+	/* Start the training iterating through available voltages and emphasis */
+	for (i=0; i < ARRAY_SIZE(hsw_ddi_buf_ctl_values); i++) {
+		/* Configure DP_TP_CTL with auto-training */
+		I915_WRITE(DP_TP_CTL(PORT_E),
+					DP_TP_CTL_FDI_AUTOTRAIN |
+					DP_TP_CTL_ENHANCED_FRAME_ENABLE |
+					DP_TP_CTL_LINK_TRAIN_PAT1 |
+					DP_TP_CTL_ENABLE);
+
+		/* Configure and enable DDI_BUF_CTL for DDI E with next voltage */
+		temp = I915_READ(DDI_BUF_CTL(PORT_E));
+		temp = (temp & ~DDI_BUF_EMP_MASK);
+		I915_WRITE(DDI_BUF_CTL(PORT_E),
+				temp |
+				DDI_BUF_CTL_ENABLE |
+				DDI_PORT_WIDTH_X2 |
+				hsw_ddi_buf_ctl_values[i]);
+
+		udelay(600);
+
+		/* Enable CPU FDI Receiver with auto-training */
+		reg = FDI_RX_CTL(pipe);
+		I915_WRITE(reg,
+				I915_READ(reg) |
+					FDI_LINK_TRAIN_AUTO |
+					FDI_RX_ENABLE |
+					FDI_LINK_TRAIN_PATTERN_1_CPT |
+					FDI_RX_ENHANCE_FRAME_ENABLE |
+					LPT_FDI_PORT_WIDTH_2X |
+					FDI_RX_PLL_ENABLE);
+		POSTING_READ(reg);
+		udelay(100);
+
+		temp = I915_READ(DP_TP_STATUS(PORT_E));
+		if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
+			DRM_INFO("BUF_CTL training done on %d step\n", i);
+
+			/* Enable normal pixel sending for FDI */
+			I915_WRITE(DP_TP_CTL(PORT_E),
+						DP_TP_CTL_FDI_AUTOTRAIN |
+						DP_TP_CTL_LINK_TRAIN_NORMAL |
+						DP_TP_CTL_ENHANCED_FRAME_ENABLE |
+						DP_TP_CTL_ENABLE);
+
+			/* Enable PIPE_DDI_FUNC_CTL for the pipe to work in FDI mode */
+			temp = I915_READ(DDI_FUNC_CTL(pipe));
+			temp &= ~PIPE_DDI_PORT_MASK;
+			temp |= PIPE_DDI_SELECT_PORT(PORT_E) |
+					PIPE_DDI_MODE_SELECT_FDI |
+					PIPE_DDI_FUNC_ENABLE |
+					PIPE_DDI_PORT_WIDTH_X2;
+			I915_WRITE(DDI_FUNC_CTL(pipe),
+					temp);
+			break;
+		} else {
+			DRM_ERROR("Error training BUF_CTL %d\n", i);
+
+			/* Disable DP_TP_CTL and FDI_RX_CTL) and retry */
+			I915_WRITE(DP_TP_CTL(PORT_E),
+					I915_READ(DP_TP_CTL(PORT_E)) &
+						~DP_TP_CTL_ENABLE);
+			I915_WRITE(FDI_RX_CTL(pipe),
+					I915_READ(FDI_RX_CTL(pipe)) &
+						~FDI_RX_PLL_ENABLE);
+			continue;
+		}
+	}
+
+	DRM_DEBUG_KMS("FDI train done.\n");
+}
+
 /* Manual link training for Ivy Bridge A0 parts */
 static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
 {
@@ -9086,6 +9193,17 @@ static void intel_init_display(struct drm_device *dev)
 			}
 			dev_priv->display.init_clock_gating = ivybridge_init_clock_gating;
 			dev_priv->display.write_eld = ironlake_write_eld;
+		} else if (IS_HASWELL(dev)) {
+			dev_priv->display.fdi_link_train = hsw_fdi_link_train;
+			if (SNB_READ_WM0_LATENCY()) {
+				dev_priv->display.update_wm = sandybridge_update_wm;
+			} else {
+				DRM_DEBUG_KMS("Failed to read display plane latency. "
+					      "Disable CxSR\n");
+				dev_priv->display.update_wm = NULL;
+			}
+			dev_priv->display.init_clock_gating = ivybridge_init_clock_gating;
+			dev_priv->display.write_eld = ironlake_write_eld;
 		} else
 			dev_priv->display.update_wm = NULL;
 	} else if (IS_PINEVIEW(dev)) {
-- 
1.7.9.5

  parent reply	other threads:[~2012-03-29 16:01 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-29 15:32 [PATCH 00/41] [RFC] Haswell v2 Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 01/41] drm/i915: transform HAS_PCH_SPLIT in a feature check Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 02/41] drm/i915: add Haswell devices and their PCI IDs Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 03/41] drm/i915: hook Haswell devices in place Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 04/41] drm/i915: add support for LynxPoint PCH Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 05/41] drm/i915: add support for power wells Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 06/41] drm/i915: add enumeration for DDI ports Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 07/41] drm/i915: add DDI registers Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 08/41] drm/i915: add DP_TP_CTL registers Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 09/41] drm/i915: add DP_TP_STATUS registers Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 10/41] drm/i915: add definitions for DDI_BUF_CTL registers Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 11/41] drm/i915: add definition of DDI buffer translations regs Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 12/41] drm/i915: add definition of LPT FDI port width registers Eugeni Dodonov
2012-03-29 20:25   ` Daniel Vetter
2012-03-29 15:32 ` [PATCH 13/41] drm/i915: add SBI registers Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 14/41] drm/i915: add support for SBI ops Eugeni Dodonov
2012-03-29 20:27   ` Daniel Vetter
2012-03-29 15:32 ` [PATCH 15/41] drm/i915: add PIXCLK_GATE register Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 16/41] drm/i915: add S PLL control Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 17/41] drm/i915: add port clock selection support for HSW Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 18/41] drm/i915: add SSC offsets for SBI access Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 19/41] drm/i915: add LCPLL control registers Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 20/41] drm/i915: add WRPLL clocks Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 21/41] drm/i915: add WM_LINETIME registers Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 22/41] drm/i915: add SFUSE_STRAP registers for digital port detection Eugeni Dodonov
2012-03-29 20:35   ` Daniel Vetter
2012-03-29 15:32 ` [PATCH 23/41] drm/i915: calculate same watermarks on Haswell as on Ivy Bridge Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 24/41] drm/i915: share forcewaking code between IVB and HSW Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 25/41] drm/i915: haswell has 3 pipes as well Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 26/41] drm/i915: reuse Ivybridge interrupts code for Haswell Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 27/41] drm/i915: share pipe count handling with Ivybridge Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 28/41] drm/i915: share IVB cursor routine with Haswell Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 29/41] drm/i915: show unknown sdvox registers on hdmi init Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 30/41] drm/i915: enable power wells on haswell init Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 31/41] drm/i915: disable rc6 on haswell for now Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 32/41] drm/i915: program WM_LINETIME on Haswell Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 33/41] drm/i915: initialize DDI buffer translations Eugeni Dodonov
2012-03-29 15:32 ` Eugeni Dodonov [this message]
2012-03-29 15:32 ` [PATCH 35/41] drm/i915: disable pipe DDI function when disabling pipe Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 36/41] drm/i915: do not use fdi_normal_train on haswell Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 37/41] drm/i915: program iCLKIP on Lynx Point Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 38/41] drm/i915: detect digital outputs on Haswell Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 39/41] drm/i915: add support for DDI-controlled digital outputs Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 40/41] drm/i915: prepare HDMI link for Haswell Eugeni Dodonov
2012-03-29 15:32 ` [PATCH 41/41] drm/i915: add debugging bits for haswell modesetting Eugeni Dodonov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1333035177-19607-35-git-send-email-eugeni.dodonov@intel.com \
    --to=eugeni.dodonov@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.