Browse Source

drm/radeon/kms: add some dp encoder/connector helper funcs

Used for dp1.2 support and for dp bridges.

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Alex Deucher 14 years ago
parent
commit
d7fa8bb385

+ 71 - 0
drivers/gpu/drm/radeon/radeon_connectors.c

@@ -1068,6 +1068,77 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
 	return ret;
 	return ret;
 }
 }
 
 
+bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector)
+{
+	struct drm_mode_object *obj;
+	struct drm_encoder *encoder;
+	struct radeon_encoder *radeon_encoder;
+	int i;
+	bool found = false;
+
+	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+		if (connector->encoder_ids[i] == 0)
+			break;
+
+		obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
+		if (!obj)
+			continue;
+
+		encoder = obj_to_encoder(obj);
+		radeon_encoder = to_radeon_encoder(encoder);
+
+		switch (radeon_encoder->encoder_id) {
+		case ENCODER_OBJECT_ID_TRAVIS:
+		case ENCODER_OBJECT_ID_NUTMEG:
+			found = true;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return found;
+}
+
+bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector)
+{
+	struct drm_mode_object *obj;
+	struct drm_encoder *encoder;
+	struct radeon_encoder *radeon_encoder;
+	int i;
+	bool found = false;
+
+	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+		if (connector->encoder_ids[i] == 0)
+			break;
+
+		obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
+		if (!obj)
+			continue;
+
+		encoder = obj_to_encoder(obj);
+		radeon_encoder = to_radeon_encoder(encoder);
+		if (radeon_encoder->caps & ATOM_ENCODER_CAP_RECORD_HBR2)
+			found = true;
+	}
+
+	return found;
+}
+
+bool radeon_connector_is_dp12_capable(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct radeon_device *rdev = dev->dev_private;
+
+	if (ASIC_IS_DCE5(rdev) &&
+	    (rdev->clock.dp_extclk >= 53900) &&
+	    radeon_connector_encoder_is_hbr2(connector)) {
+		return true;
+	}
+
+	return false;
+}
+
 static enum drm_connector_status
 static enum drm_connector_status
 radeon_dp_detect(struct drm_connector *connector, bool force)
 radeon_dp_detect(struct drm_connector *connector, bool force)
 {
 {

+ 23 - 0
drivers/gpu/drm/radeon/radeon_encoders.c

@@ -250,6 +250,25 @@ struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder
 	return NULL;
 	return NULL;
 }
 }
 
 
+bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder)
+{
+	struct drm_encoder *other_encoder = radeon_atom_get_external_encoder(encoder);
+
+	if (other_encoder) {
+		struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder);
+
+		switch (radeon_encoder->encoder_id) {
+		case ENCODER_OBJECT_ID_TRAVIS:
+		case ENCODER_OBJECT_ID_NUTMEG:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	return false;
+}
+
 void radeon_panel_mode_fixup(struct drm_encoder *encoder,
 void radeon_panel_mode_fixup(struct drm_encoder *encoder,
 			     struct drm_display_mode *adjusted_mode)
 			     struct drm_display_mode *adjusted_mode)
 {
 {
@@ -621,6 +640,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
 	struct radeon_connector *radeon_connector;
 	struct radeon_connector *radeon_connector;
 	struct radeon_connector_atom_dig *dig_connector;
 	struct radeon_connector_atom_dig *dig_connector;
 
 
+	/* dp bridges are always DP */
+	if (radeon_encoder_is_dp_bridge(encoder))
+		return ATOM_ENCODER_MODE_DP;
+
 	connector = radeon_get_connector_for_encoder(encoder);
 	connector = radeon_get_connector_for_encoder(encoder);
 	if (!connector) {
 	if (!connector) {
 		switch (radeon_encoder->encoder_id) {
 		switch (radeon_encoder->encoder_id) {

+ 5 - 0
drivers/gpu/drm/radeon/radeon_mode.h

@@ -464,6 +464,11 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev);
 extern struct drm_connector *
 extern struct drm_connector *
 radeon_get_connector_for_encoder(struct drm_encoder *encoder);
 radeon_get_connector_for_encoder(struct drm_encoder *encoder);
 
 
+extern bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder);
+extern bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector);
+extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector);
+extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector);
+
 extern void radeon_connector_hotplug(struct drm_connector *connector);
 extern void radeon_connector_hotplug(struct drm_connector *connector);
 extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
 extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
 extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
 extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,