xref: /dragonfly/sys/dev/drm/i915/intel_panel.c (revision 9317c2d0)
1 /*
2  * Copyright © 2006-2010 Intel Corporation
3  * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *	Eric Anholt <eric@anholt.net>
26  *      Dave Airlie <airlied@linux.ie>
27  *      Jesse Barnes <jesse.barnes@intel.com>
28  *      Chris Wilson <chris@chris-wilson.co.uk>
29  */
30 
31 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
32 
33 #include <linux/kernel.h>
34 #include <linux/moduleparam.h>
35 #include <linux/pwm.h>
36 #include "intel_drv.h"
37 
38 #define CRC_PMIC_PWM_PERIOD_NS	21333
39 
40 void
41 intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
42 		       struct drm_display_mode *adjusted_mode)
43 {
44 	drm_mode_copy(adjusted_mode, fixed_mode);
45 
46 	drm_mode_set_crtcinfo(adjusted_mode, 0);
47 }
48 
49 /**
50  * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID
51  * @dev: drm device
52  * @fixed_mode : panel native mode
53  * @connector: LVDS/eDP connector
54  *
55  * Return downclock_avail
56  * Find the reduced downclock for LVDS/eDP in EDID.
57  */
58 struct drm_display_mode *
59 intel_find_panel_downclock(struct drm_device *dev,
60 			struct drm_display_mode *fixed_mode,
61 			struct drm_connector *connector)
62 {
63 	struct drm_display_mode *scan, *tmp_mode;
64 	int temp_downclock;
65 
66 	temp_downclock = fixed_mode->clock;
67 	tmp_mode = NULL;
68 
69 	list_for_each_entry(scan, &connector->probed_modes, head) {
70 		/*
71 		 * If one mode has the same resolution with the fixed_panel
72 		 * mode while they have the different refresh rate, it means
73 		 * that the reduced downclock is found. In such
74 		 * case we can set the different FPx0/1 to dynamically select
75 		 * between low and high frequency.
76 		 */
77 		if (scan->hdisplay == fixed_mode->hdisplay &&
78 		    scan->hsync_start == fixed_mode->hsync_start &&
79 		    scan->hsync_end == fixed_mode->hsync_end &&
80 		    scan->htotal == fixed_mode->htotal &&
81 		    scan->vdisplay == fixed_mode->vdisplay &&
82 		    scan->vsync_start == fixed_mode->vsync_start &&
83 		    scan->vsync_end == fixed_mode->vsync_end &&
84 		    scan->vtotal == fixed_mode->vtotal) {
85 			if (scan->clock < temp_downclock) {
86 				/*
87 				 * The downclock is already found. But we
88 				 * expect to find the lower downclock.
89 				 */
90 				temp_downclock = scan->clock;
91 				tmp_mode = scan;
92 			}
93 		}
94 	}
95 
96 	if (temp_downclock < fixed_mode->clock)
97 		return drm_mode_duplicate(dev, tmp_mode);
98 	else
99 		return NULL;
100 }
101 
102 /* adjusted_mode has been preset to be the panel's fixed mode */
103 void
104 intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
105 			struct intel_crtc_state *pipe_config,
106 			int fitting_mode)
107 {
108 	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
109 	int x = 0, y = 0, width = 0, height = 0;
110 
111 	/* Native modes don't need fitting */
112 	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
113 	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
114 		goto done;
115 
116 	switch (fitting_mode) {
117 	case DRM_MODE_SCALE_CENTER:
118 		width = pipe_config->pipe_src_w;
119 		height = pipe_config->pipe_src_h;
120 		x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
121 		y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
122 		break;
123 
124 	case DRM_MODE_SCALE_ASPECT:
125 		/* Scale but preserve the aspect ratio */
126 		{
127 			u32 scaled_width = adjusted_mode->crtc_hdisplay
128 				* pipe_config->pipe_src_h;
129 			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 				if (height & 1)
141 				    height++;
142 				y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
143 				x = 0;
144 				width = adjusted_mode->crtc_hdisplay;
145 			} else {
146 				x = y = 0;
147 				width = adjusted_mode->crtc_hdisplay;
148 				height = adjusted_mode->crtc_vdisplay;
149 			}
150 		}
151 		break;
152 
153 	case DRM_MODE_SCALE_FULLSCREEN:
154 		x = y = 0;
155 		width = adjusted_mode->crtc_hdisplay;
156 		height = adjusted_mode->crtc_vdisplay;
157 		break;
158 
159 	default:
160 		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
161 		return;
162 	}
163 
164 done:
165 	pipe_config->pch_pfit.pos = (x << 16) | y;
166 	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 		    int width)
173 {
174 	u32 border, sync_pos, blank_width, sync_width;
175 
176 	/* keep the hsync and hblank widths constant */
177 	sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
178 	blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
179 	sync_pos = (blank_width - sync_width + 1) / 2;
180 
181 	border = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
182 	border += border & 1; /* make the border even */
183 
184 	adjusted_mode->crtc_hdisplay = width;
185 	adjusted_mode->crtc_hblank_start = width + border;
186 	adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width;
187 
188 	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos;
189 	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 		  int height)
195 {
196 	u32 border, sync_pos, blank_width, sync_width;
197 
198 	/* keep the vsync and vblank widths constant */
199 	sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
200 	blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start;
201 	sync_pos = (blank_width - sync_width + 1) / 2;
202 
203 	border = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
204 
205 	adjusted_mode->crtc_vdisplay = height;
206 	adjusted_mode->crtc_vblank_start = height + border;
207 	adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width;
208 
209 	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos;
210 	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + sync_width;
211 }
212 
213 static inline u32 panel_fitter_scaling(u32 source, u32 target)
214 {
215 	/*
216 	 * Floating point operation is not supported. So the FACTOR
217 	 * is defined, which can avoid the floating point computation
218 	 * when calculating the panel ratio.
219 	 */
220 #define ACCURACY 12
221 #define FACTOR (1 << ACCURACY)
222 	u32 ratio = source * FACTOR / target;
223 	return (FACTOR * ratio + FACTOR/2) / FACTOR;
224 }
225 
226 static void i965_scale_aspect(struct intel_crtc_state *pipe_config,
227 			      u32 *pfit_control)
228 {
229 	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
230 	u32 scaled_width = adjusted_mode->crtc_hdisplay *
231 		pipe_config->pipe_src_h;
232 	u32 scaled_height = pipe_config->pipe_src_w *
233 		adjusted_mode->crtc_vdisplay;
234 
235 	/* 965+ is easy, it does everything in hw */
236 	if (scaled_width > scaled_height)
237 		*pfit_control |= PFIT_ENABLE |
238 			PFIT_SCALING_PILLAR;
239 	else if (scaled_width < scaled_height)
240 		*pfit_control |= PFIT_ENABLE |
241 			PFIT_SCALING_LETTER;
242 	else if (adjusted_mode->crtc_hdisplay != pipe_config->pipe_src_w)
243 		*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
244 }
245 
246 static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config,
247 			      u32 *pfit_control, u32 *pfit_pgm_ratios,
248 			      u32 *border)
249 {
250 	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
251 	u32 scaled_width = adjusted_mode->crtc_hdisplay *
252 		pipe_config->pipe_src_h;
253 	u32 scaled_height = pipe_config->pipe_src_w *
254 		adjusted_mode->crtc_vdisplay;
255 	u32 bits;
256 
257 	/*
258 	 * For earlier chips we have to calculate the scaling
259 	 * ratio by hand and program it into the
260 	 * PFIT_PGM_RATIO register
261 	 */
262 	if (scaled_width > scaled_height) { /* pillar */
263 		centre_horizontally(adjusted_mode,
264 				    scaled_height /
265 				    pipe_config->pipe_src_h);
266 
267 		*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 			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
273 					     bits << PFIT_VERT_SCALE_SHIFT);
274 			*pfit_control |= (PFIT_ENABLE |
275 					  VERT_INTERP_BILINEAR |
276 					  HORIZ_INTERP_BILINEAR);
277 		}
278 	} else if (scaled_width < scaled_height) { /* letter */
279 		centre_vertically(adjusted_mode,
280 				  scaled_width /
281 				  pipe_config->pipe_src_w);
282 
283 		*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 			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
289 					     bits << PFIT_VERT_SCALE_SHIFT);
290 			*pfit_control |= (PFIT_ENABLE |
291 					  VERT_INTERP_BILINEAR |
292 					  HORIZ_INTERP_BILINEAR);
293 		}
294 	} else {
295 		/* Aspects match, Let hw scale both directions */
296 		*pfit_control |= (PFIT_ENABLE |
297 				  VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
298 				  VERT_INTERP_BILINEAR |
299 				  HORIZ_INTERP_BILINEAR);
300 	}
301 }
302 
303 void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
304 			      struct intel_crtc_state *pipe_config,
305 			      int fitting_mode)
306 {
307 	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
308 	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 	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
313 	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
314 		goto out;
315 
316 	switch (fitting_mode) {
317 	case DRM_MODE_SCALE_CENTER:
318 		/*
319 		 * For centered modes, we have to calculate border widths &
320 		 * heights and modify the values programmed into the CRTC.
321 		 */
322 		centre_horizontally(adjusted_mode, pipe_config->pipe_src_w);
323 		centre_vertically(adjusted_mode, pipe_config->pipe_src_h);
324 		border = LVDS_BORDER_ENABLE;
325 		break;
326 	case DRM_MODE_SCALE_ASPECT:
327 		/* Scale but preserve the aspect ratio */
328 		if (INTEL_GEN(dev_priv) >= 4)
329 			i965_scale_aspect(pipe_config, &pfit_control);
330 		else
331 			i9xx_scale_aspect(pipe_config, &pfit_control,
332 					  &pfit_pgm_ratios, &border);
333 		break;
334 	case DRM_MODE_SCALE_FULLSCREEN:
335 		/*
336 		 * Full scaling, even if it changes the aspect ratio.
337 		 * Fortunately this is all done for us in hw.
338 		 */
339 		if (pipe_config->pipe_src_h != adjusted_mode->crtc_vdisplay ||
340 		    pipe_config->pipe_src_w != adjusted_mode->crtc_hdisplay) {
341 			pfit_control |= PFIT_ENABLE;
342 			if (INTEL_GEN(dev_priv) >= 4)
343 				pfit_control |= PFIT_SCALING_AUTO;
344 			else
345 				pfit_control |= (VERT_AUTO_SCALE |
346 						 VERT_INTERP_BILINEAR |
347 						 HORIZ_AUTO_SCALE |
348 						 HORIZ_INTERP_BILINEAR);
349 		}
350 		break;
351 	default:
352 		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
353 		return;
354 	}
355 
356 	/* 965+ wants fuzzy fitting */
357 	/* FIXME: handle multiple panels by failing gracefully */
358 	if (INTEL_GEN(dev_priv) >= 4)
359 		pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
360 				 PFIT_FILTER_FUZZY);
361 
362 out:
363 	if ((pfit_control & PFIT_ENABLE) == 0) {
364 		pfit_control = 0;
365 		pfit_pgm_ratios = 0;
366 	}
367 
368 	/* Make sure pre-965 set dither correctly for 18bpp panels. */
369 	if (INTEL_GEN(dev_priv) < 4 && pipe_config->pipe_bpp == 18)
370 		pfit_control |= PANEL_8TO6_DITHER_ENABLE;
371 
372 	pipe_config->gmch_pfit.control = pfit_control;
373 	pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
374 	pipe_config->gmch_pfit.lvds_border_bits = border;
375 }
376 
377 enum drm_connector_status
378 intel_panel_detect(struct drm_device *dev)
379 {
380 	struct drm_i915_private *dev_priv = to_i915(dev);
381 
382 	/* Assume that the BIOS does not lie through the OpRegion... */
383 	if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) {
384 		return *dev_priv->opregion.lid_state & 0x1 ?
385 			connector_status_connected :
386 			connector_status_disconnected;
387 	}
388 
389 	switch (i915.panel_ignore_lid) {
390 	case -2:
391 		return connector_status_connected;
392 	case -1:
393 		return connector_status_disconnected;
394 	default:
395 		return connector_status_unknown;
396 	}
397 }
398 
399 /**
400  * scale - scale values from one range to another
401  *
402  * @source_val: value in range [@source_min..@source_max]
403  *
404  * Return @source_val in range [@source_min..@source_max] scaled to range
405  * [@target_min..@target_max].
406  */
407 static uint32_t scale(uint32_t source_val,
408 		      uint32_t source_min, uint32_t source_max,
409 		      uint32_t target_min, uint32_t target_max)
410 {
411 	uint64_t target_val;
412 
413 	WARN_ON(source_min > source_max);
414 	WARN_ON(target_min > target_max);
415 
416 	/* defensive */
417 	source_val = clamp(source_val, source_min, source_max);
418 
419 	/* avoid overflows */
420 	target_val = DIV_ROUND_CLOSEST_ULL((uint64_t)(source_val - source_min) *
421 			(target_max - target_min), source_max - source_min);
422 	target_val += target_min;
423 
424 	return target_val;
425 }
426 
427 /* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */
428 static inline u32 scale_user_to_hw(struct intel_connector *connector,
429 				   u32 user_level, u32 user_max)
430 {
431 	struct intel_panel *panel = &connector->panel;
432 
433 	return scale(user_level, 0, user_max,
434 		     panel->backlight.min, panel->backlight.max);
435 }
436 
437 /* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result
438  * to [hw_min..hw_max]. */
439 static inline u32 clamp_user_to_hw(struct intel_connector *connector,
440 				   u32 user_level, u32 user_max)
441 {
442 	struct intel_panel *panel = &connector->panel;
443 	u32 hw_level;
444 
445 	hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max);
446 	hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max);
447 
448 	return hw_level;
449 }
450 
451 /* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */
452 static inline u32 scale_hw_to_user(struct intel_connector *connector,
453 				   u32 hw_level, u32 user_max)
454 {
455 	struct intel_panel *panel = &connector->panel;
456 
457 	return scale(hw_level, panel->backlight.min, panel->backlight.max,
458 		     0, user_max);
459 }
460 
461 static u32 intel_panel_compute_brightness(struct intel_connector *connector,
462 					  u32 val)
463 {
464 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
465 	struct intel_panel *panel = &connector->panel;
466 
467 	WARN_ON(panel->backlight.max == 0);
468 
469 	if (i915.invert_brightness < 0)
470 		return val;
471 
472 	if (i915.invert_brightness > 0 ||
473 	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
474 		return panel->backlight.max - val;
475 	}
476 
477 	return val;
478 }
479 
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 	return I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
485 }
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 	return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
492 }
493 
494 static u32 i9xx_get_backlight(struct intel_connector *connector)
495 {
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 	return val;
512 }
513 
514 static u32 _vlv_get_backlight(struct drm_i915_private *dev_priv, enum i915_pipe pipe)
515 {
516 	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
517 		return 0;
518 
519 	return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
520 }
521 
522 static u32 vlv_get_backlight(struct intel_connector *connector)
523 {
524 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
525 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
526 
527 	return _vlv_get_backlight(dev_priv, pipe);
528 }
529 
530 static u32 bxt_get_backlight(struct intel_connector *connector)
531 {
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 static u32 pwm_get_backlight(struct intel_connector *connector)
539 {
540 	struct intel_panel *panel = &connector->panel;
541 	int duty_ns;
542 
543 	duty_ns = pwm_get_duty_cycle(panel->backlight.pwm);
544 	return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS);
545 }
546 
547 #if 0
548 static u32 intel_panel_get_backlight(struct intel_connector *connector)
549 {
550 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
551 	struct intel_panel *panel = &connector->panel;
552 	u32 val = 0;
553 
554 	mutex_lock(&dev_priv->backlight_lock);
555 
556 	if (panel->backlight.enabled) {
557 		val = panel->backlight.get(connector);
558 		val = intel_panel_compute_brightness(connector, val);
559 	}
560 
561 	mutex_unlock(&dev_priv->backlight_lock);
562 
563 	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
564 	return val;
565 }
566 #endif
567 
568 static void lpt_set_backlight(struct intel_connector *connector, u32 level)
569 {
570 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
571 	u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
572 	I915_WRITE(BLC_PWM_PCH_CTL2, val | level);
573 }
574 
575 static void pch_set_backlight(struct intel_connector *connector, u32 level)
576 {
577 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
578 	u32 tmp;
579 
580 	tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
581 	I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
582 }
583 
584 static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
585 {
586 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
587 	struct intel_panel *panel = &connector->panel;
588 	u32 tmp, mask;
589 
590 	WARN_ON(panel->backlight.max == 0);
591 
592 	if (panel->backlight.combination_mode) {
593 		u8 lbpc;
594 
595 		lbpc = level * 0xfe / panel->backlight.max + 1;
596 		level /= lbpc;
597 		pci_write_config_byte(dev_priv->drm.pdev, LBPC, lbpc);
598 	}
599 
600 	if (IS_GEN4(dev_priv)) {
601 		mask = BACKLIGHT_DUTY_CYCLE_MASK;
602 	} else {
603 		level <<= 1;
604 		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
605 	}
606 
607 	tmp = I915_READ(BLC_PWM_CTL) & ~mask;
608 	I915_WRITE(BLC_PWM_CTL, tmp | level);
609 }
610 
611 static void vlv_set_backlight(struct intel_connector *connector, u32 level)
612 {
613 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
614 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
615 	u32 tmp;
616 
617 	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
618 		return;
619 
620 	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
621 	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
622 }
623 
624 static void bxt_set_backlight(struct intel_connector *connector, u32 level)
625 {
626 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
627 	struct intel_panel *panel = &connector->panel;
628 
629 	I915_WRITE(BXT_BLC_PWM_DUTY(panel->backlight.controller), level);
630 }
631 
632 static void pwm_set_backlight(struct intel_connector *connector, u32 level)
633 {
634 	struct intel_panel *panel = &connector->panel;
635 	int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100);
636 
637 	pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS);
638 }
639 
640 static void
641 intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
642 {
643 	struct intel_panel *panel = &connector->panel;
644 
645 	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
646 
647 	level = intel_panel_compute_brightness(connector, level);
648 	panel->backlight.set(connector, level);
649 }
650 
651 /* set backlight brightness to level in range [0..max], scaling wrt hw min */
652 static void intel_panel_set_backlight(struct intel_connector *connector,
653 				      u32 user_level, u32 user_max)
654 {
655 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
656 	struct intel_panel *panel = &connector->panel;
657 	u32 hw_level;
658 
659 	if (!panel->backlight.present)
660 		return;
661 
662 	mutex_lock(&dev_priv->backlight_lock);
663 
664 	WARN_ON(panel->backlight.max == 0);
665 
666 	hw_level = scale_user_to_hw(connector, user_level, user_max);
667 	panel->backlight.level = hw_level;
668 
669 	if (panel->backlight.enabled)
670 		intel_panel_actually_set_backlight(connector, hw_level);
671 
672 	mutex_unlock(&dev_priv->backlight_lock);
673 }
674 
675 /* set backlight brightness to level in range [0..max], assuming hw min is
676  * respected.
677  */
678 void intel_panel_set_backlight_acpi(struct intel_connector *connector,
679 				    u32 user_level, u32 user_max)
680 {
681 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
682 	struct intel_panel *panel = &connector->panel;
683 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
684 	u32 hw_level;
685 
686 	/*
687 	 * INVALID_PIPE may occur during driver init because
688 	 * connection_mutex isn't held across the entire backlight
689 	 * setup + modeset readout, and the BIOS can issue the
690 	 * requests at any time.
691 	 */
692 	if (!panel->backlight.present || pipe == INVALID_PIPE)
693 		return;
694 
695 	mutex_lock(&dev_priv->backlight_lock);
696 
697 	WARN_ON(panel->backlight.max == 0);
698 
699 	hw_level = clamp_user_to_hw(connector, user_level, user_max);
700 	panel->backlight.level = hw_level;
701 
702 	if (panel->backlight.device)
703 		panel->backlight.device->props.brightness =
704 			scale_hw_to_user(connector,
705 					 panel->backlight.level,
706 					 panel->backlight.device->props.max_brightness);
707 
708 	if (panel->backlight.enabled)
709 		intel_panel_actually_set_backlight(connector, hw_level);
710 
711 	mutex_unlock(&dev_priv->backlight_lock);
712 }
713 
714 static void lpt_disable_backlight(struct intel_connector *connector)
715 {
716 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
717 	u32 tmp;
718 
719 	intel_panel_actually_set_backlight(connector, 0);
720 
721 	/*
722 	 * Although we don't support or enable CPU PWM with LPT/SPT based
723 	 * systems, it may have been enabled prior to loading the
724 	 * driver. Disable to avoid warnings on LCPLL disable.
725 	 *
726 	 * This needs rework if we need to add support for CPU PWM on PCH split
727 	 * platforms.
728 	 */
729 	tmp = I915_READ(BLC_PWM_CPU_CTL2);
730 	if (tmp & BLM_PWM_ENABLE) {
731 		DRM_DEBUG_KMS("cpu backlight was enabled, disabling\n");
732 		I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
733 	}
734 
735 	tmp = I915_READ(BLC_PWM_PCH_CTL1);
736 	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
737 }
738 
739 static void pch_disable_backlight(struct intel_connector *connector)
740 {
741 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
742 	u32 tmp;
743 
744 	intel_panel_actually_set_backlight(connector, 0);
745 
746 	tmp = I915_READ(BLC_PWM_CPU_CTL2);
747 	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
748 
749 	tmp = I915_READ(BLC_PWM_PCH_CTL1);
750 	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
751 }
752 
753 static void i9xx_disable_backlight(struct intel_connector *connector)
754 {
755 	intel_panel_actually_set_backlight(connector, 0);
756 }
757 
758 static void i965_disable_backlight(struct intel_connector *connector)
759 {
760 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
761 	u32 tmp;
762 
763 	intel_panel_actually_set_backlight(connector, 0);
764 
765 	tmp = I915_READ(BLC_PWM_CTL2);
766 	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
767 }
768 
769 static void vlv_disable_backlight(struct intel_connector *connector)
770 {
771 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
772 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
773 	u32 tmp;
774 
775 	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
776 		return;
777 
778 	intel_panel_actually_set_backlight(connector, 0);
779 
780 	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
781 	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
782 }
783 
784 static void bxt_disable_backlight(struct intel_connector *connector)
785 {
786 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
787 	struct intel_panel *panel = &connector->panel;
788 	u32 tmp, val;
789 
790 	intel_panel_actually_set_backlight(connector, 0);
791 
792 	tmp = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
793 	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
794 			tmp & ~BXT_BLC_PWM_ENABLE);
795 
796 	if (panel->backlight.controller == 1) {
797 		val = I915_READ(UTIL_PIN_CTL);
798 		val &= ~UTIL_PIN_ENABLE;
799 		I915_WRITE(UTIL_PIN_CTL, val);
800 	}
801 }
802 
803 static void pwm_disable_backlight(struct intel_connector *connector)
804 {
805 	struct intel_panel *panel = &connector->panel;
806 
807 	/* Disable the backlight */
808 	pwm_config(panel->backlight.pwm, 0, CRC_PMIC_PWM_PERIOD_NS);
809 	usleep_range(2000, 3000);
810 	pwm_disable(panel->backlight.pwm);
811 }
812 
813 void intel_panel_disable_backlight(struct intel_connector *connector)
814 {
815 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
816 	struct intel_panel *panel = &connector->panel;
817 
818 	if (!panel->backlight.present)
819 		return;
820 
821 	/*
822 	 * Do not disable backlight on the vga_switcheroo path. When switching
823 	 * away from i915, the other client may depend on i915 to handle the
824 	 * backlight. This will leave the backlight on unnecessarily when
825 	 * another client is not activated.
826 	 */
827 	if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) {
828 		DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
829 		return;
830 	}
831 
832 	mutex_lock(&dev_priv->backlight_lock);
833 
834 	if (panel->backlight.device)
835 		panel->backlight.device->props.power = FB_BLANK_POWERDOWN;
836 	panel->backlight.enabled = false;
837 	panel->backlight.disable(connector);
838 
839 	mutex_unlock(&dev_priv->backlight_lock);
840 }
841 
842 static void lpt_enable_backlight(struct intel_connector *connector)
843 {
844 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
845 	struct intel_panel *panel = &connector->panel;
846 	u32 pch_ctl1, pch_ctl2, schicken;
847 
848 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
849 	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
850 		DRM_DEBUG_KMS("pch backlight already enabled\n");
851 		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
852 		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
853 	}
854 
855 	if (HAS_PCH_LPT(dev_priv)) {
856 		schicken = I915_READ(SOUTH_CHICKEN2);
857 		if (panel->backlight.alternate_pwm_increment)
858 			schicken |= LPT_PWM_GRANULARITY;
859 		else
860 			schicken &= ~LPT_PWM_GRANULARITY;
861 		I915_WRITE(SOUTH_CHICKEN2, schicken);
862 	} else {
863 		schicken = I915_READ(SOUTH_CHICKEN1);
864 		if (panel->backlight.alternate_pwm_increment)
865 			schicken |= SPT_PWM_GRANULARITY;
866 		else
867 			schicken &= ~SPT_PWM_GRANULARITY;
868 		I915_WRITE(SOUTH_CHICKEN1, schicken);
869 	}
870 
871 	pch_ctl2 = panel->backlight.max << 16;
872 	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
873 
874 	pch_ctl1 = 0;
875 	if (panel->backlight.active_low_pwm)
876 		pch_ctl1 |= BLM_PCH_POLARITY;
877 
878 	/* After LPT, override is the default. */
879 	if (HAS_PCH_LPT(dev_priv))
880 		pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
881 
882 	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
883 	POSTING_READ(BLC_PWM_PCH_CTL1);
884 	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
885 
886 	/* This won't stick until the above enable. */
887 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
888 }
889 
890 static void pch_enable_backlight(struct intel_connector *connector)
891 {
892 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
893 	struct intel_panel *panel = &connector->panel;
894 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
895 	enum transcoder cpu_transcoder =
896 		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
897 	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
898 
899 	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
900 	if (cpu_ctl2 & BLM_PWM_ENABLE) {
901 		DRM_DEBUG_KMS("cpu backlight already enabled\n");
902 		cpu_ctl2 &= ~BLM_PWM_ENABLE;
903 		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
904 	}
905 
906 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
907 	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
908 		DRM_DEBUG_KMS("pch backlight already enabled\n");
909 		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
910 		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
911 	}
912 
913 	if (cpu_transcoder == TRANSCODER_EDP)
914 		cpu_ctl2 = BLM_TRANSCODER_EDP;
915 	else
916 		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
917 	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
918 	POSTING_READ(BLC_PWM_CPU_CTL2);
919 	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
920 
921 	/* This won't stick until the above enable. */
922 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
923 
924 	pch_ctl2 = panel->backlight.max << 16;
925 	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
926 
927 	pch_ctl1 = 0;
928 	if (panel->backlight.active_low_pwm)
929 		pch_ctl1 |= BLM_PCH_POLARITY;
930 
931 	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
932 	POSTING_READ(BLC_PWM_PCH_CTL1);
933 	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
934 }
935 
936 static void i9xx_enable_backlight(struct intel_connector *connector)
937 {
938 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
939 	struct intel_panel *panel = &connector->panel;
940 	u32 ctl, freq;
941 
942 	ctl = I915_READ(BLC_PWM_CTL);
943 	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
944 		DRM_DEBUG_KMS("backlight already enabled\n");
945 		I915_WRITE(BLC_PWM_CTL, 0);
946 	}
947 
948 	freq = panel->backlight.max;
949 	if (panel->backlight.combination_mode)
950 		freq /= 0xff;
951 
952 	ctl = freq << 17;
953 	if (panel->backlight.combination_mode)
954 		ctl |= BLM_LEGACY_MODE;
955 	if (IS_PINEVIEW(dev_priv) && panel->backlight.active_low_pwm)
956 		ctl |= BLM_POLARITY_PNV;
957 
958 	I915_WRITE(BLC_PWM_CTL, ctl);
959 	POSTING_READ(BLC_PWM_CTL);
960 
961 	/* XXX: combine this into above write? */
962 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
963 
964 	/*
965 	 * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is
966 	 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2
967 	 * that has backlight.
968 	 */
969 	if (IS_GEN2(dev_priv))
970 		I915_WRITE(BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE);
971 }
972 
973 static void i965_enable_backlight(struct intel_connector *connector)
974 {
975 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
976 	struct intel_panel *panel = &connector->panel;
977 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
978 	u32 ctl, ctl2, freq;
979 
980 	ctl2 = I915_READ(BLC_PWM_CTL2);
981 	if (ctl2 & BLM_PWM_ENABLE) {
982 		DRM_DEBUG_KMS("backlight already enabled\n");
983 		ctl2 &= ~BLM_PWM_ENABLE;
984 		I915_WRITE(BLC_PWM_CTL2, ctl2);
985 	}
986 
987 	freq = panel->backlight.max;
988 	if (panel->backlight.combination_mode)
989 		freq /= 0xff;
990 
991 	ctl = freq << 16;
992 	I915_WRITE(BLC_PWM_CTL, ctl);
993 
994 	ctl2 = BLM_PIPE(pipe);
995 	if (panel->backlight.combination_mode)
996 		ctl2 |= BLM_COMBINATION_MODE;
997 	if (panel->backlight.active_low_pwm)
998 		ctl2 |= BLM_POLARITY_I965;
999 	I915_WRITE(BLC_PWM_CTL2, ctl2);
1000 	POSTING_READ(BLC_PWM_CTL2);
1001 	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
1002 
1003 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
1004 }
1005 
1006 static void vlv_enable_backlight(struct intel_connector *connector)
1007 {
1008 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1009 	struct intel_panel *panel = &connector->panel;
1010 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
1011 	u32 ctl, ctl2;
1012 
1013 	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
1014 		return;
1015 
1016 	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
1017 	if (ctl2 & BLM_PWM_ENABLE) {
1018 		DRM_DEBUG_KMS("backlight already enabled\n");
1019 		ctl2 &= ~BLM_PWM_ENABLE;
1020 		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
1021 	}
1022 
1023 	ctl = panel->backlight.max << 16;
1024 	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
1025 
1026 	/* XXX: combine this into above write? */
1027 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
1028 
1029 	ctl2 = 0;
1030 	if (panel->backlight.active_low_pwm)
1031 		ctl2 |= BLM_POLARITY_I965;
1032 	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
1033 	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
1034 	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
1035 }
1036 
1037 static void bxt_enable_backlight(struct intel_connector *connector)
1038 {
1039 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1040 	struct intel_panel *panel = &connector->panel;
1041 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
1042 	u32 pwm_ctl, val;
1043 
1044 	/* To use 2nd set of backlight registers, utility pin has to be
1045 	 * enabled with PWM mode.
1046 	 * The field should only be changed when the utility pin is disabled
1047 	 */
1048 	if (panel->backlight.controller == 1) {
1049 		val = I915_READ(UTIL_PIN_CTL);
1050 		if (val & UTIL_PIN_ENABLE) {
1051 			DRM_DEBUG_KMS("util pin already enabled\n");
1052 			val &= ~UTIL_PIN_ENABLE;
1053 			I915_WRITE(UTIL_PIN_CTL, val);
1054 		}
1055 
1056 		val = 0;
1057 		if (panel->backlight.util_pin_active_low)
1058 			val |= UTIL_PIN_POLARITY;
1059 		I915_WRITE(UTIL_PIN_CTL, val | UTIL_PIN_PIPE(pipe) |
1060 				UTIL_PIN_MODE_PWM | UTIL_PIN_ENABLE);
1061 	}
1062 
1063 	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
1064 	if (pwm_ctl & BXT_BLC_PWM_ENABLE) {
1065 		DRM_DEBUG_KMS("backlight already enabled\n");
1066 		pwm_ctl &= ~BXT_BLC_PWM_ENABLE;
1067 		I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
1068 				pwm_ctl);
1069 	}
1070 
1071 	I915_WRITE(BXT_BLC_PWM_FREQ(panel->backlight.controller),
1072 			panel->backlight.max);
1073 
1074 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
1075 
1076 	pwm_ctl = 0;
1077 	if (panel->backlight.active_low_pwm)
1078 		pwm_ctl |= BXT_BLC_PWM_POLARITY;
1079 
1080 	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller), pwm_ctl);
1081 	POSTING_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
1082 	I915_WRITE(BXT_BLC_PWM_CTL(panel->backlight.controller),
1083 			pwm_ctl | BXT_BLC_PWM_ENABLE);
1084 }
1085 
1086 static void pwm_enable_backlight(struct intel_connector *connector)
1087 {
1088 	struct intel_panel *panel = &connector->panel;
1089 
1090 	pwm_enable(panel->backlight.pwm);
1091 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
1092 }
1093 
1094 void intel_panel_enable_backlight(struct intel_connector *connector)
1095 {
1096 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1097 	struct intel_panel *panel = &connector->panel;
1098 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
1099 
1100 	if (!panel->backlight.present)
1101 		return;
1102 
1103 	DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
1104 
1105 	mutex_lock(&dev_priv->backlight_lock);
1106 
1107 	WARN_ON(panel->backlight.max == 0);
1108 
1109 	if (panel->backlight.level <= panel->backlight.min) {
1110 		panel->backlight.level = panel->backlight.max;
1111 		if (panel->backlight.device)
1112 			panel->backlight.device->props.brightness =
1113 				scale_hw_to_user(connector,
1114 						 panel->backlight.level,
1115 						 panel->backlight.device->props.max_brightness);
1116 	}
1117 
1118 	panel->backlight.enable(connector);
1119 	panel->backlight.enabled = true;
1120 	if (panel->backlight.device)
1121 		panel->backlight.device->props.power = FB_BLANK_UNBLANK;
1122 
1123 	mutex_unlock(&dev_priv->backlight_lock);
1124 }
1125 
1126 #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
1127 #if 0 /* unused */
1128 static int intel_backlight_device_update_status(struct backlight_device *bd)
1129 {
1130 	struct intel_connector *connector = bl_get_data(bd);
1131 	struct intel_panel *panel = &connector->panel;
1132 	struct drm_device *dev = connector->base.dev;
1133 
1134 	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1135 	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
1136 		      bd->props.brightness, bd->props.max_brightness);
1137 	intel_panel_set_backlight(connector, bd->props.brightness,
1138 				  bd->props.max_brightness);
1139 
1140 	/*
1141 	 * Allow flipping bl_power as a sub-state of enabled. Sadly the
1142 	 * backlight class device does not make it easy to to differentiate
1143 	 * between callbacks for brightness and bl_power, so our backlight_power
1144 	 * callback needs to take this into account.
1145 	 */
1146 	if (panel->backlight.enabled) {
1147 		if (panel->backlight.power) {
1148 			bool enable = bd->props.power == FB_BLANK_UNBLANK &&
1149 				bd->props.brightness != 0;
1150 			panel->backlight.power(connector, enable);
1151 		}
1152 	} else {
1153 		bd->props.power = FB_BLANK_POWERDOWN;
1154 	}
1155 
1156 	drm_modeset_unlock(&dev->mode_config.connection_mutex);
1157 	return 0;
1158 }
1159 
1160 static int intel_backlight_device_get_brightness(struct backlight_device *bd)
1161 {
1162 	struct intel_connector *connector = bl_get_data(bd);
1163 	struct drm_device *dev = connector->base.dev;
1164 	struct drm_i915_private *dev_priv = to_i915(dev);
1165 	u32 hw_level;
1166 	int ret;
1167 
1168 	intel_runtime_pm_get(dev_priv);
1169 	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1170 
1171 	hw_level = intel_panel_get_backlight(connector);
1172 	ret = scale_hw_to_user(connector, hw_level, bd->props.max_brightness);
1173 
1174 	drm_modeset_unlock(&dev->mode_config.connection_mutex);
1175 	intel_runtime_pm_put(dev_priv);
1176 
1177 	return ret;
1178 }
1179 
1180 static const struct backlight_ops intel_backlight_device_ops = {
1181 	.update_status = intel_backlight_device_update_status,
1182 	.get_brightness = intel_backlight_device_get_brightness,
1183 };
1184 #endif
1185 
1186 int intel_backlight_device_register(struct intel_connector *connector)
1187 {
1188 	struct intel_panel *panel = &connector->panel;
1189 	struct backlight_properties props;
1190 
1191 	if (WARN_ON(panel->backlight.device))
1192 		return -ENODEV;
1193 
1194 	if (!panel->backlight.present)
1195 		return 0;
1196 
1197 	WARN_ON(panel->backlight.max == 0);
1198 
1199 	memset(&props, 0, sizeof(props));
1200 	props.type = BACKLIGHT_RAW;
1201 
1202 	/*
1203 	 * Note: Everything should work even if the backlight device max
1204 	 * presented to the userspace is arbitrarily chosen.
1205 	 */
1206 	props.max_brightness = panel->backlight.max;
1207 	props.brightness = scale_hw_to_user(connector,
1208 					    panel->backlight.level,
1209 					    props.max_brightness);
1210 
1211 	if (panel->backlight.enabled)
1212 		props.power = FB_BLANK_UNBLANK;
1213 	else
1214 		props.power = FB_BLANK_POWERDOWN;
1215 
1216 	/*
1217 	 * Note: using the same name independent of the connector prevents
1218 	 * registration of multiple backlight devices in the driver.
1219 	 */
1220 #if 0
1221 	panel->backlight.device =
1222 		backlight_device_register("intel_backlight",
1223 					  connector->base.kdev,
1224 					  connector,
1225 					  &intel_backlight_device_ops, &props);
1226 
1227 	if (IS_ERR(panel->backlight.device)) {
1228 		DRM_ERROR("Failed to register backlight: %ld\n",
1229 			  PTR_ERR(panel->backlight.device));
1230 		panel->backlight.device = NULL;
1231 		return -ENODEV;
1232 	}
1233 
1234 	DRM_DEBUG_KMS("Connector %s backlight sysfs interface registered\n",
1235 		      connector->base.name);
1236 #endif
1237 
1238 	return 0;
1239 }
1240 
1241 void intel_backlight_device_unregister(struct intel_connector *connector)
1242 {
1243 #if 0
1244 	struct intel_panel *panel = &connector->panel;
1245 
1246 	if (panel->backlight.device) {
1247 		backlight_device_unregister(panel->backlight.device);
1248 		panel->backlight.device = NULL;
1249 	}
1250 #endif
1251 }
1252 #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
1253 
1254 /*
1255  * BXT: PWM clock frequency = 19.2 MHz.
1256  */
1257 static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1258 {
1259 	return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz);
1260 }
1261 
1262 /*
1263  * SPT: This value represents the period of the PWM stream in clock periods
1264  * multiplied by 16 (default increment) or 128 (alternate increment selected in
1265  * SCHICKEN_1 bit 0). PWM clock is 24 MHz.
1266  */
1267 static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1268 {
1269 	struct intel_panel *panel = &connector->panel;
1270 	u32 mul;
1271 
1272 	if (panel->backlight.alternate_pwm_increment)
1273 		mul = 128;
1274 	else
1275 		mul = 16;
1276 
1277 	return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul);
1278 }
1279 
1280 /*
1281  * LPT: This value represents the period of the PWM stream in clock periods
1282  * multiplied by 128 (default increment) or 16 (alternate increment, selected in
1283  * LPT SOUTH_CHICKEN2 register bit 5).
1284  */
1285 static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1286 {
1287 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1288 	struct intel_panel *panel = &connector->panel;
1289 	u32 mul, clock;
1290 
1291 	if (panel->backlight.alternate_pwm_increment)
1292 		mul = 16;
1293 	else
1294 		mul = 128;
1295 
1296 	if (HAS_PCH_LPT_H(dev_priv))
1297 		clock = MHz(135); /* LPT:H */
1298 	else
1299 		clock = MHz(24); /* LPT:LP */
1300 
1301 	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
1302 }
1303 
1304 /*
1305  * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH
1306  * display raw clocks multiplied by 128.
1307  */
1308 static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1309 {
1310 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1311 
1312 	return DIV_ROUND_CLOSEST(KHz(dev_priv->rawclk_freq), pwm_freq_hz * 128);
1313 }
1314 
1315 /*
1316  * Gen2: This field determines the number of time base events (display core
1317  * clock frequency/32) in total for a complete cycle of modulated backlight
1318  * control.
1319  *
1320  * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock)
1321  * divided by 32.
1322  */
1323 static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1324 {
1325 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1326 	int clock;
1327 
1328 	if (IS_PINEVIEW(dev_priv))
1329 		clock = KHz(dev_priv->rawclk_freq);
1330 	else
1331 		clock = KHz(dev_priv->cdclk_freq);
1332 
1333 	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32);
1334 }
1335 
1336 /*
1337  * Gen4: This value represents the period of the PWM stream in display core
1338  * clocks ([DevCTG] HRAW clocks) multiplied by 128.
1339  *
1340  */
1341 static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1342 {
1343 	struct drm_device *dev = connector->base.dev;
1344 	struct drm_i915_private *dev_priv = to_i915(dev);
1345 	int clock;
1346 
1347 	if (IS_G4X(dev_priv))
1348 		clock = KHz(dev_priv->rawclk_freq);
1349 	else
1350 		clock = KHz(dev_priv->cdclk_freq);
1351 
1352 	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128);
1353 }
1354 
1355 /*
1356  * VLV: This value represents the period of the PWM stream in display core
1357  * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks
1358  * multiplied by 16. CHV uses a 19.2MHz S0IX clock.
1359  */
1360 static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1361 {
1362 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1363 	int mul, clock;
1364 
1365 	if ((I915_READ(CBR1_VLV) & CBR_PWM_CLOCK_MUX_SELECT) == 0) {
1366 		if (IS_CHERRYVIEW(dev_priv))
1367 			clock = KHz(19200);
1368 		else
1369 			clock = MHz(25);
1370 		mul = 16;
1371 	} else {
1372 		clock = KHz(dev_priv->rawclk_freq);
1373 		mul = 128;
1374 	}
1375 
1376 	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
1377 }
1378 
1379 static u32 get_backlight_max_vbt(struct intel_connector *connector)
1380 {
1381 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1382 	struct intel_panel *panel = &connector->panel;
1383 	u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
1384 	u32 pwm;
1385 
1386 	if (!panel->backlight.hz_to_pwm) {
1387 		DRM_DEBUG_KMS("backlight frequency conversion not supported\n");
1388 		return 0;
1389 	}
1390 
1391 	if (pwm_freq_hz) {
1392 		DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n",
1393 			      pwm_freq_hz);
1394 	} else {
1395 		pwm_freq_hz = 200;
1396 		DRM_DEBUG_KMS("default backlight frequency %u Hz\n",
1397 			      pwm_freq_hz);
1398 	}
1399 
1400 	pwm = panel->backlight.hz_to_pwm(connector, pwm_freq_hz);
1401 	if (!pwm) {
1402 		DRM_DEBUG_KMS("backlight frequency conversion failed\n");
1403 		return 0;
1404 	}
1405 
1406 	return pwm;
1407 }
1408 
1409 /*
1410  * Note: The setup hooks can't assume pipe is set!
1411  */
1412 static u32 get_backlight_min_vbt(struct intel_connector *connector)
1413 {
1414 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1415 	struct intel_panel *panel = &connector->panel;
1416 	int min;
1417 
1418 	WARN_ON(panel->backlight.max == 0);
1419 
1420 	/*
1421 	 * XXX: If the vbt value is 255, it makes min equal to max, which leads
1422 	 * to problems. There are such machines out there. Either our
1423 	 * interpretation is wrong or the vbt has bogus data. Or both. Safeguard
1424 	 * against this by letting the minimum be at most (arbitrarily chosen)
1425 	 * 25% of the max.
1426 	 */
1427 	min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64);
1428 	if (min != dev_priv->vbt.backlight.min_brightness) {
1429 		DRM_DEBUG_KMS("clamping VBT min backlight %d/255 to %d/255\n",
1430 			      dev_priv->vbt.backlight.min_brightness, min);
1431 	}
1432 
1433 	/* vbt value is a coefficient in range [0..255] */
1434 	return scale(min, 0, 255, 0, panel->backlight.max);
1435 }
1436 
1437 static int lpt_setup_backlight(struct intel_connector *connector, enum i915_pipe unused)
1438 {
1439 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1440 	struct intel_panel *panel = &connector->panel;
1441 	u32 pch_ctl1, pch_ctl2, val;
1442 	bool alt;
1443 
1444 	if (HAS_PCH_LPT(dev_priv))
1445 		alt = I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
1446 	else
1447 		alt = I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
1448 	panel->backlight.alternate_pwm_increment = alt;
1449 
1450 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
1451 	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
1452 
1453 	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
1454 	panel->backlight.max = pch_ctl2 >> 16;
1455 
1456 	if (!panel->backlight.max)
1457 		panel->backlight.max = get_backlight_max_vbt(connector);
1458 
1459 	if (!panel->backlight.max)
1460 		return -ENODEV;
1461 
1462 	panel->backlight.min = get_backlight_min_vbt(connector);
1463 
1464 	val = lpt_get_backlight(connector);
1465 	val = intel_panel_compute_brightness(connector, val);
1466 	panel->backlight.level = clamp(val, panel->backlight.min,
1467 				       panel->backlight.max);
1468 
1469 	panel->backlight.enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE;
1470 
1471 	return 0;
1472 }
1473 
1474 static int pch_setup_backlight(struct intel_connector *connector, enum i915_pipe unused)
1475 {
1476 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1477 	struct intel_panel *panel = &connector->panel;
1478 	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
1479 
1480 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
1481 	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
1482 
1483 	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
1484 	panel->backlight.max = pch_ctl2 >> 16;
1485 
1486 	if (!panel->backlight.max)
1487 		panel->backlight.max = get_backlight_max_vbt(connector);
1488 
1489 	if (!panel->backlight.max)
1490 		return -ENODEV;
1491 
1492 	panel->backlight.min = get_backlight_min_vbt(connector);
1493 
1494 	val = pch_get_backlight(connector);
1495 	val = intel_panel_compute_brightness(connector, val);
1496 	panel->backlight.level = clamp(val, panel->backlight.min,
1497 				       panel->backlight.max);
1498 
1499 	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
1500 	panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
1501 		(pch_ctl1 & BLM_PCH_PWM_ENABLE);
1502 
1503 	return 0;
1504 }
1505 
1506 static int i9xx_setup_backlight(struct intel_connector *connector, enum i915_pipe unused)
1507 {
1508 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1509 	struct intel_panel *panel = &connector->panel;
1510 	u32 ctl, val;
1511 
1512 	ctl = I915_READ(BLC_PWM_CTL);
1513 
1514 	if (IS_GEN2(dev_priv) || IS_I915GM(dev_priv) || IS_I945GM(dev_priv))
1515 		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
1516 
1517 	if (IS_PINEVIEW(dev_priv))
1518 		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
1519 
1520 	panel->backlight.max = ctl >> 17;
1521 
1522 	if (!panel->backlight.max) {
1523 		panel->backlight.max = get_backlight_max_vbt(connector);
1524 		panel->backlight.max >>= 1;
1525 	}
1526 
1527 	if (!panel->backlight.max)
1528 		return -ENODEV;
1529 
1530 	if (panel->backlight.combination_mode)
1531 		panel->backlight.max *= 0xff;
1532 
1533 	panel->backlight.min = get_backlight_min_vbt(connector);
1534 
1535 	val = i9xx_get_backlight(connector);
1536 	val = intel_panel_compute_brightness(connector, val);
1537 	panel->backlight.level = clamp(val, panel->backlight.min,
1538 				       panel->backlight.max);
1539 
1540 	panel->backlight.enabled = val != 0;
1541 
1542 	return 0;
1543 }
1544 
1545 static int i965_setup_backlight(struct intel_connector *connector, enum i915_pipe unused)
1546 {
1547 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1548 	struct intel_panel *panel = &connector->panel;
1549 	u32 ctl, ctl2, val;
1550 
1551 	ctl2 = I915_READ(BLC_PWM_CTL2);
1552 	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
1553 	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
1554 
1555 	ctl = I915_READ(BLC_PWM_CTL);
1556 	panel->backlight.max = ctl >> 16;
1557 
1558 	if (!panel->backlight.max)
1559 		panel->backlight.max = get_backlight_max_vbt(connector);
1560 
1561 	if (!panel->backlight.max)
1562 		return -ENODEV;
1563 
1564 	if (panel->backlight.combination_mode)
1565 		panel->backlight.max *= 0xff;
1566 
1567 	panel->backlight.min = get_backlight_min_vbt(connector);
1568 
1569 	val = i9xx_get_backlight(connector);
1570 	val = intel_panel_compute_brightness(connector, val);
1571 	panel->backlight.level = clamp(val, panel->backlight.min,
1572 				       panel->backlight.max);
1573 
1574 	panel->backlight.enabled = ctl2 & BLM_PWM_ENABLE;
1575 
1576 	return 0;
1577 }
1578 
1579 static int vlv_setup_backlight(struct intel_connector *connector, enum i915_pipe pipe)
1580 {
1581 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1582 	struct intel_panel *panel = &connector->panel;
1583 	u32 ctl, ctl2, val;
1584 
1585 	if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
1586 		return -ENODEV;
1587 
1588 	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
1589 	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
1590 
1591 	ctl = I915_READ(VLV_BLC_PWM_CTL(pipe));
1592 	panel->backlight.max = ctl >> 16;
1593 
1594 	if (!panel->backlight.max)
1595 		panel->backlight.max = get_backlight_max_vbt(connector);
1596 
1597 	if (!panel->backlight.max)
1598 		return -ENODEV;
1599 
1600 	panel->backlight.min = get_backlight_min_vbt(connector);
1601 
1602 	val = _vlv_get_backlight(dev_priv, pipe);
1603 	val = intel_panel_compute_brightness(connector, val);
1604 	panel->backlight.level = clamp(val, panel->backlight.min,
1605 				       panel->backlight.max);
1606 
1607 	panel->backlight.enabled = ctl2 & BLM_PWM_ENABLE;
1608 
1609 	return 0;
1610 }
1611 
1612 static int
1613 bxt_setup_backlight(struct intel_connector *connector, enum i915_pipe unused)
1614 {
1615 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1616 	struct intel_panel *panel = &connector->panel;
1617 	u32 pwm_ctl, val;
1618 
1619 	/*
1620 	 * For BXT hard coding the Backlight controller to 0.
1621 	 * TODO : Read the controller value from VBT and generalize
1622 	 */
1623 	panel->backlight.controller = 0;
1624 
1625 	pwm_ctl = I915_READ(BXT_BLC_PWM_CTL(panel->backlight.controller));
1626 
1627 	/* Keeping the check if controller 1 is to be programmed.
1628 	 * This will come into affect once the VBT parsing
1629 	 * is fixed for controller selection, and controller 1 is used
1630 	 * for a prticular display configuration.
1631 	 */
1632 	if (panel->backlight.controller == 1) {
1633 		val = I915_READ(UTIL_PIN_CTL);
1634 		panel->backlight.util_pin_active_low =
1635 					val & UTIL_PIN_POLARITY;
1636 	}
1637 
1638 	panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY;
1639 	panel->backlight.max =
1640 		I915_READ(BXT_BLC_PWM_FREQ(panel->backlight.controller));
1641 
1642 	if (!panel->backlight.max)
1643 		panel->backlight.max = get_backlight_max_vbt(connector);
1644 
1645 	if (!panel->backlight.max)
1646 		return -ENODEV;
1647 
1648 	val = bxt_get_backlight(connector);
1649 	val = intel_panel_compute_brightness(connector, val);
1650 	panel->backlight.level = clamp(val, panel->backlight.min,
1651 				       panel->backlight.max);
1652 
1653 	panel->backlight.enabled = pwm_ctl & BXT_BLC_PWM_ENABLE;
1654 
1655 	return 0;
1656 }
1657 
1658 static int pwm_setup_backlight(struct intel_connector *connector,
1659 			       enum i915_pipe pipe)
1660 {
1661 	struct drm_device *dev = connector->base.dev;
1662 	struct intel_panel *panel = &connector->panel;
1663 	int retval;
1664 
1665 	/* Get the PWM chip for backlight control */
1666 	panel->backlight.pwm = pwm_get(dev->dev, "pwm_backlight");
1667 	if (IS_ERR(panel->backlight.pwm)) {
1668 		DRM_ERROR("Failed to own the pwm chip\n");
1669 		panel->backlight.pwm = NULL;
1670 		return -ENODEV;
1671 	}
1672 
1673 	/*
1674 	 * FIXME: pwm_apply_args() should be removed when switching to
1675 	 * the atomic PWM API.
1676 	 */
1677 #if 0
1678 	pwm_apply_args(panel->backlight.pwm);
1679 #endif
1680 
1681 	retval = pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS,
1682 			    CRC_PMIC_PWM_PERIOD_NS);
1683 	if (retval < 0) {
1684 		DRM_ERROR("Failed to configure the pwm chip\n");
1685 		pwm_put(panel->backlight.pwm);
1686 		panel->backlight.pwm = NULL;
1687 		return retval;
1688 	}
1689 
1690 	panel->backlight.min = 0; /* 0% */
1691 	panel->backlight.max = 100; /* 100% */
1692 	panel->backlight.level = DIV_ROUND_UP(
1693 				 pwm_get_duty_cycle(panel->backlight.pwm) * 100,
1694 				 CRC_PMIC_PWM_PERIOD_NS);
1695 	panel->backlight.enabled = panel->backlight.level != 0;
1696 
1697 	return 0;
1698 }
1699 
1700 #ifdef __DragonFly__
1701 /*
1702  * Read max backlight level
1703  */
1704 static int
1705 sysctl_backlight_max(SYSCTL_HANDLER_ARGS)
1706 {
1707 	int err, val;
1708 	struct intel_connector *connector = arg1;
1709 	struct drm_device *dev = connector->base.dev;
1710 	struct drm_i915_private *dev_priv = dev->dev_private;
1711 	struct intel_panel *panel = &connector->panel;
1712 
1713 	mutex_lock(&dev_priv->backlight_lock);
1714 	val = panel->backlight.max;
1715 	mutex_unlock(&dev_priv->backlight_lock);
1716 
1717 	err = sysctl_handle_int(oidp, &val, 0, req);
1718 	return(err);
1719 }
1720 
1721 /*
1722  * Read/write backlight level
1723  */
1724 static int
1725 sysctl_backlight_handler(SYSCTL_HANDLER_ARGS)
1726 {
1727 	struct intel_connector *connector = arg1;
1728 	struct drm_device *dev = connector->base.dev;
1729 	struct drm_i915_private *dev_priv = dev->dev_private;
1730 	struct intel_panel *panel = &connector->panel;
1731 	int err, val;
1732 	u32 user_level, max_brightness;
1733 
1734 	mutex_lock(&dev_priv->backlight_lock);
1735 	max_brightness = panel->backlight.max;
1736 	user_level = scale_hw_to_user(connector, panel->backlight.level,
1737 	    max_brightness);
1738 	mutex_unlock(&dev_priv->backlight_lock);
1739 
1740 	val = user_level;
1741 	err = sysctl_handle_int(oidp, &val, 0, req);
1742 	if (err != 0 || req->newptr == NULL) {
1743 		return(err);
1744 	}
1745 
1746 	if (val != user_level && val >= 0 && val <= max_brightness) {
1747 		drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1748 		intel_panel_set_backlight(arg1, val, max_brightness);
1749 		drm_modeset_unlock(&dev->mode_config.connection_mutex);
1750 	}
1751 
1752 	return(err);
1753 }
1754 #endif /* __DragonFly__ */
1755 
1756 int intel_panel_setup_backlight(struct drm_connector *connector, enum i915_pipe pipe)
1757 {
1758 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
1759 	struct intel_connector *intel_connector = to_intel_connector(connector);
1760 	struct intel_panel *panel = &intel_connector->panel;
1761 	int ret;
1762 
1763 	if (!dev_priv->vbt.backlight.present) {
1764 		if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
1765 			DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n");
1766 		} else {
1767 			DRM_DEBUG_KMS("no backlight present per VBT\n");
1768 			return 0;
1769 		}
1770 	}
1771 
1772 	/* ensure intel_panel has been initialized first */
1773 	if (WARN_ON(!panel->backlight.setup))
1774 		return -ENODEV;
1775 
1776 	/* set level and max in panel struct */
1777 	mutex_lock(&dev_priv->backlight_lock);
1778 	ret = panel->backlight.setup(intel_connector, pipe);
1779 	mutex_unlock(&dev_priv->backlight_lock);
1780 
1781 	if (ret) {
1782 		DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
1783 			      connector->name);
1784 		return ret;
1785 	}
1786 
1787 	panel->backlight.present = true;
1788 
1789 #ifdef __DragonFly__
1790 	SYSCTL_ADD_PROC(&connector->dev->sysctl->ctx, &sysctl__hw_children,
1791 			OID_AUTO, "backlight_max",
1792 			CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_ANYBODY,
1793 			connector, sizeof(int),
1794 			sysctl_backlight_max,
1795 			"I", "Max backlight level");
1796 	SYSCTL_ADD_PROC(&connector->dev->sysctl->ctx, &sysctl__hw_children,
1797 			OID_AUTO, "backlight_level",
1798 			CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY,
1799 			connector, sizeof(int),
1800 			sysctl_backlight_handler,
1801 			"I", "Backlight level");
1802 #endif
1803 
1804 	DRM_DEBUG_KMS("Connector %s backlight initialized, %s, brightness %u/%u\n",
1805 		      connector->name,
1806 		      enableddisabled(panel->backlight.enabled),
1807 		      panel->backlight.level, panel->backlight.max);
1808 
1809 	return 0;
1810 }
1811 
1812 void intel_panel_destroy_backlight(struct drm_connector *connector)
1813 {
1814 	struct intel_connector *intel_connector = to_intel_connector(connector);
1815 	struct intel_panel *panel = &intel_connector->panel;
1816 
1817 	/* dispose of the pwm */
1818 	if (panel->backlight.pwm)
1819 		pwm_put(panel->backlight.pwm);
1820 
1821 	panel->backlight.present = false;
1822 }
1823 
1824 /* Set up chip specific backlight functions */
1825 static void
1826 intel_panel_init_backlight_funcs(struct intel_panel *panel)
1827 {
1828 	struct intel_connector *connector =
1829 		container_of(panel, struct intel_connector, panel);
1830 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1831 
1832 	if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
1833 	    intel_dp_aux_init_backlight_funcs(connector) == 0)
1834 		return;
1835 
1836 	if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI &&
1837 	    intel_dsi_dcs_init_backlight_funcs(connector) == 0)
1838 		return;
1839 
1840 	if (IS_BROXTON(dev_priv)) {
1841 		panel->backlight.setup = bxt_setup_backlight;
1842 		panel->backlight.enable = bxt_enable_backlight;
1843 		panel->backlight.disable = bxt_disable_backlight;
1844 		panel->backlight.set = bxt_set_backlight;
1845 		panel->backlight.get = bxt_get_backlight;
1846 		panel->backlight.hz_to_pwm = bxt_hz_to_pwm;
1847 	} else if (HAS_PCH_LPT(dev_priv) || HAS_PCH_SPT(dev_priv) ||
1848 		   HAS_PCH_KBP(dev_priv)) {
1849 		panel->backlight.setup = lpt_setup_backlight;
1850 		panel->backlight.enable = lpt_enable_backlight;
1851 		panel->backlight.disable = lpt_disable_backlight;
1852 		panel->backlight.set = lpt_set_backlight;
1853 		panel->backlight.get = lpt_get_backlight;
1854 		if (HAS_PCH_LPT(dev_priv))
1855 			panel->backlight.hz_to_pwm = lpt_hz_to_pwm;
1856 		else
1857 			panel->backlight.hz_to_pwm = spt_hz_to_pwm;
1858 	} else if (HAS_PCH_SPLIT(dev_priv)) {
1859 		panel->backlight.setup = pch_setup_backlight;
1860 		panel->backlight.enable = pch_enable_backlight;
1861 		panel->backlight.disable = pch_disable_backlight;
1862 		panel->backlight.set = pch_set_backlight;
1863 		panel->backlight.get = pch_get_backlight;
1864 		panel->backlight.hz_to_pwm = pch_hz_to_pwm;
1865 	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1866 		if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) {
1867 			panel->backlight.setup = pwm_setup_backlight;
1868 			panel->backlight.enable = pwm_enable_backlight;
1869 			panel->backlight.disable = pwm_disable_backlight;
1870 			panel->backlight.set = pwm_set_backlight;
1871 			panel->backlight.get = pwm_get_backlight;
1872 		} else {
1873 			panel->backlight.setup = vlv_setup_backlight;
1874 			panel->backlight.enable = vlv_enable_backlight;
1875 			panel->backlight.disable = vlv_disable_backlight;
1876 			panel->backlight.set = vlv_set_backlight;
1877 			panel->backlight.get = vlv_get_backlight;
1878 			panel->backlight.hz_to_pwm = vlv_hz_to_pwm;
1879 		}
1880 	} else if (IS_GEN4(dev_priv)) {
1881 		panel->backlight.setup = i965_setup_backlight;
1882 		panel->backlight.enable = i965_enable_backlight;
1883 		panel->backlight.disable = i965_disable_backlight;
1884 		panel->backlight.set = i9xx_set_backlight;
1885 		panel->backlight.get = i9xx_get_backlight;
1886 		panel->backlight.hz_to_pwm = i965_hz_to_pwm;
1887 	} else {
1888 		panel->backlight.setup = i9xx_setup_backlight;
1889 		panel->backlight.enable = i9xx_enable_backlight;
1890 		panel->backlight.disable = i9xx_disable_backlight;
1891 		panel->backlight.set = i9xx_set_backlight;
1892 		panel->backlight.get = i9xx_get_backlight;
1893 		panel->backlight.hz_to_pwm = i9xx_hz_to_pwm;
1894 	}
1895 }
1896 
1897 int intel_panel_init(struct intel_panel *panel,
1898 		     struct drm_display_mode *fixed_mode,
1899 		     struct drm_display_mode *downclock_mode)
1900 {
1901 	intel_panel_init_backlight_funcs(panel);
1902 
1903 	panel->fixed_mode = fixed_mode;
1904 	panel->downclock_mode = downclock_mode;
1905 
1906 	return 0;
1907 }
1908 
1909 void intel_panel_fini(struct intel_panel *panel)
1910 {
1911 	struct intel_connector *intel_connector =
1912 		container_of(panel, struct intel_connector, panel);
1913 
1914 	if (panel->fixed_mode)
1915 		drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
1916 
1917 	if (panel->downclock_mode)
1918 		drm_mode_destroy(intel_connector->base.dev,
1919 				panel->downclock_mode);
1920 }
1921