radeon_encoders.c revision 1.2
1/* $OpenBSD: radeon_encoders.c,v 1.2 2015/04/18 14:47:35 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 40 41static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) 42{ 43 struct drm_device *dev = encoder->dev; 44 struct radeon_device *rdev = dev->dev_private; 45 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 46 struct drm_encoder *clone_encoder; 47 uint32_t index_mask = 0; 48 int count; 49 50 /* DIG routing gets problematic */ 51 if (rdev->family >= CHIP_R600) 52 return index_mask; 53 /* LVDS/TV are too wacky */ 54 if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT) 55 return index_mask; 56 /* DVO requires 2x ppll clocks depending on tmds chip */ 57 if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) 58 return index_mask; 59 60 count = -1; 61 list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) { 62 struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder); 63 count++; 64 65 if (clone_encoder == encoder) 66 continue; 67 if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT)) 68 continue; 69 if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT) 70 continue; 71 else 72 index_mask |= (1 << count); 73 } 74 return index_mask; 75} 76 77void radeon_setup_encoder_clones(struct drm_device *dev) 78{ 79 struct drm_encoder *encoder; 80 81 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 82 encoder->possible_clones = radeon_encoder_clones(encoder); 83 } 84} 85 86uint32_t 87radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac) 88{ 89 struct radeon_device *rdev = dev->dev_private; 90 uint32_t ret = 0; 91 92 switch (supported_device) { 93 case ATOM_DEVICE_CRT1_SUPPORT: 94 case ATOM_DEVICE_TV1_SUPPORT: 95 case ATOM_DEVICE_TV2_SUPPORT: 96 case ATOM_DEVICE_CRT2_SUPPORT: 97 case ATOM_DEVICE_CV_SUPPORT: 98 switch (dac) { 99 case 1: /* dac a */ 100 if ((rdev->family == CHIP_RS300) || 101 (rdev->family == CHIP_RS400) || 102 (rdev->family == CHIP_RS480)) 103 ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; 104 else if (ASIC_IS_AVIVO(rdev)) 105 ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1; 106 else 107 ret = ENCODER_INTERNAL_DAC1_ENUM_ID1; 108 break; 109 case 2: /* dac b */ 110 if (ASIC_IS_AVIVO(rdev)) 111 ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1; 112 else { 113 /*if (rdev->family == CHIP_R200) 114 ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; 115 else*/ 116 ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; 117 } 118 break; 119 case 3: /* external dac */ 120 if (ASIC_IS_AVIVO(rdev)) 121 ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; 122 else 123 ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; 124 break; 125 } 126 break; 127 case ATOM_DEVICE_LCD1_SUPPORT: 128 if (ASIC_IS_AVIVO(rdev)) 129 ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; 130 else 131 ret = ENCODER_INTERNAL_LVDS_ENUM_ID1; 132 break; 133 case ATOM_DEVICE_DFP1_SUPPORT: 134 if ((rdev->family == CHIP_RS300) || 135 (rdev->family == CHIP_RS400) || 136 (rdev->family == CHIP_RS480)) 137 ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; 138 else if (ASIC_IS_AVIVO(rdev)) 139 ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1; 140 else 141 ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1; 142 break; 143 case ATOM_DEVICE_LCD2_SUPPORT: 144 case ATOM_DEVICE_DFP2_SUPPORT: 145 if ((rdev->family == CHIP_RS600) || 146 (rdev->family == CHIP_RS690) || 147 (rdev->family == CHIP_RS740)) 148 ret = ENCODER_INTERNAL_DDI_ENUM_ID1; 149 else if (ASIC_IS_AVIVO(rdev)) 150 ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; 151 else 152 ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; 153 break; 154 case ATOM_DEVICE_DFP3_SUPPORT: 155 ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; 156 break; 157 } 158 159 return ret; 160} 161 162void 163radeon_link_encoder_connector(struct drm_device *dev) 164{ 165 struct radeon_device *rdev = dev->dev_private; 166 struct drm_connector *connector; 167 struct radeon_connector *radeon_connector; 168 struct drm_encoder *encoder; 169 struct radeon_encoder *radeon_encoder; 170 171 /* walk the list and link encoders to connectors */ 172 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 173 radeon_connector = to_radeon_connector(connector); 174 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 175 radeon_encoder = to_radeon_encoder(encoder); 176 if (radeon_encoder->devices & radeon_connector->devices) { 177 drm_mode_connector_attach_encoder(connector, encoder); 178 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 179 if (rdev->is_atom_bios) 180 radeon_atom_backlight_init(radeon_encoder, connector); 181 else 182 radeon_legacy_backlight_init(radeon_encoder, connector); 183 rdev->mode_info.bl_encoder = radeon_encoder; 184 } 185 } 186 } 187 } 188} 189 190void radeon_encoder_set_active_device(struct drm_encoder *encoder) 191{ 192 struct drm_device *dev = encoder->dev; 193 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 194 struct drm_connector *connector; 195 196 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 197 if (connector->encoder == encoder) { 198 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 199 radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices; 200 DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n", 201 radeon_encoder->active_device, radeon_encoder->devices, 202 radeon_connector->devices, encoder->encoder_type); 203 } 204 } 205} 206 207struct drm_connector * 208radeon_get_connector_for_encoder(struct drm_encoder *encoder) 209{ 210 struct drm_device *dev = encoder->dev; 211 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 212 struct drm_connector *connector; 213 struct radeon_connector *radeon_connector; 214 215 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 216 radeon_connector = to_radeon_connector(connector); 217 if (radeon_encoder->active_device & radeon_connector->devices) 218 return connector; 219 } 220 return NULL; 221} 222 223struct drm_connector * 224radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) 225{ 226 struct drm_device *dev = encoder->dev; 227 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 228 struct drm_connector *connector; 229 struct radeon_connector *radeon_connector; 230 231 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 232 radeon_connector = to_radeon_connector(connector); 233 if (radeon_encoder->devices & radeon_connector->devices) 234 return connector; 235 } 236 return NULL; 237} 238 239struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder) 240{ 241 struct drm_device *dev = encoder->dev; 242 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 243 struct drm_encoder *other_encoder; 244 struct radeon_encoder *other_radeon_encoder; 245 246 if (radeon_encoder->is_ext_encoder) 247 return NULL; 248 249 list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { 250 if (other_encoder == encoder) 251 continue; 252 other_radeon_encoder = to_radeon_encoder(other_encoder); 253 if (other_radeon_encoder->is_ext_encoder && 254 (radeon_encoder->devices & other_radeon_encoder->devices)) 255 return other_encoder; 256 } 257 return NULL; 258} 259 260u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder) 261{ 262 struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder); 263 264 if (other_encoder) { 265 struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder); 266 267 switch (radeon_encoder->encoder_id) { 268 case ENCODER_OBJECT_ID_TRAVIS: 269 case ENCODER_OBJECT_ID_NUTMEG: 270 return radeon_encoder->encoder_id; 271 default: 272 return ENCODER_OBJECT_ID_NONE; 273 } 274 } 275 return ENCODER_OBJECT_ID_NONE; 276} 277 278void radeon_panel_mode_fixup(struct drm_encoder *encoder, 279 struct drm_display_mode *adjusted_mode) 280{ 281 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 282 struct drm_device *dev = encoder->dev; 283 struct radeon_device *rdev = dev->dev_private; 284 struct drm_display_mode *native_mode = &radeon_encoder->native_mode; 285 unsigned hblank = native_mode->htotal - native_mode->hdisplay; 286 unsigned vblank = native_mode->vtotal - native_mode->vdisplay; 287 unsigned hover = native_mode->hsync_start - native_mode->hdisplay; 288 unsigned vover = native_mode->vsync_start - native_mode->vdisplay; 289 unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start; 290 unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start; 291 292 adjusted_mode->clock = native_mode->clock; 293 adjusted_mode->flags = native_mode->flags; 294 295 if (ASIC_IS_AVIVO(rdev)) { 296 adjusted_mode->hdisplay = native_mode->hdisplay; 297 adjusted_mode->vdisplay = native_mode->vdisplay; 298 } 299 300 adjusted_mode->htotal = native_mode->hdisplay + hblank; 301 adjusted_mode->hsync_start = native_mode->hdisplay + hover; 302 adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width; 303 304 adjusted_mode->vtotal = native_mode->vdisplay + vblank; 305 adjusted_mode->vsync_start = native_mode->vdisplay + vover; 306 adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width; 307 308 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); 309 310 if (ASIC_IS_AVIVO(rdev)) { 311 adjusted_mode->crtc_hdisplay = native_mode->hdisplay; 312 adjusted_mode->crtc_vdisplay = native_mode->vdisplay; 313 } 314 315 adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank; 316 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover; 317 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width; 318 319 adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank; 320 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover; 321 adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width; 322 323} 324 325bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, 326 u32 pixel_clock) 327{ 328 struct drm_device *dev = encoder->dev; 329 struct radeon_device *rdev = dev->dev_private; 330 struct drm_connector *connector; 331 struct radeon_connector *radeon_connector; 332 struct radeon_connector_atom_dig *dig_connector; 333 334 connector = radeon_get_connector_for_encoder(encoder); 335 /* if we don't have an active device yet, just use one of 336 * the connectors tied to the encoder. 337 */ 338 if (!connector) 339 connector = radeon_get_connector_for_encoder_init(encoder); 340 radeon_connector = to_radeon_connector(connector); 341 342 switch (connector->connector_type) { 343 case DRM_MODE_CONNECTOR_DVII: 344 case DRM_MODE_CONNECTOR_HDMIB: 345 if (radeon_connector->use_digital) { 346 /* HDMI 1.3 supports up to 340 Mhz over single link */ 347 if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { 348 if (pixel_clock > 340000) 349 return true; 350 else 351 return false; 352 } else { 353 if (pixel_clock > 165000) 354 return true; 355 else 356 return false; 357 } 358 } else 359 return false; 360 case DRM_MODE_CONNECTOR_DVID: 361 case DRM_MODE_CONNECTOR_HDMIA: 362 case DRM_MODE_CONNECTOR_DisplayPort: 363 dig_connector = radeon_connector->con_priv; 364 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || 365 (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) 366 return false; 367 else { 368 /* HDMI 1.3 supports up to 340 Mhz over single link */ 369 if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { 370 if (pixel_clock > 340000) 371 return true; 372 else 373 return false; 374 } else { 375 if (pixel_clock > 165000) 376 return true; 377 else 378 return false; 379 } 380 } 381 default: 382 return false; 383 } 384} 385 386