File Index
Files and directories
Sign in
FILE

cdv_intel_lvds.c

File preview with syntax highlighting.

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