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