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/moduleparam.h>
34 #include <linux/module.h>
35 #include <linux/printk.h>
36 #include <asm/div64.h>
37 #include "intel_drv.h"
38 
39 void
intel_fixed_panel_mode(const struct drm_display_mode * fixed_mode,struct drm_display_mode * adjusted_mode)40 intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
41 		       struct drm_display_mode *adjusted_mode)
42 {
43 	drm_mode_copy(adjusted_mode, fixed_mode);
44 
45 	drm_mode_set_crtcinfo(adjusted_mode, 0);
46 }
47 
48 /* adjusted_mode has been preset to be the panel's fixed mode */
49 void
intel_pch_panel_fitting(struct intel_crtc * intel_crtc,struct intel_crtc_config * pipe_config,int fitting_mode)50 intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
51 			struct intel_crtc_config *pipe_config,
52 			int fitting_mode)
53 {
54 	struct drm_display_mode *adjusted_mode;
55 	int x, y, width, height;
56 
57 	adjusted_mode = &pipe_config->adjusted_mode;
58 
59 	x = y = width = height = 0;
60 
61 	/* Native modes don't need fitting */
62 	if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
63 	    adjusted_mode->vdisplay == pipe_config->pipe_src_h)
64 		goto done;
65 
66 	switch (fitting_mode) {
67 	case DRM_MODE_SCALE_CENTER:
68 		width = pipe_config->pipe_src_w;
69 		height = pipe_config->pipe_src_h;
70 		x = (adjusted_mode->hdisplay - width + 1)/2;
71 		y = (adjusted_mode->vdisplay - height + 1)/2;
72 		break;
73 
74 	case DRM_MODE_SCALE_ASPECT:
75 		/* Scale but preserve the aspect ratio */
76 		{
77 			u32 scaled_width = adjusted_mode->hdisplay
78 				* pipe_config->pipe_src_h;
79 			u32 scaled_height = pipe_config->pipe_src_w
80 				* adjusted_mode->vdisplay;
81 			if (scaled_width > scaled_height) { /* pillar */
82 				width = scaled_height / pipe_config->pipe_src_h;
83 				if (width & 1)
84 					width++;
85 				x = (adjusted_mode->hdisplay - width + 1) / 2;
86 				y = 0;
87 				height = adjusted_mode->vdisplay;
88 			} else if (scaled_width < scaled_height) { /* letter */
89 				height = scaled_width / pipe_config->pipe_src_w;
90 				if (height & 1)
91 				    height++;
92 				y = (adjusted_mode->vdisplay - height + 1) / 2;
93 				x = 0;
94 				width = adjusted_mode->hdisplay;
95 			} else {
96 				x = y = 0;
97 				width = adjusted_mode->hdisplay;
98 				height = adjusted_mode->vdisplay;
99 			}
100 		}
101 		break;
102 
103 	case DRM_MODE_SCALE_FULLSCREEN:
104 		x = y = 0;
105 		width = adjusted_mode->hdisplay;
106 		height = adjusted_mode->vdisplay;
107 		break;
108 
109 	default:
110 		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
111 		return;
112 	}
113 
114 done:
115 	pipe_config->pch_pfit.pos = (x << 16) | y;
116 	pipe_config->pch_pfit.size = (width << 16) | height;
117 	pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0;
118 }
119 
120 static void
centre_horizontally(struct drm_display_mode * mode,int width)121 centre_horizontally(struct drm_display_mode *mode,
122 		    int width)
123 {
124 	u32 border, sync_pos, blank_width, sync_width;
125 
126 	/* keep the hsync and hblank widths constant */
127 	sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start;
128 	blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start;
129 	sync_pos = (blank_width - sync_width + 1) / 2;
130 
131 	border = (mode->hdisplay - width + 1) / 2;
132 	border += border & 1; /* make the border even */
133 
134 	mode->crtc_hdisplay = width;
135 	mode->crtc_hblank_start = width + border;
136 	mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width;
137 
138 	mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
139 	mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
140 }
141 
142 static void
centre_vertically(struct drm_display_mode * mode,int height)143 centre_vertically(struct drm_display_mode *mode,
144 		  int height)
145 {
146 	u32 border, sync_pos, blank_width, sync_width;
147 
148 	/* keep the vsync and vblank widths constant */
149 	sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start;
150 	blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start;
151 	sync_pos = (blank_width - sync_width + 1) / 2;
152 
153 	border = (mode->vdisplay - height + 1) / 2;
154 
155 	mode->crtc_vdisplay = height;
156 	mode->crtc_vblank_start = height + border;
157 	mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width;
158 
159 	mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
160 	mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
161 }
162 
panel_fitter_scaling(u32 source,u32 target)163 static inline u32 panel_fitter_scaling(u32 source, u32 target)
164 {
165 	/*
166 	 * Floating point operation is not supported. So the FACTOR
167 	 * is defined, which can avoid the floating point computation
168 	 * when calculating the panel ratio.
169 	 */
170 #define ACCURACY 12
171 #define FACTOR (1 << ACCURACY)
172 	u32 ratio = source * FACTOR / target;
173 	return (FACTOR * ratio + FACTOR/2) / FACTOR;
174 }
175 
i965_scale_aspect(struct intel_crtc_config * pipe_config,u32 * pfit_control)176 static void i965_scale_aspect(struct intel_crtc_config *pipe_config,
177 			      u32 *pfit_control)
178 {
179 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
180 	u32 scaled_width = adjusted_mode->hdisplay *
181 		pipe_config->pipe_src_h;
182 	u32 scaled_height = pipe_config->pipe_src_w *
183 		adjusted_mode->vdisplay;
184 
185 	/* 965+ is easy, it does everything in hw */
186 	if (scaled_width > scaled_height)
187 		*pfit_control |= PFIT_ENABLE |
188 			PFIT_SCALING_PILLAR;
189 	else if (scaled_width < scaled_height)
190 		*pfit_control |= PFIT_ENABLE |
191 			PFIT_SCALING_LETTER;
192 	else if (adjusted_mode->hdisplay != pipe_config->pipe_src_w)
193 		*pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
194 }
195 
i9xx_scale_aspect(struct intel_crtc_config * pipe_config,u32 * pfit_control,u32 * pfit_pgm_ratios,u32 * border)196 static void i9xx_scale_aspect(struct intel_crtc_config *pipe_config,
197 			      u32 *pfit_control, u32 *pfit_pgm_ratios,
198 			      u32 *border)
199 {
200 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
201 	u32 scaled_width = adjusted_mode->hdisplay *
202 		pipe_config->pipe_src_h;
203 	u32 scaled_height = pipe_config->pipe_src_w *
204 		adjusted_mode->vdisplay;
205 	u32 bits;
206 
207 	/*
208 	 * For earlier chips we have to calculate the scaling
209 	 * ratio by hand and program it into the
210 	 * PFIT_PGM_RATIO register
211 	 */
212 	if (scaled_width > scaled_height) { /* pillar */
213 		centre_horizontally(adjusted_mode,
214 				    scaled_height /
215 				    pipe_config->pipe_src_h);
216 
217 		*border = LVDS_BORDER_ENABLE;
218 		if (pipe_config->pipe_src_h != adjusted_mode->vdisplay) {
219 			bits = panel_fitter_scaling(pipe_config->pipe_src_h,
220 						    adjusted_mode->vdisplay);
221 
222 			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
223 					     bits << PFIT_VERT_SCALE_SHIFT);
224 			*pfit_control |= (PFIT_ENABLE |
225 					  VERT_INTERP_BILINEAR |
226 					  HORIZ_INTERP_BILINEAR);
227 		}
228 	} else if (scaled_width < scaled_height) { /* letter */
229 		centre_vertically(adjusted_mode,
230 				  scaled_width /
231 				  pipe_config->pipe_src_w);
232 
233 		*border = LVDS_BORDER_ENABLE;
234 		if (pipe_config->pipe_src_w != adjusted_mode->hdisplay) {
235 			bits = panel_fitter_scaling(pipe_config->pipe_src_w,
236 						    adjusted_mode->hdisplay);
237 
238 			*pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
239 					     bits << PFIT_VERT_SCALE_SHIFT);
240 			*pfit_control |= (PFIT_ENABLE |
241 					  VERT_INTERP_BILINEAR |
242 					  HORIZ_INTERP_BILINEAR);
243 		}
244 	} else {
245 		/* Aspects match, Let hw scale both directions */
246 		*pfit_control |= (PFIT_ENABLE |
247 				  VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
248 				  VERT_INTERP_BILINEAR |
249 				  HORIZ_INTERP_BILINEAR);
250 	}
251 }
252 
intel_gmch_panel_fitting(struct intel_crtc * intel_crtc,struct intel_crtc_config * pipe_config,int fitting_mode)253 void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
254 			      struct intel_crtc_config *pipe_config,
255 			      int fitting_mode)
256 {
257 	struct drm_device *dev = intel_crtc->base.dev;
258 	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
259 	struct drm_display_mode *adjusted_mode;
260 
261 	adjusted_mode = &pipe_config->adjusted_mode;
262 
263 	/* Native modes don't need fitting */
264 	if (adjusted_mode->hdisplay == pipe_config->pipe_src_w &&
265 	    adjusted_mode->vdisplay == pipe_config->pipe_src_h)
266 		goto out;
267 
268 	switch (fitting_mode) {
269 	case DRM_MODE_SCALE_CENTER:
270 		/*
271 		 * For centered modes, we have to calculate border widths &
272 		 * heights and modify the values programmed into the CRTC.
273 		 */
274 		centre_horizontally(adjusted_mode, pipe_config->pipe_src_w);
275 		centre_vertically(adjusted_mode, pipe_config->pipe_src_h);
276 		border = LVDS_BORDER_ENABLE;
277 		break;
278 	case DRM_MODE_SCALE_ASPECT:
279 		/* Scale but preserve the aspect ratio */
280 		if (INTEL_INFO(dev)->gen >= 4)
281 			i965_scale_aspect(pipe_config, &pfit_control);
282 		else
283 			i9xx_scale_aspect(pipe_config, &pfit_control,
284 					  &pfit_pgm_ratios, &border);
285 		break;
286 	case DRM_MODE_SCALE_FULLSCREEN:
287 		/*
288 		 * Full scaling, even if it changes the aspect ratio.
289 		 * Fortunately this is all done for us in hw.
290 		 */
291 		if (pipe_config->pipe_src_h != adjusted_mode->vdisplay ||
292 		    pipe_config->pipe_src_w != adjusted_mode->hdisplay) {
293 			pfit_control |= PFIT_ENABLE;
294 			if (INTEL_INFO(dev)->gen >= 4)
295 				pfit_control |= PFIT_SCALING_AUTO;
296 			else
297 				pfit_control |= (VERT_AUTO_SCALE |
298 						 VERT_INTERP_BILINEAR |
299 						 HORIZ_AUTO_SCALE |
300 						 HORIZ_INTERP_BILINEAR);
301 		}
302 		break;
303 	default:
304 		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
305 		return;
306 	}
307 
308 	/* 965+ wants fuzzy fitting */
309 	/* FIXME: handle multiple panels by failing gracefully */
310 	if (INTEL_INFO(dev)->gen >= 4)
311 		pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
312 				 PFIT_FILTER_FUZZY);
313 
314 out:
315 	if ((pfit_control & PFIT_ENABLE) == 0) {
316 		pfit_control = 0;
317 		pfit_pgm_ratios = 0;
318 	}
319 
320 	/* Make sure pre-965 set dither correctly for 18bpp panels. */
321 	if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18)
322 		pfit_control |= PANEL_8TO6_DITHER_ENABLE;
323 
324 	pipe_config->gmch_pfit.control = pfit_control;
325 	pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
326 	pipe_config->gmch_pfit.lvds_border_bits = border;
327 }
328 
intel_panel_compute_brightness(struct intel_connector * connector,u32 val)329 static u32 intel_panel_compute_brightness(struct intel_connector *connector,
330 					  u32 val)
331 {
332 	struct drm_device *dev = connector->base.dev;
333 	struct drm_i915_private *dev_priv = dev->dev_private;
334 	struct intel_panel *panel = &connector->panel;
335 
336 	WARN_ON(panel->backlight.max == 0);
337 
338 	if (i915.invert_brightness < 0)
339 		return val;
340 
341 	if (i915.invert_brightness > 0 ||
342 	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
343 		return panel->backlight.max - val;
344 	}
345 
346 	return val;
347 }
348 
bdw_get_backlight(struct intel_connector * connector)349 static u32 bdw_get_backlight(struct intel_connector *connector)
350 {
351 	struct drm_device *dev = connector->base.dev;
352 	struct drm_i915_private *dev_priv = dev->dev_private;
353 
354 	return I915_READ(BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK;
355 }
356 
pch_get_backlight(struct intel_connector * connector)357 static u32 pch_get_backlight(struct intel_connector *connector)
358 {
359 	struct drm_device *dev = connector->base.dev;
360 	struct drm_i915_private *dev_priv = dev->dev_private;
361 
362 	return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
363 }
364 
i9xx_get_backlight(struct intel_connector * connector)365 static u32 i9xx_get_backlight(struct intel_connector *connector)
366 {
367 	struct drm_device *dev = connector->base.dev;
368 	struct drm_i915_private *dev_priv = dev->dev_private;
369 	struct intel_panel *panel = &connector->panel;
370 	u32 val;
371 
372 	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
373 	if (INTEL_INFO(dev)->gen < 4)
374 		val >>= 1;
375 
376 	if (panel->backlight.combination_mode) {
377 		u8 lbpc;
378 
379 		pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
380 		val *= lbpc;
381 	}
382 
383 	return val;
384 }
385 
_vlv_get_backlight(struct drm_device * dev,enum i915_pipe pipe)386 static u32 _vlv_get_backlight(struct drm_device *dev, enum i915_pipe pipe)
387 {
388 	struct drm_i915_private *dev_priv = dev->dev_private;
389 
390 	return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
391 }
392 
vlv_get_backlight(struct intel_connector * connector)393 static u32 vlv_get_backlight(struct intel_connector *connector)
394 {
395 	struct drm_device *dev = connector->base.dev;
396 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
397 
398 	return _vlv_get_backlight(dev, pipe);
399 }
400 
401 #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
intel_panel_get_backlight(struct intel_connector * connector)402 static u32 intel_panel_get_backlight(struct intel_connector *connector)
403 {
404 	struct drm_device *dev = connector->base.dev;
405 	struct drm_i915_private *dev_priv = dev->dev_private;
406 	u32 val;
407 	unsigned long flags;
408 
409 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
410 
411 	val = dev_priv->display.get_backlight(connector);
412 	val = intel_panel_compute_brightness(connector, val);
413 
414 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
415 
416 	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
417 	return val;
418 }
419 #endif
420 
bdw_set_backlight(struct intel_connector * connector,u32 level)421 static void bdw_set_backlight(struct intel_connector *connector, u32 level)
422 {
423 	struct drm_device *dev = connector->base.dev;
424 	struct drm_i915_private *dev_priv = dev->dev_private;
425 	u32 val = I915_READ(BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK;
426 	I915_WRITE(BLC_PWM_PCH_CTL2, val | level);
427 }
428 
pch_set_backlight(struct intel_connector * connector,u32 level)429 static void pch_set_backlight(struct intel_connector *connector, u32 level)
430 {
431 	struct drm_device *dev = connector->base.dev;
432 	struct drm_i915_private *dev_priv = dev->dev_private;
433 	u32 tmp;
434 
435 	tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
436 	I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
437 }
438 
i9xx_set_backlight(struct intel_connector * connector,u32 level)439 static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
440 {
441 	struct drm_device *dev = connector->base.dev;
442 	struct drm_i915_private *dev_priv = dev->dev_private;
443 	struct intel_panel *panel = &connector->panel;
444 	u32 tmp, mask;
445 
446 	WARN_ON(panel->backlight.max == 0);
447 
448 	if (panel->backlight.combination_mode) {
449 		u8 lbpc;
450 
451 		lbpc = level * 0xfe / panel->backlight.max + 1;
452 		level /= lbpc;
453 		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
454 	}
455 
456 	if (IS_GEN4(dev)) {
457 		mask = BACKLIGHT_DUTY_CYCLE_MASK;
458 	} else {
459 		level <<= 1;
460 		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
461 	}
462 
463 	tmp = I915_READ(BLC_PWM_CTL) & ~mask;
464 	I915_WRITE(BLC_PWM_CTL, tmp | level);
465 }
466 
vlv_set_backlight(struct intel_connector * connector,u32 level)467 static void vlv_set_backlight(struct intel_connector *connector, u32 level)
468 {
469 	struct drm_device *dev = connector->base.dev;
470 	struct drm_i915_private *dev_priv = dev->dev_private;
471 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
472 	u32 tmp;
473 
474 	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
475 	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
476 }
477 
478 static void
intel_panel_actually_set_backlight(struct intel_connector * connector,u32 level)479 intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
480 {
481 	struct drm_device *dev = connector->base.dev;
482 	struct drm_i915_private *dev_priv = dev->dev_private;
483 
484 	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
485 
486 	level = intel_panel_compute_brightness(connector, level);
487 	dev_priv->display.set_backlight(connector, level);
488 }
489 
490 /* set backlight brightness to level in range [0..max] */
intel_panel_set_backlight(struct intel_connector * connector,u32 level,u32 max)491 void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
492 			       u32 max)
493 {
494 	struct drm_device *dev = connector->base.dev;
495 	struct drm_i915_private *dev_priv = dev->dev_private;
496 	struct intel_panel *panel = &connector->panel;
497 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
498 	u32 freq;
499 	unsigned long flags;
500 	u64 n;
501 
502 	if (!panel->backlight.present || pipe == INVALID_PIPE)
503 		return;
504 
505 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
506 
507 	WARN_ON(panel->backlight.max == 0);
508 
509 	/* scale to hardware max, but be careful to not overflow */
510 	freq = panel->backlight.max;
511 	n = (u64)level * freq;
512 	do_div(n, max);
513 	level = n;
514 
515 	panel->backlight.level = level;
516 #ifndef __NetBSD__		/* XXX backlight */
517 	if (panel->backlight.device)
518 		panel->backlight.device->props.brightness = level;
519 #endif
520 
521 	if (panel->backlight.enabled)
522 		intel_panel_actually_set_backlight(connector, level);
523 
524 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
525 }
526 
pch_disable_backlight(struct intel_connector * connector)527 static void pch_disable_backlight(struct intel_connector *connector)
528 {
529 	struct drm_device *dev = connector->base.dev;
530 	struct drm_i915_private *dev_priv = dev->dev_private;
531 	u32 tmp;
532 
533 	intel_panel_actually_set_backlight(connector, 0);
534 
535 	tmp = I915_READ(BLC_PWM_CPU_CTL2);
536 	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
537 
538 	tmp = I915_READ(BLC_PWM_PCH_CTL1);
539 	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
540 }
541 
i9xx_disable_backlight(struct intel_connector * connector)542 static void i9xx_disable_backlight(struct intel_connector *connector)
543 {
544 	intel_panel_actually_set_backlight(connector, 0);
545 }
546 
i965_disable_backlight(struct intel_connector * connector)547 static void i965_disable_backlight(struct intel_connector *connector)
548 {
549 	struct drm_device *dev = connector->base.dev;
550 	struct drm_i915_private *dev_priv = dev->dev_private;
551 	u32 tmp;
552 
553 	intel_panel_actually_set_backlight(connector, 0);
554 
555 	tmp = I915_READ(BLC_PWM_CTL2);
556 	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
557 }
558 
vlv_disable_backlight(struct intel_connector * connector)559 static void vlv_disable_backlight(struct intel_connector *connector)
560 {
561 	struct drm_device *dev = connector->base.dev;
562 	struct drm_i915_private *dev_priv = dev->dev_private;
563 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
564 	u32 tmp;
565 
566 	intel_panel_actually_set_backlight(connector, 0);
567 
568 	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
569 	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
570 }
571 
intel_panel_disable_backlight(struct intel_connector * connector)572 void intel_panel_disable_backlight(struct intel_connector *connector)
573 {
574 	struct drm_device *dev = connector->base.dev;
575 	struct drm_i915_private *dev_priv = dev->dev_private;
576 	struct intel_panel *panel = &connector->panel;
577 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
578 	unsigned long flags;
579 
580 	if (!panel->backlight.present || pipe == INVALID_PIPE)
581 		return;
582 
583 	/*
584 	 * Do not disable backlight on the vgaswitcheroo path. When switching
585 	 * away from i915, the other client may depend on i915 to handle the
586 	 * backlight. This will leave the backlight on unnecessarily when
587 	 * another client is not activated.
588 	 */
589 	if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) {
590 		DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
591 		return;
592 	}
593 
594 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
595 
596 	panel->backlight.enabled = false;
597 	dev_priv->display.disable_backlight(connector);
598 
599 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
600 }
601 
bdw_enable_backlight(struct intel_connector * connector)602 static void bdw_enable_backlight(struct intel_connector *connector)
603 {
604 	struct drm_device *dev = connector->base.dev;
605 	struct drm_i915_private *dev_priv = dev->dev_private;
606 	struct intel_panel *panel = &connector->panel;
607 	u32 pch_ctl1, pch_ctl2;
608 
609 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
610 	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
611 		DRM_DEBUG_KMS("pch backlight already enabled\n");
612 		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
613 		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
614 	}
615 
616 	pch_ctl2 = panel->backlight.max << 16;
617 	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
618 
619 	pch_ctl1 = 0;
620 	if (panel->backlight.active_low_pwm)
621 		pch_ctl1 |= BLM_PCH_POLARITY;
622 
623 	/* BDW always uses the pch pwm controls. */
624 	pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
625 
626 	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
627 	POSTING_READ(BLC_PWM_PCH_CTL1);
628 	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
629 
630 	/* This won't stick until the above enable. */
631 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
632 }
633 
pch_enable_backlight(struct intel_connector * connector)634 static void pch_enable_backlight(struct intel_connector *connector)
635 {
636 	struct drm_device *dev = connector->base.dev;
637 	struct drm_i915_private *dev_priv = dev->dev_private;
638 	struct intel_panel *panel = &connector->panel;
639 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
640 	enum transcoder cpu_transcoder =
641 		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
642 	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
643 
644 	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
645 	if (cpu_ctl2 & BLM_PWM_ENABLE) {
646 		WARN(1, "cpu backlight already enabled\n");
647 		cpu_ctl2 &= ~BLM_PWM_ENABLE;
648 		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
649 	}
650 
651 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
652 	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
653 		DRM_DEBUG_KMS("pch backlight already enabled\n");
654 		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
655 		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
656 	}
657 
658 	if (cpu_transcoder == TRANSCODER_EDP)
659 		cpu_ctl2 = BLM_TRANSCODER_EDP;
660 	else
661 		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
662 	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
663 	POSTING_READ(BLC_PWM_CPU_CTL2);
664 	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
665 
666 	/* This won't stick until the above enable. */
667 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
668 
669 	pch_ctl2 = panel->backlight.max << 16;
670 	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
671 
672 	pch_ctl1 = 0;
673 	if (panel->backlight.active_low_pwm)
674 		pch_ctl1 |= BLM_PCH_POLARITY;
675 
676 	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
677 	POSTING_READ(BLC_PWM_PCH_CTL1);
678 	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
679 }
680 
i9xx_enable_backlight(struct intel_connector * connector)681 static void i9xx_enable_backlight(struct intel_connector *connector)
682 {
683 	struct drm_device *dev = connector->base.dev;
684 	struct drm_i915_private *dev_priv = dev->dev_private;
685 	struct intel_panel *panel = &connector->panel;
686 	u32 ctl, freq;
687 
688 	ctl = I915_READ(BLC_PWM_CTL);
689 	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
690 		WARN(1, "backlight already enabled\n");
691 		I915_WRITE(BLC_PWM_CTL, 0);
692 	}
693 
694 	freq = panel->backlight.max;
695 	if (panel->backlight.combination_mode)
696 		freq /= 0xff;
697 
698 	ctl = freq << 17;
699 	if (panel->backlight.combination_mode)
700 		ctl |= BLM_LEGACY_MODE;
701 	if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm)
702 		ctl |= BLM_POLARITY_PNV;
703 
704 	I915_WRITE(BLC_PWM_CTL, ctl);
705 	POSTING_READ(BLC_PWM_CTL);
706 
707 	/* XXX: combine this into above write? */
708 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
709 }
710 
i965_enable_backlight(struct intel_connector * connector)711 static void i965_enable_backlight(struct intel_connector *connector)
712 {
713 	struct drm_device *dev = connector->base.dev;
714 	struct drm_i915_private *dev_priv = dev->dev_private;
715 	struct intel_panel *panel = &connector->panel;
716 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
717 	u32 ctl, ctl2, freq;
718 
719 	ctl2 = I915_READ(BLC_PWM_CTL2);
720 	if (ctl2 & BLM_PWM_ENABLE) {
721 		WARN(1, "backlight already enabled\n");
722 		ctl2 &= ~BLM_PWM_ENABLE;
723 		I915_WRITE(BLC_PWM_CTL2, ctl2);
724 	}
725 
726 	freq = panel->backlight.max;
727 	if (panel->backlight.combination_mode)
728 		freq /= 0xff;
729 
730 	ctl = freq << 16;
731 	I915_WRITE(BLC_PWM_CTL, ctl);
732 
733 	ctl2 = BLM_PIPE(pipe);
734 	if (panel->backlight.combination_mode)
735 		ctl2 |= BLM_COMBINATION_MODE;
736 	if (panel->backlight.active_low_pwm)
737 		ctl2 |= BLM_POLARITY_I965;
738 	I915_WRITE(BLC_PWM_CTL2, ctl2);
739 	POSTING_READ(BLC_PWM_CTL2);
740 	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
741 
742 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
743 }
744 
vlv_enable_backlight(struct intel_connector * connector)745 static void vlv_enable_backlight(struct intel_connector *connector)
746 {
747 	struct drm_device *dev = connector->base.dev;
748 	struct drm_i915_private *dev_priv = dev->dev_private;
749 	struct intel_panel *panel = &connector->panel;
750 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
751 	u32 ctl, ctl2;
752 
753 	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
754 	if (ctl2 & BLM_PWM_ENABLE) {
755 		WARN(1, "backlight already enabled\n");
756 		ctl2 &= ~BLM_PWM_ENABLE;
757 		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
758 	}
759 
760 	ctl = panel->backlight.max << 16;
761 	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
762 
763 	/* XXX: combine this into above write? */
764 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
765 
766 	ctl2 = 0;
767 	if (panel->backlight.active_low_pwm)
768 		ctl2 |= BLM_POLARITY_I965;
769 	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
770 	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
771 	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
772 }
773 
intel_panel_enable_backlight(struct intel_connector * connector)774 void intel_panel_enable_backlight(struct intel_connector *connector)
775 {
776 	struct drm_device *dev = connector->base.dev;
777 	struct drm_i915_private *dev_priv = dev->dev_private;
778 	struct intel_panel *panel = &connector->panel;
779 	enum i915_pipe pipe = intel_get_pipe_from_connector(connector);
780 	unsigned long flags;
781 
782 	if (!panel->backlight.present || pipe == INVALID_PIPE)
783 		return;
784 
785 	DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
786 
787 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
788 
789 	WARN_ON(panel->backlight.max == 0);
790 
791 	if (panel->backlight.level == 0) {
792 		panel->backlight.level = panel->backlight.max;
793 #ifndef __NetBSD__		/* XXX backlight */
794 		if (panel->backlight.device)
795 			panel->backlight.device->props.brightness =
796 				panel->backlight.level;
797 #endif
798 	}
799 
800 	dev_priv->display.enable_backlight(connector);
801 	panel->backlight.enabled = true;
802 
803 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
804 }
805 
806 #ifdef __NetBSD__		/* XXX This is worse than the others!  */
807 static inline uint32_t
ioread32(const uint32_t __acpi_iomem * ptr)808 ioread32(const uint32_t __acpi_iomem *ptr)
809 {
810 	const uint32_t value = *ptr;
811 
812 	__insn_barrier();
813 	return value;
814 }
815 #endif
816 
817 enum drm_connector_status
intel_panel_detect(struct drm_device * dev)818 intel_panel_detect(struct drm_device *dev)
819 {
820 	struct drm_i915_private *dev_priv = dev->dev_private;
821 
822 	/* Assume that the BIOS does not lie through the OpRegion... */
823 	if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) {
824 		return ioread32(dev_priv->opregion.lid_state) & 0x1 ?
825 			connector_status_connected :
826 			connector_status_disconnected;
827 	}
828 
829 	switch (i915.panel_ignore_lid) {
830 	case -2:
831 		return connector_status_connected;
832 	case -1:
833 		return connector_status_disconnected;
834 	default:
835 		return connector_status_unknown;
836 	}
837 }
838 
839 #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
intel_backlight_device_update_status(struct backlight_device * bd)840 static int intel_backlight_device_update_status(struct backlight_device *bd)
841 {
842 	struct intel_connector *connector = bl_get_data(bd);
843 	struct drm_device *dev = connector->base.dev;
844 
845 	mutex_lock(&dev->mode_config.mutex);
846 	DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
847 		      bd->props.brightness, bd->props.max_brightness);
848 	intel_panel_set_backlight(connector, bd->props.brightness,
849 				  bd->props.max_brightness);
850 	mutex_unlock(&dev->mode_config.mutex);
851 	return 0;
852 }
853 
intel_backlight_device_get_brightness(struct backlight_device * bd)854 static int intel_backlight_device_get_brightness(struct backlight_device *bd)
855 {
856 	struct intel_connector *connector = bl_get_data(bd);
857 	struct drm_device *dev = connector->base.dev;
858 	struct drm_i915_private *dev_priv = dev->dev_private;
859 	int ret;
860 
861 	intel_runtime_pm_get(dev_priv);
862 	mutex_lock(&dev->mode_config.mutex);
863 	ret = intel_panel_get_backlight(connector);
864 	mutex_unlock(&dev->mode_config.mutex);
865 	intel_runtime_pm_put(dev_priv);
866 
867 	return ret;
868 }
869 
870 static const struct backlight_ops intel_backlight_device_ops = {
871 	.update_status = intel_backlight_device_update_status,
872 	.get_brightness = intel_backlight_device_get_brightness,
873 };
874 
intel_backlight_device_register(struct intel_connector * connector)875 static int intel_backlight_device_register(struct intel_connector *connector)
876 {
877 	struct intel_panel *panel = &connector->panel;
878 	struct backlight_properties props;
879 
880 	if (WARN_ON(panel->backlight.device))
881 		return -ENODEV;
882 
883 	BUG_ON(panel->backlight.max == 0);
884 
885 	memset(&props, 0, sizeof(props));
886 	props.type = BACKLIGHT_RAW;
887 	props.brightness = panel->backlight.level;
888 	props.max_brightness = panel->backlight.max;
889 
890 	/*
891 	 * Note: using the same name independent of the connector prevents
892 	 * registration of multiple backlight devices in the driver.
893 	 */
894 	panel->backlight.device =
895 		backlight_device_register("intel_backlight",
896 					  connector->base.kdev,
897 					  connector,
898 					  &intel_backlight_device_ops, &props);
899 
900 	if (IS_ERR(panel->backlight.device)) {
901 		DRM_ERROR("Failed to register backlight: %ld\n",
902 			  PTR_ERR(panel->backlight.device));
903 		panel->backlight.device = NULL;
904 		return -ENODEV;
905 	}
906 	return 0;
907 }
908 
intel_backlight_device_unregister(struct intel_connector * connector)909 static void intel_backlight_device_unregister(struct intel_connector *connector)
910 {
911 	struct intel_panel *panel = &connector->panel;
912 
913 	if (panel->backlight.device) {
914 		backlight_device_unregister(panel->backlight.device);
915 		panel->backlight.device = NULL;
916 	}
917 }
918 #else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
intel_backlight_device_register(struct intel_connector * connector)919 static int intel_backlight_device_register(struct intel_connector *connector)
920 {
921 	return 0;
922 }
intel_backlight_device_unregister(struct intel_connector * connector)923 static void intel_backlight_device_unregister(struct intel_connector *connector)
924 {
925 }
926 #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
927 
928 /*
929  * Note: The setup hooks can't assume pipe is set!
930  *
931  * XXX: Query mode clock or hardware clock and program PWM modulation frequency
932  * appropriately when it's 0. Use VBT and/or sane defaults.
933  */
bdw_setup_backlight(struct intel_connector * connector)934 static int bdw_setup_backlight(struct intel_connector *connector)
935 {
936 	struct drm_device *dev = connector->base.dev;
937 	struct drm_i915_private *dev_priv = dev->dev_private;
938 	struct intel_panel *panel = &connector->panel;
939 	u32 pch_ctl1, pch_ctl2, val;
940 
941 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
942 	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
943 
944 	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
945 	panel->backlight.max = pch_ctl2 >> 16;
946 	if (!panel->backlight.max)
947 		return -ENODEV;
948 
949 	val = bdw_get_backlight(connector);
950 	panel->backlight.level = intel_panel_compute_brightness(connector, val);
951 
952 	panel->backlight.enabled = (pch_ctl1 & BLM_PCH_PWM_ENABLE) &&
953 		panel->backlight.level != 0;
954 
955 	return 0;
956 }
957 
pch_setup_backlight(struct intel_connector * connector)958 static int pch_setup_backlight(struct intel_connector *connector)
959 {
960 	struct drm_device *dev = connector->base.dev;
961 	struct drm_i915_private *dev_priv = dev->dev_private;
962 	struct intel_panel *panel = &connector->panel;
963 	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
964 
965 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
966 	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
967 
968 	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
969 	panel->backlight.max = pch_ctl2 >> 16;
970 	if (!panel->backlight.max)
971 		return -ENODEV;
972 
973 	val = pch_get_backlight(connector);
974 	panel->backlight.level = intel_panel_compute_brightness(connector, val);
975 
976 	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
977 	panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
978 		(pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0;
979 
980 	return 0;
981 }
982 
i9xx_setup_backlight(struct intel_connector * connector)983 static int i9xx_setup_backlight(struct intel_connector *connector)
984 {
985 	struct drm_device *dev = connector->base.dev;
986 	struct drm_i915_private *dev_priv = dev->dev_private;
987 	struct intel_panel *panel = &connector->panel;
988 	u32 ctl, val;
989 
990 	ctl = I915_READ(BLC_PWM_CTL);
991 
992 	if (IS_GEN2(dev) || IS_I915GM(dev) || IS_I945GM(dev))
993 		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
994 
995 	if (IS_PINEVIEW(dev))
996 		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
997 
998 	panel->backlight.max = ctl >> 17;
999 	if (panel->backlight.combination_mode)
1000 		panel->backlight.max *= 0xff;
1001 
1002 	if (!panel->backlight.max)
1003 		return -ENODEV;
1004 
1005 	val = i9xx_get_backlight(connector);
1006 	panel->backlight.level = intel_panel_compute_brightness(connector, val);
1007 
1008 	panel->backlight.enabled = panel->backlight.level != 0;
1009 
1010 	return 0;
1011 }
1012 
i965_setup_backlight(struct intel_connector * connector)1013 static int i965_setup_backlight(struct intel_connector *connector)
1014 {
1015 	struct drm_device *dev = connector->base.dev;
1016 	struct drm_i915_private *dev_priv = dev->dev_private;
1017 	struct intel_panel *panel = &connector->panel;
1018 	u32 ctl, ctl2, val;
1019 
1020 	ctl2 = I915_READ(BLC_PWM_CTL2);
1021 	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
1022 	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
1023 
1024 	ctl = I915_READ(BLC_PWM_CTL);
1025 	panel->backlight.max = ctl >> 16;
1026 	if (panel->backlight.combination_mode)
1027 		panel->backlight.max *= 0xff;
1028 
1029 	if (!panel->backlight.max)
1030 		return -ENODEV;
1031 
1032 	val = i9xx_get_backlight(connector);
1033 	panel->backlight.level = intel_panel_compute_brightness(connector, val);
1034 
1035 	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
1036 		panel->backlight.level != 0;
1037 
1038 	return 0;
1039 }
1040 
vlv_setup_backlight(struct intel_connector * connector)1041 static int vlv_setup_backlight(struct intel_connector *connector)
1042 {
1043 	struct drm_device *dev = connector->base.dev;
1044 	struct drm_i915_private *dev_priv = dev->dev_private;
1045 	struct intel_panel *panel = &connector->panel;
1046 	enum i915_pipe pipe;
1047 	u32 ctl, ctl2, val;
1048 
1049 	for_each_pipe(pipe) {
1050 		u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe));
1051 
1052 		/* Skip if the modulation freq is already set */
1053 		if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK)
1054 			continue;
1055 
1056 		cur_val &= BACKLIGHT_DUTY_CYCLE_MASK;
1057 		I915_WRITE(VLV_BLC_PWM_CTL(pipe), (0xf42 << 16) |
1058 			   cur_val);
1059 	}
1060 
1061 	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
1062 	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
1063 
1064 	ctl = I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
1065 	panel->backlight.max = ctl >> 16;
1066 	if (!panel->backlight.max)
1067 		return -ENODEV;
1068 
1069 	val = _vlv_get_backlight(dev, PIPE_A);
1070 	panel->backlight.level = intel_panel_compute_brightness(connector, val);
1071 
1072 	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
1073 		panel->backlight.level != 0;
1074 
1075 	return 0;
1076 }
1077 
intel_panel_setup_backlight(struct drm_connector * connector)1078 int intel_panel_setup_backlight(struct drm_connector *connector)
1079 {
1080 	struct drm_device *dev = connector->dev;
1081 	struct drm_i915_private *dev_priv = dev->dev_private;
1082 	struct intel_connector *intel_connector = to_intel_connector(connector);
1083 	struct intel_panel *panel = &intel_connector->panel;
1084 	unsigned long flags;
1085 	int ret;
1086 
1087 	if (!dev_priv->vbt.backlight.present) {
1088 		DRM_DEBUG_KMS("native backlight control not available per VBT\n");
1089 		return 0;
1090 	}
1091 
1092 	/* set level and max in panel struct */
1093 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
1094 	ret = dev_priv->display.setup_backlight(intel_connector);
1095 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
1096 
1097 	if (ret) {
1098 		DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
1099 			      drm_get_connector_name(connector));
1100 		return ret;
1101 	}
1102 
1103 	intel_backlight_device_register(intel_connector);
1104 
1105 	panel->backlight.present = true;
1106 
1107 	DRM_DEBUG_KMS("backlight initialized, %s, brightness %u/%u, "
1108 		      "sysfs interface %sregistered\n",
1109 		      panel->backlight.enabled ? "enabled" : "disabled",
1110 		      panel->backlight.level, panel->backlight.max,
1111 		      panel->backlight.device ? "" : "not ");
1112 
1113 	return 0;
1114 }
1115 
intel_panel_destroy_backlight(struct drm_connector * connector)1116 void intel_panel_destroy_backlight(struct drm_connector *connector)
1117 {
1118 	struct intel_connector *intel_connector = to_intel_connector(connector);
1119 	struct intel_panel *panel = &intel_connector->panel;
1120 
1121 	panel->backlight.present = false;
1122 	intel_backlight_device_unregister(intel_connector);
1123 }
1124 
1125 /**
1126  * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID
1127  * @dev: drm device
1128  * @fixed_mode : panel native mode
1129  * @connector: LVDS/eDP connector
1130  *
1131  * Return downclock_avail
1132  * Find the reduced downclock for LVDS/eDP in EDID.
1133  */
1134 struct drm_display_mode *
intel_find_panel_downclock(struct drm_device * dev,struct drm_display_mode * fixed_mode,struct drm_connector * connector)1135 intel_find_panel_downclock(struct drm_device *dev,
1136 			struct drm_display_mode *fixed_mode,
1137 			struct drm_connector *connector)
1138 {
1139 	struct drm_display_mode *scan, *tmp_mode;
1140 	int temp_downclock;
1141 
1142 	temp_downclock = fixed_mode->clock;
1143 	tmp_mode = NULL;
1144 
1145 	list_for_each_entry(scan, &connector->probed_modes, head) {
1146 		/*
1147 		 * If one mode has the same resolution with the fixed_panel
1148 		 * mode while they have the different refresh rate, it means
1149 		 * that the reduced downclock is found. In such
1150 		 * case we can set the different FPx0/1 to dynamically select
1151 		 * between low and high frequency.
1152 		 */
1153 		if (scan->hdisplay == fixed_mode->hdisplay &&
1154 		    scan->hsync_start == fixed_mode->hsync_start &&
1155 		    scan->hsync_end == fixed_mode->hsync_end &&
1156 		    scan->htotal == fixed_mode->htotal &&
1157 		    scan->vdisplay == fixed_mode->vdisplay &&
1158 		    scan->vsync_start == fixed_mode->vsync_start &&
1159 		    scan->vsync_end == fixed_mode->vsync_end &&
1160 		    scan->vtotal == fixed_mode->vtotal) {
1161 			if (scan->clock < temp_downclock) {
1162 				/*
1163 				 * The downclock is already found. But we
1164 				 * expect to find the lower downclock.
1165 				 */
1166 				temp_downclock = scan->clock;
1167 				tmp_mode = scan;
1168 			}
1169 		}
1170 	}
1171 
1172 	if (temp_downclock < fixed_mode->clock)
1173 		return drm_mode_duplicate(dev, tmp_mode);
1174 	else
1175 		return NULL;
1176 }
1177 
1178 /* Set up chip specific backlight functions */
intel_panel_init_backlight_funcs(struct drm_device * dev)1179 void intel_panel_init_backlight_funcs(struct drm_device *dev)
1180 {
1181 	struct drm_i915_private *dev_priv = dev->dev_private;
1182 
1183 	if (IS_BROADWELL(dev)) {
1184 		dev_priv->display.setup_backlight = bdw_setup_backlight;
1185 		dev_priv->display.enable_backlight = bdw_enable_backlight;
1186 		dev_priv->display.disable_backlight = pch_disable_backlight;
1187 		dev_priv->display.set_backlight = bdw_set_backlight;
1188 		dev_priv->display.get_backlight = bdw_get_backlight;
1189 	} else if (HAS_PCH_SPLIT(dev)) {
1190 		dev_priv->display.setup_backlight = pch_setup_backlight;
1191 		dev_priv->display.enable_backlight = pch_enable_backlight;
1192 		dev_priv->display.disable_backlight = pch_disable_backlight;
1193 		dev_priv->display.set_backlight = pch_set_backlight;
1194 		dev_priv->display.get_backlight = pch_get_backlight;
1195 	} else if (IS_VALLEYVIEW(dev)) {
1196 		dev_priv->display.setup_backlight = vlv_setup_backlight;
1197 		dev_priv->display.enable_backlight = vlv_enable_backlight;
1198 		dev_priv->display.disable_backlight = vlv_disable_backlight;
1199 		dev_priv->display.set_backlight = vlv_set_backlight;
1200 		dev_priv->display.get_backlight = vlv_get_backlight;
1201 	} else if (IS_GEN4(dev)) {
1202 		dev_priv->display.setup_backlight = i965_setup_backlight;
1203 		dev_priv->display.enable_backlight = i965_enable_backlight;
1204 		dev_priv->display.disable_backlight = i965_disable_backlight;
1205 		dev_priv->display.set_backlight = i9xx_set_backlight;
1206 		dev_priv->display.get_backlight = i9xx_get_backlight;
1207 	} else {
1208 		dev_priv->display.setup_backlight = i9xx_setup_backlight;
1209 		dev_priv->display.enable_backlight = i9xx_enable_backlight;
1210 		dev_priv->display.disable_backlight = i9xx_disable_backlight;
1211 		dev_priv->display.set_backlight = i9xx_set_backlight;
1212 		dev_priv->display.get_backlight = i9xx_get_backlight;
1213 	}
1214 }
1215 
intel_panel_init(struct intel_panel * panel,struct drm_display_mode * fixed_mode,struct drm_display_mode * downclock_mode)1216 int intel_panel_init(struct intel_panel *panel,
1217 		     struct drm_display_mode *fixed_mode,
1218 		     struct drm_display_mode *downclock_mode)
1219 {
1220 	panel->fixed_mode = fixed_mode;
1221 	panel->downclock_mode = downclock_mode;
1222 
1223 	return 0;
1224 }
1225 
intel_panel_fini(struct intel_panel * panel)1226 void intel_panel_fini(struct intel_panel *panel)
1227 {
1228 	struct intel_connector *intel_connector =
1229 		container_of(panel, struct intel_connector, panel);
1230 
1231 	if (panel->fixed_mode)
1232 		drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
1233 
1234 	if (panel->downclock_mode)
1235 		drm_mode_destroy(intel_connector->base.dev,
1236 				panel->downclock_mode);
1237 }
1238