1 /* 2 * Copyright © 2006-2007 Intel Corporation 3 * Copyright (c) 2006 Dave Airlie <airlied@linux.ie> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Eric Anholt <eric@anholt.net> 26 * Dave Airlie <airlied@linux.ie> 27 * Jesse Barnes <jesse.barnes@intel.com> 28 * $FreeBSD: src/sys/dev/drm2/i915/intel_lvds.c,v 1.1 2012/05/22 11:07:44 kib Exp $ 29 */ 30 31 #include <drm/drmP.h> 32 #include <drm/drm_crtc.h> 33 #include <drm/drm_edid.h> 34 #include "intel_drv.h" 35 #include <drm/i915_drm.h> 36 #include "i915_drv.h" 37 38 /* Private structure for the integrated LVDS support */ 39 struct intel_lvds { 40 struct intel_encoder base; 41 42 struct edid *edid; 43 44 int fitting_mode; 45 u32 pfit_control; 46 u32 pfit_pgm_ratios; 47 bool pfit_dirty; 48 49 struct drm_display_mode *fixed_mode; 50 }; 51 52 static struct intel_lvds *to_intel_lvds(struct drm_encoder *encoder) 53 { 54 return container_of(encoder, struct intel_lvds, base.base); 55 } 56 57 static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) 58 { 59 return container_of(intel_attached_encoder(connector), 60 struct intel_lvds, base); 61 } 62 63 /** 64 * Sets the power state for the panel. 65 */ 66 static void intel_lvds_enable(struct intel_lvds *intel_lvds) 67 { 68 struct drm_device *dev = intel_lvds->base.base.dev; 69 struct drm_i915_private *dev_priv = dev->dev_private; 70 u32 ctl_reg, lvds_reg, stat_reg; 71 72 if (HAS_PCH_SPLIT(dev)) { 73 ctl_reg = PCH_PP_CONTROL; 74 lvds_reg = PCH_LVDS; 75 stat_reg = PCH_PP_STATUS; 76 } else { 77 ctl_reg = PP_CONTROL; 78 lvds_reg = LVDS; 79 stat_reg = PP_STATUS; 80 } 81 82 I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); 83 84 if (intel_lvds->pfit_dirty) { 85 /* 86 * Enable automatic panel scaling so that non-native modes 87 * fill the screen. The panel fitter should only be 88 * adjusted whilst the pipe is disabled, according to 89 * register description and PRM. 90 */ 91 DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", 92 intel_lvds->pfit_control, 93 intel_lvds->pfit_pgm_ratios); 94 95 I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); 96 I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); 97 intel_lvds->pfit_dirty = false; 98 } 99 100 I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); 101 POSTING_READ(lvds_reg); 102 if (_intel_wait_for(dev, 103 (I915_READ(stat_reg) & PP_ON) == 0, 1000, 104 1, "915lvds")) 105 DRM_ERROR("timed out waiting for panel to power off\n"); 106 107 intel_panel_enable_backlight(dev); 108 } 109 110 static void intel_lvds_disable(struct intel_lvds *intel_lvds) 111 { 112 struct drm_device *dev = intel_lvds->base.base.dev; 113 struct drm_i915_private *dev_priv = dev->dev_private; 114 u32 ctl_reg, lvds_reg, stat_reg; 115 116 if (HAS_PCH_SPLIT(dev)) { 117 ctl_reg = PCH_PP_CONTROL; 118 lvds_reg = PCH_LVDS; 119 stat_reg = PCH_PP_STATUS; 120 } else { 121 ctl_reg = PP_CONTROL; 122 lvds_reg = LVDS; 123 stat_reg = PP_STATUS; 124 } 125 126 intel_panel_disable_backlight(dev); 127 128 I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); 129 if (_intel_wait_for(dev, 130 (I915_READ(stat_reg) & PP_ON) == 0, 1000, 131 1, "915lvo")) 132 DRM_ERROR("timed out waiting for panel to power off\n"); 133 134 if (intel_lvds->pfit_control) { 135 I915_WRITE(PFIT_CONTROL, 0); 136 intel_lvds->pfit_dirty = true; 137 } 138 139 I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); 140 POSTING_READ(lvds_reg); 141 } 142 143 static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) 144 { 145 struct intel_lvds *intel_lvds = to_intel_lvds(encoder); 146 147 if (mode == DRM_MODE_DPMS_ON) 148 intel_lvds_enable(intel_lvds); 149 else 150 intel_lvds_disable(intel_lvds); 151 152 /* XXX: We never power down the LVDS pairs. */ 153 } 154 155 static int intel_lvds_mode_valid(struct drm_connector *connector, 156 struct drm_display_mode *mode) 157 { 158 struct intel_lvds *intel_lvds = intel_attached_lvds(connector); 159 struct drm_display_mode *fixed_mode = intel_lvds->fixed_mode; 160 161 if (mode->hdisplay > fixed_mode->hdisplay) 162 return MODE_PANEL; 163 if (mode->vdisplay > fixed_mode->vdisplay) 164 return MODE_PANEL; 165 166 return MODE_OK; 167 } 168 169 static void 170 centre_horizontally(struct drm_display_mode *mode, 171 int width) 172 { 173 u32 border, sync_pos, blank_width, sync_width; 174 175 /* keep the hsync and hblank widths constant */ 176 sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start; 177 blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start; 178 sync_pos = (blank_width - sync_width + 1) / 2; 179 180 border = (mode->hdisplay - width + 1) / 2; 181 border += border & 1; /* make the border even */ 182 183 mode->crtc_hdisplay = width; 184 mode->crtc_hblank_start = width + border; 185 mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width; 186 187 mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; 188 mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; 189 190 mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; 191 } 192 193 static void 194 centre_vertically(struct drm_display_mode *mode, 195 int height) 196 { 197 u32 border, sync_pos, blank_width, sync_width; 198 199 /* keep the vsync and vblank widths constant */ 200 sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start; 201 blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start; 202 sync_pos = (blank_width - sync_width + 1) / 2; 203 204 border = (mode->vdisplay - height + 1) / 2; 205 206 mode->crtc_vdisplay = height; 207 mode->crtc_vblank_start = height + border; 208 mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width; 209 210 mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; 211 mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; 212 213 mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; 214 } 215 216 static inline u32 panel_fitter_scaling(u32 source, u32 target) 217 { 218 /* 219 * Floating point operation is not supported. So the FACTOR 220 * is defined, which can avoid the floating point computation 221 * when calculating the panel ratio. 222 */ 223 #define ACCURACY 12 224 #define FACTOR (1 << ACCURACY) 225 u32 ratio = source * FACTOR / target; 226 return (FACTOR * ratio + FACTOR/2) / FACTOR; 227 } 228 229 static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, 230 const struct drm_display_mode *mode, 231 struct drm_display_mode *adjusted_mode) 232 { 233 struct drm_device *dev = encoder->dev; 234 struct drm_i915_private *dev_priv = dev->dev_private; 235 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); 236 struct intel_lvds *intel_lvds = to_intel_lvds(encoder); 237 struct drm_encoder *tmp_encoder; 238 u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; 239 int pipe; 240 241 /* Should never happen!! */ 242 if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) { 243 DRM_ERROR("Can't support LVDS on pipe A\n"); 244 return false; 245 } 246 247 /* Should never happen!! */ 248 list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { 249 if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { 250 DRM_ERROR("Can't enable LVDS and another " 251 "encoder on the same pipe\n"); 252 return false; 253 } 254 } 255 256 /* 257 * We have timings from the BIOS for the panel, put them in 258 * to the adjusted mode. The CRTC will be set up for this mode, 259 * with the panel scaling set up to source from the H/VDisplay 260 * of the original mode. 261 */ 262 intel_fixed_panel_mode(intel_lvds->fixed_mode, adjusted_mode); 263 264 if (HAS_PCH_SPLIT(dev)) { 265 intel_pch_panel_fitting(dev, intel_lvds->fitting_mode, 266 mode, adjusted_mode); 267 return true; 268 } 269 270 /* Native modes don't need fitting */ 271 if (adjusted_mode->hdisplay == mode->hdisplay && 272 adjusted_mode->vdisplay == mode->vdisplay) 273 goto out; 274 275 /* 965+ wants fuzzy fitting */ 276 if (INTEL_INFO(dev)->gen >= 4) 277 pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | 278 PFIT_FILTER_FUZZY); 279 280 /* 281 * Enable automatic panel scaling for non-native modes so that they fill 282 * the screen. Should be enabled before the pipe is enabled, according 283 * to register description and PRM. 284 * Change the value here to see the borders for debugging 285 */ 286 for_each_pipe(pipe) 287 I915_WRITE(BCLRPAT(pipe), 0); 288 289 drm_mode_set_crtcinfo(adjusted_mode, 0); 290 291 switch (intel_lvds->fitting_mode) { 292 case DRM_MODE_SCALE_CENTER: 293 /* 294 * For centered modes, we have to calculate border widths & 295 * heights and modify the values programmed into the CRTC. 296 */ 297 centre_horizontally(adjusted_mode, mode->hdisplay); 298 centre_vertically(adjusted_mode, mode->vdisplay); 299 border = LVDS_BORDER_ENABLE; 300 break; 301 302 case DRM_MODE_SCALE_ASPECT: 303 /* Scale but preserve the aspect ratio */ 304 if (INTEL_INFO(dev)->gen >= 4) { 305 u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; 306 u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; 307 308 /* 965+ is easy, it does everything in hw */ 309 if (scaled_width > scaled_height) 310 pfit_control |= PFIT_ENABLE | PFIT_SCALING_PILLAR; 311 else if (scaled_width < scaled_height) 312 pfit_control |= PFIT_ENABLE | PFIT_SCALING_LETTER; 313 else if (adjusted_mode->hdisplay != mode->hdisplay) 314 pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; 315 } else { 316 u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; 317 u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; 318 /* 319 * For earlier chips we have to calculate the scaling 320 * ratio by hand and program it into the 321 * PFIT_PGM_RATIO register 322 */ 323 if (scaled_width > scaled_height) { /* pillar */ 324 centre_horizontally(adjusted_mode, scaled_height / mode->vdisplay); 325 326 border = LVDS_BORDER_ENABLE; 327 if (mode->vdisplay != adjusted_mode->vdisplay) { 328 u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay); 329 pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | 330 bits << PFIT_VERT_SCALE_SHIFT); 331 pfit_control |= (PFIT_ENABLE | 332 VERT_INTERP_BILINEAR | 333 HORIZ_INTERP_BILINEAR); 334 } 335 } else if (scaled_width < scaled_height) { /* letter */ 336 centre_vertically(adjusted_mode, scaled_width / mode->hdisplay); 337 338 border = LVDS_BORDER_ENABLE; 339 if (mode->hdisplay != adjusted_mode->hdisplay) { 340 u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay); 341 pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | 342 bits << PFIT_VERT_SCALE_SHIFT); 343 pfit_control |= (PFIT_ENABLE | 344 VERT_INTERP_BILINEAR | 345 HORIZ_INTERP_BILINEAR); 346 } 347 } else 348 /* Aspects match, Let hw scale both directions */ 349 pfit_control |= (PFIT_ENABLE | 350 VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | 351 VERT_INTERP_BILINEAR | 352 HORIZ_INTERP_BILINEAR); 353 } 354 break; 355 356 case DRM_MODE_SCALE_FULLSCREEN: 357 /* 358 * Full scaling, even if it changes the aspect ratio. 359 * Fortunately this is all done for us in hw. 360 */ 361 if (mode->vdisplay != adjusted_mode->vdisplay || 362 mode->hdisplay != adjusted_mode->hdisplay) { 363 pfit_control |= PFIT_ENABLE; 364 if (INTEL_INFO(dev)->gen >= 4) 365 pfit_control |= PFIT_SCALING_AUTO; 366 else 367 pfit_control |= (VERT_AUTO_SCALE | 368 VERT_INTERP_BILINEAR | 369 HORIZ_AUTO_SCALE | 370 HORIZ_INTERP_BILINEAR); 371 } 372 break; 373 374 default: 375 break; 376 } 377 378 out: 379 /* If not enabling scaling, be consistent and always use 0. */ 380 if ((pfit_control & PFIT_ENABLE) == 0) { 381 pfit_control = 0; 382 pfit_pgm_ratios = 0; 383 } 384 385 /* Make sure pre-965 set dither correctly */ 386 if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither) 387 pfit_control |= PANEL_8TO6_DITHER_ENABLE; 388 389 if (pfit_control != intel_lvds->pfit_control || 390 pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) { 391 intel_lvds->pfit_control = pfit_control; 392 intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios; 393 intel_lvds->pfit_dirty = true; 394 } 395 dev_priv->lvds_border_bits = border; 396 397 /* 398 * XXX: It would be nice to support lower refresh rates on the 399 * panels to reduce power consumption, and perhaps match the 400 * user's requested refresh rate. 401 */ 402 403 return true; 404 } 405 406 static void intel_lvds_prepare(struct drm_encoder *encoder) 407 { 408 struct intel_lvds *intel_lvds = to_intel_lvds(encoder); 409 410 /* 411 * Prior to Ironlake, we must disable the pipe if we want to adjust 412 * the panel fitter. However at all other times we can just reset 413 * the registers regardless. 414 */ 415 if (!HAS_PCH_SPLIT(encoder->dev) && intel_lvds->pfit_dirty) 416 intel_lvds_disable(intel_lvds); 417 } 418 419 static void intel_lvds_commit(struct drm_encoder *encoder) 420 { 421 struct intel_lvds *intel_lvds = to_intel_lvds(encoder); 422 423 /* Always do a full power on as we do not know what state 424 * we were left in. 425 */ 426 intel_lvds_enable(intel_lvds); 427 } 428 429 static void intel_lvds_mode_set(struct drm_encoder *encoder, 430 struct drm_display_mode *mode, 431 struct drm_display_mode *adjusted_mode) 432 { 433 /* 434 * The LVDS pin pair will already have been turned on in the 435 * intel_crtc_mode_set since it has a large impact on the DPLL 436 * settings. 437 */ 438 } 439 440 /** 441 * Detect the LVDS connection. 442 * 443 * Since LVDS doesn't have hotlug, we use the lid as a proxy. Open means 444 * connected and closed means disconnected. We also send hotplug events as 445 * needed, using lid status notification from the input layer. 446 */ 447 static enum drm_connector_status 448 intel_lvds_detect(struct drm_connector *connector, bool force) 449 { 450 struct drm_device *dev = connector->dev; 451 enum drm_connector_status status; 452 453 status = intel_panel_detect(dev); 454 if (status != connector_status_unknown) 455 return status; 456 457 return connector_status_connected; 458 } 459 460 /** 461 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. 462 */ 463 static int intel_lvds_get_modes(struct drm_connector *connector) 464 { 465 struct intel_lvds *intel_lvds = intel_attached_lvds(connector); 466 struct drm_device *dev = connector->dev; 467 struct drm_display_mode *mode; 468 469 if (intel_lvds->edid) 470 return drm_add_edid_modes(connector, intel_lvds->edid); 471 472 mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode); 473 if (mode == NULL) 474 return 0; 475 476 drm_mode_probed_add(connector, mode); 477 return 1; 478 } 479 480 static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id) 481 { 482 DRM_DEBUG_KMS("Skipping forced modeset for %s\n", id->ident); 483 return 1; 484 } 485 486 /* The GPU hangs up on these systems if modeset is performed on LID open */ 487 static const struct dmi_system_id intel_no_modeset_on_lid[] = { 488 { 489 .callback = intel_no_modeset_on_lid_dmi_callback, 490 .ident = "Toshiba Tecra A11", 491 .matches = { 492 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 493 DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"), 494 }, 495 }, 496 497 { } /* terminating entry */ 498 }; 499 500 #ifdef NOTYET 501 /* 502 * Lid events. Note the use of 'modeset_on_lid': 503 * - we set it on lid close, and reset it on open 504 * - we use it as a "only once" bit (ie we ignore 505 * duplicate events where it was already properly 506 * set/reset) 507 * - the suspend/resume paths will also set it to 508 * zero, since they restore the mode ("lid open"). 509 */ 510 static int intel_lid_notify(struct notifier_block *nb, unsigned long val, 511 void *unused) 512 { 513 struct drm_i915_private *dev_priv = 514 container_of(nb, struct drm_i915_private, lid_notifier); 515 struct drm_device *dev = dev_priv->dev; 516 struct drm_connector *connector = dev_priv->int_lvds_connector; 517 518 if (dev->switch_power_state != DRM_SWITCH_POWER_ON) 519 return NOTIFY_OK; 520 521 /* 522 * check and update the status of LVDS connector after receiving 523 * the LID nofication event. 524 */ 525 if (connector) 526 connector->status = connector->funcs->detect(connector, 527 false); 528 529 /* Don't force modeset on machines where it causes a GPU lockup */ 530 if (dmi_check_system(intel_no_modeset_on_lid)) 531 return NOTIFY_OK; 532 if (!acpi_lid_open()) { 533 dev_priv->modeset_on_lid = 1; 534 return NOTIFY_OK; 535 } 536 537 if (!dev_priv->modeset_on_lid) 538 return NOTIFY_OK; 539 540 dev_priv->modeset_on_lid = 0; 541 542 mutex_lock(&dev->mode_config.mutex); 543 drm_helper_resume_force_mode(dev); 544 mutex_unlock(&dev->mode_config.mutex); 545 546 return NOTIFY_OK; 547 } 548 #endif 549 550 /** 551 * intel_lvds_destroy - unregister and free LVDS structures 552 * @connector: connector to free 553 * 554 * Unregister the DDC bus for this connector then free the driver private 555 * structure. 556 */ 557 static void intel_lvds_destroy(struct drm_connector *connector) 558 { 559 struct drm_device *dev = connector->dev; 560 #if 0 561 struct drm_i915_private *dev_priv = dev->dev_private; 562 #endif 563 564 intel_panel_destroy_backlight(dev); 565 566 #if 0 567 if (dev_priv->lid_notifier.notifier_call) 568 acpi_lid_notifier_unregister(&dev_priv->lid_notifier); 569 #endif 570 #if 0 571 drm_sysfs_connector_remove(connector); 572 #endif 573 drm_connector_cleanup(connector); 574 drm_free(connector, DRM_MEM_KMS); 575 } 576 577 static int intel_lvds_set_property(struct drm_connector *connector, 578 struct drm_property *property, 579 uint64_t value) 580 { 581 struct intel_lvds *intel_lvds = intel_attached_lvds(connector); 582 struct drm_device *dev = connector->dev; 583 584 if (property == dev->mode_config.scaling_mode_property) { 585 struct drm_crtc *crtc = intel_lvds->base.base.crtc; 586 587 if (value == DRM_MODE_SCALE_NONE) { 588 DRM_DEBUG_KMS("no scaling not supported\n"); 589 return -EINVAL; 590 } 591 592 if (intel_lvds->fitting_mode == value) { 593 /* the LVDS scaling property is not changed */ 594 return 0; 595 } 596 intel_lvds->fitting_mode = value; 597 if (crtc && crtc->enabled) { 598 /* 599 * If the CRTC is enabled, the display will be changed 600 * according to the new panel fitting mode. 601 */ 602 drm_crtc_helper_set_mode(crtc, &crtc->mode, 603 crtc->x, crtc->y, crtc->fb); 604 } 605 } 606 607 return 0; 608 } 609 610 static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { 611 .dpms = intel_lvds_dpms, 612 .mode_fixup = intel_lvds_mode_fixup, 613 .prepare = intel_lvds_prepare, 614 .mode_set = intel_lvds_mode_set, 615 .commit = intel_lvds_commit, 616 }; 617 618 static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { 619 .get_modes = intel_lvds_get_modes, 620 .mode_valid = intel_lvds_mode_valid, 621 .best_encoder = intel_best_encoder, 622 }; 623 624 static const struct drm_connector_funcs intel_lvds_connector_funcs = { 625 .dpms = drm_helper_connector_dpms, 626 .detect = intel_lvds_detect, 627 .fill_modes = drm_helper_probe_single_connector_modes, 628 .set_property = intel_lvds_set_property, 629 .destroy = intel_lvds_destroy, 630 }; 631 632 static const struct drm_encoder_funcs intel_lvds_enc_funcs = { 633 .destroy = intel_encoder_destroy, 634 }; 635 636 static int intel_no_lvds_dmi_callback(const struct dmi_system_id *id) 637 { 638 DRM_DEBUG_KMS("Skipping LVDS initialization for %s\n", id->ident); 639 return 1; 640 } 641 642 /* These systems claim to have LVDS, but really don't */ 643 static const struct dmi_system_id intel_no_lvds[] = { 644 { 645 .callback = intel_no_lvds_dmi_callback, 646 .ident = "Apple Mac Mini (Core series)", 647 .matches = { 648 DMI_MATCH(DMI_SYS_VENDOR, "Apple"), 649 DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), 650 }, 651 }, 652 { 653 .callback = intel_no_lvds_dmi_callback, 654 .ident = "Apple Mac Mini (Core 2 series)", 655 .matches = { 656 DMI_MATCH(DMI_SYS_VENDOR, "Apple"), 657 DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"), 658 }, 659 }, 660 { 661 .callback = intel_no_lvds_dmi_callback, 662 .ident = "MSI IM-945GSE-A", 663 .matches = { 664 DMI_MATCH(DMI_SYS_VENDOR, "MSI"), 665 DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"), 666 }, 667 }, 668 { 669 .callback = intel_no_lvds_dmi_callback, 670 .ident = "Dell Studio Hybrid", 671 .matches = { 672 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 673 DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"), 674 }, 675 }, 676 { 677 .callback = intel_no_lvds_dmi_callback, 678 .ident = "Dell OptiPlex FX170", 679 .matches = { 680 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 681 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex FX170"), 682 }, 683 }, 684 { 685 .callback = intel_no_lvds_dmi_callback, 686 .ident = "AOpen Mini PC", 687 .matches = { 688 DMI_MATCH(DMI_SYS_VENDOR, "AOpen"), 689 DMI_MATCH(DMI_PRODUCT_NAME, "i965GMx-IF"), 690 }, 691 }, 692 { 693 .callback = intel_no_lvds_dmi_callback, 694 .ident = "AOpen Mini PC MP915", 695 .matches = { 696 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 697 DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"), 698 }, 699 }, 700 { 701 .callback = intel_no_lvds_dmi_callback, 702 .ident = "AOpen i915GMm-HFS", 703 .matches = { 704 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 705 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 706 }, 707 }, 708 { 709 .callback = intel_no_lvds_dmi_callback, 710 .ident = "AOpen i45GMx-I", 711 .matches = { 712 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 713 DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"), 714 }, 715 }, 716 { 717 .callback = intel_no_lvds_dmi_callback, 718 .ident = "Aopen i945GTt-VFA", 719 .matches = { 720 DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), 721 }, 722 }, 723 { 724 .callback = intel_no_lvds_dmi_callback, 725 .ident = "Clientron U800", 726 .matches = { 727 DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), 728 DMI_MATCH(DMI_PRODUCT_NAME, "U800"), 729 }, 730 }, 731 { 732 .callback = intel_no_lvds_dmi_callback, 733 .ident = "Clientron E830", 734 .matches = { 735 DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), 736 DMI_MATCH(DMI_PRODUCT_NAME, "E830"), 737 }, 738 }, 739 { 740 .callback = intel_no_lvds_dmi_callback, 741 .ident = "Asus EeeBox PC EB1007", 742 .matches = { 743 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), 744 DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"), 745 }, 746 }, 747 { 748 .callback = intel_no_lvds_dmi_callback, 749 .ident = "Asus AT5NM10T-I", 750 .matches = { 751 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), 752 DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"), 753 }, 754 }, 755 { 756 .callback = intel_no_lvds_dmi_callback, 757 .ident = "Hewlett-Packard t5745", 758 .matches = { 759 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), 760 DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"), 761 }, 762 }, 763 { 764 .callback = intel_no_lvds_dmi_callback, 765 .ident = "Hewlett-Packard st5747", 766 .matches = { 767 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), 768 DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"), 769 }, 770 }, 771 { 772 .callback = intel_no_lvds_dmi_callback, 773 .ident = "MSI Wind Box DC500", 774 .matches = { 775 DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), 776 DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), 777 }, 778 }, 779 { 780 .callback = intel_no_lvds_dmi_callback, 781 .ident = "Supermicro X7SPA-H", 782 .matches = { 783 DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), 784 DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"), 785 }, 786 }, 787 788 { } /* terminating entry */ 789 }; 790 791 /** 792 * intel_find_lvds_downclock - find the reduced downclock for LVDS in EDID 793 * @dev: drm device 794 * @connector: LVDS connector 795 * 796 * Find the reduced downclock for LVDS in EDID. 797 */ 798 static void intel_find_lvds_downclock(struct drm_device *dev, 799 struct drm_display_mode *fixed_mode, 800 struct drm_connector *connector) 801 { 802 struct drm_i915_private *dev_priv = dev->dev_private; 803 struct drm_display_mode *scan; 804 int temp_downclock; 805 806 temp_downclock = fixed_mode->clock; 807 list_for_each_entry(scan, &connector->probed_modes, head) { 808 /* 809 * If one mode has the same resolution with the fixed_panel 810 * mode while they have the different refresh rate, it means 811 * that the reduced downclock is found for the LVDS. In such 812 * case we can set the different FPx0/1 to dynamically select 813 * between low and high frequency. 814 */ 815 if (scan->hdisplay == fixed_mode->hdisplay && 816 scan->hsync_start == fixed_mode->hsync_start && 817 scan->hsync_end == fixed_mode->hsync_end && 818 scan->htotal == fixed_mode->htotal && 819 scan->vdisplay == fixed_mode->vdisplay && 820 scan->vsync_start == fixed_mode->vsync_start && 821 scan->vsync_end == fixed_mode->vsync_end && 822 scan->vtotal == fixed_mode->vtotal) { 823 if (scan->clock < temp_downclock) { 824 /* 825 * The downclock is already found. But we 826 * expect to find the lower downclock. 827 */ 828 temp_downclock = scan->clock; 829 } 830 } 831 } 832 if (temp_downclock < fixed_mode->clock && i915_lvds_downclock) { 833 /* We found the downclock for LVDS. */ 834 dev_priv->lvds_downclock_avail = 1; 835 dev_priv->lvds_downclock = temp_downclock; 836 DRM_DEBUG_KMS("LVDS downclock is found in EDID. " 837 "Normal clock %dKhz, downclock %dKhz\n", 838 fixed_mode->clock, temp_downclock); 839 } 840 } 841 842 /* 843 * Enumerate the child dev array parsed from VBT to check whether 844 * the LVDS is present. 845 * If it is present, return 1. 846 * If it is not present, return false. 847 * If no child dev is parsed from VBT, it assumes that the LVDS is present. 848 */ 849 static bool lvds_is_present_in_vbt(struct drm_device *dev, 850 u8 *i2c_pin) 851 { 852 struct drm_i915_private *dev_priv = dev->dev_private; 853 int i; 854 855 if (!dev_priv->child_dev_num) 856 return true; 857 858 for (i = 0; i < dev_priv->child_dev_num; i++) { 859 struct child_device_config *child = dev_priv->child_dev + i; 860 861 /* If the device type is not LFP, continue. 862 * We have to check both the new identifiers as well as the 863 * old for compatibility with some BIOSes. 864 */ 865 if (child->device_type != DEVICE_TYPE_INT_LFP && 866 child->device_type != DEVICE_TYPE_LFP) 867 continue; 868 869 if (child->i2c_pin) 870 *i2c_pin = child->i2c_pin; 871 872 /* However, we cannot trust the BIOS writers to populate 873 * the VBT correctly. Since LVDS requires additional 874 * information from AIM blocks, a non-zero addin offset is 875 * a good indicator that the LVDS is actually present. 876 */ 877 if (child->addin_offset) 878 return true; 879 880 /* But even then some BIOS writers perform some black magic 881 * and instantiate the device without reference to any 882 * additional data. Trust that if the VBT was written into 883 * the OpRegion then they have validated the LVDS's existence. 884 */ 885 if (dev_priv->opregion.vbt) 886 return true; 887 } 888 889 return false; 890 } 891 892 static bool intel_lvds_supported(struct drm_device *dev) 893 { 894 /* With the introduction of the PCH we gained a dedicated 895 * LVDS presence pin, use it. */ 896 if (HAS_PCH_SPLIT(dev)) 897 return true; 898 899 /* Otherwise LVDS was only attached to mobile products, 900 * except for the inglorious 830gm */ 901 return IS_MOBILE(dev) && !IS_I830(dev); 902 } 903 904 /** 905 * intel_lvds_init - setup LVDS connectors on this device 906 * @dev: drm device 907 * 908 * Create the connector, register the LVDS DDC bus, and try to figure out what 909 * modes we can display on the LVDS panel (if present). 910 */ 911 bool intel_lvds_init(struct drm_device *dev) 912 { 913 struct drm_i915_private *dev_priv = dev->dev_private; 914 struct intel_lvds *intel_lvds; 915 struct intel_encoder *intel_encoder; 916 struct intel_connector *intel_connector; 917 struct drm_connector *connector; 918 struct drm_encoder *encoder; 919 struct drm_display_mode *scan; /* *modes, *bios_mode; */ 920 struct drm_crtc *crtc; 921 u32 lvds; 922 int pipe; 923 u8 pin; 924 925 if (!intel_lvds_supported(dev)) 926 return false; 927 928 /* Skip init on machines we know falsely report LVDS */ 929 if (dmi_check_system(intel_no_lvds)) 930 return false; 931 932 pin = GMBUS_PORT_PANEL; 933 if (!lvds_is_present_in_vbt(dev, &pin)) { 934 DRM_DEBUG_KMS("LVDS is not present in VBT\n"); 935 return false; 936 } 937 938 if (HAS_PCH_SPLIT(dev)) { 939 if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) 940 return false; 941 if (dev_priv->edp.support) { 942 DRM_DEBUG_KMS("disable LVDS for eDP support\n"); 943 return false; 944 } 945 } 946 947 intel_lvds = kmalloc(sizeof(struct intel_lvds), DRM_MEM_KMS, 948 M_WAITOK | M_ZERO); 949 intel_connector = kmalloc(sizeof(struct intel_connector), DRM_MEM_KMS, 950 M_WAITOK | M_ZERO); 951 952 if (!HAS_PCH_SPLIT(dev)) { 953 intel_lvds->pfit_control = I915_READ(PFIT_CONTROL); 954 } 955 956 intel_encoder = &intel_lvds->base; 957 encoder = &intel_encoder->base; 958 connector = &intel_connector->base; 959 drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, 960 DRM_MODE_CONNECTOR_LVDS); 961 962 drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs, 963 DRM_MODE_ENCODER_LVDS); 964 965 intel_connector_attach_encoder(intel_connector, intel_encoder); 966 intel_encoder->type = INTEL_OUTPUT_LVDS; 967 968 intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); 969 if (HAS_PCH_SPLIT(dev)) 970 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); 971 else 972 intel_encoder->crtc_mask = (1 << 1); 973 974 drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); 975 drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); 976 connector->display_info.subpixel_order = SubPixelHorizontalRGB; 977 connector->interlace_allowed = false; 978 connector->doublescan_allowed = false; 979 980 /* create the scaling mode property */ 981 drm_mode_create_scaling_mode_property(dev); 982 /* 983 * the initial panel fitting mode will be FULL_SCREEN. 984 */ 985 986 drm_connector_attach_property(&intel_connector->base, 987 dev->mode_config.scaling_mode_property, 988 DRM_MODE_SCALE_ASPECT); 989 intel_lvds->fitting_mode = DRM_MODE_SCALE_ASPECT; 990 /* 991 * LVDS discovery: 992 * 1) check for EDID on DDC 993 * 2) check for VBT data 994 * 3) check to see if LVDS is already on 995 * if none of the above, no panel 996 * 4) make sure lid is open 997 * if closed, act like it's not there for now 998 */ 999 1000 /* 1001 * Attempt to get the fixed panel mode from DDC. Assume that the 1002 * preferred mode is the right one. 1003 */ 1004 intel_lvds->edid = drm_get_edid(connector, dev_priv->gmbus[pin]); 1005 if (intel_lvds->edid) { 1006 if (drm_add_edid_modes(connector, 1007 intel_lvds->edid)) { 1008 drm_mode_connector_update_edid_property(connector, 1009 intel_lvds->edid); 1010 } else { 1011 drm_free(intel_lvds->edid, DRM_MEM_KMS); 1012 intel_lvds->edid = NULL; 1013 } 1014 } 1015 if (!intel_lvds->edid) { 1016 /* Didn't get an EDID, so 1017 * Set wide sync ranges so we get all modes 1018 * handed to valid_mode for checking 1019 */ 1020 connector->display_info.min_vfreq = 0; 1021 connector->display_info.max_vfreq = 200; 1022 connector->display_info.min_hfreq = 0; 1023 connector->display_info.max_hfreq = 200; 1024 } 1025 1026 list_for_each_entry(scan, &connector->probed_modes, head) { 1027 if (scan->type & DRM_MODE_TYPE_PREFERRED) { 1028 intel_lvds->fixed_mode = 1029 drm_mode_duplicate(dev, scan); 1030 intel_find_lvds_downclock(dev, 1031 intel_lvds->fixed_mode, 1032 connector); 1033 goto out; 1034 } 1035 } 1036 1037 /* Failed to get EDID, what about VBT? */ 1038 if (dev_priv->lfp_lvds_vbt_mode) { 1039 intel_lvds->fixed_mode = 1040 drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); 1041 if (intel_lvds->fixed_mode) { 1042 intel_lvds->fixed_mode->type |= 1043 DRM_MODE_TYPE_PREFERRED; 1044 goto out; 1045 } 1046 } 1047 1048 /* 1049 * If we didn't get EDID, try checking if the panel is already turned 1050 * on. If so, assume that whatever is currently programmed is the 1051 * correct mode. 1052 */ 1053 1054 /* Ironlake: FIXME if still fail, not try pipe mode now */ 1055 if (HAS_PCH_SPLIT(dev)) 1056 goto failed; 1057 1058 lvds = I915_READ(LVDS); 1059 pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; 1060 crtc = intel_get_crtc_for_pipe(dev, pipe); 1061 1062 if (crtc && (lvds & LVDS_PORT_EN)) { 1063 intel_lvds->fixed_mode = intel_crtc_mode_get(dev, crtc); 1064 if (intel_lvds->fixed_mode) { 1065 intel_lvds->fixed_mode->type |= 1066 DRM_MODE_TYPE_PREFERRED; 1067 goto out; 1068 } 1069 } 1070 1071 /* If we still don't have a mode after all that, give up. */ 1072 if (!intel_lvds->fixed_mode) 1073 goto failed; 1074 1075 out: 1076 if (HAS_PCH_SPLIT(dev)) { 1077 u32 pwm; 1078 1079 pipe = (I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT) ? 1 : 0; 1080 1081 /* make sure PWM is enabled and locked to the LVDS pipe */ 1082 pwm = I915_READ(BLC_PWM_CPU_CTL2); 1083 if (pipe == 0 && (pwm & PWM_PIPE_B)) 1084 I915_WRITE(BLC_PWM_CPU_CTL2, pwm & ~PWM_ENABLE); 1085 if (pipe) 1086 pwm |= PWM_PIPE_B; 1087 else 1088 pwm &= ~PWM_PIPE_B; 1089 I915_WRITE(BLC_PWM_CPU_CTL2, pwm | PWM_ENABLE); 1090 1091 pwm = I915_READ(BLC_PWM_PCH_CTL1); 1092 pwm |= PWM_PCH_ENABLE; 1093 I915_WRITE(BLC_PWM_PCH_CTL1, pwm); 1094 /* 1095 * Unlock registers and just 1096 * leave them unlocked 1097 */ 1098 I915_WRITE(PCH_PP_CONTROL, 1099 I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); 1100 } else { 1101 /* 1102 * Unlock registers and just 1103 * leave them unlocked 1104 */ 1105 I915_WRITE(PP_CONTROL, 1106 I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); 1107 } 1108 #ifdef NOTYET 1109 dev_priv->lid_notifier.notifier_call = intel_lid_notify; 1110 if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) { 1111 DRM_DEBUG_KMS("lid notifier registration failed\n"); 1112 dev_priv->lid_notifier.notifier_call = NULL; 1113 } 1114 #endif 1115 /* keep the LVDS connector */ 1116 dev_priv->int_lvds_connector = connector; 1117 #if 0 1118 drm_sysfs_connector_add(connector); 1119 #endif 1120 intel_panel_setup_backlight(dev); 1121 return true; 1122 1123 failed: 1124 DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); 1125 drm_connector_cleanup(connector); 1126 drm_encoder_cleanup(encoder); 1127 drm_free(intel_lvds, DRM_MEM_KMS); 1128 drm_free(intel_connector, DRM_MEM_KMS); 1129 return false; 1130 } 1131