The Ivybridge eDP control register looks like a cross between a
Cougarpoint PCH DP control register and a Sandybridge eDP control
register.
Where things trivially match, share the code. Where there are any
tricky bits, just split things out into two obviously separate code paths.
Signed-off-by: Keith Packard kei...@keithp.com
---
drivers/gpu/drm/i915/i915_reg.h | 18 +
drivers/gpu/drm/i915/intel_dp.c | 151 ++-
2 files changed, 135 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b080cc8..43f27ad 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3447,6 +3447,24 @@
#define EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B (0x3822)
#define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f22)
+/* IVB */
+#define EDP_LINK_TRAIN_400MV_0DB_IVB (0x24 22)
+#define EDP_LINK_TRAIN_400MV_3_5DB_IVB (0x2a 22)
+#define EDP_LINK_TRAIN_400MV_6DB_IVB (0x2f 22)
+#define EDP_LINK_TRAIN_600MV_0DB_IVB (0x30 22)
+#define EDP_LINK_TRAIN_600MV_3_5DB_IVB (0x36 22)
+#define EDP_LINK_TRAIN_800MV_0DB_IVB (0x38 22)
+#define EDP_LINK_TRAIN_800MV_3_5DB_IVB (0x33 22)
+
+/* legacy values */
+#define EDP_LINK_TRAIN_500MV_0DB_IVB (0x00 22)
+#define EDP_LINK_TRAIN_1000MV_0DB_IVB (0x20 22)
+#define EDP_LINK_TRAIN_500MV_3_5DB_IVB (0x02 22)
+#define EDP_LINK_TRAIN_1000MV_3_5DB_IVB(0x22 22)
+#define EDP_LINK_TRAIN_1000MV_6DB_IVB (0x23 22)
+
+#define EDP_LINK_TRAIN_VOL_EMP_MASK_IVB (0x3f22)
+
#define FORCEWAKE 0xA18C
#define FORCEWAKE_ACK 0x130090
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index ec28aeb..f63c6b2 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -361,8 +361,8 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
* clock divider.
*/
if (is_cpu_edp(intel_dp)) {
- if (IS_GEN6(dev))
- aux_clock_divider = 200; /* SNB eDP input clock at
400Mhz */
+ if (IS_GEN6(dev) || IS_GEN7(dev))
+ aux_clock_divider = 200; /* SNB IVB eDP input clock
at 400Mhz */
else
aux_clock_divider = 225; /* eDP input clock at 450Mhz */
} else if (HAS_PCH_SPLIT(dev))
@@ -816,10 +816,11 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct
drm_display_mode *mode,
}
/*
-* There are three kinds of DP registers:
+* There are four kinds of DP registers:
*
* IBX PCH
-* CPU
+* SNB CPU
+* IVB CPU
* CPT PCH
*
* IBX PCH and CPU are the same for almost everything,
@@ -872,7 +873,26 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct
drm_display_mode *mode,
/* Split out the IBX/CPU vs CPT settings */
- if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
+ if (is_cpu_edp(intel_dp) IS_GEN7(dev)) {
+ if (adjusted_mode-flags DRM_MODE_FLAG_PHSYNC)
+ intel_dp-DP |= DP_SYNC_HS_HIGH;
+ if (adjusted_mode-flags DRM_MODE_FLAG_PVSYNC)
+ intel_dp-DP |= DP_SYNC_VS_HIGH;
+ intel_dp-DP |= DP_LINK_TRAIN_OFF_CPT;
+
+ if (intel_dp-link_configuration[1]
DP_LANE_COUNT_ENHANCED_FRAME_EN)
+ intel_dp-DP |= DP_ENHANCED_FRAMING;
+
+ intel_dp-DP |= intel_crtc-pipe 29;
+
+ /* don't miss out required setting for eDP */
+ intel_dp-DP |= DP_PLL_ENABLE;
+ if (adjusted_mode-clock 20)
+ intel_dp-DP |= DP_PLL_FREQ_160MHZ;
+ else
+ intel_dp-DP |= DP_PLL_FREQ_270MHZ;
+
+ } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
intel_dp-DP |= intel_dp-color_range;
if (adjusted_mode-flags DRM_MODE_FLAG_PHSYNC)
@@ -1374,34 +1394,60 @@ static char *link_train_names[] = {
* These are source-specific values; current Intel hardware supports
* a maximum voltage of 800mV and a maximum pre-emphasis of 6dB
*/
-#define I830_DP_VOLTAGE_MAXDP_TRAIN_VOLTAGE_SWING_800
-#define I830_DP_VOLTAGE_MAX_CPTDP_TRAIN_VOLTAGE_SWING_1200
static uint8_t
-intel_dp_pre_emphasis_max(uint8_t voltage_swing)
+intel_dp_voltage_max(struct intel_dp *intel_dp)
{
- switch (voltage_swing DP_TRAIN_VOLTAGE_SWING_MASK) {
- case DP_TRAIN_VOLTAGE_SWING_400:
- return DP_TRAIN_PRE_EMPHASIS_6;
- case DP_TRAIN_VOLTAGE_SWING_600:
- return DP_TRAIN_PRE_EMPHASIS_6;
- case DP_TRAIN_VOLTAGE_SWING_800:
- return DP_TRAIN_PRE_EMPHASIS_3_5;
- case DP_TRAIN_VOLTAGE_SWING_1200:
-