linux/drivers/gpu/drm/gma500/psb_intel_lvds.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright © 2006-2007 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/i2c.h>
  12#include <linux/pm_runtime.h>
  13
  14#include <drm/drm_simple_kms_helper.h>
  15
  16#include "intel_bios.h"
  17#include "power.h"
  18#include "psb_drv.h"
  19#include "psb_intel_drv.h"
  20#include "psb_intel_reg.h"
  21
  22/*
  23 * LVDS I2C backlight control macros
  24 */
  25#define BRIGHTNESS_MAX_LEVEL 100
  26#define BRIGHTNESS_MASK 0xFF
  27#define BLC_I2C_TYPE    0x01
  28#define BLC_PWM_TYPT    0x02
  29
  30#define BLC_POLARITY_NORMAL 0
  31#define BLC_POLARITY_INVERSE 1
  32
  33#define PSB_BLC_MAX_PWM_REG_FREQ       (0xFFFE)
  34#define PSB_BLC_MIN_PWM_REG_FREQ        (0x2)
  35#define PSB_BLC_PWM_PRECISION_FACTOR    (10)
  36#define PSB_BACKLIGHT_PWM_CTL_SHIFT     (16)
  37#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
  38
  39struct psb_intel_lvds_priv {
  40        /*
  41         * Saved LVDO output states
  42         */
  43        uint32_t savePP_ON;
  44        uint32_t savePP_OFF;
  45        uint32_t saveLVDS;
  46        uint32_t savePP_CONTROL;
  47        uint32_t savePP_CYCLE;
  48        uint32_t savePFIT_CONTROL;
  49        uint32_t savePFIT_PGM_RATIOS;
  50        uint32_t saveBLC_PWM_CTL;
  51
  52        struct psb_intel_i2c_chan *i2c_bus;
  53        struct psb_intel_i2c_chan *ddc_bus;
  54};
  55
  56
  57/*
  58 * Returns the maximum level of the backlight duty cycle field.
  59 */
  60static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev)
  61{
  62        struct drm_psb_private *dev_priv = dev->dev_private;
  63        u32 ret;
  64
  65        if (gma_power_begin(dev, false)) {
  66                ret = REG_READ(BLC_PWM_CTL);
  67                gma_power_end(dev);
  68        } else /* Powered off, use the saved value */
  69                ret = dev_priv->regs.saveBLC_PWM_CTL;
  70
  71        /* Top 15bits hold the frequency mask */
  72        ret = (ret &  BACKLIGHT_MODULATION_FREQ_MASK) >>
  73                                        BACKLIGHT_MODULATION_FREQ_SHIFT;
  74
  75        ret *= 2;       /* Return a 16bit range as needed for setting */
  76        if (ret == 0)
  77                dev_err(dev->dev, "BL bug: Reg %08x save %08X\n",
  78                        REG_READ(BLC_PWM_CTL), dev_priv->regs.saveBLC_PWM_CTL);
  79        return ret;
  80}
  81
  82/*
  83 * Set LVDS backlight level by I2C command
  84 *
  85 * FIXME: at some point we need to both track this for PM and also
  86 * disable runtime pm on MRST if the brightness is nil (ie blanked)
  87 */
  88static int psb_lvds_i2c_set_brightness(struct drm_device *dev,
  89                                        unsigned int level)
  90{
  91        struct drm_psb_private *dev_priv =
  92                (struct drm_psb_private *)dev->dev_private;
  93
  94        struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus;
  95        u8 out_buf[2];
  96        unsigned int blc_i2c_brightness;
  97
  98        struct i2c_msg msgs[] = {
  99                {
 100                        .addr = lvds_i2c_bus->slave_addr,
 101                        .flags = 0,
 102                        .len = 2,
 103                        .buf = out_buf,
 104                }
 105        };
 106
 107        blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level *
 108                             BRIGHTNESS_MASK /
 109                             BRIGHTNESS_MAX_LEVEL);
 110
 111        if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
 112                blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness;
 113
 114        out_buf[0] = dev_priv->lvds_bl->brightnesscmd;
 115        out_buf[1] = (u8)blc_i2c_brightness;
 116
 117        if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) {
 118                dev_dbg(dev->dev, "I2C set brightness.(command, value) (%d, %d)\n",
 119                        dev_priv->lvds_bl->brightnesscmd,
 120                        blc_i2c_brightness);
 121                return 0;
 122        }
 123
 124        dev_err(dev->dev, "I2C transfer error\n");
 125        return -1;
 126}
 127
 128
 129static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level)
 130{
 131        struct drm_psb_private *dev_priv =
 132                        (struct drm_psb_private *)dev->dev_private;
 133
 134        u32 max_pwm_blc;
 135        u32 blc_pwm_duty_cycle;
 136
 137        max_pwm_blc = psb_intel_lvds_get_max_backlight(dev);
 138
 139        /*BLC_PWM_CTL Should be initiated while backlight device init*/
 140        BUG_ON(max_pwm_blc == 0);
 141
 142        blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
 143
 144        if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
 145                blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle;
 146
 147        blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
 148        REG_WRITE(BLC_PWM_CTL,
 149                  (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
 150                  (blc_pwm_duty_cycle));
 151
 152        dev_info(dev->dev, "Backlight lvds set brightness %08x\n",
 153                  (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
 154                  (blc_pwm_duty_cycle));
 155
 156        return 0;
 157}
 158
 159/*
 160 * Set LVDS backlight level either by I2C or PWM
 161 */
 162void psb_intel_lvds_set_brightness(struct drm_device *dev, int level)
 163{
 164        struct drm_psb_private *dev_priv = dev->dev_private;
 165
 166        dev_dbg(dev->dev, "backlight level is %d\n", level);
 167
 168        if (!dev_priv->lvds_bl) {
 169                dev_err(dev->dev, "NO LVDS backlight info\n");
 170                return;
 171        }
 172
 173        if (dev_priv->lvds_bl->type == BLC_I2C_TYPE)
 174                psb_lvds_i2c_set_brightness(dev, level);
 175        else
 176                psb_lvds_pwm_set_brightness(dev, level);
 177}
 178
 179/*
 180 * Sets the backlight level.
 181 *
 182 * level: backlight level, from 0 to psb_intel_lvds_get_max_backlight().
 183 */
 184static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level)
 185{
 186        struct drm_psb_private *dev_priv = dev->dev_private;
 187        u32 blc_pwm_ctl;
 188
 189        if (gma_power_begin(dev, false)) {
 190                blc_pwm_ctl = REG_READ(BLC_PWM_CTL);
 191                blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
 192                REG_WRITE(BLC_PWM_CTL,
 193                                (blc_pwm_ctl |
 194                                (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
 195                dev_priv->regs.saveBLC_PWM_CTL = (blc_pwm_ctl |
 196                                        (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
 197                gma_power_end(dev);
 198        } else {
 199                blc_pwm_ctl = dev_priv->regs.saveBLC_PWM_CTL &
 200                                ~BACKLIGHT_DUTY_CYCLE_MASK;
 201                dev_priv->regs.saveBLC_PWM_CTL = (blc_pwm_ctl |
 202                                        (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
 203        }
 204}
 205
 206/*
 207 * Sets the power state for the panel.
 208 */
 209static void psb_intel_lvds_set_power(struct drm_device *dev, bool on)
 210{
 211        struct drm_psb_private *dev_priv = dev->dev_private;
 212        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
 213        u32 pp_status;
 214
 215        if (!gma_power_begin(dev, true)) {
 216                dev_err(dev->dev, "set power, chip off!\n");
 217                return;
 218        }
 219
 220        if (on) {
 221                REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
 222                          POWER_TARGET_ON);
 223                do {
 224                        pp_status = REG_READ(PP_STATUS);
 225                } while ((pp_status & PP_ON) == 0);
 226
 227                psb_intel_lvds_set_backlight(dev,
 228                                             mode_dev->backlight_duty_cycle);
 229        } else {
 230                psb_intel_lvds_set_backlight(dev, 0);
 231
 232                REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
 233                          ~POWER_TARGET_ON);
 234                do {
 235                        pp_status = REG_READ(PP_STATUS);
 236                } while (pp_status & PP_ON);
 237        }
 238
 239        gma_power_end(dev);
 240}
 241
 242static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
 243{
 244        struct drm_device *dev = encoder->dev;
 245
 246        if (mode == DRM_MODE_DPMS_ON)
 247                psb_intel_lvds_set_power(dev, true);
 248        else
 249                psb_intel_lvds_set_power(dev, false);
 250
 251        /* XXX: We never power down the LVDS pairs. */
 252}
 253
 254static void psb_intel_lvds_save(struct drm_connector *connector)
 255{
 256        struct drm_device *dev = connector->dev;
 257        struct drm_psb_private *dev_priv =
 258                (struct drm_psb_private *)dev->dev_private;
 259        struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
 260        struct psb_intel_lvds_priv *lvds_priv =
 261                (struct psb_intel_lvds_priv *)gma_encoder->dev_priv;
 262
 263        lvds_priv->savePP_ON = REG_READ(LVDSPP_ON);
 264        lvds_priv->savePP_OFF = REG_READ(LVDSPP_OFF);
 265        lvds_priv->saveLVDS = REG_READ(LVDS);
 266        lvds_priv->savePP_CONTROL = REG_READ(PP_CONTROL);
 267        lvds_priv->savePP_CYCLE = REG_READ(PP_CYCLE);
 268        /*lvds_priv->savePP_DIVISOR = REG_READ(PP_DIVISOR);*/
 269        lvds_priv->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
 270        lvds_priv->savePFIT_CONTROL = REG_READ(PFIT_CONTROL);
 271        lvds_priv->savePFIT_PGM_RATIOS = REG_READ(PFIT_PGM_RATIOS);
 272
 273        /*TODO: move backlight_duty_cycle to psb_intel_lvds_priv*/
 274        dev_priv->backlight_duty_cycle = (dev_priv->regs.saveBLC_PWM_CTL &
 275                                                BACKLIGHT_DUTY_CYCLE_MASK);
 276
 277        /*
 278         * If the light is off at server startup,
 279         * just make it full brightness
 280         */
 281        if (dev_priv->backlight_duty_cycle == 0)
 282                dev_priv->backlight_duty_cycle =
 283                psb_intel_lvds_get_max_backlight(dev);
 284
 285        dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
 286                        lvds_priv->savePP_ON,
 287                        lvds_priv->savePP_OFF,
 288                        lvds_priv->saveLVDS,
 289                        lvds_priv->savePP_CONTROL,
 290                        lvds_priv->savePP_CYCLE,
 291                        lvds_priv->saveBLC_PWM_CTL);
 292}
 293
 294static void psb_intel_lvds_restore(struct drm_connector *connector)
 295{
 296        struct drm_device *dev = connector->dev;
 297        u32 pp_status;
 298        struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
 299        struct psb_intel_lvds_priv *lvds_priv =
 300                (struct psb_intel_lvds_priv *)gma_encoder->dev_priv;
 301
 302        dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
 303                        lvds_priv->savePP_ON,
 304                        lvds_priv->savePP_OFF,
 305                        lvds_priv->saveLVDS,
 306                        lvds_priv->savePP_CONTROL,
 307                        lvds_priv->savePP_CYCLE,
 308                        lvds_priv->saveBLC_PWM_CTL);
 309
 310        REG_WRITE(BLC_PWM_CTL, lvds_priv->saveBLC_PWM_CTL);
 311        REG_WRITE(PFIT_CONTROL, lvds_priv->savePFIT_CONTROL);
 312        REG_WRITE(PFIT_PGM_RATIOS, lvds_priv->savePFIT_PGM_RATIOS);
 313        REG_WRITE(LVDSPP_ON, lvds_priv->savePP_ON);
 314        REG_WRITE(LVDSPP_OFF, lvds_priv->savePP_OFF);
 315        /*REG_WRITE(PP_DIVISOR, lvds_priv->savePP_DIVISOR);*/
 316        REG_WRITE(PP_CYCLE, lvds_priv->savePP_CYCLE);
 317        REG_WRITE(PP_CONTROL, lvds_priv->savePP_CONTROL);
 318        REG_WRITE(LVDS, lvds_priv->saveLVDS);
 319
 320        if (lvds_priv->savePP_CONTROL & POWER_TARGET_ON) {
 321                REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
 322                        POWER_TARGET_ON);
 323                do {
 324                        pp_status = REG_READ(PP_STATUS);
 325                } while ((pp_status & PP_ON) == 0);
 326        } else {
 327                REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
 328                        ~POWER_TARGET_ON);
 329                do {
 330                        pp_status = REG_READ(PP_STATUS);
 331                } while (pp_status & PP_ON);
 332        }
 333}
 334
 335enum drm_mode_status psb_intel_lvds_mode_valid(struct drm_connector *connector,
 336                                 struct drm_display_mode *mode)
 337{
 338        struct drm_psb_private *dev_priv = connector->dev->dev_private;
 339        struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
 340        struct drm_display_mode *fixed_mode =
 341                                        dev_priv->mode_dev.panel_fixed_mode;
 342
 343        if (gma_encoder->type == INTEL_OUTPUT_MIPI2)
 344                fixed_mode = dev_priv->mode_dev.panel_fixed_mode2;
 345
 346        /* just in case */
 347        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 348                return MODE_NO_DBLESCAN;
 349
 350        /* just in case */
 351        if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 352                return MODE_NO_INTERLACE;
 353
 354        if (fixed_mode) {
 355                if (mode->hdisplay > fixed_mode->hdisplay)
 356                        return MODE_PANEL;
 357                if (mode->vdisplay > fixed_mode->vdisplay)
 358                        return MODE_PANEL;
 359        }
 360        return MODE_OK;
 361}
 362
 363bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
 364                                  const struct drm_display_mode *mode,
 365                                  struct drm_display_mode *adjusted_mode)
 366{
 367        struct drm_device *dev = encoder->dev;
 368        struct drm_psb_private *dev_priv = dev->dev_private;
 369        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
 370        struct gma_crtc *gma_crtc = to_gma_crtc(encoder->crtc);
 371        struct drm_encoder *tmp_encoder;
 372        struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
 373        struct gma_encoder *gma_encoder = to_gma_encoder(encoder);
 374
 375        if (gma_encoder->type == INTEL_OUTPUT_MIPI2)
 376                panel_fixed_mode = mode_dev->panel_fixed_mode2;
 377
 378        /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */
 379        if (!IS_MRST(dev) && gma_crtc->pipe == 0) {
 380                pr_err("Can't support LVDS on pipe A\n");
 381                return false;
 382        }
 383        if (IS_MRST(dev) && gma_crtc->pipe != 0) {
 384                pr_err("Must use PIPE A\n");
 385                return false;
 386        }
 387        /* Should never happen!! */
 388        list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
 389                            head) {
 390                if (tmp_encoder != encoder
 391                    && tmp_encoder->crtc == encoder->crtc) {
 392                        pr_err("Can't enable LVDS and another encoder on the same pipe\n");
 393                        return false;
 394                }
 395        }
 396
 397        /*
 398         * If we have timings from the BIOS for the panel, put them in
 399         * to the adjusted mode.  The CRTC will be set up for this mode,
 400         * with the panel scaling set up to source from the H/VDisplay
 401         * of the original mode.
 402         */
 403        if (panel_fixed_mode != NULL) {
 404                adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;
 405                adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;
 406                adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;
 407                adjusted_mode->htotal = panel_fixed_mode->htotal;
 408                adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;
 409                adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;
 410                adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;
 411                adjusted_mode->vtotal = panel_fixed_mode->vtotal;
 412                adjusted_mode->clock = panel_fixed_mode->clock;
 413                drm_mode_set_crtcinfo(adjusted_mode,
 414                                      CRTC_INTERLACE_HALVE_V);
 415        }
 416
 417        /*
 418         * XXX: It would be nice to support lower refresh rates on the
 419         * panels to reduce power consumption, and perhaps match the
 420         * user's requested refresh rate.
 421         */
 422
 423        return true;
 424}
 425
 426static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
 427{
 428        struct drm_device *dev = encoder->dev;
 429        struct drm_psb_private *dev_priv = dev->dev_private;
 430        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
 431
 432        if (!gma_power_begin(dev, true))
 433                return;
 434
 435        mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
 436        mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
 437                                          BACKLIGHT_DUTY_CYCLE_MASK);
 438
 439        psb_intel_lvds_set_power(dev, false);
 440
 441        gma_power_end(dev);
 442}
 443
 444static void psb_intel_lvds_commit(struct drm_encoder *encoder)
 445{
 446        struct drm_device *dev = encoder->dev;
 447        struct drm_psb_private *dev_priv = dev->dev_private;
 448        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
 449
 450        if (mode_dev->backlight_duty_cycle == 0)
 451                mode_dev->backlight_duty_cycle =
 452                    psb_intel_lvds_get_max_backlight(dev);
 453
 454        psb_intel_lvds_set_power(dev, true);
 455}
 456
 457static void psb_intel_lvds_mode_set(struct drm_encoder *encoder,
 458                                struct drm_display_mode *mode,
 459                                struct drm_display_mode *adjusted_mode)
 460{
 461        struct drm_device *dev = encoder->dev;
 462        struct drm_psb_private *dev_priv = dev->dev_private;
 463        u32 pfit_control;
 464
 465        /*
 466         * The LVDS pin pair will already have been turned on in the
 467         * psb_intel_crtc_mode_set since it has a large impact on the DPLL
 468         * settings.
 469         */
 470
 471        /*
 472         * Enable automatic panel scaling so that non-native modes fill the
 473         * screen.  Should be enabled before the pipe is enabled, according to
 474         * register description and PRM.
 475         */
 476        if (mode->hdisplay != adjusted_mode->hdisplay ||
 477            mode->vdisplay != adjusted_mode->vdisplay)
 478                pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
 479                                HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
 480                                HORIZ_INTERP_BILINEAR);
 481        else
 482                pfit_control = 0;
 483
 484        if (dev_priv->lvds_dither)
 485                pfit_control |= PANEL_8TO6_DITHER_ENABLE;
 486
 487        REG_WRITE(PFIT_CONTROL, pfit_control);
 488}
 489
 490/*
 491 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
 492 */
 493static int psb_intel_lvds_get_modes(struct drm_connector *connector)
 494{
 495        struct drm_device *dev = connector->dev;
 496        struct drm_psb_private *dev_priv = dev->dev_private;
 497        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
 498        struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
 499        struct psb_intel_lvds_priv *lvds_priv = gma_encoder->dev_priv;
 500        int ret = 0;
 501
 502        if (!IS_MRST(dev))
 503                ret = psb_intel_ddc_get_modes(connector, &lvds_priv->i2c_bus->adapter);
 504
 505        if (ret)
 506                return ret;
 507
 508        if (mode_dev->panel_fixed_mode != NULL) {
 509                struct drm_display_mode *mode =
 510                    drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
 511                drm_mode_probed_add(connector, mode);
 512                return 1;
 513        }
 514
 515        return 0;
 516}
 517
 518/**
 519 * psb_intel_lvds_destroy - unregister and free LVDS structures
 520 * @connector: connector to free
 521 *
 522 * Unregister the DDC bus for this connector then free the driver private
 523 * structure.
 524 */
 525void psb_intel_lvds_destroy(struct drm_connector *connector)
 526{
 527        struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
 528        struct psb_intel_lvds_priv *lvds_priv = gma_encoder->dev_priv;
 529
 530        psb_intel_i2c_destroy(lvds_priv->ddc_bus);
 531        drm_connector_unregister(connector);
 532        drm_connector_cleanup(connector);
 533        kfree(connector);
 534}
 535
 536int psb_intel_lvds_set_property(struct drm_connector *connector,
 537                                       struct drm_property *property,
 538                                       uint64_t value)
 539{
 540        struct drm_encoder *encoder = connector->encoder;
 541
 542        if (!encoder)
 543                return -1;
 544
 545        if (!strcmp(property->name, "scaling mode")) {
 546                struct gma_crtc *crtc = to_gma_crtc(encoder->crtc);
 547                uint64_t curval;
 548
 549                if (!crtc)
 550                        goto set_prop_error;
 551
 552                switch (value) {
 553                case DRM_MODE_SCALE_FULLSCREEN:
 554                        break;
 555                case DRM_MODE_SCALE_NO_SCALE:
 556                        break;
 557                case DRM_MODE_SCALE_ASPECT:
 558                        break;
 559                default:
 560                        goto set_prop_error;
 561                }
 562
 563                if (drm_object_property_get_value(&connector->base,
 564                                                     property,
 565                                                     &curval))
 566                        goto set_prop_error;
 567
 568                if (curval == value)
 569                        goto set_prop_done;
 570
 571                if (drm_object_property_set_value(&connector->base,
 572                                                        property,
 573                                                        value))
 574                        goto set_prop_error;
 575
 576                if (crtc->saved_mode.hdisplay != 0 &&
 577                    crtc->saved_mode.vdisplay != 0) {
 578                        if (!drm_crtc_helper_set_mode(encoder->crtc,
 579                                                      &crtc->saved_mode,
 580                                                      encoder->crtc->x,
 581                                                      encoder->crtc->y,
 582                                                      encoder->crtc->primary->fb))
 583                                goto set_prop_error;
 584                }
 585        } else if (!strcmp(property->name, "backlight")) {
 586                if (drm_object_property_set_value(&connector->base,
 587                                                        property,
 588                                                        value))
 589                        goto set_prop_error;
 590                else
 591                        gma_backlight_set(encoder->dev, value);
 592        } else if (!strcmp(property->name, "DPMS")) {
 593                const struct drm_encoder_helper_funcs *hfuncs
 594                                                = encoder->helper_private;
 595                hfuncs->dpms(encoder, value);
 596        }
 597
 598set_prop_done:
 599        return 0;
 600set_prop_error:
 601        return -1;
 602}
 603
 604static const struct drm_encoder_helper_funcs psb_intel_lvds_helper_funcs = {
 605        .dpms = psb_intel_lvds_encoder_dpms,
 606        .mode_fixup = psb_intel_lvds_mode_fixup,
 607        .prepare = psb_intel_lvds_prepare,
 608        .mode_set = psb_intel_lvds_mode_set,
 609        .commit = psb_intel_lvds_commit,
 610};
 611
 612const struct drm_connector_helper_funcs
 613                                psb_intel_lvds_connector_helper_funcs = {
 614        .get_modes = psb_intel_lvds_get_modes,
 615        .mode_valid = psb_intel_lvds_mode_valid,
 616        .best_encoder = gma_best_encoder,
 617};
 618
 619const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
 620        .dpms = drm_helper_connector_dpms,
 621        .fill_modes = drm_helper_probe_single_connector_modes,
 622        .set_property = psb_intel_lvds_set_property,
 623        .destroy = psb_intel_lvds_destroy,
 624};
 625
 626/**
 627 * psb_intel_lvds_init - setup LVDS connectors on this device
 628 * @dev: drm device
 629 * @mode_dev: mode device
 630 *
 631 * Create the connector, register the LVDS DDC bus, and try to figure out what
 632 * modes we can display on the LVDS panel (if present).
 633 */
 634void psb_intel_lvds_init(struct drm_device *dev,
 635                         struct psb_intel_mode_device *mode_dev)
 636{
 637        struct gma_encoder *gma_encoder;
 638        struct gma_connector *gma_connector;
 639        struct psb_intel_lvds_priv *lvds_priv;
 640        struct drm_connector *connector;
 641        struct drm_encoder *encoder;
 642        struct drm_display_mode *scan;  /* *modes, *bios_mode; */
 643        struct drm_crtc *crtc;
 644        struct drm_psb_private *dev_priv = dev->dev_private;
 645        u32 lvds;
 646        int pipe;
 647
 648        gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL);
 649        if (!gma_encoder) {
 650                dev_err(dev->dev, "gma_encoder allocation error\n");
 651                return;
 652        }
 653
 654        gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL);
 655        if (!gma_connector) {
 656                dev_err(dev->dev, "gma_connector allocation error\n");
 657                goto failed_encoder;
 658        }
 659
 660        lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL);
 661        if (!lvds_priv) {
 662                dev_err(dev->dev, "LVDS private allocation error\n");
 663                goto failed_connector;
 664        }
 665
 666        gma_encoder->dev_priv = lvds_priv;
 667
 668        connector = &gma_connector->base;
 669        gma_connector->save = psb_intel_lvds_save;
 670        gma_connector->restore = psb_intel_lvds_restore;
 671
 672        encoder = &gma_encoder->base;
 673        drm_connector_init(dev, connector,
 674                           &psb_intel_lvds_connector_funcs,
 675                           DRM_MODE_CONNECTOR_LVDS);
 676
 677        drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS);
 678
 679        gma_connector_attach_encoder(gma_connector, gma_encoder);
 680        gma_encoder->type = INTEL_OUTPUT_LVDS;
 681
 682        drm_encoder_helper_add(encoder, &psb_intel_lvds_helper_funcs);
 683        drm_connector_helper_add(connector,
 684                                 &psb_intel_lvds_connector_helper_funcs);
 685        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 686        connector->interlace_allowed = false;
 687        connector->doublescan_allowed = false;
 688
 689        /*Attach connector properties*/
 690        drm_object_attach_property(&connector->base,
 691                                      dev->mode_config.scaling_mode_property,
 692                                      DRM_MODE_SCALE_FULLSCREEN);
 693        drm_object_attach_property(&connector->base,
 694                                      dev_priv->backlight_property,
 695                                      BRIGHTNESS_MAX_LEVEL);
 696
 697        /*
 698         * Set up I2C bus
 699         * FIXME: distroy i2c_bus when exit
 700         */
 701        lvds_priv->i2c_bus = psb_intel_i2c_create(dev, GPIOB, "LVDSBLC_B");
 702        if (!lvds_priv->i2c_bus) {
 703                dev_printk(KERN_ERR,
 704                        dev->dev, "I2C bus registration failed.\n");
 705                goto failed_blc_i2c;
 706        }
 707        lvds_priv->i2c_bus->slave_addr = 0x2C;
 708        dev_priv->lvds_i2c_bus =  lvds_priv->i2c_bus;
 709
 710        /*
 711         * LVDS discovery:
 712         * 1) check for EDID on DDC
 713         * 2) check for VBT data
 714         * 3) check to see if LVDS is already on
 715         *    if none of the above, no panel
 716         * 4) make sure lid is open
 717         *    if closed, act like it's not there for now
 718         */
 719
 720        /* Set up the DDC bus. */
 721        lvds_priv->ddc_bus = psb_intel_i2c_create(dev, GPIOC, "LVDSDDC_C");
 722        if (!lvds_priv->ddc_bus) {
 723                dev_printk(KERN_ERR, dev->dev,
 724                           "DDC bus registration " "failed.\n");
 725                goto failed_ddc;
 726        }
 727
 728        /*
 729         * Attempt to get the fixed panel mode from DDC.  Assume that the
 730         * preferred mode is the right one.
 731         */
 732        mutex_lock(&dev->mode_config.mutex);
 733        psb_intel_ddc_get_modes(connector, &lvds_priv->ddc_bus->adapter);
 734        list_for_each_entry(scan, &connector->probed_modes, head) {
 735                if (scan->type & DRM_MODE_TYPE_PREFERRED) {
 736                        mode_dev->panel_fixed_mode =
 737                            drm_mode_duplicate(dev, scan);
 738                        DRM_DEBUG_KMS("Using mode from DDC\n");
 739                        goto out;       /* FIXME: check for quirks */
 740                }
 741        }
 742
 743        /* Failed to get EDID, what about VBT? do we need this? */
 744        if (dev_priv->lfp_lvds_vbt_mode) {
 745                mode_dev->panel_fixed_mode =
 746                        drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
 747
 748                if (mode_dev->panel_fixed_mode) {
 749                        mode_dev->panel_fixed_mode->type |=
 750                                DRM_MODE_TYPE_PREFERRED;
 751                        DRM_DEBUG_KMS("Using mode from VBT\n");
 752                        goto out;
 753                }
 754        }
 755
 756        /*
 757         * If we didn't get EDID, try checking if the panel is already turned
 758         * on.  If so, assume that whatever is currently programmed is the
 759         * correct mode.
 760         */
 761        lvds = REG_READ(LVDS);
 762        pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
 763        crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
 764
 765        if (crtc && (lvds & LVDS_PORT_EN)) {
 766                mode_dev->panel_fixed_mode =
 767                    psb_intel_crtc_mode_get(dev, crtc);
 768                if (mode_dev->panel_fixed_mode) {
 769                        mode_dev->panel_fixed_mode->type |=
 770                            DRM_MODE_TYPE_PREFERRED;
 771                        DRM_DEBUG_KMS("Using pre-programmed mode\n");
 772                        goto out;       /* FIXME: check for quirks */
 773                }
 774        }
 775
 776        /* If we still don't have a mode after all that, give up. */
 777        if (!mode_dev->panel_fixed_mode) {
 778                dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n");
 779                goto failed_find;
 780        }
 781
 782        /*
 783         * Blacklist machines with BIOSes that list an LVDS panel without
 784         * actually having one.
 785         */
 786out:
 787        mutex_unlock(&dev->mode_config.mutex);
 788        drm_connector_register(connector);
 789        return;
 790
 791failed_find:
 792        mutex_unlock(&dev->mode_config.mutex);
 793        psb_intel_i2c_destroy(lvds_priv->ddc_bus);
 794failed_ddc:
 795        psb_intel_i2c_destroy(lvds_priv->i2c_bus);
 796failed_blc_i2c:
 797        drm_encoder_cleanup(encoder);
 798        drm_connector_cleanup(connector);
 799failed_connector:
 800        kfree(gma_connector);
 801failed_encoder:
 802        kfree(gma_encoder);
 803}
 804
 805