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