1254885Sdumbbell/* 2254885Sdumbbell * Copyright 2007-8 Advanced Micro Devices, Inc. 3254885Sdumbbell * Copyright 2008 Red Hat Inc. 4254885Sdumbbell * 5254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a 6254885Sdumbbell * copy of this software and associated documentation files (the "Software"), 7254885Sdumbbell * to deal in the Software without restriction, including without limitation 8254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the 10254885Sdumbbell * Software is furnished to do so, subject to the following conditions: 11254885Sdumbbell * 12254885Sdumbbell * The above copyright notice and this permission notice shall be included in 13254885Sdumbbell * all copies or substantial portions of the Software. 14254885Sdumbbell * 15254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18254885Sdumbbell * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19254885Sdumbbell * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20254885Sdumbbell * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21254885Sdumbbell * OTHER DEALINGS IN THE SOFTWARE. 22254885Sdumbbell * 23254885Sdumbbell * Authors: Dave Airlie 24254885Sdumbbell * Alex Deucher 25254885Sdumbbell */ 26254885Sdumbbell 27254885Sdumbbell#include <sys/cdefs.h> 28254885Sdumbbell__FBSDID("$FreeBSD$"); 29254885Sdumbbell 30254885Sdumbbell#include <dev/drm2/drmP.h> 31254885Sdumbbell#include <dev/drm2/drm_edid.h> 32254885Sdumbbell#include <dev/drm2/drm_crtc_helper.h> 33254885Sdumbbell#include <dev/drm2/drm_fb_helper.h> 34254885Sdumbbell#include <dev/drm2/radeon/radeon_drm.h> 35254885Sdumbbell#include "radeon.h" 36254885Sdumbbell#include "atom.h" 37254885Sdumbbell 38254885Sdumbbellvoid radeon_connector_hotplug(struct drm_connector *connector) 39254885Sdumbbell{ 40254885Sdumbbell struct drm_device *dev = connector->dev; 41254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 42254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 43254885Sdumbbell 44254885Sdumbbell /* bail if the connector does not have hpd pin, e.g., 45254885Sdumbbell * VGA, TV, etc. 46254885Sdumbbell */ 47254885Sdumbbell if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) 48254885Sdumbbell return; 49254885Sdumbbell 50254885Sdumbbell radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); 51254885Sdumbbell 52254885Sdumbbell /* if the connector is already off, don't turn it back on */ 53254885Sdumbbell if (connector->dpms != DRM_MODE_DPMS_ON) 54254885Sdumbbell return; 55254885Sdumbbell 56254885Sdumbbell /* just deal with DP (not eDP) here. */ 57254885Sdumbbell if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { 58254885Sdumbbell struct radeon_connector_atom_dig *dig_connector = 59254885Sdumbbell radeon_connector->con_priv; 60254885Sdumbbell 61254885Sdumbbell /* if existing sink type was not DP no need to retrain */ 62254885Sdumbbell if (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT) 63254885Sdumbbell return; 64254885Sdumbbell 65254885Sdumbbell /* first get sink type as it may be reset after (un)plug */ 66254885Sdumbbell dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); 67254885Sdumbbell /* don't do anything if sink is not display port, i.e., 68254885Sdumbbell * passive dp->(dvi|hdmi) adaptor 69254885Sdumbbell */ 70254885Sdumbbell if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { 71254885Sdumbbell int saved_dpms = connector->dpms; 72254885Sdumbbell /* Only turn off the display if it's physically disconnected */ 73254885Sdumbbell if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { 74254885Sdumbbell drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); 75254885Sdumbbell } else if (radeon_dp_needs_link_train(radeon_connector)) { 76254885Sdumbbell /* set it to OFF so that drm_helper_connector_dpms() 77254885Sdumbbell * won't return immediately since the current state 78254885Sdumbbell * is ON at this point. 79254885Sdumbbell */ 80254885Sdumbbell connector->dpms = DRM_MODE_DPMS_OFF; 81254885Sdumbbell drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); 82254885Sdumbbell } 83254885Sdumbbell connector->dpms = saved_dpms; 84254885Sdumbbell } 85254885Sdumbbell } 86254885Sdumbbell} 87254885Sdumbbell 88254885Sdumbbellstatic void radeon_property_change_mode(struct drm_encoder *encoder) 89254885Sdumbbell{ 90254885Sdumbbell struct drm_crtc *crtc = encoder->crtc; 91254885Sdumbbell 92254885Sdumbbell if (crtc && crtc->enabled) { 93254885Sdumbbell drm_crtc_helper_set_mode(crtc, &crtc->mode, 94254885Sdumbbell crtc->x, crtc->y, crtc->fb); 95254885Sdumbbell } 96254885Sdumbbell} 97254885Sdumbbell 98254885Sdumbbellint radeon_get_monitor_bpc(struct drm_connector *connector) 99254885Sdumbbell{ 100254885Sdumbbell struct drm_device *dev = connector->dev; 101254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 102254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 103254885Sdumbbell struct radeon_connector_atom_dig *dig_connector; 104254885Sdumbbell int bpc = 8; 105254885Sdumbbell 106254885Sdumbbell switch (connector->connector_type) { 107254885Sdumbbell case DRM_MODE_CONNECTOR_DVII: 108254885Sdumbbell case DRM_MODE_CONNECTOR_HDMIB: 109254885Sdumbbell if (radeon_connector->use_digital) { 110254885Sdumbbell if (drm_detect_hdmi_monitor(radeon_connector->edid)) { 111254885Sdumbbell if (connector->display_info.bpc) 112254885Sdumbbell bpc = connector->display_info.bpc; 113254885Sdumbbell } 114254885Sdumbbell } 115254885Sdumbbell break; 116254885Sdumbbell case DRM_MODE_CONNECTOR_DVID: 117254885Sdumbbell case DRM_MODE_CONNECTOR_HDMIA: 118254885Sdumbbell if (drm_detect_hdmi_monitor(radeon_connector->edid)) { 119254885Sdumbbell if (connector->display_info.bpc) 120254885Sdumbbell bpc = connector->display_info.bpc; 121254885Sdumbbell } 122254885Sdumbbell break; 123254885Sdumbbell case DRM_MODE_CONNECTOR_DisplayPort: 124254885Sdumbbell dig_connector = radeon_connector->con_priv; 125254885Sdumbbell if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || 126254885Sdumbbell (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) || 127254885Sdumbbell drm_detect_hdmi_monitor(radeon_connector->edid)) { 128254885Sdumbbell if (connector->display_info.bpc) 129254885Sdumbbell bpc = connector->display_info.bpc; 130254885Sdumbbell } 131254885Sdumbbell break; 132254885Sdumbbell case DRM_MODE_CONNECTOR_eDP: 133254885Sdumbbell case DRM_MODE_CONNECTOR_LVDS: 134254885Sdumbbell if (connector->display_info.bpc) 135254885Sdumbbell bpc = connector->display_info.bpc; 136254885Sdumbbell else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { 137254885Sdumbbell struct drm_connector_helper_funcs *connector_funcs = 138254885Sdumbbell connector->helper_private; 139254885Sdumbbell struct drm_encoder *encoder = connector_funcs->best_encoder(connector); 140254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 141254885Sdumbbell struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 142254885Sdumbbell 143254885Sdumbbell if (dig->lcd_misc & ATOM_PANEL_MISC_V13_6BIT_PER_COLOR) 144254885Sdumbbell bpc = 6; 145254885Sdumbbell else if (dig->lcd_misc & ATOM_PANEL_MISC_V13_8BIT_PER_COLOR) 146254885Sdumbbell bpc = 8; 147254885Sdumbbell } 148254885Sdumbbell break; 149254885Sdumbbell } 150254885Sdumbbell return bpc; 151254885Sdumbbell} 152254885Sdumbbell 153254885Sdumbbellstatic void 154254885Sdumbbellradeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status) 155254885Sdumbbell{ 156254885Sdumbbell struct drm_device *dev = connector->dev; 157254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 158254885Sdumbbell struct drm_encoder *best_encoder = NULL; 159254885Sdumbbell struct drm_encoder *encoder = NULL; 160254885Sdumbbell struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; 161254885Sdumbbell struct drm_mode_object *obj; 162254885Sdumbbell bool connected; 163254885Sdumbbell int i; 164254885Sdumbbell 165254885Sdumbbell best_encoder = connector_funcs->best_encoder(connector); 166254885Sdumbbell 167254885Sdumbbell for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 168254885Sdumbbell if (connector->encoder_ids[i] == 0) 169254885Sdumbbell break; 170254885Sdumbbell 171254885Sdumbbell obj = drm_mode_object_find(connector->dev, 172254885Sdumbbell connector->encoder_ids[i], 173254885Sdumbbell DRM_MODE_OBJECT_ENCODER); 174254885Sdumbbell if (!obj) 175254885Sdumbbell continue; 176254885Sdumbbell 177254885Sdumbbell encoder = obj_to_encoder(obj); 178254885Sdumbbell 179254885Sdumbbell if ((encoder == best_encoder) && (status == connector_status_connected)) 180254885Sdumbbell connected = true; 181254885Sdumbbell else 182254885Sdumbbell connected = false; 183254885Sdumbbell 184254885Sdumbbell if (rdev->is_atom_bios) 185254885Sdumbbell radeon_atombios_connected_scratch_regs(connector, encoder, connected); 186254885Sdumbbell else 187254885Sdumbbell radeon_combios_connected_scratch_regs(connector, encoder, connected); 188254885Sdumbbell 189254885Sdumbbell } 190254885Sdumbbell} 191254885Sdumbbell 192254885Sdumbbellstatic struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type) 193254885Sdumbbell{ 194254885Sdumbbell struct drm_mode_object *obj; 195254885Sdumbbell struct drm_encoder *encoder; 196254885Sdumbbell int i; 197254885Sdumbbell 198254885Sdumbbell for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 199254885Sdumbbell if (connector->encoder_ids[i] == 0) 200254885Sdumbbell break; 201254885Sdumbbell 202254885Sdumbbell obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER); 203254885Sdumbbell if (!obj) 204254885Sdumbbell continue; 205254885Sdumbbell 206254885Sdumbbell encoder = obj_to_encoder(obj); 207254885Sdumbbell if (encoder->encoder_type == encoder_type) 208254885Sdumbbell return encoder; 209254885Sdumbbell } 210254885Sdumbbell return NULL; 211254885Sdumbbell} 212254885Sdumbbell 213254885Sdumbbellstatic struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) 214254885Sdumbbell{ 215254885Sdumbbell int enc_id = connector->encoder_ids[0]; 216254885Sdumbbell struct drm_mode_object *obj; 217254885Sdumbbell struct drm_encoder *encoder; 218254885Sdumbbell 219254885Sdumbbell /* pick the encoder ids */ 220254885Sdumbbell if (enc_id) { 221254885Sdumbbell obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER); 222254885Sdumbbell if (!obj) 223254885Sdumbbell return NULL; 224254885Sdumbbell encoder = obj_to_encoder(obj); 225254885Sdumbbell return encoder; 226254885Sdumbbell } 227254885Sdumbbell return NULL; 228254885Sdumbbell} 229254885Sdumbbell 230254885Sdumbbell/* 231254885Sdumbbell * radeon_connector_analog_encoder_conflict_solve 232254885Sdumbbell * - search for other connectors sharing this encoder 233254885Sdumbbell * if priority is true, then set them disconnected if this is connected 234254885Sdumbbell * if priority is false, set us disconnected if they are connected 235254885Sdumbbell */ 236254885Sdumbbellstatic enum drm_connector_status 237254885Sdumbbellradeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, 238254885Sdumbbell struct drm_encoder *encoder, 239254885Sdumbbell enum drm_connector_status current_status, 240254885Sdumbbell bool priority) 241254885Sdumbbell{ 242254885Sdumbbell struct drm_device *dev = connector->dev; 243254885Sdumbbell struct drm_connector *conflict; 244254885Sdumbbell struct radeon_connector *radeon_conflict; 245254885Sdumbbell int i; 246254885Sdumbbell 247254885Sdumbbell list_for_each_entry(conflict, &dev->mode_config.connector_list, head) { 248254885Sdumbbell if (conflict == connector) 249254885Sdumbbell continue; 250254885Sdumbbell 251254885Sdumbbell radeon_conflict = to_radeon_connector(conflict); 252254885Sdumbbell for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 253254885Sdumbbell if (conflict->encoder_ids[i] == 0) 254254885Sdumbbell break; 255254885Sdumbbell 256254885Sdumbbell /* if the IDs match */ 257254885Sdumbbell if (conflict->encoder_ids[i] == encoder->base.id) { 258254885Sdumbbell if (conflict->status != connector_status_connected) 259254885Sdumbbell continue; 260254885Sdumbbell 261254885Sdumbbell if (radeon_conflict->use_digital) 262254885Sdumbbell continue; 263254885Sdumbbell 264254885Sdumbbell if (priority == true) { 265254885Sdumbbell DRM_DEBUG_KMS("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); 266254885Sdumbbell DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(connector)); 267254885Sdumbbell conflict->status = connector_status_disconnected; 268254885Sdumbbell radeon_connector_update_scratch_regs(conflict, connector_status_disconnected); 269254885Sdumbbell } else { 270254885Sdumbbell DRM_DEBUG_KMS("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector)); 271254885Sdumbbell DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(conflict)); 272254885Sdumbbell current_status = connector_status_disconnected; 273254885Sdumbbell } 274254885Sdumbbell break; 275254885Sdumbbell } 276254885Sdumbbell } 277254885Sdumbbell } 278254885Sdumbbell return current_status; 279254885Sdumbbell 280254885Sdumbbell} 281254885Sdumbbell 282254885Sdumbbellstatic struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder) 283254885Sdumbbell{ 284254885Sdumbbell struct drm_device *dev = encoder->dev; 285254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 286254885Sdumbbell struct drm_display_mode *mode = NULL; 287254885Sdumbbell struct drm_display_mode *native_mode = &radeon_encoder->native_mode; 288254885Sdumbbell 289254885Sdumbbell if (native_mode->hdisplay != 0 && 290254885Sdumbbell native_mode->vdisplay != 0 && 291254885Sdumbbell native_mode->clock != 0) { 292254885Sdumbbell mode = drm_mode_duplicate(dev, native_mode); 293254885Sdumbbell mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; 294254885Sdumbbell drm_mode_set_name(mode); 295254885Sdumbbell 296254885Sdumbbell DRM_DEBUG_KMS("Adding native panel mode %s\n", mode->name); 297254885Sdumbbell } else if (native_mode->hdisplay != 0 && 298254885Sdumbbell native_mode->vdisplay != 0) { 299254885Sdumbbell /* mac laptops without an edid */ 300254885Sdumbbell /* Note that this is not necessarily the exact panel mode, 301254885Sdumbbell * but an approximation based on the cvt formula. For these 302254885Sdumbbell * systems we should ideally read the mode info out of the 303254885Sdumbbell * registers or add a mode table, but this works and is much 304254885Sdumbbell * simpler. 305254885Sdumbbell */ 306254885Sdumbbell mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); 307254885Sdumbbell mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; 308254885Sdumbbell DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name); 309254885Sdumbbell } 310254885Sdumbbell return mode; 311254885Sdumbbell} 312254885Sdumbbell 313254885Sdumbbellstatic void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_connector *connector) 314254885Sdumbbell{ 315254885Sdumbbell struct drm_device *dev = encoder->dev; 316254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 317254885Sdumbbell struct drm_display_mode *mode = NULL; 318254885Sdumbbell struct drm_display_mode *native_mode = &radeon_encoder->native_mode; 319254885Sdumbbell int i; 320254885Sdumbbell struct mode_size { 321254885Sdumbbell int w; 322254885Sdumbbell int h; 323254885Sdumbbell } common_modes[17] = { 324254885Sdumbbell { 640, 480}, 325254885Sdumbbell { 720, 480}, 326254885Sdumbbell { 800, 600}, 327254885Sdumbbell { 848, 480}, 328254885Sdumbbell {1024, 768}, 329254885Sdumbbell {1152, 768}, 330254885Sdumbbell {1280, 720}, 331254885Sdumbbell {1280, 800}, 332254885Sdumbbell {1280, 854}, 333254885Sdumbbell {1280, 960}, 334254885Sdumbbell {1280, 1024}, 335254885Sdumbbell {1440, 900}, 336254885Sdumbbell {1400, 1050}, 337254885Sdumbbell {1680, 1050}, 338254885Sdumbbell {1600, 1200}, 339254885Sdumbbell {1920, 1080}, 340254885Sdumbbell {1920, 1200} 341254885Sdumbbell }; 342254885Sdumbbell 343254885Sdumbbell for (i = 0; i < 17; i++) { 344254885Sdumbbell if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) { 345254885Sdumbbell if (common_modes[i].w > 1024 || 346254885Sdumbbell common_modes[i].h > 768) 347254885Sdumbbell continue; 348254885Sdumbbell } 349254885Sdumbbell if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 350254885Sdumbbell if (common_modes[i].w > native_mode->hdisplay || 351254885Sdumbbell common_modes[i].h > native_mode->vdisplay || 352254885Sdumbbell (common_modes[i].w == native_mode->hdisplay && 353254885Sdumbbell common_modes[i].h == native_mode->vdisplay)) 354254885Sdumbbell continue; 355254885Sdumbbell } 356254885Sdumbbell if (common_modes[i].w < 320 || common_modes[i].h < 200) 357254885Sdumbbell continue; 358254885Sdumbbell 359254885Sdumbbell mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false); 360254885Sdumbbell drm_mode_probed_add(connector, mode); 361254885Sdumbbell } 362254885Sdumbbell} 363254885Sdumbbell 364254885Sdumbbellstatic int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, 365254885Sdumbbell uint64_t val) 366254885Sdumbbell{ 367254885Sdumbbell struct drm_device *dev = connector->dev; 368254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 369254885Sdumbbell struct drm_encoder *encoder; 370254885Sdumbbell struct radeon_encoder *radeon_encoder; 371254885Sdumbbell 372254885Sdumbbell if (property == rdev->mode_info.coherent_mode_property) { 373254885Sdumbbell struct radeon_encoder_atom_dig *dig; 374254885Sdumbbell bool new_coherent_mode; 375254885Sdumbbell 376254885Sdumbbell /* need to find digital encoder on connector */ 377254885Sdumbbell encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); 378254885Sdumbbell if (!encoder) 379254885Sdumbbell return 0; 380254885Sdumbbell 381254885Sdumbbell radeon_encoder = to_radeon_encoder(encoder); 382254885Sdumbbell 383254885Sdumbbell if (!radeon_encoder->enc_priv) 384254885Sdumbbell return 0; 385254885Sdumbbell 386254885Sdumbbell dig = radeon_encoder->enc_priv; 387254885Sdumbbell new_coherent_mode = val ? true : false; 388254885Sdumbbell if (dig->coherent_mode != new_coherent_mode) { 389254885Sdumbbell dig->coherent_mode = new_coherent_mode; 390254885Sdumbbell radeon_property_change_mode(&radeon_encoder->base); 391254885Sdumbbell } 392254885Sdumbbell } 393254885Sdumbbell 394254885Sdumbbell if (property == rdev->mode_info.underscan_property) { 395254885Sdumbbell /* need to find digital encoder on connector */ 396254885Sdumbbell encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); 397254885Sdumbbell if (!encoder) 398254885Sdumbbell return 0; 399254885Sdumbbell 400254885Sdumbbell radeon_encoder = to_radeon_encoder(encoder); 401254885Sdumbbell 402254885Sdumbbell if (radeon_encoder->underscan_type != val) { 403254885Sdumbbell radeon_encoder->underscan_type = val; 404254885Sdumbbell radeon_property_change_mode(&radeon_encoder->base); 405254885Sdumbbell } 406254885Sdumbbell } 407254885Sdumbbell 408254885Sdumbbell if (property == rdev->mode_info.underscan_hborder_property) { 409254885Sdumbbell /* need to find digital encoder on connector */ 410254885Sdumbbell encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); 411254885Sdumbbell if (!encoder) 412254885Sdumbbell return 0; 413254885Sdumbbell 414254885Sdumbbell radeon_encoder = to_radeon_encoder(encoder); 415254885Sdumbbell 416254885Sdumbbell if (radeon_encoder->underscan_hborder != val) { 417254885Sdumbbell radeon_encoder->underscan_hborder = val; 418254885Sdumbbell radeon_property_change_mode(&radeon_encoder->base); 419254885Sdumbbell } 420254885Sdumbbell } 421254885Sdumbbell 422254885Sdumbbell if (property == rdev->mode_info.underscan_vborder_property) { 423254885Sdumbbell /* need to find digital encoder on connector */ 424254885Sdumbbell encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); 425254885Sdumbbell if (!encoder) 426254885Sdumbbell return 0; 427254885Sdumbbell 428254885Sdumbbell radeon_encoder = to_radeon_encoder(encoder); 429254885Sdumbbell 430254885Sdumbbell if (radeon_encoder->underscan_vborder != val) { 431254885Sdumbbell radeon_encoder->underscan_vborder = val; 432254885Sdumbbell radeon_property_change_mode(&radeon_encoder->base); 433254885Sdumbbell } 434254885Sdumbbell } 435254885Sdumbbell 436254885Sdumbbell if (property == rdev->mode_info.tv_std_property) { 437254885Sdumbbell encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TVDAC); 438254885Sdumbbell if (!encoder) { 439254885Sdumbbell encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_DAC); 440254885Sdumbbell } 441254885Sdumbbell 442254885Sdumbbell if (!encoder) 443254885Sdumbbell return 0; 444254885Sdumbbell 445254885Sdumbbell radeon_encoder = to_radeon_encoder(encoder); 446254885Sdumbbell if (!radeon_encoder->enc_priv) 447254885Sdumbbell return 0; 448254885Sdumbbell if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) { 449254885Sdumbbell struct radeon_encoder_atom_dac *dac_int; 450254885Sdumbbell dac_int = radeon_encoder->enc_priv; 451254885Sdumbbell dac_int->tv_std = val; 452254885Sdumbbell } else { 453254885Sdumbbell struct radeon_encoder_tv_dac *dac_int; 454254885Sdumbbell dac_int = radeon_encoder->enc_priv; 455254885Sdumbbell dac_int->tv_std = val; 456254885Sdumbbell } 457254885Sdumbbell radeon_property_change_mode(&radeon_encoder->base); 458254885Sdumbbell } 459254885Sdumbbell 460254885Sdumbbell if (property == rdev->mode_info.load_detect_property) { 461254885Sdumbbell struct radeon_connector *radeon_connector = 462254885Sdumbbell to_radeon_connector(connector); 463254885Sdumbbell 464254885Sdumbbell if (val == 0) 465254885Sdumbbell radeon_connector->dac_load_detect = false; 466254885Sdumbbell else 467254885Sdumbbell radeon_connector->dac_load_detect = true; 468254885Sdumbbell } 469254885Sdumbbell 470254885Sdumbbell if (property == rdev->mode_info.tmds_pll_property) { 471254885Sdumbbell struct radeon_encoder_int_tmds *tmds = NULL; 472254885Sdumbbell bool ret = false; 473254885Sdumbbell /* need to find digital encoder on connector */ 474254885Sdumbbell encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); 475254885Sdumbbell if (!encoder) 476254885Sdumbbell return 0; 477254885Sdumbbell 478254885Sdumbbell radeon_encoder = to_radeon_encoder(encoder); 479254885Sdumbbell 480254885Sdumbbell tmds = radeon_encoder->enc_priv; 481254885Sdumbbell if (!tmds) 482254885Sdumbbell return 0; 483254885Sdumbbell 484254885Sdumbbell if (val == 0) { 485254885Sdumbbell if (rdev->is_atom_bios) 486254885Sdumbbell ret = radeon_atombios_get_tmds_info(radeon_encoder, tmds); 487254885Sdumbbell else 488254885Sdumbbell ret = radeon_legacy_get_tmds_info_from_combios(radeon_encoder, tmds); 489254885Sdumbbell } 490254885Sdumbbell if (val == 1 || ret == false) { 491254885Sdumbbell radeon_legacy_get_tmds_info_from_table(radeon_encoder, tmds); 492254885Sdumbbell } 493254885Sdumbbell radeon_property_change_mode(&radeon_encoder->base); 494254885Sdumbbell } 495254885Sdumbbell 496254885Sdumbbell return 0; 497254885Sdumbbell} 498254885Sdumbbell 499254885Sdumbbellstatic void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, 500254885Sdumbbell struct drm_connector *connector) 501254885Sdumbbell{ 502254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 503254885Sdumbbell struct drm_display_mode *native_mode = &radeon_encoder->native_mode; 504254885Sdumbbell struct drm_display_mode *t, *mode; 505254885Sdumbbell 506254885Sdumbbell /* If the EDID preferred mode doesn't match the native mode, use it */ 507254885Sdumbbell list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { 508254885Sdumbbell if (mode->type & DRM_MODE_TYPE_PREFERRED) { 509254885Sdumbbell if (mode->hdisplay != native_mode->hdisplay || 510254885Sdumbbell mode->vdisplay != native_mode->vdisplay) 511254885Sdumbbell memcpy(native_mode, mode, sizeof(*mode)); 512254885Sdumbbell } 513254885Sdumbbell } 514254885Sdumbbell 515254885Sdumbbell /* Try to get native mode details from EDID if necessary */ 516254885Sdumbbell if (!native_mode->clock) { 517254885Sdumbbell list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { 518254885Sdumbbell if (mode->hdisplay == native_mode->hdisplay && 519254885Sdumbbell mode->vdisplay == native_mode->vdisplay) { 520254885Sdumbbell *native_mode = *mode; 521254885Sdumbbell drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V); 522254885Sdumbbell DRM_DEBUG_KMS("Determined LVDS native mode details from EDID\n"); 523254885Sdumbbell break; 524254885Sdumbbell } 525254885Sdumbbell } 526254885Sdumbbell } 527254885Sdumbbell 528254885Sdumbbell if (!native_mode->clock) { 529254885Sdumbbell DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n"); 530254885Sdumbbell radeon_encoder->rmx_type = RMX_OFF; 531254885Sdumbbell } 532254885Sdumbbell} 533254885Sdumbbell 534254885Sdumbbellstatic int radeon_lvds_get_modes(struct drm_connector *connector) 535254885Sdumbbell{ 536254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 537254885Sdumbbell struct drm_encoder *encoder; 538254885Sdumbbell int ret = 0; 539254885Sdumbbell struct drm_display_mode *mode; 540254885Sdumbbell 541254885Sdumbbell if (radeon_connector->ddc_bus) { 542254885Sdumbbell ret = radeon_ddc_get_modes(radeon_connector); 543254885Sdumbbell if (ret > 0) { 544254885Sdumbbell encoder = radeon_best_single_encoder(connector); 545254885Sdumbbell if (encoder) { 546254885Sdumbbell radeon_fixup_lvds_native_mode(encoder, connector); 547254885Sdumbbell /* add scaled modes */ 548254885Sdumbbell radeon_add_common_modes(encoder, connector); 549254885Sdumbbell } 550254885Sdumbbell return ret; 551254885Sdumbbell } 552254885Sdumbbell } 553254885Sdumbbell 554254885Sdumbbell encoder = radeon_best_single_encoder(connector); 555254885Sdumbbell if (!encoder) 556254885Sdumbbell return 0; 557254885Sdumbbell 558254885Sdumbbell /* we have no EDID modes */ 559254885Sdumbbell mode = radeon_fp_native_mode(encoder); 560254885Sdumbbell if (mode) { 561254885Sdumbbell ret = 1; 562254885Sdumbbell drm_mode_probed_add(connector, mode); 563254885Sdumbbell /* add the width/height from vbios tables if available */ 564254885Sdumbbell connector->display_info.width_mm = mode->width_mm; 565254885Sdumbbell connector->display_info.height_mm = mode->height_mm; 566254885Sdumbbell /* add scaled modes */ 567254885Sdumbbell radeon_add_common_modes(encoder, connector); 568254885Sdumbbell } 569254885Sdumbbell 570254885Sdumbbell return ret; 571254885Sdumbbell} 572254885Sdumbbell 573254885Sdumbbellstatic int radeon_lvds_mode_valid(struct drm_connector *connector, 574254885Sdumbbell struct drm_display_mode *mode) 575254885Sdumbbell{ 576254885Sdumbbell struct drm_encoder *encoder = radeon_best_single_encoder(connector); 577254885Sdumbbell 578254885Sdumbbell if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) 579254885Sdumbbell return MODE_PANEL; 580254885Sdumbbell 581254885Sdumbbell if (encoder) { 582254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 583254885Sdumbbell struct drm_display_mode *native_mode = &radeon_encoder->native_mode; 584254885Sdumbbell 585254885Sdumbbell /* AVIVO hardware supports downscaling modes larger than the panel 586254885Sdumbbell * to the panel size, but I'm not sure this is desirable. 587254885Sdumbbell */ 588254885Sdumbbell if ((mode->hdisplay > native_mode->hdisplay) || 589254885Sdumbbell (mode->vdisplay > native_mode->vdisplay)) 590254885Sdumbbell return MODE_PANEL; 591254885Sdumbbell 592254885Sdumbbell /* if scaling is disabled, block non-native modes */ 593254885Sdumbbell if (radeon_encoder->rmx_type == RMX_OFF) { 594254885Sdumbbell if ((mode->hdisplay != native_mode->hdisplay) || 595254885Sdumbbell (mode->vdisplay != native_mode->vdisplay)) 596254885Sdumbbell return MODE_PANEL; 597254885Sdumbbell } 598254885Sdumbbell } 599254885Sdumbbell 600254885Sdumbbell return MODE_OK; 601254885Sdumbbell} 602254885Sdumbbell 603254885Sdumbbellstatic enum drm_connector_status 604254885Sdumbbellradeon_lvds_detect(struct drm_connector *connector, bool force) 605254885Sdumbbell{ 606254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 607254885Sdumbbell struct drm_encoder *encoder = radeon_best_single_encoder(connector); 608254885Sdumbbell enum drm_connector_status ret = connector_status_disconnected; 609254885Sdumbbell 610254885Sdumbbell if (encoder) { 611254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 612254885Sdumbbell struct drm_display_mode *native_mode = &radeon_encoder->native_mode; 613254885Sdumbbell 614254885Sdumbbell /* check if panel is valid */ 615254885Sdumbbell if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) 616254885Sdumbbell ret = connector_status_connected; 617254885Sdumbbell 618254885Sdumbbell } 619254885Sdumbbell 620254885Sdumbbell /* check for edid as well */ 621254885Sdumbbell if (radeon_connector->edid) 622254885Sdumbbell ret = connector_status_connected; 623254885Sdumbbell else { 624254885Sdumbbell if (radeon_connector->ddc_bus) { 625254885Sdumbbell radeon_connector->edid = drm_get_edid(&radeon_connector->base, 626254885Sdumbbell radeon_connector->ddc_bus->adapter); 627254885Sdumbbell if (radeon_connector->edid) 628254885Sdumbbell ret = connector_status_connected; 629254885Sdumbbell } 630254885Sdumbbell } 631254885Sdumbbell /* check acpi lid status ??? */ 632254885Sdumbbell 633254885Sdumbbell radeon_connector_update_scratch_regs(connector, ret); 634254885Sdumbbell return ret; 635254885Sdumbbell} 636254885Sdumbbell 637254885Sdumbbellstatic void radeon_connector_destroy(struct drm_connector *connector) 638254885Sdumbbell{ 639254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 640254885Sdumbbell 641254885Sdumbbell if (radeon_connector->edid) 642254885Sdumbbell free(radeon_connector->edid, DRM_MEM_KMS); 643254885Sdumbbell free(radeon_connector->con_priv, DRM_MEM_DRIVER); 644254885Sdumbbell#ifdef DUMBBELL_WIP 645254885Sdumbbell drm_sysfs_connector_remove(connector); 646254885Sdumbbell#endif /* DUMBBELL_WIP */ 647254885Sdumbbell drm_connector_cleanup(connector); 648254885Sdumbbell free(connector, DRM_MEM_DRIVER); 649254885Sdumbbell} 650254885Sdumbbell 651254885Sdumbbellstatic int radeon_lvds_set_property(struct drm_connector *connector, 652254885Sdumbbell struct drm_property *property, 653254885Sdumbbell uint64_t value) 654254885Sdumbbell{ 655254885Sdumbbell struct drm_device *dev = connector->dev; 656254885Sdumbbell struct radeon_encoder *radeon_encoder; 657254885Sdumbbell enum radeon_rmx_type rmx_type; 658254885Sdumbbell 659254885Sdumbbell DRM_DEBUG_KMS("\n"); 660254885Sdumbbell if (property != dev->mode_config.scaling_mode_property) 661254885Sdumbbell return 0; 662254885Sdumbbell 663254885Sdumbbell if (connector->encoder) 664254885Sdumbbell radeon_encoder = to_radeon_encoder(connector->encoder); 665254885Sdumbbell else { 666254885Sdumbbell struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; 667254885Sdumbbell radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); 668254885Sdumbbell } 669254885Sdumbbell 670254885Sdumbbell switch (value) { 671254885Sdumbbell case DRM_MODE_SCALE_NONE: rmx_type = RMX_OFF; break; 672254885Sdumbbell case DRM_MODE_SCALE_CENTER: rmx_type = RMX_CENTER; break; 673254885Sdumbbell case DRM_MODE_SCALE_ASPECT: rmx_type = RMX_ASPECT; break; 674254885Sdumbbell default: 675254885Sdumbbell case DRM_MODE_SCALE_FULLSCREEN: rmx_type = RMX_FULL; break; 676254885Sdumbbell } 677254885Sdumbbell if (radeon_encoder->rmx_type == rmx_type) 678254885Sdumbbell return 0; 679254885Sdumbbell 680254885Sdumbbell radeon_encoder->rmx_type = rmx_type; 681254885Sdumbbell 682254885Sdumbbell radeon_property_change_mode(&radeon_encoder->base); 683254885Sdumbbell return 0; 684254885Sdumbbell} 685254885Sdumbbell 686254885Sdumbbell 687254885Sdumbbellstatic const struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = { 688254885Sdumbbell .get_modes = radeon_lvds_get_modes, 689254885Sdumbbell .mode_valid = radeon_lvds_mode_valid, 690254885Sdumbbell .best_encoder = radeon_best_single_encoder, 691254885Sdumbbell}; 692254885Sdumbbell 693254885Sdumbbellstatic const struct drm_connector_funcs radeon_lvds_connector_funcs = { 694254885Sdumbbell .dpms = drm_helper_connector_dpms, 695254885Sdumbbell .detect = radeon_lvds_detect, 696254885Sdumbbell .fill_modes = drm_helper_probe_single_connector_modes, 697254885Sdumbbell .destroy = radeon_connector_destroy, 698254885Sdumbbell .set_property = radeon_lvds_set_property, 699254885Sdumbbell}; 700254885Sdumbbell 701254885Sdumbbellstatic int radeon_vga_get_modes(struct drm_connector *connector) 702254885Sdumbbell{ 703254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 704254885Sdumbbell int ret; 705254885Sdumbbell 706254885Sdumbbell ret = radeon_ddc_get_modes(radeon_connector); 707254885Sdumbbell 708254885Sdumbbell return ret; 709254885Sdumbbell} 710254885Sdumbbell 711254885Sdumbbellstatic int radeon_vga_mode_valid(struct drm_connector *connector, 712254885Sdumbbell struct drm_display_mode *mode) 713254885Sdumbbell{ 714254885Sdumbbell struct drm_device *dev = connector->dev; 715254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 716254885Sdumbbell 717254885Sdumbbell /* XXX check mode bandwidth */ 718254885Sdumbbell 719254885Sdumbbell if ((mode->clock / 10) > rdev->clock.max_pixel_clock) 720254885Sdumbbell return MODE_CLOCK_HIGH; 721254885Sdumbbell 722254885Sdumbbell return MODE_OK; 723254885Sdumbbell} 724254885Sdumbbell 725254885Sdumbbellstatic enum drm_connector_status 726254885Sdumbbellradeon_vga_detect(struct drm_connector *connector, bool force) 727254885Sdumbbell{ 728254885Sdumbbell struct drm_device *dev = connector->dev; 729254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 730254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 731254885Sdumbbell struct drm_encoder *encoder; 732254885Sdumbbell struct drm_encoder_helper_funcs *encoder_funcs; 733254885Sdumbbell bool dret = false; 734254885Sdumbbell enum drm_connector_status ret = connector_status_disconnected; 735254885Sdumbbell 736254885Sdumbbell encoder = radeon_best_single_encoder(connector); 737254885Sdumbbell if (!encoder) 738254885Sdumbbell ret = connector_status_disconnected; 739254885Sdumbbell 740254885Sdumbbell if (radeon_connector->ddc_bus) 741254885Sdumbbell dret = radeon_ddc_probe(radeon_connector, false); 742254885Sdumbbell if (dret) { 743254885Sdumbbell radeon_connector->detected_by_load = false; 744254885Sdumbbell if (radeon_connector->edid) { 745254885Sdumbbell free(radeon_connector->edid, DRM_MEM_KMS); 746254885Sdumbbell radeon_connector->edid = NULL; 747254885Sdumbbell } 748254885Sdumbbell radeon_connector->edid = drm_get_edid(&radeon_connector->base, radeon_connector->ddc_bus->adapter); 749254885Sdumbbell 750254885Sdumbbell if (!radeon_connector->edid) { 751254885Sdumbbell DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", 752254885Sdumbbell drm_get_connector_name(connector)); 753254885Sdumbbell ret = connector_status_connected; 754254885Sdumbbell } else { 755254885Sdumbbell radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); 756254885Sdumbbell 757254885Sdumbbell /* some oems have boards with separate digital and analog connectors 758254885Sdumbbell * with a shared ddc line (often vga + hdmi) 759254885Sdumbbell */ 760254885Sdumbbell if (radeon_connector->use_digital && radeon_connector->shared_ddc) { 761254885Sdumbbell free(radeon_connector->edid, DRM_MEM_KMS); 762254885Sdumbbell radeon_connector->edid = NULL; 763254885Sdumbbell ret = connector_status_disconnected; 764254885Sdumbbell } else 765254885Sdumbbell ret = connector_status_connected; 766254885Sdumbbell } 767254885Sdumbbell } else { 768254885Sdumbbell 769254885Sdumbbell /* if we aren't forcing don't do destructive polling */ 770254885Sdumbbell if (!force) { 771254885Sdumbbell /* only return the previous status if we last 772254885Sdumbbell * detected a monitor via load. 773254885Sdumbbell */ 774254885Sdumbbell if (radeon_connector->detected_by_load) 775254885Sdumbbell return connector->status; 776254885Sdumbbell else 777254885Sdumbbell return ret; 778254885Sdumbbell } 779254885Sdumbbell 780254885Sdumbbell if (radeon_connector->dac_load_detect && encoder) { 781254885Sdumbbell encoder_funcs = encoder->helper_private; 782254885Sdumbbell ret = encoder_funcs->detect(encoder, connector); 783254885Sdumbbell if (ret != connector_status_disconnected) 784254885Sdumbbell radeon_connector->detected_by_load = true; 785254885Sdumbbell } 786254885Sdumbbell } 787254885Sdumbbell 788254885Sdumbbell if (ret == connector_status_connected) 789254885Sdumbbell ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); 790254885Sdumbbell 791254885Sdumbbell /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the 792254885Sdumbbell * vbios to deal with KVMs. If we have one and are not able to detect a monitor 793254885Sdumbbell * by other means, assume the CRT is connected and use that EDID. 794254885Sdumbbell */ 795254885Sdumbbell if ((!rdev->is_atom_bios) && 796254885Sdumbbell (ret == connector_status_disconnected) && 797254885Sdumbbell rdev->mode_info.bios_hardcoded_edid_size) { 798254885Sdumbbell ret = connector_status_connected; 799254885Sdumbbell } 800254885Sdumbbell 801254885Sdumbbell radeon_connector_update_scratch_regs(connector, ret); 802254885Sdumbbell return ret; 803254885Sdumbbell} 804254885Sdumbbell 805254885Sdumbbellstatic const struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = { 806254885Sdumbbell .get_modes = radeon_vga_get_modes, 807254885Sdumbbell .mode_valid = radeon_vga_mode_valid, 808254885Sdumbbell .best_encoder = radeon_best_single_encoder, 809254885Sdumbbell}; 810254885Sdumbbell 811254885Sdumbbellstatic const struct drm_connector_funcs radeon_vga_connector_funcs = { 812254885Sdumbbell .dpms = drm_helper_connector_dpms, 813254885Sdumbbell .detect = radeon_vga_detect, 814254885Sdumbbell .fill_modes = drm_helper_probe_single_connector_modes, 815254885Sdumbbell .destroy = radeon_connector_destroy, 816254885Sdumbbell .set_property = radeon_connector_set_property, 817254885Sdumbbell}; 818254885Sdumbbell 819254885Sdumbbellstatic int radeon_tv_get_modes(struct drm_connector *connector) 820254885Sdumbbell{ 821254885Sdumbbell struct drm_device *dev = connector->dev; 822254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 823254885Sdumbbell struct drm_display_mode *tv_mode; 824254885Sdumbbell struct drm_encoder *encoder; 825254885Sdumbbell 826254885Sdumbbell encoder = radeon_best_single_encoder(connector); 827254885Sdumbbell if (!encoder) 828254885Sdumbbell return 0; 829254885Sdumbbell 830254885Sdumbbell /* avivo chips can scale any mode */ 831254885Sdumbbell if (rdev->family >= CHIP_RS600) 832254885Sdumbbell /* add scaled modes */ 833254885Sdumbbell radeon_add_common_modes(encoder, connector); 834254885Sdumbbell else { 835254885Sdumbbell /* only 800x600 is supported right now on pre-avivo chips */ 836254885Sdumbbell tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false); 837254885Sdumbbell tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 838254885Sdumbbell drm_mode_probed_add(connector, tv_mode); 839254885Sdumbbell } 840254885Sdumbbell return 1; 841254885Sdumbbell} 842254885Sdumbbell 843254885Sdumbbellstatic int radeon_tv_mode_valid(struct drm_connector *connector, 844254885Sdumbbell struct drm_display_mode *mode) 845254885Sdumbbell{ 846254885Sdumbbell if ((mode->hdisplay > 1024) || (mode->vdisplay > 768)) 847254885Sdumbbell return MODE_CLOCK_RANGE; 848254885Sdumbbell return MODE_OK; 849254885Sdumbbell} 850254885Sdumbbell 851254885Sdumbbellstatic enum drm_connector_status 852254885Sdumbbellradeon_tv_detect(struct drm_connector *connector, bool force) 853254885Sdumbbell{ 854254885Sdumbbell struct drm_encoder *encoder; 855254885Sdumbbell struct drm_encoder_helper_funcs *encoder_funcs; 856254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 857254885Sdumbbell enum drm_connector_status ret = connector_status_disconnected; 858254885Sdumbbell 859254885Sdumbbell if (!radeon_connector->dac_load_detect) 860254885Sdumbbell return ret; 861254885Sdumbbell 862254885Sdumbbell encoder = radeon_best_single_encoder(connector); 863254885Sdumbbell if (!encoder) 864254885Sdumbbell ret = connector_status_disconnected; 865254885Sdumbbell else { 866254885Sdumbbell encoder_funcs = encoder->helper_private; 867254885Sdumbbell ret = encoder_funcs->detect(encoder, connector); 868254885Sdumbbell } 869254885Sdumbbell if (ret == connector_status_connected) 870254885Sdumbbell ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); 871254885Sdumbbell radeon_connector_update_scratch_regs(connector, ret); 872254885Sdumbbell return ret; 873254885Sdumbbell} 874254885Sdumbbell 875254885Sdumbbellstatic const struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = { 876254885Sdumbbell .get_modes = radeon_tv_get_modes, 877254885Sdumbbell .mode_valid = radeon_tv_mode_valid, 878254885Sdumbbell .best_encoder = radeon_best_single_encoder, 879254885Sdumbbell}; 880254885Sdumbbell 881254885Sdumbbellstatic const struct drm_connector_funcs radeon_tv_connector_funcs = { 882254885Sdumbbell .dpms = drm_helper_connector_dpms, 883254885Sdumbbell .detect = radeon_tv_detect, 884254885Sdumbbell .fill_modes = drm_helper_probe_single_connector_modes, 885254885Sdumbbell .destroy = radeon_connector_destroy, 886254885Sdumbbell .set_property = radeon_connector_set_property, 887254885Sdumbbell}; 888254885Sdumbbell 889254885Sdumbbellstatic int radeon_dvi_get_modes(struct drm_connector *connector) 890254885Sdumbbell{ 891254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 892254885Sdumbbell int ret; 893254885Sdumbbell 894254885Sdumbbell ret = radeon_ddc_get_modes(radeon_connector); 895254885Sdumbbell return ret; 896254885Sdumbbell} 897254885Sdumbbell 898254885Sdumbbellstatic bool radeon_check_hpd_status_unchanged(struct drm_connector *connector) 899254885Sdumbbell{ 900254885Sdumbbell struct drm_device *dev = connector->dev; 901254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 902254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 903254885Sdumbbell enum drm_connector_status status; 904254885Sdumbbell 905254885Sdumbbell /* We only trust HPD on R600 and newer ASICS. */ 906254885Sdumbbell if (rdev->family >= CHIP_R600 907254885Sdumbbell && radeon_connector->hpd.hpd != RADEON_HPD_NONE) { 908254885Sdumbbell if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) 909254885Sdumbbell status = connector_status_connected; 910254885Sdumbbell else 911254885Sdumbbell status = connector_status_disconnected; 912254885Sdumbbell if (connector->status == status) 913254885Sdumbbell return true; 914254885Sdumbbell } 915254885Sdumbbell 916254885Sdumbbell return false; 917254885Sdumbbell} 918254885Sdumbbell 919254885Sdumbbell/* 920254885Sdumbbell * DVI is complicated 921254885Sdumbbell * Do a DDC probe, if DDC probe passes, get the full EDID so 922254885Sdumbbell * we can do analog/digital monitor detection at this point. 923254885Sdumbbell * If the monitor is an analog monitor or we got no DDC, 924254885Sdumbbell * we need to find the DAC encoder object for this connector. 925254885Sdumbbell * If we got no DDC, we do load detection on the DAC encoder object. 926254885Sdumbbell * If we got analog DDC or load detection passes on the DAC encoder 927254885Sdumbbell * we have to check if this analog encoder is shared with anyone else (TV) 928254885Sdumbbell * if its shared we have to set the other connector to disconnected. 929254885Sdumbbell */ 930254885Sdumbbellstatic enum drm_connector_status 931254885Sdumbbellradeon_dvi_detect(struct drm_connector *connector, bool force) 932254885Sdumbbell{ 933254885Sdumbbell struct drm_device *dev = connector->dev; 934254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 935254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 936254885Sdumbbell struct drm_encoder *encoder = NULL; 937254885Sdumbbell struct drm_encoder_helper_funcs *encoder_funcs; 938254885Sdumbbell struct drm_mode_object *obj; 939254885Sdumbbell int i; 940254885Sdumbbell enum drm_connector_status ret = connector_status_disconnected; 941254885Sdumbbell bool dret = false, broken_edid = false; 942254885Sdumbbell 943254885Sdumbbell if (!force && radeon_check_hpd_status_unchanged(connector)) 944254885Sdumbbell return connector->status; 945254885Sdumbbell 946254885Sdumbbell if (radeon_connector->ddc_bus) 947254885Sdumbbell dret = radeon_ddc_probe(radeon_connector, false); 948254885Sdumbbell if (dret) { 949254885Sdumbbell radeon_connector->detected_by_load = false; 950254885Sdumbbell if (radeon_connector->edid) { 951254885Sdumbbell free(radeon_connector->edid, DRM_MEM_KMS); 952254885Sdumbbell radeon_connector->edid = NULL; 953254885Sdumbbell } 954254885Sdumbbell radeon_connector->edid = drm_get_edid(&radeon_connector->base, radeon_connector->ddc_bus->adapter); 955254885Sdumbbell 956254885Sdumbbell if (!radeon_connector->edid) { 957254885Sdumbbell DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", 958254885Sdumbbell drm_get_connector_name(connector)); 959254885Sdumbbell /* rs690 seems to have a problem with connectors not existing and always 960254885Sdumbbell * return a block of 0's. If we see this just stop polling on this output */ 961254885Sdumbbell if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) && radeon_connector->base.null_edid_counter) { 962254885Sdumbbell ret = connector_status_disconnected; 963254885Sdumbbell DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); 964254885Sdumbbell radeon_connector->ddc_bus = NULL; 965254885Sdumbbell } else { 966254885Sdumbbell ret = connector_status_connected; 967254885Sdumbbell broken_edid = true; /* defer use_digital to later */ 968254885Sdumbbell } 969254885Sdumbbell } else { 970254885Sdumbbell radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); 971254885Sdumbbell 972254885Sdumbbell /* some oems have boards with separate digital and analog connectors 973254885Sdumbbell * with a shared ddc line (often vga + hdmi) 974254885Sdumbbell */ 975254885Sdumbbell if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) { 976254885Sdumbbell free(radeon_connector->edid, DRM_MEM_KMS); 977254885Sdumbbell radeon_connector->edid = NULL; 978254885Sdumbbell ret = connector_status_disconnected; 979254885Sdumbbell } else 980254885Sdumbbell ret = connector_status_connected; 981254885Sdumbbell 982254885Sdumbbell /* This gets complicated. We have boards with VGA + HDMI with a 983254885Sdumbbell * shared DDC line and we have boards with DVI-D + HDMI with a shared 984254885Sdumbbell * DDC line. The latter is more complex because with DVI<->HDMI adapters 985254885Sdumbbell * you don't really know what's connected to which port as both are digital. 986254885Sdumbbell */ 987254885Sdumbbell if (radeon_connector->shared_ddc && (ret == connector_status_connected)) { 988254885Sdumbbell struct drm_connector *list_connector; 989254885Sdumbbell struct radeon_connector *list_radeon_connector; 990254885Sdumbbell list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) { 991254885Sdumbbell if (connector == list_connector) 992254885Sdumbbell continue; 993254885Sdumbbell list_radeon_connector = to_radeon_connector(list_connector); 994254885Sdumbbell if (list_radeon_connector->shared_ddc && 995254885Sdumbbell (list_radeon_connector->ddc_bus->rec.i2c_id == 996254885Sdumbbell radeon_connector->ddc_bus->rec.i2c_id)) { 997254885Sdumbbell /* cases where both connectors are digital */ 998254885Sdumbbell if (list_connector->connector_type != DRM_MODE_CONNECTOR_VGA) { 999254885Sdumbbell /* hpd is our only option in this case */ 1000254885Sdumbbell if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { 1001254885Sdumbbell free(radeon_connector->edid, DRM_MEM_KMS); 1002254885Sdumbbell radeon_connector->edid = NULL; 1003254885Sdumbbell ret = connector_status_disconnected; 1004254885Sdumbbell } 1005254885Sdumbbell } 1006254885Sdumbbell } 1007254885Sdumbbell } 1008254885Sdumbbell } 1009254885Sdumbbell } 1010254885Sdumbbell } 1011254885Sdumbbell 1012254885Sdumbbell if ((ret == connector_status_connected) && (radeon_connector->use_digital == true)) 1013254885Sdumbbell goto out; 1014254885Sdumbbell 1015254885Sdumbbell /* DVI-D and HDMI-A are digital only */ 1016254885Sdumbbell if ((connector->connector_type == DRM_MODE_CONNECTOR_DVID) || 1017254885Sdumbbell (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA)) 1018254885Sdumbbell goto out; 1019254885Sdumbbell 1020254885Sdumbbell /* if we aren't forcing don't do destructive polling */ 1021254885Sdumbbell if (!force) { 1022254885Sdumbbell /* only return the previous status if we last 1023254885Sdumbbell * detected a monitor via load. 1024254885Sdumbbell */ 1025254885Sdumbbell if (radeon_connector->detected_by_load) 1026254885Sdumbbell ret = connector->status; 1027254885Sdumbbell goto out; 1028254885Sdumbbell } 1029254885Sdumbbell 1030254885Sdumbbell /* find analog encoder */ 1031254885Sdumbbell if (radeon_connector->dac_load_detect) { 1032254885Sdumbbell for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 1033254885Sdumbbell if (connector->encoder_ids[i] == 0) 1034254885Sdumbbell break; 1035254885Sdumbbell 1036254885Sdumbbell obj = drm_mode_object_find(connector->dev, 1037254885Sdumbbell connector->encoder_ids[i], 1038254885Sdumbbell DRM_MODE_OBJECT_ENCODER); 1039254885Sdumbbell if (!obj) 1040254885Sdumbbell continue; 1041254885Sdumbbell 1042254885Sdumbbell encoder = obj_to_encoder(obj); 1043254885Sdumbbell 1044254885Sdumbbell if (encoder->encoder_type != DRM_MODE_ENCODER_DAC && 1045254885Sdumbbell encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) 1046254885Sdumbbell continue; 1047254885Sdumbbell 1048254885Sdumbbell encoder_funcs = encoder->helper_private; 1049254885Sdumbbell if (encoder_funcs->detect) { 1050254885Sdumbbell if (!broken_edid) { 1051254885Sdumbbell if (ret != connector_status_connected) { 1052254885Sdumbbell /* deal with analog monitors without DDC */ 1053254885Sdumbbell ret = encoder_funcs->detect(encoder, connector); 1054254885Sdumbbell if (ret == connector_status_connected) { 1055254885Sdumbbell radeon_connector->use_digital = false; 1056254885Sdumbbell } 1057254885Sdumbbell if (ret != connector_status_disconnected) 1058254885Sdumbbell radeon_connector->detected_by_load = true; 1059254885Sdumbbell } 1060254885Sdumbbell } else { 1061254885Sdumbbell enum drm_connector_status lret; 1062254885Sdumbbell /* assume digital unless load detected otherwise */ 1063254885Sdumbbell radeon_connector->use_digital = true; 1064254885Sdumbbell lret = encoder_funcs->detect(encoder, connector); 1065254885Sdumbbell DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret); 1066254885Sdumbbell if (lret == connector_status_connected) 1067254885Sdumbbell radeon_connector->use_digital = false; 1068254885Sdumbbell } 1069254885Sdumbbell break; 1070254885Sdumbbell } 1071254885Sdumbbell } 1072254885Sdumbbell } 1073254885Sdumbbell 1074254885Sdumbbell if ((ret == connector_status_connected) && (radeon_connector->use_digital == false) && 1075254885Sdumbbell encoder) { 1076254885Sdumbbell ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); 1077254885Sdumbbell } 1078254885Sdumbbell 1079254885Sdumbbell /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the 1080254885Sdumbbell * vbios to deal with KVMs. If we have one and are not able to detect a monitor 1081254885Sdumbbell * by other means, assume the DFP is connected and use that EDID. In most 1082254885Sdumbbell * cases the DVI port is actually a virtual KVM port connected to the service 1083254885Sdumbbell * processor. 1084254885Sdumbbell */ 1085254885Sdumbbellout: 1086254885Sdumbbell if ((!rdev->is_atom_bios) && 1087254885Sdumbbell (ret == connector_status_disconnected) && 1088254885Sdumbbell rdev->mode_info.bios_hardcoded_edid_size) { 1089254885Sdumbbell radeon_connector->use_digital = true; 1090254885Sdumbbell ret = connector_status_connected; 1091254885Sdumbbell } 1092254885Sdumbbell 1093254885Sdumbbell /* updated in get modes as well since we need to know if it's analog or digital */ 1094254885Sdumbbell radeon_connector_update_scratch_regs(connector, ret); 1095254885Sdumbbell return ret; 1096254885Sdumbbell} 1097254885Sdumbbell 1098254885Sdumbbell/* okay need to be smart in here about which encoder to pick */ 1099254885Sdumbbellstatic struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) 1100254885Sdumbbell{ 1101254885Sdumbbell int enc_id = connector->encoder_ids[0]; 1102254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1103254885Sdumbbell struct drm_mode_object *obj; 1104254885Sdumbbell struct drm_encoder *encoder; 1105254885Sdumbbell int i; 1106254885Sdumbbell for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 1107254885Sdumbbell if (connector->encoder_ids[i] == 0) 1108254885Sdumbbell break; 1109254885Sdumbbell 1110254885Sdumbbell obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER); 1111254885Sdumbbell if (!obj) 1112254885Sdumbbell continue; 1113254885Sdumbbell 1114254885Sdumbbell encoder = obj_to_encoder(obj); 1115254885Sdumbbell 1116254885Sdumbbell if (radeon_connector->use_digital == true) { 1117254885Sdumbbell if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS) 1118254885Sdumbbell return encoder; 1119254885Sdumbbell } else { 1120254885Sdumbbell if (encoder->encoder_type == DRM_MODE_ENCODER_DAC || 1121254885Sdumbbell encoder->encoder_type == DRM_MODE_ENCODER_TVDAC) 1122254885Sdumbbell return encoder; 1123254885Sdumbbell } 1124254885Sdumbbell } 1125254885Sdumbbell 1126254885Sdumbbell /* see if we have a default encoder TODO */ 1127254885Sdumbbell 1128254885Sdumbbell /* then check use digitial */ 1129254885Sdumbbell /* pick the first one */ 1130254885Sdumbbell if (enc_id) { 1131254885Sdumbbell obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER); 1132254885Sdumbbell if (!obj) 1133254885Sdumbbell return NULL; 1134254885Sdumbbell encoder = obj_to_encoder(obj); 1135254885Sdumbbell return encoder; 1136254885Sdumbbell } 1137254885Sdumbbell return NULL; 1138254885Sdumbbell} 1139254885Sdumbbell 1140254885Sdumbbellstatic void radeon_dvi_force(struct drm_connector *connector) 1141254885Sdumbbell{ 1142254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1143254885Sdumbbell if (connector->force == DRM_FORCE_ON) 1144254885Sdumbbell radeon_connector->use_digital = false; 1145254885Sdumbbell if (connector->force == DRM_FORCE_ON_DIGITAL) 1146254885Sdumbbell radeon_connector->use_digital = true; 1147254885Sdumbbell} 1148254885Sdumbbell 1149254885Sdumbbellstatic int radeon_dvi_mode_valid(struct drm_connector *connector, 1150254885Sdumbbell struct drm_display_mode *mode) 1151254885Sdumbbell{ 1152254885Sdumbbell struct drm_device *dev = connector->dev; 1153254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1154254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1155254885Sdumbbell 1156254885Sdumbbell /* XXX check mode bandwidth */ 1157254885Sdumbbell 1158254885Sdumbbell /* clocks over 135 MHz have heat issues with DVI on RV100 */ 1159254885Sdumbbell if (radeon_connector->use_digital && 1160254885Sdumbbell (rdev->family == CHIP_RV100) && 1161254885Sdumbbell (mode->clock > 135000)) 1162254885Sdumbbell return MODE_CLOCK_HIGH; 1163254885Sdumbbell 1164254885Sdumbbell if (radeon_connector->use_digital && (mode->clock > 165000)) { 1165254885Sdumbbell if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || 1166254885Sdumbbell (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || 1167254885Sdumbbell (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) 1168254885Sdumbbell return MODE_OK; 1169254885Sdumbbell else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) { 1170254885Sdumbbell if (ASIC_IS_DCE6(rdev)) { 1171254885Sdumbbell /* HDMI 1.3+ supports max clock of 340 Mhz */ 1172254885Sdumbbell if (mode->clock > 340000) 1173254885Sdumbbell return MODE_CLOCK_HIGH; 1174254885Sdumbbell else 1175254885Sdumbbell return MODE_OK; 1176254885Sdumbbell } else 1177254885Sdumbbell return MODE_CLOCK_HIGH; 1178254885Sdumbbell } else 1179254885Sdumbbell return MODE_CLOCK_HIGH; 1180254885Sdumbbell } 1181254885Sdumbbell 1182254885Sdumbbell /* check against the max pixel clock */ 1183254885Sdumbbell if ((mode->clock / 10) > rdev->clock.max_pixel_clock) 1184254885Sdumbbell return MODE_CLOCK_HIGH; 1185254885Sdumbbell 1186254885Sdumbbell return MODE_OK; 1187254885Sdumbbell} 1188254885Sdumbbell 1189254885Sdumbbellstatic const struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { 1190254885Sdumbbell .get_modes = radeon_dvi_get_modes, 1191254885Sdumbbell .mode_valid = radeon_dvi_mode_valid, 1192254885Sdumbbell .best_encoder = radeon_dvi_encoder, 1193254885Sdumbbell}; 1194254885Sdumbbell 1195254885Sdumbbellstatic const struct drm_connector_funcs radeon_dvi_connector_funcs = { 1196254885Sdumbbell .dpms = drm_helper_connector_dpms, 1197254885Sdumbbell .detect = radeon_dvi_detect, 1198254885Sdumbbell .fill_modes = drm_helper_probe_single_connector_modes, 1199254885Sdumbbell .set_property = radeon_connector_set_property, 1200254885Sdumbbell .destroy = radeon_connector_destroy, 1201254885Sdumbbell .force = radeon_dvi_force, 1202254885Sdumbbell}; 1203254885Sdumbbell 1204254885Sdumbbellstatic void radeon_dp_connector_destroy(struct drm_connector *connector) 1205254885Sdumbbell{ 1206254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1207254885Sdumbbell struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; 1208254885Sdumbbell 1209254885Sdumbbell if (radeon_connector->edid) 1210254885Sdumbbell free(radeon_connector->edid, DRM_MEM_KMS); 1211254885Sdumbbell if (radeon_dig_connector->dp_i2c_bus) 1212254885Sdumbbell radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus); 1213254885Sdumbbell free(radeon_connector->con_priv, DRM_MEM_DRIVER); 1214254885Sdumbbell#ifdef DUMBBELL_WIP 1215254885Sdumbbell drm_sysfs_connector_remove(connector); 1216254885Sdumbbell#endif /* DUMBBELL_WIP */ 1217254885Sdumbbell drm_connector_cleanup(connector); 1218254885Sdumbbell free(connector, DRM_MEM_DRIVER); 1219254885Sdumbbell} 1220254885Sdumbbell 1221254885Sdumbbellstatic int radeon_dp_get_modes(struct drm_connector *connector) 1222254885Sdumbbell{ 1223254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1224254885Sdumbbell struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; 1225254885Sdumbbell struct drm_encoder *encoder = radeon_best_single_encoder(connector); 1226254885Sdumbbell int ret; 1227254885Sdumbbell 1228254885Sdumbbell if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || 1229254885Sdumbbell (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { 1230254885Sdumbbell struct drm_display_mode *mode; 1231254885Sdumbbell 1232254885Sdumbbell if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { 1233254885Sdumbbell if (!radeon_dig_connector->edp_on) 1234254885Sdumbbell atombios_set_edp_panel_power(connector, 1235254885Sdumbbell ATOM_TRANSMITTER_ACTION_POWER_ON); 1236254885Sdumbbell ret = radeon_ddc_get_modes(radeon_connector); 1237254885Sdumbbell if (!radeon_dig_connector->edp_on) 1238254885Sdumbbell atombios_set_edp_panel_power(connector, 1239254885Sdumbbell ATOM_TRANSMITTER_ACTION_POWER_OFF); 1240254885Sdumbbell } else { 1241254885Sdumbbell /* need to setup ddc on the bridge */ 1242254885Sdumbbell if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != 1243254885Sdumbbell ENCODER_OBJECT_ID_NONE) { 1244254885Sdumbbell if (encoder) 1245254885Sdumbbell radeon_atom_ext_encoder_setup_ddc(encoder); 1246254885Sdumbbell } 1247254885Sdumbbell ret = radeon_ddc_get_modes(radeon_connector); 1248254885Sdumbbell } 1249254885Sdumbbell 1250254885Sdumbbell if (ret > 0) { 1251254885Sdumbbell if (encoder) { 1252254885Sdumbbell radeon_fixup_lvds_native_mode(encoder, connector); 1253254885Sdumbbell /* add scaled modes */ 1254254885Sdumbbell radeon_add_common_modes(encoder, connector); 1255254885Sdumbbell } 1256254885Sdumbbell return ret; 1257254885Sdumbbell } 1258254885Sdumbbell 1259254885Sdumbbell if (!encoder) 1260254885Sdumbbell return 0; 1261254885Sdumbbell 1262254885Sdumbbell /* we have no EDID modes */ 1263254885Sdumbbell mode = radeon_fp_native_mode(encoder); 1264254885Sdumbbell if (mode) { 1265254885Sdumbbell ret = 1; 1266254885Sdumbbell drm_mode_probed_add(connector, mode); 1267254885Sdumbbell /* add the width/height from vbios tables if available */ 1268254885Sdumbbell connector->display_info.width_mm = mode->width_mm; 1269254885Sdumbbell connector->display_info.height_mm = mode->height_mm; 1270254885Sdumbbell /* add scaled modes */ 1271254885Sdumbbell radeon_add_common_modes(encoder, connector); 1272254885Sdumbbell } 1273254885Sdumbbell } else { 1274254885Sdumbbell /* need to setup ddc on the bridge */ 1275254885Sdumbbell if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != 1276254885Sdumbbell ENCODER_OBJECT_ID_NONE) { 1277254885Sdumbbell if (encoder) 1278254885Sdumbbell radeon_atom_ext_encoder_setup_ddc(encoder); 1279254885Sdumbbell } 1280254885Sdumbbell ret = radeon_ddc_get_modes(radeon_connector); 1281254885Sdumbbell } 1282254885Sdumbbell 1283254885Sdumbbell return ret; 1284254885Sdumbbell} 1285254885Sdumbbell 1286254885Sdumbbellu16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector) 1287254885Sdumbbell{ 1288254885Sdumbbell struct drm_mode_object *obj; 1289254885Sdumbbell struct drm_encoder *encoder; 1290254885Sdumbbell struct radeon_encoder *radeon_encoder; 1291254885Sdumbbell int i; 1292254885Sdumbbell 1293254885Sdumbbell for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 1294254885Sdumbbell if (connector->encoder_ids[i] == 0) 1295254885Sdumbbell break; 1296254885Sdumbbell 1297254885Sdumbbell obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER); 1298254885Sdumbbell if (!obj) 1299254885Sdumbbell continue; 1300254885Sdumbbell 1301254885Sdumbbell encoder = obj_to_encoder(obj); 1302254885Sdumbbell radeon_encoder = to_radeon_encoder(encoder); 1303254885Sdumbbell 1304254885Sdumbbell switch (radeon_encoder->encoder_id) { 1305254885Sdumbbell case ENCODER_OBJECT_ID_TRAVIS: 1306254885Sdumbbell case ENCODER_OBJECT_ID_NUTMEG: 1307254885Sdumbbell return radeon_encoder->encoder_id; 1308254885Sdumbbell default: 1309254885Sdumbbell break; 1310254885Sdumbbell } 1311254885Sdumbbell } 1312254885Sdumbbell 1313254885Sdumbbell return ENCODER_OBJECT_ID_NONE; 1314254885Sdumbbell} 1315254885Sdumbbell 1316254885Sdumbbellbool radeon_connector_encoder_is_hbr2(struct drm_connector *connector) 1317254885Sdumbbell{ 1318254885Sdumbbell struct drm_mode_object *obj; 1319254885Sdumbbell struct drm_encoder *encoder; 1320254885Sdumbbell struct radeon_encoder *radeon_encoder; 1321254885Sdumbbell int i; 1322254885Sdumbbell bool found = false; 1323254885Sdumbbell 1324254885Sdumbbell for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 1325254885Sdumbbell if (connector->encoder_ids[i] == 0) 1326254885Sdumbbell break; 1327254885Sdumbbell 1328254885Sdumbbell obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER); 1329254885Sdumbbell if (!obj) 1330254885Sdumbbell continue; 1331254885Sdumbbell 1332254885Sdumbbell encoder = obj_to_encoder(obj); 1333254885Sdumbbell radeon_encoder = to_radeon_encoder(encoder); 1334254885Sdumbbell if (radeon_encoder->caps & ATOM_ENCODER_CAP_RECORD_HBR2) 1335254885Sdumbbell found = true; 1336254885Sdumbbell } 1337254885Sdumbbell 1338254885Sdumbbell return found; 1339254885Sdumbbell} 1340254885Sdumbbell 1341254885Sdumbbellbool radeon_connector_is_dp12_capable(struct drm_connector *connector) 1342254885Sdumbbell{ 1343254885Sdumbbell struct drm_device *dev = connector->dev; 1344254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1345254885Sdumbbell 1346254885Sdumbbell if (ASIC_IS_DCE5(rdev) && 1347254885Sdumbbell (rdev->clock.dp_extclk >= 53900) && 1348254885Sdumbbell radeon_connector_encoder_is_hbr2(connector)) { 1349254885Sdumbbell return true; 1350254885Sdumbbell } 1351254885Sdumbbell 1352254885Sdumbbell return false; 1353254885Sdumbbell} 1354254885Sdumbbell 1355254885Sdumbbellstatic enum drm_connector_status 1356254885Sdumbbellradeon_dp_detect(struct drm_connector *connector, bool force) 1357254885Sdumbbell{ 1358254885Sdumbbell struct drm_device *dev = connector->dev; 1359254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1360254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1361254885Sdumbbell enum drm_connector_status ret = connector_status_disconnected; 1362254885Sdumbbell struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; 1363254885Sdumbbell struct drm_encoder *encoder = radeon_best_single_encoder(connector); 1364254885Sdumbbell 1365254885Sdumbbell if (!force && radeon_check_hpd_status_unchanged(connector)) 1366254885Sdumbbell return connector->status; 1367254885Sdumbbell 1368254885Sdumbbell if (radeon_connector->edid) { 1369254885Sdumbbell free(radeon_connector->edid, DRM_MEM_KMS); 1370254885Sdumbbell radeon_connector->edid = NULL; 1371254885Sdumbbell } 1372254885Sdumbbell 1373254885Sdumbbell if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || 1374254885Sdumbbell (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { 1375254885Sdumbbell if (encoder) { 1376254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1377254885Sdumbbell struct drm_display_mode *native_mode = &radeon_encoder->native_mode; 1378254885Sdumbbell 1379254885Sdumbbell /* check if panel is valid */ 1380254885Sdumbbell if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) 1381254885Sdumbbell ret = connector_status_connected; 1382254885Sdumbbell } 1383254885Sdumbbell /* eDP is always DP */ 1384254885Sdumbbell radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; 1385254885Sdumbbell if (!radeon_dig_connector->edp_on) 1386254885Sdumbbell atombios_set_edp_panel_power(connector, 1387254885Sdumbbell ATOM_TRANSMITTER_ACTION_POWER_ON); 1388254885Sdumbbell if (radeon_dp_getdpcd(radeon_connector)) 1389254885Sdumbbell ret = connector_status_connected; 1390254885Sdumbbell if (!radeon_dig_connector->edp_on) 1391254885Sdumbbell atombios_set_edp_panel_power(connector, 1392254885Sdumbbell ATOM_TRANSMITTER_ACTION_POWER_OFF); 1393254885Sdumbbell } else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != 1394254885Sdumbbell ENCODER_OBJECT_ID_NONE) { 1395254885Sdumbbell /* DP bridges are always DP */ 1396254885Sdumbbell radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; 1397254885Sdumbbell /* get the DPCD from the bridge */ 1398254885Sdumbbell radeon_dp_getdpcd(radeon_connector); 1399254885Sdumbbell 1400254885Sdumbbell if (encoder) { 1401254885Sdumbbell /* setup ddc on the bridge */ 1402254885Sdumbbell radeon_atom_ext_encoder_setup_ddc(encoder); 1403254885Sdumbbell /* bridge chips are always aux */ 1404254885Sdumbbell if (radeon_ddc_probe(radeon_connector, true)) /* try DDC */ 1405254885Sdumbbell ret = connector_status_connected; 1406254885Sdumbbell else if (radeon_connector->dac_load_detect) { /* try load detection */ 1407254885Sdumbbell struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; 1408254885Sdumbbell ret = encoder_funcs->detect(encoder, connector); 1409254885Sdumbbell } 1410254885Sdumbbell } 1411254885Sdumbbell } else { 1412254885Sdumbbell radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); 1413254885Sdumbbell if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { 1414254885Sdumbbell ret = connector_status_connected; 1415254885Sdumbbell if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) 1416254885Sdumbbell radeon_dp_getdpcd(radeon_connector); 1417254885Sdumbbell } else { 1418254885Sdumbbell if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { 1419254885Sdumbbell if (radeon_dp_getdpcd(radeon_connector)) 1420254885Sdumbbell ret = connector_status_connected; 1421254885Sdumbbell } else { 1422254885Sdumbbell /* try non-aux ddc (DP to DVI/HMDI/etc. adapter) */ 1423254885Sdumbbell if (radeon_ddc_probe(radeon_connector, false)) 1424254885Sdumbbell ret = connector_status_connected; 1425254885Sdumbbell } 1426254885Sdumbbell } 1427254885Sdumbbell } 1428254885Sdumbbell 1429254885Sdumbbell radeon_connector_update_scratch_regs(connector, ret); 1430254885Sdumbbell return ret; 1431254885Sdumbbell} 1432254885Sdumbbell 1433254885Sdumbbellstatic int radeon_dp_mode_valid(struct drm_connector *connector, 1434254885Sdumbbell struct drm_display_mode *mode) 1435254885Sdumbbell{ 1436254885Sdumbbell struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1437254885Sdumbbell struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; 1438254885Sdumbbell 1439254885Sdumbbell /* XXX check mode bandwidth */ 1440254885Sdumbbell 1441254885Sdumbbell if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || 1442254885Sdumbbell (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { 1443254885Sdumbbell struct drm_encoder *encoder = radeon_best_single_encoder(connector); 1444254885Sdumbbell 1445254885Sdumbbell if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) 1446254885Sdumbbell return MODE_PANEL; 1447254885Sdumbbell 1448254885Sdumbbell if (encoder) { 1449254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1450254885Sdumbbell struct drm_display_mode *native_mode = &radeon_encoder->native_mode; 1451254885Sdumbbell 1452254885Sdumbbell /* AVIVO hardware supports downscaling modes larger than the panel 1453254885Sdumbbell * to the panel size, but I'm not sure this is desirable. 1454254885Sdumbbell */ 1455254885Sdumbbell if ((mode->hdisplay > native_mode->hdisplay) || 1456254885Sdumbbell (mode->vdisplay > native_mode->vdisplay)) 1457254885Sdumbbell return MODE_PANEL; 1458254885Sdumbbell 1459254885Sdumbbell /* if scaling is disabled, block non-native modes */ 1460254885Sdumbbell if (radeon_encoder->rmx_type == RMX_OFF) { 1461254885Sdumbbell if ((mode->hdisplay != native_mode->hdisplay) || 1462254885Sdumbbell (mode->vdisplay != native_mode->vdisplay)) 1463254885Sdumbbell return MODE_PANEL; 1464254885Sdumbbell } 1465254885Sdumbbell } 1466254885Sdumbbell return MODE_OK; 1467254885Sdumbbell } else { 1468254885Sdumbbell if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || 1469254885Sdumbbell (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) 1470254885Sdumbbell return radeon_dp_mode_valid_helper(connector, mode); 1471254885Sdumbbell else 1472254885Sdumbbell return MODE_OK; 1473254885Sdumbbell } 1474254885Sdumbbell} 1475254885Sdumbbell 1476254885Sdumbbellstatic const struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { 1477254885Sdumbbell .get_modes = radeon_dp_get_modes, 1478254885Sdumbbell .mode_valid = radeon_dp_mode_valid, 1479254885Sdumbbell .best_encoder = radeon_dvi_encoder, 1480254885Sdumbbell}; 1481254885Sdumbbell 1482254885Sdumbbellstatic const struct drm_connector_funcs radeon_dp_connector_funcs = { 1483254885Sdumbbell .dpms = drm_helper_connector_dpms, 1484254885Sdumbbell .detect = radeon_dp_detect, 1485254885Sdumbbell .fill_modes = drm_helper_probe_single_connector_modes, 1486254885Sdumbbell .set_property = radeon_connector_set_property, 1487254885Sdumbbell .destroy = radeon_dp_connector_destroy, 1488254885Sdumbbell .force = radeon_dvi_force, 1489254885Sdumbbell}; 1490254885Sdumbbell 1491254885Sdumbbellvoid 1492254885Sdumbbellradeon_add_atom_connector(struct drm_device *dev, 1493254885Sdumbbell uint32_t connector_id, 1494254885Sdumbbell uint32_t supported_device, 1495254885Sdumbbell int connector_type, 1496254885Sdumbbell struct radeon_i2c_bus_rec *i2c_bus, 1497254885Sdumbbell uint32_t igp_lane_info, 1498254885Sdumbbell uint16_t connector_object_id, 1499254885Sdumbbell struct radeon_hpd *hpd, 1500254885Sdumbbell struct radeon_router *router) 1501254885Sdumbbell{ 1502254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1503254885Sdumbbell struct drm_connector *connector; 1504254885Sdumbbell struct radeon_connector *radeon_connector; 1505254885Sdumbbell struct radeon_connector_atom_dig *radeon_dig_connector; 1506254885Sdumbbell struct drm_encoder *encoder; 1507254885Sdumbbell struct radeon_encoder *radeon_encoder; 1508254885Sdumbbell uint32_t subpixel_order = SubPixelNone; 1509254885Sdumbbell bool shared_ddc = false; 1510254885Sdumbbell bool is_dp_bridge = false; 1511254885Sdumbbell 1512254885Sdumbbell if (connector_type == DRM_MODE_CONNECTOR_Unknown) 1513254885Sdumbbell return; 1514254885Sdumbbell 1515254885Sdumbbell /* if the user selected tv=0 don't try and add the connector */ 1516254885Sdumbbell if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) || 1517254885Sdumbbell (connector_type == DRM_MODE_CONNECTOR_Composite) || 1518254885Sdumbbell (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) && 1519254885Sdumbbell (radeon_tv == 0)) 1520254885Sdumbbell return; 1521254885Sdumbbell 1522254885Sdumbbell /* see if we already added it */ 1523254885Sdumbbell list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1524254885Sdumbbell radeon_connector = to_radeon_connector(connector); 1525254885Sdumbbell if (radeon_connector->connector_id == connector_id) { 1526254885Sdumbbell radeon_connector->devices |= supported_device; 1527254885Sdumbbell return; 1528254885Sdumbbell } 1529254885Sdumbbell if (radeon_connector->ddc_bus && i2c_bus->valid) { 1530254885Sdumbbell if (radeon_connector->ddc_bus->rec.i2c_id == i2c_bus->i2c_id) { 1531254885Sdumbbell radeon_connector->shared_ddc = true; 1532254885Sdumbbell shared_ddc = true; 1533254885Sdumbbell } 1534254885Sdumbbell if (radeon_connector->router_bus && router->ddc_valid && 1535254885Sdumbbell (radeon_connector->router.router_id == router->router_id)) { 1536254885Sdumbbell radeon_connector->shared_ddc = false; 1537254885Sdumbbell shared_ddc = false; 1538254885Sdumbbell } 1539254885Sdumbbell } 1540254885Sdumbbell } 1541254885Sdumbbell 1542254885Sdumbbell /* check if it's a dp bridge */ 1543254885Sdumbbell list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 1544254885Sdumbbell radeon_encoder = to_radeon_encoder(encoder); 1545254885Sdumbbell if (radeon_encoder->devices & supported_device) { 1546254885Sdumbbell switch (radeon_encoder->encoder_id) { 1547254885Sdumbbell case ENCODER_OBJECT_ID_TRAVIS: 1548254885Sdumbbell case ENCODER_OBJECT_ID_NUTMEG: 1549254885Sdumbbell is_dp_bridge = true; 1550254885Sdumbbell break; 1551254885Sdumbbell default: 1552254885Sdumbbell break; 1553254885Sdumbbell } 1554254885Sdumbbell } 1555254885Sdumbbell } 1556254885Sdumbbell 1557254885Sdumbbell radeon_connector = malloc(sizeof(struct radeon_connector), 1558254885Sdumbbell DRM_MEM_DRIVER, M_ZERO | M_WAITOK); 1559254885Sdumbbell if (!radeon_connector) 1560254885Sdumbbell return; 1561254885Sdumbbell 1562254885Sdumbbell connector = &radeon_connector->base; 1563254885Sdumbbell 1564254885Sdumbbell radeon_connector->connector_id = connector_id; 1565254885Sdumbbell radeon_connector->devices = supported_device; 1566254885Sdumbbell radeon_connector->shared_ddc = shared_ddc; 1567254885Sdumbbell radeon_connector->connector_object_id = connector_object_id; 1568254885Sdumbbell radeon_connector->hpd = *hpd; 1569254885Sdumbbell 1570254885Sdumbbell radeon_connector->router = *router; 1571254885Sdumbbell if (router->ddc_valid || router->cd_valid) { 1572254885Sdumbbell radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); 1573254885Sdumbbell if (!radeon_connector->router_bus) 1574254885Sdumbbell DRM_ERROR("Failed to assign router i2c bus! Check dmesg for i2c errors.\n"); 1575254885Sdumbbell } 1576254885Sdumbbell 1577254885Sdumbbell if (is_dp_bridge) { 1578254885Sdumbbell radeon_dig_connector = malloc( 1579254885Sdumbbell sizeof(struct radeon_connector_atom_dig), 1580254885Sdumbbell DRM_MEM_DRIVER, M_ZERO | M_WAITOK); 1581254885Sdumbbell if (!radeon_dig_connector) 1582254885Sdumbbell goto failed; 1583254885Sdumbbell radeon_dig_connector->igp_lane_info = igp_lane_info; 1584254885Sdumbbell radeon_connector->con_priv = radeon_dig_connector; 1585254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); 1586254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); 1587254885Sdumbbell if (i2c_bus->valid) { 1588254885Sdumbbell /* add DP i2c bus */ 1589254885Sdumbbell if (connector_type == DRM_MODE_CONNECTOR_eDP) 1590254885Sdumbbell radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch"); 1591254885Sdumbbell else 1592254885Sdumbbell radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); 1593254885Sdumbbell if (!radeon_dig_connector->dp_i2c_bus) 1594254885Sdumbbell DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); 1595254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 1596254885Sdumbbell if (!radeon_connector->ddc_bus) 1597254885Sdumbbell DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 1598254885Sdumbbell } 1599254885Sdumbbell switch (connector_type) { 1600254885Sdumbbell case DRM_MODE_CONNECTOR_VGA: 1601254885Sdumbbell case DRM_MODE_CONNECTOR_DVIA: 1602254885Sdumbbell default: 1603254885Sdumbbell connector->interlace_allowed = true; 1604254885Sdumbbell connector->doublescan_allowed = true; 1605254885Sdumbbell radeon_connector->dac_load_detect = true; 1606254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1607254885Sdumbbell rdev->mode_info.load_detect_property, 1608254885Sdumbbell 1); 1609254885Sdumbbell break; 1610254885Sdumbbell case DRM_MODE_CONNECTOR_DVII: 1611254885Sdumbbell case DRM_MODE_CONNECTOR_DVID: 1612254885Sdumbbell case DRM_MODE_CONNECTOR_HDMIA: 1613254885Sdumbbell case DRM_MODE_CONNECTOR_HDMIB: 1614254885Sdumbbell case DRM_MODE_CONNECTOR_DisplayPort: 1615254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1616254885Sdumbbell rdev->mode_info.underscan_property, 1617254885Sdumbbell UNDERSCAN_OFF); 1618254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1619254885Sdumbbell rdev->mode_info.underscan_hborder_property, 1620254885Sdumbbell 0); 1621254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1622254885Sdumbbell rdev->mode_info.underscan_vborder_property, 1623254885Sdumbbell 0); 1624254885Sdumbbell subpixel_order = SubPixelHorizontalRGB; 1625254885Sdumbbell connector->interlace_allowed = true; 1626254885Sdumbbell if (connector_type == DRM_MODE_CONNECTOR_HDMIB) 1627254885Sdumbbell connector->doublescan_allowed = true; 1628254885Sdumbbell else 1629254885Sdumbbell connector->doublescan_allowed = false; 1630254885Sdumbbell if (connector_type == DRM_MODE_CONNECTOR_DVII) { 1631254885Sdumbbell radeon_connector->dac_load_detect = true; 1632254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1633254885Sdumbbell rdev->mode_info.load_detect_property, 1634254885Sdumbbell 1); 1635254885Sdumbbell } 1636254885Sdumbbell break; 1637254885Sdumbbell case DRM_MODE_CONNECTOR_LVDS: 1638254885Sdumbbell case DRM_MODE_CONNECTOR_eDP: 1639254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1640254885Sdumbbell dev->mode_config.scaling_mode_property, 1641254885Sdumbbell DRM_MODE_SCALE_FULLSCREEN); 1642254885Sdumbbell subpixel_order = SubPixelHorizontalRGB; 1643254885Sdumbbell connector->interlace_allowed = false; 1644254885Sdumbbell connector->doublescan_allowed = false; 1645254885Sdumbbell break; 1646254885Sdumbbell } 1647254885Sdumbbell } else { 1648254885Sdumbbell switch (connector_type) { 1649254885Sdumbbell case DRM_MODE_CONNECTOR_VGA: 1650254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1651254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1652254885Sdumbbell if (i2c_bus->valid) { 1653254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 1654254885Sdumbbell if (!radeon_connector->ddc_bus) 1655254885Sdumbbell DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 1656254885Sdumbbell } 1657254885Sdumbbell radeon_connector->dac_load_detect = true; 1658254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1659254885Sdumbbell rdev->mode_info.load_detect_property, 1660254885Sdumbbell 1); 1661254885Sdumbbell /* no HPD on analog connectors */ 1662254885Sdumbbell radeon_connector->hpd.hpd = RADEON_HPD_NONE; 1663254885Sdumbbell connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1664254885Sdumbbell connector->interlace_allowed = true; 1665254885Sdumbbell connector->doublescan_allowed = true; 1666254885Sdumbbell break; 1667254885Sdumbbell case DRM_MODE_CONNECTOR_DVIA: 1668254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1669254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1670254885Sdumbbell if (i2c_bus->valid) { 1671254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 1672254885Sdumbbell if (!radeon_connector->ddc_bus) 1673254885Sdumbbell DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 1674254885Sdumbbell } 1675254885Sdumbbell radeon_connector->dac_load_detect = true; 1676254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1677254885Sdumbbell rdev->mode_info.load_detect_property, 1678254885Sdumbbell 1); 1679254885Sdumbbell /* no HPD on analog connectors */ 1680254885Sdumbbell radeon_connector->hpd.hpd = RADEON_HPD_NONE; 1681254885Sdumbbell connector->interlace_allowed = true; 1682254885Sdumbbell connector->doublescan_allowed = true; 1683254885Sdumbbell break; 1684254885Sdumbbell case DRM_MODE_CONNECTOR_DVII: 1685254885Sdumbbell case DRM_MODE_CONNECTOR_DVID: 1686254885Sdumbbell radeon_dig_connector = malloc( 1687254885Sdumbbell sizeof(struct radeon_connector_atom_dig), 1688254885Sdumbbell DRM_MEM_DRIVER, M_ZERO | M_WAITOK); 1689254885Sdumbbell if (!radeon_dig_connector) 1690254885Sdumbbell goto failed; 1691254885Sdumbbell radeon_dig_connector->igp_lane_info = igp_lane_info; 1692254885Sdumbbell radeon_connector->con_priv = radeon_dig_connector; 1693254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); 1694254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); 1695254885Sdumbbell if (i2c_bus->valid) { 1696254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 1697254885Sdumbbell if (!radeon_connector->ddc_bus) 1698254885Sdumbbell DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 1699254885Sdumbbell } 1700254885Sdumbbell subpixel_order = SubPixelHorizontalRGB; 1701254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1702254885Sdumbbell rdev->mode_info.coherent_mode_property, 1703254885Sdumbbell 1); 1704254885Sdumbbell if (ASIC_IS_AVIVO(rdev)) { 1705254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1706254885Sdumbbell rdev->mode_info.underscan_property, 1707254885Sdumbbell UNDERSCAN_OFF); 1708254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1709254885Sdumbbell rdev->mode_info.underscan_hborder_property, 1710254885Sdumbbell 0); 1711254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1712254885Sdumbbell rdev->mode_info.underscan_vborder_property, 1713254885Sdumbbell 0); 1714254885Sdumbbell } 1715254885Sdumbbell if (connector_type == DRM_MODE_CONNECTOR_DVII) { 1716254885Sdumbbell radeon_connector->dac_load_detect = true; 1717254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1718254885Sdumbbell rdev->mode_info.load_detect_property, 1719254885Sdumbbell 1); 1720254885Sdumbbell } 1721254885Sdumbbell connector->interlace_allowed = true; 1722254885Sdumbbell if (connector_type == DRM_MODE_CONNECTOR_DVII) 1723254885Sdumbbell connector->doublescan_allowed = true; 1724254885Sdumbbell else 1725254885Sdumbbell connector->doublescan_allowed = false; 1726254885Sdumbbell break; 1727254885Sdumbbell case DRM_MODE_CONNECTOR_HDMIA: 1728254885Sdumbbell case DRM_MODE_CONNECTOR_HDMIB: 1729254885Sdumbbell radeon_dig_connector = malloc( 1730254885Sdumbbell sizeof(struct radeon_connector_atom_dig), 1731254885Sdumbbell DRM_MEM_DRIVER, M_ZERO | M_WAITOK); 1732254885Sdumbbell if (!radeon_dig_connector) 1733254885Sdumbbell goto failed; 1734254885Sdumbbell radeon_dig_connector->igp_lane_info = igp_lane_info; 1735254885Sdumbbell radeon_connector->con_priv = radeon_dig_connector; 1736254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); 1737254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); 1738254885Sdumbbell if (i2c_bus->valid) { 1739254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 1740254885Sdumbbell if (!radeon_connector->ddc_bus) 1741254885Sdumbbell DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 1742254885Sdumbbell } 1743254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1744254885Sdumbbell rdev->mode_info.coherent_mode_property, 1745254885Sdumbbell 1); 1746254885Sdumbbell if (ASIC_IS_AVIVO(rdev)) { 1747254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1748254885Sdumbbell rdev->mode_info.underscan_property, 1749254885Sdumbbell UNDERSCAN_OFF); 1750254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1751254885Sdumbbell rdev->mode_info.underscan_hborder_property, 1752254885Sdumbbell 0); 1753254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1754254885Sdumbbell rdev->mode_info.underscan_vborder_property, 1755254885Sdumbbell 0); 1756254885Sdumbbell } 1757254885Sdumbbell subpixel_order = SubPixelHorizontalRGB; 1758254885Sdumbbell connector->interlace_allowed = true; 1759254885Sdumbbell if (connector_type == DRM_MODE_CONNECTOR_HDMIB) 1760254885Sdumbbell connector->doublescan_allowed = true; 1761254885Sdumbbell else 1762254885Sdumbbell connector->doublescan_allowed = false; 1763254885Sdumbbell break; 1764254885Sdumbbell case DRM_MODE_CONNECTOR_DisplayPort: 1765254885Sdumbbell radeon_dig_connector = malloc( 1766254885Sdumbbell sizeof(struct radeon_connector_atom_dig), 1767254885Sdumbbell DRM_MEM_DRIVER, M_ZERO | M_WAITOK); 1768254885Sdumbbell if (!radeon_dig_connector) 1769254885Sdumbbell goto failed; 1770254885Sdumbbell radeon_dig_connector->igp_lane_info = igp_lane_info; 1771254885Sdumbbell radeon_connector->con_priv = radeon_dig_connector; 1772254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); 1773254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); 1774254885Sdumbbell if (i2c_bus->valid) { 1775254885Sdumbbell /* add DP i2c bus */ 1776254885Sdumbbell radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); 1777254885Sdumbbell if (!radeon_dig_connector->dp_i2c_bus) 1778254885Sdumbbell DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); 1779254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 1780254885Sdumbbell if (!radeon_connector->ddc_bus) 1781254885Sdumbbell DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 1782254885Sdumbbell } 1783254885Sdumbbell subpixel_order = SubPixelHorizontalRGB; 1784254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1785254885Sdumbbell rdev->mode_info.coherent_mode_property, 1786254885Sdumbbell 1); 1787254885Sdumbbell if (ASIC_IS_AVIVO(rdev)) { 1788254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1789254885Sdumbbell rdev->mode_info.underscan_property, 1790254885Sdumbbell UNDERSCAN_OFF); 1791254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1792254885Sdumbbell rdev->mode_info.underscan_hborder_property, 1793254885Sdumbbell 0); 1794254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1795254885Sdumbbell rdev->mode_info.underscan_vborder_property, 1796254885Sdumbbell 0); 1797254885Sdumbbell } 1798254885Sdumbbell connector->interlace_allowed = true; 1799254885Sdumbbell /* in theory with a DP to VGA converter... */ 1800254885Sdumbbell connector->doublescan_allowed = false; 1801254885Sdumbbell break; 1802254885Sdumbbell case DRM_MODE_CONNECTOR_eDP: 1803254885Sdumbbell radeon_dig_connector = malloc( 1804254885Sdumbbell sizeof(struct radeon_connector_atom_dig), 1805254885Sdumbbell DRM_MEM_DRIVER, M_ZERO | M_WAITOK); 1806254885Sdumbbell if (!radeon_dig_connector) 1807254885Sdumbbell goto failed; 1808254885Sdumbbell radeon_dig_connector->igp_lane_info = igp_lane_info; 1809254885Sdumbbell radeon_connector->con_priv = radeon_dig_connector; 1810254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); 1811254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); 1812254885Sdumbbell if (i2c_bus->valid) { 1813254885Sdumbbell /* add DP i2c bus */ 1814254885Sdumbbell radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch"); 1815254885Sdumbbell if (!radeon_dig_connector->dp_i2c_bus) 1816254885Sdumbbell DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); 1817254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 1818254885Sdumbbell if (!radeon_connector->ddc_bus) 1819254885Sdumbbell DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 1820254885Sdumbbell } 1821254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1822254885Sdumbbell dev->mode_config.scaling_mode_property, 1823254885Sdumbbell DRM_MODE_SCALE_FULLSCREEN); 1824254885Sdumbbell subpixel_order = SubPixelHorizontalRGB; 1825254885Sdumbbell connector->interlace_allowed = false; 1826254885Sdumbbell connector->doublescan_allowed = false; 1827254885Sdumbbell break; 1828254885Sdumbbell case DRM_MODE_CONNECTOR_SVIDEO: 1829254885Sdumbbell case DRM_MODE_CONNECTOR_Composite: 1830254885Sdumbbell case DRM_MODE_CONNECTOR_9PinDIN: 1831254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); 1832254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); 1833254885Sdumbbell radeon_connector->dac_load_detect = true; 1834254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1835254885Sdumbbell rdev->mode_info.load_detect_property, 1836254885Sdumbbell 1); 1837254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1838254885Sdumbbell rdev->mode_info.tv_std_property, 1839254885Sdumbbell radeon_atombios_get_tv_info(rdev)); 1840254885Sdumbbell /* no HPD on analog connectors */ 1841254885Sdumbbell radeon_connector->hpd.hpd = RADEON_HPD_NONE; 1842254885Sdumbbell connector->interlace_allowed = false; 1843254885Sdumbbell connector->doublescan_allowed = false; 1844254885Sdumbbell break; 1845254885Sdumbbell case DRM_MODE_CONNECTOR_LVDS: 1846254885Sdumbbell radeon_dig_connector = malloc( 1847254885Sdumbbell sizeof(struct radeon_connector_atom_dig), 1848254885Sdumbbell DRM_MEM_DRIVER, M_ZERO | M_WAITOK); 1849254885Sdumbbell if (!radeon_dig_connector) 1850254885Sdumbbell goto failed; 1851254885Sdumbbell radeon_dig_connector->igp_lane_info = igp_lane_info; 1852254885Sdumbbell radeon_connector->con_priv = radeon_dig_connector; 1853254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); 1854254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); 1855254885Sdumbbell if (i2c_bus->valid) { 1856254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 1857254885Sdumbbell if (!radeon_connector->ddc_bus) 1858254885Sdumbbell DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 1859254885Sdumbbell } 1860254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1861254885Sdumbbell dev->mode_config.scaling_mode_property, 1862254885Sdumbbell DRM_MODE_SCALE_FULLSCREEN); 1863254885Sdumbbell subpixel_order = SubPixelHorizontalRGB; 1864254885Sdumbbell connector->interlace_allowed = false; 1865254885Sdumbbell connector->doublescan_allowed = false; 1866254885Sdumbbell break; 1867254885Sdumbbell } 1868254885Sdumbbell } 1869254885Sdumbbell 1870254885Sdumbbell if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { 1871254885Sdumbbell if (i2c_bus->valid) 1872254885Sdumbbell connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1873254885Sdumbbell } else 1874254885Sdumbbell connector->polled = DRM_CONNECTOR_POLL_HPD; 1875254885Sdumbbell 1876254885Sdumbbell connector->display_info.subpixel_order = subpixel_order; 1877254885Sdumbbell#ifdef DUMBBELL_WIP 1878254885Sdumbbell drm_sysfs_connector_add(connector); 1879254885Sdumbbell#endif /* DUMBBELL_WIP */ 1880254885Sdumbbell return; 1881254885Sdumbbell 1882254885Sdumbbellfailed: 1883254885Sdumbbell drm_connector_cleanup(connector); 1884254885Sdumbbell free(connector, DRM_MEM_DRIVER); 1885254885Sdumbbell} 1886254885Sdumbbell 1887254885Sdumbbellvoid 1888254885Sdumbbellradeon_add_legacy_connector(struct drm_device *dev, 1889254885Sdumbbell uint32_t connector_id, 1890254885Sdumbbell uint32_t supported_device, 1891254885Sdumbbell int connector_type, 1892254885Sdumbbell struct radeon_i2c_bus_rec *i2c_bus, 1893254885Sdumbbell uint16_t connector_object_id, 1894254885Sdumbbell struct radeon_hpd *hpd) 1895254885Sdumbbell{ 1896254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1897254885Sdumbbell struct drm_connector *connector; 1898254885Sdumbbell struct radeon_connector *radeon_connector; 1899254885Sdumbbell uint32_t subpixel_order = SubPixelNone; 1900254885Sdumbbell 1901254885Sdumbbell if (connector_type == DRM_MODE_CONNECTOR_Unknown) 1902254885Sdumbbell return; 1903254885Sdumbbell 1904254885Sdumbbell /* if the user selected tv=0 don't try and add the connector */ 1905254885Sdumbbell if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) || 1906254885Sdumbbell (connector_type == DRM_MODE_CONNECTOR_Composite) || 1907254885Sdumbbell (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) && 1908254885Sdumbbell (radeon_tv == 0)) 1909254885Sdumbbell return; 1910254885Sdumbbell 1911254885Sdumbbell /* see if we already added it */ 1912254885Sdumbbell list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 1913254885Sdumbbell radeon_connector = to_radeon_connector(connector); 1914254885Sdumbbell if (radeon_connector->connector_id == connector_id) { 1915254885Sdumbbell radeon_connector->devices |= supported_device; 1916254885Sdumbbell return; 1917254885Sdumbbell } 1918254885Sdumbbell } 1919254885Sdumbbell 1920254885Sdumbbell radeon_connector = malloc(sizeof(struct radeon_connector), 1921254885Sdumbbell DRM_MEM_DRIVER, M_ZERO | M_WAITOK); 1922254885Sdumbbell if (!radeon_connector) 1923254885Sdumbbell return; 1924254885Sdumbbell 1925254885Sdumbbell connector = &radeon_connector->base; 1926254885Sdumbbell 1927254885Sdumbbell radeon_connector->connector_id = connector_id; 1928254885Sdumbbell radeon_connector->devices = supported_device; 1929254885Sdumbbell radeon_connector->connector_object_id = connector_object_id; 1930254885Sdumbbell radeon_connector->hpd = *hpd; 1931254885Sdumbbell 1932254885Sdumbbell switch (connector_type) { 1933254885Sdumbbell case DRM_MODE_CONNECTOR_VGA: 1934254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1935254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1936254885Sdumbbell if (i2c_bus->valid) { 1937254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 1938254885Sdumbbell if (!radeon_connector->ddc_bus) 1939254885Sdumbbell DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 1940254885Sdumbbell } 1941254885Sdumbbell radeon_connector->dac_load_detect = true; 1942254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1943254885Sdumbbell rdev->mode_info.load_detect_property, 1944254885Sdumbbell 1); 1945254885Sdumbbell /* no HPD on analog connectors */ 1946254885Sdumbbell radeon_connector->hpd.hpd = RADEON_HPD_NONE; 1947254885Sdumbbell connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1948254885Sdumbbell connector->interlace_allowed = true; 1949254885Sdumbbell connector->doublescan_allowed = true; 1950254885Sdumbbell break; 1951254885Sdumbbell case DRM_MODE_CONNECTOR_DVIA: 1952254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 1953254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); 1954254885Sdumbbell if (i2c_bus->valid) { 1955254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 1956254885Sdumbbell if (!radeon_connector->ddc_bus) 1957254885Sdumbbell DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 1958254885Sdumbbell } 1959254885Sdumbbell radeon_connector->dac_load_detect = true; 1960254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1961254885Sdumbbell rdev->mode_info.load_detect_property, 1962254885Sdumbbell 1); 1963254885Sdumbbell /* no HPD on analog connectors */ 1964254885Sdumbbell radeon_connector->hpd.hpd = RADEON_HPD_NONE; 1965254885Sdumbbell connector->interlace_allowed = true; 1966254885Sdumbbell connector->doublescan_allowed = true; 1967254885Sdumbbell break; 1968254885Sdumbbell case DRM_MODE_CONNECTOR_DVII: 1969254885Sdumbbell case DRM_MODE_CONNECTOR_DVID: 1970254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); 1971254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); 1972254885Sdumbbell if (i2c_bus->valid) { 1973254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 1974254885Sdumbbell if (!radeon_connector->ddc_bus) 1975254885Sdumbbell DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 1976254885Sdumbbell } 1977254885Sdumbbell if (connector_type == DRM_MODE_CONNECTOR_DVII) { 1978254885Sdumbbell radeon_connector->dac_load_detect = true; 1979254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 1980254885Sdumbbell rdev->mode_info.load_detect_property, 1981254885Sdumbbell 1); 1982254885Sdumbbell } 1983254885Sdumbbell subpixel_order = SubPixelHorizontalRGB; 1984254885Sdumbbell connector->interlace_allowed = true; 1985254885Sdumbbell if (connector_type == DRM_MODE_CONNECTOR_DVII) 1986254885Sdumbbell connector->doublescan_allowed = true; 1987254885Sdumbbell else 1988254885Sdumbbell connector->doublescan_allowed = false; 1989254885Sdumbbell break; 1990254885Sdumbbell case DRM_MODE_CONNECTOR_SVIDEO: 1991254885Sdumbbell case DRM_MODE_CONNECTOR_Composite: 1992254885Sdumbbell case DRM_MODE_CONNECTOR_9PinDIN: 1993254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); 1994254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); 1995254885Sdumbbell radeon_connector->dac_load_detect = true; 1996254885Sdumbbell /* RS400,RC410,RS480 chipset seems to report a lot 1997254885Sdumbbell * of false positive on load detect, we haven't yet 1998254885Sdumbbell * found a way to make load detect reliable on those 1999254885Sdumbbell * chipset, thus just disable it for TV. 2000254885Sdumbbell */ 2001254885Sdumbbell if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) 2002254885Sdumbbell radeon_connector->dac_load_detect = false; 2003254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 2004254885Sdumbbell rdev->mode_info.load_detect_property, 2005254885Sdumbbell radeon_connector->dac_load_detect); 2006254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 2007254885Sdumbbell rdev->mode_info.tv_std_property, 2008254885Sdumbbell radeon_combios_get_tv_info(rdev)); 2009254885Sdumbbell /* no HPD on analog connectors */ 2010254885Sdumbbell radeon_connector->hpd.hpd = RADEON_HPD_NONE; 2011254885Sdumbbell connector->interlace_allowed = false; 2012254885Sdumbbell connector->doublescan_allowed = false; 2013254885Sdumbbell break; 2014254885Sdumbbell case DRM_MODE_CONNECTOR_LVDS: 2015254885Sdumbbell drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); 2016254885Sdumbbell drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); 2017254885Sdumbbell if (i2c_bus->valid) { 2018254885Sdumbbell radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); 2019254885Sdumbbell if (!radeon_connector->ddc_bus) 2020254885Sdumbbell DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); 2021254885Sdumbbell } 2022254885Sdumbbell drm_connector_attach_property(&radeon_connector->base, 2023254885Sdumbbell dev->mode_config.scaling_mode_property, 2024254885Sdumbbell DRM_MODE_SCALE_FULLSCREEN); 2025254885Sdumbbell subpixel_order = SubPixelHorizontalRGB; 2026254885Sdumbbell connector->interlace_allowed = false; 2027254885Sdumbbell connector->doublescan_allowed = false; 2028254885Sdumbbell break; 2029254885Sdumbbell } 2030254885Sdumbbell 2031254885Sdumbbell if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { 2032254885Sdumbbell if (i2c_bus->valid) 2033254885Sdumbbell connector->polled = DRM_CONNECTOR_POLL_CONNECT; 2034254885Sdumbbell } else 2035254885Sdumbbell connector->polled = DRM_CONNECTOR_POLL_HPD; 2036254885Sdumbbell connector->display_info.subpixel_order = subpixel_order; 2037254885Sdumbbell#ifdef DUMBBELL_WIP 2038254885Sdumbbell drm_sysfs_connector_add(connector); 2039254885Sdumbbell#endif /* DUMBBELL_WIP */ 2040254885Sdumbbell} 2041