linux/drivers/gpu/drm/gma500/oaktrail_lvds.c
<<
>>
Prefs
   1/*
   2 * Copyright © 2006-2009 Intel Corporation
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms and conditions of the GNU General Public License,
   6 * version 2, as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope it will be useful, but WITHOUT
   9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  11 * more details.
  12 *
  13 * You should have received a copy of the GNU General Public License along with
  14 * this program; if not, write to the Free Software Foundation, Inc.,
  15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  16 *
  17 * Authors:
  18 *      Eric Anholt <eric@anholt.net>
  19 *      Dave Airlie <airlied@linux.ie>
  20 *      Jesse Barnes <jesse.barnes@intel.com>
  21 */
  22
  23#include <linux/i2c.h>
  24#include <drm/drmP.h>
  25#include <asm/intel-mid.h>
  26
  27#include "intel_bios.h"
  28#include "psb_drv.h"
  29#include "psb_intel_drv.h"
  30#include "psb_intel_reg.h"
  31#include "power.h"
  32#include <linux/pm_runtime.h>
  33
  34/* The max/min PWM frequency in BPCR[31:17] - */
  35/* The smallest number is 1 (not 0) that can fit in the
  36 * 15-bit field of the and then*/
  37/* shifts to the left by one bit to get the actual 16-bit
  38 * value that the 15-bits correspond to.*/
  39#define MRST_BLC_MAX_PWM_REG_FREQ           0xFFFF
  40#define BRIGHTNESS_MAX_LEVEL 100
  41
  42/**
  43 * Sets the power state for the panel.
  44 */
  45static void oaktrail_lvds_set_power(struct drm_device *dev,
  46                                struct gma_encoder *gma_encoder,
  47                                bool on)
  48{
  49        u32 pp_status;
  50        struct drm_psb_private *dev_priv = dev->dev_private;
  51
  52        if (!gma_power_begin(dev, true))
  53                return;
  54
  55        if (on) {
  56                REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
  57                          POWER_TARGET_ON);
  58                do {
  59                        pp_status = REG_READ(PP_STATUS);
  60                } while ((pp_status & (PP_ON | PP_READY)) == PP_READY);
  61                dev_priv->is_lvds_on = true;
  62                if (dev_priv->ops->lvds_bl_power)
  63                        dev_priv->ops->lvds_bl_power(dev, true);
  64        } else {
  65                if (dev_priv->ops->lvds_bl_power)
  66                        dev_priv->ops->lvds_bl_power(dev, false);
  67                REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
  68                          ~POWER_TARGET_ON);
  69                do {
  70                        pp_status = REG_READ(PP_STATUS);
  71                } while (pp_status & PP_ON);
  72                dev_priv->is_lvds_on = false;
  73                pm_request_idle(&dev->pdev->dev);
  74        }
  75        gma_power_end(dev);
  76}
  77
  78static void oaktrail_lvds_dpms(struct drm_encoder *encoder, int mode)
  79{
  80        struct drm_device *dev = encoder->dev;
  81        struct gma_encoder *gma_encoder = to_gma_encoder(encoder);
  82
  83        if (mode == DRM_MODE_DPMS_ON)
  84                oaktrail_lvds_set_power(dev, gma_encoder, true);
  85        else
  86                oaktrail_lvds_set_power(dev, gma_encoder, false);
  87
  88        /* XXX: We never power down the LVDS pairs. */
  89}
  90
  91static void oaktrail_lvds_mode_set(struct drm_encoder *encoder,
  92                               struct drm_display_mode *mode,
  93                               struct drm_display_mode *adjusted_mode)
  94{
  95        struct drm_device *dev = encoder->dev;
  96        struct drm_psb_private *dev_priv = dev->dev_private;
  97        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
  98        struct drm_mode_config *mode_config = &dev->mode_config;
  99        struct drm_connector *connector = NULL;
 100        struct drm_crtc *crtc = encoder->crtc;
 101        u32 lvds_port;
 102        uint64_t v = DRM_MODE_SCALE_FULLSCREEN;
 103
 104        if (!gma_power_begin(dev, true))
 105                return;
 106
 107        /*
 108         * The LVDS pin pair will already have been turned on in the
 109         * psb_intel_crtc_mode_set since it has a large impact on the DPLL
 110         * settings.
 111         */
 112        lvds_port = (REG_READ(LVDS) &
 113                    (~LVDS_PIPEB_SELECT)) |
 114                    LVDS_PORT_EN |
 115                    LVDS_BORDER_EN;
 116
 117        /* If the firmware says dither on Moorestown, or the BIOS does
 118           on Oaktrail then enable dithering */
 119        if (mode_dev->panel_wants_dither || dev_priv->lvds_dither)
 120                lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE;
 121
 122        REG_WRITE(LVDS, lvds_port);
 123
 124        /* Find the connector we're trying to set up */
 125        list_for_each_entry(connector, &mode_config->connector_list, head) {
 126                if (!connector->encoder || connector->encoder->crtc != crtc)
 127                        continue;
 128        }
 129
 130        if (!connector) {
 131                DRM_ERROR("Couldn't find connector when setting mode");
 132                return;
 133        }
 134
 135        drm_object_property_get_value(
 136                &connector->base,
 137                dev->mode_config.scaling_mode_property,
 138                &v);
 139
 140        if (v == DRM_MODE_SCALE_NO_SCALE)
 141                REG_WRITE(PFIT_CONTROL, 0);
 142        else if (v == DRM_MODE_SCALE_ASPECT) {
 143                if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) ||
 144                    (mode->hdisplay != adjusted_mode->crtc_hdisplay)) {
 145                        if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) ==
 146                            (mode->hdisplay * adjusted_mode->crtc_vdisplay))
 147                                REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
 148                        else if ((adjusted_mode->crtc_hdisplay *
 149                                mode->vdisplay) > (mode->hdisplay *
 150                                adjusted_mode->crtc_vdisplay))
 151                                REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
 152                                          PFIT_SCALING_MODE_PILLARBOX);
 153                        else
 154                                REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
 155                                          PFIT_SCALING_MODE_LETTERBOX);
 156                } else
 157                        REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
 158        } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/
 159                REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
 160
 161        gma_power_end(dev);
 162}
 163
 164static void oaktrail_lvds_prepare(struct drm_encoder *encoder)
 165{
 166        struct drm_device *dev = encoder->dev;
 167        struct drm_psb_private *dev_priv = dev->dev_private;
 168        struct gma_encoder *gma_encoder = to_gma_encoder(encoder);
 169        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
 170
 171        if (!gma_power_begin(dev, true))
 172                return;
 173
 174        mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
 175        mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
 176                                          BACKLIGHT_DUTY_CYCLE_MASK);
 177        oaktrail_lvds_set_power(dev, gma_encoder, false);
 178        gma_power_end(dev);
 179}
 180
 181static u32 oaktrail_lvds_get_max_backlight(struct drm_device *dev)
 182{
 183        struct drm_psb_private *dev_priv = dev->dev_private;
 184        u32 ret;
 185
 186        if (gma_power_begin(dev, false)) {
 187                ret = ((REG_READ(BLC_PWM_CTL) &
 188                          BACKLIGHT_MODULATION_FREQ_MASK) >>
 189                          BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
 190
 191                gma_power_end(dev);
 192        } else
 193                ret = ((dev_priv->regs.saveBLC_PWM_CTL &
 194                          BACKLIGHT_MODULATION_FREQ_MASK) >>
 195                          BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
 196
 197        return ret;
 198}
 199
 200static void oaktrail_lvds_commit(struct drm_encoder *encoder)
 201{
 202        struct drm_device *dev = encoder->dev;
 203        struct drm_psb_private *dev_priv = dev->dev_private;
 204        struct gma_encoder *gma_encoder = to_gma_encoder(encoder);
 205        struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
 206
 207        if (mode_dev->backlight_duty_cycle == 0)
 208                mode_dev->backlight_duty_cycle =
 209                                        oaktrail_lvds_get_max_backlight(dev);
 210        oaktrail_lvds_set_power(dev, gma_encoder, true);
 211}
 212
 213static const struct drm_encoder_helper_funcs oaktrail_lvds_helper_funcs = {
 214        .dpms = oaktrail_lvds_dpms,
 215        .mode_fixup = psb_intel_lvds_mode_fixup,
 216        .prepare = oaktrail_lvds_prepare,
 217        .mode_set = oaktrail_lvds_mode_set,
 218        .commit = oaktrail_lvds_commit,
 219};
 220
 221/* Returns the panel fixed mode from configuration. */
 222
 223static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev,
 224                                        struct psb_intel_mode_device *mode_dev)
 225{
 226        struct drm_display_mode *mode = NULL;
 227        struct drm_psb_private *dev_priv = dev->dev_private;
 228        struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD;
 229
 230        mode_dev->panel_fixed_mode = NULL;
 231
 232        /* Use the firmware provided data on Moorestown */
 233        if (dev_priv->has_gct) {
 234                mode = kzalloc(sizeof(*mode), GFP_KERNEL);
 235                if (!mode)
 236                        return;
 237
 238                mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
 239                mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
 240                mode->hsync_start = mode->hdisplay + \
 241                                ((ti->hsync_offset_hi << 8) | \
 242                                ti->hsync_offset_lo);
 243                mode->hsync_end = mode->hsync_start + \
 244                                ((ti->hsync_pulse_width_hi << 8) | \
 245                                ti->hsync_pulse_width_lo);
 246                mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
 247                                                        ti->hblank_lo);
 248                mode->vsync_start = \
 249                        mode->vdisplay + ((ti->vsync_offset_hi << 4) | \
 250                                                ti->vsync_offset_lo);
 251                mode->vsync_end = \
 252                        mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \
 253                                                ti->vsync_pulse_width_lo);
 254                mode->vtotal = mode->vdisplay + \
 255                                ((ti->vblank_hi << 8) | ti->vblank_lo);
 256                mode->clock = ti->pixel_clock * 10;
 257#if 0
 258                printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay);
 259                printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay);
 260                printk(KERN_INFO "HSS is %d\n", mode->hsync_start);
 261                printk(KERN_INFO "HSE is %d\n", mode->hsync_end);
 262                printk(KERN_INFO "htotal is %d\n", mode->htotal);
 263                printk(KERN_INFO "VSS is %d\n", mode->vsync_start);
 264                printk(KERN_INFO "VSE is %d\n", mode->vsync_end);
 265                printk(KERN_INFO "vtotal is %d\n", mode->vtotal);
 266                printk(KERN_INFO "clock is %d\n", mode->clock);
 267#endif
 268                mode_dev->panel_fixed_mode = mode;
 269        }
 270
 271        /* Use the BIOS VBT mode if available */
 272        if (mode_dev->panel_fixed_mode == NULL && mode_dev->vbt_mode)
 273                mode_dev->panel_fixed_mode = drm_mode_duplicate(dev,
 274                                                mode_dev->vbt_mode);
 275
 276        /* Then try the LVDS VBT mode */
 277        if (mode_dev->panel_fixed_mode == NULL)
 278                if (dev_priv->lfp_lvds_vbt_mode)
 279                        mode_dev->panel_fixed_mode =
 280                                drm_mode_duplicate(dev,
 281                                        dev_priv->lfp_lvds_vbt_mode);
 282
 283        /* If we still got no mode then bail */
 284        if (mode_dev->panel_fixed_mode == NULL)
 285                return;
 286
 287        drm_mode_set_name(mode_dev->panel_fixed_mode);
 288        drm_mode_set_crtcinfo(mode_dev->panel_fixed_mode, 0);
 289}
 290
 291/**
 292 * oaktrail_lvds_init - setup LVDS connectors on this device
 293 * @dev: drm device
 294 *
 295 * Create the connector, register the LVDS DDC bus, and try to figure out what
 296 * modes we can display on the LVDS panel (if present).
 297 */
 298void oaktrail_lvds_init(struct drm_device *dev,
 299                    struct psb_intel_mode_device *mode_dev)
 300{
 301        struct gma_encoder *gma_encoder;
 302        struct gma_connector *gma_connector;
 303        struct drm_connector *connector;
 304        struct drm_encoder *encoder;
 305        struct drm_psb_private *dev_priv = dev->dev_private;
 306        struct edid *edid;
 307        struct i2c_adapter *i2c_adap;
 308        struct drm_display_mode *scan;  /* *modes, *bios_mode; */
 309
 310        gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL);
 311        if (!gma_encoder)
 312                return;
 313
 314        gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL);
 315        if (!gma_connector)
 316                goto failed_connector;
 317
 318        connector = &gma_connector->base;
 319        encoder = &gma_encoder->base;
 320        dev_priv->is_lvds_on = true;
 321        drm_connector_init(dev, connector,
 322                           &psb_intel_lvds_connector_funcs,
 323                           DRM_MODE_CONNECTOR_LVDS);
 324
 325        drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs,
 326                         DRM_MODE_ENCODER_LVDS);
 327
 328        gma_connector_attach_encoder(gma_connector, gma_encoder);
 329        gma_encoder->type = INTEL_OUTPUT_LVDS;
 330
 331        drm_encoder_helper_add(encoder, &oaktrail_lvds_helper_funcs);
 332        drm_connector_helper_add(connector,
 333                                 &psb_intel_lvds_connector_helper_funcs);
 334        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 335        connector->interlace_allowed = false;
 336        connector->doublescan_allowed = false;
 337
 338        drm_object_attach_property(&connector->base,
 339                                        dev->mode_config.scaling_mode_property,
 340                                        DRM_MODE_SCALE_FULLSCREEN);
 341        drm_object_attach_property(&connector->base,
 342                                        dev_priv->backlight_property,
 343                                        BRIGHTNESS_MAX_LEVEL);
 344
 345        mode_dev->panel_wants_dither = false;
 346        if (dev_priv->has_gct)
 347                mode_dev->panel_wants_dither = (dev_priv->gct_data.
 348                        Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE);
 349        if (dev_priv->lvds_dither)
 350                mode_dev->panel_wants_dither = 1;
 351
 352        /*
 353         * LVDS discovery:
 354         * 1) check for EDID on DDC
 355         * 2) check for VBT data
 356         * 3) check to see if LVDS is already on
 357         *    if none of the above, no panel
 358         * 4) make sure lid is open
 359         *    if closed, act like it's not there for now
 360         */
 361
 362        mutex_lock(&dev->mode_config.mutex);
 363        i2c_adap = i2c_get_adapter(dev_priv->ops->i2c_bus);
 364        if (i2c_adap == NULL)
 365                dev_err(dev->dev, "No ddc adapter available!\n");
 366        /*
 367         * Attempt to get the fixed panel mode from DDC.  Assume that the
 368         * preferred mode is the right one.
 369         */
 370        if (i2c_adap) {
 371                edid = drm_get_edid(connector, i2c_adap);
 372                if (edid) {
 373                        drm_mode_connector_update_edid_property(connector,
 374                                                                        edid);
 375                        drm_add_edid_modes(connector, edid);
 376                        kfree(edid);
 377                }
 378
 379                list_for_each_entry(scan, &connector->probed_modes, head) {
 380                        if (scan->type & DRM_MODE_TYPE_PREFERRED) {
 381                                mode_dev->panel_fixed_mode =
 382                                    drm_mode_duplicate(dev, scan);
 383                                goto out;       /* FIXME: check for quirks */
 384                        }
 385                }
 386        }
 387        /*
 388         * If we didn't get EDID, try geting panel timing
 389         * from configuration data
 390         */
 391        oaktrail_lvds_get_configuration_mode(dev, mode_dev);
 392
 393        if (mode_dev->panel_fixed_mode) {
 394                mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
 395                goto out;       /* FIXME: check for quirks */
 396        }
 397
 398        /* If we still don't have a mode after all that, give up. */
 399        if (!mode_dev->panel_fixed_mode) {
 400                dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n");
 401                goto failed_find;
 402        }
 403
 404out:
 405        mutex_unlock(&dev->mode_config.mutex);
 406
 407        drm_connector_register(connector);
 408        return;
 409
 410failed_find:
 411        mutex_unlock(&dev->mode_config.mutex);
 412
 413        dev_dbg(dev->dev, "No LVDS modes found, disabling.\n");
 414        if (gma_encoder->ddc_bus)
 415                psb_intel_i2c_destroy(gma_encoder->ddc_bus);
 416
 417/* failed_ddc: */
 418
 419        drm_encoder_cleanup(encoder);
 420        drm_connector_cleanup(connector);
 421        kfree(gma_connector);
 422failed_connector:
 423        kfree(gma_encoder);
 424}
 425
 426