From: Eugeni Dodonov <eugeni.dodonov@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: Eugeni Dodonov <eugeni.dodonov@intel.com>
Subject: [PATCH 03/21] drm/i915: Add DP Helper functions for Haswell
Date: Thu, 28 Jun 2012 15:55:31 -0300 [thread overview]
Message-ID: <1340909749-15249-4-git-send-email-eugeni.dodonov@intel.com> (raw)
In-Reply-To: <1340909749-15249-1-git-send-email-eugeni.dodonov@intel.com>
From: Shobhit Kumar <shobhit.kumar@intel.com>
Need to program new helpers for mode set and dpms as most of the stuff is done
using DDI port. The current commit uses SPLL clock for SCC enabled panel and
LCPLL for Non-SSC.
Also Haswell has LPT and DDIs are moved on CPU side and has DP_BUF_CTL and
DP_TP_CTL so added a new TP (Transport) holder as well along with DP in intel_dp
Main stream attributes have to be set explicitely from HSW onwrads. So
programmed the same.
Note that in DP mode the value of port width must match the one in the
DDI_BUF_CTL for the DDI port attached to the pipe.
Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com>
Signed-off-by: Sateesh Kavuri <sateesh.kavuri@intel.com>
Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 26 +++++-
drivers/gpu/drm/i915/intel_ddi.c | 167 +++++++++++++++++++++++++++++++++++++--
drivers/gpu/drm/i915/intel_dp.c | 18 ++++-
drivers/gpu/drm/i915/intel_drv.h | 8 ++
4 files changed, 210 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9dfc4c5..51398a8 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4289,6 +4289,7 @@
#define PIPE_DDI_BPC_6 (2<<20)
#define PIPE_DDI_BPC_12 (3<<20)
#define PIPE_DDI_BFI_ENABLE (1<<4)
+#define PIPE_DDI_PORT_WIDTH_MASK (7<<1)
#define PIPE_DDI_PORT_WIDTH_X1 (0<<1)
#define PIPE_DDI_PORT_WIDTH_X2 (1<<1)
#define PIPE_DDI_PORT_WIDTH_X4 (3<<1)
@@ -4335,6 +4336,7 @@
#define DDI_BUF_EMP_800MV_3_5DB_HSW (8<<24) /* Sel8 */
#define DDI_BUF_EMP_MASK (0xf<<24)
#define DDI_BUF_IS_IDLE (1<<7)
+#define DDI_PORT_WIDTH_MASK (7<<1)
#define DDI_PORT_WIDTH_X1 (0<<1)
#define DDI_PORT_WIDTH_X2 (1<<1)
#define DDI_PORT_WIDTH_X4 (3<<1)
@@ -4427,9 +4429,31 @@
#define LCPLL_CTL 0x130040
#define LCPLL_PLL_DISABLE (1<<31)
#define LCPLL_PLL_LOCK (1<<30)
-#define LCPLL_CD_CLOCK_DISABLE (1<<25)
+
+#define LCPLL_PLL_REFERENCE_BLK (2<<28)
+#define LCPLL_PLL_REFERENCE_SSC (3<<28)
+#define LCPLL_PLL_REFERENCE_NON_SSC (0<<28)
+#define LCPLL_PLL_REFERENCE_MASK (0x3<<28)
+
+#define LCPLL_CD_FREQ_SELECT_MASK (0x3<<26)
+#define LCPLL_CD_FREQ_450MHZ (0x0<<26)
+#define LCPLL_CD_FREQ_550MHZ (0x1<<26)
+
+#define LCPLL_CD_CLOCK_DISABLE (1<<25)
+#define LCPLL_ROOT_CD2X_CLOCK_DISABLE (1<<24)
#define LCPLL_CD2X_CLOCK_DISABLE (1<<23)
+#define HSW_MSA_CTL 0x60410
+#define HSW_MSA_SYNC_CLK (1<<0)
+#define HSW_MSA_DYNAMIC_RANGE (1<<3)
+#define HSW_MSA_COLORIMETRY (1<<4)
+#define HSW_MSA_BPC_MASK (7<<5)
+#define HSW_MSA_BPC_6_BITS (0<<5)
+#define HSW_MSA_BPC_8_BITS (1<<5)
+#define HSW_MSA_BPC_10_BITS (2<<5)
+#define HSW_MSA_BPC_12_BITS (3<<5)
+#define HSW_MSA_BPC_16_BITS (4<<5)
+
/* Pipe WM_LINETIME - watermark line time */
#define PIPE_WM_LINETIME_A 0x45270
#define PIPE_WM_LINETIME_B 0x45274
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index f33fe1a..91ed708 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -729,10 +729,159 @@ void intel_ddi_mode_set(struct drm_encoder *encoder,
intel_hdmi->set_infoframes(encoder, adjusted_mode);
}
+void
+intel_ddi_mode_set_dp(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct drm_crtc *crtc = intel_dp->base.base.crtc;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ int port = intel_dp->ddi_port;
+ int pipe = intel_crtc->pipe;
+ int port_width = PIPE_DDI_PORT_WIDTH_X1;
+ int temp;
+
+ DRM_DEBUG_KMS("Preparing DP DDI mode for Haswell on port %c, pipe %c\n",
+ port_name(port), pipe_name(pipe));
+
+ /* Turn on the eDP PLL if needed */
+ /* TBD: */
+
+ /*
+ * There are two kinds of DP registers in HSW:
+ * DDI CPU
+ * LPT PCH
+ */
+ /* Preserve the BIOS-computed detected bit. This is
+ * supposed to be read-only.
+ */
+ intel_dp->DP = I915_READ(DDI_BUF_CTL(intel_dp->ddi_port));
+ intel_dp->DP |= DDI_BUF_EMP_400MV_0DB_HSW;
+ intel_dp->TP = I915_READ(DP_TP_CTL(intel_dp->ddi_port));
+
+ intel_dp->DP &= ~(DDI_PORT_WIDTH_MASK);
+ switch (intel_dp->lane_count) {
+ case 1:
+ intel_dp->DP |= DDI_PORT_WIDTH_X1;
+ port_width = PIPE_DDI_PORT_WIDTH_X1;
+ break;
+ case 2:
+ intel_dp->DP |= DDI_PORT_WIDTH_X2;
+ port_width = PIPE_DDI_PORT_WIDTH_X2;
+ break;
+ case 4:
+ intel_dp->DP |= DDI_PORT_WIDTH_X4;
+ port_width = PIPE_DDI_PORT_WIDTH_X4;
+ break;
+ default:
+ BUG();
+ }
+
+ if (intel_dp->has_audio)
+ DRM_DEBUG_DRIVER("HSW DP Audio not yet supported\n");
+
+ memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
+ intel_dp->link_configuration[0] = intel_dp->link_bw;
+ intel_dp->link_configuration[1] = intel_dp->lane_count;
+ intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B;
+ /*
+ * Check for DPCD version > 1.1 and enhanced framing support
+ */
+ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+ (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) {
+ intel_dp->link_configuration[1] |=
+ DP_LANE_COUNT_ENHANCED_FRAME_EN;
+ }
+
+ /* Enable LCPLL if disabled; required in all cases */
+ temp = I915_READ(LCPLL_CTL);
+ if (temp & LCPLL_PLL_DISABLE) {
+ temp &= ~LCPLL_PLL_DISABLE;
+ temp &= ~LCPLL_CD2X_CLOCK_DISABLE;
+ temp &= ~LCPLL_ROOT_CD2X_CLOCK_DISABLE;
+ temp &= ~LCPLL_CD_CLOCK_DISABLE;
+ temp = (temp & ~LCPLL_CD_FREQ_SELECT_MASK) |
+ LCPLL_CD_FREQ_450MHZ;
+ I915_WRITE(LCPLL_CTL, temp);
+ udelay(20);
+ }
+
+ if (IS_HASWELL(dev)) {
+ if (intel_dp->link_configuration[1] &
+ DP_LANE_COUNT_ENHANCED_FRAME_EN)
+ intel_dp->TP |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
+
+ /* Set the MSA bits, since from HSW onwards,
+ * this has to be explictly set */
+ temp = I915_READ(HSW_MSA_CTL);
+ temp |= HSW_MSA_SYNC_CLK;
+ temp &= ~HSW_MSA_DYNAMIC_RANGE;
+ temp &= ~HSW_MSA_COLORIMETRY;
+ temp &= ~HSW_MSA_BPC_MASK;
+ temp |= HSW_MSA_BPC_8_BITS; /* Color depth */
+
+ I915_WRITE(HSW_MSA_CTL, temp);
+
+ if ((intel_dp->dpcd[DP_MAX_DOWNSPREAD] & 0x1) == 0x1) {
+ /* SSC Enabled Panel */
+ /* Configure SPLL, program the correct divider values
+ * for the desired frequency and wait for warmup */
+ I915_WRITE(SPLL_CTL,
+ SPLL_PLL_ENABLE |
+ SPLL_PLL_SCC |
+ SPLL_PLL_FREQ_1350MHz);
+ udelay(20);
+
+ /* Use SPLL clock to drive the output to the dp port,
+ * and tell the pipe to use this port for connection.
+ */
+ I915_WRITE(PORT_CLK_SEL(port),
+ PORT_CLK_SEL_SPLL);
+ I915_WRITE(PIPE_CLK_SEL(pipe),
+ PIPE_CLK_SEL_PORT(port));
+ } else {
+ /* Non SSC Panel */
+ /* configure LCPLL for NON-SSC */
+ temp = I915_READ(LCPLL_CTL);
+ temp = (temp & ~LCPLL_PLL_REFERENCE_MASK) |
+ LCPLL_PLL_REFERENCE_NON_SSC;
+ I915_WRITE(LCPLL_CTL, temp);
+ udelay(20);
+
+ /* Use LCPLL clock to drive the output to the dp port,
+ * and tell the pipe to use this port for connection.
+ */
+ I915_WRITE(PORT_CLK_SEL(port),
+ PORT_CLK_SEL_LCPLL_1350);
+ I915_WRITE(PIPE_CLK_SEL(pipe),
+ PIPE_CLK_SEL_PORT(port));
+ }
+
+ /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in DP mode */
+ temp = I915_READ(DDI_FUNC_CTL(pipe));
+ temp &= ~PIPE_DDI_PORT_MASK;
+ temp &= ~PIPE_DDI_BPC_12;
+ temp &= ~PIPE_DDI_PORT_WIDTH_MASK;
+ temp |= PIPE_DDI_SELECT_PORT(port) |
+ PIPE_DDI_MODE_SELECT_DP_SST |
+ port_width |
+ ((intel_crtc->bpp > 24) ?
+ PIPE_DDI_BPC_12 :
+ PIPE_DDI_BPC_8) |
+ PIPE_DDI_FUNC_ENABLE;
+
+ I915_WRITE(DDI_FUNC_CTL(pipe), temp);
+ }
+}
+
void intel_ddi_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
int port = intel_hdmi->ddi_port;
u32 temp;
@@ -745,10 +894,16 @@ void intel_ddi_dpms(struct drm_encoder *encoder, int mode)
temp |= DDI_BUF_CTL_ENABLE;
}
- /* 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),
- temp);
+ if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
+ DRM_DEBUG_DRIVER("DPMS is not yet enabled on DP port\n");
+ return;
+ } else {
+
+ /* 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),
+ temp);
+ }
}
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e324c7a..f4c6e98 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -74,7 +74,7 @@ static bool is_cpu_edp(struct intel_dp *intel_dp)
return is_edp(intel_dp) && !is_pch_edp(intel_dp);
}
-static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
+struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
{
return container_of(encoder, struct intel_dp, base.base);
}
@@ -2339,6 +2339,14 @@ static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
.commit = intel_dp_commit,
};
+static const struct drm_encoder_helper_funcs intel_dp_helper_funcs_hsw = {
+ .dpms = intel_ddi_dpms,
+ .mode_fixup = intel_dp_mode_fixup,
+ .prepare = intel_dp_prepare,
+ .mode_set = intel_ddi_mode_set_dp,
+ .commit = intel_dp_commit,
+};
+
static const struct drm_connector_funcs intel_dp_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = intel_dp_detect,
@@ -2482,7 +2490,13 @@ intel_dp_init(struct drm_device *dev, int output_reg)
drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs,
DRM_MODE_ENCODER_TMDS);
- drm_encoder_helper_add(&intel_encoder->base, &intel_dp_helper_funcs);
+
+ if (IS_HASWELL(dev))
+ drm_encoder_helper_add(&intel_encoder->base,
+ &intel_dp_helper_funcs_hsw);
+ else
+ drm_encoder_helper_add(&intel_encoder->base,
+ &intel_dp_helper_funcs);
intel_connector_attach_encoder(intel_connector, intel_encoder);
drm_sysfs_connector_add(connector);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 7cffb12..65b5b7c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -316,6 +316,7 @@ struct intel_dp {
struct intel_encoder base;
uint32_t output_reg;
uint32_t DP;
+ uint32_t TP;
uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE];
bool has_audio;
enum hdmi_force_audio force_audio;
@@ -390,6 +391,8 @@ extern void intel_mark_busy(struct drm_device *dev,
struct drm_i915_gem_object *obj);
extern bool intel_lvds_init(struct drm_device *dev);
extern void intel_dp_init(struct drm_device *dev, int dp_reg);
+extern struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder);
+
void
intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
@@ -534,5 +537,10 @@ extern void intel_ddi_dpms(struct drm_encoder *encoder, int mode);
extern void intel_ddi_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
+void
+intel_ddi_mode_set_dp(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+
#endif /* __INTEL_DRV_H__ */
--
1.7.11.1
next prev parent reply other threads:[~2012-06-28 18:54 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-28 18:55 [PATCH 00/21] More Haswell patches Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 01/21] drm/i915: Move DP structs to shared location Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 02/21] drm/i915: Add support for DDI control DP outputs Eugeni Dodonov
2012-06-28 18:55 ` Eugeni Dodonov [this message]
2012-06-28 18:55 ` [PATCH 04/21] drm/i915: Haswell specific code for the DP Link Training Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 05/21] drm/i915: Disable DDI Pipe Control on HSW while disabling pipe Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 06/21] drm/i915: Hook DP init in ddi module Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 07/21] drm/i915: re-initialize DDI buffer translations after resume Eugeni Dodonov
2012-07-04 20:07 ` Paulo Zanoni
2012-07-04 20:35 ` Daniel Vetter
2012-07-04 23:13 ` Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 08/21] drm/i915: simplify FDI RX check for LPT Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 09/21] drm/i915: account for only one transcoder on LPT Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 10/21] drm/i915: introduce lpt_enable_pch and cpt_enable_pch Eugeni Dodonov
2012-07-04 18:21 ` Paulo Zanoni
2012-07-06 20:47 ` Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 11/21] drm/i915: program FDI_RX TP and FDI delays Eugeni Dodonov
2012-07-04 21:15 ` Paulo Zanoni
2012-07-04 23:15 ` [PATCH 10/31] " Eugeni Dodonov
2012-07-05 12:58 ` Paulo Zanoni
2012-07-05 13:12 ` Daniel Vetter
2012-06-28 18:55 ` [PATCH 12/21] drm/i915: support Haswell-style force waking Eugeni Dodonov
2012-06-28 19:38 ` Daniel Vetter
2012-06-28 20:06 ` Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 13/21] drm/i915: add RPS configuration for Haswell Eugeni Dodonov
2012-06-29 9:56 ` Daniel Vetter
2012-06-29 13:49 ` Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 14/21] drm/i915: Add EDP Registers " Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 15/21] drm/i915: Timing initialization for eDP on HSW Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 16/21] drm/i915: Modesetting for eDP on HSw Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 17/21] drm/i915: Hook eDP initialization on DDI A Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 18/21] drm/i915: introduce haswell_init_clock_gating Eugeni Dodonov
2012-06-28 18:55 ` [PATCH 19/21] drm/i915: prevent bogus intel_update_fbc notifications Eugeni Dodonov
2012-06-28 19:24 ` Daniel Vetter
2012-06-28 20:11 ` Eugeni Dodonov
2012-07-04 17:41 ` Paulo Zanoni
2012-07-04 23:19 ` Eugeni Dodonov
2012-07-05 7:47 ` Daniel Vetter
2012-06-28 18:55 ` [PATCH 20/21] drm/i915: fix PIPE_WM_LINETIME definition Eugeni Dodonov
2012-06-28 19:39 ` Daniel Vetter
2012-06-28 18:55 ` [PATCH 21/21] drm/i915: enable RC6 workaround on Haswell Eugeni Dodonov
2012-06-28 19:23 ` Daniel Vetter
2012-06-28 20:10 ` Eugeni Dodonov
2012-06-28 19:22 ` [PATCH 00/21] More Haswell patches Paulo Zanoni
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=1340909749-15249-4-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox