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