drm/i915/bdw: add support for BDW DP voltage swings and pre-emphasis
authorPaulo Zanoni <paulo.r.zanoni@intel.com>
Sun, 3 Nov 2013 04:07:43 +0000 (21:07 -0700)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 8 Nov 2013 17:09:57 +0000 (18:09 +0100)
They're not the same as the Haswell ones.

Reviewed-by: Art Runyan <arthur.j.runyan@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Todd Previte <tprevite@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_dp.c

index 0b7983b87ce87bc155bdb943dd2e6e5712003201..ad903b927fb8bdef83d0edf75f1cc35c47c637f8 100644 (file)
 #define DDI_BUF_CTL_B                          0x64100
 #define DDI_BUF_CTL(port) _PORT(port, DDI_BUF_CTL_A, DDI_BUF_CTL_B)
 #define  DDI_BUF_CTL_ENABLE                    (1<<31)
+/* Haswell */
 #define  DDI_BUF_EMP_400MV_0DB_HSW             (0<<24)   /* Sel0 */
 #define  DDI_BUF_EMP_400MV_3_5DB_HSW           (1<<24)   /* Sel1 */
 #define  DDI_BUF_EMP_400MV_6DB_HSW             (2<<24)   /* Sel2 */
 #define  DDI_BUF_EMP_600MV_6DB_HSW             (6<<24)   /* Sel6 */
 #define  DDI_BUF_EMP_800MV_0DB_HSW             (7<<24)   /* Sel7 */
 #define  DDI_BUF_EMP_800MV_3_5DB_HSW           (8<<24)   /* Sel8 */
+/* Broadwell */
+#define  DDI_BUF_EMP_400MV_0DB_BDW             (0<<24)   /* Sel0 */
+#define  DDI_BUF_EMP_400MV_3_5DB_BDW           (1<<24)   /* Sel1 */
+#define  DDI_BUF_EMP_400MV_6DB_BDW             (2<<24)   /* Sel2 */
+#define  DDI_BUF_EMP_600MV_0DB_BDW             (3<<24)   /* Sel3 */
+#define  DDI_BUF_EMP_600MV_3_5DB_BDW           (4<<24)   /* Sel4 */
+#define  DDI_BUF_EMP_600MV_6DB_BDW             (5<<24)   /* Sel5 */
+#define  DDI_BUF_EMP_800MV_0DB_BDW             (6<<24)   /* Sel6 */
+#define  DDI_BUF_EMP_800MV_3_5DB_BDW           (7<<24)   /* Sel7 */
+#define  DDI_BUF_EMP_1200MV_0DB_BDW            (8<<24)   /* Sel8 */
 #define  DDI_BUF_EMP_MASK                      (0xf<<24)
 #define  DDI_BUF_PORT_REVERSAL                 (1<<16)
 #define  DDI_BUF_IS_IDLE                       (1<<7)
index 7619eae35b25626c8001f7415ec2631ad7dd53b5..f39856e12094a5f074fb059d7ea6c25c061dc68b 100644 (file)
@@ -1958,7 +1958,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
        enum port port = dp_to_dig_port(intel_dp)->port;
 
-       if (IS_VALLEYVIEW(dev))
+       if (IS_VALLEYVIEW(dev) || IS_BROADWELL(dev))
                return DP_TRAIN_VOLTAGE_SWING_1200;
        else if (IS_GEN7(dev) && port == PORT_A)
                return DP_TRAIN_VOLTAGE_SWING_800;
@@ -1974,7 +1974,18 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
        enum port port = dp_to_dig_port(intel_dp)->port;
 
-       if (HAS_DDI(dev)) {
+       if (IS_BROADWELL(dev)) {
+               switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+               case DP_TRAIN_VOLTAGE_SWING_400:
+               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:
+               default:
+                       return DP_TRAIN_PRE_EMPHASIS_0;
+               }
+       } else if (IS_HASWELL(dev)) {
                switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
                case DP_TRAIN_VOLTAGE_SWING_400:
                        return DP_TRAIN_PRE_EMPHASIS_9_5;
@@ -2286,6 +2297,41 @@ intel_hsw_signal_levels(uint8_t train_set)
        }
 }
 
+static uint32_t
+intel_bdw_signal_levels(uint8_t train_set)
+{
+       int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+                                        DP_TRAIN_PRE_EMPHASIS_MASK);
+       switch (signal_levels) {
+       case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0:
+               return DDI_BUF_EMP_400MV_0DB_BDW;       /* Sel0 */
+       case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5:
+               return DDI_BUF_EMP_400MV_3_5DB_BDW;     /* Sel1 */
+       case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6:
+               return DDI_BUF_EMP_400MV_6DB_BDW;       /* Sel2 */
+
+       case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0:
+               return DDI_BUF_EMP_600MV_0DB_BDW;       /* Sel3 */
+       case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5:
+               return DDI_BUF_EMP_600MV_3_5DB_BDW;     /* Sel4 */
+       case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_6:
+               return DDI_BUF_EMP_600MV_6DB_BDW;       /* Sel5 */
+
+       case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0:
+               return DDI_BUF_EMP_800MV_0DB_BDW;       /* Sel6 */
+       case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5:
+               return DDI_BUF_EMP_800MV_3_5DB_BDW;     /* Sel7 */
+
+       case DP_TRAIN_VOLTAGE_SWING_1200 | DP_TRAIN_PRE_EMPHASIS_0:
+               return DDI_BUF_EMP_1200MV_0DB_BDW;      /* Sel8 */
+
+       default:
+               DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
+                             "0x%x\n", signal_levels);
+               return DDI_BUF_EMP_400MV_0DB_BDW;       /* Sel0 */
+       }
+}
+
 /* Properly updates "DP" with the correct signal levels. */
 static void
 intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
@@ -2296,7 +2342,10 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
        uint32_t signal_levels, mask;
        uint8_t train_set = intel_dp->train_set[0];
 
-       if (HAS_DDI(dev)) {
+       if (IS_BROADWELL(dev)) {
+               signal_levels = intel_bdw_signal_levels(train_set);
+               mask = DDI_BUF_EMP_MASK;
+       } else if (IS_HASWELL(dev)) {
                signal_levels = intel_hsw_signal_levels(train_set);
                mask = DDI_BUF_EMP_MASK;
        } else if (IS_VALLEYVIEW(dev)) {