Home | History | Annotate | Line # | Download | only in radeon
radeon_encoders.c revision 1.1
      1 /*
      2  * Copyright 2007-8 Advanced Micro Devices, Inc.
      3  * Copyright 2008 Red Hat Inc.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be included in
     13  * all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     21  * OTHER DEALINGS IN THE SOFTWARE.
     22  *
     23  * Authors: Dave Airlie
     24  *          Alex Deucher
     25  */
     26 #include <drm/drmP.h>
     27 #include <drm/drm_crtc_helper.h>
     28 #include <drm/radeon_drm.h>
     29 #include "radeon.h"
     30 #include "atom.h"
     31 
     32 extern void
     33 radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
     34 			     struct drm_connector *drm_connector);
     35 extern void
     36 radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
     37 			   struct drm_connector *drm_connector);
     38 
     39 
     40 static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
     41 {
     42 	struct drm_device *dev = encoder->dev;
     43 	struct radeon_device *rdev = dev->dev_private;
     44 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
     45 	struct drm_encoder *clone_encoder;
     46 	uint32_t index_mask = 0;
     47 	int count;
     48 
     49 	/* DIG routing gets problematic */
     50 	if (rdev->family >= CHIP_R600)
     51 		return index_mask;
     52 	/* LVDS/TV are too wacky */
     53 	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
     54 		return index_mask;
     55 	/* DVO requires 2x ppll clocks depending on tmds chip */
     56 	if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
     57 		return index_mask;
     58 
     59 	count = -1;
     60 	list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
     61 		struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
     62 		count++;
     63 
     64 		if (clone_encoder == encoder)
     65 			continue;
     66 		if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
     67 			continue;
     68 		if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
     69 			continue;
     70 		else
     71 			index_mask |= (1 << count);
     72 	}
     73 	return index_mask;
     74 }
     75 
     76 void radeon_setup_encoder_clones(struct drm_device *dev)
     77 {
     78 	struct drm_encoder *encoder;
     79 
     80 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
     81 		encoder->possible_clones = radeon_encoder_clones(encoder);
     82 	}
     83 }
     84 
     85 uint32_t
     86 radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
     87 {
     88 	struct radeon_device *rdev = dev->dev_private;
     89 	uint32_t ret = 0;
     90 
     91 	switch (supported_device) {
     92 	case ATOM_DEVICE_CRT1_SUPPORT:
     93 	case ATOM_DEVICE_TV1_SUPPORT:
     94 	case ATOM_DEVICE_TV2_SUPPORT:
     95 	case ATOM_DEVICE_CRT2_SUPPORT:
     96 	case ATOM_DEVICE_CV_SUPPORT:
     97 		switch (dac) {
     98 		case 1: /* dac a */
     99 			if ((rdev->family == CHIP_RS300) ||
    100 			    (rdev->family == CHIP_RS400) ||
    101 			    (rdev->family == CHIP_RS480))
    102 				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
    103 			else if (ASIC_IS_AVIVO(rdev))
    104 				ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;
    105 			else
    106 				ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;
    107 			break;
    108 		case 2: /* dac b */
    109 			if (ASIC_IS_AVIVO(rdev))
    110 				ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;
    111 			else {
    112 				/*if (rdev->family == CHIP_R200)
    113 				  ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
    114 				  else*/
    115 				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
    116 			}
    117 			break;
    118 		case 3: /* external dac */
    119 			if (ASIC_IS_AVIVO(rdev))
    120 				ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
    121 			else
    122 				ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
    123 			break;
    124 		}
    125 		break;
    126 	case ATOM_DEVICE_LCD1_SUPPORT:
    127 		if (ASIC_IS_AVIVO(rdev))
    128 			ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
    129 		else
    130 			ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;
    131 		break;
    132 	case ATOM_DEVICE_DFP1_SUPPORT:
    133 		if ((rdev->family == CHIP_RS300) ||
    134 		    (rdev->family == CHIP_RS400) ||
    135 		    (rdev->family == CHIP_RS480))
    136 			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
    137 		else if (ASIC_IS_AVIVO(rdev))
    138 			ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;
    139 		else
    140 			ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;
    141 		break;
    142 	case ATOM_DEVICE_LCD2_SUPPORT:
    143 	case ATOM_DEVICE_DFP2_SUPPORT:
    144 		if ((rdev->family == CHIP_RS600) ||
    145 		    (rdev->family == CHIP_RS690) ||
    146 		    (rdev->family == CHIP_RS740))
    147 			ret = ENCODER_INTERNAL_DDI_ENUM_ID1;
    148 		else if (ASIC_IS_AVIVO(rdev))
    149 			ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
    150 		else
    151 			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
    152 		break;
    153 	case ATOM_DEVICE_DFP3_SUPPORT:
    154 		ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
    155 		break;
    156 	}
    157 
    158 	return ret;
    159 }
    160 
    161 void
    162 radeon_link_encoder_connector(struct drm_device *dev)
    163 {
    164 	struct radeon_device *rdev = dev->dev_private;
    165 	struct drm_connector *connector;
    166 	struct radeon_connector *radeon_connector;
    167 	struct drm_encoder *encoder;
    168 	struct radeon_encoder *radeon_encoder;
    169 
    170 	/* walk the list and link encoders to connectors */
    171 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
    172 		radeon_connector = to_radeon_connector(connector);
    173 		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
    174 			radeon_encoder = to_radeon_encoder(encoder);
    175 			if (radeon_encoder->devices & radeon_connector->devices) {
    176 				drm_mode_connector_attach_encoder(connector, encoder);
    177 				if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
    178 					if (rdev->is_atom_bios)
    179 						radeon_atom_backlight_init(radeon_encoder, connector);
    180 					else
    181 						radeon_legacy_backlight_init(radeon_encoder, connector);
    182 					rdev->mode_info.bl_encoder = radeon_encoder;
    183 				}
    184 			}
    185 		}
    186 	}
    187 }
    188 
    189 void radeon_encoder_set_active_device(struct drm_encoder *encoder)
    190 {
    191 	struct drm_device *dev = encoder->dev;
    192 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
    193 	struct drm_connector *connector;
    194 
    195 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
    196 		if (connector->encoder == encoder) {
    197 			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
    198 			radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices;
    199 			DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
    200 				  radeon_encoder->active_device, radeon_encoder->devices,
    201 				  radeon_connector->devices, encoder->encoder_type);
    202 		}
    203 	}
    204 }
    205 
    206 struct drm_connector *
    207 radeon_get_connector_for_encoder(struct drm_encoder *encoder)
    208 {
    209 	struct drm_device *dev = encoder->dev;
    210 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
    211 	struct drm_connector *connector;
    212 	struct radeon_connector *radeon_connector;
    213 
    214 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
    215 		radeon_connector = to_radeon_connector(connector);
    216 		if (radeon_encoder->active_device & radeon_connector->devices)
    217 			return connector;
    218 	}
    219 	return NULL;
    220 }
    221 
    222 struct drm_connector *
    223 radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
    224 {
    225 	struct drm_device *dev = encoder->dev;
    226 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
    227 	struct drm_connector *connector;
    228 	struct radeon_connector *radeon_connector;
    229 
    230 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
    231 		radeon_connector = to_radeon_connector(connector);
    232 		if (radeon_encoder->devices & radeon_connector->devices)
    233 			return connector;
    234 	}
    235 	return NULL;
    236 }
    237 
    238 struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder)
    239 {
    240 	struct drm_device *dev = encoder->dev;
    241 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
    242 	struct drm_encoder *other_encoder;
    243 	struct radeon_encoder *other_radeon_encoder;
    244 
    245 	if (radeon_encoder->is_ext_encoder)
    246 		return NULL;
    247 
    248 	list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
    249 		if (other_encoder == encoder)
    250 			continue;
    251 		other_radeon_encoder = to_radeon_encoder(other_encoder);
    252 		if (other_radeon_encoder->is_ext_encoder &&
    253 		    (radeon_encoder->devices & other_radeon_encoder->devices))
    254 			return other_encoder;
    255 	}
    256 	return NULL;
    257 }
    258 
    259 u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder)
    260 {
    261 	struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder);
    262 
    263 	if (other_encoder) {
    264 		struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder);
    265 
    266 		switch (radeon_encoder->encoder_id) {
    267 		case ENCODER_OBJECT_ID_TRAVIS:
    268 		case ENCODER_OBJECT_ID_NUTMEG:
    269 			return radeon_encoder->encoder_id;
    270 		default:
    271 			return ENCODER_OBJECT_ID_NONE;
    272 		}
    273 	}
    274 	return ENCODER_OBJECT_ID_NONE;
    275 }
    276 
    277 void radeon_panel_mode_fixup(struct drm_encoder *encoder,
    278 			     struct drm_display_mode *adjusted_mode)
    279 {
    280 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
    281 	struct drm_device *dev = encoder->dev;
    282 	struct radeon_device *rdev = dev->dev_private;
    283 	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
    284 	unsigned hblank = native_mode->htotal - native_mode->hdisplay;
    285 	unsigned vblank = native_mode->vtotal - native_mode->vdisplay;
    286 	unsigned hover = native_mode->hsync_start - native_mode->hdisplay;
    287 	unsigned vover = native_mode->vsync_start - native_mode->vdisplay;
    288 	unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start;
    289 	unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start;
    290 
    291 	adjusted_mode->clock = native_mode->clock;
    292 	adjusted_mode->flags = native_mode->flags;
    293 
    294 	if (ASIC_IS_AVIVO(rdev)) {
    295 		adjusted_mode->hdisplay = native_mode->hdisplay;
    296 		adjusted_mode->vdisplay = native_mode->vdisplay;
    297 	}
    298 
    299 	adjusted_mode->htotal = native_mode->hdisplay + hblank;
    300 	adjusted_mode->hsync_start = native_mode->hdisplay + hover;
    301 	adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
    302 
    303 	adjusted_mode->vtotal = native_mode->vdisplay + vblank;
    304 	adjusted_mode->vsync_start = native_mode->vdisplay + vover;
    305 	adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
    306 
    307 	drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
    308 
    309 	if (ASIC_IS_AVIVO(rdev)) {
    310 		adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
    311 		adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
    312 	}
    313 
    314 	adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
    315 	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
    316 	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
    317 
    318 	adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
    319 	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
    320 	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
    321 
    322 }
    323 
    324 bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
    325 				    u32 pixel_clock)
    326 {
    327 	struct drm_device *dev = encoder->dev;
    328 	struct radeon_device *rdev = dev->dev_private;
    329 	struct drm_connector *connector;
    330 	struct radeon_connector *radeon_connector;
    331 	struct radeon_connector_atom_dig *dig_connector;
    332 
    333 	connector = radeon_get_connector_for_encoder(encoder);
    334 	/* if we don't have an active device yet, just use one of
    335 	 * the connectors tied to the encoder.
    336 	 */
    337 	if (!connector)
    338 		connector = radeon_get_connector_for_encoder_init(encoder);
    339 	radeon_connector = to_radeon_connector(connector);
    340 
    341 	switch (connector->connector_type) {
    342 	case DRM_MODE_CONNECTOR_DVII:
    343 	case DRM_MODE_CONNECTOR_HDMIB:
    344 		if (radeon_connector->use_digital) {
    345 			/* HDMI 1.3 supports up to 340 Mhz over single link */
    346 			if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
    347 				if (pixel_clock > 340000)
    348 					return true;
    349 				else
    350 					return false;
    351 			} else {
    352 				if (pixel_clock > 165000)
    353 					return true;
    354 				else
    355 					return false;
    356 			}
    357 		} else
    358 			return false;
    359 	case DRM_MODE_CONNECTOR_DVID:
    360 	case DRM_MODE_CONNECTOR_HDMIA:
    361 	case DRM_MODE_CONNECTOR_DisplayPort:
    362 		dig_connector = radeon_connector->con_priv;
    363 		if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
    364 		    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
    365 			return false;
    366 		else {
    367 			/* HDMI 1.3 supports up to 340 Mhz over single link */
    368 			if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
    369 				if (pixel_clock > 340000)
    370 					return true;
    371 				else
    372 					return false;
    373 			} else {
    374 				if (pixel_clock > 165000)
    375 					return true;
    376 				else
    377 					return false;
    378 			}
    379 		}
    380 	default:
    381 		return false;
    382 	}
    383 }
    384 
    385