xref: /openbsd-src/sys/dev/pci/drm/radeon/radeon_encoders.c (revision 79cedbc2b2561dea1832e45eec850b440c20f930)
11099013bSjsg /*
21099013bSjsg  * Copyright 2007-8 Advanced Micro Devices, Inc.
31099013bSjsg  * Copyright 2008 Red Hat Inc.
41099013bSjsg  *
51099013bSjsg  * Permission is hereby granted, free of charge, to any person obtaining a
61099013bSjsg  * copy of this software and associated documentation files (the "Software"),
71099013bSjsg  * to deal in the Software without restriction, including without limitation
81099013bSjsg  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
91099013bSjsg  * and/or sell copies of the Software, and to permit persons to whom the
101099013bSjsg  * Software is furnished to do so, subject to the following conditions:
111099013bSjsg  *
121099013bSjsg  * The above copyright notice and this permission notice shall be included in
131099013bSjsg  * all copies or substantial portions of the Software.
141099013bSjsg  *
151099013bSjsg  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161099013bSjsg  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171099013bSjsg  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181099013bSjsg  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
191099013bSjsg  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
201099013bSjsg  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
211099013bSjsg  * OTHER DEALINGS IN THE SOFTWARE.
221099013bSjsg  *
231099013bSjsg  * Authors: Dave Airlie
241099013bSjsg  *          Alex Deucher
251099013bSjsg  */
26c349dbc7Sjsg 
27c349dbc7Sjsg #include <linux/pci.h>
28c349dbc7Sjsg 
29c349dbc7Sjsg #include <drm/drm_device.h>
307f4dd379Sjsg #include <drm/radeon_drm.h>
31c349dbc7Sjsg 
321bb76ff1Sjsg #include <acpi/video.h>
331bb76ff1Sjsg 
341099013bSjsg #include "radeon.h"
355ca02815Sjsg #include "radeon_atombios.h"
365ca02815Sjsg #include "radeon_legacy_encoders.h"
371099013bSjsg #include "atom.h"
381099013bSjsg 
391099013bSjsg static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
401099013bSjsg {
411099013bSjsg 	struct drm_device *dev = encoder->dev;
421099013bSjsg 	struct radeon_device *rdev = dev->dev_private;
431099013bSjsg 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
441099013bSjsg 	struct drm_encoder *clone_encoder;
45*79cedbc2Sjsg 	uint32_t index_mask = drm_encoder_mask(encoder);
461099013bSjsg 	int count;
471099013bSjsg 
481099013bSjsg 	/* DIG routing gets problematic */
491099013bSjsg 	if (rdev->family >= CHIP_R600)
501099013bSjsg 		return index_mask;
511099013bSjsg 	/* LVDS/TV are too wacky */
521099013bSjsg 	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
531099013bSjsg 		return index_mask;
541099013bSjsg 	/* DVO requires 2x ppll clocks depending on tmds chip */
551099013bSjsg 	if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
561099013bSjsg 		return index_mask;
571099013bSjsg 
581099013bSjsg 	count = -1;
591099013bSjsg 	list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
601099013bSjsg 		struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
61f005ef32Sjsg 
621099013bSjsg 		count++;
631099013bSjsg 
641099013bSjsg 		if (clone_encoder == encoder)
651099013bSjsg 			continue;
661099013bSjsg 		if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
671099013bSjsg 			continue;
681099013bSjsg 		if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
691099013bSjsg 			continue;
701099013bSjsg 		else
711099013bSjsg 			index_mask |= (1 << count);
721099013bSjsg 	}
731099013bSjsg 	return index_mask;
741099013bSjsg }
751099013bSjsg 
761099013bSjsg void radeon_setup_encoder_clones(struct drm_device *dev)
771099013bSjsg {
781099013bSjsg 	struct drm_encoder *encoder;
791099013bSjsg 
801099013bSjsg 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
811099013bSjsg 		encoder->possible_clones = radeon_encoder_clones(encoder);
821099013bSjsg 	}
831099013bSjsg }
841099013bSjsg 
851099013bSjsg uint32_t
861099013bSjsg radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
871099013bSjsg {
881099013bSjsg 	struct radeon_device *rdev = dev->dev_private;
891099013bSjsg 	uint32_t ret = 0;
901099013bSjsg 
911099013bSjsg 	switch (supported_device) {
921099013bSjsg 	case ATOM_DEVICE_CRT1_SUPPORT:
931099013bSjsg 	case ATOM_DEVICE_TV1_SUPPORT:
941099013bSjsg 	case ATOM_DEVICE_TV2_SUPPORT:
951099013bSjsg 	case ATOM_DEVICE_CRT2_SUPPORT:
961099013bSjsg 	case ATOM_DEVICE_CV_SUPPORT:
971099013bSjsg 		switch (dac) {
981099013bSjsg 		case 1: /* dac a */
991099013bSjsg 			if ((rdev->family == CHIP_RS300) ||
1001099013bSjsg 			    (rdev->family == CHIP_RS400) ||
1011099013bSjsg 			    (rdev->family == CHIP_RS480))
1021099013bSjsg 				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
1031099013bSjsg 			else if (ASIC_IS_AVIVO(rdev))
1041099013bSjsg 				ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;
1051099013bSjsg 			else
1061099013bSjsg 				ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;
1071099013bSjsg 			break;
1081099013bSjsg 		case 2: /* dac b */
1091099013bSjsg 			if (ASIC_IS_AVIVO(rdev))
1101099013bSjsg 				ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;
1111099013bSjsg 			else {
1121099013bSjsg 				/* if (rdev->family == CHIP_R200)
113f005ef32Sjsg 				 * ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
114f005ef32Sjsg 				 * else
115f005ef32Sjsg 				 */
1161099013bSjsg 				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
1171099013bSjsg 			}
1181099013bSjsg 			break;
1191099013bSjsg 		case 3: /* external dac */
1201099013bSjsg 			if (ASIC_IS_AVIVO(rdev))
1211099013bSjsg 				ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
1221099013bSjsg 			else
1231099013bSjsg 				ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
1241099013bSjsg 			break;
1251099013bSjsg 		}
1261099013bSjsg 		break;
1271099013bSjsg 	case ATOM_DEVICE_LCD1_SUPPORT:
1281099013bSjsg 		if (ASIC_IS_AVIVO(rdev))
1291099013bSjsg 			ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
1301099013bSjsg 		else
1311099013bSjsg 			ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;
1321099013bSjsg 		break;
1331099013bSjsg 	case ATOM_DEVICE_DFP1_SUPPORT:
1341099013bSjsg 		if ((rdev->family == CHIP_RS300) ||
1351099013bSjsg 		    (rdev->family == CHIP_RS400) ||
1361099013bSjsg 		    (rdev->family == CHIP_RS480))
1371099013bSjsg 			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
1381099013bSjsg 		else if (ASIC_IS_AVIVO(rdev))
1391099013bSjsg 			ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;
1401099013bSjsg 		else
1411099013bSjsg 			ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;
1421099013bSjsg 		break;
1431099013bSjsg 	case ATOM_DEVICE_LCD2_SUPPORT:
1441099013bSjsg 	case ATOM_DEVICE_DFP2_SUPPORT:
1451099013bSjsg 		if ((rdev->family == CHIP_RS600) ||
1461099013bSjsg 		    (rdev->family == CHIP_RS690) ||
1471099013bSjsg 		    (rdev->family == CHIP_RS740))
1481099013bSjsg 			ret = ENCODER_INTERNAL_DDI_ENUM_ID1;
1491099013bSjsg 		else if (ASIC_IS_AVIVO(rdev))
1501099013bSjsg 			ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
1511099013bSjsg 		else
1521099013bSjsg 			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
1531099013bSjsg 		break;
1541099013bSjsg 	case ATOM_DEVICE_DFP3_SUPPORT:
1551099013bSjsg 		ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
1561099013bSjsg 		break;
1571099013bSjsg 	}
1581099013bSjsg 
1591099013bSjsg 	return ret;
1601099013bSjsg }
1611099013bSjsg 
1627ccd5a2cSjsg static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder,
1637ccd5a2cSjsg 					 struct drm_connector *connector)
1647ccd5a2cSjsg {
1657ccd5a2cSjsg 	struct drm_device *dev = radeon_encoder->base.dev;
1667ccd5a2cSjsg 	struct radeon_device *rdev = dev->dev_private;
1677ccd5a2cSjsg 	bool use_bl = false;
1687ccd5a2cSjsg 
1697ccd5a2cSjsg 	if (!(radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)))
1707ccd5a2cSjsg 		return;
1717ccd5a2cSjsg 
1727ccd5a2cSjsg 	if (radeon_backlight == 0) {
1731bb76ff1Sjsg 		use_bl = false;
1747ccd5a2cSjsg 	} else if (radeon_backlight == 1) {
1757ccd5a2cSjsg 		use_bl = true;
1767ccd5a2cSjsg 	} else if (radeon_backlight == -1) {
1777ccd5a2cSjsg 		/* Quirks */
1787ccd5a2cSjsg 		/* Amilo Xi 2550 only works with acpi bl */
1797ccd5a2cSjsg 		if ((rdev->pdev->device == 0x9583) &&
1807ccd5a2cSjsg 		    (rdev->pdev->subsystem_vendor == 0x1734) &&
1817ccd5a2cSjsg 		    (rdev->pdev->subsystem_device == 0x1107))
1827ccd5a2cSjsg 			use_bl = false;
1837ccd5a2cSjsg /* Older PPC macs use on-GPU backlight controller */
1847ccd5a2cSjsg #ifndef CONFIG_PPC_PMAC
1857ccd5a2cSjsg 		/* disable native backlight control on older asics */
1867ccd5a2cSjsg 		else if (rdev->family < CHIP_R600)
1877ccd5a2cSjsg 			use_bl = false;
1887ccd5a2cSjsg #endif
1897ccd5a2cSjsg 		else
1907ccd5a2cSjsg 			use_bl = true;
1917ccd5a2cSjsg 	}
1927ccd5a2cSjsg 
1937ccd5a2cSjsg 	if (use_bl) {
1947ccd5a2cSjsg 		if (rdev->is_atom_bios)
1957ccd5a2cSjsg 			radeon_atom_backlight_init(radeon_encoder, connector);
1967ccd5a2cSjsg 		else
1977ccd5a2cSjsg 			radeon_legacy_backlight_init(radeon_encoder, connector);
1987ccd5a2cSjsg 	}
1991bb76ff1Sjsg 
2001bb76ff1Sjsg 	/*
2011bb76ff1Sjsg 	 * If there is no native backlight device (which may happen even when
2021bb76ff1Sjsg 	 * use_bl==true) try registering an ACPI video backlight device instead.
2031bb76ff1Sjsg 	 */
2041bb76ff1Sjsg 	if (!rdev->mode_info.bl_encoder)
2051bb76ff1Sjsg 		acpi_video_register_backlight();
2067ccd5a2cSjsg }
2077ccd5a2cSjsg 
2081099013bSjsg void
2091099013bSjsg radeon_link_encoder_connector(struct drm_device *dev)
2101099013bSjsg {
2111099013bSjsg 	struct drm_connector *connector;
2121099013bSjsg 	struct radeon_connector *radeon_connector;
2131099013bSjsg 	struct drm_encoder *encoder;
2141099013bSjsg 	struct radeon_encoder *radeon_encoder;
2151099013bSjsg 
2161099013bSjsg 	/* walk the list and link encoders to connectors */
2171099013bSjsg 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
2181099013bSjsg 		radeon_connector = to_radeon_connector(connector);
2191099013bSjsg 		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
2201099013bSjsg 			radeon_encoder = to_radeon_encoder(encoder);
2211099013bSjsg 			if (radeon_encoder->devices & radeon_connector->devices) {
2227f4dd379Sjsg 				drm_connector_attach_encoder(connector, encoder);
2237ccd5a2cSjsg 				if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
2247ccd5a2cSjsg 					radeon_encoder_add_backlight(radeon_encoder, connector);
2251099013bSjsg 			}
2261099013bSjsg 		}
2271099013bSjsg 	}
2281099013bSjsg }
2291099013bSjsg 
2301099013bSjsg void radeon_encoder_set_active_device(struct drm_encoder *encoder)
2311099013bSjsg {
2321099013bSjsg 	struct drm_device *dev = encoder->dev;
2331099013bSjsg 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2341099013bSjsg 	struct drm_connector *connector;
2351099013bSjsg 
2361099013bSjsg 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
2371099013bSjsg 		if (connector->encoder == encoder) {
2381099013bSjsg 			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
239f005ef32Sjsg 
2401099013bSjsg 			radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices;
2411099013bSjsg 			DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
2421099013bSjsg 				  radeon_encoder->active_device, radeon_encoder->devices,
2431099013bSjsg 				  radeon_connector->devices, encoder->encoder_type);
2441099013bSjsg 		}
2451099013bSjsg 	}
2461099013bSjsg }
2471099013bSjsg 
2481099013bSjsg struct drm_connector *
2491099013bSjsg radeon_get_connector_for_encoder(struct drm_encoder *encoder)
2501099013bSjsg {
2511099013bSjsg 	struct drm_device *dev = encoder->dev;
2521099013bSjsg 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2531099013bSjsg 	struct drm_connector *connector;
2541099013bSjsg 	struct radeon_connector *radeon_connector;
2551099013bSjsg 
2561099013bSjsg 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
2571099013bSjsg 		radeon_connector = to_radeon_connector(connector);
2581bb76ff1Sjsg 		if (radeon_encoder->active_device & radeon_connector->devices)
2591099013bSjsg 			return connector;
2601099013bSjsg 	}
2611099013bSjsg 	return NULL;
2621099013bSjsg }
2631099013bSjsg 
2641099013bSjsg struct drm_connector *
2651099013bSjsg radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
2661099013bSjsg {
2671099013bSjsg 	struct drm_device *dev = encoder->dev;
2681099013bSjsg 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2691099013bSjsg 	struct drm_connector *connector;
2701099013bSjsg 	struct radeon_connector *radeon_connector;
2711099013bSjsg 
2721099013bSjsg 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
2731099013bSjsg 		radeon_connector = to_radeon_connector(connector);
2741099013bSjsg 		if (radeon_encoder->devices & radeon_connector->devices)
2751099013bSjsg 			return connector;
2761099013bSjsg 	}
2771099013bSjsg 	return NULL;
2781099013bSjsg }
2791099013bSjsg 
2801099013bSjsg struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder)
2811099013bSjsg {
2821099013bSjsg 	struct drm_device *dev = encoder->dev;
2831099013bSjsg 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2841099013bSjsg 	struct drm_encoder *other_encoder;
2851099013bSjsg 	struct radeon_encoder *other_radeon_encoder;
2861099013bSjsg 
2871099013bSjsg 	if (radeon_encoder->is_ext_encoder)
2881099013bSjsg 		return NULL;
2891099013bSjsg 
2901099013bSjsg 	list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
2911099013bSjsg 		if (other_encoder == encoder)
2921099013bSjsg 			continue;
2931099013bSjsg 		other_radeon_encoder = to_radeon_encoder(other_encoder);
2941099013bSjsg 		if (other_radeon_encoder->is_ext_encoder &&
2951099013bSjsg 		    (radeon_encoder->devices & other_radeon_encoder->devices))
2961099013bSjsg 			return other_encoder;
2971099013bSjsg 	}
2981099013bSjsg 	return NULL;
2991099013bSjsg }
3001099013bSjsg 
3011099013bSjsg u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder)
3021099013bSjsg {
3031099013bSjsg 	struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder);
3041099013bSjsg 
3051099013bSjsg 	if (other_encoder) {
3061099013bSjsg 		struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder);
3071099013bSjsg 
3081099013bSjsg 		switch (radeon_encoder->encoder_id) {
3091099013bSjsg 		case ENCODER_OBJECT_ID_TRAVIS:
3101099013bSjsg 		case ENCODER_OBJECT_ID_NUTMEG:
3111099013bSjsg 			return radeon_encoder->encoder_id;
3121099013bSjsg 		default:
3131099013bSjsg 			return ENCODER_OBJECT_ID_NONE;
3141099013bSjsg 		}
3151099013bSjsg 	}
3161099013bSjsg 	return ENCODER_OBJECT_ID_NONE;
3171099013bSjsg }
3181099013bSjsg 
3191099013bSjsg void radeon_panel_mode_fixup(struct drm_encoder *encoder,
3201099013bSjsg 			     struct drm_display_mode *adjusted_mode)
3211099013bSjsg {
3221099013bSjsg 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
3231099013bSjsg 	struct drm_device *dev = encoder->dev;
3241099013bSjsg 	struct radeon_device *rdev = dev->dev_private;
3251099013bSjsg 	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
326f005ef32Sjsg 	unsigned int hblank = native_mode->htotal - native_mode->hdisplay;
327f005ef32Sjsg 	unsigned int vblank = native_mode->vtotal - native_mode->vdisplay;
328f005ef32Sjsg 	unsigned int hover = native_mode->hsync_start - native_mode->hdisplay;
329f005ef32Sjsg 	unsigned int vover = native_mode->vsync_start - native_mode->vdisplay;
330f005ef32Sjsg 	unsigned int hsync_width = native_mode->hsync_end - native_mode->hsync_start;
331f005ef32Sjsg 	unsigned int vsync_width = native_mode->vsync_end - native_mode->vsync_start;
3321099013bSjsg 
3331099013bSjsg 	adjusted_mode->clock = native_mode->clock;
3341099013bSjsg 	adjusted_mode->flags = native_mode->flags;
3351099013bSjsg 
3361099013bSjsg 	if (ASIC_IS_AVIVO(rdev)) {
3371099013bSjsg 		adjusted_mode->hdisplay = native_mode->hdisplay;
3381099013bSjsg 		adjusted_mode->vdisplay = native_mode->vdisplay;
3391099013bSjsg 	}
3401099013bSjsg 
3411099013bSjsg 	adjusted_mode->htotal = native_mode->hdisplay + hblank;
3421099013bSjsg 	adjusted_mode->hsync_start = native_mode->hdisplay + hover;
3431099013bSjsg 	adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
3441099013bSjsg 
3451099013bSjsg 	adjusted_mode->vtotal = native_mode->vdisplay + vblank;
3461099013bSjsg 	adjusted_mode->vsync_start = native_mode->vdisplay + vover;
3471099013bSjsg 	adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
3481099013bSjsg 
3491099013bSjsg 	drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
3501099013bSjsg 
3511099013bSjsg 	if (ASIC_IS_AVIVO(rdev)) {
3521099013bSjsg 		adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
3531099013bSjsg 		adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
3541099013bSjsg 	}
3551099013bSjsg 
3561099013bSjsg 	adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
3571099013bSjsg 	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
3581099013bSjsg 	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
3591099013bSjsg 
3601099013bSjsg 	adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
3611099013bSjsg 	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
3621099013bSjsg 	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
3631099013bSjsg 
3641099013bSjsg }
3651099013bSjsg 
3661099013bSjsg bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
3671099013bSjsg 				    u32 pixel_clock)
3681099013bSjsg {
3691099013bSjsg 	struct drm_device *dev = encoder->dev;
3701099013bSjsg 	struct radeon_device *rdev = dev->dev_private;
3711099013bSjsg 	struct drm_connector *connector;
3721099013bSjsg 	struct radeon_connector *radeon_connector;
3731099013bSjsg 	struct radeon_connector_atom_dig *dig_connector;
3741099013bSjsg 
3751099013bSjsg 	connector = radeon_get_connector_for_encoder(encoder);
3761099013bSjsg 	/* if we don't have an active device yet, just use one of
3771099013bSjsg 	 * the connectors tied to the encoder.
3781099013bSjsg 	 */
3791099013bSjsg 	if (!connector)
3801099013bSjsg 		connector = radeon_get_connector_for_encoder_init(encoder);
3811099013bSjsg 	radeon_connector = to_radeon_connector(connector);
3821099013bSjsg 
3831099013bSjsg 	switch (connector->connector_type) {
3841099013bSjsg 	case DRM_MODE_CONNECTOR_DVII:
3851099013bSjsg 	case DRM_MODE_CONNECTOR_HDMIB:
3861099013bSjsg 		if (radeon_connector->use_digital) {
3871099013bSjsg 			/* HDMI 1.3 supports up to 340 Mhz over single link */
3887ccd5a2cSjsg 			if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
3891099013bSjsg 				if (pixel_clock > 340000)
3901099013bSjsg 					return true;
3911099013bSjsg 				else
3921099013bSjsg 					return false;
3931099013bSjsg 			} else {
3941099013bSjsg 				if (pixel_clock > 165000)
3951099013bSjsg 					return true;
3961099013bSjsg 				else
3971099013bSjsg 					return false;
3981099013bSjsg 			}
3991099013bSjsg 		} else
4001099013bSjsg 			return false;
4011099013bSjsg 	case DRM_MODE_CONNECTOR_DVID:
4021099013bSjsg 	case DRM_MODE_CONNECTOR_HDMIA:
4031099013bSjsg 	case DRM_MODE_CONNECTOR_DisplayPort:
4041099013bSjsg 		dig_connector = radeon_connector->con_priv;
4051099013bSjsg 		if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
4061099013bSjsg 		    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
4071099013bSjsg 			return false;
4081099013bSjsg 		else {
4091099013bSjsg 			/* HDMI 1.3 supports up to 340 Mhz over single link */
4107ccd5a2cSjsg 			if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
4111099013bSjsg 				if (pixel_clock > 340000)
4121099013bSjsg 					return true;
4131099013bSjsg 				else
4141099013bSjsg 					return false;
4151099013bSjsg 			} else {
4161099013bSjsg 				if (pixel_clock > 165000)
4171099013bSjsg 					return true;
4181099013bSjsg 				else
4191099013bSjsg 					return false;
4201099013bSjsg 			}
4211099013bSjsg 		}
4221099013bSjsg 	default:
4231099013bSjsg 		return false;
4241099013bSjsg 	}
4251099013bSjsg }
4261099013bSjsg 
4277ccd5a2cSjsg bool radeon_encoder_is_digital(struct drm_encoder *encoder)
4287ccd5a2cSjsg {
4297ccd5a2cSjsg 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
430f005ef32Sjsg 
4317ccd5a2cSjsg 	switch (radeon_encoder->encoder_id) {
4327ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
4337ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
4347ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
4357ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
4367ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
4377ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
4387ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_DDI:
4397ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
4407ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
4417ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
4427ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
4437ccd5a2cSjsg 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
4447ccd5a2cSjsg 		return true;
4457ccd5a2cSjsg 	default:
4467ccd5a2cSjsg 		return false;
4477ccd5a2cSjsg 	}
4487ccd5a2cSjsg }
449