intel_panel.c 52.9 KB
Newer Older
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 30
/*
 * Copyright © 2006-2010 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>
 *      Chris Wilson <chris@chris-wilson.co.uk>
 */

31 32
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

33
#include <linux/kernel.h>
34
#include <linux/moduleparam.h>
35
#include <linux/pwm.h>
36 37
#include "intel_drv.h"

38 39
#define CRC_PMIC_PWM_PERIOD_NS	21333

40
void
41
intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
42 43
		       struct drm_display_mode *adjusted_mode)
{
44
	drm_mode_copy(adjusted_mode, fixed_mode);
45 46

	drm_mode_set_crtcinfo(adjusted_mode, 0);
47 48
}

J
Jani Nikula 已提交
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
/**
 * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID
 * @dev: drm device
 * @fixed_mode : panel native mode
 * @connector: LVDS/eDP connector
 *
 * Return downclock_avail
 * Find the reduced downclock for LVDS/eDP in EDID.
 */
struct drm_display_mode *
intel_find_panel_downclock(struct drm_device *dev,
			struct drm_display_mode *fixed_mode,
			struct drm_connector *connector)
{
	struct drm_display_mode *scan, *tmp_mode;
	int temp_downclock;

	temp_downclock = fixed_mode->clock;
	tmp_mode = NULL;

	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. In such
		 * case we can set the different FPx0/1 to dynamically select
		 * between low and high frequency.
		 */
		if (scan->hdisplay == fixed_mode->hdisplay &&
		    scan->hsync_start == fixed_mode->hsync_start &&
		    scan->hsync_end == fixed_mode->hsync_end &&
		    scan->htotal == fixed_mode->htotal &&
		    scan->vdisplay == fixed_mode->vdisplay &&
		    scan->vsync_start == fixed_mode->vsync_start &&
		    scan->vsync_end == fixed_mode->vsync_end &&
		    scan->vtotal == 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;
				tmp_mode = scan;
			}
		}
	}

	if (temp_downclock < fixed_mode->clock)
		return drm_mode_duplicate(dev, tmp_mode);
	else
		return NULL;
}

102 103
/* adjusted_mode has been preset to be the panel's fixed mode */
void
104
intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
105
			struct intel_crtc_state *pipe_config,
106
			int fitting_mode)
107
{
108 109
	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
	int x = 0, y = 0, width = 0, height = 0;
110 111

	/* Native modes don't need fitting */
112 113
	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
114 115 116 117
		goto done;

	switch (fitting_mode) {
	case DRM_MODE_SCALE_CENTER:
118 119
		width = pipe_config->pipe_src_w;
		height = pipe_config->pipe_src_h;
120 121
		x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
		y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
122 123 124 125 126
		break;

	case DRM_MODE_SCALE_ASPECT:
		/* Scale but preserve the aspect ratio */
		{
127
			u32 scaled_width = adjusted_mode->crtc_hdisplay
128 129
				* pipe_config->pipe_src_h;
			u32 scaled_height = pipe_config->pipe_src_w
130
				* adjusted_mode->crtc_vdisplay;
131
			if (scaled_width > scaled_height) { /* pillar */
132
				width = scaled_height / pipe_config->pipe_src_h;
133
				if (width & 1)
134
					width++;
135
				x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
136
				y = 0;
137
				height = adjusted_mode->crtc_vdisplay;
138
			} else if (scaled_width < scaled_height) { /* letter */
139
				height = scaled_width / pipe_config->pipe_src_w;
140 141
				if (height & 1)
				    height++;
142
				y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
143
				x = 0;
144
				width = adjusted_mode->crtc_hdisplay;
145 146
			} else {
				x = y = 0;
147 148
				width = adjusted_mode->crtc_hdisplay;
				height = adjusted_mode->crtc_vdisplay;
149 150 151 152 153 154
			}
		}
		break;

	case DRM_MODE_SCALE_FULLSCREEN:
		x = y = 0;
155 156
		width = adjusted_mode->crtc_hdisplay;
		height = adjusted_mode->crtc_vdisplay;
157
		break;
158 159 160 161

	default:
		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
		return;
162 163 164
	}

done:
165 166
	pipe_config->pch_pfit.pos = (x << 16) | y;
	pipe_config->pch_pfit.size = (width << 16) | height;
167
	pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0;
168
}
169

170
static void
171
centre_horizontally(struct drm_display_mode *adjusted_mode,
172 173 174 175 176
		    int width)
{
	u32 border, sync_pos, blank_width, sync_width;

	/* keep the hsync and hblank widths constant */
177 178
	sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
	blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
179 180
	sync_pos = (blank_width - sync_width + 1) / 2;

181
	border = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
182 183
	border += border & 1; /* make the border even */

184 185 186
	adjusted_mode->crtc_hdisplay = width;
	adjusted_mode->crtc_hblank_start = width + border;
	adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width;
187

188 189
	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos;
	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width;
190 191 192
}

static void
193
centre_vertically(struct drm_display_mode *adjusted_mode,
194 195 196 197 198
		  int height)
{
	u32 border, sync_pos, blank_width, sync_width;

	/* keep the vsync and vblank widths constant */
199 200
	sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
	blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start;
201 202
	sync_pos = (blank_width - sync_width + 1) / 2;

203
	border = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
204

205 206 207
	adjusted_mode->crtc_vdisplay = height;
	adjusted_mode->crtc_vblank_start = height + border;
	adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width;
208

209 210
	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos;
	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + sync_width;
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
}

static inline u32 panel_fitter_scaling(u32 source, u32 target)
{
	/*
	 * Floating point operation is not supported. So the FACTOR
	 * is defined, which can avoid the floating point computation
	 * when calculating the panel ratio.
	 */
#define ACCURACY 12
#define FACTOR (1 << ACCURACY)
	u32 ratio = source * FACTOR / target;
	return (FACTOR * ratio + FACTOR/2) / FACTOR;
}

226
static void i965_scale_aspect(struct intel_crtc_state *pipe_config,
227 228
			      u32 *pfit_control)
{
229
	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
230
	u32 scaled_width = adjusted_mode->crtc_hdisplay *
231 232
		pipe_config->pipe_src_h;
	u32 scaled_height = pipe_config->pipe_src_w *
233
		adjusted_mode->crtc_vdisplay;
234 235 236 237 238 239 240 241

	/* 965+ is easy, it does everything in hw */
	if (scaled_width > scaled_height)
		*pfit_control |= PFIT_ENABLE |
			PFIT_SCALING_PILLAR;
	else if (scaled_width < scaled_height)
		*pfit_control |= PFIT_ENABLE |
			PFIT_SCALING_LETTER;
242
	else if (adjusted_mode->crtc_hdisplay != pipe_config->pipe_src_w)
243 244 245
		*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
}

246
static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config,
247 248 249
			      u32 *pfit_control, u32 *pfit_pgm_ratios,
			      u32 *border)
{
250
	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
251
	u32 scaled_width = adjusted_mode->crtc_hdisplay *
252 253
		pipe_config->pipe_src_h;
	u32 scaled_height = pipe_config->pipe_src_w *
254
		adjusted_mode->crtc_vdisplay;
255 256 257 258 259 260 261 262 263 264 265 266 267
	u32 bits;

	/*
	 * For earlier chips we have to calculate the scaling
	 * ratio by hand and program it into the
	 * PFIT_PGM_RATIO register
	 */
	if (scaled_width > scaled_height) { /* pillar */
		centre_horizontally(adjusted_mode,
				    scaled_height /
				    pipe_config->pipe_src_h);

		*border = LVDS_BORDER_ENABLE;
268
		if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay) {
269
			bits = panel_fitter_scaling(pipe_config->pipe_src_h,
270
						    adjusted_mode->crtc_vdisplay);
271 272 273 274 275 276 277 278 279 280 281 282 283

			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
					     bits << PFIT_VERT_SCALE_SHIFT);
			*pfit_control |= (PFIT_ENABLE |
					  VERT_INTERP_BILINEAR |
					  HORIZ_INTERP_BILINEAR);
		}
	} else if (scaled_width < scaled_height) { /* letter */
		centre_vertically(adjusted_mode,
				  scaled_width /
				  pipe_config->pipe_src_w);

		*border = LVDS_BORDER_ENABLE;
284
		if (pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) {
285
			bits = panel_fitter_scaling(pipe_config->pipe_src_w,
286
						    adjusted_mode->crtc_hdisplay);
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302

			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
					     bits << PFIT_VERT_SCALE_SHIFT);
			*pfit_control |= (PFIT_ENABLE |
					  VERT_INTERP_BILINEAR |
					  HORIZ_INTERP_BILINEAR);
		}
	} else {
		/* Aspects match, Let hw scale both directions */
		*pfit_control |= (PFIT_ENABLE |
				  VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
				  VERT_INTERP_BILINEAR |
				  HORIZ_INTERP_BILINEAR);
	}
}

303
void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
304
			      struct intel_crtc_state *pipe_config,
305 306 307 308
			      int fitting_mode)
{
	struct drm_device *dev = intel_crtc->base.dev;
	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
309
	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
310 311

	/* Native modes don't need fitting */
312 313
	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
314 315 316 317 318 319 320 321
		goto out;

	switch (fitting_mode) {
	case DRM_MODE_SCALE_CENTER:
		/*
		 * For centered modes, we have to calculate border widths &
		 * heights and modify the values programmed into the CRTC.
		 */
322 323
		centre_horizontally(adjusted_mode, pipe_config->pipe_src_w);
		centre_vertically(adjusted_mode, pipe_config->pipe_src_h);
324 325 326 327
		border = LVDS_BORDER_ENABLE;
		break;
	case DRM_MODE_SCALE_ASPECT:
		/* Scale but preserve the aspect ratio */
328 329 330 331 332
		if (INTEL_INFO(dev)->gen >= 4)
			i965_scale_aspect(pipe_config, &pfit_control);
		else
			i9xx_scale_aspect(pipe_config, &pfit_control,
					  &pfit_pgm_ratios, &border);
333 334 335 336 337 338
		break;
	case DRM_MODE_SCALE_FULLSCREEN:
		/*
		 * Full scaling, even if it changes the aspect ratio.
		 * Fortunately this is all done for us in hw.
		 */
339 340
		if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay ||
		    pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) {
341 342 343 344 345 346 347 348 349 350
			pfit_control |= PFIT_ENABLE;
			if (INTEL_INFO(dev)->gen >= 4)
				pfit_control |= PFIT_SCALING_AUTO;
			else
				pfit_control |= (VERT_AUTO_SCALE |
						 VERT_INTERP_BILINEAR |
						 HORIZ_AUTO_SCALE |
						 HORIZ_INTERP_BILINEAR);
		}
		break;
351 352 353
	default:
		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
		return;
354 355 356 357 358 359 360 361 362 363 364 365 366 367
	}

	/* 965+ wants fuzzy fitting */
	/* FIXME: handle multiple panels by failing gracefully */
	if (INTEL_INFO(dev)->gen >= 4)
		pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
				 PFIT_FILTER_FUZZY);

out:
	if ((pfit_control & PFIT_ENABLE) == 0) {
		pfit_control = 0;
		pfit_pgm_ratios = 0;
	}

368 369 370 371
	/* Make sure pre-965 set dither correctly for 18bpp panels. */
	if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18)
		pfit_control |= PANEL_8TO6_DITHER_ENABLE;

372 373
	pipe_config->gmch_pfit.control = pfit_control;
	pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
374
	pipe_config->gmch_pfit.lvds_border_bits = border;
375 376
}

J
Jani Nikula 已提交
377 378 379
enum drm_connector_status
intel_panel_detect(struct drm_device *dev)
{
380
	struct drm_i915_private *dev_priv = to_i915(dev);
J
Jani Nikula 已提交
381 382 383

	/* Assume that the BIOS does not lie through the OpRegion... */
	if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) {
384
		return *dev_priv->opregion.lid_state & 0x1 ?
J
Jani Nikula 已提交
385 386 387 388 389 390 391 392 393 394 395 396 397 398
			connector_status_connected :
			connector_status_disconnected;
	}

	switch (i915.panel_ignore_lid) {
	case -2:
		return connector_status_connected;
	case -1:
		return connector_status_disconnected;
	default:
		return connector_status_unknown;
	}
}

399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
/**
 * scale - scale values from one range to another
 *
 * @source_val: value in range [@source_min..@source_max]
 *
 * Return @source_val in range [@source_min..@source_max] scaled to range
 * [@target_min..@target_max].
 */
static uint32_t scale(uint32_t source_val,
		      uint32_t source_min, uint32_t source_max,
		      uint32_t target_min, uint32_t target_max)
{
	uint64_t target_val;

	WARN_ON(source_min > source_max);
	WARN_ON(target_min > target_max);

	/* defensive */
	source_val = clamp(source_val, source_min, source_max);

	/* avoid overflows */
420 421
	target_val = DIV_ROUND_CLOSEST_ULL((uint64_t)(source_val - source_min) *
			(target_max - target_min), source_max - source_min);
422 423 424 425 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
	target_val += target_min;

	return target_val;
}

/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */
static inline u32 scale_user_to_hw(struct intel_connector *connector,
				   u32 user_level, u32 user_max)
{
	struct intel_panel *panel = &connector->panel;

	return scale(user_level, 0, user_max,
		     panel->backlight.min, panel->backlight.max);
}

/* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result
 * to [hw_min..hw_max]. */
static inline u32 clamp_user_to_hw(struct intel_connector *connector,
				   u32 user_level, u32 user_max)
{
	struct intel_panel *panel = &connector->panel;
	u32 hw_level;

	hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max);
	hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max);

	return hw_level;
}

/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */
static inline u32 scale_hw_to_user(struct intel_connector *connector,
				   u32 hw_level, u32 user_max)
{
	struct intel_panel *panel = &connector->panel;

	return scale(hw_level, panel->backlight.min, panel->backlight.max,
		     0, user_max);
}

461 462
static u32 intel_panel_compute_brightness(struct intel_connector *connector,
					  u32 val)
463
{
464
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
465 466 467
	struct intel_panel *panel = &connector->panel;

	WARN_ON(panel->backlight.max == 0);
468

469
	if (i915.invert_brightness < 0)
470 471
		return val;

472
	if (i915.invert_brightness > 0 ||
473
	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
474
		return panel->backlight.max - val;
475
	}
476 477 478 479

	return val;
}

480
static u32 lpt_get_backlight(struct intel_connector *connector)
481
{
482
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
483

484 485
	return I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
}
486

487
static u32 pch_get_backlight(struct intel_connector *connector)
488
{
489
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
490

491 492
	return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
}
493

494 495
static u32 i9xx_get_backlight(struct intel_connector *connector)
{
496
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
497
	struct intel_panel *panel = &connector->panel;
498
	u32 val;
499

500
	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
501
	if (INTEL_INFO(dev_priv)->gen < 4)
502
		val >>= 1;
503

504
	if (panel->backlight.combination_mode) {
505
		u8 lbpc;
506

507
		pci_read_config_byte(dev_priv->drm.pdev, LBPC, &lbpc);
508
		val *= lbpc;
509 510
	}

511 512 513
	return val;
}

514
static u32 _vlv_get_backlight(struct drm_i915_private *dev_priv, enum pipe pipe)
515
{
516 517 518
	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
		return 0;

519 520 521 522 523
	return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
}

static u32 vlv_get_backlight(struct intel_connector *connector)
{
524
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
525 526
	enum pipe pipe = intel_get_pipe_from_connector(connector);

527
	return _vlv_get_backlight(dev_priv, pipe);
528 529
}

530 531
static u32 bxt_get_backlight(struct intel_connector *connector)
{
532
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
533
	struct intel_panel *panel = &connector->panel;
534

535
	return I915_READ(BXT_BLC_PWM_DUTY(panel->backlight.controller));
536 537
}

538 539 540 541 542 543 544 545 546
static u32 pwm_get_backlight(struct intel_connector *connector)
{
	struct intel_panel *panel = &connector->panel;
	int duty_ns;

	duty_ns = pwm_get_duty_cycle(panel->backlight.pwm);
	return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS);
}

547 548
static u32 intel_panel_get_backlight(struct intel_connector *connector)
{
549
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
550 551
	struct intel_panel *panel = &connector->panel;
	u32 val = 0;
552

553
	mutex_lock(&dev_priv->backlight_lock);
554

555
	if (panel->backlight.enabled) {
556
		val = panel->backlight.get(connector);
557 558
		val = intel_panel_compute_brightness(connector, val);
	}
559

560
	mutex_unlock(&dev_priv->backlight_lock);
561

562 563 564 565
	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
	return val;
}

566
static void lpt_set_backlight(struct intel_connector *connector, u32 level)
567
{
568
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
569 570 571 572
	u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
	I915_WRITE(BLC_PWM_PCH_CTL2, val | level);
}

573
static void pch_set_backlight(struct intel_connector *connector, u32 level)
574
{
575
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
576 577 578 579
	u32 tmp;

	tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
	I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
580 581
}

582
static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
583
{
584
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
585
	struct intel_panel *panel = &connector->panel;
586
	u32 tmp, mask;
587

588 589
	WARN_ON(panel->backlight.max == 0);

590
	if (panel->backlight.combination_mode) {
591 592
		u8 lbpc;

593
		lbpc = level * 0xfe / panel->backlight.max + 1;
594
		level /= lbpc;
595
		pci_write_config_byte(dev_priv->drm.pdev, LBPC, lbpc);
596 597
	}

598
	if (IS_GEN4(dev_priv)) {
599 600
		mask = BACKLIGHT_DUTY_CYCLE_MASK;
	} else {
601
		level <<= 1;
602 603
		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
	}
604

605
	tmp = I915_READ(BLC_PWM_CTL) & ~mask;
606 607 608 609 610
	I915_WRITE(BLC_PWM_CTL, tmp | level);
}

static void vlv_set_backlight(struct intel_connector *connector, u32 level)
{
611
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
612 613 614
	enum pipe pipe = intel_get_pipe_from_connector(connector);
	u32 tmp;

615 616 617
	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
		return;

618 619 620 621
	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
}

622 623
static void bxt_set_backlight(struct intel_connector *connector, u32 level)
{
624
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
625
	struct intel_panel *panel = &connector->panel;
626

627
	I915_WRITE(BXT_BLC_PWM_DUTY(panel->backlight.controller), level);
628 629
}

630 631 632 633 634 635 636 637
static void pwm_set_backlight(struct intel_connector *connector, u32 level)
{
	struct intel_panel *panel = &connector->panel;
	int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100);

	pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS);
}

638 639 640
static void
intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
{
641
	struct intel_panel *panel = &connector->panel;
642 643 644 645

	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);

	level = intel_panel_compute_brightness(connector, level);
646
	panel->backlight.set(connector, level);
647
}
648

649 650 651
/* set backlight brightness to level in range [0..max], scaling wrt hw min */
static void intel_panel_set_backlight(struct intel_connector *connector,
				      u32 user_level, u32 user_max)
652
{
653
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
654
	struct intel_panel *panel = &connector->panel;
655
	u32 hw_level;
656

657
	if (!panel->backlight.present)
658 659
		return;

660
	mutex_lock(&dev_priv->backlight_lock);
661

662
	WARN_ON(panel->backlight.max == 0);
663

664 665 666 667 668 669
	hw_level = scale_user_to_hw(connector, user_level, user_max);
	panel->backlight.level = hw_level;

	if (panel->backlight.enabled)
		intel_panel_actually_set_backlight(connector, hw_level);

670
	mutex_unlock(&dev_priv->backlight_lock);
671 672 673 674 675 676 677 678
}

/* set backlight brightness to level in range [0..max], assuming hw min is
 * respected.
 */
void intel_panel_set_backlight_acpi(struct intel_connector *connector,
				    u32 user_level, u32 user_max)
{
679
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
680 681 682 683
	struct intel_panel *panel = &connector->panel;
	enum pipe pipe = intel_get_pipe_from_connector(connector);
	u32 hw_level;

684 685 686 687 688 689
	/*
	 * INVALID_PIPE may occur during driver init because
	 * connection_mutex isn't held across the entire backlight
	 * setup + modeset readout, and the BIOS can issue the
	 * requests at any time.
	 */
690 691 692
	if (!panel->backlight.present || pipe == INVALID_PIPE)
		return;

693
	mutex_lock(&dev_priv->backlight_lock);
694 695 696 697 698

	WARN_ON(panel->backlight.max == 0);

	hw_level = clamp_user_to_hw(connector, user_level, user_max);
	panel->backlight.level = hw_level;
699

700
	if (panel->backlight.device)
701 702 703 704
		panel->backlight.device->props.brightness =
			scale_hw_to_user(connector,
					 panel->backlight.level,
					 panel->backlight.device->props.max_brightness);
705

706
	if (panel->backlight.enabled)
707
		intel_panel_actually_set_backlight(connector, hw_level);
708

709
	mutex_unlock(&dev_priv->backlight_lock);
710 711
}

712 713
static void lpt_disable_backlight(struct intel_connector *connector)
{
714
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
715 716 717 718
	u32 tmp;

	intel_panel_actually_set_backlight(connector, 0);

719 720 721 722 723 724 725 726 727 728 729 730 731 732
	/*
	 * Although we don't support or enable CPU PWM with LPT/SPT based
	 * systems, it may have been enabled prior to loading the
	 * driver. Disable to avoid warnings on LCPLL disable.
	 *
	 * This needs rework if we need to add support for CPU PWM on PCH split
	 * platforms.
	 */
	tmp = I915_READ(BLC_PWM_CPU_CTL2);
	if (tmp & BLM_PWM_ENABLE) {
		DRM_DEBUG_KMS("cpu backlight was enabled, disabling\n");
		I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
	}

733 734 735 736
	tmp = I915_READ(BLC_PWM_PCH_CTL1);
	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
}

737 738
static void pch_disable_backlight(struct intel_connector *connector)
{
739
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
740 741
	u32 tmp;

742 743
	intel_panel_actually_set_backlight(connector, 0);

744 745 746 747 748 749 750
	tmp = I915_READ(BLC_PWM_CPU_CTL2);
	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);

	tmp = I915_READ(BLC_PWM_PCH_CTL1);
	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
}

751 752 753 754 755
static void i9xx_disable_backlight(struct intel_connector *connector)
{
	intel_panel_actually_set_backlight(connector, 0);
}

756 757
static void i965_disable_backlight(struct intel_connector *connector)
{
758
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
759 760
	u32 tmp;

761 762
	intel_panel_actually_set_backlight(connector, 0);

763 764 765 766 767 768
	tmp = I915_READ(BLC_PWM_CTL2);
	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
}

static void vlv_disable_backlight(struct intel_connector *connector)
{
769
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
770 771 772
	enum pipe pipe = intel_get_pipe_from_connector(connector);
	u32 tmp;

773 774 775
	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
		return;

776 777
	intel_panel_actually_set_backlight(connector, 0);

778 779 780 781
	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
}

782 783
static void bxt_disable_backlight(struct intel_connector *connector)
{
784
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
785 786
	struct intel_panel *panel = &connector->panel;
	u32 tmp, val;
787 788 789

	intel_panel_actually_set_backlight(connector, 0);

790 791 792 793 794 795 796 797 798
	tmp = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
			tmp & ~BXT_BLC_PWM_ENABLE);

	if (panel->backlight.controller == 1) {
		val = I915_READ(UTIL_PIN_CTL);
		val &= ~UTIL_PIN_ENABLE;
		I915_WRITE(UTIL_PIN_CTL, val);
	}
799 800
}

801 802 803 804 805 806 807 808 809 810
static void pwm_disable_backlight(struct intel_connector *connector)
{
	struct intel_panel *panel = &connector->panel;

	/* Disable the backlight */
	pwm_config(panel->backlight.pwm, 0, CRC_PMIC_PWM_PERIOD_NS);
	usleep_range(2000, 3000);
	pwm_disable(panel->backlight.pwm);
}

811
void intel_panel_disable_backlight(struct intel_connector *connector)
812
{
813
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
814
	struct intel_panel *panel = &connector->panel;
815

816
	if (!panel->backlight.present)
817 818
		return;

819
	/*
820
	 * Do not disable backlight on the vga_switcheroo path. When switching
821 822 823 824
	 * away from i915, the other client may depend on i915 to handle the
	 * backlight. This will leave the backlight on unnecessarily when
	 * another client is not activated.
	 */
825
	if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) {
826 827 828 829
		DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
		return;
	}

830
	mutex_lock(&dev_priv->backlight_lock);
831

832 833
	if (panel->backlight.device)
		panel->backlight.device->props.power = FB_BLANK_POWERDOWN;
834
	panel->backlight.enabled = false;
835
	panel->backlight.disable(connector);
836

837
	mutex_unlock(&dev_priv->backlight_lock);
838
}
839

840
static void lpt_enable_backlight(struct intel_connector *connector)
841
{
842
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
843 844 845 846 847 848 849 850 851
	struct intel_panel *panel = &connector->panel;
	u32 pch_ctl1, pch_ctl2;

	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
		DRM_DEBUG_KMS("pch backlight already enabled\n");
		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
	}
852

853 854
	pch_ctl2 = panel->backlight.max << 16;
	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
855

856 857 858
	pch_ctl1 = 0;
	if (panel->backlight.active_low_pwm)
		pch_ctl1 |= BLM_PCH_POLARITY;
859

860 861 862
	/* After LPT, override is the default. */
	if (HAS_PCH_LPT(dev_priv))
		pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
863 864 865 866 867 868 869

	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
	POSTING_READ(BLC_PWM_PCH_CTL1);
	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);

	/* This won't stick until the above enable. */
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
870 871
}

872 873
static void pch_enable_backlight(struct intel_connector *connector)
{
874
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
875
	struct intel_panel *panel = &connector->panel;
876 877 878
	enum pipe pipe = intel_get_pipe_from_connector(connector);
	enum transcoder cpu_transcoder =
		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
879
	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
880

881 882
	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
	if (cpu_ctl2 & BLM_PWM_ENABLE) {
883
		DRM_DEBUG_KMS("cpu backlight already enabled\n");
884 885 886
		cpu_ctl2 &= ~BLM_PWM_ENABLE;
		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
	}
887

888 889 890 891 892 893
	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
		DRM_DEBUG_KMS("pch backlight already enabled\n");
		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
	}
894 895

	if (cpu_transcoder == TRANSCODER_EDP)
896
		cpu_ctl2 = BLM_TRANSCODER_EDP;
897
	else
898 899
		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
900
	POSTING_READ(BLC_PWM_CPU_CTL2);
901
	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
902

903
	/* This won't stick until the above enable. */
904
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
905 906 907 908 909 910 911

	pch_ctl2 = panel->backlight.max << 16;
	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);

	pch_ctl1 = 0;
	if (panel->backlight.active_low_pwm)
		pch_ctl1 |= BLM_PCH_POLARITY;
912

913 914 915
	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
	POSTING_READ(BLC_PWM_PCH_CTL1);
	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
916 917 918 919
}

static void i9xx_enable_backlight(struct intel_connector *connector)
{
920
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
921
	struct intel_panel *panel = &connector->panel;
922 923 924 925
	u32 ctl, freq;

	ctl = I915_READ(BLC_PWM_CTL);
	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
926
		DRM_DEBUG_KMS("backlight already enabled\n");
927 928
		I915_WRITE(BLC_PWM_CTL, 0);
	}
929

930 931 932 933 934
	freq = panel->backlight.max;
	if (panel->backlight.combination_mode)
		freq /= 0xff;

	ctl = freq << 17;
935
	if (panel->backlight.combination_mode)
936
		ctl |= BLM_LEGACY_MODE;
937
	if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm)
938 939 940 941 942 943
		ctl |= BLM_POLARITY_PNV;

	I915_WRITE(BLC_PWM_CTL, ctl);
	POSTING_READ(BLC_PWM_CTL);

	/* XXX: combine this into above write? */
944
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
945 946 947 948 949 950

	/*
	 * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is
	 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2
	 * that has backlight.
	 */
951
	if (IS_GEN2(dev_priv))
952
		I915_WRITE(BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE);
953
}
954

955 956
static void i965_enable_backlight(struct intel_connector *connector)
{
957
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
958
	struct intel_panel *panel = &connector->panel;
959
	enum pipe pipe = intel_get_pipe_from_connector(connector);
960
	u32 ctl, ctl2, freq;
961

962 963
	ctl2 = I915_READ(BLC_PWM_CTL2);
	if (ctl2 & BLM_PWM_ENABLE) {
964
		DRM_DEBUG_KMS("backlight already enabled\n");
965 966 967
		ctl2 &= ~BLM_PWM_ENABLE;
		I915_WRITE(BLC_PWM_CTL2, ctl2);
	}
968

969 970 971
	freq = panel->backlight.max;
	if (panel->backlight.combination_mode)
		freq /= 0xff;
972

973 974
	ctl = freq << 16;
	I915_WRITE(BLC_PWM_CTL, ctl);
975

976 977 978 979 980 981 982 983
	ctl2 = BLM_PIPE(pipe);
	if (panel->backlight.combination_mode)
		ctl2 |= BLM_COMBINATION_MODE;
	if (panel->backlight.active_low_pwm)
		ctl2 |= BLM_POLARITY_I965;
	I915_WRITE(BLC_PWM_CTL2, ctl2);
	POSTING_READ(BLC_PWM_CTL2);
	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
984 985

	intel_panel_actually_set_backlight(connector, panel->backlight.level);
986 987 988 989
}

static void vlv_enable_backlight(struct intel_connector *connector)
{
990
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
991
	struct intel_panel *panel = &connector->panel;
992
	enum pipe pipe = intel_get_pipe_from_connector(connector);
993
	u32 ctl, ctl2;
994

995 996 997
	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
		return;

998 999
	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
	if (ctl2 & BLM_PWM_ENABLE) {
1000
		DRM_DEBUG_KMS("backlight already enabled\n");
1001 1002 1003
		ctl2 &= ~BLM_PWM_ENABLE;
		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
	}
1004

1005 1006
	ctl = panel->backlight.max << 16;
	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
1007

1008 1009
	/* XXX: combine this into above write? */
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
1010

1011 1012 1013 1014
	ctl2 = 0;
	if (panel->backlight.active_low_pwm)
		ctl2 |= BLM_POLARITY_I965;
	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
1015
	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
1016
	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
1017 1018
}

1019 1020
static void bxt_enable_backlight(struct intel_connector *connector)
{
1021
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1022
	struct intel_panel *panel = &connector->panel;
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
	enum pipe pipe = intel_get_pipe_from_connector(connector);
	u32 pwm_ctl, val;

	/* To use 2nd set of backlight registers, utility pin has to be
	 * enabled with PWM mode.
	 * The field should only be changed when the utility pin is disabled
	 */
	if (panel->backlight.controller == 1) {
		val = I915_READ(UTIL_PIN_CTL);
		if (val & UTIL_PIN_ENABLE) {
			DRM_DEBUG_KMS("util pin already enabled\n");
			val &= ~UTIL_PIN_ENABLE;
			I915_WRITE(UTIL_PIN_CTL, val);
		}
1037

1038 1039 1040 1041 1042 1043 1044 1045
		val = 0;
		if (panel->backlight.util_pin_active_low)
			val |= UTIL_PIN_POLARITY;
		I915_WRITE(UTIL_PIN_CTL, val | UTIL_PIN_PIPE(pipe) |
				UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE);
	}

	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
1046 1047 1048
	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
		DRM_DEBUG_KMS("backlight already enabled\n");
		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
1049 1050
		I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
				pwm_ctl);
1051 1052
	}

1053 1054
	I915_WRITE(BXT_BLC_PWM_FREQ(panel->backlight.controller),
			panel->backlight.max);
1055 1056 1057 1058 1059 1060 1061

	intel_panel_actually_set_backlight(connector, panel->backlight.level);

	pwm_ctl = 0;
	if (panel->backlight.active_low_pwm)
		pwm_ctl |= BXT_BLC_PWM_POLARITY;

1062 1063 1064 1065
	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl);
	POSTING_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
			pwm_ctl | BXT_BLC_PWM_ENABLE);
1066 1067
}

1068 1069 1070 1071 1072 1073 1074 1075
static void pwm_enable_backlight(struct intel_connector *connector)
{
	struct intel_panel *panel = &connector->panel;

	pwm_enable(panel->backlight.pwm);
	intel_panel_actually_set_backlight(connector, panel->backlight.level);
}

1076
void intel_panel_enable_backlight(struct intel_connector *connector)
1077
{
1078
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1079
	struct intel_panel *panel = &connector->panel;
1080
	enum pipe pipe = intel_get_pipe_from_connector(connector);
1081

1082
	if (!panel->backlight.present)
1083 1084
		return;

1085
	DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
1086

1087
	mutex_lock(&dev_priv->backlight_lock);
1088

1089 1090
	WARN_ON(panel->backlight.max == 0);

1091
	if (panel->backlight.level <= panel->backlight.min) {
1092
		panel->backlight.level = panel->backlight.max;
1093 1094
		if (panel->backlight.device)
			panel->backlight.device->props.brightness =
1095 1096 1097
				scale_hw_to_user(connector,
						 panel->backlight.level,
						 panel->backlight.device->props.max_brightness);
1098
	}
1099

1100
	panel->backlight.enable(connector);
1101
	panel->backlight.enabled = true;
1102 1103
	if (panel->backlight.device)
		panel->backlight.device->props.power = FB_BLANK_UNBLANK;
1104

1105
	mutex_unlock(&dev_priv->backlight_lock);
1106 1107
}

1108
#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
1109
static int intel_backlight_device_update_status(struct backlight_device *bd)
1110
{
1111
	struct intel_connector *connector = bl_get_data(bd);
1112
	struct intel_panel *panel = &connector->panel;
1113 1114
	struct drm_device *dev = connector->base.dev;

1115
	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1116 1117
	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
		      bd->props.brightness, bd->props.max_brightness);
1118
	intel_panel_set_backlight(connector, bd->props.brightness,
1119
				  bd->props.max_brightness);
1120 1121 1122 1123 1124 1125 1126 1127

	/*
	 * Allow flipping bl_power as a sub-state of enabled. Sadly the
	 * backlight class device does not make it easy to to differentiate
	 * between callbacks for brightness and bl_power, so our backlight_power
	 * callback needs to take this into account.
	 */
	if (panel->backlight.enabled) {
1128
		if (panel->backlight.power) {
1129 1130
			bool enable = bd->props.power == FB_BLANK_UNBLANK &&
				bd->props.brightness != 0;
1131
			panel->backlight.power(connector, enable);
1132 1133 1134 1135 1136
		}
	} else {
		bd->props.power = FB_BLANK_POWERDOWN;
	}

1137
	drm_modeset_unlock(&dev->mode_config.connection_mutex);
1138 1139 1140
	return 0;
}

1141
static int intel_backlight_device_get_brightness(struct backlight_device *bd)
1142
{
1143 1144
	struct intel_connector *connector = bl_get_data(bd);
	struct drm_device *dev = connector->base.dev;
1145
	struct drm_i915_private *dev_priv = to_i915(dev);
1146
	u32 hw_level;
1147
	int ret;
1148

1149
	intel_runtime_pm_get(dev_priv);
1150
	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1151 1152 1153 1154

	hw_level = intel_panel_get_backlight(connector);
	ret = scale_hw_to_user(connector, hw_level, bd->props.max_brightness);

1155
	drm_modeset_unlock(&dev->mode_config.connection_mutex);
1156
	intel_runtime_pm_put(dev_priv);
1157

1158
	return ret;
1159 1160
}

1161 1162 1163
static const struct backlight_ops intel_backlight_device_ops = {
	.update_status = intel_backlight_device_update_status,
	.get_brightness = intel_backlight_device_get_brightness,
1164 1165
};

1166
int intel_backlight_device_register(struct intel_connector *connector)
1167
{
1168
	struct intel_panel *panel = &connector->panel;
1169 1170
	struct backlight_properties props;

1171
	if (WARN_ON(panel->backlight.device))
1172 1173
		return -ENODEV;

1174 1175 1176
	if (!panel->backlight.present)
		return 0;

1177
	WARN_ON(panel->backlight.max == 0);
1178

1179
	memset(&props, 0, sizeof(props));
1180
	props.type = BACKLIGHT_RAW;
1181 1182 1183 1184 1185

	/*
	 * Note: Everything should work even if the backlight device max
	 * presented to the userspace is arbitrarily chosen.
	 */
1186
	props.max_brightness = panel->backlight.max;
1187 1188 1189
	props.brightness = scale_hw_to_user(connector,
					    panel->backlight.level,
					    props.max_brightness);
1190

1191 1192 1193 1194 1195
	if (panel->backlight.enabled)
		props.power = FB_BLANK_UNBLANK;
	else
		props.power = FB_BLANK_POWERDOWN;

1196 1197 1198 1199 1200
	/*
	 * Note: using the same name independent of the connector prevents
	 * registration of multiple backlight devices in the driver.
	 */
	panel->backlight.device =
1201
		backlight_device_register("intel_backlight",
1202 1203 1204
					  connector->base.kdev,
					  connector,
					  &intel_backlight_device_ops, &props);
1205

1206
	if (IS_ERR(panel->backlight.device)) {
1207
		DRM_ERROR("Failed to register backlight: %ld\n",
1208 1209
			  PTR_ERR(panel->backlight.device));
		panel->backlight.device = NULL;
1210 1211
		return -ENODEV;
	}
1212 1213 1214 1215

	DRM_DEBUG_KMS("Connector %s backlight sysfs interface registered\n",
		      connector->base.name);

1216 1217 1218
	return 0;
}

1219
void intel_backlight_device_unregister(struct intel_connector *connector)
1220
{
1221 1222 1223 1224 1225
	struct intel_panel *panel = &connector->panel;

	if (panel->backlight.device) {
		backlight_device_unregister(panel->backlight.device);
		panel->backlight.device = NULL;
1226
	}
1227
}
1228 1229
#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */

1230 1231 1232 1233 1234
/*
 * BXT: PWM clock frequency = 19.2 MHz.
 */
static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
{
1235
	return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz);
1236 1237
}

1238
/*
1239 1240 1241 1242 1243 1244
 * SPT: This value represents the period of the PWM stream in clock periods
 * multiplied by 16 (default increment) or 128 (alternate increment selected in
 * SCHICKEN_1 bit 0). PWM clock is 24 MHz.
 */
static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
{
1245
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1246
	u32 mul;
1247 1248 1249 1250 1251 1252

	if (I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY)
		mul = 128;
	else
		mul = 16;

1253
	return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul);
1254 1255 1256 1257 1258 1259 1260 1261 1262
}

/*
 * LPT: This value represents the period of the PWM stream in clock periods
 * multiplied by 128 (default increment) or 16 (alternate increment, selected in
 * LPT SOUTH_CHICKEN2 register bit 5).
 */
static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
{
1263
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1264 1265 1266 1267 1268 1269 1270
	u32 mul, clock;

	if (I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY)
		mul = 16;
	else
		mul = 128;

V
Ville Syrjälä 已提交
1271
	if (HAS_PCH_LPT_H(dev_priv))
1272 1273 1274 1275
		clock = MHz(135); /* LPT:H */
	else
		clock = MHz(24); /* LPT:LP */

1276
	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
1277 1278 1279 1280 1281 1282 1283 1284
}

/*
 * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH
 * display raw clocks multiplied by 128.
 */
static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
{
1285
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1286

1287
	return DIV_ROUND_CLOSEST(KHz(dev_priv->rawclk_freq), pwm_freq_hz * 128);
1288 1289 1290 1291 1292 1293
}

/*
 * Gen2: This field determines the number of time base events (display core
 * clock frequency/32) in total for a complete cycle of modulated backlight
 * control.
1294
 *
1295 1296 1297 1298 1299
 * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock)
 * divided by 32.
 */
static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
{
1300
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1301 1302
	int clock;

1303 1304
	if (IS_PINEVIEW(dev_priv))
		clock = KHz(dev_priv->rawclk_freq);
1305
	else
1306
		clock = KHz(dev_priv->cdclk_freq);
1307

1308
	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32);
1309 1310 1311 1312
}

/*
 * Gen4: This value represents the period of the PWM stream in display core
1313 1314
 * clocks ([DevCTG] HRAW clocks) multiplied by 128.
 *
1315 1316 1317 1318
 */
static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
{
	struct drm_device *dev = connector->base.dev;
1319
	struct drm_i915_private *dev_priv = to_i915(dev);
1320 1321 1322
	int clock;

	if (IS_G4X(dev_priv))
1323
		clock = KHz(dev_priv->rawclk_freq);
1324
	else
1325
		clock = KHz(dev_priv->cdclk_freq);
1326

1327
	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128);
1328 1329 1330 1331 1332 1333 1334 1335 1336
}

/*
 * VLV: This value represents the period of the PWM stream in display core
 * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks
 * multiplied by 16. CHV uses a 19.2MHz S0IX clock.
 */
static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
{
1337 1338
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
	int mul, clock;
1339 1340

	if ((I915_READ(CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) {
1341 1342
		if (IS_CHERRYVIEW(dev_priv))
			clock = KHz(19200);
1343
		else
1344 1345
			clock = MHz(25);
		mul = 16;
1346
	} else {
1347 1348
		clock = KHz(dev_priv->rawclk_freq);
		mul = 128;
1349
	}
1350

1351
	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
1352 1353 1354 1355
}

static u32 get_backlight_max_vbt(struct intel_connector *connector)
{
1356
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1357
	struct intel_panel *panel = &connector->panel;
1358 1359 1360
	u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
	u32 pwm;

1361 1362
	if (!panel->backlight.hz_to_pwm) {
		DRM_DEBUG_KMS("backlight frequency conversion not supported\n");
1363 1364 1365
		return 0;
	}

1366 1367 1368 1369 1370 1371 1372
	if (pwm_freq_hz) {
		DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n",
			      pwm_freq_hz);
	} else {
		pwm_freq_hz = 200;
		DRM_DEBUG_KMS("default backlight frequency %u Hz\n",
			      pwm_freq_hz);
1373 1374
	}

1375
	pwm = panel->backlight.hz_to_pwm(connector, pwm_freq_hz);
1376 1377 1378 1379 1380 1381 1382 1383 1384 1385
	if (!pwm) {
		DRM_DEBUG_KMS("backlight frequency conversion failed\n");
		return 0;
	}

	return pwm;
}

/*
 * Note: The setup hooks can't assume pipe is set!
1386
 */
1387 1388
static u32 get_backlight_min_vbt(struct intel_connector *connector)
{
1389
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1390
	struct intel_panel *panel = &connector->panel;
1391
	int min;
1392 1393 1394

	WARN_ON(panel->backlight.max == 0);

1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407
	/*
	 * XXX: If the vbt value is 255, it makes min equal to max, which leads
	 * to problems. There are such machines out there. Either our
	 * interpretation is wrong or the vbt has bogus data. Or both. Safeguard
	 * against this by letting the minimum be at most (arbitrarily chosen)
	 * 25% of the max.
	 */
	min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64);
	if (min != dev_priv->vbt.backlight.min_brightness) {
		DRM_DEBUG_KMS("clamping VBT min backlight %d/255 to %d/255\n",
			      dev_priv->vbt.backlight.min_brightness, min);
	}

1408
	/* vbt value is a coefficient in range [0..255] */
1409
	return scale(min, 0, 255, 0, panel->backlight.max);
1410 1411
}

1412
static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused)
1413
{
1414
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1415 1416 1417 1418 1419 1420 1421 1422
	struct intel_panel *panel = &connector->panel;
	u32 pch_ctl1, pch_ctl2, val;

	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;

	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
	panel->backlight.max = pch_ctl2 >> 16;
1423 1424 1425 1426

	if (!panel->backlight.max)
		panel->backlight.max = get_backlight_max_vbt(connector);

1427 1428 1429
	if (!panel->backlight.max)
		return -ENODEV;

1430 1431
	panel->backlight.min = get_backlight_min_vbt(connector);

1432
	val = lpt_get_backlight(connector);
1433 1434 1435 1436 1437 1438 1439 1440
	panel->backlight.level = intel_panel_compute_brightness(connector, val);

	panel->backlight.enabled = (pch_ctl1 & BLM_PCH_PWM_ENABLE) &&
		panel->backlight.level != 0;

	return 0;
}

1441
static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused)
1442
{
1443
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1444
	struct intel_panel *panel = &connector->panel;
1445
	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
1446

1447 1448 1449 1450 1451
	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;

	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
	panel->backlight.max = pch_ctl2 >> 16;
1452 1453 1454 1455

	if (!panel->backlight.max)
		panel->backlight.max = get_backlight_max_vbt(connector);

1456 1457 1458
	if (!panel->backlight.max)
		return -ENODEV;

1459 1460
	panel->backlight.min = get_backlight_min_vbt(connector);

1461 1462 1463
	val = pch_get_backlight(connector);
	panel->backlight.level = intel_panel_compute_brightness(connector, val);

1464 1465 1466 1467
	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
	panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
		(pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0;

1468 1469 1470
	return 0;
}

1471
static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused)
1472
{
1473
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1474
	struct intel_panel *panel = &connector->panel;
1475 1476 1477 1478
	u32 ctl, val;

	ctl = I915_READ(BLC_PWM_CTL);

1479
	if (IS_GEN2(dev_priv) || IS_I915GM(dev_priv) || IS_I945GM(dev_priv))
1480 1481
		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;

1482
	if (IS_PINEVIEW(dev_priv))
1483 1484 1485
		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;

	panel->backlight.max = ctl >> 17;
1486 1487 1488 1489 1490

	if (!panel->backlight.max) {
		panel->backlight.max = get_backlight_max_vbt(connector);
		panel->backlight.max >>= 1;
	}
1491 1492 1493 1494

	if (!panel->backlight.max)
		return -ENODEV;

1495 1496 1497
	if (panel->backlight.combination_mode)
		panel->backlight.max *= 0xff;

1498 1499
	panel->backlight.min = get_backlight_min_vbt(connector);

1500 1501 1502
	val = i9xx_get_backlight(connector);
	panel->backlight.level = intel_panel_compute_brightness(connector, val);

1503 1504
	panel->backlight.enabled = panel->backlight.level != 0;

1505 1506 1507
	return 0;
}

1508
static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused)
1509
{
1510
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1511
	struct intel_panel *panel = &connector->panel;
1512 1513 1514 1515 1516 1517 1518 1519
	u32 ctl, ctl2, val;

	ctl2 = I915_READ(BLC_PWM_CTL2);
	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;

	ctl = I915_READ(BLC_PWM_CTL);
	panel->backlight.max = ctl >> 16;
1520 1521 1522

	if (!panel->backlight.max)
		panel->backlight.max = get_backlight_max_vbt(connector);
1523 1524 1525 1526

	if (!panel->backlight.max)
		return -ENODEV;

1527 1528 1529
	if (panel->backlight.combination_mode)
		panel->backlight.max *= 0xff;

1530 1531
	panel->backlight.min = get_backlight_min_vbt(connector);

1532 1533 1534
	val = i9xx_get_backlight(connector);
	panel->backlight.level = intel_panel_compute_brightness(connector, val);

1535 1536 1537
	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
		panel->backlight.level != 0;

1538 1539 1540
	return 0;
}

1541
static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe)
1542
{
1543
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1544
	struct intel_panel *panel = &connector->panel;
1545
	u32 ctl, ctl2, val;
1546

1547 1548 1549 1550
	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
		return -ENODEV;

	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
1551 1552
	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;

1553
	ctl = I915_READ(VLV_BLC_PWM_CTL(pipe));
1554
	panel->backlight.max = ctl >> 16;
1555 1556 1557 1558

	if (!panel->backlight.max)
		panel->backlight.max = get_backlight_max_vbt(connector);

1559 1560 1561
	if (!panel->backlight.max)
		return -ENODEV;

1562 1563
	panel->backlight.min = get_backlight_min_vbt(connector);

1564
	val = _vlv_get_backlight(dev_priv, pipe);
1565 1566
	panel->backlight.level = intel_panel_compute_brightness(connector, val);

1567 1568 1569
	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
		panel->backlight.level != 0;

1570 1571 1572
	return 0;
}

1573 1574 1575
static int
bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
{
1576
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1577 1578 1579
	struct intel_panel *panel = &connector->panel;
	u32 pwm_ctl, val;

1580 1581 1582 1583 1584
	/*
	 * For BXT hard coding the Backlight controller to 0.
	 * TODO : Read the controller value from VBT and generalize
	 */
	panel->backlight.controller = 0;
1585

1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601
	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));

	/* Keeping the check if controller 1 is to be programmed.
	 * This will come into affect once the VBT parsing
	 * is fixed for controller selection, and controller 1 is used
	 * for a prticular display configuration.
	 */
	if (panel->backlight.controller == 1) {
		val = I915_READ(UTIL_PIN_CTL);
		panel->backlight.util_pin_active_low =
					val & UTIL_PIN_POLARITY;
	}

	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
	panel->backlight.max =
		I915_READ(BXT_BLC_PWM_FREQ(panel->backlight.controller));
1602 1603 1604 1605

	if (!panel->backlight.max)
		panel->backlight.max = get_backlight_max_vbt(connector);

1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617
	if (!panel->backlight.max)
		return -ENODEV;

	val = bxt_get_backlight(connector);
	panel->backlight.level = intel_panel_compute_brightness(connector, val);

	panel->backlight.enabled = (pwm_ctl & BXT_BLC_PWM_ENABLE) &&
		panel->backlight.level != 0;

	return 0;
}

1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632
static int pwm_setup_backlight(struct intel_connector *connector,
			       enum pipe pipe)
{
	struct drm_device *dev = connector->base.dev;
	struct intel_panel *panel = &connector->panel;
	int retval;

	/* Get the PWM chip for backlight control */
	panel->backlight.pwm = pwm_get(dev->dev, "pwm_backlight");
	if (IS_ERR(panel->backlight.pwm)) {
		DRM_ERROR("Failed to own the pwm chip\n");
		panel->backlight.pwm = NULL;
		return -ENODEV;
	}

1633 1634 1635 1636 1637 1638
	/*
	 * FIXME: pwm_apply_args() should be removed when switching to
	 * the atomic PWM API.
	 */
	pwm_apply_args(panel->backlight.pwm);

1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657
	retval = pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS,
			    CRC_PMIC_PWM_PERIOD_NS);
	if (retval < 0) {
		DRM_ERROR("Failed to configure the pwm chip\n");
		pwm_put(panel->backlight.pwm);
		panel->backlight.pwm = NULL;
		return retval;
	}

	panel->backlight.min = 0; /* 0% */
	panel->backlight.max = 100; /* 100% */
	panel->backlight.level = DIV_ROUND_UP(
				 pwm_get_duty_cycle(panel->backlight.pwm) * 100,
				 CRC_PMIC_PWM_PERIOD_NS);
	panel->backlight.enabled = panel->backlight.level != 0;

	return 0;
}

1658
int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
1659
{
1660
	struct drm_i915_private *dev_priv = to_i915(connector->dev);
1661
	struct intel_connector *intel_connector = to_intel_connector(connector);
1662
	struct intel_panel *panel = &intel_connector->panel;
1663
	int ret;
1664

1665
	if (!dev_priv->vbt.backlight.present) {
1666 1667 1668 1669 1670 1671
		if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
			DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n");
		} else {
			DRM_DEBUG_KMS("no backlight present per VBT\n");
			return 0;
		}
1672 1673
	}

1674 1675 1676 1677
	/* ensure intel_panel has been initialized first */
	if (WARN_ON(!panel->backlight.setup))
		return -ENODEV;

1678
	/* set level and max in panel struct */
1679
	mutex_lock(&dev_priv->backlight_lock);
1680
	ret = panel->backlight.setup(intel_connector, pipe);
1681
	mutex_unlock(&dev_priv->backlight_lock);
1682 1683 1684

	if (ret) {
		DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
1685
			      connector->name);
1686 1687
		return ret;
	}
1688

1689 1690
	panel->backlight.present = true;

1691 1692
	DRM_DEBUG_KMS("Connector %s backlight initialized, %s, brightness %u/%u\n",
		      connector->name,
1693
		      panel->backlight.enabled ? "enabled" : "disabled",
1694
		      panel->backlight.level, panel->backlight.max);
1695

1696 1697 1698
	return 0;
}

1699
void intel_panel_destroy_backlight(struct drm_connector *connector)
1700
{
1701
	struct intel_connector *intel_connector = to_intel_connector(connector);
1702
	struct intel_panel *panel = &intel_connector->panel;
1703

1704 1705 1706 1707
	/* dispose of the pwm */
	if (panel->backlight.pwm)
		pwm_put(panel->backlight.pwm);

1708
	panel->backlight.present = false;
1709
}
1710

1711
/* Set up chip specific backlight functions */
1712 1713
static void
intel_panel_init_backlight_funcs(struct intel_panel *panel)
1714
{
1715
	struct intel_connector *connector =
1716
		container_of(panel, struct intel_connector, panel);
1717
	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1718

1719 1720 1721 1722
	if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
	    intel_dp_aux_init_backlight_funcs(connector) == 0)
		return;

1723 1724 1725 1726
	if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI &&
	    intel_dsi_dcs_init_backlight_funcs(connector) == 0)
		return;

1727
	if (IS_BROXTON(dev_priv)) {
1728 1729 1730 1731 1732
		panel->backlight.setup = bxt_setup_backlight;
		panel->backlight.enable = bxt_enable_backlight;
		panel->backlight.disable = bxt_disable_backlight;
		panel->backlight.set = bxt_set_backlight;
		panel->backlight.get = bxt_get_backlight;
1733
		panel->backlight.hz_to_pwm = bxt_hz_to_pwm;
1734 1735
	} else if (HAS_PCH_LPT(dev_priv) || HAS_PCH_SPT(dev_priv) ||
		   HAS_PCH_KBP(dev_priv)) {
1736 1737 1738 1739 1740
		panel->backlight.setup = lpt_setup_backlight;
		panel->backlight.enable = lpt_enable_backlight;
		panel->backlight.disable = lpt_disable_backlight;
		panel->backlight.set = lpt_set_backlight;
		panel->backlight.get = lpt_get_backlight;
1741
		if (HAS_PCH_LPT(dev_priv))
1742
			panel->backlight.hz_to_pwm = lpt_hz_to_pwm;
1743
		else
1744
			panel->backlight.hz_to_pwm = spt_hz_to_pwm;
1745
	} else if (HAS_PCH_SPLIT(dev_priv)) {
1746 1747 1748 1749 1750 1751
		panel->backlight.setup = pch_setup_backlight;
		panel->backlight.enable = pch_enable_backlight;
		panel->backlight.disable = pch_disable_backlight;
		panel->backlight.set = pch_set_backlight;
		panel->backlight.get = pch_get_backlight;
		panel->backlight.hz_to_pwm = pch_hz_to_pwm;
1752
	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1753
		if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) {
1754 1755 1756 1757 1758
			panel->backlight.setup = pwm_setup_backlight;
			panel->backlight.enable = pwm_enable_backlight;
			panel->backlight.disable = pwm_disable_backlight;
			panel->backlight.set = pwm_set_backlight;
			panel->backlight.get = pwm_get_backlight;
1759
		} else {
1760 1761 1762 1763 1764 1765
			panel->backlight.setup = vlv_setup_backlight;
			panel->backlight.enable = vlv_enable_backlight;
			panel->backlight.disable = vlv_disable_backlight;
			panel->backlight.set = vlv_set_backlight;
			panel->backlight.get = vlv_get_backlight;
			panel->backlight.hz_to_pwm = vlv_hz_to_pwm;
1766
		}
1767
	} else if (IS_GEN4(dev_priv)) {
1768 1769 1770 1771 1772 1773
		panel->backlight.setup = i965_setup_backlight;
		panel->backlight.enable = i965_enable_backlight;
		panel->backlight.disable = i965_disable_backlight;
		panel->backlight.set = i9xx_set_backlight;
		panel->backlight.get = i9xx_get_backlight;
		panel->backlight.hz_to_pwm = i965_hz_to_pwm;
1774
	} else {
1775 1776 1777 1778 1779 1780
		panel->backlight.setup = i9xx_setup_backlight;
		panel->backlight.enable = i9xx_enable_backlight;
		panel->backlight.disable = i9xx_disable_backlight;
		panel->backlight.set = i9xx_set_backlight;
		panel->backlight.get = i9xx_get_backlight;
		panel->backlight.hz_to_pwm = i9xx_hz_to_pwm;
1781 1782 1783
	}
}

1784
int intel_panel_init(struct intel_panel *panel,
1785 1786
		     struct drm_display_mode *fixed_mode,
		     struct drm_display_mode *downclock_mode)
1787
{
1788 1789
	intel_panel_init_backlight_funcs(panel);

1790
	panel->fixed_mode = fixed_mode;
1791
	panel->downclock_mode = downclock_mode;
1792

1793 1794 1795 1796 1797
	return 0;
}

void intel_panel_fini(struct intel_panel *panel)
{
1798 1799 1800 1801 1802
	struct intel_connector *intel_connector =
		container_of(panel, struct intel_connector, panel);

	if (panel->fixed_mode)
		drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
1803 1804 1805 1806

	if (panel->downclock_mode)
		drm_mode_destroy(intel_connector->base.dev,
				panel->downclock_mode);
1807
}