xf86-video-ati: Branch 'master'

Jerome Glisse glisse at kemper.freedesktop.org
Wed Jan 26 13:55:33 PST 2011


 src/atombios_output.c |  402 +++++++++++++++++++++++++-------------------------
 1 file changed, 208 insertions(+), 194 deletions(-)

New commits:
commit f58e1354b78bf6b70120bddfe1566da3b0723f72
Author: Jerome Glisse <jglisse at redhat.com>
Date:   Wed Jan 26 16:13:30 2011 -0500

    dp: fix displayport support by syncing with KMS code
    
    Warning the dp clock value are divided by 10 in ddx (10 times
    bigger than kernel value) this is somethings very picky.
    
    Signed-off-by: Jerome Glisse <jglisse at redhat.com>

diff --git a/src/atombios_output.c b/src/atombios_output.c
index cad506e..af0e59a 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -65,7 +65,114 @@ const char *device_name[12] = {
     "DFP5",
 };
 
+#define AUX_NATIVE_WRITE                    0x8
+#define AUX_NATIVE_READ                     0x9
+
+#define AUX_I2C_WRITE                       0x0
+#define AUX_I2C_READ                        0x1
+#define AUX_I2C_STATUS                      0x2
+#define AUX_I2C_MOT                         0x4
+
+#define DP_DPCD_REV                         0x0
+#define DP_MAX_LINK_RATE                    0x1
+#define DP_MAX_LANE_COUNT                   0x2
+#define DP_MAX_DOWNSPREAD                   0x3
+#define DP_NORP                             0x4
+#define DP_DOWNSTREAMPORT_PRESENT           0x5
+#define DP_MAIN_LINK_CHANNEL_CONFIG         0x6
+#define DP_DP11_DOWNSTREAM_PORT_COUNT       0x7
+
+/* from intel i830_dp.h */
+#define DP_LINK_BW_SET                      0x100
+//# define DP_LINK_BW_1_62                    0x06
+//# define DP_LINK_BW_2_7                     0x0a
+#define DP_LANE_COUNT_SET                   0x101
+# define DP_LANE_COUNT_MASK                 0x0f
+# define DP_LANE_COUNT_ENHANCED_FRAME_EN    (1 << 7)
+
+#define DP_TRAINING_PATTERN_SET             0x102
+
+# define DP_TRAINING_PATTERN_DISABLE        0
+# define DP_TRAINING_PATTERN_1              1
+# define DP_TRAINING_PATTERN_2              2
+# define DP_TRAINING_PATTERN_MASK           0x3
+
+# define DP_LINK_QUAL_PATTERN_DISABLE       (0 << 2)
+# define DP_LINK_QUAL_PATTERN_D10_2         (1 << 2)
+# define DP_LINK_QUAL_PATTERN_ERROR_RATE    (2 << 2)
+# define DP_LINK_QUAL_PATTERN_PRBS7         (3 << 2)
+# define DP_LINK_QUAL_PATTERN_MASK          (3 << 2)
+# define DP_RECOVERED_CLOCK_OUT_EN          (1 << 4)
+# define DP_LINK_SCRAMBLING_DISABLE         (1 << 5)
+
+# define DP_SYMBOL_ERROR_COUNT_BOTH         (0 << 6)
+# define DP_SYMBOL_ERROR_COUNT_DISPARITY    (1 << 6)
+# define DP_SYMBOL_ERROR_COUNT_SYMBOL       (2 << 6)
+# define DP_SYMBOL_ERROR_COUNT_MASK         (3 << 6)
+
+#define DP_TRAINING_LANE0_SET               0x103
+#define DP_TRAINING_LANE1_SET               0x104
+#define DP_TRAINING_LANE2_SET               0x105
+#define DP_TRAINING_LANE3_SET               0x106
+# define DP_TRAIN_VOLTAGE_SWING_MASK        0x3
+# define DP_TRAIN_VOLTAGE_SWING_SHIFT       0
+# define DP_TRAIN_MAX_SWING_REACHED         (1 << 2)
+# define DP_TRAIN_VOLTAGE_SWING_400         (0 << 0)
+# define DP_TRAIN_VOLTAGE_SWING_600         (1 << 0)
+# define DP_TRAIN_VOLTAGE_SWING_800         (2 << 0)
+# define DP_TRAIN_VOLTAGE_SWING_1200        (3 << 0)
+
+# define DP_TRAIN_PRE_EMPHASIS_MASK         (3 << 3)
+# define DP_TRAIN_PRE_EMPHASIS_0            (0 << 3)
+# define DP_TRAIN_PRE_EMPHASIS_3_5          (1 << 3)
+# define DP_TRAIN_PRE_EMPHASIS_6            (2 << 3)
+# define DP_TRAIN_PRE_EMPHASIS_9_5          (3 << 3)
+
+# define DP_TRAIN_PRE_EMPHASIS_SHIFT        3
+# define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED  (1 << 5)
+#define DP_DOWNSPREAD_CTRL                  0x107
+# define DP_SPREAD_AMP_0_5                  (1 << 4)
+
+#define DP_MAIN_LINK_CHANNEL_CODING_SET     0x108
+# define DP_SET_ANSI_8B10B                  (1 << 0)
+
+#define DP_LANE0_1_STATUS                   0x202
+#define DP_LANE2_3_STATUS                   0x203
+
+# define DP_LANE_CR_DONE                    (1 << 0)
+# define DP_LANE_CHANNEL_EQ_DONE            (1 << 1)
+# define DP_LANE_SYMBOL_LOCKED              (1 << 2)
+
+#define DP_LANE_ALIGN_STATUS_UPDATED        0x204
+#define DP_INTERLANE_ALIGN_DONE             (1 << 0)
+#define DP_DOWNSTREAM_PORT_STATUS_CHANGED   (1 << 6)
+#define DP_LINK_STATUS_UPDATED              (1 << 7)
+
+#define DP_SINK_STATUS                      0x205
+
+#define DP_RECEIVE_PORT_0_STATUS            (1 << 0)
+#define DP_RECEIVE_PORT_1_STATUS            (1 << 1)
+
+#define DP_ADJUST_REQUEST_LANE0_1           0x206
+#define DP_ADJUST_REQUEST_LANE2_3           0x207
+
+#define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK  0x03
+#define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0
+#define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK   0x0c
+#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT  2
+#define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK  0x30
+#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4
+#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK   0xc0
+#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT  6
+
+#define DP_LINK_STATUS_SIZE                 6
+#define DP_LINK_CONFIGURATION_SIZE          9
+
+#define DP_SET_POWER_D0  0x1
+#define DP_SET_POWER_D3  0x2
+
 static void do_displayport_link_train(xf86OutputPtr output);
+static void atombios_pick_dig_encoder(xf86OutputPtr output);
 
 static int
 atombios_output_dac_setup(xf86OutputPtr output, int action)
@@ -487,40 +594,68 @@ static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int);
 
 # define DP_LINK_BW_1_62                    0x06
 # define DP_LINK_BW_2_7                     0x0a
+static int radeon_dp_max_lane_count(xf86OutputPtr output);
 
 static int
-dp_lanes_for_mode_clock(RADEONOutputPrivatePtr radeon_output,
-			int mode_clock)
+dp_lanes_for_mode_clock(xf86OutputPtr output, int mode_clock)
 {
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int i;
     int max_link_bw = radeon_output->dpcd[1];
+    int max_lane_count = radeon_dp_max_lane_count(output);
 
     switch (max_link_bw) {
     case DP_LINK_BW_1_62:
     default:
 	for (i = 0; i < num_dp_clocks; i++) {
-	    if (i % 2)
-		continue;
-	    if (dp_clocks[i] > (mode_clock / 10)) {
-		if (i < 2)
-		    return 1;
-		else if (i < 4)
-		    return 2;
-		else
-		    return 4;
-	    }
+		if (i % 2)
+			continue;
+		switch (max_lane_count) {
+		case 1:
+			if (i > 1)
+				return 0;
+			break;
+		case 2:
+			if (i > 3)
+				return 0;
+			break;
+		case 4:
+		default:
+			break;
+		}
+		if (dp_clocks[i] > (mode_clock/10)) {
+			if (i < 2)
+				return 1;
+			else if (i < 4)
+				return 2;
+			else
+				return 4;
+		}
 	}
 	break;
     case DP_LINK_BW_2_7:
 	for (i = 0; i < num_dp_clocks; i++) {
-	    if (dp_clocks[i] > (mode_clock / 10)) {
-		if (i < 2)
-		    return 1;
-		else if (i < 4)
-		    return 2;
-		else
-		    return 4;
-	    }
+		switch (max_lane_count) {
+		case 1:
+			if (i > 1)
+				return 0;
+			break;
+		case 2:
+			if (i > 3)
+				return 0;
+			break;
+		case 4:
+		default:
+			break;
+		}
+		if (dp_clocks[i] > (mode_clock/10)) {
+			if (i < 2)
+				return 1;
+			else if (i < 4)
+				return 2;
+			else
+				return 4;
+		}
 	}
         break;
     }
@@ -529,21 +664,54 @@ dp_lanes_for_mode_clock(RADEONOutputPrivatePtr radeon_output,
 }
 
 static int
-dp_link_clock_for_mode_clock(RADEONOutputPrivatePtr radeon_output,
-			     int mode_clock)
+dp_link_clock_for_mode_clock(xf86OutputPtr output, int mode_clock)
 {
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int i;
     int max_link_bw = radeon_output->dpcd[1];
+    int max_lane_count = radeon_dp_max_lane_count(output);
 
     switch (max_link_bw) {
     case DP_LINK_BW_1_62:
     default:
-	return 16200;
+	for (i = 0; i < num_dp_clocks; i++) {
+		if (i % 2)
+			continue;
+		switch (max_lane_count) {
+		case 1:
+			if (i > 1)
+				return 0;
+			break;
+		case 2:
+			if (i > 3)
+				return 0;
+			break;
+		case 4:
+		default:
+			break;
+		}
+		if (dp_clocks[i] > (mode_clock/10))
+			return 16200;
+	}
 	break;
     case DP_LINK_BW_2_7:
-	for (i = 0; i < num_dp_clocks; i++)
-	    if (dp_clocks[i] > (mode_clock / 10))
-		return (i % 2) ? 27000 : 16200;
+	for (i = 0; i < num_dp_clocks; i++) {
+		switch (max_lane_count) {
+		case 1:
+			if (i > 1)
+				return 0;
+			break;
+		case 2:
+			if (i > 3)
+				return 0;
+			break;
+		case 4:
+		default:
+			break;
+		}
+		if (dp_clocks[i] > (mode_clock/10))
+			return (i % 2) ? 27000 : 16200;
+	}
         break;
     }
 
@@ -624,9 +792,9 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, int action)
     disp_data.v1.ucEncoderMode = atombios_get_encoder_mode(output);
 
     if (disp_data.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
-	if (dp_link_clock_for_mode_clock(radeon_output, clock) == 27000)
+	if (dp_link_clock_for_mode_clock(output, clock) == 27000)
 	    disp_data.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
-	disp_data.v1.ucLaneNum = dp_lanes_for_mode_clock(radeon_output, clock);
+	disp_data.v1.ucLaneNum = dp_lanes_for_mode_clock(output, clock);
     } else if (clock > 165000)
 	disp_data.v1.ucLaneNum = 8;
     else
@@ -716,7 +884,7 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int action, uint8_t
     } else {
 	if (radeon_output->MonType == MT_DP) 
 	    disp_data.v1.usPixelClock =
-		cpu_to_le16(dp_link_clock_for_mode_clock(radeon_output, clock));
+		cpu_to_le16(dp_link_clock_for_mode_clock(output, clock));
 	else if (clock > 165000)
 	    disp_data.v1.usPixelClock = cpu_to_le16((clock / 2) / 10);
 	else
@@ -725,7 +893,7 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int action, uint8_t
 
     if (IS_DCE4_VARIANT) {
 	if (radeon_output->MonType == MT_DP)
-	    disp_data.v3.ucLaneNum = dp_lanes_for_mode_clock(radeon_output, clock);
+	    disp_data.v3.ucLaneNum = dp_lanes_for_mode_clock(output, clock);
 	else if (clock > 165000)
 	    disp_data.v3.ucLaneNum = 8;
 	else
@@ -1301,6 +1469,7 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
 
     if (radeon_encoder == NULL)
         return;
+    atombios_pick_dig_encoder(output);
 
     switch (radeon_encoder->encoder_id) {
     case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
@@ -1887,111 +2056,6 @@ atombios_dac_detect(xf86OutputPtr output)
     return MonType;
 }
 
-#define AUX_NATIVE_WRITE                    0x8
-#define AUX_NATIVE_READ                     0x9
-
-#define AUX_I2C_WRITE                       0x0
-#define AUX_I2C_READ                        0x1
-#define AUX_I2C_STATUS                      0x2
-#define AUX_I2C_MOT                         0x4
-
-#define DP_DPCD_REV                         0x0
-#define DP_MAX_LINK_RATE                    0x1
-#define DP_MAX_LANE_COUNT                   0x2
-#define DP_MAX_DOWNSPREAD                   0x3
-#define DP_NORP                             0x4
-#define DP_DOWNSTREAMPORT_PRESENT           0x5
-#define DP_MAIN_LINK_CHANNEL_CONFIG         0x6
-#define DP_DP11_DOWNSTREAM_PORT_COUNT       0x7
-
-/* from intel i830_dp.h */
-#define DP_LINK_BW_SET                      0x100
-//# define DP_LINK_BW_1_62                    0x06
-//# define DP_LINK_BW_2_7                     0x0a
-#define DP_LANE_COUNT_SET                   0x101
-# define DP_LANE_COUNT_MASK                 0x0f
-# define DP_LANE_COUNT_ENHANCED_FRAME_EN    (1 << 7)
-
-#define DP_TRAINING_PATTERN_SET             0x102
-
-# define DP_TRAINING_PATTERN_DISABLE        0
-# define DP_TRAINING_PATTERN_1              1
-# define DP_TRAINING_PATTERN_2              2
-# define DP_TRAINING_PATTERN_MASK           0x3
-
-# define DP_LINK_QUAL_PATTERN_DISABLE       (0 << 2)
-# define DP_LINK_QUAL_PATTERN_D10_2         (1 << 2)
-# define DP_LINK_QUAL_PATTERN_ERROR_RATE    (2 << 2)
-# define DP_LINK_QUAL_PATTERN_PRBS7         (3 << 2)
-# define DP_LINK_QUAL_PATTERN_MASK          (3 << 2)
-# define DP_RECOVERED_CLOCK_OUT_EN          (1 << 4)
-# define DP_LINK_SCRAMBLING_DISABLE         (1 << 5)
-
-# define DP_SYMBOL_ERROR_COUNT_BOTH         (0 << 6)
-# define DP_SYMBOL_ERROR_COUNT_DISPARITY    (1 << 6)
-# define DP_SYMBOL_ERROR_COUNT_SYMBOL       (2 << 6)
-# define DP_SYMBOL_ERROR_COUNT_MASK         (3 << 6)
-
-#define DP_TRAINING_LANE0_SET               0x103
-#define DP_TRAINING_LANE1_SET               0x104
-#define DP_TRAINING_LANE2_SET               0x105
-#define DP_TRAINING_LANE3_SET               0x106
-# define DP_TRAIN_VOLTAGE_SWING_MASK        0x3
-# define DP_TRAIN_VOLTAGE_SWING_SHIFT       0
-# define DP_TRAIN_MAX_SWING_REACHED         (1 << 2)
-# define DP_TRAIN_VOLTAGE_SWING_400         (0 << 0)
-# define DP_TRAIN_VOLTAGE_SWING_600         (1 << 0)
-# define DP_TRAIN_VOLTAGE_SWING_800         (2 << 0)
-# define DP_TRAIN_VOLTAGE_SWING_1200        (3 << 0)
-
-# define DP_TRAIN_PRE_EMPHASIS_MASK         (3 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_0            (0 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_3_5          (1 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_6            (2 << 3)
-# define DP_TRAIN_PRE_EMPHASIS_9_5          (3 << 3)
-
-# define DP_TRAIN_PRE_EMPHASIS_SHIFT        3
-# define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED  (1 << 5)
-#define DP_DOWNSPREAD_CTRL                  0x107
-# define DP_SPREAD_AMP_0_5                  (1 << 4)
-
-#define DP_MAIN_LINK_CHANNEL_CODING_SET     0x108
-# define DP_SET_ANSI_8B10B                  (1 << 0)
-
-#define DP_LANE0_1_STATUS                   0x202
-#define DP_LANE2_3_STATUS                   0x203
-
-# define DP_LANE_CR_DONE                    (1 << 0)
-# define DP_LANE_CHANNEL_EQ_DONE            (1 << 1)
-# define DP_LANE_SYMBOL_LOCKED              (1 << 2)
-
-#define DP_LANE_ALIGN_STATUS_UPDATED        0x204
-#define DP_INTERLANE_ALIGN_DONE             (1 << 0)
-#define DP_DOWNSTREAM_PORT_STATUS_CHANGED   (1 << 6)
-#define DP_LINK_STATUS_UPDATED              (1 << 7)
-
-#define DP_SINK_STATUS                      0x205
-
-#define DP_RECEIVE_PORT_0_STATUS            (1 << 0)
-#define DP_RECEIVE_PORT_1_STATUS            (1 << 1)
-
-#define DP_ADJUST_REQUEST_LANE0_1           0x206
-#define DP_ADJUST_REQUEST_LANE2_3           0x207
-
-#define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK  0x03
-#define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0
-#define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK   0x0c
-#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT  2
-#define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK  0x30
-#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4
-#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK   0xc0
-#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT  6
-
-#define DP_LINK_STATUS_SIZE                 6
-#define DP_LINK_CONFIGURATION_SIZE          9
-
-#define DP_SET_POWER_D0  0x1
-#define DP_SET_POWER_D3  0x2
 
 static inline int atom_dp_get_encoder_id(xf86OutputPtr output)
 {
@@ -2534,66 +2598,16 @@ static int radeon_dp_max_lane_count(xf86OutputPtr output)
     return max_lane_count;
 }
 
-static int radeon_dp_max_link_bw(xf86OutputPtr output)
-{
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int max_link_bw = radeon_output->dpcd[1];
-    switch(max_link_bw) {
-    case DP_LINK_BW_1_62:
-    case DP_LINK_BW_2_7:
-	break;
-    default:
-	max_link_bw = DP_LINK_BW_1_62;
-	break;
-    }
-    return max_link_bw;
-}
-
-static int radeon_dp_link_clock(uint8_t link_bw)
-{
-    if (link_bw == DP_LINK_BW_2_7)
-	return 270000;
-    else
-	return 162000;
-}
-
-
-/* I think this is a fiction */
-static int radeon_dp_link_required(int pixel_clock)
-{
-    return pixel_clock * 3;
-}
-
-static int link_bw_avail(int max_link_clock, int max_lanes)
-{
-    return (max_link_clock * max_lanes * 8) / 10;
-}
-
 Bool radeon_dp_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
 {
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int lane_count, clock;
-    int max_lane_count = radeon_dp_max_lane_count(output);
-    int max_clock = radeon_dp_max_link_bw(output) == DP_LINK_BW_2_7 ? 1 : 0;
-    static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
-
-    for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
-	for (clock = 0; clock <= max_clock; clock++) {
-	    int link_avail = link_bw_avail(radeon_dp_link_clock(bws[clock]), lane_count);
-
-	    if (radeon_dp_link_required(mode->Clock) <= link_avail) {
-		radeon_output->dp_lane_count = lane_count;
-		radeon_output->dp_clock = radeon_dp_link_clock(bws[clock]);
-		if (0)
-			xf86DrvMsg(0, X_INFO,
-				   "lane_count %d clock %d\n",
-				   radeon_output->dp_lane_count,
-				   radeon_output->dp_clock);
-		return TRUE;
-	    }
-	}
-    }
-    return FALSE;
+	RADEONOutputPrivatePtr radeon_output = output->driver_private;
+	int clock = adjusted_mode->Clock;
+
+	radeon_output->dp_lane_count = dp_lanes_for_mode_clock(output, clock);
+	radeon_output->dp_clock = dp_link_clock_for_mode_clock(output, clock);
+	if (!radeon_output->dp_lane_count || !radeon_output->dp_clock)
+		return FALSE;
+	return TRUE;
 }
 
 static void dp_update_dpvs_emph(xf86OutputPtr output, uint8_t train_set[4])
@@ -2625,7 +2639,7 @@ static void do_displayport_link_train(xf86OutputPtr output)
     /* set up link configuration */
     memset(dp_link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
 
-    if (radeon_output->dp_clock == 270000)
+    if (radeon_output->dp_clock == 27000)
 	dp_link_configuration[0] = DP_LINK_BW_2_7;
     else
 	dp_link_configuration[0] = DP_LINK_BW_1_62;


More information about the xorg-commit mailing list