668 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright © 2006-2011 Intel Corporation4 *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/dmi.h>12#include <linux/i2c.h>13#include <linux/pm_runtime.h>14 15#include <drm/drm_crtc_helper.h>16#include <drm/drm_modeset_helper_vtables.h>17#include <drm/drm_simple_kms_helper.h>18 19#include "cdv_device.h"20#include "intel_bios.h"21#include "power.h"22#include "psb_drv.h"23#include "psb_intel_drv.h"24#include "psb_intel_reg.h"25 26/*27 * LVDS I2C backlight control macros28 */29#define BRIGHTNESS_MAX_LEVEL 10030#define BRIGHTNESS_MASK 0xFF31#define BLC_I2C_TYPE 0x0132#define BLC_PWM_TYPT 0x0233 34#define BLC_POLARITY_NORMAL 035#define BLC_POLARITY_INVERSE 136 37#define PSB_BLC_MAX_PWM_REG_FREQ (0xFFFE)38#define PSB_BLC_MIN_PWM_REG_FREQ (0x2)39#define PSB_BLC_PWM_PRECISION_FACTOR (10)40#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)41#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)42 43struct cdv_intel_lvds_priv {44 /**45 * Saved LVDO output states46 */47 uint32_t savePP_ON;48 uint32_t savePP_OFF;49 uint32_t saveLVDS;50 uint32_t savePP_CONTROL;51 uint32_t savePP_CYCLE;52 uint32_t savePFIT_CONTROL;53 uint32_t savePFIT_PGM_RATIOS;54 uint32_t saveBLC_PWM_CTL;55};56 57/*58 * Returns the maximum level of the backlight duty cycle field.59 */60static u32 cdv_intel_lvds_get_max_backlight(struct drm_device *dev)61{62 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);63 u32 retval;64 65 if (gma_power_begin(dev, false)) {66 retval = ((REG_READ(BLC_PWM_CTL) &67 BACKLIGHT_MODULATION_FREQ_MASK) >>68 BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;69 70 gma_power_end(dev);71 } else72 retval = ((dev_priv->regs.saveBLC_PWM_CTL &73 BACKLIGHT_MODULATION_FREQ_MASK) >>74 BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;75 76 return retval;77}78 79/*80 * Sets the backlight level.81 *82 * level backlight level, from 0 to cdv_intel_lvds_get_max_backlight().83 */84static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level)85{86 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);87 u32 blc_pwm_ctl;88 89 if (gma_power_begin(dev, false)) {90 blc_pwm_ctl =91 REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;92 REG_WRITE(BLC_PWM_CTL,93 (blc_pwm_ctl |94 (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));95 gma_power_end(dev);96 } else {97 blc_pwm_ctl = dev_priv->regs.saveBLC_PWM_CTL &98 ~BACKLIGHT_DUTY_CYCLE_MASK;99 dev_priv->regs.saveBLC_PWM_CTL = (blc_pwm_ctl |100 (level << BACKLIGHT_DUTY_CYCLE_SHIFT));101 }102}103 104/*105 * Sets the power state for the panel.106 */107static void cdv_intel_lvds_set_power(struct drm_device *dev,108 struct drm_encoder *encoder, bool on)109{110 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);111 u32 pp_status;112 113 if (!gma_power_begin(dev, true))114 return;115 116 if (on) {117 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |118 POWER_TARGET_ON);119 do {120 pp_status = REG_READ(PP_STATUS);121 } while ((pp_status & PP_ON) == 0);122 123 cdv_intel_lvds_set_backlight(dev,124 dev_priv->mode_dev.backlight_duty_cycle);125 } else {126 cdv_intel_lvds_set_backlight(dev, 0);127 128 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &129 ~POWER_TARGET_ON);130 do {131 pp_status = REG_READ(PP_STATUS);132 } while (pp_status & PP_ON);133 }134 gma_power_end(dev);135}136 137static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)138{139 struct drm_device *dev = encoder->dev;140 if (mode == DRM_MODE_DPMS_ON)141 cdv_intel_lvds_set_power(dev, encoder, true);142 else143 cdv_intel_lvds_set_power(dev, encoder, false);144 /* XXX: We never power down the LVDS pairs. */145}146 147static void cdv_intel_lvds_save(struct drm_connector *connector)148{149}150 151static void cdv_intel_lvds_restore(struct drm_connector *connector)152{153}154 155static enum drm_mode_status cdv_intel_lvds_mode_valid(struct drm_connector *connector,156 struct drm_display_mode *mode)157{158 struct drm_device *dev = connector->dev;159 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);160 struct drm_display_mode *fixed_mode =161 dev_priv->mode_dev.panel_fixed_mode;162 163 /* just in case */164 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)165 return MODE_NO_DBLESCAN;166 167 /* just in case */168 if (mode->flags & DRM_MODE_FLAG_INTERLACE)169 return MODE_NO_INTERLACE;170 171 if (fixed_mode) {172 if (mode->hdisplay > fixed_mode->hdisplay)173 return MODE_PANEL;174 if (mode->vdisplay > fixed_mode->vdisplay)175 return MODE_PANEL;176 }177 return MODE_OK;178}179 180static bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder,181 const struct drm_display_mode *mode,182 struct drm_display_mode *adjusted_mode)183{184 struct drm_device *dev = encoder->dev;185 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);186 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;187 struct drm_encoder *tmp_encoder;188 struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;189 190 /* Should never happen!! */191 list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,192 head) {193 if (tmp_encoder != encoder194 && tmp_encoder->crtc == encoder->crtc) {195 pr_err("Can't enable LVDS and another encoder on the same pipe\n");196 return false;197 }198 }199 200 /*201 * If we have timings from the BIOS for the panel, put them in202 * to the adjusted mode. The CRTC will be set up for this mode,203 * with the panel scaling set up to source from the H/VDisplay204 * of the original mode.205 */206 if (panel_fixed_mode != NULL) {207 adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;208 adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;209 adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;210 adjusted_mode->htotal = panel_fixed_mode->htotal;211 adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;212 adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;213 adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;214 adjusted_mode->vtotal = panel_fixed_mode->vtotal;215 adjusted_mode->clock = panel_fixed_mode->clock;216 drm_mode_set_crtcinfo(adjusted_mode,217 CRTC_INTERLACE_HALVE_V);218 }219 220 /*221 * XXX: It would be nice to support lower refresh rates on the222 * panels to reduce power consumption, and perhaps match the223 * user's requested refresh rate.224 */225 226 return true;227}228 229static void cdv_intel_lvds_prepare(struct drm_encoder *encoder)230{231 struct drm_device *dev = encoder->dev;232 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);233 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;234 235 if (!gma_power_begin(dev, true))236 return;237 238 mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);239 mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &240 BACKLIGHT_DUTY_CYCLE_MASK);241 242 cdv_intel_lvds_set_power(dev, encoder, false);243 244 gma_power_end(dev);245}246 247static void cdv_intel_lvds_commit(struct drm_encoder *encoder)248{249 struct drm_device *dev = encoder->dev;250 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);251 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;252 253 if (mode_dev->backlight_duty_cycle == 0)254 mode_dev->backlight_duty_cycle =255 cdv_intel_lvds_get_max_backlight(dev);256 257 cdv_intel_lvds_set_power(dev, encoder, true);258}259 260static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,261 struct drm_display_mode *mode,262 struct drm_display_mode *adjusted_mode)263{264 struct drm_device *dev = encoder->dev;265 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);266 struct gma_crtc *gma_crtc = to_gma_crtc(encoder->crtc);267 u32 pfit_control;268 269 /*270 * The LVDS pin pair will already have been turned on in the271 * cdv_intel_crtc_mode_set since it has a large impact on the DPLL272 * settings.273 */274 275 /*276 * Enable automatic panel scaling so that non-native modes fill the277 * screen. Should be enabled before the pipe is enabled, according to278 * register description and PRM.279 */280 if (mode->hdisplay != adjusted_mode->hdisplay ||281 mode->vdisplay != adjusted_mode->vdisplay)282 pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |283 HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |284 HORIZ_INTERP_BILINEAR);285 else286 pfit_control = 0;287 288 pfit_control |= gma_crtc->pipe << PFIT_PIPE_SHIFT;289 290 if (dev_priv->lvds_dither)291 pfit_control |= PANEL_8TO6_DITHER_ENABLE;292 293 REG_WRITE(PFIT_CONTROL, pfit_control);294}295 296/*297 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.298 */299static int cdv_intel_lvds_get_modes(struct drm_connector *connector)300{301 struct drm_device *dev = connector->dev;302 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);303 struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;304 int ret;305 306 ret = psb_intel_ddc_get_modes(connector, connector->ddc);307 308 if (ret)309 return ret;310 311 if (mode_dev->panel_fixed_mode != NULL) {312 struct drm_display_mode *mode =313 drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);314 if (!mode)315 return 0;316 317 drm_mode_probed_add(connector, mode);318 return 1;319 }320 321 return 0;322}323 324static void cdv_intel_lvds_destroy(struct drm_connector *connector)325{326 struct gma_connector *gma_connector = to_gma_connector(connector);327 struct gma_encoder *gma_encoder = gma_attached_encoder(connector);328 329 gma_i2c_destroy(to_gma_i2c_chan(connector->ddc));330 gma_i2c_destroy(gma_encoder->i2c_bus);331 drm_connector_cleanup(connector);332 kfree(gma_connector);333}334 335static int cdv_intel_lvds_set_property(struct drm_connector *connector,336 struct drm_property *property,337 uint64_t value)338{339 struct drm_encoder *encoder = connector->encoder;340 341 if (!strcmp(property->name, "scaling mode") && encoder) {342 struct gma_crtc *crtc = to_gma_crtc(encoder->crtc);343 uint64_t curValue;344 345 if (!crtc)346 return -1;347 348 switch (value) {349 case DRM_MODE_SCALE_FULLSCREEN:350 break;351 case DRM_MODE_SCALE_NO_SCALE:352 break;353 case DRM_MODE_SCALE_ASPECT:354 break;355 default:356 return -1;357 }358 359 if (drm_object_property_get_value(&connector->base,360 property,361 &curValue))362 return -1;363 364 if (curValue == value)365 return 0;366 367 if (drm_object_property_set_value(&connector->base,368 property,369 value))370 return -1;371 372 if (crtc->saved_mode.hdisplay != 0 &&373 crtc->saved_mode.vdisplay != 0) {374 if (!drm_crtc_helper_set_mode(encoder->crtc,375 &crtc->saved_mode,376 encoder->crtc->x,377 encoder->crtc->y,378 encoder->crtc->primary->fb))379 return -1;380 }381 } else if (!strcmp(property->name, "backlight") && encoder) {382 if (drm_object_property_set_value(&connector->base,383 property,384 value))385 return -1;386 else387 gma_backlight_set(encoder->dev, value);388 } else if (!strcmp(property->name, "DPMS") && encoder) {389 const struct drm_encoder_helper_funcs *helpers =390 encoder->helper_private;391 helpers->dpms(encoder, value);392 }393 return 0;394}395 396static const struct drm_encoder_helper_funcs397 cdv_intel_lvds_helper_funcs = {398 .dpms = cdv_intel_lvds_encoder_dpms,399 .mode_fixup = cdv_intel_lvds_mode_fixup,400 .prepare = cdv_intel_lvds_prepare,401 .mode_set = cdv_intel_lvds_mode_set,402 .commit = cdv_intel_lvds_commit,403};404 405static const struct drm_connector_helper_funcs406 cdv_intel_lvds_connector_helper_funcs = {407 .get_modes = cdv_intel_lvds_get_modes,408 .mode_valid = cdv_intel_lvds_mode_valid,409 .best_encoder = gma_best_encoder,410};411 412static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = {413 .dpms = drm_helper_connector_dpms,414 .fill_modes = drm_helper_probe_single_connector_modes,415 .set_property = cdv_intel_lvds_set_property,416 .destroy = cdv_intel_lvds_destroy,417};418 419/*420 * Enumerate the child dev array parsed from VBT to check whether421 * the LVDS is present.422 * If it is present, return 1.423 * If it is not present, return false.424 * If no child dev is parsed from VBT, it assumes that the LVDS is present.425 */426static bool lvds_is_present_in_vbt(struct drm_device *dev,427 u8 *i2c_pin)428{429 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);430 int i;431 432 if (!dev_priv->child_dev_num)433 return true;434 435 for (i = 0; i < dev_priv->child_dev_num; i++) {436 struct child_device_config *child = dev_priv->child_dev + i;437 438 /* If the device type is not LFP, continue.439 * We have to check both the new identifiers as well as the440 * old for compatibility with some BIOSes.441 */442 if (child->device_type != DEVICE_TYPE_INT_LFP &&443 child->device_type != DEVICE_TYPE_LFP)444 continue;445 446 if (child->i2c_pin)447 *i2c_pin = child->i2c_pin;448 449 /* However, we cannot trust the BIOS writers to populate450 * the VBT correctly. Since LVDS requires additional451 * information from AIM blocks, a non-zero addin offset is452 * a good indicator that the LVDS is actually present.453 */454 if (child->addin_offset)455 return true;456 457 /* But even then some BIOS writers perform some black magic458 * and instantiate the device without reference to any459 * additional data. Trust that if the VBT was written into460 * the OpRegion then they have validated the LVDS's existence.461 */462 if (dev_priv->opregion.vbt)463 return true;464 }465 466 return false;467}468 469/**470 * cdv_intel_lvds_init - setup LVDS connectors on this device471 * @dev: drm device472 * @mode_dev: PSB mode device473 *474 * Create the connector, register the LVDS DDC bus, and try to figure out what475 * modes we can display on the LVDS panel (if present).476 */477void cdv_intel_lvds_init(struct drm_device *dev,478 struct psb_intel_mode_device *mode_dev)479{480 struct gma_encoder *gma_encoder;481 struct gma_connector *gma_connector;482 struct cdv_intel_lvds_priv *lvds_priv;483 struct drm_connector *connector;484 struct drm_encoder *encoder;485 struct drm_display_mode *scan;486 struct drm_crtc *crtc;487 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);488 struct gma_i2c_chan *ddc_bus;489 u32 lvds;490 int pipe;491 int ret;492 u8 pin;493 494 if (!dev_priv->lvds_enabled_in_vbt)495 return;496 497 pin = GMBUS_PORT_PANEL;498 if (!lvds_is_present_in_vbt(dev, &pin)) {499 DRM_DEBUG_KMS("LVDS is not present in VBT\n");500 return;501 }502 503 gma_encoder = kzalloc(sizeof(struct gma_encoder),504 GFP_KERNEL);505 if (!gma_encoder)506 return;507 508 gma_connector = kzalloc(sizeof(struct gma_connector),509 GFP_KERNEL);510 if (!gma_connector)511 goto err_free_encoder;512 513 lvds_priv = kzalloc(sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL);514 if (!lvds_priv)515 goto err_free_connector;516 517 gma_encoder->dev_priv = lvds_priv;518 519 connector = &gma_connector->base;520 gma_connector->save = cdv_intel_lvds_save;521 gma_connector->restore = cdv_intel_lvds_restore;522 encoder = &gma_encoder->base;523 524 /* Set up the DDC bus. */525 ddc_bus = gma_i2c_create(dev, GPIOC, "LVDSDDC_C");526 if (!ddc_bus) {527 dev_printk(KERN_ERR, dev->dev,528 "DDC bus registration " "failed.\n");529 goto err_free_lvds_priv;530 }531 532 ret = drm_connector_init_with_ddc(dev, connector,533 &cdv_intel_lvds_connector_funcs,534 DRM_MODE_CONNECTOR_LVDS,535 &ddc_bus->base);536 if (ret)537 goto err_destroy_ddc;538 539 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS);540 if (ret)541 goto err_connector_cleanup;542 543 gma_connector_attach_encoder(gma_connector, gma_encoder);544 gma_encoder->type = INTEL_OUTPUT_LVDS;545 546 drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs);547 drm_connector_helper_add(connector,548 &cdv_intel_lvds_connector_helper_funcs);549 connector->display_info.subpixel_order = SubPixelHorizontalRGB;550 connector->interlace_allowed = false;551 connector->doublescan_allowed = false;552 553 /*Attach connector properties*/554 drm_object_attach_property(&connector->base,555 dev->mode_config.scaling_mode_property,556 DRM_MODE_SCALE_FULLSCREEN);557 drm_object_attach_property(&connector->base,558 dev_priv->backlight_property,559 BRIGHTNESS_MAX_LEVEL);560 561 /**562 * Set up I2C bus563 * FIXME: distroy i2c_bus when exit564 */565 gma_encoder->i2c_bus = gma_i2c_create(dev, GPIOB, "LVDSBLC_B");566 if (!gma_encoder->i2c_bus) {567 dev_printk(KERN_ERR,568 dev->dev, "I2C bus registration failed.\n");569 goto err_encoder_cleanup;570 }571 gma_encoder->i2c_bus->target_addr = 0x2C;572 dev_priv->lvds_i2c_bus = gma_encoder->i2c_bus;573 574 /*575 * LVDS discovery:576 * 1) check for EDID on DDC577 * 2) check for VBT data578 * 3) check to see if LVDS is already on579 * if none of the above, no panel580 * 4) make sure lid is open581 * if closed, act like it's not there for now582 */583 584 /*585 * Attempt to get the fixed panel mode from DDC. Assume that the586 * preferred mode is the right one.587 */588 mutex_lock(&dev->mode_config.mutex);589 psb_intel_ddc_get_modes(connector, &ddc_bus->base);590 591 list_for_each_entry(scan, &connector->probed_modes, head) {592 if (scan->type & DRM_MODE_TYPE_PREFERRED) {593 mode_dev->panel_fixed_mode =594 drm_mode_duplicate(dev, scan);595 goto out; /* FIXME: check for quirks */596 }597 }598 599 /* Failed to get EDID, what about VBT? do we need this?*/600 if (dev_priv->lfp_lvds_vbt_mode) {601 mode_dev->panel_fixed_mode =602 drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);603 if (mode_dev->panel_fixed_mode) {604 mode_dev->panel_fixed_mode->type |=605 DRM_MODE_TYPE_PREFERRED;606 goto out; /* FIXME: check for quirks */607 }608 }609 /*610 * If we didn't get EDID, try checking if the panel is already turned611 * on. If so, assume that whatever is currently programmed is the612 * correct mode.613 */614 lvds = REG_READ(LVDS);615 pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;616 crtc = psb_intel_get_crtc_from_pipe(dev, pipe);617 618 if (crtc && (lvds & LVDS_PORT_EN)) {619 mode_dev->panel_fixed_mode =620 cdv_intel_crtc_mode_get(dev, crtc);621 if (mode_dev->panel_fixed_mode) {622 mode_dev->panel_fixed_mode->type |=623 DRM_MODE_TYPE_PREFERRED;624 goto out; /* FIXME: check for quirks */625 }626 }627 628 /* If we still don't have a mode after all that, give up. */629 if (!mode_dev->panel_fixed_mode) {630 DRM_DEBUG631 ("Found no modes on the lvds, ignoring the LVDS\n");632 goto err_unlock;633 }634 635 /* setup PWM */636 {637 u32 pwm;638 639 pwm = REG_READ(BLC_PWM_CTL2);640 if (pipe == 1)641 pwm |= PWM_PIPE_B;642 else643 pwm &= ~PWM_PIPE_B;644 pwm |= PWM_ENABLE;645 REG_WRITE(BLC_PWM_CTL2, pwm);646 }647 648out:649 mutex_unlock(&dev->mode_config.mutex);650 return;651 652err_unlock:653 mutex_unlock(&dev->mode_config.mutex);654 gma_i2c_destroy(gma_encoder->i2c_bus);655err_encoder_cleanup:656 drm_encoder_cleanup(encoder);657err_connector_cleanup:658 drm_connector_cleanup(connector);659err_destroy_ddc:660 gma_i2c_destroy(ddc_bus);661err_free_lvds_priv:662 kfree(lvds_priv);663err_free_connector:664 kfree(gma_connector);665err_free_encoder:666 kfree(gma_encoder);667}668