linux/drivers/gpu/drm/i915/intel_lvds.c
<<
>>
Prefs
   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 */
  29
  30#include <acpi/button.h>
  31#include <linux/dmi.h>
  32#include <linux/i2c.h>
  33#include <linux/slab.h>
  34#include <linux/vga_switcheroo.h>
  35#include <drm/drmP.h>
  36#include <drm/drm_atomic_helper.h>
  37#include <drm/drm_crtc.h>
  38#include <drm/drm_edid.h>
  39#include "intel_drv.h"
  40#include <drm/i915_drm.h>
  41#include "i915_drv.h"
  42#include <linux/acpi.h>
  43
  44/* Private structure for the integrated LVDS support */
  45struct intel_lvds_connector {
  46        struct intel_connector base;
  47
  48        struct notifier_block lid_notifier;
  49};
  50
  51struct intel_lvds_pps {
  52        /* 100us units */
  53        int t1_t2;
  54        int t3;
  55        int t4;
  56        int t5;
  57        int tx;
  58
  59        int divider;
  60
  61        int port;
  62        bool powerdown_on_reset;
  63};
  64
  65struct intel_lvds_encoder {
  66        struct intel_encoder base;
  67
  68        bool is_dual_link;
  69        i915_reg_t reg;
  70        u32 a3_power;
  71
  72        struct intel_lvds_pps init_pps;
  73        u32 init_lvds_val;
  74
  75        struct intel_lvds_connector *attached_connector;
  76};
  77
  78static struct intel_lvds_encoder *to_lvds_encoder(struct drm_encoder *encoder)
  79{
  80        return container_of(encoder, struct intel_lvds_encoder, base.base);
  81}
  82
  83static struct intel_lvds_connector *to_lvds_connector(struct drm_connector *connector)
  84{
  85        return container_of(connector, struct intel_lvds_connector, base.base);
  86}
  87
  88static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
  89                                    enum pipe *pipe)
  90{
  91        struct drm_device *dev = encoder->base.dev;
  92        struct drm_i915_private *dev_priv = to_i915(dev);
  93        struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
  94        enum intel_display_power_domain power_domain;
  95        u32 tmp;
  96        bool ret;
  97
  98        power_domain = intel_display_port_power_domain(encoder);
  99        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
 100                return false;
 101
 102        ret = false;
 103
 104        tmp = I915_READ(lvds_encoder->reg);
 105
 106        if (!(tmp & LVDS_PORT_EN))
 107                goto out;
 108
 109        if (HAS_PCH_CPT(dev))
 110                *pipe = PORT_TO_PIPE_CPT(tmp);
 111        else
 112                *pipe = PORT_TO_PIPE(tmp);
 113
 114        ret = true;
 115
 116out:
 117        intel_display_power_put(dev_priv, power_domain);
 118
 119        return ret;
 120}
 121
 122static void intel_lvds_get_config(struct intel_encoder *encoder,
 123                                  struct intel_crtc_state *pipe_config)
 124{
 125        struct drm_device *dev = encoder->base.dev;
 126        struct drm_i915_private *dev_priv = to_i915(dev);
 127        struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
 128        u32 tmp, flags = 0;
 129
 130        tmp = I915_READ(lvds_encoder->reg);
 131        if (tmp & LVDS_HSYNC_POLARITY)
 132                flags |= DRM_MODE_FLAG_NHSYNC;
 133        else
 134                flags |= DRM_MODE_FLAG_PHSYNC;
 135        if (tmp & LVDS_VSYNC_POLARITY)
 136                flags |= DRM_MODE_FLAG_NVSYNC;
 137        else
 138                flags |= DRM_MODE_FLAG_PVSYNC;
 139
 140        pipe_config->base.adjusted_mode.flags |= flags;
 141
 142        if (INTEL_INFO(dev)->gen < 5)
 143                pipe_config->gmch_pfit.lvds_border_bits =
 144                        tmp & LVDS_BORDER_ENABLE;
 145
 146        /* gen2/3 store dither state in pfit control, needs to match */
 147        if (INTEL_INFO(dev)->gen < 4) {
 148                tmp = I915_READ(PFIT_CONTROL);
 149
 150                pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
 151        }
 152
 153        pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
 154}
 155
 156static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv,
 157                                        struct intel_lvds_pps *pps)
 158{
 159        u32 val;
 160
 161        pps->powerdown_on_reset = I915_READ(PP_CONTROL(0)) & PANEL_POWER_RESET;
 162
 163        val = I915_READ(PP_ON_DELAYS(0));
 164        pps->port = (val & PANEL_PORT_SELECT_MASK) >>
 165                    PANEL_PORT_SELECT_SHIFT;
 166        pps->t1_t2 = (val & PANEL_POWER_UP_DELAY_MASK) >>
 167                     PANEL_POWER_UP_DELAY_SHIFT;
 168        pps->t5 = (val & PANEL_LIGHT_ON_DELAY_MASK) >>
 169                  PANEL_LIGHT_ON_DELAY_SHIFT;
 170
 171        val = I915_READ(PP_OFF_DELAYS(0));
 172        pps->t3 = (val & PANEL_POWER_DOWN_DELAY_MASK) >>
 173                  PANEL_POWER_DOWN_DELAY_SHIFT;
 174        pps->tx = (val & PANEL_LIGHT_OFF_DELAY_MASK) >>
 175                  PANEL_LIGHT_OFF_DELAY_SHIFT;
 176
 177        val = I915_READ(PP_DIVISOR(0));
 178        pps->divider = (val & PP_REFERENCE_DIVIDER_MASK) >>
 179                       PP_REFERENCE_DIVIDER_SHIFT;
 180        val = (val & PANEL_POWER_CYCLE_DELAY_MASK) >>
 181              PANEL_POWER_CYCLE_DELAY_SHIFT;
 182        /*
 183         * Remove the BSpec specified +1 (100ms) offset that accounts for a
 184         * too short power-cycle delay due to the asynchronous programming of
 185         * the register.
 186         */
 187        if (val)
 188                val--;
 189        /* Convert from 100ms to 100us units */
 190        pps->t4 = val * 1000;
 191
 192        if (INTEL_INFO(dev_priv)->gen <= 4 &&
 193            pps->t1_t2 == 0 && pps->t5 == 0 && pps->t3 == 0 && pps->tx == 0) {
 194                DRM_DEBUG_KMS("Panel power timings uninitialized, "
 195                              "setting defaults\n");
 196                /* Set T2 to 40ms and T5 to 200ms in 100 usec units */
 197                pps->t1_t2 = 40 * 10;
 198                pps->t5 = 200 * 10;
 199                /* Set T3 to 35ms and Tx to 200ms in 100 usec units */
 200                pps->t3 = 35 * 10;
 201                pps->tx = 200 * 10;
 202        }
 203
 204        DRM_DEBUG_DRIVER("LVDS PPS:t1+t2 %d t3 %d t4 %d t5 %d tx %d "
 205                         "divider %d port %d powerdown_on_reset %d\n",
 206                         pps->t1_t2, pps->t3, pps->t4, pps->t5, pps->tx,
 207                         pps->divider, pps->port, pps->powerdown_on_reset);
 208}
 209
 210static void intel_lvds_pps_init_hw(struct drm_i915_private *dev_priv,
 211                                   struct intel_lvds_pps *pps)
 212{
 213        u32 val;
 214
 215        val = I915_READ(PP_CONTROL(0));
 216        WARN_ON((val & PANEL_UNLOCK_MASK) != PANEL_UNLOCK_REGS);
 217        if (pps->powerdown_on_reset)
 218                val |= PANEL_POWER_RESET;
 219        I915_WRITE(PP_CONTROL(0), val);
 220
 221        I915_WRITE(PP_ON_DELAYS(0), (pps->port << PANEL_PORT_SELECT_SHIFT) |
 222                                    (pps->t1_t2 << PANEL_POWER_UP_DELAY_SHIFT) |
 223                                    (pps->t5 << PANEL_LIGHT_ON_DELAY_SHIFT));
 224        I915_WRITE(PP_OFF_DELAYS(0), (pps->t3 << PANEL_POWER_DOWN_DELAY_SHIFT) |
 225                                     (pps->tx << PANEL_LIGHT_OFF_DELAY_SHIFT));
 226
 227        val = pps->divider << PP_REFERENCE_DIVIDER_SHIFT;
 228        val |= (DIV_ROUND_UP(pps->t4, 1000) + 1) <<
 229               PANEL_POWER_CYCLE_DELAY_SHIFT;
 230        I915_WRITE(PP_DIVISOR(0), val);
 231}
 232
 233static void intel_pre_enable_lvds(struct intel_encoder *encoder,
 234                                  struct intel_crtc_state *pipe_config,
 235                                  struct drm_connector_state *conn_state)
 236{
 237        struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
 238        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 239        struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
 240        const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 241        int pipe = crtc->pipe;
 242        u32 temp;
 243
 244        if (HAS_PCH_SPLIT(dev_priv)) {
 245                assert_fdi_rx_pll_disabled(dev_priv, pipe);
 246                assert_shared_dpll_disabled(dev_priv,
 247                                            pipe_config->shared_dpll);
 248        } else {
 249                assert_pll_disabled(dev_priv, pipe);
 250        }
 251
 252        intel_lvds_pps_init_hw(dev_priv, &lvds_encoder->init_pps);
 253
 254        temp = lvds_encoder->init_lvds_val;
 255        temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
 256
 257        if (HAS_PCH_CPT(dev_priv)) {
 258                temp &= ~PORT_TRANS_SEL_MASK;
 259                temp |= PORT_TRANS_SEL_CPT(pipe);
 260        } else {
 261                if (pipe == 1) {
 262                        temp |= LVDS_PIPEB_SELECT;
 263                } else {
 264                        temp &= ~LVDS_PIPEB_SELECT;
 265                }
 266        }
 267
 268        /* set the corresponsding LVDS_BORDER bit */
 269        temp &= ~LVDS_BORDER_ENABLE;
 270        temp |= pipe_config->gmch_pfit.lvds_border_bits;
 271        /* Set the B0-B3 data pairs corresponding to whether we're going to
 272         * set the DPLLs for dual-channel mode or not.
 273         */
 274        if (lvds_encoder->is_dual_link)
 275                temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
 276        else
 277                temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
 278
 279        /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
 280         * appropriately here, but we need to look more thoroughly into how
 281         * panels behave in the two modes. For now, let's just maintain the
 282         * value we got from the BIOS.
 283         */
 284        temp &= ~LVDS_A3_POWER_MASK;
 285        temp |= lvds_encoder->a3_power;
 286
 287        /* Set the dithering flag on LVDS as needed, note that there is no
 288         * special lvds dither control bit on pch-split platforms, dithering is
 289         * only controlled through the PIPECONF reg. */
 290        if (IS_GEN4(dev_priv)) {
 291                /* Bspec wording suggests that LVDS port dithering only exists
 292                 * for 18bpp panels. */
 293                if (pipe_config->dither && pipe_config->pipe_bpp == 18)
 294                        temp |= LVDS_ENABLE_DITHER;
 295                else
 296                        temp &= ~LVDS_ENABLE_DITHER;
 297        }
 298        temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
 299        if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
 300                temp |= LVDS_HSYNC_POLARITY;
 301        if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
 302                temp |= LVDS_VSYNC_POLARITY;
 303
 304        I915_WRITE(lvds_encoder->reg, temp);
 305}
 306
 307/**
 308 * Sets the power state for the panel.
 309 */
 310static void intel_enable_lvds(struct intel_encoder *encoder,
 311                              struct intel_crtc_state *pipe_config,
 312                              struct drm_connector_state *conn_state)
 313{
 314        struct drm_device *dev = encoder->base.dev;
 315        struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
 316        struct intel_connector *intel_connector =
 317                &lvds_encoder->attached_connector->base;
 318        struct drm_i915_private *dev_priv = to_i915(dev);
 319
 320        I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) | LVDS_PORT_EN);
 321
 322        I915_WRITE(PP_CONTROL(0), I915_READ(PP_CONTROL(0)) | PANEL_POWER_ON);
 323        POSTING_READ(lvds_encoder->reg);
 324        if (intel_wait_for_register(dev_priv, PP_STATUS(0), PP_ON, PP_ON, 1000))
 325                DRM_ERROR("timed out waiting for panel to power on\n");
 326
 327        intel_panel_enable_backlight(intel_connector);
 328}
 329
 330static void intel_disable_lvds(struct intel_encoder *encoder,
 331                               struct intel_crtc_state *old_crtc_state,
 332                               struct drm_connector_state *old_conn_state)
 333{
 334        struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
 335        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 336
 337        I915_WRITE(PP_CONTROL(0), I915_READ(PP_CONTROL(0)) & ~PANEL_POWER_ON);
 338        if (intel_wait_for_register(dev_priv, PP_STATUS(0), PP_ON, 0, 1000))
 339                DRM_ERROR("timed out waiting for panel to power off\n");
 340
 341        I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) & ~LVDS_PORT_EN);
 342        POSTING_READ(lvds_encoder->reg);
 343}
 344
 345static void gmch_disable_lvds(struct intel_encoder *encoder,
 346                              struct intel_crtc_state *old_crtc_state,
 347                              struct drm_connector_state *old_conn_state)
 348
 349{
 350        struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
 351        struct intel_connector *intel_connector =
 352                &lvds_encoder->attached_connector->base;
 353
 354        intel_panel_disable_backlight(intel_connector);
 355
 356        intel_disable_lvds(encoder, old_crtc_state, old_conn_state);
 357}
 358
 359static void pch_disable_lvds(struct intel_encoder *encoder,
 360                             struct intel_crtc_state *old_crtc_state,
 361                             struct drm_connector_state *old_conn_state)
 362{
 363        struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
 364        struct intel_connector *intel_connector =
 365                &lvds_encoder->attached_connector->base;
 366
 367        intel_panel_disable_backlight(intel_connector);
 368}
 369
 370static void pch_post_disable_lvds(struct intel_encoder *encoder,
 371                                  struct intel_crtc_state *old_crtc_state,
 372                                  struct drm_connector_state *old_conn_state)
 373{
 374        intel_disable_lvds(encoder, old_crtc_state, old_conn_state);
 375}
 376
 377static enum drm_mode_status
 378intel_lvds_mode_valid(struct drm_connector *connector,
 379                      struct drm_display_mode *mode)
 380{
 381        struct intel_connector *intel_connector = to_intel_connector(connector);
 382        struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
 383        int max_pixclk = to_i915(connector->dev)->max_dotclk_freq;
 384
 385        if (mode->hdisplay > fixed_mode->hdisplay)
 386                return MODE_PANEL;
 387        if (mode->vdisplay > fixed_mode->vdisplay)
 388                return MODE_PANEL;
 389        if (fixed_mode->clock > max_pixclk)
 390                return MODE_CLOCK_HIGH;
 391
 392        return MODE_OK;
 393}
 394
 395static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
 396                                      struct intel_crtc_state *pipe_config,
 397                                      struct drm_connector_state *conn_state)
 398{
 399        struct drm_device *dev = intel_encoder->base.dev;
 400        struct intel_lvds_encoder *lvds_encoder =
 401                to_lvds_encoder(&intel_encoder->base);
 402        struct intel_connector *intel_connector =
 403                &lvds_encoder->attached_connector->base;
 404        struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 405        struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
 406        unsigned int lvds_bpp;
 407
 408        /* Should never happen!! */
 409        if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) {
 410                DRM_ERROR("Can't support LVDS on pipe A\n");
 411                return false;
 412        }
 413
 414        if (lvds_encoder->a3_power == LVDS_A3_POWER_UP)
 415                lvds_bpp = 8*3;
 416        else
 417                lvds_bpp = 6*3;
 418
 419        if (lvds_bpp != pipe_config->pipe_bpp && !pipe_config->bw_constrained) {
 420                DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n",
 421                              pipe_config->pipe_bpp, lvds_bpp);
 422                pipe_config->pipe_bpp = lvds_bpp;
 423        }
 424
 425        /*
 426         * We have timings from the BIOS for the panel, put them in
 427         * to the adjusted mode.  The CRTC will be set up for this mode,
 428         * with the panel scaling set up to source from the H/VDisplay
 429         * of the original mode.
 430         */
 431        intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
 432                               adjusted_mode);
 433
 434        if (HAS_PCH_SPLIT(dev)) {
 435                pipe_config->has_pch_encoder = true;
 436
 437                intel_pch_panel_fitting(intel_crtc, pipe_config,
 438                                        intel_connector->panel.fitting_mode);
 439        } else {
 440                intel_gmch_panel_fitting(intel_crtc, pipe_config,
 441                                         intel_connector->panel.fitting_mode);
 442
 443        }
 444
 445        /*
 446         * XXX: It would be nice to support lower refresh rates on the
 447         * panels to reduce power consumption, and perhaps match the
 448         * user's requested refresh rate.
 449         */
 450
 451        return true;
 452}
 453
 454/**
 455 * Detect the LVDS connection.
 456 *
 457 * Since LVDS doesn't have hotlug, we use the lid as a proxy.  Open means
 458 * connected and closed means disconnected.  We also send hotplug events as
 459 * needed, using lid status notification from the input layer.
 460 */
 461static enum drm_connector_status
 462intel_lvds_detect(struct drm_connector *connector, bool force)
 463{
 464        struct drm_device *dev = connector->dev;
 465        enum drm_connector_status status;
 466
 467        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 468                      connector->base.id, connector->name);
 469
 470        status = intel_panel_detect(dev);
 471        if (status != connector_status_unknown)
 472                return status;
 473
 474        return connector_status_connected;
 475}
 476
 477/**
 478 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
 479 */
 480static int intel_lvds_get_modes(struct drm_connector *connector)
 481{
 482        struct intel_lvds_connector *lvds_connector = to_lvds_connector(connector);
 483        struct drm_device *dev = connector->dev;
 484        struct drm_display_mode *mode;
 485
 486        /* use cached edid if we have one */
 487        if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
 488                return drm_add_edid_modes(connector, lvds_connector->base.edid);
 489
 490        mode = drm_mode_duplicate(dev, lvds_connector->base.panel.fixed_mode);
 491        if (mode == NULL)
 492                return 0;
 493
 494        drm_mode_probed_add(connector, mode);
 495        return 1;
 496}
 497
 498static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id)
 499{
 500        DRM_INFO("Skipping forced modeset for %s\n", id->ident);
 501        return 1;
 502}
 503
 504/* The GPU hangs up on these systems if modeset is performed on LID open */
 505static const struct dmi_system_id intel_no_modeset_on_lid[] = {
 506        {
 507                .callback = intel_no_modeset_on_lid_dmi_callback,
 508                .ident = "Toshiba Tecra A11",
 509                .matches = {
 510                        DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 511                        DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"),
 512                },
 513        },
 514
 515        { }     /* terminating entry */
 516};
 517
 518/*
 519 * Lid events. Note the use of 'modeset':
 520 *  - we set it to MODESET_ON_LID_OPEN on lid close,
 521 *    and set it to MODESET_DONE on open
 522 *  - we use it as a "only once" bit (ie we ignore
 523 *    duplicate events where it was already properly set)
 524 *  - the suspend/resume paths will set it to
 525 *    MODESET_SUSPENDED and ignore the lid open event,
 526 *    because they restore the mode ("lid open").
 527 */
 528static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
 529                            void *unused)
 530{
 531        struct intel_lvds_connector *lvds_connector =
 532                container_of(nb, struct intel_lvds_connector, lid_notifier);
 533        struct drm_connector *connector = &lvds_connector->base.base;
 534        struct drm_device *dev = connector->dev;
 535        struct drm_i915_private *dev_priv = to_i915(dev);
 536
 537        if (dev->switch_power_state != DRM_SWITCH_POWER_ON)
 538                return NOTIFY_OK;
 539
 540        mutex_lock(&dev_priv->modeset_restore_lock);
 541        if (dev_priv->modeset_restore == MODESET_SUSPENDED)
 542                goto exit;
 543        /*
 544         * check and update the status of LVDS connector after receiving
 545         * the LID nofication event.
 546         */
 547        connector->status = connector->funcs->detect(connector, false);
 548
 549        /* Don't force modeset on machines where it causes a GPU lockup */
 550        if (dmi_check_system(intel_no_modeset_on_lid))
 551                goto exit;
 552        if (!acpi_lid_open()) {
 553                /* do modeset on next lid open event */
 554                dev_priv->modeset_restore = MODESET_ON_LID_OPEN;
 555                goto exit;
 556        }
 557
 558        if (dev_priv->modeset_restore == MODESET_DONE)
 559                goto exit;
 560
 561        /*
 562         * Some old platform's BIOS love to wreak havoc while the lid is closed.
 563         * We try to detect this here and undo any damage. The split for PCH
 564         * platforms is rather conservative and a bit arbitrary expect that on
 565         * those platforms VGA disabling requires actual legacy VGA I/O access,
 566         * and as part of the cleanup in the hw state restore we also redisable
 567         * the vga plane.
 568         */
 569        if (!HAS_PCH_SPLIT(dev))
 570                intel_display_resume(dev);
 571
 572        dev_priv->modeset_restore = MODESET_DONE;
 573
 574exit:
 575        mutex_unlock(&dev_priv->modeset_restore_lock);
 576        return NOTIFY_OK;
 577}
 578
 579/**
 580 * intel_lvds_destroy - unregister and free LVDS structures
 581 * @connector: connector to free
 582 *
 583 * Unregister the DDC bus for this connector then free the driver private
 584 * structure.
 585 */
 586static void intel_lvds_destroy(struct drm_connector *connector)
 587{
 588        struct intel_lvds_connector *lvds_connector =
 589                to_lvds_connector(connector);
 590
 591        if (lvds_connector->lid_notifier.notifier_call)
 592                acpi_lid_notifier_unregister(&lvds_connector->lid_notifier);
 593
 594        if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
 595                kfree(lvds_connector->base.edid);
 596
 597        intel_panel_fini(&lvds_connector->base.panel);
 598
 599        drm_connector_cleanup(connector);
 600        kfree(connector);
 601}
 602
 603static int intel_lvds_set_property(struct drm_connector *connector,
 604                                   struct drm_property *property,
 605                                   uint64_t value)
 606{
 607        struct intel_connector *intel_connector = to_intel_connector(connector);
 608        struct drm_device *dev = connector->dev;
 609
 610        if (property == dev->mode_config.scaling_mode_property) {
 611                struct drm_crtc *crtc;
 612
 613                if (value == DRM_MODE_SCALE_NONE) {
 614                        DRM_DEBUG_KMS("no scaling not supported\n");
 615                        return -EINVAL;
 616                }
 617
 618                if (intel_connector->panel.fitting_mode == value) {
 619                        /* the LVDS scaling property is not changed */
 620                        return 0;
 621                }
 622                intel_connector->panel.fitting_mode = value;
 623
 624                crtc = intel_attached_encoder(connector)->base.crtc;
 625                if (crtc && crtc->state->enable) {
 626                        /*
 627                         * If the CRTC is enabled, the display will be changed
 628                         * according to the new panel fitting mode.
 629                         */
 630                        intel_crtc_restore_mode(crtc);
 631                }
 632        }
 633
 634        return 0;
 635}
 636
 637static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
 638        .get_modes = intel_lvds_get_modes,
 639        .mode_valid = intel_lvds_mode_valid,
 640};
 641
 642static const struct drm_connector_funcs intel_lvds_connector_funcs = {
 643        .dpms = drm_atomic_helper_connector_dpms,
 644        .detect = intel_lvds_detect,
 645        .fill_modes = drm_helper_probe_single_connector_modes,
 646        .set_property = intel_lvds_set_property,
 647        .atomic_get_property = intel_connector_atomic_get_property,
 648        .late_register = intel_connector_register,
 649        .early_unregister = intel_connector_unregister,
 650        .destroy = intel_lvds_destroy,
 651        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 652        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 653};
 654
 655static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
 656        .destroy = intel_encoder_destroy,
 657};
 658
 659static int intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
 660{
 661        DRM_INFO("Skipping LVDS initialization for %s\n", id->ident);
 662        return 1;
 663}
 664
 665/* These systems claim to have LVDS, but really don't */
 666static const struct dmi_system_id intel_no_lvds[] = {
 667        {
 668                .callback = intel_no_lvds_dmi_callback,
 669                .ident = "Apple Mac Mini (Core series)",
 670                .matches = {
 671                        DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
 672                        DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
 673                },
 674        },
 675        {
 676                .callback = intel_no_lvds_dmi_callback,
 677                .ident = "Apple Mac Mini (Core 2 series)",
 678                .matches = {
 679                        DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
 680                        DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"),
 681                },
 682        },
 683        {
 684                .callback = intel_no_lvds_dmi_callback,
 685                .ident = "MSI IM-945GSE-A",
 686                .matches = {
 687                        DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
 688                        DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"),
 689                },
 690        },
 691        {
 692                .callback = intel_no_lvds_dmi_callback,
 693                .ident = "Dell Studio Hybrid",
 694                .matches = {
 695                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 696                        DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"),
 697                },
 698        },
 699        {
 700                .callback = intel_no_lvds_dmi_callback,
 701                .ident = "Dell OptiPlex FX170",
 702                .matches = {
 703                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 704                        DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex FX170"),
 705                },
 706        },
 707        {
 708                .callback = intel_no_lvds_dmi_callback,
 709                .ident = "AOpen Mini PC",
 710                .matches = {
 711                        DMI_MATCH(DMI_SYS_VENDOR, "AOpen"),
 712                        DMI_MATCH(DMI_PRODUCT_NAME, "i965GMx-IF"),
 713                },
 714        },
 715        {
 716                .callback = intel_no_lvds_dmi_callback,
 717                .ident = "AOpen Mini PC MP915",
 718                .matches = {
 719                        DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
 720                        DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"),
 721                },
 722        },
 723        {
 724                .callback = intel_no_lvds_dmi_callback,
 725                .ident = "AOpen i915GMm-HFS",
 726                .matches = {
 727                        DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
 728                        DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
 729                },
 730        },
 731        {
 732                .callback = intel_no_lvds_dmi_callback,
 733                .ident = "AOpen i45GMx-I",
 734                .matches = {
 735                        DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
 736                        DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"),
 737                },
 738        },
 739        {
 740                .callback = intel_no_lvds_dmi_callback,
 741                .ident = "Aopen i945GTt-VFA",
 742                .matches = {
 743                        DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
 744                },
 745        },
 746        {
 747                .callback = intel_no_lvds_dmi_callback,
 748                .ident = "Clientron U800",
 749                .matches = {
 750                        DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
 751                        DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
 752                },
 753        },
 754        {
 755                .callback = intel_no_lvds_dmi_callback,
 756                .ident = "Clientron E830",
 757                .matches = {
 758                        DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
 759                        DMI_MATCH(DMI_PRODUCT_NAME, "E830"),
 760                },
 761        },
 762        {
 763                .callback = intel_no_lvds_dmi_callback,
 764                .ident = "Asus EeeBox PC EB1007",
 765                .matches = {
 766                        DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
 767                        DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"),
 768                },
 769        },
 770        {
 771                .callback = intel_no_lvds_dmi_callback,
 772                .ident = "Asus AT5NM10T-I",
 773                .matches = {
 774                        DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
 775                        DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"),
 776                },
 777        },
 778        {
 779                .callback = intel_no_lvds_dmi_callback,
 780                .ident = "Hewlett-Packard HP t5740",
 781                .matches = {
 782                        DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
 783                        DMI_MATCH(DMI_PRODUCT_NAME, " t5740"),
 784                },
 785        },
 786        {
 787                .callback = intel_no_lvds_dmi_callback,
 788                .ident = "Hewlett-Packard t5745",
 789                .matches = {
 790                        DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
 791                        DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"),
 792                },
 793        },
 794        {
 795                .callback = intel_no_lvds_dmi_callback,
 796                .ident = "Hewlett-Packard st5747",
 797                .matches = {
 798                        DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
 799                        DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"),
 800                },
 801        },
 802        {
 803                .callback = intel_no_lvds_dmi_callback,
 804                .ident = "MSI Wind Box DC500",
 805                .matches = {
 806                        DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
 807                        DMI_MATCH(DMI_BOARD_NAME, "MS-7469"),
 808                },
 809        },
 810        {
 811                .callback = intel_no_lvds_dmi_callback,
 812                .ident = "Gigabyte GA-D525TUD",
 813                .matches = {
 814                        DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
 815                        DMI_MATCH(DMI_BOARD_NAME, "D525TUD"),
 816                },
 817        },
 818        {
 819                .callback = intel_no_lvds_dmi_callback,
 820                .ident = "Supermicro X7SPA-H",
 821                .matches = {
 822                        DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
 823                        DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"),
 824                },
 825        },
 826        {
 827                .callback = intel_no_lvds_dmi_callback,
 828                .ident = "Fujitsu Esprimo Q900",
 829                .matches = {
 830                        DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
 831                        DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Q900"),
 832                },
 833        },
 834        {
 835                .callback = intel_no_lvds_dmi_callback,
 836                .ident = "Intel D410PT",
 837                .matches = {
 838                        DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
 839                        DMI_MATCH(DMI_BOARD_NAME, "D410PT"),
 840                },
 841        },
 842        {
 843                .callback = intel_no_lvds_dmi_callback,
 844                .ident = "Intel D425KT",
 845                .matches = {
 846                        DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
 847                        DMI_EXACT_MATCH(DMI_BOARD_NAME, "D425KT"),
 848                },
 849        },
 850        {
 851                .callback = intel_no_lvds_dmi_callback,
 852                .ident = "Intel D510MO",
 853                .matches = {
 854                        DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
 855                        DMI_EXACT_MATCH(DMI_BOARD_NAME, "D510MO"),
 856                },
 857        },
 858        {
 859                .callback = intel_no_lvds_dmi_callback,
 860                .ident = "Intel D525MW",
 861                .matches = {
 862                        DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
 863                        DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
 864                },
 865        },
 866
 867        { }     /* terminating entry */
 868};
 869
 870static int intel_dual_link_lvds_callback(const struct dmi_system_id *id)
 871{
 872        DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident);
 873        return 1;
 874}
 875
 876static const struct dmi_system_id intel_dual_link_lvds[] = {
 877        {
 878                .callback = intel_dual_link_lvds_callback,
 879                .ident = "Apple MacBook Pro 15\" (2010)",
 880                .matches = {
 881                        DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
 882                        DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6,2"),
 883                },
 884        },
 885        {
 886                .callback = intel_dual_link_lvds_callback,
 887                .ident = "Apple MacBook Pro 15\" (2011)",
 888                .matches = {
 889                        DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
 890                        DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"),
 891                },
 892        },
 893        {
 894                .callback = intel_dual_link_lvds_callback,
 895                .ident = "Apple MacBook Pro 15\" (2012)",
 896                .matches = {
 897                        DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
 898                        DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro9,1"),
 899                },
 900        },
 901        { }     /* terminating entry */
 902};
 903
 904struct intel_encoder *intel_get_lvds_encoder(struct drm_device *dev)
 905{
 906        struct intel_encoder *intel_encoder;
 907
 908        for_each_intel_encoder(dev, intel_encoder)
 909                if (intel_encoder->type == INTEL_OUTPUT_LVDS)
 910                        return intel_encoder;
 911
 912        return NULL;
 913}
 914
 915bool intel_is_dual_link_lvds(struct drm_device *dev)
 916{
 917        struct intel_encoder *encoder = intel_get_lvds_encoder(dev);
 918
 919        return encoder && to_lvds_encoder(&encoder->base)->is_dual_link;
 920}
 921
 922static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
 923{
 924        struct drm_device *dev = lvds_encoder->base.base.dev;
 925        unsigned int val;
 926        struct drm_i915_private *dev_priv = to_i915(dev);
 927
 928        /* use the module option value if specified */
 929        if (i915.lvds_channel_mode > 0)
 930                return i915.lvds_channel_mode == 2;
 931
 932        /* single channel LVDS is limited to 112 MHz */
 933        if (lvds_encoder->attached_connector->base.panel.fixed_mode->clock
 934            > 112999)
 935                return true;
 936
 937        if (dmi_check_system(intel_dual_link_lvds))
 938                return true;
 939
 940        /* BIOS should set the proper LVDS register value at boot, but
 941         * in reality, it doesn't set the value when the lid is closed;
 942         * we need to check "the value to be set" in VBT when LVDS
 943         * register is uninitialized.
 944         */
 945        val = I915_READ(lvds_encoder->reg);
 946        if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED)))
 947                val = dev_priv->vbt.bios_lvds_val;
 948
 949        return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
 950}
 951
 952static bool intel_lvds_supported(struct drm_device *dev)
 953{
 954        /* With the introduction of the PCH we gained a dedicated
 955         * LVDS presence pin, use it. */
 956        if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
 957                return true;
 958
 959        /* Otherwise LVDS was only attached to mobile products,
 960         * except for the inglorious 830gm */
 961        if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev))
 962                return true;
 963
 964        return false;
 965}
 966
 967/**
 968 * intel_lvds_init - setup LVDS connectors on this device
 969 * @dev: drm device
 970 *
 971 * Create the connector, register the LVDS DDC bus, and try to figure out what
 972 * modes we can display on the LVDS panel (if present).
 973 */
 974void intel_lvds_init(struct drm_device *dev)
 975{
 976        struct drm_i915_private *dev_priv = to_i915(dev);
 977        struct intel_lvds_encoder *lvds_encoder;
 978        struct intel_encoder *intel_encoder;
 979        struct intel_lvds_connector *lvds_connector;
 980        struct intel_connector *intel_connector;
 981        struct drm_connector *connector;
 982        struct drm_encoder *encoder;
 983        struct drm_display_mode *scan; /* *modes, *bios_mode; */
 984        struct drm_display_mode *fixed_mode = NULL;
 985        struct drm_display_mode *downclock_mode = NULL;
 986        struct edid *edid;
 987        struct drm_crtc *crtc;
 988        i915_reg_t lvds_reg;
 989        u32 lvds;
 990        int pipe;
 991        u8 pin;
 992
 993        if (!intel_lvds_supported(dev))
 994                return;
 995
 996        /* Skip init on machines we know falsely report LVDS */
 997        if (dmi_check_system(intel_no_lvds))
 998                return;
 999
1000        if (HAS_PCH_SPLIT(dev))
1001                lvds_reg = PCH_LVDS;
1002        else
1003                lvds_reg = LVDS;
1004
1005        lvds = I915_READ(lvds_reg);
1006
1007        if (HAS_PCH_SPLIT(dev)) {
1008                if ((lvds & LVDS_DETECTED) == 0)
1009                        return;
1010                if (dev_priv->vbt.edp.support) {
1011                        DRM_DEBUG_KMS("disable LVDS for eDP support\n");
1012                        return;
1013                }
1014        }
1015
1016        pin = GMBUS_PIN_PANEL;
1017        if (!intel_bios_is_lvds_present(dev_priv, &pin)) {
1018                if ((lvds & LVDS_PORT_EN) == 0) {
1019                        DRM_DEBUG_KMS("LVDS is not present in VBT\n");
1020                        return;
1021                }
1022                DRM_DEBUG_KMS("LVDS is not present in VBT, but enabled anyway\n");
1023        }
1024
1025        lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL);
1026        if (!lvds_encoder)
1027                return;
1028
1029        lvds_connector = kzalloc(sizeof(*lvds_connector), GFP_KERNEL);
1030        if (!lvds_connector) {
1031                kfree(lvds_encoder);
1032                return;
1033        }
1034
1035        if (intel_connector_init(&lvds_connector->base) < 0) {
1036                kfree(lvds_connector);
1037                kfree(lvds_encoder);
1038                return;
1039        }
1040
1041        lvds_encoder->attached_connector = lvds_connector;
1042
1043        intel_encoder = &lvds_encoder->base;
1044        encoder = &intel_encoder->base;
1045        intel_connector = &lvds_connector->base;
1046        connector = &intel_connector->base;
1047        drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs,
1048                           DRM_MODE_CONNECTOR_LVDS);
1049
1050        drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs,
1051                         DRM_MODE_ENCODER_LVDS, "LVDS");
1052
1053        intel_encoder->enable = intel_enable_lvds;
1054        intel_encoder->pre_enable = intel_pre_enable_lvds;
1055        intel_encoder->compute_config = intel_lvds_compute_config;
1056        if (HAS_PCH_SPLIT(dev_priv)) {
1057                intel_encoder->disable = pch_disable_lvds;
1058                intel_encoder->post_disable = pch_post_disable_lvds;
1059        } else {
1060                intel_encoder->disable = gmch_disable_lvds;
1061        }
1062        intel_encoder->get_hw_state = intel_lvds_get_hw_state;
1063        intel_encoder->get_config = intel_lvds_get_config;
1064        intel_connector->get_hw_state = intel_connector_get_hw_state;
1065
1066        intel_connector_attach_encoder(intel_connector, intel_encoder);
1067        intel_encoder->type = INTEL_OUTPUT_LVDS;
1068
1069        intel_encoder->cloneable = 0;
1070        if (HAS_PCH_SPLIT(dev))
1071                intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
1072        else if (IS_GEN4(dev))
1073                intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
1074        else
1075                intel_encoder->crtc_mask = (1 << 1);
1076
1077        drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
1078        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1079        connector->interlace_allowed = false;
1080        connector->doublescan_allowed = false;
1081
1082        lvds_encoder->reg = lvds_reg;
1083
1084        /* create the scaling mode property */
1085        drm_mode_create_scaling_mode_property(dev);
1086        drm_object_attach_property(&connector->base,
1087                                      dev->mode_config.scaling_mode_property,
1088                                      DRM_MODE_SCALE_ASPECT);
1089        intel_connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT;
1090
1091        intel_lvds_pps_get_hw_state(dev_priv, &lvds_encoder->init_pps);
1092        lvds_encoder->init_lvds_val = lvds;
1093
1094        /*
1095         * LVDS discovery:
1096         * 1) check for EDID on DDC
1097         * 2) check for VBT data
1098         * 3) check to see if LVDS is already on
1099         *    if none of the above, no panel
1100         * 4) make sure lid is open
1101         *    if closed, act like it's not there for now
1102         */
1103
1104        /*
1105         * Attempt to get the fixed panel mode from DDC.  Assume that the
1106         * preferred mode is the right one.
1107         */
1108        mutex_lock(&dev->mode_config.mutex);
1109        if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC)
1110                edid = drm_get_edid_switcheroo(connector,
1111                                    intel_gmbus_get_adapter(dev_priv, pin));
1112        else
1113                edid = drm_get_edid(connector,
1114                                    intel_gmbus_get_adapter(dev_priv, pin));
1115        if (edid) {
1116                if (drm_add_edid_modes(connector, edid)) {
1117                        drm_mode_connector_update_edid_property(connector,
1118                                                                edid);
1119                } else {
1120                        kfree(edid);
1121                        edid = ERR_PTR(-EINVAL);
1122                }
1123        } else {
1124                edid = ERR_PTR(-ENOENT);
1125        }
1126        lvds_connector->base.edid = edid;
1127
1128        list_for_each_entry(scan, &connector->probed_modes, head) {
1129                if (scan->type & DRM_MODE_TYPE_PREFERRED) {
1130                        DRM_DEBUG_KMS("using preferred mode from EDID: ");
1131                        drm_mode_debug_printmodeline(scan);
1132
1133                        fixed_mode = drm_mode_duplicate(dev, scan);
1134                        if (fixed_mode)
1135                                goto out;
1136                }
1137        }
1138
1139        /* Failed to get EDID, what about VBT? */
1140        if (dev_priv->vbt.lfp_lvds_vbt_mode) {
1141                DRM_DEBUG_KMS("using mode from VBT: ");
1142                drm_mode_debug_printmodeline(dev_priv->vbt.lfp_lvds_vbt_mode);
1143
1144                fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode);
1145                if (fixed_mode) {
1146                        fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
1147                        connector->display_info.width_mm = fixed_mode->width_mm;
1148                        connector->display_info.height_mm = fixed_mode->height_mm;
1149                        goto out;
1150                }
1151        }
1152
1153        /*
1154         * If we didn't get EDID, try checking if the panel is already turned
1155         * on.  If so, assume that whatever is currently programmed is the
1156         * correct mode.
1157         */
1158
1159        /* Ironlake: FIXME if still fail, not try pipe mode now */
1160        if (HAS_PCH_SPLIT(dev))
1161                goto failed;
1162
1163        pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
1164        crtc = intel_get_crtc_for_pipe(dev, pipe);
1165
1166        if (crtc && (lvds & LVDS_PORT_EN)) {
1167                fixed_mode = intel_crtc_mode_get(dev, crtc);
1168                if (fixed_mode) {
1169                        DRM_DEBUG_KMS("using current (BIOS) mode: ");
1170                        drm_mode_debug_printmodeline(fixed_mode);
1171                        fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
1172                        goto out;
1173                }
1174        }
1175
1176        /* If we still don't have a mode after all that, give up. */
1177        if (!fixed_mode)
1178                goto failed;
1179
1180out:
1181        mutex_unlock(&dev->mode_config.mutex);
1182
1183        intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
1184        intel_panel_setup_backlight(connector, INVALID_PIPE);
1185
1186        lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder);
1187        DRM_DEBUG_KMS("detected %s-link lvds configuration\n",
1188                      lvds_encoder->is_dual_link ? "dual" : "single");
1189
1190        lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK;
1191
1192        lvds_connector->lid_notifier.notifier_call = intel_lid_notify;
1193        if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) {
1194                DRM_DEBUG_KMS("lid notifier registration failed\n");
1195                lvds_connector->lid_notifier.notifier_call = NULL;
1196        }
1197
1198        return;
1199
1200failed:
1201        mutex_unlock(&dev->mode_config.mutex);
1202
1203        DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
1204        drm_connector_cleanup(connector);
1205        drm_encoder_cleanup(encoder);
1206        kfree(lvds_encoder);
1207        kfree(lvds_connector);
1208        return;
1209}
1210