drm/radeon/kms: DP fixes and cleanup from the ddx

- dpcp -> dpcd
- fix up dig encoder routing
- aux transaction table takes delay in 10 usec units

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index a4bc801..d1c144b 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -34,7 +34,7 @@
 #define DP_LINK_STATUS_SIZE	6
 
 bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
-			   int num_bytes, u8 *read_byte, 
+			   int num_bytes, u8 *read_byte,
 			   u8 read_buf_len, u8 delay)
 {
 	struct drm_device *dev = chan->dev;
@@ -42,9 +42,9 @@
 	PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args;
 	int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
 	unsigned char *base;
-	
+
 	memset(&args, 0, sizeof(args));
-	
+
 	base = (unsigned char *)rdev->mode_info.atom_context->scratch;
 
 	memcpy(base, req_bytes, num_bytes);
@@ -53,7 +53,7 @@
 	args.lpDataOut = 16;
 	args.ucDataOutLen = 0;
 	args.ucChannelID = chan->i2c_id;
-	args.ucDelay = delay;
+	args.ucDelay = delay / 10;
 
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
@@ -158,24 +158,24 @@
 	return ret;
 }
 
-void radeon_dp_getdpcp(struct radeon_connector *radeon_connector)
+void radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
 {
 	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
 	u8 msg[25];
 	int ret;
 
-	ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCP_REV, 0, 8, msg);
+	ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, 0, 8, msg);
 	if (ret) {
-		memcpy(radeon_dig_connector->dpcp, msg, 8);
-		{ 
+		memcpy(radeon_dig_connector->dpcd, msg, 8);
+		{
 			int i;
-			printk("DPCP: ");
+			printk("DPCD: ");
 			for (i = 0; i < 8; i++)
 				printk("%02x ", msg[i]);
 			printk("\n");
 		}
 	}
-	radeon_dig_connector->dpcp[0] = 0;
+	radeon_dig_connector->dpcd[0] = 0;
 	return;
 }
 
@@ -199,8 +199,8 @@
 static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state)
 {
 	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
-	if (radeon_dig_connector->dpcp[0] >= 0x11) {
-		radeon_dp_aux_native_write(radeon_connector, 0x600, 1,
+	if (radeon_dig_connector->dpcd[0] >= 0x11) {
+		radeon_dp_aux_native_write(radeon_connector, DP_SET_POWER, 1,
 					   &power_state);
 	}
 }
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 7334275..4d457bc 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -923,7 +923,7 @@
 
 	sink_type = radeon_dp_getsinktype(radeon_connector);
 	if (sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
-		radeon_dp_getdpcp(radeon_connector);
+		radeon_dp_getdpcd(radeon_connector);
 		ret = connector_status_connected;
 	}
 	return ret;
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 37f5ea1..b4e7aba 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -605,6 +605,30 @@
 	}
 }
 
+/*
+ * DIG Encoder/Transmitter Setup
+ *
+ * DCE 3.0/3.1
+ * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA.
+ * Supports up to 3 digital outputs
+ * - 2 DIG encoder blocks.
+ * DIG1 can drive UNIPHY link A or link B
+ * DIG2 can drive UNIPHY link B or LVTMA
+ *
+ * DCE 3.2
+ * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B).
+ * Supports up to 5 digital outputs
+ * - 2 DIG encoder blocks.
+ * DIG1/2 can drive UNIPHY0/1/2 link A or link B
+ *
+ * Routing
+ * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
+ * Examples:
+ * crtc0 -> dig2 -> LVTMA   links A+B -> TMDS/HDMI
+ * crtc1 -> dig1 -> UNIPHY0 link  B   -> DP
+ * crtc0 -> dig1 -> UNIPHY2 link  A   -> LVDS
+ * crtc1 -> dig2 -> UNIPHY1 link  B+A -> TMDS/HDMI
+ */
 static void
 atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
 {
@@ -646,10 +670,17 @@
 	} else {
 		switch (radeon_encoder->encoder_id) {
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+			/* XXX doesn't really matter which dig encoder we pick as long as it's
+			 * not already in use
+			 */
+			if (dig_connector->linkb)
+				index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+			else
+				index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
 			num = 1;
 			break;
 		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+			/* Only dig2 encoder can drive LVTMA */
 			index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
 			num = 2;
 			break;
@@ -684,16 +715,15 @@
 		}
 	}
 
-	if (radeon_encoder->pixel_clock > 165000) {
-		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
+	if (radeon_encoder->pixel_clock > 165000)
 		args.ucLaneNum = 8;
-	} else {
-		if (dig_connector->linkb)
-			args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
-		else
-			args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
+	else
 		args.ucLaneNum = 4;
-	}
+
+	if (dig_connector->linkb)
+		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
+	else
+		args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
 
 	args.ucEncoderMode = atombios_get_encoder_mode(encoder);
 
@@ -707,7 +737,7 @@
 };
 
 static void
-atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action)
+atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set)
 {
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
@@ -756,6 +786,9 @@
 	args.v1.ucAction = action;
 	if (action == ATOM_TRANSMITTER_ACTION_INIT) {
 		args.v1.usInitInfo = radeon_connector->connector_object_id;
+	} else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
+		args.v1.asMode.ucLaneSel = lane_num;
+		args.v1.asMode.ucLaneSet = lane_set;
 	} else {
 		if (radeon_encoder->pixel_clock > 165000)
 			args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
@@ -767,6 +800,8 @@
 			args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
 		if (dig->dig_block)
 			args.v2.acConfig.ucEncoderSel = 1;
+		if (dig_connector->linkb)
+			args.v2.acConfig.ucLinkSel = 1;
 
 		switch (radeon_encoder->encoder_id) {
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
@@ -792,17 +827,20 @@
 
 		switch (radeon_encoder->encoder_id) {
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
+			/* XXX doesn't really matter which dig encoder we pick as long as it's
+			 * not already in use
+			 */
+			if (dig_connector->linkb)
+				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
+			else
+				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
 			if (rdev->flags & RADEON_IS_IGP) {
 				if (radeon_encoder->pixel_clock > 165000) {
-					args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
-							     ATOM_TRANSMITTER_CONFIG_LINKA_B);
 					if (dig_connector->igp_lane_info & 0x3)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
 					else if (dig_connector->igp_lane_info & 0xc)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
 				} else {
-					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
 					if (dig_connector->igp_lane_info & 0x1)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
 					else if (dig_connector->igp_lane_info & 0x2)
@@ -812,34 +850,22 @@
 					else if (dig_connector->igp_lane_info & 0x8)
 						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
 				}
-			} else {
-				if (radeon_encoder->pixel_clock > 165000)
-					args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
-							     ATOM_TRANSMITTER_CONFIG_LINKA_B |
-							     ATOM_TRANSMITTER_CONFIG_LANE_0_7);
-				else {
-					if (dig_connector->linkb)
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-					else
-						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-				}
 			}
 			break;
 		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+			/* Only dig2 encoder can drive LVTMA */
 			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
-			if (radeon_encoder->pixel_clock > 165000)
-				args.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
-						     ATOM_TRANSMITTER_CONFIG_LINKA_B |
-						     ATOM_TRANSMITTER_CONFIG_LANE_0_7);
-			else {
-				if (dig_connector->linkb)
-					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-				else
-					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-			}
 			break;
 		}
 
+		if (radeon_encoder->pixel_clock > 165000)
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
+
+		if (dig_connector->linkb)
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;
+		else
+			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
+
 		if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
 			if (dig->coherent_mode)
 				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
@@ -851,99 +877,6 @@
 }
 
 static void
-atombios_dig_transmitter_setup_vsemph(struct drm_encoder *encoder, u8 lane_num,
-				      u8 lane_set)
-{
-	struct drm_device *dev = encoder->dev;
-	struct radeon_device *rdev = dev->dev_private;
-	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-	union dig_transmitter_control args;
-	int index = 0, num = 0;
-	uint8_t frev, crev;
-	struct radeon_encoder_atom_dig *dig;
-	struct drm_connector *connector;
-	struct radeon_connector *radeon_connector;
-	struct radeon_connector_atom_dig *dig_connector;
-
-	connector = radeon_get_connector_for_encoder(encoder);
-	if (!connector)
-		return;
-
-	radeon_connector = to_radeon_connector(connector);
-
-	if (!radeon_encoder->enc_priv)
-		return;
-
-	dig = radeon_encoder->enc_priv;
-
-	if (!radeon_connector->con_priv)
-		return;
-
-	dig_connector = radeon_connector->con_priv;
-
-	memset(&args, 0, sizeof(args));
-
-	if (ASIC_IS_DCE32(rdev))
-		index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
-	else {
-		switch (radeon_encoder->encoder_id) {
-		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
-			break;
-		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-			index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
-			break;
-		}
-	}
-
-	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev);
-
-	args.v1.ucAction = ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH;
-	args.v1.asMode.ucLaneSel = lane_num;
-	args.v1.asMode.ucLaneSet = lane_set;
-
-	if (ASIC_IS_DCE32(rdev)) {
-		args.v2.acConfig.fDPConnector = 1;
-
-		if (dig->dig_block)
-			args.v2.acConfig.ucEncoderSel = 1;
-
-		switch (radeon_encoder->encoder_id) {
-		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			args.v2.acConfig.ucTransmitterSel = 0;
-			num = 0;
-			break;
-		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-			args.v2.acConfig.ucTransmitterSel = 1;
-			num = 1;
-			break;
-		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-			args.v2.acConfig.ucTransmitterSel = 2;
-			num = 2;
-			break;
-		}
-	} else {
-		args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
-
-		switch (radeon_encoder->encoder_id) {
-		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
-			if (dig_connector->linkb)
-				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-			else
-				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-		}
-	}
-
-	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
-	if (ASIC_IS_DCE32(rdev))
-		DRM_INFO("Output UNIPHY%d transmitter VSEMPH setup success\n", num);
-	else
-		DRM_INFO("Output DIG%d transmitter VSEMPH setup success\n", num);
-}
-
-static void
 atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
 {
 	struct drm_device *dev = encoder->dev;
@@ -1150,13 +1083,33 @@
 						args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
 					else
 						args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
-				} else
-					args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+				} else {
+					struct drm_connector *connector;
+					struct radeon_connector *radeon_connector;
+					struct radeon_connector_atom_dig *dig_connector;
+
+					connector = radeon_get_connector_for_encoder(encoder);
+					if (!connector)
+						return;
+					radeon_connector = to_radeon_connector(connector);
+					if (!radeon_connector->con_priv)
+						return;
+					dig_connector = radeon_connector->con_priv;
+
+					/* XXX doesn't really matter which dig encoder we pick as long as it's
+					 * not already in use
+					 */
+					if (dig_connector->linkb)
+						args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+					else
+						args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+				}
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
 				args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+				/* Only dig2 encoder can drive LVTMA */
 				args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
@@ -1259,14 +1212,14 @@
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 		/* disable the encoder and transmitter */
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
 		atombios_dig_encoder_setup(encoder, ATOM_DISABLE);
 
 		/* setup and enable the encoder and transmitter */
 		atombios_dig_encoder_setup(encoder, ATOM_ENABLE);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP);
-		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
+		atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DDI:
 		atombios_ddia_setup(encoder, ATOM_ENABLE);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index ce1cdc7..166f753 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -335,7 +335,7 @@
 	bool linkb;
 	uint16_t uc_i2c_id;
 	struct radeon_i2c_chan *dp_i2c_bus;
-	u8 dpcp[8];
+	u8 dpcd[8];
 };
 
 struct radeon_connector {
@@ -362,7 +362,7 @@
 };
 
 extern int radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
-extern void radeon_dp_getdpcp(struct radeon_connector *connector);
+extern void radeon_dp_getdpcd(struct radeon_connector *connector);
 extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
 				uint8_t write_byte, uint8_t *read_byte);
 
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 376155f..f09b0b2 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -43,7 +43,7 @@
 #define AUX_I2C_REPLY_MASK	(0x3 << 6)
 
 /* AUX CH addresses */
-#define DP_DPCP_REV 0x0
+#define DP_DPCD_REV 0x0
 
 #define	DP_LINK_BW_SET		0x100
 # define DP_LINK_BW_1_62		    0x06
@@ -132,6 +132,8 @@
 #define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK   0xc0
 #define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT  6
 
+#define DP_SET_POWER                        0x600
+
 #define MODE_I2C_START	1
 #define MODE_I2C_WRITE	2
 #define MODE_I2C_READ	4