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