root/drivers/gpu/drm/gma500/oaktrail_lvds.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. oaktrail_lvds_set_power
  2. oaktrail_lvds_dpms
  3. oaktrail_lvds_mode_set
  4. oaktrail_lvds_prepare
  5. oaktrail_lvds_get_max_backlight
  6. oaktrail_lvds_commit
  7. oaktrail_lvds_get_configuration_mode
  8. oaktrail_lvds_init

   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  */
  33 static 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 
  66 static 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 
  79 static 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 
 152 static 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 
 169 static 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 
 188 static 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 
 201 static 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 
 211 static 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  */
 286 void 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 
 397 out:
 398         mutex_unlock(&dev->mode_config.mutex);
 399 
 400         drm_connector_register(connector);
 401         return;
 402 
 403 failed_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);
 417 failed_connector:
 418         kfree(gma_encoder);
 419 }
 420 

/* [<][>][^][v][top][bottom][index][help] */