intel_lvds.c 32.5 KB
Newer Older
J
Jesse Barnes 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
 * Copyright © 2006-2007 Intel Corporation
 * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *	Eric Anholt <eric@anholt.net>
 *      Dave Airlie <airlied@linux.ie>
 *      Jesse Barnes <jesse.barnes@intel.com>
 */

30
#include <acpi/button.h>
31
#include <linux/dmi.h>
J
Jesse Barnes 已提交
32
#include <linux/i2c.h>
33
#include <linux/slab.h>
J
Jesse Barnes 已提交
34 35 36 37 38 39 40
#include "drmP.h"
#include "drm.h"
#include "drm_crtc.h"
#include "drm_edid.h"
#include "intel_drv.h"
#include "i915_drm.h"
#include "i915_drv.h"
41
#include <linux/acpi.h>
J
Jesse Barnes 已提交
42

43 44 45 46 47 48 49
/* Private structure for the integrated LVDS support */
struct intel_lvds_priv {
	int fitting_mode;
	u32 pfit_control;
	u32 pfit_pgm_ratios;
};

J
Jesse Barnes 已提交
50 51 52 53 54 55 56 57
/**
 * Sets the backlight level.
 *
 * \param level backlight level, from 0 to intel_lvds_get_max_backlight().
 */
static void intel_lvds_set_backlight(struct drm_device *dev, int level)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
58
	u32 blc_pwm_ctl, reg;
J
Jesse Barnes 已提交
59

60
	if (HAS_PCH_SPLIT(dev))
61 62 63
		reg = BLC_PWM_CPU_CTL;
	else
		reg = BLC_PWM_CTL;
J
Jesse Barnes 已提交
64

65 66
	blc_pwm_ctl = I915_READ(reg) & ~BACKLIGHT_DUTY_CYCLE_MASK;
	I915_WRITE(reg, (blc_pwm_ctl |
J
Jesse Barnes 已提交
67 68 69 70 71 72 73 74 75
				 (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
}

/**
 * Returns the maximum level of the backlight duty cycle field.
 */
static u32 intel_lvds_get_max_backlight(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
76 77
	u32 reg;

78
	if (HAS_PCH_SPLIT(dev))
79 80 81
		reg = BLC_PWM_PCH_CTL2;
	else
		reg = BLC_PWM_CTL;
J
Jesse Barnes 已提交
82

83
	return ((I915_READ(reg) & BACKLIGHT_MODULATION_FREQ_MASK) >>
J
Jesse Barnes 已提交
84 85 86 87 88 89 90 91 92
		BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
}

/**
 * Sets the power state for the panel.
 */
static void intel_lvds_set_power(struct drm_device *dev, bool on)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
93
	u32 pp_status, ctl_reg, status_reg, lvds_reg;
94

95
	if (HAS_PCH_SPLIT(dev)) {
96 97
		ctl_reg = PCH_PP_CONTROL;
		status_reg = PCH_PP_STATUS;
98
		lvds_reg = PCH_LVDS;
99 100 101
	} else {
		ctl_reg = PP_CONTROL;
		status_reg = PP_STATUS;
102
		lvds_reg = LVDS;
103
	}
J
Jesse Barnes 已提交
104 105

	if (on) {
106 107 108
		I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);
		POSTING_READ(lvds_reg);

109
		I915_WRITE(ctl_reg, I915_READ(ctl_reg) |
J
Jesse Barnes 已提交
110 111
			   POWER_TARGET_ON);
		do {
112
			pp_status = I915_READ(status_reg);
J
Jesse Barnes 已提交
113 114 115 116 117 118
		} while ((pp_status & PP_ON) == 0);

		intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle);
	} else {
		intel_lvds_set_backlight(dev, 0);

119
		I915_WRITE(ctl_reg, I915_READ(ctl_reg) &
J
Jesse Barnes 已提交
120 121
			   ~POWER_TARGET_ON);
		do {
122
			pp_status = I915_READ(status_reg);
J
Jesse Barnes 已提交
123
		} while (pp_status & PP_ON);
124 125 126

		I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
		POSTING_READ(lvds_reg);
J
Jesse Barnes 已提交
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
	}
}

static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
{
	struct drm_device *dev = encoder->dev;

	if (mode == DRM_MODE_DPMS_ON)
		intel_lvds_set_power(dev, true);
	else
		intel_lvds_set_power(dev, false);

	/* XXX: We never power down the LVDS pairs. */
}

static int intel_lvds_mode_valid(struct drm_connector *connector,
				 struct drm_display_mode *mode)
{
	struct drm_device *dev = connector->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode;

	if (fixed_mode)	{
		if (mode->hdisplay > fixed_mode->hdisplay)
			return MODE_PANEL;
		if (mode->vdisplay > fixed_mode->vdisplay)
			return MODE_PANEL;
	}

	return MODE_OK;
}

static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
				  struct drm_display_mode *mode,
				  struct drm_display_mode *adjusted_mode)
{
163 164 165 166 167 168
	/*
	 * float point operation is not supported . So the PANEL_RATIO_FACTOR
	 * is defined, which can avoid the float point computation when
	 * calculating the panel ratio.
	 */
#define PANEL_RATIO_FACTOR 8192
J
Jesse Barnes 已提交
169 170 171 172
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	struct drm_encoder *tmp_encoder;
173 174
	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
	struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
175 176 177 178 179 180
	u32 pfit_control = 0, pfit_pgm_ratios = 0;
	int left_border = 0, right_border = 0, top_border = 0;
	int bottom_border = 0;
	bool border = 0;
	int panel_ratio, desired_ratio, vert_scale, horiz_scale;
	int horiz_ratio, vert_ratio;
181 182 183
	u32 hsync_width, vsync_width;
	u32 hblank_width, vblank_width;
	u32 hsync_pos, vsync_pos;
J
Jesse Barnes 已提交
184 185 186

	/* Should never happen!! */
	if (!IS_I965G(dev) && intel_crtc->pipe == 0) {
187
		DRM_ERROR("Can't support LVDS on pipe A\n");
J
Jesse Barnes 已提交
188 189 190 191 192 193
		return false;
	}

	/* Should never happen!! */
	list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) {
		if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) {
194
			DRM_ERROR("Can't enable LVDS and another "
J
Jesse Barnes 已提交
195 196 197 198
			       "encoder on the same pipe\n");
			return false;
		}
	}
199 200 201
	/* If we don't have a panel mode, there is nothing we can do */
	if (dev_priv->panel_fixed_mode == NULL)
		return true;
J
Jesse Barnes 已提交
202
	/*
203
	 * We have timings from the BIOS for the panel, put them in
J
Jesse Barnes 已提交
204 205 206 207
	 * to the adjusted mode.  The CRTC will be set up for this mode,
	 * with the panel scaling set up to source from the H/VDisplay
	 * of the original mode.
	 */
208 209 210 211 212 213 214 215 216 217 218 219 220 221
	adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay;
	adjusted_mode->hsync_start =
		dev_priv->panel_fixed_mode->hsync_start;
	adjusted_mode->hsync_end =
		dev_priv->panel_fixed_mode->hsync_end;
	adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal;
	adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay;
	adjusted_mode->vsync_start =
		dev_priv->panel_fixed_mode->vsync_start;
	adjusted_mode->vsync_end =
		dev_priv->panel_fixed_mode->vsync_end;
	adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal;
	adjusted_mode->clock = dev_priv->panel_fixed_mode->clock;
	drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
J
Jesse Barnes 已提交
222

223 224 225 226 227 228 229 230 231 232 233 234 235 236
	/* Make sure pre-965s set dither correctly */
	if (!IS_I965G(dev)) {
		if (dev_priv->panel_wants_dither || dev_priv->lvds_dither)
			pfit_control |= PANEL_8TO6_DITHER_ENABLE;
	}

	/* Native modes don't need fitting */
	if (adjusted_mode->hdisplay == mode->hdisplay &&
			adjusted_mode->vdisplay == mode->vdisplay) {
		pfit_pgm_ratios = 0;
		border = 0;
		goto out;
	}

237
	/* full screen scale for now */
238
	if (HAS_PCH_SPLIT(dev))
239 240
		goto out;

241 242 243 244 245
	/* 965+ wants fuzzy fitting */
	if (IS_I965G(dev))
		pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) |
					PFIT_FILTER_FUZZY;

246 247 248 249 250 251 252 253
	hsync_width = adjusted_mode->crtc_hsync_end -
					adjusted_mode->crtc_hsync_start;
	vsync_width = adjusted_mode->crtc_vsync_end -
					adjusted_mode->crtc_vsync_start;
	hblank_width = adjusted_mode->crtc_hblank_end -
					adjusted_mode->crtc_hblank_start;
	vblank_width = adjusted_mode->crtc_vblank_end -
					adjusted_mode->crtc_vblank_start;
254 255 256 257 258 259 260 261 262 263 264 265 266 267
	/*
	 * Deal with panel fitting options. Figure out how to stretch the
	 * image based on its aspect ratio & the current panel fitting mode.
	 */
	panel_ratio = adjusted_mode->hdisplay * PANEL_RATIO_FACTOR /
				adjusted_mode->vdisplay;
	desired_ratio = mode->hdisplay * PANEL_RATIO_FACTOR /
				mode->vdisplay;
	/*
	 * Enable automatic panel scaling for non-native modes so that they fill
	 * the screen.  Should be enabled before the pipe is enabled, according
	 * to register description and PRM.
	 * Change the value here to see the borders for debugging
	 */
268
	if (!HAS_PCH_SPLIT(dev)) {
269 270 271
		I915_WRITE(BCLRPAT_A, 0);
		I915_WRITE(BCLRPAT_B, 0);
	}
272 273

	switch (lvds_priv->fitting_mode) {
274
	case DRM_MODE_SCALE_CENTER:
275 276 277 278 279 280 281 282 283 284 285 286 287 288
		/*
		 * For centered modes, we have to calculate border widths &
		 * heights and modify the values programmed into the CRTC.
		 */
		left_border = (adjusted_mode->hdisplay - mode->hdisplay) / 2;
		right_border = left_border;
		if (mode->hdisplay & 1)
			right_border++;
		top_border = (adjusted_mode->vdisplay - mode->vdisplay) / 2;
		bottom_border = top_border;
		if (mode->vdisplay & 1)
			bottom_border++;
		/* Set active & border values */
		adjusted_mode->crtc_hdisplay = mode->hdisplay;
289 290 291 292
		/* Keep the boder be even */
		if (right_border & 1)
			right_border++;
		/* use the border directly instead of border minuse one */
293
		adjusted_mode->crtc_hblank_start = mode->hdisplay +
294 295 296 297 298 299 300 301 302
						right_border;
		/* keep the blank width constant */
		adjusted_mode->crtc_hblank_end =
			adjusted_mode->crtc_hblank_start + hblank_width;
		/* get the hsync pos relative to hblank start */
		hsync_pos = (hblank_width - hsync_width) / 2;
		/* keep the hsync pos be even */
		if (hsync_pos & 1)
			hsync_pos++;
303
		adjusted_mode->crtc_hsync_start =
304 305
				adjusted_mode->crtc_hblank_start + hsync_pos;
		/* keep the hsync width constant */
306
		adjusted_mode->crtc_hsync_end =
307
				adjusted_mode->crtc_hsync_start + hsync_width;
308
		adjusted_mode->crtc_vdisplay = mode->vdisplay;
309
		/* use the border instead of border minus one */
310
		adjusted_mode->crtc_vblank_start = mode->vdisplay +
311 312 313 314 315 316
						bottom_border;
		/* keep the vblank width constant */
		adjusted_mode->crtc_vblank_end =
				adjusted_mode->crtc_vblank_start + vblank_width;
		/* get the vsync start postion relative to vblank start */
		vsync_pos = (vblank_width - vsync_width) / 2;
317
		adjusted_mode->crtc_vsync_start =
318 319
				adjusted_mode->crtc_vblank_start + vsync_pos;
		/* keep the vsync width constant */
320
		adjusted_mode->crtc_vsync_end =
321
				adjusted_mode->crtc_vsync_start + vsync_width;
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
		border = 1;
		break;
	case DRM_MODE_SCALE_ASPECT:
		/* Scale but preserve the spect ratio */
		pfit_control |= PFIT_ENABLE;
		if (IS_I965G(dev)) {
			/* 965+ is easy, it does everything in hw */
			if (panel_ratio > desired_ratio)
				pfit_control |= PFIT_SCALING_PILLAR;
			else if (panel_ratio < desired_ratio)
				pfit_control |= PFIT_SCALING_LETTER;
			else
				pfit_control |= PFIT_SCALING_AUTO;
		} else {
			/*
			 * For earlier chips we have to calculate the scaling
			 * ratio by hand and program it into the
			 * PFIT_PGM_RATIO register
			 */
			u32 horiz_bits, vert_bits, bits = 12;
			horiz_ratio = mode->hdisplay * PANEL_RATIO_FACTOR/
						adjusted_mode->hdisplay;
			vert_ratio = mode->vdisplay * PANEL_RATIO_FACTOR/
						adjusted_mode->vdisplay;
			horiz_scale = adjusted_mode->hdisplay *
					PANEL_RATIO_FACTOR / mode->hdisplay;
			vert_scale = adjusted_mode->vdisplay *
					PANEL_RATIO_FACTOR / mode->vdisplay;

			/* retain aspect ratio */
			if (panel_ratio > desired_ratio) { /* Pillar */
				u32 scaled_width;
				scaled_width = mode->hdisplay * vert_scale /
						PANEL_RATIO_FACTOR;
				horiz_ratio = vert_ratio;
				pfit_control |= (VERT_AUTO_SCALE |
						 VERT_INTERP_BILINEAR |
						 HORIZ_INTERP_BILINEAR);
				/* Pillar will have left/right borders */
				left_border = (adjusted_mode->hdisplay -
						scaled_width) / 2;
				right_border = left_border;
				if (mode->hdisplay & 1) /* odd resolutions */
					right_border++;
366 367 368
				/* keep the border be even */
				if (right_border & 1)
					right_border++;
369
				adjusted_mode->crtc_hdisplay = scaled_width;
370
				/* use border instead of border minus one */
371
				adjusted_mode->crtc_hblank_start =
372 373
					scaled_width + right_border;
				/* keep the hblank width constant */
374
				adjusted_mode->crtc_hblank_end =
375 376 377 378 379 380 381 382 383 384
					adjusted_mode->crtc_hblank_start +
							hblank_width;
				/*
				 * get the hsync start pos relative to
				 * hblank start
				 */
				hsync_pos = (hblank_width - hsync_width) / 2;
				/* keep the hsync_pos be even */
				if (hsync_pos & 1)
					hsync_pos++;
385
				adjusted_mode->crtc_hsync_start =
386 387 388
					adjusted_mode->crtc_hblank_start +
							hsync_pos;
				/* keept hsync width constant */
389
				adjusted_mode->crtc_hsync_end =
390 391
					adjusted_mode->crtc_hsync_start +
							hsync_width;
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
				border = 1;
			} else if (panel_ratio < desired_ratio) { /* letter */
				u32 scaled_height = mode->vdisplay *
					horiz_scale / PANEL_RATIO_FACTOR;
				vert_ratio = horiz_ratio;
				pfit_control |= (HORIZ_AUTO_SCALE |
						 VERT_INTERP_BILINEAR |
						 HORIZ_INTERP_BILINEAR);
				/* Letterbox will have top/bottom border */
				top_border = (adjusted_mode->vdisplay -
					scaled_height) / 2;
				bottom_border = top_border;
				if (mode->vdisplay & 1)
					bottom_border++;
				adjusted_mode->crtc_vdisplay = scaled_height;
407
				/* use border instead of border minus one */
408
				adjusted_mode->crtc_vblank_start =
409 410
					scaled_height + bottom_border;
				/* keep the vblank width constant */
411
				adjusted_mode->crtc_vblank_end =
412 413 414 415 416 417 418
					adjusted_mode->crtc_vblank_start +
							vblank_width;
				/*
				 * get the vsync start pos relative to
				 * vblank start
				 */
				vsync_pos = (vblank_width - vsync_width) / 2;
419
				adjusted_mode->crtc_vsync_start =
420 421 422
					adjusted_mode->crtc_vblank_start +
							vsync_pos;
				/* keep the vsync width constant */
423
				adjusted_mode->crtc_vsync_end =
424 425
					adjusted_mode->crtc_vsync_start +
							vsync_width;
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
				border = 1;
			} else {
			/* Aspects match, Let hw scale both directions */
				pfit_control |= (VERT_AUTO_SCALE |
						 HORIZ_AUTO_SCALE |
						 VERT_INTERP_BILINEAR |
						 HORIZ_INTERP_BILINEAR);
			}
			horiz_bits = (1 << bits) * horiz_ratio /
					PANEL_RATIO_FACTOR;
			vert_bits = (1 << bits) * vert_ratio /
					PANEL_RATIO_FACTOR;
			pfit_pgm_ratios =
				((vert_bits << PFIT_VERT_SCALE_SHIFT) &
						PFIT_VERT_SCALE_MASK) |
				((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) &
						PFIT_HORIZ_SCALE_MASK);
		}
		break;

	case DRM_MODE_SCALE_FULLSCREEN:
		/*
		 * Full scaling, even if it changes the aspect ratio.
		 * Fortunately this is all done for us in hw.
		 */
		pfit_control |= PFIT_ENABLE;
		if (IS_I965G(dev))
			pfit_control |= PFIT_SCALING_AUTO;
		else
			pfit_control |= (VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
					 VERT_INTERP_BILINEAR |
					 HORIZ_INTERP_BILINEAR);
		break;
	default:
		break;
	}

out:
	lvds_priv->pfit_control = pfit_control;
	lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios;
466 467 468 469 470 471 472 473
	/*
	 * When there exists the border, it means that the LVDS_BORDR
	 * should be enabled.
	 */
	if (border)
		dev_priv->lvds_border_bits |= LVDS_BORDER_ENABLE;
	else
		dev_priv->lvds_border_bits &= ~(LVDS_BORDER_ENABLE);
J
Jesse Barnes 已提交
474 475 476 477 478 479 480 481 482 483 484 485 486
	/*
	 * XXX: It would be nice to support lower refresh rates on the
	 * panels to reduce power consumption, and perhaps match the
	 * user's requested refresh rate.
	 */

	return true;
}

static void intel_lvds_prepare(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
487
	u32 reg;
J
Jesse Barnes 已提交
488

489
	if (HAS_PCH_SPLIT(dev))
490 491 492
		reg = BLC_PWM_CPU_CTL;
	else
		reg = BLC_PWM_CTL;
J
Jesse Barnes 已提交
493

494
	dev_priv->saveBLC_PWM_CTL = I915_READ(reg);
J
Jesse Barnes 已提交
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
	dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
				       BACKLIGHT_DUTY_CYCLE_MASK);

	intel_lvds_set_power(dev, false);
}

static void intel_lvds_commit( struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;

	if (dev_priv->backlight_duty_cycle == 0)
		dev_priv->backlight_duty_cycle =
			intel_lvds_get_max_backlight(dev);

	intel_lvds_set_power(dev, true);
}

static void intel_lvds_mode_set(struct drm_encoder *encoder,
				struct drm_display_mode *mode,
				struct drm_display_mode *adjusted_mode)
{
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
519 520
	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
	struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
J
Jesse Barnes 已提交
521 522 523 524 525 526 527

	/*
	 * The LVDS pin pair will already have been turned on in the
	 * intel_crtc_mode_set since it has a large impact on the DPLL
	 * settings.
	 */

528
	if (HAS_PCH_SPLIT(dev))
529 530
		return;

J
Jesse Barnes 已提交
531 532 533 534 535
	/*
	 * Enable automatic panel scaling so that non-native modes fill the
	 * screen.  Should be enabled before the pipe is enabled, according to
	 * register description and PRM.
	 */
536 537
	I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios);
	I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control);
J
Jesse Barnes 已提交
538 539 540 541 542
}

/**
 * Detect the LVDS connection.
 *
543 544 545
 * Since LVDS doesn't have hotlug, we use the lid as a proxy.  Open means
 * connected and closed means disconnected.  We also send hotplug events as
 * needed, using lid status notification from the input layer.
J
Jesse Barnes 已提交
546 547 548
 */
static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector)
{
549
	struct drm_device *dev = connector->dev;
550 551
	enum drm_connector_status status = connector_status_connected;

552 553 554
	/* ACPI lid methods were generally unreliable in this generation, so
	 * don't even bother.
	 */
555
	if (IS_GEN2(dev) || IS_GEN3(dev))
556 557
		return connector_status_connected;

558
	return status;
J
Jesse Barnes 已提交
559 560 561 562 563 564 565 566
}

/**
 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
 */
static int intel_lvds_get_modes(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;
567 568
	struct drm_encoder *encoder = intel_attached_encoder(connector);
	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
J
Jesse Barnes 已提交
569 570 571
	struct drm_i915_private *dev_priv = dev->dev_private;
	int ret = 0;

572
	if (dev_priv->lvds_edid_good) {
573
		ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
J
Jesse Barnes 已提交
574

575 576 577
		if (ret)
			return ret;
	}
J
Jesse Barnes 已提交
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599

	/* Didn't get an EDID, so
	 * Set wide sync ranges so we get all modes
	 * handed to valid_mode for checking
	 */
	connector->display_info.min_vfreq = 0;
	connector->display_info.max_vfreq = 200;
	connector->display_info.min_hfreq = 0;
	connector->display_info.max_hfreq = 200;

	if (dev_priv->panel_fixed_mode != NULL) {
		struct drm_display_mode *mode;

		mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
		drm_mode_probed_add(connector, mode);

		return 1;
	}

	return 0;
}

600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id)
{
	DRM_DEBUG_KMS("Skipping forced modeset for %s\n", id->ident);
	return 1;
}

/* The GPU hangs up on these systems if modeset is performed on LID open */
static const struct dmi_system_id intel_no_modeset_on_lid[] = {
	{
		.callback = intel_no_modeset_on_lid_dmi_callback,
		.ident = "Toshiba Tecra A11",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
			DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"),
		},
	},

	{ }	/* terminating entry */
};

620 621 622 623 624 625 626 627 628
/*
 * Lid events. Note the use of 'modeset_on_lid':
 *  - we set it on lid close, and reset it on open
 *  - we use it as a "only once" bit (ie we ignore
 *    duplicate events where it was already properly
 *    set/reset)
 *  - the suspend/resume paths will also set it to
 *    zero, since they restore the mode ("lid open").
 */
629 630 631 632 633 634
static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
			    void *unused)
{
	struct drm_i915_private *dev_priv =
		container_of(nb, struct drm_i915_private, lid_notifier);
	struct drm_device *dev = dev_priv->dev;
635
	struct drm_connector *connector = dev_priv->int_lvds_connector;
636

637 638 639 640 641 642
	/*
	 * check and update the status of LVDS connector after receiving
	 * the LID nofication event.
	 */
	if (connector)
		connector->status = connector->funcs->detect(connector);
643 644 645
	/* Don't force modeset on machines where it causes a GPU lockup */
	if (dmi_check_system(intel_no_modeset_on_lid))
		return NOTIFY_OK;
646 647 648
	if (!acpi_lid_open()) {
		dev_priv->modeset_on_lid = 1;
		return NOTIFY_OK;
649
	}
650

651 652 653 654 655 656 657 658
	if (!dev_priv->modeset_on_lid)
		return NOTIFY_OK;

	dev_priv->modeset_on_lid = 0;

	mutex_lock(&dev->mode_config.mutex);
	drm_helper_resume_force_mode(dev);
	mutex_unlock(&dev->mode_config.mutex);
659

660 661 662
	return NOTIFY_OK;
}

J
Jesse Barnes 已提交
663 664 665 666 667 668 669 670 671
/**
 * intel_lvds_destroy - unregister and free LVDS structures
 * @connector: connector to free
 *
 * Unregister the DDC bus for this connector then free the driver private
 * structure.
 */
static void intel_lvds_destroy(struct drm_connector *connector)
{
672 673
	struct drm_device *dev = connector->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
J
Jesse Barnes 已提交
674

675 676
	if (dev_priv->lid_notifier.notifier_call)
		acpi_lid_notifier_unregister(&dev_priv->lid_notifier);
J
Jesse Barnes 已提交
677 678 679 680 681
	drm_sysfs_connector_remove(connector);
	drm_connector_cleanup(connector);
	kfree(connector);
}

682 683 684 685
static int intel_lvds_set_property(struct drm_connector *connector,
				   struct drm_property *property,
				   uint64_t value)
{
686 687 688 689 690
	struct drm_device *dev = connector->dev;

	if (property == dev->mode_config.scaling_mode_property &&
				connector->encoder) {
		struct drm_crtc *crtc = connector->encoder->crtc;
691 692
		struct drm_encoder *encoder = connector->encoder;
		struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
693
		struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
694

695 696
		if (value == DRM_MODE_SCALE_NONE) {
			DRM_DEBUG_KMS("no scaling not supported\n");
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713
			return 0;
		}
		if (lvds_priv->fitting_mode == value) {
			/* the LVDS scaling property is not changed */
			return 0;
		}
		lvds_priv->fitting_mode = value;
		if (crtc && crtc->enabled) {
			/*
			 * If the CRTC is enabled, the display will be changed
			 * according to the new panel fitting mode.
			 */
			drm_crtc_helper_set_mode(crtc, &crtc->mode,
				crtc->x, crtc->y, crtc->fb);
		}
	}

714 715 716
	return 0;
}

J
Jesse Barnes 已提交
717 718 719 720 721 722 723 724 725 726 727
static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
	.dpms = intel_lvds_dpms,
	.mode_fixup = intel_lvds_mode_fixup,
	.prepare = intel_lvds_prepare,
	.mode_set = intel_lvds_mode_set,
	.commit = intel_lvds_commit,
};

static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
	.get_modes = intel_lvds_get_modes,
	.mode_valid = intel_lvds_mode_valid,
728
	.best_encoder = intel_attached_encoder,
J
Jesse Barnes 已提交
729 730 731
};

static const struct drm_connector_funcs intel_lvds_connector_funcs = {
732
	.dpms = drm_helper_connector_dpms,
J
Jesse Barnes 已提交
733 734
	.detect = intel_lvds_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
735
	.set_property = intel_lvds_set_property,
J
Jesse Barnes 已提交
736 737 738 739 740 741
	.destroy = intel_lvds_destroy,
};


static void intel_lvds_enc_destroy(struct drm_encoder *encoder)
{
742 743 744 745
	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);

	if (intel_encoder->ddc_bus)
		intel_i2c_destroy(intel_encoder->ddc_bus);
J
Jesse Barnes 已提交
746
	drm_encoder_cleanup(encoder);
747
	kfree(intel_encoder);
J
Jesse Barnes 已提交
748 749 750 751 752 753
}

static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
	.destroy = intel_lvds_enc_destroy,
};

754 755
static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
{
756
	DRM_DEBUG_KMS("Skipping LVDS initialization for %s\n", id->ident);
757 758
	return 1;
}
J
Jesse Barnes 已提交
759

760
/* These systems claim to have LVDS, but really don't */
761
static const struct dmi_system_id intel_no_lvds[] = {
762 763 764 765
	{
		.callback = intel_no_lvds_dmi_callback,
		.ident = "Apple Mac Mini (Core series)",
		.matches = {
766
			DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
767 768 769 770 771 772 773
			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
		},
	},
	{
		.callback = intel_no_lvds_dmi_callback,
		.ident = "Apple Mac Mini (Core 2 series)",
		.matches = {
774
			DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
			DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"),
		},
	},
	{
		.callback = intel_no_lvds_dmi_callback,
		.ident = "MSI IM-945GSE-A",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
			DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"),
		},
	},
	{
		.callback = intel_no_lvds_dmi_callback,
		.ident = "Dell Studio Hybrid",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
			DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"),
		},
	},
794 795 796 797 798 799 800 801
	{
		.callback = intel_no_lvds_dmi_callback,
		.ident = "AOpen Mini PC",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "AOpen"),
			DMI_MATCH(DMI_PRODUCT_NAME, "i965GMx-IF"),
		},
	},
802 803 804 805 806 807 808 809
	{
		.callback = intel_no_lvds_dmi_callback,
		.ident = "AOpen Mini PC MP915",
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
			DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"),
		},
	},
810 811 812 813 814 815 816
	{
		.callback = intel_no_lvds_dmi_callback,
		.ident = "Aopen i945GTt-VFA",
		.matches = {
			DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
		},
	},
817 818 819 820 821 822 823 824
	{
		.callback = intel_no_lvds_dmi_callback,
		.ident = "Clientron U800",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
			DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
		},
	},
825 826 827

	{ }	/* terminating entry */
};
J
Jesse Barnes 已提交
828

829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
/**
 * intel_find_lvds_downclock - find the reduced downclock for LVDS in EDID
 * @dev: drm device
 * @connector: LVDS connector
 *
 * Find the reduced downclock for LVDS in EDID.
 */
static void intel_find_lvds_downclock(struct drm_device *dev,
				struct drm_connector *connector)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_display_mode *scan, *panel_fixed_mode;
	int temp_downclock;

	panel_fixed_mode = dev_priv->panel_fixed_mode;
	temp_downclock = panel_fixed_mode->clock;

	mutex_lock(&dev->mode_config.mutex);
	list_for_each_entry(scan, &connector->probed_modes, head) {
		/*
		 * If one mode has the same resolution with the fixed_panel
		 * mode while they have the different refresh rate, it means
		 * that the reduced downclock is found for the LVDS. In such
		 * case we can set the different FPx0/1 to dynamically select
		 * between low and high frequency.
		 */
		if (scan->hdisplay == panel_fixed_mode->hdisplay &&
			scan->hsync_start == panel_fixed_mode->hsync_start &&
			scan->hsync_end == panel_fixed_mode->hsync_end &&
			scan->htotal == panel_fixed_mode->htotal &&
			scan->vdisplay == panel_fixed_mode->vdisplay &&
			scan->vsync_start == panel_fixed_mode->vsync_start &&
			scan->vsync_end == panel_fixed_mode->vsync_end &&
			scan->vtotal == panel_fixed_mode->vtotal) {
			if (scan->clock < temp_downclock) {
				/*
				 * The downclock is already found. But we
				 * expect to find the lower downclock.
				 */
				temp_downclock = scan->clock;
			}
		}
	}
	mutex_unlock(&dev->mode_config.mutex);
873 874
	if (temp_downclock < panel_fixed_mode->clock &&
	    i915_lvds_downclock) {
875 876 877 878 879 880 881 882 883 884
		/* We found the downclock for LVDS. */
		dev_priv->lvds_downclock_avail = 1;
		dev_priv->lvds_downclock = temp_downclock;
		DRM_DEBUG_KMS("LVDS downclock is found in EDID. "
				"Normal clock %dKhz, downclock %dKhz\n",
				panel_fixed_mode->clock, temp_downclock);
	}
	return;
}

885 886 887 888 889 890 891 892 893
/*
 * Enumerate the child dev array parsed from VBT to check whether
 * the LVDS is present.
 * If it is present, return 1.
 * If it is not present, return false.
 * If no child dev is parsed from VBT, it assumes that the LVDS is present.
 * Note: The addin_offset should also be checked for LVDS panel.
 * Only when it is non-zero, it is assumed that it is present.
 */
894
static int lvds_is_present_in_vbt(struct drm_device *dev)
895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct child_device_config *p_child;
	int i, ret;

	if (!dev_priv->child_dev_num)
		return 1;

	ret = 0;
	for (i = 0; i < dev_priv->child_dev_num; i++) {
		p_child = dev_priv->child_dev + i;
		/*
		 * If the device type is not LFP, continue.
		 * If the device type is 0x22, it is also regarded as LFP.
		 */
		if (p_child->device_type != DEVICE_TYPE_INT_LFP &&
			p_child->device_type != DEVICE_TYPE_LFP)
			continue;

		/* The addin_offset should be checked. Only when it is
		 * non-zero, it is regarded as present.
		 */
		if (p_child->addin_offset) {
			ret = 1;
			break;
		}
	}
	return ret;
}

J
Jesse Barnes 已提交
925 926 927 928 929 930 931 932 933 934
/**
 * intel_lvds_init - setup LVDS connectors on this device
 * @dev: drm device
 *
 * Create the connector, register the LVDS DDC bus, and try to figure out what
 * modes we can display on the LVDS panel (if present).
 */
void intel_lvds_init(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
935
	struct intel_encoder *intel_encoder;
936
	struct intel_connector *intel_connector;
J
Jesse Barnes 已提交
937 938 939 940
	struct drm_connector *connector;
	struct drm_encoder *encoder;
	struct drm_display_mode *scan; /* *modes, *bios_mode; */
	struct drm_crtc *crtc;
941
	struct intel_lvds_priv *lvds_priv;
J
Jesse Barnes 已提交
942
	u32 lvds;
943
	int pipe, gpio = GPIOC;
J
Jesse Barnes 已提交
944

945 946
	/* Skip init on machines we know falsely report LVDS */
	if (dmi_check_system(intel_no_lvds))
947 948
		return;

949 950
	if (!lvds_is_present_in_vbt(dev)) {
		DRM_DEBUG_KMS("LVDS is not present in VBT\n");
951
		return;
A
Adam Jackson 已提交
952
	}
953

954
	if (HAS_PCH_SPLIT(dev)) {
955 956
		if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
			return;
957
		if (dev_priv->edp_support) {
958
			DRM_DEBUG_KMS("disable LVDS for eDP support\n");
959 960
			return;
		}
961 962 963
		gpio = PCH_GPIOC;
	}

964
	intel_encoder = kzalloc(sizeof(struct intel_encoder) +
965
				sizeof(struct intel_lvds_priv), GFP_KERNEL);
966
	if (!intel_encoder) {
J
Jesse Barnes 已提交
967 968 969
		return;
	}

970 971 972 973 974 975 976
	intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
	if (!intel_connector) {
		kfree(intel_encoder);
		return;
	}

	connector = &intel_connector->base;
977
	encoder = &intel_encoder->enc;
978
	drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs,
J
Jesse Barnes 已提交
979 980
			   DRM_MODE_CONNECTOR_LVDS);

981
	drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs,
J
Jesse Barnes 已提交
982 983
			 DRM_MODE_ENCODER_LVDS);

984
	drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc);
985
	intel_encoder->type = INTEL_OUTPUT_LVDS;
J
Jesse Barnes 已提交
986

987 988
	intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
	intel_encoder->crtc_mask = (1 << 1);
989 990
	if (IS_I965G(dev))
		intel_encoder->crtc_mask |= (1 << 0);
J
Jesse Barnes 已提交
991 992 993 994 995 996
	drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
	drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
	connector->interlace_allowed = false;
	connector->doublescan_allowed = false;

997 998
	lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1);
	intel_encoder->dev_priv = lvds_priv;
999 1000 1001 1002 1003
	/* create the scaling mode property */
	drm_mode_create_scaling_mode_property(dev);
	/*
	 * the initial panel fitting mode will be FULL_SCREEN.
	 */
J
Jesse Barnes 已提交
1004

1005
	drm_connector_attach_property(&intel_connector->base,
1006
				      dev->mode_config.scaling_mode_property,
1007 1008
				      DRM_MODE_SCALE_ASPECT);
	lvds_priv->fitting_mode = DRM_MODE_SCALE_ASPECT;
J
Jesse Barnes 已提交
1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
	/*
	 * LVDS discovery:
	 * 1) check for EDID on DDC
	 * 2) check for VBT data
	 * 3) check to see if LVDS is already on
	 *    if none of the above, no panel
	 * 4) make sure lid is open
	 *    if closed, act like it's not there for now
	 */

	/* Set up the DDC bus. */
1020 1021
	intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
	if (!intel_encoder->ddc_bus) {
J
Jesse Barnes 已提交
1022 1023 1024 1025 1026 1027 1028 1029 1030
		dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
			   "failed.\n");
		goto failed;
	}

	/*
	 * Attempt to get the fixed panel mode from DDC.  Assume that the
	 * preferred mode is the right one.
	 */
1031 1032
	dev_priv->lvds_edid_good = true;

1033
	if (!intel_ddc_get_modes(connector, intel_encoder->ddc_bus))
1034
		dev_priv->lvds_edid_good = false;
J
Jesse Barnes 已提交
1035 1036 1037 1038 1039 1040 1041

	list_for_each_entry(scan, &connector->probed_modes, head) {
		mutex_lock(&dev->mode_config.mutex);
		if (scan->type & DRM_MODE_TYPE_PREFERRED) {
			dev_priv->panel_fixed_mode =
				drm_mode_duplicate(dev, scan);
			mutex_unlock(&dev->mode_config.mutex);
1042
			intel_find_lvds_downclock(dev, connector);
1043
			goto out;
J
Jesse Barnes 已提交
1044 1045 1046 1047 1048
		}
		mutex_unlock(&dev->mode_config.mutex);
	}

	/* Failed to get EDID, what about VBT? */
1049
	if (dev_priv->lfp_lvds_vbt_mode) {
J
Jesse Barnes 已提交
1050 1051
		mutex_lock(&dev->mode_config.mutex);
		dev_priv->panel_fixed_mode =
1052
			drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
J
Jesse Barnes 已提交
1053
		mutex_unlock(&dev->mode_config.mutex);
1054 1055 1056 1057 1058
		if (dev_priv->panel_fixed_mode) {
			dev_priv->panel_fixed_mode->type |=
				DRM_MODE_TYPE_PREFERRED;
			goto out;
		}
J
Jesse Barnes 已提交
1059 1060 1061 1062 1063 1064 1065
	}

	/*
	 * If we didn't get EDID, try checking if the panel is already turned
	 * on.  If so, assume that whatever is currently programmed is the
	 * correct mode.
	 */
1066

1067
	/* Ironlake: FIXME if still fail, not try pipe mode now */
1068
	if (HAS_PCH_SPLIT(dev))
1069 1070
		goto failed;

J
Jesse Barnes 已提交
1071 1072 1073 1074 1075 1076 1077 1078 1079
	lvds = I915_READ(LVDS);
	pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
	crtc = intel_get_crtc_from_pipe(dev, pipe);

	if (crtc && (lvds & LVDS_PORT_EN)) {
		dev_priv->panel_fixed_mode = intel_crtc_mode_get(dev, crtc);
		if (dev_priv->panel_fixed_mode) {
			dev_priv->panel_fixed_mode->type |=
				DRM_MODE_TYPE_PREFERRED;
1080
			goto out;
J
Jesse Barnes 已提交
1081 1082 1083 1084 1085 1086 1087 1088
		}
	}

	/* If we still don't have a mode after all that, give up. */
	if (!dev_priv->panel_fixed_mode)
		goto failed;

out:
1089
	if (HAS_PCH_SPLIT(dev)) {
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
		u32 pwm;
		/* make sure PWM is enabled */
		pwm = I915_READ(BLC_PWM_CPU_CTL2);
		pwm |= (PWM_ENABLE | PWM_PIPE_B);
		I915_WRITE(BLC_PWM_CPU_CTL2, pwm);

		pwm = I915_READ(BLC_PWM_PCH_CTL1);
		pwm |= PWM_PCH_ENABLE;
		I915_WRITE(BLC_PWM_PCH_CTL1, pwm);
	}
1100 1101
	dev_priv->lid_notifier.notifier_call = intel_lid_notify;
	if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) {
1102
		DRM_DEBUG_KMS("lid notifier registration failed\n");
1103 1104
		dev_priv->lid_notifier.notifier_call = NULL;
	}
1105 1106
	/* keep the LVDS connector */
	dev_priv->int_lvds_connector = connector;
J
Jesse Barnes 已提交
1107 1108 1109 1110
	drm_sysfs_connector_add(connector);
	return;

failed:
1111
	DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
1112 1113
	if (intel_encoder->ddc_bus)
		intel_i2c_destroy(intel_encoder->ddc_bus);
J
Jesse Barnes 已提交
1114
	drm_connector_cleanup(connector);
1115
	drm_encoder_cleanup(encoder);
1116
	kfree(intel_encoder);
1117
	kfree(intel_connector);
J
Jesse Barnes 已提交
1118
}