2 * Copyright © 2006-2010 Intel Corporation
3 * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
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:
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
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.
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>
31 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
33 #include <linux/moduleparam.h>
34 #include "intel_drv.h"
36 #define PCI_LBPC 0xf4 /* legacy/combination backlight modes */
39 intel_fixed_panel_mode(const struct drm_display_mode
*fixed_mode
,
40 struct drm_display_mode
*adjusted_mode
)
42 drm_mode_copy(adjusted_mode
, fixed_mode
);
44 drm_mode_set_crtcinfo(adjusted_mode
, 0);
47 /* adjusted_mode has been preset to be the panel's fixed mode */
49 intel_pch_panel_fitting(struct intel_crtc
*intel_crtc
,
50 struct intel_crtc_config
*pipe_config
,
53 struct drm_display_mode
*adjusted_mode
;
54 int x
, y
, width
, height
;
56 adjusted_mode
= &pipe_config
->adjusted_mode
;
58 x
= y
= width
= height
= 0;
60 /* Native modes don't need fitting */
61 if (adjusted_mode
->hdisplay
== pipe_config
->pipe_src_w
&&
62 adjusted_mode
->vdisplay
== pipe_config
->pipe_src_h
)
65 switch (fitting_mode
) {
66 case DRM_MODE_SCALE_CENTER
:
67 width
= pipe_config
->pipe_src_w
;
68 height
= pipe_config
->pipe_src_h
;
69 x
= (adjusted_mode
->hdisplay
- width
+ 1)/2;
70 y
= (adjusted_mode
->vdisplay
- height
+ 1)/2;
73 case DRM_MODE_SCALE_ASPECT
:
74 /* Scale but preserve the aspect ratio */
76 u32 scaled_width
= adjusted_mode
->hdisplay
77 * pipe_config
->pipe_src_h
;
78 u32 scaled_height
= pipe_config
->pipe_src_w
79 * adjusted_mode
->vdisplay
;
80 if (scaled_width
> scaled_height
) { /* pillar */
81 width
= scaled_height
/ pipe_config
->pipe_src_h
;
84 x
= (adjusted_mode
->hdisplay
- width
+ 1) / 2;
86 height
= adjusted_mode
->vdisplay
;
87 } else if (scaled_width
< scaled_height
) { /* letter */
88 height
= scaled_width
/ pipe_config
->pipe_src_w
;
91 y
= (adjusted_mode
->vdisplay
- height
+ 1) / 2;
93 width
= adjusted_mode
->hdisplay
;
96 width
= adjusted_mode
->hdisplay
;
97 height
= adjusted_mode
->vdisplay
;
102 case DRM_MODE_SCALE_FULLSCREEN
:
104 width
= adjusted_mode
->hdisplay
;
105 height
= adjusted_mode
->vdisplay
;
109 WARN(1, "bad panel fit mode: %d\n", fitting_mode
);
114 pipe_config
->pch_pfit
.pos
= (x
<< 16) | y
;
115 pipe_config
->pch_pfit
.size
= (width
<< 16) | height
;
116 pipe_config
->pch_pfit
.enabled
= pipe_config
->pch_pfit
.size
!= 0;
120 centre_horizontally(struct drm_display_mode
*mode
,
123 u32 border
, sync_pos
, blank_width
, sync_width
;
125 /* keep the hsync and hblank widths constant */
126 sync_width
= mode
->crtc_hsync_end
- mode
->crtc_hsync_start
;
127 blank_width
= mode
->crtc_hblank_end
- mode
->crtc_hblank_start
;
128 sync_pos
= (blank_width
- sync_width
+ 1) / 2;
130 border
= (mode
->hdisplay
- width
+ 1) / 2;
131 border
+= border
& 1; /* make the border even */
133 mode
->crtc_hdisplay
= width
;
134 mode
->crtc_hblank_start
= width
+ border
;
135 mode
->crtc_hblank_end
= mode
->crtc_hblank_start
+ blank_width
;
137 mode
->crtc_hsync_start
= mode
->crtc_hblank_start
+ sync_pos
;
138 mode
->crtc_hsync_end
= mode
->crtc_hsync_start
+ sync_width
;
142 centre_vertically(struct drm_display_mode
*mode
,
145 u32 border
, sync_pos
, blank_width
, sync_width
;
147 /* keep the vsync and vblank widths constant */
148 sync_width
= mode
->crtc_vsync_end
- mode
->crtc_vsync_start
;
149 blank_width
= mode
->crtc_vblank_end
- mode
->crtc_vblank_start
;
150 sync_pos
= (blank_width
- sync_width
+ 1) / 2;
152 border
= (mode
->vdisplay
- height
+ 1) / 2;
154 mode
->crtc_vdisplay
= height
;
155 mode
->crtc_vblank_start
= height
+ border
;
156 mode
->crtc_vblank_end
= mode
->crtc_vblank_start
+ blank_width
;
158 mode
->crtc_vsync_start
= mode
->crtc_vblank_start
+ sync_pos
;
159 mode
->crtc_vsync_end
= mode
->crtc_vsync_start
+ sync_width
;
162 static inline u32
panel_fitter_scaling(u32 source
, u32 target
)
165 * Floating point operation is not supported. So the FACTOR
166 * is defined, which can avoid the floating point computation
167 * when calculating the panel ratio.
170 #define FACTOR (1 << ACCURACY)
171 u32 ratio
= source
* FACTOR
/ target
;
172 return (FACTOR
* ratio
+ FACTOR
/2) / FACTOR
;
175 static void i965_scale_aspect(struct intel_crtc_config
*pipe_config
,
178 struct drm_display_mode
*adjusted_mode
= &pipe_config
->adjusted_mode
;
179 u32 scaled_width
= adjusted_mode
->hdisplay
*
180 pipe_config
->pipe_src_h
;
181 u32 scaled_height
= pipe_config
->pipe_src_w
*
182 adjusted_mode
->vdisplay
;
184 /* 965+ is easy, it does everything in hw */
185 if (scaled_width
> scaled_height
)
186 *pfit_control
|= PFIT_ENABLE
|
188 else if (scaled_width
< scaled_height
)
189 *pfit_control
|= PFIT_ENABLE
|
191 else if (adjusted_mode
->hdisplay
!= pipe_config
->pipe_src_w
)
192 *pfit_control
|= PFIT_ENABLE
| PFIT_SCALING_AUTO
;
195 static void i9xx_scale_aspect(struct intel_crtc_config
*pipe_config
,
196 u32
*pfit_control
, u32
*pfit_pgm_ratios
,
199 struct drm_display_mode
*adjusted_mode
= &pipe_config
->adjusted_mode
;
200 u32 scaled_width
= adjusted_mode
->hdisplay
*
201 pipe_config
->pipe_src_h
;
202 u32 scaled_height
= pipe_config
->pipe_src_w
*
203 adjusted_mode
->vdisplay
;
207 * For earlier chips we have to calculate the scaling
208 * ratio by hand and program it into the
209 * PFIT_PGM_RATIO register
211 if (scaled_width
> scaled_height
) { /* pillar */
212 centre_horizontally(adjusted_mode
,
214 pipe_config
->pipe_src_h
);
216 *border
= LVDS_BORDER_ENABLE
;
217 if (pipe_config
->pipe_src_h
!= adjusted_mode
->vdisplay
) {
218 bits
= panel_fitter_scaling(pipe_config
->pipe_src_h
,
219 adjusted_mode
->vdisplay
);
221 *pfit_pgm_ratios
|= (bits
<< PFIT_HORIZ_SCALE_SHIFT
|
222 bits
<< PFIT_VERT_SCALE_SHIFT
);
223 *pfit_control
|= (PFIT_ENABLE
|
224 VERT_INTERP_BILINEAR
|
225 HORIZ_INTERP_BILINEAR
);
227 } else if (scaled_width
< scaled_height
) { /* letter */
228 centre_vertically(adjusted_mode
,
230 pipe_config
->pipe_src_w
);
232 *border
= LVDS_BORDER_ENABLE
;
233 if (pipe_config
->pipe_src_w
!= adjusted_mode
->hdisplay
) {
234 bits
= panel_fitter_scaling(pipe_config
->pipe_src_w
,
235 adjusted_mode
->hdisplay
);
237 *pfit_pgm_ratios
|= (bits
<< PFIT_HORIZ_SCALE_SHIFT
|
238 bits
<< PFIT_VERT_SCALE_SHIFT
);
239 *pfit_control
|= (PFIT_ENABLE
|
240 VERT_INTERP_BILINEAR
|
241 HORIZ_INTERP_BILINEAR
);
244 /* Aspects match, Let hw scale both directions */
245 *pfit_control
|= (PFIT_ENABLE
|
246 VERT_AUTO_SCALE
| HORIZ_AUTO_SCALE
|
247 VERT_INTERP_BILINEAR
|
248 HORIZ_INTERP_BILINEAR
);
252 void intel_gmch_panel_fitting(struct intel_crtc
*intel_crtc
,
253 struct intel_crtc_config
*pipe_config
,
256 struct drm_device
*dev
= intel_crtc
->base
.dev
;
257 u32 pfit_control
= 0, pfit_pgm_ratios
= 0, border
= 0;
258 struct drm_display_mode
*adjusted_mode
;
260 adjusted_mode
= &pipe_config
->adjusted_mode
;
262 /* Native modes don't need fitting */
263 if (adjusted_mode
->hdisplay
== pipe_config
->pipe_src_w
&&
264 adjusted_mode
->vdisplay
== pipe_config
->pipe_src_h
)
267 switch (fitting_mode
) {
268 case DRM_MODE_SCALE_CENTER
:
270 * For centered modes, we have to calculate border widths &
271 * heights and modify the values programmed into the CRTC.
273 centre_horizontally(adjusted_mode
, pipe_config
->pipe_src_w
);
274 centre_vertically(adjusted_mode
, pipe_config
->pipe_src_h
);
275 border
= LVDS_BORDER_ENABLE
;
277 case DRM_MODE_SCALE_ASPECT
:
278 /* Scale but preserve the aspect ratio */
279 if (INTEL_INFO(dev
)->gen
>= 4)
280 i965_scale_aspect(pipe_config
, &pfit_control
);
282 i9xx_scale_aspect(pipe_config
, &pfit_control
,
283 &pfit_pgm_ratios
, &border
);
285 case DRM_MODE_SCALE_FULLSCREEN
:
287 * Full scaling, even if it changes the aspect ratio.
288 * Fortunately this is all done for us in hw.
290 if (pipe_config
->pipe_src_h
!= adjusted_mode
->vdisplay
||
291 pipe_config
->pipe_src_w
!= adjusted_mode
->hdisplay
) {
292 pfit_control
|= PFIT_ENABLE
;
293 if (INTEL_INFO(dev
)->gen
>= 4)
294 pfit_control
|= PFIT_SCALING_AUTO
;
296 pfit_control
|= (VERT_AUTO_SCALE
|
297 VERT_INTERP_BILINEAR
|
299 HORIZ_INTERP_BILINEAR
);
303 WARN(1, "bad panel fit mode: %d\n", fitting_mode
);
307 /* 965+ wants fuzzy fitting */
308 /* FIXME: handle multiple panels by failing gracefully */
309 if (INTEL_INFO(dev
)->gen
>= 4)
310 pfit_control
|= ((intel_crtc
->pipe
<< PFIT_PIPE_SHIFT
) |
314 if ((pfit_control
& PFIT_ENABLE
) == 0) {
319 /* Make sure pre-965 set dither correctly for 18bpp panels. */
320 if (INTEL_INFO(dev
)->gen
< 4 && pipe_config
->pipe_bpp
== 18)
321 pfit_control
|= PANEL_8TO6_DITHER_ENABLE
;
323 pipe_config
->gmch_pfit
.control
= pfit_control
;
324 pipe_config
->gmch_pfit
.pgm_ratios
= pfit_pgm_ratios
;
325 pipe_config
->gmch_pfit
.lvds_border_bits
= border
;
328 static int i915_panel_invert_brightness
;
329 MODULE_PARM_DESC(invert_brightness
, "Invert backlight brightness "
330 "(-1 force normal, 0 machine defaults, 1 force inversion), please "
331 "report PCI device ID, subsystem vendor and subsystem device ID "
332 "to dri-devel@lists.freedesktop.org, if your machine needs it. "
333 "It will then be included in an upcoming module version.");
334 module_param_named(invert_brightness
, i915_panel_invert_brightness
, int, 0600);
335 static u32
intel_panel_compute_brightness(struct intel_connector
*connector
,
338 struct drm_device
*dev
= connector
->base
.dev
;
339 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
340 struct intel_panel
*panel
= &connector
->panel
;
342 WARN_ON(panel
->backlight
.max
== 0);
344 if (i915_panel_invert_brightness
< 0)
347 if (i915_panel_invert_brightness
> 0 ||
348 dev_priv
->quirks
& QUIRK_INVERT_BRIGHTNESS
) {
349 return panel
->backlight
.max
- val
;
355 static u32
bdw_get_backlight(struct intel_connector
*connector
)
357 struct drm_device
*dev
= connector
->base
.dev
;
358 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
360 return I915_READ(BLC_PWM_PCH_CTL2
) & BACKLIGHT_DUTY_CYCLE_MASK
;
363 static u32
pch_get_backlight(struct intel_connector
*connector
)
365 struct drm_device
*dev
= connector
->base
.dev
;
366 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
368 return I915_READ(BLC_PWM_CPU_CTL
) & BACKLIGHT_DUTY_CYCLE_MASK
;
371 static u32
i9xx_get_backlight(struct intel_connector
*connector
)
373 struct drm_device
*dev
= connector
->base
.dev
;
374 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
375 struct intel_panel
*panel
= &connector
->panel
;
378 val
= I915_READ(BLC_PWM_CTL
) & BACKLIGHT_DUTY_CYCLE_MASK
;
379 if (INTEL_INFO(dev
)->gen
< 4)
382 if (panel
->backlight
.combination_mode
) {
385 pci_read_config_byte(dev
->pdev
, PCI_LBPC
, &lbpc
);
392 static u32
_vlv_get_backlight(struct drm_device
*dev
, enum pipe pipe
)
394 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
396 return I915_READ(VLV_BLC_PWM_CTL(pipe
)) & BACKLIGHT_DUTY_CYCLE_MASK
;
399 static u32
vlv_get_backlight(struct intel_connector
*connector
)
401 struct drm_device
*dev
= connector
->base
.dev
;
402 enum pipe pipe
= intel_get_pipe_from_connector(connector
);
404 return _vlv_get_backlight(dev
, pipe
);
407 static u32
intel_panel_get_backlight(struct intel_connector
*connector
)
409 struct drm_device
*dev
= connector
->base
.dev
;
410 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
414 spin_lock_irqsave(&dev_priv
->backlight_lock
, flags
);
416 val
= dev_priv
->display
.get_backlight(connector
);
417 val
= intel_panel_compute_brightness(connector
, val
);
419 spin_unlock_irqrestore(&dev_priv
->backlight_lock
, flags
);
421 DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val
);
425 static void bdw_set_backlight(struct intel_connector
*connector
, u32 level
)
427 struct drm_device
*dev
= connector
->base
.dev
;
428 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
429 u32 val
= I915_READ(BLC_PWM_PCH_CTL2
) & ~BACKLIGHT_DUTY_CYCLE_MASK
;
430 I915_WRITE(BLC_PWM_PCH_CTL2
, val
| level
);
433 static void pch_set_backlight(struct intel_connector
*connector
, u32 level
)
435 struct drm_device
*dev
= connector
->base
.dev
;
436 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
439 tmp
= I915_READ(BLC_PWM_CPU_CTL
) & ~BACKLIGHT_DUTY_CYCLE_MASK
;
440 I915_WRITE(BLC_PWM_CPU_CTL
, tmp
| level
);
443 static void i9xx_set_backlight(struct intel_connector
*connector
, u32 level
)
445 struct drm_device
*dev
= connector
->base
.dev
;
446 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
447 struct intel_panel
*panel
= &connector
->panel
;
450 WARN_ON(panel
->backlight
.max
== 0);
452 if (panel
->backlight
.combination_mode
) {
455 lbpc
= level
* 0xfe / panel
->backlight
.max
+ 1;
457 pci_write_config_byte(dev
->pdev
, PCI_LBPC
, lbpc
);
461 mask
= BACKLIGHT_DUTY_CYCLE_MASK
;
464 mask
= BACKLIGHT_DUTY_CYCLE_MASK_PNV
;
467 tmp
= I915_READ(BLC_PWM_CTL
) & ~mask
;
468 I915_WRITE(BLC_PWM_CTL
, tmp
| level
);
471 static void vlv_set_backlight(struct intel_connector
*connector
, u32 level
)
473 struct drm_device
*dev
= connector
->base
.dev
;
474 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
475 enum pipe pipe
= intel_get_pipe_from_connector(connector
);
478 tmp
= I915_READ(VLV_BLC_PWM_CTL(pipe
)) & ~BACKLIGHT_DUTY_CYCLE_MASK
;
479 I915_WRITE(VLV_BLC_PWM_CTL(pipe
), tmp
| level
);
483 intel_panel_actually_set_backlight(struct intel_connector
*connector
, u32 level
)
485 struct drm_device
*dev
= connector
->base
.dev
;
486 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
488 DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level
);
490 level
= intel_panel_compute_brightness(connector
, level
);
491 dev_priv
->display
.set_backlight(connector
, level
);
494 /* set backlight brightness to level in range [0..max] */
495 void intel_panel_set_backlight(struct intel_connector
*connector
, u32 level
,
498 struct drm_device
*dev
= connector
->base
.dev
;
499 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
500 struct intel_panel
*panel
= &connector
->panel
;
501 enum pipe pipe
= intel_get_pipe_from_connector(connector
);
505 if (!panel
->backlight
.present
|| pipe
== INVALID_PIPE
)
508 spin_lock_irqsave(&dev_priv
->backlight_lock
, flags
);
510 WARN_ON(panel
->backlight
.max
== 0);
512 /* scale to hardware max, but be careful to not overflow */
513 freq
= panel
->backlight
.max
;
515 level
= level
* freq
/ max
;
517 level
= freq
/ max
* level
;
519 panel
->backlight
.level
= level
;
520 if (panel
->backlight
.device
)
521 panel
->backlight
.device
->props
.brightness
= level
;
523 if (panel
->backlight
.enabled
)
524 intel_panel_actually_set_backlight(connector
, level
);
526 spin_unlock_irqrestore(&dev_priv
->backlight_lock
, flags
);
529 static void pch_disable_backlight(struct intel_connector
*connector
)
531 struct drm_device
*dev
= connector
->base
.dev
;
532 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
535 intel_panel_actually_set_backlight(connector
, 0);
537 tmp
= I915_READ(BLC_PWM_CPU_CTL2
);
538 I915_WRITE(BLC_PWM_CPU_CTL2
, tmp
& ~BLM_PWM_ENABLE
);
540 tmp
= I915_READ(BLC_PWM_PCH_CTL1
);
541 I915_WRITE(BLC_PWM_PCH_CTL1
, tmp
& ~BLM_PCH_PWM_ENABLE
);
544 static void i9xx_disable_backlight(struct intel_connector
*connector
)
546 intel_panel_actually_set_backlight(connector
, 0);
549 static void i965_disable_backlight(struct intel_connector
*connector
)
551 struct drm_device
*dev
= connector
->base
.dev
;
552 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
555 intel_panel_actually_set_backlight(connector
, 0);
557 tmp
= I915_READ(BLC_PWM_CTL2
);
558 I915_WRITE(BLC_PWM_CTL2
, tmp
& ~BLM_PWM_ENABLE
);
561 static void vlv_disable_backlight(struct intel_connector
*connector
)
563 struct drm_device
*dev
= connector
->base
.dev
;
564 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
565 enum pipe pipe
= intel_get_pipe_from_connector(connector
);
568 intel_panel_actually_set_backlight(connector
, 0);
570 tmp
= I915_READ(VLV_BLC_PWM_CTL2(pipe
));
571 I915_WRITE(VLV_BLC_PWM_CTL2(pipe
), tmp
& ~BLM_PWM_ENABLE
);
574 void intel_panel_disable_backlight(struct intel_connector
*connector
)
576 struct drm_device
*dev
= connector
->base
.dev
;
577 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
578 struct intel_panel
*panel
= &connector
->panel
;
579 enum pipe pipe
= intel_get_pipe_from_connector(connector
);
582 if (!panel
->backlight
.present
|| pipe
== INVALID_PIPE
)
586 * Do not disable backlight on the vgaswitcheroo path. When switching
587 * away from i915, the other client may depend on i915 to handle the
588 * backlight. This will leave the backlight on unnecessarily when
589 * another client is not activated.
591 if (dev
->switch_power_state
== DRM_SWITCH_POWER_CHANGING
) {
592 DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
596 spin_lock_irqsave(&dev_priv
->backlight_lock
, flags
);
598 panel
->backlight
.enabled
= false;
599 dev_priv
->display
.disable_backlight(connector
);
601 spin_unlock_irqrestore(&dev_priv
->backlight_lock
, flags
);
604 static void bdw_enable_backlight(struct intel_connector
*connector
)
606 struct drm_device
*dev
= connector
->base
.dev
;
607 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
608 struct intel_panel
*panel
= &connector
->panel
;
609 u32 pch_ctl1
, pch_ctl2
;
611 pch_ctl1
= I915_READ(BLC_PWM_PCH_CTL1
);
612 if (pch_ctl1
& BLM_PCH_PWM_ENABLE
) {
613 DRM_DEBUG_KMS("pch backlight already enabled\n");
614 pch_ctl1
&= ~BLM_PCH_PWM_ENABLE
;
615 I915_WRITE(BLC_PWM_PCH_CTL1
, pch_ctl1
);
618 pch_ctl2
= panel
->backlight
.max
<< 16;
619 I915_WRITE(BLC_PWM_PCH_CTL2
, pch_ctl2
);
622 if (panel
->backlight
.active_low_pwm
)
623 pch_ctl1
|= BLM_PCH_POLARITY
;
625 /* BDW always uses the pch pwm controls. */
626 pch_ctl1
|= BLM_PCH_OVERRIDE_ENABLE
;
628 I915_WRITE(BLC_PWM_PCH_CTL1
, pch_ctl1
);
629 POSTING_READ(BLC_PWM_PCH_CTL1
);
630 I915_WRITE(BLC_PWM_PCH_CTL1
, pch_ctl1
| BLM_PCH_PWM_ENABLE
);
632 /* This won't stick until the above enable. */
633 intel_panel_actually_set_backlight(connector
, panel
->backlight
.level
);
636 static void pch_enable_backlight(struct intel_connector
*connector
)
638 struct drm_device
*dev
= connector
->base
.dev
;
639 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
640 struct intel_panel
*panel
= &connector
->panel
;
641 enum pipe pipe
= intel_get_pipe_from_connector(connector
);
642 enum transcoder cpu_transcoder
=
643 intel_pipe_to_cpu_transcoder(dev_priv
, pipe
);
644 u32 cpu_ctl2
, pch_ctl1
, pch_ctl2
;
646 cpu_ctl2
= I915_READ(BLC_PWM_CPU_CTL2
);
647 if (cpu_ctl2
& BLM_PWM_ENABLE
) {
648 WARN(1, "cpu backlight already enabled\n");
649 cpu_ctl2
&= ~BLM_PWM_ENABLE
;
650 I915_WRITE(BLC_PWM_CPU_CTL2
, cpu_ctl2
);
653 pch_ctl1
= I915_READ(BLC_PWM_PCH_CTL1
);
654 if (pch_ctl1
& BLM_PCH_PWM_ENABLE
) {
655 DRM_DEBUG_KMS("pch backlight already enabled\n");
656 pch_ctl1
&= ~BLM_PCH_PWM_ENABLE
;
657 I915_WRITE(BLC_PWM_PCH_CTL1
, pch_ctl1
);
660 if (cpu_transcoder
== TRANSCODER_EDP
)
661 cpu_ctl2
= BLM_TRANSCODER_EDP
;
663 cpu_ctl2
= BLM_PIPE(cpu_transcoder
);
664 I915_WRITE(BLC_PWM_CPU_CTL2
, cpu_ctl2
);
665 POSTING_READ(BLC_PWM_CPU_CTL2
);
666 I915_WRITE(BLC_PWM_CPU_CTL2
, cpu_ctl2
| BLM_PWM_ENABLE
);
668 /* This won't stick until the above enable. */
669 intel_panel_actually_set_backlight(connector
, panel
->backlight
.level
);
671 pch_ctl2
= panel
->backlight
.max
<< 16;
672 I915_WRITE(BLC_PWM_PCH_CTL2
, pch_ctl2
);
675 if (panel
->backlight
.active_low_pwm
)
676 pch_ctl1
|= BLM_PCH_POLARITY
;
678 I915_WRITE(BLC_PWM_PCH_CTL1
, pch_ctl1
);
679 POSTING_READ(BLC_PWM_PCH_CTL1
);
680 I915_WRITE(BLC_PWM_PCH_CTL1
, pch_ctl1
| BLM_PCH_PWM_ENABLE
);
683 static void i9xx_enable_backlight(struct intel_connector
*connector
)
685 struct drm_device
*dev
= connector
->base
.dev
;
686 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
687 struct intel_panel
*panel
= &connector
->panel
;
690 ctl
= I915_READ(BLC_PWM_CTL
);
691 if (ctl
& BACKLIGHT_DUTY_CYCLE_MASK_PNV
) {
692 WARN(1, "backlight already enabled\n");
693 I915_WRITE(BLC_PWM_CTL
, 0);
696 freq
= panel
->backlight
.max
;
697 if (panel
->backlight
.combination_mode
)
701 if (IS_GEN2(dev
) && panel
->backlight
.combination_mode
)
702 ctl
|= BLM_LEGACY_MODE
;
703 if (IS_PINEVIEW(dev
) && panel
->backlight
.active_low_pwm
)
704 ctl
|= BLM_POLARITY_PNV
;
706 I915_WRITE(BLC_PWM_CTL
, ctl
);
707 POSTING_READ(BLC_PWM_CTL
);
709 /* XXX: combine this into above write? */
710 intel_panel_actually_set_backlight(connector
, panel
->backlight
.level
);
713 static void i965_enable_backlight(struct intel_connector
*connector
)
715 struct drm_device
*dev
= connector
->base
.dev
;
716 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
717 struct intel_panel
*panel
= &connector
->panel
;
718 enum pipe pipe
= intel_get_pipe_from_connector(connector
);
721 ctl2
= I915_READ(BLC_PWM_CTL2
);
722 if (ctl2
& BLM_PWM_ENABLE
) {
723 WARN(1, "backlight already enabled\n");
724 ctl2
&= ~BLM_PWM_ENABLE
;
725 I915_WRITE(BLC_PWM_CTL2
, ctl2
);
728 freq
= panel
->backlight
.max
;
729 if (panel
->backlight
.combination_mode
)
733 I915_WRITE(BLC_PWM_CTL
, ctl
);
735 /* XXX: combine this into above write? */
736 intel_panel_actually_set_backlight(connector
, panel
->backlight
.level
);
738 ctl2
= BLM_PIPE(pipe
);
739 if (panel
->backlight
.combination_mode
)
740 ctl2
|= BLM_COMBINATION_MODE
;
741 if (panel
->backlight
.active_low_pwm
)
742 ctl2
|= BLM_POLARITY_I965
;
743 I915_WRITE(BLC_PWM_CTL2
, ctl2
);
744 POSTING_READ(BLC_PWM_CTL2
);
745 I915_WRITE(BLC_PWM_CTL2
, ctl2
| BLM_PWM_ENABLE
);
748 static void vlv_enable_backlight(struct intel_connector
*connector
)
750 struct drm_device
*dev
= connector
->base
.dev
;
751 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
752 struct intel_panel
*panel
= &connector
->panel
;
753 enum pipe pipe
= intel_get_pipe_from_connector(connector
);
756 ctl2
= I915_READ(VLV_BLC_PWM_CTL2(pipe
));
757 if (ctl2
& BLM_PWM_ENABLE
) {
758 WARN(1, "backlight already enabled\n");
759 ctl2
&= ~BLM_PWM_ENABLE
;
760 I915_WRITE(VLV_BLC_PWM_CTL2(pipe
), ctl2
);
763 ctl
= panel
->backlight
.max
<< 16;
764 I915_WRITE(VLV_BLC_PWM_CTL(pipe
), ctl
);
766 /* XXX: combine this into above write? */
767 intel_panel_actually_set_backlight(connector
, panel
->backlight
.level
);
770 if (panel
->backlight
.active_low_pwm
)
771 ctl2
|= BLM_POLARITY_I965
;
772 I915_WRITE(VLV_BLC_PWM_CTL2(pipe
), ctl2
);
773 POSTING_READ(VLV_BLC_PWM_CTL2(pipe
));
774 I915_WRITE(VLV_BLC_PWM_CTL2(pipe
), ctl2
| BLM_PWM_ENABLE
);
777 void intel_panel_enable_backlight(struct intel_connector
*connector
)
779 struct drm_device
*dev
= connector
->base
.dev
;
780 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
781 struct intel_panel
*panel
= &connector
->panel
;
782 enum pipe pipe
= intel_get_pipe_from_connector(connector
);
785 if (!panel
->backlight
.present
|| pipe
== INVALID_PIPE
)
788 DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe
));
790 spin_lock_irqsave(&dev_priv
->backlight_lock
, flags
);
792 WARN_ON(panel
->backlight
.max
== 0);
794 if (panel
->backlight
.level
== 0) {
795 panel
->backlight
.level
= panel
->backlight
.max
;
796 if (panel
->backlight
.device
)
797 panel
->backlight
.device
->props
.brightness
=
798 panel
->backlight
.level
;
801 dev_priv
->display
.enable_backlight(connector
);
802 panel
->backlight
.enabled
= true;
804 spin_unlock_irqrestore(&dev_priv
->backlight_lock
, flags
);
807 enum drm_connector_status
808 intel_panel_detect(struct drm_device
*dev
)
810 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
812 /* Assume that the BIOS does not lie through the OpRegion... */
813 if (!i915_panel_ignore_lid
&& dev_priv
->opregion
.lid_state
) {
814 return ioread32(dev_priv
->opregion
.lid_state
) & 0x1 ?
815 connector_status_connected
:
816 connector_status_disconnected
;
819 switch (i915_panel_ignore_lid
) {
821 return connector_status_connected
;
823 return connector_status_disconnected
;
825 return connector_status_unknown
;
829 #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
830 static int intel_backlight_device_update_status(struct backlight_device
*bd
)
832 struct intel_connector
*connector
= bl_get_data(bd
);
833 struct drm_device
*dev
= connector
->base
.dev
;
835 mutex_lock(&dev
->mode_config
.mutex
);
836 DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
837 bd
->props
.brightness
, bd
->props
.max_brightness
);
838 intel_panel_set_backlight(connector
, bd
->props
.brightness
,
839 bd
->props
.max_brightness
);
840 mutex_unlock(&dev
->mode_config
.mutex
);
844 static int intel_backlight_device_get_brightness(struct backlight_device
*bd
)
846 struct intel_connector
*connector
= bl_get_data(bd
);
847 struct drm_device
*dev
= connector
->base
.dev
;
848 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
851 intel_runtime_pm_get(dev_priv
);
852 mutex_lock(&dev
->mode_config
.mutex
);
853 ret
= intel_panel_get_backlight(connector
);
854 mutex_unlock(&dev
->mode_config
.mutex
);
855 intel_runtime_pm_put(dev_priv
);
860 static const struct backlight_ops intel_backlight_device_ops
= {
861 .update_status
= intel_backlight_device_update_status
,
862 .get_brightness
= intel_backlight_device_get_brightness
,
865 static int intel_backlight_device_register(struct intel_connector
*connector
)
867 struct intel_panel
*panel
= &connector
->panel
;
868 struct backlight_properties props
;
870 if (WARN_ON(panel
->backlight
.device
))
873 BUG_ON(panel
->backlight
.max
== 0);
875 memset(&props
, 0, sizeof(props
));
876 props
.type
= BACKLIGHT_RAW
;
877 props
.brightness
= panel
->backlight
.level
;
878 props
.max_brightness
= panel
->backlight
.max
;
881 * Note: using the same name independent of the connector prevents
882 * registration of multiple backlight devices in the driver.
884 panel
->backlight
.device
=
885 backlight_device_register("intel_backlight",
886 connector
->base
.kdev
,
888 &intel_backlight_device_ops
, &props
);
890 if (IS_ERR(panel
->backlight
.device
)) {
891 DRM_ERROR("Failed to register backlight: %ld\n",
892 PTR_ERR(panel
->backlight
.device
));
893 panel
->backlight
.device
= NULL
;
899 static void intel_backlight_device_unregister(struct intel_connector
*connector
)
901 struct intel_panel
*panel
= &connector
->panel
;
903 if (panel
->backlight
.device
) {
904 backlight_device_unregister(panel
->backlight
.device
);
905 panel
->backlight
.device
= NULL
;
908 #else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
909 static int intel_backlight_device_register(struct intel_connector
*connector
)
913 static void intel_backlight_device_unregister(struct intel_connector
*connector
)
916 #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
919 * Note: The setup hooks can't assume pipe is set!
921 * XXX: Query mode clock or hardware clock and program PWM modulation frequency
922 * appropriately when it's 0. Use VBT and/or sane defaults.
924 static int bdw_setup_backlight(struct intel_connector
*connector
)
926 struct drm_device
*dev
= connector
->base
.dev
;
927 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
928 struct intel_panel
*panel
= &connector
->panel
;
929 u32 pch_ctl1
, pch_ctl2
, val
;
931 pch_ctl1
= I915_READ(BLC_PWM_PCH_CTL1
);
932 panel
->backlight
.active_low_pwm
= pch_ctl1
& BLM_PCH_POLARITY
;
934 pch_ctl2
= I915_READ(BLC_PWM_PCH_CTL2
);
935 panel
->backlight
.max
= pch_ctl2
>> 16;
936 if (!panel
->backlight
.max
)
939 val
= bdw_get_backlight(connector
);
940 panel
->backlight
.level
= intel_panel_compute_brightness(connector
, val
);
942 panel
->backlight
.enabled
= (pch_ctl1
& BLM_PCH_PWM_ENABLE
) &&
943 panel
->backlight
.level
!= 0;
948 static int pch_setup_backlight(struct intel_connector
*connector
)
950 struct drm_device
*dev
= connector
->base
.dev
;
951 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
952 struct intel_panel
*panel
= &connector
->panel
;
953 u32 cpu_ctl2
, pch_ctl1
, pch_ctl2
, val
;
955 pch_ctl1
= I915_READ(BLC_PWM_PCH_CTL1
);
956 panel
->backlight
.active_low_pwm
= pch_ctl1
& BLM_PCH_POLARITY
;
958 pch_ctl2
= I915_READ(BLC_PWM_PCH_CTL2
);
959 panel
->backlight
.max
= pch_ctl2
>> 16;
960 if (!panel
->backlight
.max
)
963 val
= pch_get_backlight(connector
);
964 panel
->backlight
.level
= intel_panel_compute_brightness(connector
, val
);
966 cpu_ctl2
= I915_READ(BLC_PWM_CPU_CTL2
);
967 panel
->backlight
.enabled
= (cpu_ctl2
& BLM_PWM_ENABLE
) &&
968 (pch_ctl1
& BLM_PCH_PWM_ENABLE
) && panel
->backlight
.level
!= 0;
973 static int i9xx_setup_backlight(struct intel_connector
*connector
)
975 struct drm_device
*dev
= connector
->base
.dev
;
976 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
977 struct intel_panel
*panel
= &connector
->panel
;
980 ctl
= I915_READ(BLC_PWM_CTL
);
983 panel
->backlight
.combination_mode
= ctl
& BLM_LEGACY_MODE
;
985 if (IS_PINEVIEW(dev
))
986 panel
->backlight
.active_low_pwm
= ctl
& BLM_POLARITY_PNV
;
988 panel
->backlight
.max
= ctl
>> 17;
989 if (panel
->backlight
.combination_mode
)
990 panel
->backlight
.max
*= 0xff;
992 if (!panel
->backlight
.max
)
995 val
= i9xx_get_backlight(connector
);
996 panel
->backlight
.level
= intel_panel_compute_brightness(connector
, val
);
998 panel
->backlight
.enabled
= panel
->backlight
.level
!= 0;
1003 static int i965_setup_backlight(struct intel_connector
*connector
)
1005 struct drm_device
*dev
= connector
->base
.dev
;
1006 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
1007 struct intel_panel
*panel
= &connector
->panel
;
1010 ctl2
= I915_READ(BLC_PWM_CTL2
);
1011 panel
->backlight
.combination_mode
= ctl2
& BLM_COMBINATION_MODE
;
1012 panel
->backlight
.active_low_pwm
= ctl2
& BLM_POLARITY_I965
;
1014 ctl
= I915_READ(BLC_PWM_CTL
);
1015 panel
->backlight
.max
= ctl
>> 16;
1016 if (panel
->backlight
.combination_mode
)
1017 panel
->backlight
.max
*= 0xff;
1019 if (!panel
->backlight
.max
)
1022 val
= i9xx_get_backlight(connector
);
1023 panel
->backlight
.level
= intel_panel_compute_brightness(connector
, val
);
1025 panel
->backlight
.enabled
= (ctl2
& BLM_PWM_ENABLE
) &&
1026 panel
->backlight
.level
!= 0;
1031 static int vlv_setup_backlight(struct intel_connector
*connector
)
1033 struct drm_device
*dev
= connector
->base
.dev
;
1034 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
1035 struct intel_panel
*panel
= &connector
->panel
;
1039 for_each_pipe(pipe
) {
1040 u32 cur_val
= I915_READ(VLV_BLC_PWM_CTL(pipe
));
1042 /* Skip if the modulation freq is already set */
1043 if (cur_val
& ~BACKLIGHT_DUTY_CYCLE_MASK
)
1046 cur_val
&= BACKLIGHT_DUTY_CYCLE_MASK
;
1047 I915_WRITE(VLV_BLC_PWM_CTL(pipe
), (0xf42 << 16) |
1051 ctl2
= I915_READ(VLV_BLC_PWM_CTL2(PIPE_A
));
1052 panel
->backlight
.active_low_pwm
= ctl2
& BLM_POLARITY_I965
;
1054 ctl
= I915_READ(VLV_BLC_PWM_CTL(PIPE_A
));
1055 panel
->backlight
.max
= ctl
>> 16;
1056 if (!panel
->backlight
.max
)
1059 val
= _vlv_get_backlight(dev
, PIPE_A
);
1060 panel
->backlight
.level
= intel_panel_compute_brightness(connector
, val
);
1062 panel
->backlight
.enabled
= (ctl2
& BLM_PWM_ENABLE
) &&
1063 panel
->backlight
.level
!= 0;
1068 int intel_panel_setup_backlight(struct drm_connector
*connector
)
1070 struct drm_device
*dev
= connector
->dev
;
1071 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
1072 struct intel_connector
*intel_connector
= to_intel_connector(connector
);
1073 struct intel_panel
*panel
= &intel_connector
->panel
;
1074 unsigned long flags
;
1077 /* set level and max in panel struct */
1078 spin_lock_irqsave(&dev_priv
->backlight_lock
, flags
);
1079 ret
= dev_priv
->display
.setup_backlight(intel_connector
);
1080 spin_unlock_irqrestore(&dev_priv
->backlight_lock
, flags
);
1083 DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
1084 drm_get_connector_name(connector
));
1088 intel_backlight_device_register(intel_connector
);
1090 panel
->backlight
.present
= true;
1092 DRM_DEBUG_KMS("backlight initialized, %s, brightness %u/%u, "
1093 "sysfs interface %sregistered\n",
1094 panel
->backlight
.enabled
? "enabled" : "disabled",
1095 panel
->backlight
.level
, panel
->backlight
.max
,
1096 panel
->backlight
.device
? "" : "not ");
1101 void intel_panel_destroy_backlight(struct drm_connector
*connector
)
1103 struct intel_connector
*intel_connector
= to_intel_connector(connector
);
1104 struct intel_panel
*panel
= &intel_connector
->panel
;
1106 panel
->backlight
.present
= false;
1107 intel_backlight_device_unregister(intel_connector
);
1111 * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID
1113 * @fixed_mode : panel native mode
1114 * @connector: LVDS/eDP connector
1116 * Return downclock_avail
1117 * Find the reduced downclock for LVDS/eDP in EDID.
1119 struct drm_display_mode
*
1120 intel_find_panel_downclock(struct drm_device
*dev
,
1121 struct drm_display_mode
*fixed_mode
,
1122 struct drm_connector
*connector
)
1124 struct drm_display_mode
*scan
, *tmp_mode
;
1127 temp_downclock
= fixed_mode
->clock
;
1130 list_for_each_entry(scan
, &connector
->probed_modes
, head
) {
1132 * If one mode has the same resolution with the fixed_panel
1133 * mode while they have the different refresh rate, it means
1134 * that the reduced downclock is found. In such
1135 * case we can set the different FPx0/1 to dynamically select
1136 * between low and high frequency.
1138 if (scan
->hdisplay
== fixed_mode
->hdisplay
&&
1139 scan
->hsync_start
== fixed_mode
->hsync_start
&&
1140 scan
->hsync_end
== fixed_mode
->hsync_end
&&
1141 scan
->htotal
== fixed_mode
->htotal
&&
1142 scan
->vdisplay
== fixed_mode
->vdisplay
&&
1143 scan
->vsync_start
== fixed_mode
->vsync_start
&&
1144 scan
->vsync_end
== fixed_mode
->vsync_end
&&
1145 scan
->vtotal
== fixed_mode
->vtotal
) {
1146 if (scan
->clock
< temp_downclock
) {
1148 * The downclock is already found. But we
1149 * expect to find the lower downclock.
1151 temp_downclock
= scan
->clock
;
1157 if (temp_downclock
< fixed_mode
->clock
)
1158 return drm_mode_duplicate(dev
, tmp_mode
);
1163 /* Set up chip specific backlight functions */
1164 void intel_panel_init_backlight_funcs(struct drm_device
*dev
)
1166 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
1168 if (IS_BROADWELL(dev
)) {
1169 dev_priv
->display
.setup_backlight
= bdw_setup_backlight
;
1170 dev_priv
->display
.enable_backlight
= bdw_enable_backlight
;
1171 dev_priv
->display
.disable_backlight
= pch_disable_backlight
;
1172 dev_priv
->display
.set_backlight
= bdw_set_backlight
;
1173 dev_priv
->display
.get_backlight
= bdw_get_backlight
;
1174 } else if (HAS_PCH_SPLIT(dev
)) {
1175 dev_priv
->display
.setup_backlight
= pch_setup_backlight
;
1176 dev_priv
->display
.enable_backlight
= pch_enable_backlight
;
1177 dev_priv
->display
.disable_backlight
= pch_disable_backlight
;
1178 dev_priv
->display
.set_backlight
= pch_set_backlight
;
1179 dev_priv
->display
.get_backlight
= pch_get_backlight
;
1180 } else if (IS_VALLEYVIEW(dev
)) {
1181 dev_priv
->display
.setup_backlight
= vlv_setup_backlight
;
1182 dev_priv
->display
.enable_backlight
= vlv_enable_backlight
;
1183 dev_priv
->display
.disable_backlight
= vlv_disable_backlight
;
1184 dev_priv
->display
.set_backlight
= vlv_set_backlight
;
1185 dev_priv
->display
.get_backlight
= vlv_get_backlight
;
1186 } else if (IS_GEN4(dev
)) {
1187 dev_priv
->display
.setup_backlight
= i965_setup_backlight
;
1188 dev_priv
->display
.enable_backlight
= i965_enable_backlight
;
1189 dev_priv
->display
.disable_backlight
= i965_disable_backlight
;
1190 dev_priv
->display
.set_backlight
= i9xx_set_backlight
;
1191 dev_priv
->display
.get_backlight
= i9xx_get_backlight
;
1193 dev_priv
->display
.setup_backlight
= i9xx_setup_backlight
;
1194 dev_priv
->display
.enable_backlight
= i9xx_enable_backlight
;
1195 dev_priv
->display
.disable_backlight
= i9xx_disable_backlight
;
1196 dev_priv
->display
.set_backlight
= i9xx_set_backlight
;
1197 dev_priv
->display
.get_backlight
= i9xx_get_backlight
;
1201 int intel_panel_init(struct intel_panel
*panel
,
1202 struct drm_display_mode
*fixed_mode
)
1204 panel
->fixed_mode
= fixed_mode
;
1209 void intel_panel_fini(struct intel_panel
*panel
)
1211 struct intel_connector
*intel_connector
=
1212 container_of(panel
, struct intel_connector
, panel
);
1214 if (panel
->fixed_mode
)
1215 drm_mode_destroy(intel_connector
->base
.dev
, panel
->fixed_mode
);
1217 if (panel
->downclock_mode
)
1218 drm_mode_destroy(intel_connector
->base
.dev
,
1219 panel
->downclock_mode
);