intel_crt.c revision 280183
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 280183 2015-03-17 18:50:33Z 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 iic; 502 503 iic = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); 504 ret = intel_ddc_get_modes(connector, iic); 505 if (ret || !IS_G4X(dev)) 506 return ret; 507 508 /* Try to probe digital port for output in DVI-I -> VGA mode. */ 509 iic = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); 510 return intel_ddc_get_modes(connector, iic); 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 * Routines for controlling stuff on the analog port 531 */ 532 533static const struct drm_encoder_helper_funcs pch_encoder_funcs = { 534 .mode_fixup = intel_crt_mode_fixup, 535 .prepare = intel_encoder_prepare, 536 .commit = intel_encoder_commit, 537 .mode_set = intel_crt_mode_set, 538 .dpms = pch_crt_dpms, 539}; 540 541static const struct drm_encoder_helper_funcs gmch_encoder_funcs = { 542 .mode_fixup = intel_crt_mode_fixup, 543 .prepare = intel_encoder_prepare, 544 .commit = intel_encoder_commit, 545 .mode_set = intel_crt_mode_set, 546 .dpms = gmch_crt_dpms, 547}; 548 549static const struct drm_connector_funcs intel_crt_connector_funcs = { 550 .reset = intel_crt_reset, 551 .dpms = drm_helper_connector_dpms, 552 .detect = intel_crt_detect, 553 .fill_modes = drm_helper_probe_single_connector_modes, 554 .destroy = intel_crt_destroy, 555 .set_property = intel_crt_set_property, 556}; 557 558static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = { 559 .mode_valid = intel_crt_mode_valid, 560 .get_modes = intel_crt_get_modes, 561 .best_encoder = intel_best_encoder, 562}; 563 564static const struct drm_encoder_funcs intel_crt_enc_funcs = { 565 .destroy = intel_encoder_destroy, 566}; 567 568static int intel_no_crt_dmi_callback(const struct dmi_system_id *id) 569{ 570 DRM_INFO("Skipping CRT initialization for %s\n", id->ident); 571 return 1; 572} 573 574static const struct dmi_system_id intel_no_crt[] = { 575 { 576 .callback = intel_no_crt_dmi_callback, 577 .ident = "ACER ZGB", 578 .matches = { 579 DMI_MATCH(DMI_SYS_VENDOR, "ACER"), 580 DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), 581 }, 582 }, 583 { } 584}; 585 586void intel_crt_init(struct drm_device *dev) 587{ 588 struct drm_connector *connector; 589 struct intel_crt *crt; 590 struct intel_connector *intel_connector; 591 struct drm_i915_private *dev_priv = dev->dev_private; 592 const struct drm_encoder_helper_funcs *encoder_helper_funcs; 593 594 /* Skip machines without VGA that falsely report hotplug events */ 595 if (dmi_check_system(intel_no_crt)) 596 return; 597 598 crt = malloc(sizeof(struct intel_crt), DRM_MEM_KMS, M_WAITOK | M_ZERO); 599 intel_connector = malloc(sizeof(struct intel_connector), DRM_MEM_KMS, 600 M_WAITOK | M_ZERO); 601 602 connector = &intel_connector->base; 603 drm_connector_init(dev, &intel_connector->base, 604 &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); 605 606 drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs, 607 DRM_MODE_ENCODER_DAC); 608 609 intel_connector_attach_encoder(intel_connector, &crt->base); 610 611 crt->base.type = INTEL_OUTPUT_ANALOG; 612 crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT | 613 1 << INTEL_ANALOG_CLONE_BIT | 614 1 << INTEL_SDVO_LVDS_CLONE_BIT); 615 if (IS_HASWELL(dev)) 616 crt->base.crtc_mask = (1 << 0); 617 else 618 crt->base.crtc_mask = (1 << 0) | (1 << 1); 619 620 if (IS_GEN2(dev)) 621 connector->interlace_allowed = 0; 622 else 623 connector->interlace_allowed = 1; 624 connector->doublescan_allowed = 0; 625 626 if (HAS_PCH_SPLIT(dev)) 627 encoder_helper_funcs = &pch_encoder_funcs; 628 else 629 encoder_helper_funcs = &gmch_encoder_funcs; 630 631 drm_encoder_helper_add(&crt->base.base, encoder_helper_funcs); 632 drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); 633 634#if 0 635 drm_sysfs_connector_add(connector); 636#endif 637 638 if (I915_HAS_HOTPLUG(dev)) 639 connector->polled = DRM_CONNECTOR_POLL_HPD; 640 else 641 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 642 643 /* 644 * Configure the automatic hotplug detection stuff 645 */ 646 crt->force_hotplug_required = 0; 647 if (HAS_PCH_SPLIT(dev)) { 648 u32 adpa; 649 650 adpa = I915_READ(PCH_ADPA); 651 adpa &= ~ADPA_CRT_HOTPLUG_MASK; 652 adpa |= ADPA_HOTPLUG_BITS; 653 I915_WRITE(PCH_ADPA, adpa); 654 POSTING_READ(PCH_ADPA); 655 656 DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa); 657 crt->force_hotplug_required = 1; 658 } 659 660 dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; 661} 662