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