cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cdv_intel_lvds.c (18254B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright © 2006-2011 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/dmi.h>
     12#include <linux/i2c.h>
     13#include <linux/pm_runtime.h>
     14
     15#include <drm/drm_simple_kms_helper.h>
     16
     17#include "cdv_device.h"
     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/*
     25 * LVDS I2C backlight control macros
     26 */
     27#define BRIGHTNESS_MAX_LEVEL 100
     28#define BRIGHTNESS_MASK 0xFF
     29#define BLC_I2C_TYPE	0x01
     30#define BLC_PWM_TYPT	0x02
     31
     32#define BLC_POLARITY_NORMAL 0
     33#define BLC_POLARITY_INVERSE 1
     34
     35#define PSB_BLC_MAX_PWM_REG_FREQ       (0xFFFE)
     36#define PSB_BLC_MIN_PWM_REG_FREQ	(0x2)
     37#define PSB_BLC_PWM_PRECISION_FACTOR	(10)
     38#define PSB_BACKLIGHT_PWM_CTL_SHIFT	(16)
     39#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
     40
     41struct cdv_intel_lvds_priv {
     42	/**
     43	 * Saved LVDO output states
     44	 */
     45	uint32_t savePP_ON;
     46	uint32_t savePP_OFF;
     47	uint32_t saveLVDS;
     48	uint32_t savePP_CONTROL;
     49	uint32_t savePP_CYCLE;
     50	uint32_t savePFIT_CONTROL;
     51	uint32_t savePFIT_PGM_RATIOS;
     52	uint32_t saveBLC_PWM_CTL;
     53};
     54
     55/*
     56 * Returns the maximum level of the backlight duty cycle field.
     57 */
     58static u32 cdv_intel_lvds_get_max_backlight(struct drm_device *dev)
     59{
     60	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
     61	u32 retval;
     62
     63	if (gma_power_begin(dev, false)) {
     64		retval = ((REG_READ(BLC_PWM_CTL) &
     65			  BACKLIGHT_MODULATION_FREQ_MASK) >>
     66			  BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
     67
     68		gma_power_end(dev);
     69	} else
     70		retval = ((dev_priv->regs.saveBLC_PWM_CTL &
     71			  BACKLIGHT_MODULATION_FREQ_MASK) >>
     72			  BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
     73
     74	return retval;
     75}
     76
     77/*
     78 * Sets the backlight level.
     79 *
     80 * level backlight level, from 0 to cdv_intel_lvds_get_max_backlight().
     81 */
     82static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level)
     83{
     84	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
     85	u32 blc_pwm_ctl;
     86
     87	if (gma_power_begin(dev, false)) {
     88		blc_pwm_ctl =
     89			REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
     90		REG_WRITE(BLC_PWM_CTL,
     91				(blc_pwm_ctl |
     92				(level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
     93		gma_power_end(dev);
     94	} else {
     95		blc_pwm_ctl = dev_priv->regs.saveBLC_PWM_CTL &
     96				~BACKLIGHT_DUTY_CYCLE_MASK;
     97		dev_priv->regs.saveBLC_PWM_CTL = (blc_pwm_ctl |
     98					(level << BACKLIGHT_DUTY_CYCLE_SHIFT));
     99	}
    100}
    101
    102/*
    103 * Sets the power state for the panel.
    104 */
    105static void cdv_intel_lvds_set_power(struct drm_device *dev,
    106				     struct drm_encoder *encoder, bool on)
    107{
    108	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    109	u32 pp_status;
    110
    111	if (!gma_power_begin(dev, true))
    112		return;
    113
    114	if (on) {
    115		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
    116			  POWER_TARGET_ON);
    117		do {
    118			pp_status = REG_READ(PP_STATUS);
    119		} while ((pp_status & PP_ON) == 0);
    120
    121		cdv_intel_lvds_set_backlight(dev,
    122				dev_priv->mode_dev.backlight_duty_cycle);
    123	} else {
    124		cdv_intel_lvds_set_backlight(dev, 0);
    125
    126		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
    127			  ~POWER_TARGET_ON);
    128		do {
    129			pp_status = REG_READ(PP_STATUS);
    130		} while (pp_status & PP_ON);
    131	}
    132	gma_power_end(dev);
    133}
    134
    135static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
    136{
    137	struct drm_device *dev = encoder->dev;
    138	if (mode == DRM_MODE_DPMS_ON)
    139		cdv_intel_lvds_set_power(dev, encoder, true);
    140	else
    141		cdv_intel_lvds_set_power(dev, encoder, false);
    142	/* XXX: We never power down the LVDS pairs. */
    143}
    144
    145static void cdv_intel_lvds_save(struct drm_connector *connector)
    146{
    147}
    148
    149static void cdv_intel_lvds_restore(struct drm_connector *connector)
    150{
    151}
    152
    153static enum drm_mode_status cdv_intel_lvds_mode_valid(struct drm_connector *connector,
    154			      struct drm_display_mode *mode)
    155{
    156	struct drm_device *dev = connector->dev;
    157	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    158	struct drm_display_mode *fixed_mode =
    159					dev_priv->mode_dev.panel_fixed_mode;
    160
    161	/* just in case */
    162	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
    163		return MODE_NO_DBLESCAN;
    164
    165	/* just in case */
    166	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
    167		return MODE_NO_INTERLACE;
    168
    169	if (fixed_mode) {
    170		if (mode->hdisplay > fixed_mode->hdisplay)
    171			return MODE_PANEL;
    172		if (mode->vdisplay > fixed_mode->vdisplay)
    173			return MODE_PANEL;
    174	}
    175	return MODE_OK;
    176}
    177
    178static bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder,
    179				  const struct drm_display_mode *mode,
    180				  struct drm_display_mode *adjusted_mode)
    181{
    182	struct drm_device *dev = encoder->dev;
    183	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    184	struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
    185	struct drm_encoder *tmp_encoder;
    186	struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
    187
    188	/* Should never happen!! */
    189	list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
    190			    head) {
    191		if (tmp_encoder != encoder
    192		    && tmp_encoder->crtc == encoder->crtc) {
    193			pr_err("Can't enable LVDS and another encoder on the same pipe\n");
    194			return false;
    195		}
    196	}
    197
    198	/*
    199	 * If we have timings from the BIOS for the panel, put them in
    200	 * to the adjusted mode.  The CRTC will be set up for this mode,
    201	 * with the panel scaling set up to source from the H/VDisplay
    202	 * of the original mode.
    203	 */
    204	if (panel_fixed_mode != NULL) {
    205		adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;
    206		adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;
    207		adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;
    208		adjusted_mode->htotal = panel_fixed_mode->htotal;
    209		adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;
    210		adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;
    211		adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;
    212		adjusted_mode->vtotal = panel_fixed_mode->vtotal;
    213		adjusted_mode->clock = panel_fixed_mode->clock;
    214		drm_mode_set_crtcinfo(adjusted_mode,
    215				      CRTC_INTERLACE_HALVE_V);
    216	}
    217
    218	/*
    219	 * XXX: It would be nice to support lower refresh rates on the
    220	 * panels to reduce power consumption, and perhaps match the
    221	 * user's requested refresh rate.
    222	 */
    223
    224	return true;
    225}
    226
    227static void cdv_intel_lvds_prepare(struct drm_encoder *encoder)
    228{
    229	struct drm_device *dev = encoder->dev;
    230	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    231	struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
    232
    233	if (!gma_power_begin(dev, true))
    234		return;
    235
    236	mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
    237	mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
    238					  BACKLIGHT_DUTY_CYCLE_MASK);
    239
    240	cdv_intel_lvds_set_power(dev, encoder, false);
    241
    242	gma_power_end(dev);
    243}
    244
    245static void cdv_intel_lvds_commit(struct drm_encoder *encoder)
    246{
    247	struct drm_device *dev = encoder->dev;
    248	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    249	struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
    250
    251	if (mode_dev->backlight_duty_cycle == 0)
    252		mode_dev->backlight_duty_cycle =
    253		    cdv_intel_lvds_get_max_backlight(dev);
    254
    255	cdv_intel_lvds_set_power(dev, encoder, true);
    256}
    257
    258static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
    259				struct drm_display_mode *mode,
    260				struct drm_display_mode *adjusted_mode)
    261{
    262	struct drm_device *dev = encoder->dev;
    263	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    264	struct gma_crtc *gma_crtc = to_gma_crtc(encoder->crtc);
    265	u32 pfit_control;
    266
    267	/*
    268	 * The LVDS pin pair will already have been turned on in the
    269	 * cdv_intel_crtc_mode_set since it has a large impact on the DPLL
    270	 * settings.
    271	 */
    272
    273	/*
    274	 * Enable automatic panel scaling so that non-native modes fill the
    275	 * screen.  Should be enabled before the pipe is enabled, according to
    276	 * register description and PRM.
    277	 */
    278	if (mode->hdisplay != adjusted_mode->hdisplay ||
    279	    mode->vdisplay != adjusted_mode->vdisplay)
    280		pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
    281				HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
    282				HORIZ_INTERP_BILINEAR);
    283	else
    284		pfit_control = 0;
    285
    286	pfit_control |= gma_crtc->pipe << PFIT_PIPE_SHIFT;
    287
    288	if (dev_priv->lvds_dither)
    289		pfit_control |= PANEL_8TO6_DITHER_ENABLE;
    290
    291	REG_WRITE(PFIT_CONTROL, pfit_control);
    292}
    293
    294/*
    295 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
    296 */
    297static int cdv_intel_lvds_get_modes(struct drm_connector *connector)
    298{
    299	struct drm_device *dev = connector->dev;
    300	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    301	struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
    302	struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
    303	int ret;
    304
    305	ret = psb_intel_ddc_get_modes(connector, &gma_encoder->i2c_bus->adapter);
    306
    307	if (ret)
    308		return ret;
    309
    310	if (mode_dev->panel_fixed_mode != NULL) {
    311		struct drm_display_mode *mode =
    312		    drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
    313		drm_mode_probed_add(connector, mode);
    314		return 1;
    315	}
    316
    317	return 0;
    318}
    319
    320/**
    321 * cdv_intel_lvds_destroy - unregister and free LVDS structures
    322 * @connector: connector to free
    323 *
    324 * Unregister the DDC bus for this connector then free the driver private
    325 * structure.
    326 */
    327static void cdv_intel_lvds_destroy(struct drm_connector *connector)
    328{
    329	struct gma_connector *gma_connector = to_gma_connector(connector);
    330	struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
    331
    332	psb_intel_i2c_destroy(gma_encoder->i2c_bus);
    333	drm_connector_cleanup(connector);
    334	kfree(gma_connector);
    335}
    336
    337static int cdv_intel_lvds_set_property(struct drm_connector *connector,
    338				       struct drm_property *property,
    339				       uint64_t value)
    340{
    341	struct drm_encoder *encoder = connector->encoder;
    342
    343	if (!strcmp(property->name, "scaling mode") && encoder) {
    344		struct gma_crtc *crtc = to_gma_crtc(encoder->crtc);
    345		uint64_t curValue;
    346
    347		if (!crtc)
    348			return -1;
    349
    350		switch (value) {
    351		case DRM_MODE_SCALE_FULLSCREEN:
    352			break;
    353		case DRM_MODE_SCALE_NO_SCALE:
    354			break;
    355		case DRM_MODE_SCALE_ASPECT:
    356			break;
    357		default:
    358			return -1;
    359		}
    360
    361		if (drm_object_property_get_value(&connector->base,
    362						     property,
    363						     &curValue))
    364			return -1;
    365
    366		if (curValue == value)
    367			return 0;
    368
    369		if (drm_object_property_set_value(&connector->base,
    370							property,
    371							value))
    372			return -1;
    373
    374		if (crtc->saved_mode.hdisplay != 0 &&
    375		    crtc->saved_mode.vdisplay != 0) {
    376			if (!drm_crtc_helper_set_mode(encoder->crtc,
    377						      &crtc->saved_mode,
    378						      encoder->crtc->x,
    379						      encoder->crtc->y,
    380						      encoder->crtc->primary->fb))
    381				return -1;
    382		}
    383	} else if (!strcmp(property->name, "backlight") && encoder) {
    384		if (drm_object_property_set_value(&connector->base,
    385							property,
    386							value))
    387			return -1;
    388		else
    389                        gma_backlight_set(encoder->dev, value);
    390	} else if (!strcmp(property->name, "DPMS") && encoder) {
    391		const struct drm_encoder_helper_funcs *helpers =
    392					encoder->helper_private;
    393		helpers->dpms(encoder, value);
    394	}
    395	return 0;
    396}
    397
    398static const struct drm_encoder_helper_funcs
    399					cdv_intel_lvds_helper_funcs = {
    400	.dpms = cdv_intel_lvds_encoder_dpms,
    401	.mode_fixup = cdv_intel_lvds_mode_fixup,
    402	.prepare = cdv_intel_lvds_prepare,
    403	.mode_set = cdv_intel_lvds_mode_set,
    404	.commit = cdv_intel_lvds_commit,
    405};
    406
    407static const struct drm_connector_helper_funcs
    408				cdv_intel_lvds_connector_helper_funcs = {
    409	.get_modes = cdv_intel_lvds_get_modes,
    410	.mode_valid = cdv_intel_lvds_mode_valid,
    411	.best_encoder = gma_best_encoder,
    412};
    413
    414static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = {
    415	.dpms = drm_helper_connector_dpms,
    416	.fill_modes = drm_helper_probe_single_connector_modes,
    417	.set_property = cdv_intel_lvds_set_property,
    418	.destroy = cdv_intel_lvds_destroy,
    419};
    420
    421/*
    422 * Enumerate the child dev array parsed from VBT to check whether
    423 * the LVDS is present.
    424 * If it is present, return 1.
    425 * If it is not present, return false.
    426 * If no child dev is parsed from VBT, it assumes that the LVDS is present.
    427 */
    428static bool lvds_is_present_in_vbt(struct drm_device *dev,
    429				   u8 *i2c_pin)
    430{
    431	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    432	int i;
    433
    434	if (!dev_priv->child_dev_num)
    435		return true;
    436
    437	for (i = 0; i < dev_priv->child_dev_num; i++) {
    438		struct child_device_config *child = dev_priv->child_dev + i;
    439
    440		/* If the device type is not LFP, continue.
    441		 * We have to check both the new identifiers as well as the
    442		 * old for compatibility with some BIOSes.
    443		 */
    444		if (child->device_type != DEVICE_TYPE_INT_LFP &&
    445		    child->device_type != DEVICE_TYPE_LFP)
    446			continue;
    447
    448		if (child->i2c_pin)
    449		    *i2c_pin = child->i2c_pin;
    450
    451		/* However, we cannot trust the BIOS writers to populate
    452		 * the VBT correctly.  Since LVDS requires additional
    453		 * information from AIM blocks, a non-zero addin offset is
    454		 * a good indicator that the LVDS is actually present.
    455		 */
    456		if (child->addin_offset)
    457			return true;
    458
    459		/* But even then some BIOS writers perform some black magic
    460		 * and instantiate the device without reference to any
    461		 * additional data.  Trust that if the VBT was written into
    462		 * the OpRegion then they have validated the LVDS's existence.
    463		 */
    464		if (dev_priv->opregion.vbt)
    465			return true;
    466	}
    467
    468	return false;
    469}
    470
    471/**
    472 * cdv_intel_lvds_init - setup LVDS connectors on this device
    473 * @dev: drm device
    474 * @mode_dev: PSB mode device
    475 *
    476 * Create the connector, register the LVDS DDC bus, and try to figure out what
    477 * modes we can display on the LVDS panel (if present).
    478 */
    479void cdv_intel_lvds_init(struct drm_device *dev,
    480		     struct psb_intel_mode_device *mode_dev)
    481{
    482	struct gma_encoder *gma_encoder;
    483	struct gma_connector *gma_connector;
    484	struct cdv_intel_lvds_priv *lvds_priv;
    485	struct drm_connector *connector;
    486	struct drm_encoder *encoder;
    487	struct drm_display_mode *scan;
    488	struct drm_crtc *crtc;
    489	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
    490	u32 lvds;
    491	int pipe;
    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 failed_connector;
    512
    513	lvds_priv = kzalloc(sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL);
    514	if (!lvds_priv)
    515		goto failed_lvds_priv;
    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
    525	drm_connector_init(dev, connector,
    526			   &cdv_intel_lvds_connector_funcs,
    527			   DRM_MODE_CONNECTOR_LVDS);
    528
    529	drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_LVDS);
    530
    531	gma_connector_attach_encoder(gma_connector, gma_encoder);
    532	gma_encoder->type = INTEL_OUTPUT_LVDS;
    533
    534	drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs);
    535	drm_connector_helper_add(connector,
    536				 &cdv_intel_lvds_connector_helper_funcs);
    537	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
    538	connector->interlace_allowed = false;
    539	connector->doublescan_allowed = false;
    540
    541	/*Attach connector properties*/
    542	drm_object_attach_property(&connector->base,
    543				      dev->mode_config.scaling_mode_property,
    544				      DRM_MODE_SCALE_FULLSCREEN);
    545	drm_object_attach_property(&connector->base,
    546				      dev_priv->backlight_property,
    547				      BRIGHTNESS_MAX_LEVEL);
    548
    549	/**
    550	 * Set up I2C bus
    551	 * FIXME: distroy i2c_bus when exit
    552	 */
    553	gma_encoder->i2c_bus = psb_intel_i2c_create(dev,
    554							 GPIOB,
    555							 "LVDSBLC_B");
    556	if (!gma_encoder->i2c_bus) {
    557		dev_printk(KERN_ERR,
    558			dev->dev, "I2C bus registration failed.\n");
    559		goto failed_blc_i2c;
    560	}
    561	gma_encoder->i2c_bus->slave_addr = 0x2C;
    562	dev_priv->lvds_i2c_bus = gma_encoder->i2c_bus;
    563
    564	/*
    565	 * LVDS discovery:
    566	 * 1) check for EDID on DDC
    567	 * 2) check for VBT data
    568	 * 3) check to see if LVDS is already on
    569	 *    if none of the above, no panel
    570	 * 4) make sure lid is open
    571	 *    if closed, act like it's not there for now
    572	 */
    573
    574	/* Set up the DDC bus. */
    575	gma_encoder->ddc_bus = psb_intel_i2c_create(dev,
    576							 GPIOC,
    577							 "LVDSDDC_C");
    578	if (!gma_encoder->ddc_bus) {
    579		dev_printk(KERN_ERR, dev->dev,
    580			   "DDC bus registration " "failed.\n");
    581		goto failed_ddc;
    582	}
    583
    584	/*
    585	 * Attempt to get the fixed panel mode from DDC.  Assume that the
    586	 * preferred mode is the right one.
    587	 */
    588	mutex_lock(&dev->mode_config.mutex);
    589	psb_intel_ddc_get_modes(connector,
    590				&gma_encoder->ddc_bus->adapter);
    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 turned
    611	 * on.	If so, assume that whatever is currently programmed is the
    612	 * 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_DEBUG
    631			("Found no modes on the lvds, ignoring the LVDS\n");
    632		goto failed_find;
    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		else
    643			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
    652failed_find:
    653	mutex_unlock(&dev->mode_config.mutex);
    654	pr_err("Failed find\n");
    655	psb_intel_i2c_destroy(gma_encoder->ddc_bus);
    656failed_ddc:
    657	pr_err("Failed DDC\n");
    658	psb_intel_i2c_destroy(gma_encoder->i2c_bus);
    659failed_blc_i2c:
    660	pr_err("Failed BLC\n");
    661	drm_encoder_cleanup(encoder);
    662	drm_connector_cleanup(connector);
    663	kfree(lvds_priv);
    664failed_lvds_priv:
    665	kfree(gma_connector);
    666failed_connector:
    667	kfree(gma_encoder);
    668}