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