linux/drivers/gpu/drm/gma500/cdv_intel_lvds.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright © 2006-2011 Intel Corporation
   4 *
   5 * Authors:
   6 *      Eric Anholt <eric@anholt.net>
   7 *      Dave Airlie <airlied@linux.ie>
   8 *      Jesse Barnes <jesse.barnes@intel.com>
   9 */
  10
  11#include <linux/dmi.h>
  12#include <linux/i2c.h>
  13#include <linux/pm_runtime.h>
  14
  15#include <drm/drm_simple_kms_helper.h>
  16
  17#include "cdv_device.h"
  18#include "intel_bios.h"
  19#include "power.h"
  20#include "psb_drv.h"
  21#include "psb_intel_drv.h"
  22#include "psb_intel_reg.h"
  23
  24/*
  25 * LVDS I2C backlight control macros
  26 */
  27#define BRIGHTNESS_MAX_LEVEL 100
  28#define BRIGHTNESS_MASK 0xFF
  29#define BLC_I2C_TYPE    0x01
  30#define BLC_PWM_TYPT    0x02
  31
  32#define BLC_POLARITY_NORMAL 0
  33#define BLC_POLARITY_INVERSE 1
  34
  35#define PSB_BLC_MAX_PWM_REG_FREQ       (0xFFFE)
  36#define PSB_BLC_MIN_PWM_REG_FREQ        (0x2)
  37#define PSB_BLC_PWM_PRECISION_FACTOR    (10)
  38#define PSB_BACKLIGHT_PWM_CTL_SHIFT     (16)
  39#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
  40
  41struct cdv_intel_lvds_priv {
  42        /**
  43         * Saved LVDO output states
  44         */
  45        uint32_t savePP_ON;
  46        uint32_t savePP_OFF;
  47        uint32_t saveLVDS;
  48        uint32_t savePP_CONTROL;
  49        uint32_t savePP_CYCLE;
  50        uint32_t savePFIT_CONTROL;
  51        uint32_t savePFIT_PGM_RATIOS;
  52        uint32_t saveBLC_PWM_CTL;
  53};
  54
  55/*
  56 * Returns the maximum level of the backlight duty cycle field.
  57 */
  58static u32 cdv_intel_lvds_get_max_backlight(struct drm_device *dev)
  59{
  60        struct drm_psb_private *dev_priv = dev->dev_private;
  61        u32 retval;
  62
  63        if (gma_power_begin(dev, false)) {
  64                retval = ((REG_READ(BLC_PWM_CTL) &
  65                          BACKLIGHT_MODULATION_FREQ_MASK) >>
  66                          BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
  67
  68                gma_power_end(dev);
  69        } else
  70                retval = ((dev_priv->regs.saveBLC_PWM_CTL &
  71                          BACKLIGHT_MODULATION_FREQ_MASK) >>
  72                          BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
  73
  74        return retval;
  75}
  76
  77/*
  78 * Sets the backlight level.
  79 *
  80 * level backlight level, from 0 to cdv_intel_lvds_get_max_backlight().
  81 */
  82static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level)
  83{
  84        struct drm_psb_private *dev_priv = dev->dev_private;
  85        u32 blc_pwm_ctl;
  86
  87        if (gma_power_begin(dev, false)) {
  88                blc_pwm_ctl =
  89                        REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
  90                REG_WRITE(BLC_PWM_CTL,
  91                                (blc_pwm_ctl |
  92                                (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
  93                gma_power_end(dev);
  94        } else {
  95                blc_pwm_ctl = dev_priv->regs.saveBLC_PWM_CTL &
  96                                ~BACKLIGHT_DUTY_CYCLE_MASK;
  97                dev_priv->regs.saveBLC_PWM_CTL = (blc_pwm_ctl |
  98                                        (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
  99        }
 100}
 101
 102/*
 103 * Sets the power state for the panel.
 104 */
 105static void cdv_intel_lvds_set_power(struct drm_device *dev,
 106                                     struct drm_encoder *encoder, bool on)
 107{
 108        struct drm_psb_private *dev_priv = dev->dev_private;
 109        u32 pp_status;
 110
 111        if (!gma_power_begin(dev, true))
 112                return;
 113
 114        if (on) {
 115                REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
 116                          POWER_TARGET_ON);
 117                do {
 118                        pp_status = REG_READ(PP_STATUS);
 119                } while ((pp_status & PP_ON) == 0);
 120
 121                cdv_intel_lvds_set_backlight(dev,
 122                                dev_priv->mode_dev.backlight_duty_cycle);
 123        } else {
 124                cdv_intel_lvds_set_backlight(dev, 0);
 125
 126                REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
 127                          ~POWER_TARGET_ON);
 128                do {
 129                        pp_status = REG_READ(PP_STATUS);
 130                } while (pp_status & PP_ON);
 131        }
 132        gma_power_end(dev);
 133}
 134
 135static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
 136{
 137        struct drm_device *dev = encoder->dev;
 138        if (mode == DRM_MODE_DPMS_ON)
 139                cdv_intel_lvds_set_power(dev, encoder, true);
 140        else
 141                cdv_intel_lvds_set_power(dev, encoder, false);
 142        /* XXX: We never power down the LVDS pairs. */
 143}
 144
 145static void cdv_intel_lvds_save(struct drm_connector *connector)
 146{
 147}
 148
 149static void cdv_intel_lvds_restore(struct drm_connector *connector)
 150{
 151}
 152
 153static enum drm_mode_status cdv_intel_lvds_mode_valid(struct drm_connector *connector,
 154                              struct drm_display_mode *mode)
 155{
 156        struct drm_device *dev = connector->dev;
 157        struct drm_psb_private *dev_priv = dev->dev_private;
 158        struct drm_display_mode *fixed_mode =
 159                                        dev_priv->mode_dev.panel_fixed_mode;
 160
 161        /* just in case */
 162        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 163                return MODE_NO_DBLESCAN;
 164
 165        /* just in case */
 166        if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 167                return MODE_NO_INTERLACE;
 168
 169        if (fixed_mode) {
 170                if (mode->hdisplay > fixed_mode->hdisplay)
 171                        return MODE_PANEL;
 172                if (mode->vdisplay > fixed_mode->vdisplay)
 173                        return MODE_PANEL;
 174        }
 175        return MODE_OK;
 176}
 177
 178static bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder,
 179                                  const struct drm_display_mode *mode,
 180                                  struct drm_display_mode *adjusted_mode)
 181{
 182        struct drm_device *dev = encoder->dev;
 183        struct drm_psb_private *dev_priv = dev->dev_private;
 184        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
 185        struct drm_encoder *tmp_encoder;
 186        struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
 187
 188        /* Should never happen!! */
 189        list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
 190                            head) {
 191                if (tmp_encoder != encoder
 192                    && tmp_encoder->crtc == encoder->crtc) {
 193                        pr_err("Can't enable LVDS and another encoder on the same pipe\n");
 194                        return false;
 195                }
 196        }
 197
 198        /*
 199         * If we have timings from the BIOS for the panel, put them in
 200         * to the adjusted mode.  The CRTC will be set up for this mode,
 201         * with the panel scaling set up to source from the H/VDisplay
 202         * of the original mode.
 203         */
 204        if (panel_fixed_mode != NULL) {
 205                adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;
 206                adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;
 207                adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;
 208                adjusted_mode->htotal = panel_fixed_mode->htotal;
 209                adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;
 210                adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;
 211                adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;
 212                adjusted_mode->vtotal = panel_fixed_mode->vtotal;
 213                adjusted_mode->clock = panel_fixed_mode->clock;
 214                drm_mode_set_crtcinfo(adjusted_mode,
 215                                      CRTC_INTERLACE_HALVE_V);
 216        }
 217
 218        /*
 219         * XXX: It would be nice to support lower refresh rates on the
 220         * panels to reduce power consumption, and perhaps match the
 221         * user's requested refresh rate.
 222         */
 223
 224        return true;
 225}
 226
 227static void cdv_intel_lvds_prepare(struct drm_encoder *encoder)
 228{
 229        struct drm_device *dev = encoder->dev;
 230        struct drm_psb_private *dev_priv = dev->dev_private;
 231        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
 232
 233        if (!gma_power_begin(dev, true))
 234                return;
 235
 236        mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
 237        mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
 238                                          BACKLIGHT_DUTY_CYCLE_MASK);
 239
 240        cdv_intel_lvds_set_power(dev, encoder, false);
 241
 242        gma_power_end(dev);
 243}
 244
 245static void cdv_intel_lvds_commit(struct drm_encoder *encoder)
 246{
 247        struct drm_device *dev = encoder->dev;
 248        struct drm_psb_private *dev_priv = dev->dev_private;
 249        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
 250
 251        if (mode_dev->backlight_duty_cycle == 0)
 252                mode_dev->backlight_duty_cycle =
 253                    cdv_intel_lvds_get_max_backlight(dev);
 254
 255        cdv_intel_lvds_set_power(dev, encoder, true);
 256}
 257
 258static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
 259                                struct drm_display_mode *mode,
 260                                struct drm_display_mode *adjusted_mode)
 261{
 262        struct drm_device *dev = encoder->dev;
 263        struct drm_psb_private *dev_priv = dev->dev_private;
 264        struct gma_crtc *gma_crtc = to_gma_crtc(encoder->crtc);
 265        u32 pfit_control;
 266
 267        /*
 268         * The LVDS pin pair will already have been turned on in the
 269         * cdv_intel_crtc_mode_set since it has a large impact on the DPLL
 270         * settings.
 271         */
 272
 273        /*
 274         * Enable automatic panel scaling so that non-native modes fill the
 275         * screen.  Should be enabled before the pipe is enabled, according to
 276         * register description and PRM.
 277         */
 278        if (mode->hdisplay != adjusted_mode->hdisplay ||
 279            mode->vdisplay != adjusted_mode->vdisplay)
 280                pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
 281                                HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
 282                                HORIZ_INTERP_BILINEAR);
 283        else
 284                pfit_control = 0;
 285
 286        pfit_control |= gma_crtc->pipe << PFIT_PIPE_SHIFT;
 287
 288        if (dev_priv->lvds_dither)
 289                pfit_control |= PANEL_8TO6_DITHER_ENABLE;
 290
 291        REG_WRITE(PFIT_CONTROL, pfit_control);
 292}
 293
 294/*
 295 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
 296 */
 297static int cdv_intel_lvds_get_modes(struct drm_connector *connector)
 298{
 299        struct drm_device *dev = connector->dev;
 300        struct drm_psb_private *dev_priv = dev->dev_private;
 301        struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
 302        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
 303        int ret;
 304
 305        ret = psb_intel_ddc_get_modes(connector, &gma_encoder->i2c_bus->adapter);
 306
 307        if (ret)
 308                return ret;
 309
 310        if (mode_dev->panel_fixed_mode != NULL) {
 311                struct drm_display_mode *mode =
 312                    drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
 313                drm_mode_probed_add(connector, mode);
 314                return 1;
 315        }
 316
 317        return 0;
 318}
 319
 320/**
 321 * cdv_intel_lvds_destroy - unregister and free LVDS structures
 322 * @connector: connector to free
 323 *
 324 * Unregister the DDC bus for this connector then free the driver private
 325 * structure.
 326 */
 327static void cdv_intel_lvds_destroy(struct drm_connector *connector)
 328{
 329        struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
 330
 331        psb_intel_i2c_destroy(gma_encoder->i2c_bus);
 332        drm_connector_unregister(connector);
 333        drm_connector_cleanup(connector);
 334        kfree(connector);
 335}
 336
 337static int cdv_intel_lvds_set_property(struct drm_connector *connector,
 338                                       struct drm_property *property,
 339                                       uint64_t value)
 340{
 341        struct drm_encoder *encoder = connector->encoder;
 342
 343        if (!strcmp(property->name, "scaling mode") && encoder) {
 344                struct gma_crtc *crtc = to_gma_crtc(encoder->crtc);
 345                uint64_t curValue;
 346
 347                if (!crtc)
 348                        return -1;
 349
 350                switch (value) {
 351                case DRM_MODE_SCALE_FULLSCREEN:
 352                        break;
 353                case DRM_MODE_SCALE_NO_SCALE:
 354                        break;
 355                case DRM_MODE_SCALE_ASPECT:
 356                        break;
 357                default:
 358                        return -1;
 359                }
 360
 361                if (drm_object_property_get_value(&connector->base,
 362                                                     property,
 363                                                     &curValue))
 364                        return -1;
 365
 366                if (curValue == value)
 367                        return 0;
 368
 369                if (drm_object_property_set_value(&connector->base,
 370                                                        property,
 371                                                        value))
 372                        return -1;
 373
 374                if (crtc->saved_mode.hdisplay != 0 &&
 375                    crtc->saved_mode.vdisplay != 0) {
 376                        if (!drm_crtc_helper_set_mode(encoder->crtc,
 377                                                      &crtc->saved_mode,
 378                                                      encoder->crtc->x,
 379                                                      encoder->crtc->y,
 380                                                      encoder->crtc->primary->fb))
 381                                return -1;
 382                }
 383        } else if (!strcmp(property->name, "backlight") && encoder) {
 384                if (drm_object_property_set_value(&connector->base,
 385                                                        property,
 386                                                        value))
 387                        return -1;
 388                else
 389                        gma_backlight_set(encoder->dev, value);
 390        } else if (!strcmp(property->name, "DPMS") && encoder) {
 391                const struct drm_encoder_helper_funcs *helpers =
 392                                        encoder->helper_private;
 393                helpers->dpms(encoder, value);
 394        }
 395        return 0;
 396}
 397
 398static const struct drm_encoder_helper_funcs
 399                                        cdv_intel_lvds_helper_funcs = {
 400        .dpms = cdv_intel_lvds_encoder_dpms,
 401        .mode_fixup = cdv_intel_lvds_mode_fixup,
 402        .prepare = cdv_intel_lvds_prepare,
 403        .mode_set = cdv_intel_lvds_mode_set,
 404        .commit = cdv_intel_lvds_commit,
 405};
 406
 407static const struct drm_connector_helper_funcs
 408                                cdv_intel_lvds_connector_helper_funcs = {
 409        .get_modes = cdv_intel_lvds_get_modes,
 410        .mode_valid = cdv_intel_lvds_mode_valid,
 411        .best_encoder = gma_best_encoder,
 412};
 413
 414static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = {
 415        .dpms = drm_helper_connector_dpms,
 416        .fill_modes = drm_helper_probe_single_connector_modes,
 417        .set_property = cdv_intel_lvds_set_property,
 418        .destroy = cdv_intel_lvds_destroy,
 419};
 420
 421/*
 422 * Enumerate the child dev array parsed from VBT to check whether
 423 * the LVDS is present.
 424 * If it is present, return 1.
 425 * If it is not present, return false.
 426 * If no child dev is parsed from VBT, it assumes that the LVDS is present.
 427 */
 428static bool lvds_is_present_in_vbt(struct drm_device *dev,
 429                                   u8 *i2c_pin)
 430{
 431        struct drm_psb_private *dev_priv = dev->dev_private;
 432        int i;
 433
 434        if (!dev_priv->child_dev_num)
 435                return true;
 436
 437        for (i = 0; i < dev_priv->child_dev_num; i++) {
 438                struct child_device_config *child = dev_priv->child_dev + i;
 439
 440                /* If the device type is not LFP, continue.
 441                 * We have to check both the new identifiers as well as the
 442                 * old for compatibility with some BIOSes.
 443                 */
 444                if (child->device_type != DEVICE_TYPE_INT_LFP &&
 445                    child->device_type != DEVICE_TYPE_LFP)
 446                        continue;
 447
 448                if (child->i2c_pin)
 449                    *i2c_pin = child->i2c_pin;
 450
 451                /* However, we cannot trust the BIOS writers to populate
 452                 * the VBT correctly.  Since LVDS requires additional
 453                 * information from AIM blocks, a non-zero addin offset is
 454                 * a good indicator that the LVDS is actually present.
 455                 */
 456                if (child->addin_offset)
 457                        return true;
 458
 459                /* But even then some BIOS writers perform some black magic
 460                 * and instantiate the device without reference to any
 461                 * additional data.  Trust that if the VBT was written into
 462                 * the OpRegion then they have validated the LVDS's existence.
 463                 */
 464                if (dev_priv->opregion.vbt)
 465                        return true;
 466        }
 467
 468        return false;
 469}
 470
 471/**
 472 * cdv_intel_lvds_init - setup LVDS connectors on this device
 473 * @dev: drm device
 474 * @mode_dev: PSB mode device
 475 *
 476 * Create the connector, register the LVDS DDC bus, and try to figure out what
 477 * modes we can display on the LVDS panel (if present).
 478 */
 479void cdv_intel_lvds_init(struct drm_device *dev,
 480                     struct psb_intel_mode_device *mode_dev)
 481{
 482        struct gma_encoder *gma_encoder;
 483        struct gma_connector *gma_connector;
 484        struct cdv_intel_lvds_priv *lvds_priv;
 485        struct drm_connector *connector;
 486        struct drm_encoder *encoder;
 487        struct drm_display_mode *scan;
 488        struct drm_crtc *crtc;
 489        struct drm_psb_private *dev_priv = dev->dev_private;
 490        u32 lvds;
 491        int pipe;
 492        u8 pin;
 493
 494        if (!dev_priv->lvds_enabled_in_vbt)
 495                return;
 496
 497        pin = GMBUS_PORT_PANEL;
 498        if (!lvds_is_present_in_vbt(dev, &pin)) {
 499                DRM_DEBUG_KMS("LVDS is not present in VBT\n");
 500                return;
 501        }
 502
 503        gma_encoder = kzalloc(sizeof(struct gma_encoder),
 504                                    GFP_KERNEL);
 505        if (!gma_encoder)
 506                return;
 507
 508        gma_connector = kzalloc(sizeof(struct gma_connector),
 509                                      GFP_KERNEL);
 510        if (!gma_connector)
 511                goto failed_connector;
 512
 513        lvds_priv = kzalloc(sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL);
 514        if (!lvds_priv)
 515                goto failed_lvds_priv;
 516
 517        gma_encoder->dev_priv = lvds_priv;
 518
 519        connector = &gma_connector->base;
 520        gma_connector->save = cdv_intel_lvds_save;
 521        gma_connector->restore = cdv_intel_lvds_restore;
 522        encoder = &gma_encoder->base;
 523
 524
 525        drm_connector_init(dev, connector,
 526                           &cdv_intel_lvds_connector_funcs,
 527                           DRM_MODE_CONNECTOR_LVDS);
 528
 529        drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS);
 530
 531        gma_connector_attach_encoder(gma_connector, gma_encoder);
 532        gma_encoder->type = INTEL_OUTPUT_LVDS;
 533
 534        drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs);
 535        drm_connector_helper_add(connector,
 536                                 &cdv_intel_lvds_connector_helper_funcs);
 537        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 538        connector->interlace_allowed = false;
 539        connector->doublescan_allowed = false;
 540
 541        /*Attach connector properties*/
 542        drm_object_attach_property(&connector->base,
 543                                      dev->mode_config.scaling_mode_property,
 544                                      DRM_MODE_SCALE_FULLSCREEN);
 545        drm_object_attach_property(&connector->base,
 546                                      dev_priv->backlight_property,
 547                                      BRIGHTNESS_MAX_LEVEL);
 548
 549        /**
 550         * Set up I2C bus
 551         * FIXME: distroy i2c_bus when exit
 552         */
 553        gma_encoder->i2c_bus = psb_intel_i2c_create(dev,
 554                                                         GPIOB,
 555                                                         "LVDSBLC_B");
 556        if (!gma_encoder->i2c_bus) {
 557                dev_printk(KERN_ERR,
 558                        dev->dev, "I2C bus registration failed.\n");
 559                goto failed_blc_i2c;
 560        }
 561        gma_encoder->i2c_bus->slave_addr = 0x2C;
 562        dev_priv->lvds_i2c_bus = gma_encoder->i2c_bus;
 563
 564        /*
 565         * LVDS discovery:
 566         * 1) check for EDID on DDC
 567         * 2) check for VBT data
 568         * 3) check to see if LVDS is already on
 569         *    if none of the above, no panel
 570         * 4) make sure lid is open
 571         *    if closed, act like it's not there for now
 572         */
 573
 574        /* Set up the DDC bus. */
 575        gma_encoder->ddc_bus = psb_intel_i2c_create(dev,
 576                                                         GPIOC,
 577                                                         "LVDSDDC_C");
 578        if (!gma_encoder->ddc_bus) {
 579                dev_printk(KERN_ERR, dev->dev,
 580                           "DDC bus registration " "failed.\n");
 581                goto failed_ddc;
 582        }
 583
 584        /*
 585         * Attempt to get the fixed panel mode from DDC.  Assume that the
 586         * preferred mode is the right one.
 587         */
 588        mutex_lock(&dev->mode_config.mutex);
 589        psb_intel_ddc_get_modes(connector,
 590                                &gma_encoder->ddc_bus->adapter);
 591        list_for_each_entry(scan, &connector->probed_modes, head) {
 592                if (scan->type & DRM_MODE_TYPE_PREFERRED) {
 593                        mode_dev->panel_fixed_mode =
 594                            drm_mode_duplicate(dev, scan);
 595                        goto out;       /* FIXME: check for quirks */
 596                }
 597        }
 598
 599        /* Failed to get EDID, what about VBT? do we need this?*/
 600        if (dev_priv->lfp_lvds_vbt_mode) {
 601                mode_dev->panel_fixed_mode =
 602                        drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
 603                if (mode_dev->panel_fixed_mode) {
 604                        mode_dev->panel_fixed_mode->type |=
 605                                DRM_MODE_TYPE_PREFERRED;
 606                        goto out;       /* FIXME: check for quirks */
 607                }
 608        }
 609        /*
 610         * If we didn't get EDID, try checking if the panel is already turned
 611         * on.  If so, assume that whatever is currently programmed is the
 612         * correct mode.
 613         */
 614        lvds = REG_READ(LVDS);
 615        pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
 616        crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
 617
 618        if (crtc && (lvds & LVDS_PORT_EN)) {
 619                mode_dev->panel_fixed_mode =
 620                    cdv_intel_crtc_mode_get(dev, crtc);
 621                if (mode_dev->panel_fixed_mode) {
 622                        mode_dev->panel_fixed_mode->type |=
 623                            DRM_MODE_TYPE_PREFERRED;
 624                        goto out;       /* FIXME: check for quirks */
 625                }
 626        }
 627
 628        /* If we still don't have a mode after all that, give up. */
 629        if (!mode_dev->panel_fixed_mode) {
 630                DRM_DEBUG
 631                        ("Found no modes on the lvds, ignoring the LVDS\n");
 632                goto failed_find;
 633        }
 634
 635        /* setup PWM */
 636        {
 637                u32 pwm;
 638
 639                pwm = REG_READ(BLC_PWM_CTL2);
 640                if (pipe == 1)
 641                        pwm |= PWM_PIPE_B;
 642                else
 643                        pwm &= ~PWM_PIPE_B;
 644                pwm |= PWM_ENABLE;
 645                REG_WRITE(BLC_PWM_CTL2, pwm);
 646        }
 647
 648out:
 649        mutex_unlock(&dev->mode_config.mutex);
 650        drm_connector_register(connector);
 651        return;
 652
 653failed_find:
 654        mutex_unlock(&dev->mode_config.mutex);
 655        pr_err("Failed find\n");
 656        psb_intel_i2c_destroy(gma_encoder->ddc_bus);
 657failed_ddc:
 658        pr_err("Failed DDC\n");
 659        psb_intel_i2c_destroy(gma_encoder->i2c_bus);
 660failed_blc_i2c:
 661        pr_err("Failed BLC\n");
 662        drm_encoder_cleanup(encoder);
 663        drm_connector_cleanup(connector);
 664        kfree(lvds_priv);
 665failed_lvds_priv:
 666        kfree(gma_connector);
 667failed_connector:
 668        kfree(gma_encoder);
 669}
 670