intel_crt.c revision 289936
1/* 2 * Copyright �� 2006-2007 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: 24 * Eric Anholt <eric@anholt.net> 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/dev/drm2/i915/intel_crt.c 289936 2015-10-25 14:57:53Z dumbbell $"); 29 30#include <dev/drm2/drmP.h> 31#include <dev/drm2/drm.h> 32#include <dev/drm2/drm_crtc.h> 33#include <dev/drm2/drm_crtc_helper.h> 34#include <dev/drm2/drm_edid.h> 35#include <dev/drm2/i915/i915_drm.h> 36#include <dev/drm2/i915/i915_drv.h> 37#include <dev/drm2/i915/intel_drv.h> 38 39/* Here's the desired hotplug mode */ 40#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \ 41 ADPA_CRT_HOTPLUG_WARMUP_10MS | \ 42 ADPA_CRT_HOTPLUG_SAMPLE_4S | \ 43 ADPA_CRT_HOTPLUG_VOLTAGE_50 | \ 44 ADPA_CRT_HOTPLUG_VOLREF_325MV | \ 45 ADPA_CRT_HOTPLUG_ENABLE) 46 47struct intel_crt { 48 struct intel_encoder base; 49 bool force_hotplug_required; 50}; 51 52static struct intel_crt *intel_attached_crt(struct drm_connector *connector) 53{ 54 return container_of(intel_attached_encoder(connector), 55 struct intel_crt, base); 56} 57 58static void pch_crt_dpms(struct drm_encoder *encoder, int mode) 59{ 60 struct drm_device *dev = encoder->dev; 61 struct drm_i915_private *dev_priv = dev->dev_private; 62 u32 temp; 63 64 temp = I915_READ(PCH_ADPA); 65 temp &= ~ADPA_DAC_ENABLE; 66 67 switch (mode) { 68 case DRM_MODE_DPMS_ON: 69 temp |= ADPA_DAC_ENABLE; 70 break; 71 case DRM_MODE_DPMS_STANDBY: 72 case DRM_MODE_DPMS_SUSPEND: 73 case DRM_MODE_DPMS_OFF: 74 /* Just leave port enable cleared */ 75 break; 76 } 77 78 I915_WRITE(PCH_ADPA, temp); 79} 80 81static void gmch_crt_dpms(struct drm_encoder *encoder, int mode) 82{ 83 struct drm_device *dev = encoder->dev; 84 struct drm_i915_private *dev_priv = dev->dev_private; 85 u32 temp; 86 87 temp = I915_READ(ADPA); 88 temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); 89 temp &= ~ADPA_DAC_ENABLE; 90 91 switch (mode) { 92 case DRM_MODE_DPMS_ON: 93 temp |= ADPA_DAC_ENABLE; 94 break; 95 case DRM_MODE_DPMS_STANDBY: 96 temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE; 97 break; 98 case DRM_MODE_DPMS_SUSPEND: 99 temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE; 100 break; 101 case DRM_MODE_DPMS_OFF: 102 temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE; 103 break; 104 } 105 106 I915_WRITE(ADPA, temp); 107} 108 109static int intel_crt_mode_valid(struct drm_connector *connector, 110 struct drm_display_mode *mode) 111{ 112 struct drm_device *dev = connector->dev; 113 114 int max_clock = 0; 115 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 116 return MODE_NO_DBLESCAN; 117 118 if (mode->clock < 25000) 119 return MODE_CLOCK_LOW; 120 121 if (IS_GEN2(dev)) 122 max_clock = 350000; 123 else 124 max_clock = 400000; 125 if (mode->clock > max_clock) 126 return MODE_CLOCK_HIGH; 127 128 return MODE_OK; 129} 130 131static bool intel_crt_mode_fixup(struct drm_encoder *encoder, 132 const struct drm_display_mode *mode, 133 struct drm_display_mode *adjusted_mode) 134{ 135 return true; 136} 137 138static void intel_crt_mode_set(struct drm_encoder *encoder, 139 struct drm_display_mode *mode, 140 struct drm_display_mode *adjusted_mode) 141{ 142 143 struct drm_device *dev = encoder->dev; 144 struct drm_crtc *crtc = encoder->crtc; 145 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 146 struct drm_i915_private *dev_priv = dev->dev_private; 147 int dpll_md_reg; 148 u32 adpa, dpll_md; 149 u32 adpa_reg; 150 151 dpll_md_reg = DPLL_MD(intel_crtc->pipe); 152 153 if (HAS_PCH_SPLIT(dev)) 154 adpa_reg = PCH_ADPA; 155 else 156 adpa_reg = ADPA; 157 158 /* 159 * Disable separate mode multiplier used when cloning SDVO to CRT 160 * XXX this needs to be adjusted when we really are cloning 161 */ 162 if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { 163 dpll_md = I915_READ(dpll_md_reg); 164 I915_WRITE(dpll_md_reg, 165 dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); 166 } 167 168 adpa = ADPA_HOTPLUG_BITS; 169 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) 170 adpa |= ADPA_HSYNC_ACTIVE_HIGH; 171 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) 172 adpa |= ADPA_VSYNC_ACTIVE_HIGH; 173 174 /* For CPT allow 3 pipe config, for others just use A or B */ 175 if (HAS_PCH_CPT(dev)) 176 adpa |= PORT_TRANS_SEL_CPT(intel_crtc->pipe); 177 else if (intel_crtc->pipe == 0) 178 adpa |= ADPA_PIPE_A_SELECT; 179 else 180 adpa |= ADPA_PIPE_B_SELECT; 181 182 if (!HAS_PCH_SPLIT(dev)) 183 I915_WRITE(BCLRPAT(intel_crtc->pipe), 0); 184 185 I915_WRITE(adpa_reg, adpa); 186} 187 188static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) 189{ 190 struct drm_device *dev = connector->dev; 191 struct intel_crt *crt = intel_attached_crt(connector); 192 struct drm_i915_private *dev_priv = dev->dev_private; 193 u32 adpa; 194 bool ret; 195 196 /* The first time through, trigger an explicit detection cycle */ 197 if (crt->force_hotplug_required) { 198 bool turn_off_dac = HAS_PCH_SPLIT(dev); 199 u32 save_adpa; 200 201 crt->force_hotplug_required = 0; 202 203 save_adpa = adpa = I915_READ(PCH_ADPA); 204 DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa); 205 206 adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; 207 if (turn_off_dac) 208 adpa &= ~ADPA_DAC_ENABLE; 209 210 I915_WRITE(PCH_ADPA, adpa); 211 212 if (_intel_wait_for(dev, 213 (I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, 214 1000, 1, "915crt")) 215 DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER\n"); 216 217 if (turn_off_dac) { 218 I915_WRITE(PCH_ADPA, save_adpa); 219 POSTING_READ(PCH_ADPA); 220 } 221 } 222 223 /* Check the status to see if both blue and green are on now */ 224 adpa = I915_READ(PCH_ADPA); 225 if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) 226 ret = true; 227 else 228 ret = false; 229 DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret); 230 231 return ret; 232} 233 234/** 235 * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence. 236 * 237 * Not for i915G/i915GM 238 * 239 * \return true if CRT is connected. 240 * \return false if CRT is disconnected. 241 */ 242static bool intel_crt_detect_hotplug(struct drm_connector *connector) 243{ 244 struct drm_device *dev = connector->dev; 245 struct drm_i915_private *dev_priv = dev->dev_private; 246 u32 hotplug_en, orig, stat; 247 bool ret = false; 248 int i, tries = 0; 249 250 if (HAS_PCH_SPLIT(dev)) 251 return intel_ironlake_crt_detect_hotplug(connector); 252 253 /* 254 * On 4 series desktop, CRT detect sequence need to be done twice 255 * to get a reliable result. 256 */ 257 258 if (IS_G4X(dev) && !IS_GM45(dev)) 259 tries = 2; 260 else 261 tries = 1; 262 hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN); 263 hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; 264 265 for (i = 0; i < tries ; i++) { 266 /* turn on the FORCE_DETECT */ 267 I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); 268 /* wait for FORCE_DETECT to go off */ 269 if (_intel_wait_for(dev, 270 (I915_READ(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT) == 0, 271 1000, 1, "915cr2")) 272 DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off"); 273 } 274 275 stat = I915_READ(PORT_HOTPLUG_STAT); 276 if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE) 277 ret = true; 278 279 /* clear the interrupt we just generated, if any */ 280 I915_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS); 281 282 /* and put the bits back */ 283 I915_WRITE(PORT_HOTPLUG_EN, orig); 284 285 return ret; 286} 287 288static bool intel_crt_detect_ddc(struct drm_connector *connector) 289{ 290 struct intel_crt *crt = intel_attached_crt(connector); 291 struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; 292 293 /* CRT should always be at 0, but check anyway */ 294 if (crt->base.type != INTEL_OUTPUT_ANALOG) 295 return false; 296 297 if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { 298 struct edid *edid; 299 bool is_digital = false; 300 device_t iic; 301 302 iic = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); 303 edid = drm_get_edid(connector, iic); 304 /* 305 * This may be a DVI-I connector with a shared DDC 306 * link between analog and digital outputs, so we 307 * have to check the EDID input spec of the attached device. 308 * 309 * On the other hand, what should we do if it is a broken EDID? 310 */ 311 if (edid != NULL) { 312 is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; 313 free(edid, DRM_MEM_KMS); 314 } 315 316 if (!is_digital) { 317 DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); 318 return true; 319 } else { 320 DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n"); 321 } 322 } 323 324 return false; 325} 326 327static enum drm_connector_status 328intel_crt_load_detect(struct intel_crt *crt) 329{ 330 struct drm_device *dev = crt->base.base.dev; 331 struct drm_i915_private *dev_priv = dev->dev_private; 332 uint32_t pipe = to_intel_crtc(crt->base.base.crtc)->pipe; 333 uint32_t save_bclrpat; 334 uint32_t save_vtotal; 335 uint32_t vtotal, vactive; 336 uint32_t vsample; 337 uint32_t vblank, vblank_start, vblank_end; 338 uint32_t dsl; 339 uint32_t bclrpat_reg; 340 uint32_t vtotal_reg; 341 uint32_t vblank_reg; 342 uint32_t vsync_reg; 343 uint32_t pipeconf_reg; 344 uint32_t pipe_dsl_reg; 345 uint8_t st00; 346 enum drm_connector_status status; 347 348 DRM_DEBUG_KMS("starting load-detect on CRT\n"); 349 350 bclrpat_reg = BCLRPAT(pipe); 351 vtotal_reg = VTOTAL(pipe); 352 vblank_reg = VBLANK(pipe); 353 vsync_reg = VSYNC(pipe); 354 pipeconf_reg = PIPECONF(pipe); 355 pipe_dsl_reg = PIPEDSL(pipe); 356 357 save_bclrpat = I915_READ(bclrpat_reg); 358 save_vtotal = I915_READ(vtotal_reg); 359 vblank = I915_READ(vblank_reg); 360 361 vtotal = ((save_vtotal >> 16) & 0xfff) + 1; 362 vactive = (save_vtotal & 0x7ff) + 1; 363 364 vblank_start = (vblank & 0xfff) + 1; 365 vblank_end = ((vblank >> 16) & 0xfff) + 1; 366 367 /* Set the border color to purple. */ 368 I915_WRITE(bclrpat_reg, 0x500050); 369 370 if (!IS_GEN2(dev)) { 371 uint32_t pipeconf = I915_READ(pipeconf_reg); 372 I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); 373 POSTING_READ(pipeconf_reg); 374 /* Wait for next Vblank to substitue 375 * border color for Color info */ 376 intel_wait_for_vblank(dev, pipe); 377 st00 = I915_READ8(VGA_MSR_WRITE); 378 status = ((st00 & (1 << 4)) != 0) ? 379 connector_status_connected : 380 connector_status_disconnected; 381 382 I915_WRITE(pipeconf_reg, pipeconf); 383 } else { 384 bool restore_vblank = false; 385 int count, detect; 386 387 /* 388 * If there isn't any border, add some. 389 * Yes, this will flicker 390 */ 391 if (vblank_start <= vactive && vblank_end >= vtotal) { 392 uint32_t vsync = I915_READ(vsync_reg); 393 uint32_t vsync_start = (vsync & 0xffff) + 1; 394 395 vblank_start = vsync_start; 396 I915_WRITE(vblank_reg, 397 (vblank_start - 1) | 398 ((vblank_end - 1) << 16)); 399 restore_vblank = true; 400 } 401 /* sample in the vertical border, selecting the larger one */ 402 if (vblank_start - vactive >= vtotal - vblank_end) 403 vsample = (vblank_start + vactive) >> 1; 404 else 405 vsample = (vtotal + vblank_end) >> 1; 406 407 /* 408 * Wait for the border to be displayed 409 */ 410 while (I915_READ(pipe_dsl_reg) >= vactive) 411 ; 412 while ((dsl = I915_READ(pipe_dsl_reg)) <= vsample) 413 ; 414 /* 415 * Watch ST00 for an entire scanline 416 */ 417 detect = 0; 418 count = 0; 419 do { 420 count++; 421 /* Read the ST00 VGA status register */ 422 st00 = I915_READ8(VGA_MSR_WRITE); 423 if (st00 & (1 << 4)) 424 detect++; 425 } while ((I915_READ(pipe_dsl_reg) == dsl)); 426 427 /* restore vblank if necessary */ 428 if (restore_vblank) 429 I915_WRITE(vblank_reg, vblank); 430 /* 431 * If more than 3/4 of the scanline detected a monitor, 432 * then it is assumed to be present. This works even on i830, 433 * where there isn't any way to force the border color across 434 * the screen 435 */ 436 status = detect * 4 > count * 3 ? 437 connector_status_connected : 438 connector_status_disconnected; 439 } 440 441 /* Restore previous settings */ 442 I915_WRITE(bclrpat_reg, save_bclrpat); 443 444 return status; 445} 446 447static enum drm_connector_status 448intel_crt_detect(struct drm_connector *connector, bool force) 449{ 450 struct drm_device *dev = connector->dev; 451 struct intel_crt *crt = intel_attached_crt(connector); 452 enum drm_connector_status status; 453 struct intel_load_detect_pipe tmp; 454 455 if (I915_HAS_HOTPLUG(dev)) { 456 if (intel_crt_detect_hotplug(connector)) { 457 DRM_DEBUG_KMS("CRT detected via hotplug\n"); 458 return connector_status_connected; 459 } else { 460 DRM_DEBUG_KMS("CRT not detected via hotplug\n"); 461 return connector_status_disconnected; 462 } 463 } 464 465 if (intel_crt_detect_ddc(connector)) 466 return connector_status_connected; 467 468 if (!force) 469 return connector->status; 470 471 /* for pre-945g platforms use load detect */ 472 if (intel_get_load_detect_pipe(&crt->base, connector, NULL, 473 &tmp)) { 474 if (intel_crt_detect_ddc(connector)) 475 status = connector_status_connected; 476 else 477 status = intel_crt_load_detect(crt); 478 intel_release_load_detect_pipe(&crt->base, connector, 479 &tmp); 480 } else 481 status = connector_status_unknown; 482 483 return status; 484} 485 486static void intel_crt_destroy(struct drm_connector *connector) 487{ 488 489#if 0 490 drm_sysfs_connector_remove(connector); 491#endif 492 drm_connector_cleanup(connector); 493 free(connector, DRM_MEM_KMS); 494} 495 496static int intel_crt_get_modes(struct drm_connector *connector) 497{ 498 struct drm_device *dev = connector->dev; 499 struct drm_i915_private *dev_priv = dev->dev_private; 500 int ret; 501 device_t i2c; 502 503 i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); 504 ret = intel_ddc_get_modes(connector, i2c); 505 if (ret || !IS_G4X(dev)) 506 return ret; 507 508 /* Try to probe digital port for output in DVI-I -> VGA mode. */ 509 i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); 510 return intel_ddc_get_modes(connector, i2c); 511} 512 513static int intel_crt_set_property(struct drm_connector *connector, 514 struct drm_property *property, 515 uint64_t value) 516{ 517 return 0; 518} 519 520static void intel_crt_reset(struct drm_connector *connector) 521{ 522 struct drm_device *dev = connector->dev; 523 struct intel_crt *crt = intel_attached_crt(connector); 524 525 if (HAS_PCH_SPLIT(dev)) { 526 crt->force_hotplug_required = 1; 527 } 528} 529 530/* 531 * Routines for controlling stuff on the analog port 532 */ 533 534static const struct drm_encoder_helper_funcs pch_encoder_funcs = { 535 .mode_fixup = intel_crt_mode_fixup, 536 .prepare = intel_encoder_prepare, 537 .commit = intel_encoder_commit, 538 .mode_set = intel_crt_mode_set, 539 .dpms = pch_crt_dpms, 540}; 541 542static const struct drm_encoder_helper_funcs gmch_encoder_funcs = { 543 .mode_fixup = intel_crt_mode_fixup, 544 .prepare = intel_encoder_prepare, 545 .commit = intel_encoder_commit, 546 .mode_set = intel_crt_mode_set, 547 .dpms = gmch_crt_dpms, 548}; 549 550static const struct drm_connector_funcs intel_crt_connector_funcs = { 551 .reset = intel_crt_reset, 552 .dpms = drm_helper_connector_dpms, 553 .detect = intel_crt_detect, 554 .fill_modes = drm_helper_probe_single_connector_modes, 555 .destroy = intel_crt_destroy, 556 .set_property = intel_crt_set_property, 557}; 558 559static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = { 560 .mode_valid = intel_crt_mode_valid, 561 .get_modes = intel_crt_get_modes, 562 .best_encoder = intel_best_encoder, 563}; 564 565static const struct drm_encoder_funcs intel_crt_enc_funcs = { 566 .destroy = intel_encoder_destroy, 567}; 568 569static int intel_no_crt_dmi_callback(const struct dmi_system_id *id) 570{ 571 DRM_INFO("Skipping CRT initialization for %s\n", id->ident); 572 return 1; 573} 574 575static const struct dmi_system_id intel_no_crt[] = { 576 { 577 .callback = intel_no_crt_dmi_callback, 578 .ident = "ACER ZGB", 579 .matches = { 580 DMI_MATCH(DMI_SYS_VENDOR, "ACER"), 581 DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), 582 }, 583 }, 584 { } 585}; 586 587void intel_crt_init(struct drm_device *dev) 588{ 589 struct drm_connector *connector; 590 struct intel_crt *crt; 591 struct intel_connector *intel_connector; 592 struct drm_i915_private *dev_priv = dev->dev_private; 593 const struct drm_encoder_helper_funcs *encoder_helper_funcs; 594 595 /* Skip machines without VGA that falsely report hotplug events */ 596 if (dmi_check_system(intel_no_crt)) 597 return; 598 599 crt = malloc(sizeof(struct intel_crt), DRM_MEM_KMS, M_WAITOK | M_ZERO); 600 601 intel_connector = malloc(sizeof(struct intel_connector), DRM_MEM_KMS, 602 M_WAITOK | M_ZERO); 603 604 connector = &intel_connector->base; 605 drm_connector_init(dev, &intel_connector->base, 606 &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); 607 608 drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs, 609 DRM_MODE_ENCODER_DAC); 610 611 intel_connector_attach_encoder(intel_connector, &crt->base); 612 613 crt->base.type = INTEL_OUTPUT_ANALOG; 614 crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT | 615 1 << INTEL_ANALOG_CLONE_BIT | 616 1 << INTEL_SDVO_LVDS_CLONE_BIT); 617 if (IS_HASWELL(dev)) 618 crt->base.crtc_mask = (1 << 0); 619 else 620 crt->base.crtc_mask = (1 << 0) | (1 << 1); 621 622 if (IS_GEN2(dev)) 623 connector->interlace_allowed = 0; 624 else 625 connector->interlace_allowed = 1; 626 connector->doublescan_allowed = 0; 627 628 if (HAS_PCH_SPLIT(dev)) 629 encoder_helper_funcs = &pch_encoder_funcs; 630 else 631 encoder_helper_funcs = &gmch_encoder_funcs; 632 633 drm_encoder_helper_add(&crt->base.base, encoder_helper_funcs); 634 drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); 635 636#if 0 637 drm_sysfs_connector_add(connector); 638#endif 639 640 if (I915_HAS_HOTPLUG(dev)) 641 connector->polled = DRM_CONNECTOR_POLL_HPD; 642 else 643 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 644 645 /* 646 * Configure the automatic hotplug detection stuff 647 */ 648 crt->force_hotplug_required = 0; 649 if (HAS_PCH_SPLIT(dev)) { 650 u32 adpa; 651 652 adpa = I915_READ(PCH_ADPA); 653 adpa &= ~ADPA_CRT_HOTPLUG_MASK; 654 adpa |= ADPA_HOTPLUG_BITS; 655 I915_WRITE(PCH_ADPA, adpa); 656 POSTING_READ(PCH_ADPA); 657 658 DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa); 659 crt->force_hotplug_required = 1; 660 } 661 662 dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; 663} 664