Bug Summary

File:dev/pci/drm/i915/display/intel_panel.c
Warning:line 484, column 15
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name intel_panel.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/pci/drm/i915/display/intel_panel.c
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 KBUILD_MODNAME ": " fmt
32
33#include <linux/kernel.h>
34#include <linux/moduleparam.h>
35#include <linux/pwm.h>
36
37#include "intel_connector.h"
38#include "intel_display_types.h"
39#include "intel_dp_aux_backlight.h"
40#include "intel_dsi_dcs_backlight.h"
41#include "intel_panel.h"
42
43void
44intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
45 struct drm_display_mode *adjusted_mode)
46{
47 drm_mode_copy(adjusted_mode, fixed_mode);
48
49 drm_mode_set_crtcinfo(adjusted_mode, 0);
50}
51
52static bool_Bool is_downclock_mode(const struct drm_display_mode *downclock_mode,
53 const struct drm_display_mode *fixed_mode)
54{
55 return drm_mode_match(downclock_mode, fixed_mode,
56 DRM_MODE_MATCH_TIMINGS(1 << 0) |
57 DRM_MODE_MATCH_FLAGS(1 << 2) |
58 DRM_MODE_MATCH_3D_FLAGS(1 << 3)) &&
59 downclock_mode->clock < fixed_mode->clock;
60}
61
62struct drm_display_mode *
63intel_panel_edid_downclock_mode(struct intel_connector *connector,
64 const struct drm_display_mode *fixed_mode)
65{
66 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
67 const struct drm_display_mode *scan, *best_mode = NULL((void *)0);
68 struct drm_display_mode *downclock_mode;
69 int best_clock = fixed_mode->clock;
70
71 list_for_each_entry(scan, &connector->base.probed_modes, head)for (scan = ({ const __typeof( ((__typeof(*scan) *)0)->head
) *__mptr = ((&connector->base.probed_modes)->next
); (__typeof(*scan) *)( (char *)__mptr - __builtin_offsetof(__typeof
(*scan), head) );}); &scan->head != (&connector->
base.probed_modes); scan = ({ const __typeof( ((__typeof(*scan
) *)0)->head ) *__mptr = (scan->head.next); (__typeof(*
scan) *)( (char *)__mptr - __builtin_offsetof(__typeof(*scan)
, head) );}))
{
72 /*
73 * If one mode has the same resolution with the fixed_panel
74 * mode while they have the different refresh rate, it means
75 * that the reduced downclock is found. In such
76 * case we can set the different FPx0/1 to dynamically select
77 * between low and high frequency.
78 */
79 if (is_downclock_mode(scan, fixed_mode) &&
80 scan->clock < best_clock) {
81 /*
82 * The downclock is already found. But we
83 * expect to find the lower downclock.
84 */
85 best_clock = scan->clock;
86 best_mode = scan;
87 }
88 }
89
90 if (!best_mode)
91 return NULL((void *)0);
92
93 downclock_mode = drm_mode_duplicate(&dev_priv->drm, best_mode);
94 if (!downclock_mode)
95 return NULL((void *)0);
96
97 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] using downclock mode from EDID: "
, connector->base.base.id, connector->base.name)
98 "[CONNECTOR:%d:%s] using downclock mode from EDID: ",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] using downclock mode from EDID: "
, connector->base.base.id, connector->base.name)
99 connector->base.base.id, connector->base.name)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] using downclock mode from EDID: "
, connector->base.base.id, connector->base.name)
;
100 drm_mode_debug_printmodeline(downclock_mode);
101
102 return downclock_mode;
103}
104
105struct drm_display_mode *
106intel_panel_edid_fixed_mode(struct intel_connector *connector)
107{
108 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
109 const struct drm_display_mode *scan;
110 struct drm_display_mode *fixed_mode;
111
112 if (list_empty(&connector->base.probed_modes))
113 return NULL((void *)0);
114
115 /* prefer fixed mode from EDID if available */
116 list_for_each_entry(scan, &connector->base.probed_modes, head)for (scan = ({ const __typeof( ((__typeof(*scan) *)0)->head
) *__mptr = ((&connector->base.probed_modes)->next
); (__typeof(*scan) *)( (char *)__mptr - __builtin_offsetof(__typeof
(*scan), head) );}); &scan->head != (&connector->
base.probed_modes); scan = ({ const __typeof( ((__typeof(*scan
) *)0)->head ) *__mptr = (scan->head.next); (__typeof(*
scan) *)( (char *)__mptr - __builtin_offsetof(__typeof(*scan)
, head) );}))
{
117 if ((scan->type & DRM_MODE_TYPE_PREFERRED(1<<3)) == 0)
118 continue;
119
120 fixed_mode = drm_mode_duplicate(&dev_priv->drm, scan);
121 if (!fixed_mode)
122 return NULL((void *)0);
123
124 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] using preferred mode from EDID: "
, connector->base.base.id, connector->base.name)
125 "[CONNECTOR:%d:%s] using preferred mode from EDID: ",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] using preferred mode from EDID: "
, connector->base.base.id, connector->base.name)
126 connector->base.base.id, connector->base.name)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] using preferred mode from EDID: "
, connector->base.base.id, connector->base.name)
;
127 drm_mode_debug_printmodeline(fixed_mode);
128
129 return fixed_mode;
130 }
131
132 scan = list_first_entry(&connector->base.probed_modes,({ const __typeof( ((typeof(*scan) *)0)->head ) *__mptr = (
(&connector->base.probed_modes)->next); (typeof(*scan
) *)( (char *)__mptr - __builtin_offsetof(typeof(*scan), head
) );})
133 typeof(*scan), head)({ const __typeof( ((typeof(*scan) *)0)->head ) *__mptr = (
(&connector->base.probed_modes)->next); (typeof(*scan
) *)( (char *)__mptr - __builtin_offsetof(typeof(*scan), head
) );})
;
134
135 fixed_mode = drm_mode_duplicate(&dev_priv->drm, scan);
136 if (!fixed_mode)
137 return NULL((void *)0);
138
139 fixed_mode->type |= DRM_MODE_TYPE_PREFERRED(1<<3);
140
141 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] using first mode from EDID: "
, connector->base.base.id, connector->base.name)
142 "[CONNECTOR:%d:%s] using first mode from EDID: ",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] using first mode from EDID: "
, connector->base.base.id, connector->base.name)
143 connector->base.base.id, connector->base.name)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] using first mode from EDID: "
, connector->base.base.id, connector->base.name)
;
144 drm_mode_debug_printmodeline(fixed_mode);
145
146 return fixed_mode;
147}
148
149struct drm_display_mode *
150intel_panel_vbt_fixed_mode(struct intel_connector *connector)
151{
152 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
153 struct drm_display_info *info = &connector->base.display_info;
154 struct drm_display_mode *fixed_mode;
155
156 if (!dev_priv->vbt.lfp_lvds_vbt_mode)
157 return NULL((void *)0);
158
159 fixed_mode = drm_mode_duplicate(&dev_priv->drm,
160 dev_priv->vbt.lfp_lvds_vbt_mode);
161 if (!fixed_mode)
162 return NULL((void *)0);
163
164 fixed_mode->type |= DRM_MODE_TYPE_PREFERRED(1<<3);
165
166 drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s] using mode from VBT: ",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] using mode from VBT: "
, connector->base.base.id, connector->base.name)
167 connector->base.base.id, connector->base.name)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "[CONNECTOR:%d:%s] using mode from VBT: "
, connector->base.base.id, connector->base.name)
;
168 drm_mode_debug_printmodeline(fixed_mode);
169
170 info->width_mm = fixed_mode->width_mm;
171 info->height_mm = fixed_mode->height_mm;
172
173 return fixed_mode;
174}
175
176/* adjusted_mode has been preset to be the panel's fixed mode */
177int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state,
178 const struct drm_connector_state *conn_state)
179{
180 const struct drm_display_mode *adjusted_mode =
181 &crtc_state->hw.adjusted_mode;
182 int x, y, width, height;
183
184 /* Native modes don't need fitting */
185 if (adjusted_mode->crtc_hdisplay == crtc_state->pipe_src_w &&
186 adjusted_mode->crtc_vdisplay == crtc_state->pipe_src_h &&
187 crtc_state->output_format != INTEL_OUTPUT_FORMAT_YCBCR420)
188 return 0;
189
190 switch (conn_state->scaling_mode) {
191 case DRM_MODE_SCALE_CENTER2:
192 width = crtc_state->pipe_src_w;
193 height = crtc_state->pipe_src_h;
194 x = (adjusted_mode->crtc_hdisplay - width + 1)/2;
195 y = (adjusted_mode->crtc_vdisplay - height + 1)/2;
196 break;
197
198 case DRM_MODE_SCALE_ASPECT3:
199 /* Scale but preserve the aspect ratio */
200 {
201 u32 scaled_width = adjusted_mode->crtc_hdisplay
202 * crtc_state->pipe_src_h;
203 u32 scaled_height = crtc_state->pipe_src_w
204 * adjusted_mode->crtc_vdisplay;
205 if (scaled_width > scaled_height) { /* pillar */
206 width = scaled_height / crtc_state->pipe_src_h;
207 if (width & 1)
208 width++;
209 x = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
210 y = 0;
211 height = adjusted_mode->crtc_vdisplay;
212 } else if (scaled_width < scaled_height) { /* letter */
213 height = scaled_width / crtc_state->pipe_src_w;
214 if (height & 1)
215 height++;
216 y = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
217 x = 0;
218 width = adjusted_mode->crtc_hdisplay;
219 } else {
220 x = y = 0;
221 width = adjusted_mode->crtc_hdisplay;
222 height = adjusted_mode->crtc_vdisplay;
223 }
224 }
225 break;
226
227 case DRM_MODE_SCALE_NONE0:
228 WARN_ON(adjusted_mode->crtc_hdisplay != crtc_state->pipe_src_w)({ int __ret = !!((adjusted_mode->crtc_hdisplay != crtc_state
->pipe_src_w)); if (__ret) printf("%s", "WARN_ON(" "adjusted_mode->crtc_hdisplay != crtc_state->pipe_src_w"
")"); __builtin_expect(!!(__ret), 0); })
;
229 WARN_ON(adjusted_mode->crtc_vdisplay != crtc_state->pipe_src_h)({ int __ret = !!((adjusted_mode->crtc_vdisplay != crtc_state
->pipe_src_h)); if (__ret) printf("%s", "WARN_ON(" "adjusted_mode->crtc_vdisplay != crtc_state->pipe_src_h"
")"); __builtin_expect(!!(__ret), 0); })
;
230 fallthroughdo {} while (0);
231 case DRM_MODE_SCALE_FULLSCREEN1:
232 x = y = 0;
233 width = adjusted_mode->crtc_hdisplay;
234 height = adjusted_mode->crtc_vdisplay;
235 break;
236
237 default:
238 MISSING_CASE(conn_state->scaling_mode)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n"
, "conn_state->scaling_mode", (long)(conn_state->scaling_mode
)); __builtin_expect(!!(__ret), 0); })
;
239 return -EINVAL22;
240 }
241
242 drm_rect_init(&crtc_state->pch_pfit.dst,
243 x, y, width, height);
244 crtc_state->pch_pfit.enabled = true1;
245
246 return 0;
247}
248
249static void
250centre_horizontally(struct drm_display_mode *adjusted_mode,
251 int width)
252{
253 u32 border, sync_pos, blank_width, sync_width;
254
255 /* keep the hsync and hblank widths constant */
256 sync_width = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
257 blank_width = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
258 sync_pos = (blank_width - sync_width + 1) / 2;
259
260 border = (adjusted_mode->crtc_hdisplay - width + 1) / 2;
261 border += border & 1; /* make the border even */
262
263 adjusted_mode->crtc_hdisplay = width;
264 adjusted_mode->crtc_hblank_start = width + border;
265 adjusted_mode->crtc_hblank_end = adjusted_mode->crtc_hblank_start + blank_width;
266
267 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hblank_start + sync_pos;
268 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + sync_width;
269}
270
271static void
272centre_vertically(struct drm_display_mode *adjusted_mode,
273 int height)
274{
275 u32 border, sync_pos, blank_width, sync_width;
276
277 /* keep the vsync and vblank widths constant */
278 sync_width = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
279 blank_width = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vblank_start;
280 sync_pos = (blank_width - sync_width + 1) / 2;
281
282 border = (adjusted_mode->crtc_vdisplay - height + 1) / 2;
283
284 adjusted_mode->crtc_vdisplay = height;
285 adjusted_mode->crtc_vblank_start = height + border;
286 adjusted_mode->crtc_vblank_end = adjusted_mode->crtc_vblank_start + blank_width;
287
288 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vblank_start + sync_pos;
289 adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + sync_width;
290}
291
292static u32 panel_fitter_scaling(u32 source, u32 target)
293{
294 /*
295 * Floating point operation is not supported. So the FACTOR
296 * is defined, which can avoid the floating point computation
297 * when calculating the panel ratio.
298 */
299#define ACCURACY12 12
300#define FACTOR(1 << 12) (1 << ACCURACY12)
301 u32 ratio = source * FACTOR(1 << 12) / target;
302 return (FACTOR(1 << 12) * ratio + FACTOR(1 << 12)/2) / FACTOR(1 << 12);
303}
304
305static void i965_scale_aspect(struct intel_crtc_state *crtc_state,
306 u32 *pfit_control)
307{
308 const struct drm_display_mode *adjusted_mode =
309 &crtc_state->hw.adjusted_mode;
310 u32 scaled_width = adjusted_mode->crtc_hdisplay *
311 crtc_state->pipe_src_h;
312 u32 scaled_height = crtc_state->pipe_src_w *
313 adjusted_mode->crtc_vdisplay;
314
315 /* 965+ is easy, it does everything in hw */
316 if (scaled_width > scaled_height)
317 *pfit_control |= PFIT_ENABLE(1 << 31) |
318 PFIT_SCALING_PILLAR(2 << 26);
319 else if (scaled_width < scaled_height)
320 *pfit_control |= PFIT_ENABLE(1 << 31) |
321 PFIT_SCALING_LETTER(3 << 26);
322 else if (adjusted_mode->crtc_hdisplay != crtc_state->pipe_src_w)
323 *pfit_control |= PFIT_ENABLE(1 << 31) | PFIT_SCALING_AUTO(0 << 26);
324}
325
326static void i9xx_scale_aspect(struct intel_crtc_state *crtc_state,
327 u32 *pfit_control, u32 *pfit_pgm_ratios,
328 u32 *border)
329{
330 struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
331 u32 scaled_width = adjusted_mode->crtc_hdisplay *
332 crtc_state->pipe_src_h;
333 u32 scaled_height = crtc_state->pipe_src_w *
334 adjusted_mode->crtc_vdisplay;
335 u32 bits;
336
337 /*
338 * For earlier chips we have to calculate the scaling
339 * ratio by hand and program it into the
340 * PFIT_PGM_RATIO register
341 */
342 if (scaled_width > scaled_height) { /* pillar */
343 centre_horizontally(adjusted_mode,
344 scaled_height /
345 crtc_state->pipe_src_h);
346
347 *border = LVDS_BORDER_ENABLE(1 << 15);
348 if (crtc_state->pipe_src_h != adjusted_mode->crtc_vdisplay) {
349 bits = panel_fitter_scaling(crtc_state->pipe_src_h,
350 adjusted_mode->crtc_vdisplay);
351
352 *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT4 |
353 bits << PFIT_VERT_SCALE_SHIFT20);
354 *pfit_control |= (PFIT_ENABLE(1 << 31) |
355 VERT_INTERP_BILINEAR(1 << 10) |
356 HORIZ_INTERP_BILINEAR(1 << 6));
357 }
358 } else if (scaled_width < scaled_height) { /* letter */
359 centre_vertically(adjusted_mode,
360 scaled_width /
361 crtc_state->pipe_src_w);
362
363 *border = LVDS_BORDER_ENABLE(1 << 15);
364 if (crtc_state->pipe_src_w != adjusted_mode->crtc_hdisplay) {
365 bits = panel_fitter_scaling(crtc_state->pipe_src_w,
366 adjusted_mode->crtc_hdisplay);
367
368 *pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT4 |
369 bits << PFIT_VERT_SCALE_SHIFT20);
370 *pfit_control |= (PFIT_ENABLE(1 << 31) |
371 VERT_INTERP_BILINEAR(1 << 10) |
372 HORIZ_INTERP_BILINEAR(1 << 6));
373 }
374 } else {
375 /* Aspects match, Let hw scale both directions */
376 *pfit_control |= (PFIT_ENABLE(1 << 31) |
377 VERT_AUTO_SCALE(1 << 9) | HORIZ_AUTO_SCALE(1 << 5) |
378 VERT_INTERP_BILINEAR(1 << 10) |
379 HORIZ_INTERP_BILINEAR(1 << 6));
380 }
381}
382
383int intel_gmch_panel_fitting(struct intel_crtc_state *crtc_state,
384 const struct drm_connector_state *conn_state)
385{
386 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr
= (crtc_state->uapi.crtc); (struct intel_crtc *)( (char *
)__mptr - __builtin_offsetof(struct intel_crtc, base) );})
;
387 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(crtc->base.dev);
388 u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
389 struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
390
391 /* Native modes don't need fitting */
392 if (adjusted_mode->crtc_hdisplay == crtc_state->pipe_src_w &&
393 adjusted_mode->crtc_vdisplay == crtc_state->pipe_src_h)
394 goto out;
395
396 switch (conn_state->scaling_mode) {
397 case DRM_MODE_SCALE_CENTER2:
398 /*
399 * For centered modes, we have to calculate border widths &
400 * heights and modify the values programmed into the CRTC.
401 */
402 centre_horizontally(adjusted_mode, crtc_state->pipe_src_w);
403 centre_vertically(adjusted_mode, crtc_state->pipe_src_h);
404 border = LVDS_BORDER_ENABLE(1 << 15);
405 break;
406 case DRM_MODE_SCALE_ASPECT3:
407 /* Scale but preserve the aspect ratio */
408 if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 4)
409 i965_scale_aspect(crtc_state, &pfit_control);
410 else
411 i9xx_scale_aspect(crtc_state, &pfit_control,
412 &pfit_pgm_ratios, &border);
413 break;
414 case DRM_MODE_SCALE_FULLSCREEN1:
415 /*
416 * Full scaling, even if it changes the aspect ratio.
417 * Fortunately this is all done for us in hw.
418 */
419 if (crtc_state->pipe_src_h != adjusted_mode->crtc_vdisplay ||
420 crtc_state->pipe_src_w != adjusted_mode->crtc_hdisplay) {
421 pfit_control |= PFIT_ENABLE(1 << 31);
422 if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 4)
423 pfit_control |= PFIT_SCALING_AUTO(0 << 26);
424 else
425 pfit_control |= (VERT_AUTO_SCALE(1 << 9) |
426 VERT_INTERP_BILINEAR(1 << 10) |
427 HORIZ_AUTO_SCALE(1 << 5) |
428 HORIZ_INTERP_BILINEAR(1 << 6));
429 }
430 break;
431 default:
432 MISSING_CASE(conn_state->scaling_mode)({ int __ret = !!(1); if (__ret) printf("Missing case (%s == %ld)\n"
, "conn_state->scaling_mode", (long)(conn_state->scaling_mode
)); __builtin_expect(!!(__ret), 0); })
;
433 return -EINVAL22;
434 }
435
436 /* 965+ wants fuzzy fitting */
437 /* FIXME: handle multiple panels by failing gracefully */
438 if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) >= 4)
439 pfit_control |= PFIT_PIPE(crtc->pipe)((crtc->pipe) << 29) | PFIT_FILTER_FUZZY(0 << 24);
440
441out:
442 if ((pfit_control & PFIT_ENABLE(1 << 31)) == 0) {
443 pfit_control = 0;
444 pfit_pgm_ratios = 0;
445 }
446
447 /* Make sure pre-965 set dither correctly for 18bpp panels. */
448 if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) < 4 && crtc_state->pipe_bpp == 18)
449 pfit_control |= PANEL_8TO6_DITHER_ENABLE(1 << 3);
450
451 crtc_state->gmch_pfit.control = pfit_control;
452 crtc_state->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
453 crtc_state->gmch_pfit.lvds_border_bits = border;
454
455 return 0;
456}
457
458/**
459 * scale - scale values from one range to another
460 * @source_val: value in range [@source_min..@source_max]
461 * @source_min: minimum legal value for @source_val
462 * @source_max: maximum legal value for @source_val
463 * @target_min: corresponding target value for @source_min
464 * @target_max: corresponding target value for @source_max
465 *
466 * Return @source_val in range [@source_min..@source_max] scaled to range
467 * [@target_min..@target_max].
468 */
469static u32 scale(u32 source_val,
470 u32 source_min, u32 source_max,
471 u32 target_min, u32 target_max)
472{
473 u64 target_val;
474
475 WARN_ON(source_min > source_max)({ int __ret = !!((source_min > source_max)); if (__ret) printf
("%s", "WARN_ON(" "source_min > source_max" ")"); __builtin_expect
(!!(__ret), 0); })
;
4
Assuming 'source_min' is <= 'source_max'
5
Taking false branch
476 WARN_ON(target_min > target_max)({ int __ret = !!((target_min > target_max)); if (__ret) printf
("%s", "WARN_ON(" "target_min > target_max" ")"); __builtin_expect
(!!(__ret), 0); })
;
6
Taking false branch
477
478 /* defensive */
479 source_val = clamp(source_val, source_min, source_max)({ __typeof(source_val) __min_a = (({ __typeof(source_val) __max_a
= (source_val); __typeof(source_val) __max_b = (source_min);
__max_a > __max_b ? __max_a : __max_b; })); __typeof(source_val
) __min_b = (source_max); __min_a < __min_b ? __min_a : __min_b
; })
;
7
Assuming '__max_a' is <= '__max_b'
8
'?' condition is false
9
'?' condition is false
480
481 /* avoid overflows */
482 target_val = mul_u32_u32(source_val - source_min,
483 target_max - target_min);
484 target_val = DIV_ROUND_CLOSEST_ULL(target_val, source_max - source_min)(((target_val) + ((source_max - source_min) / 2)) / (source_max
- source_min))
;
10
Division by zero
485 target_val += target_min;
486
487 return target_val;
488}
489
490/* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result
491 * to [hw_min..hw_max]. */
492static u32 clamp_user_to_hw(struct intel_connector *connector,
493 u32 user_level, u32 user_max)
494{
495 struct intel_panel *panel = &connector->panel;
496 u32 hw_level;
497
498 hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max);
499 hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max)({ __typeof(hw_level) __min_a = (({ __typeof(hw_level) __max_a
= (hw_level); __typeof(hw_level) __max_b = (panel->backlight
.min); __max_a > __max_b ? __max_a : __max_b; })); __typeof
(hw_level) __min_b = (panel->backlight.max); __min_a < __min_b
? __min_a : __min_b; })
;
500
501 return hw_level;
502}
503
504/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */
505static u32 scale_hw_to_user(struct intel_connector *connector,
506 u32 hw_level, u32 user_max)
507{
508 struct intel_panel *panel = &connector->panel;
509
510 return scale(hw_level, panel->backlight.min, panel->backlight.max,
3
Calling 'scale'
511 0, user_max);
512}
513
514static u32 intel_panel_compute_brightness(struct intel_connector *connector,
515 u32 val)
516{
517 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
518 struct intel_panel *panel = &connector->panel;
519
520 drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0)({ int __ret = !!((panel->backlight.max == 0)); if (__ret)
printf("%s %s: " "%s", dev_driver_string(((&dev_priv->
drm))->dev), "", "drm_WARN_ON(" "panel->backlight.max == 0"
")"); __builtin_expect(!!(__ret), 0); })
;
521
522 if (dev_priv->params.invert_brightness < 0)
523 return val;
524
525 if (dev_priv->params.invert_brightness > 0 ||
526 dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS(1<<2)) {
527 return panel->backlight.max - val + panel->backlight.min;
528 }
529
530 return val;
531}
532
533static u32 lpt_get_backlight(struct intel_connector *connector)
534{
535 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
536
537 return intel_de_read(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) })) & BACKLIGHT_DUTY_CYCLE_MASK(0xffff);
538}
539
540static u32 pch_get_backlight(struct intel_connector *connector)
541{
542 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
543
544 return intel_de_read(dev_priv, BLC_PWM_CPU_CTL((const i915_reg_t){ .reg = (0x48254) })) & BACKLIGHT_DUTY_CYCLE_MASK(0xffff);
545}
546
547static u32 i9xx_get_backlight(struct intel_connector *connector)
548{
549 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
550 struct intel_panel *panel = &connector->panel;
551 u32 val;
552
553 val = intel_de_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61254) })
) & BACKLIGHT_DUTY_CYCLE_MASK(0xffff);
554 if (INTEL_GEN(dev_priv)((&(dev_priv)->__info)->gen) < 4)
555 val >>= 1;
556
557 if (panel->backlight.combination_mode) {
558 u8 lbpc;
559
560 pci_read_config_byte(dev_priv->drm.pdev, LBPC0xf4, &lbpc);
561 val *= lbpc;
562 }
563
564 return val;
565}
566
567static u32 _vlv_get_backlight(struct drm_i915_privateinteldrm_softc *dev_priv, enum pipe pipe)
568{
569 if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B)({ int __ret = !!((pipe != PIPE_A && pipe != PIPE_B))
; if (__ret) printf("%s %s: " "%s", dev_driver_string(((&
dev_priv->drm))->dev), "", "drm_WARN_ON(" "pipe != PIPE_A && pipe != PIPE_B"
")"); __builtin_expect(!!(__ret), 0); })
)
570 return 0;
571
572 return intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61254)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61354)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61254))))
) })
) & BACKLIGHT_DUTY_CYCLE_MASK(0xffff);
573}
574
575static u32 vlv_get_backlight(struct intel_connector *connector)
576{
577 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
578 enum pipe pipe = intel_connector_get_pipe(connector);
579
580 return _vlv_get_backlight(dev_priv, pipe);
581}
582
583static u32 bxt_get_backlight(struct intel_connector *connector)
584{
585 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
586 struct intel_panel *panel = &connector->panel;
587
588 return intel_de_read(dev_priv,
589 BXT_BLC_PWM_DUTY(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8258) + (panel->backlight
.controller) * ((0xC8358) - (0xC8258)))) })
);
590}
591
592static u32 pwm_get_backlight(struct intel_connector *connector)
593{
594 STUB()do { printf("%s: stub\n", __func__); } while(0);
595 return 0;
596#ifdef notyet
597 struct intel_panel *panel = &connector->panel;
598 struct pwm_state state;
599
600 pwm_get_state(panel->backlight.pwm, &state);
601 return pwm_get_relative_duty_cycle(&state, 100);
602#endif
603}
604
605static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
606{
607 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
608 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
609
610 u32 val = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) })) & ~BACKLIGHT_DUTY_CYCLE_MASK(0xffff);
611 intel_de_write(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) }), val | level);
612}
613
614static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level)
615{
616 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
617 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
618 u32 tmp;
619
620 tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL((const i915_reg_t){ .reg = (0x48254) })) & ~BACKLIGHT_DUTY_CYCLE_MASK(0xffff);
621 intel_de_write(dev_priv, BLC_PWM_CPU_CTL((const i915_reg_t){ .reg = (0x48254) }), tmp | level);
622}
623
624static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32 level)
625{
626 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
627 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
628 struct intel_panel *panel = &connector->panel;
629 u32 tmp, mask;
630
631 drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0)({ int __ret = !!((panel->backlight.max == 0)); if (__ret)
printf("%s %s: " "%s", dev_driver_string(((&dev_priv->
drm))->dev), "", "drm_WARN_ON(" "panel->backlight.max == 0"
")"); __builtin_expect(!!(__ret), 0); })
;
632
633 if (panel->backlight.combination_mode) {
634 u8 lbpc;
635
636 lbpc = level * 0xfe / panel->backlight.max + 1;
637 level /= lbpc;
638 pci_write_config_byte(dev_priv->drm.pdev, LBPC0xf4, lbpc);
639 }
640
641 if (IS_GEN(dev_priv, 4)(0 + (&(dev_priv)->__info)->gen == (4))) {
642 mask = BACKLIGHT_DUTY_CYCLE_MASK(0xffff);
643 } else {
644 level <<= 1;
645 mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV(0xfffe);
646 }
647
648 tmp = intel_de_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61254) })
) & ~mask;
649 intel_de_write(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61254) })
, tmp | level);
650}
651
652static void vlv_set_backlight(const struct drm_connector_state *conn_state, u32 level)
653{
654 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
655 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
656 enum pipe pipe = to_intel_crtc(conn_state->crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr
= (conn_state->crtc); (struct intel_crtc *)( (char *)__mptr
- __builtin_offsetof(struct intel_crtc, base) );})
->pipe;
657 u32 tmp;
658
659 tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61254)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61354)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61254))))
) })
) & ~BACKLIGHT_DUTY_CYCLE_MASK(0xffff);
660 intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61254)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61354)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61254))))
) })
, tmp | level);
661}
662
663static void bxt_set_backlight(const struct drm_connector_state *conn_state, u32 level)
664{
665 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
666 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
667 struct intel_panel *panel = &connector->panel;
668
669 intel_de_write(dev_priv,
670 BXT_BLC_PWM_DUTY(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8258) + (panel->backlight
.controller) * ((0xC8358) - (0xC8258)))) })
, level);
671}
672
673static void pwm_set_backlight(const struct drm_connector_state *conn_state, u32 level)
674{
675 STUB()do { printf("%s: stub\n", __func__); } while(0);
676#ifdef notyet
677 struct intel_panel *panel = &to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
->panel;
678
679 pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100);
680 pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
681#endif
682}
683
684static void
685intel_panel_actually_set_backlight(const struct drm_connector_state *conn_state, u32 level)
686{
687 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
688 struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev);
689 struct intel_panel *panel = &connector->panel;
690
691 drm_dbg_kms(&i915->drm, "set backlight PWM = %d\n", level)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "set backlight PWM = %d\n"
, level)
;
692
693 level = intel_panel_compute_brightness(connector, level);
694 panel->backlight.set(conn_state, level);
695}
696
697/* set backlight brightness to level in range [0..max], assuming hw min is
698 * respected.
699 */
700void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state,
701 u32 user_level, u32 user_max)
702{
703 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
704 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
705 struct intel_panel *panel = &connector->panel;
706 u32 hw_level;
707
708 /*
709 * Lack of crtc may occur during driver init because
710 * connection_mutex isn't held across the entire backlight
711 * setup + modeset readout, and the BIOS can issue the
712 * requests at any time.
713 */
714 if (!panel->backlight.present || !conn_state->crtc)
715 return;
716
717 mutex_lock(&dev_priv->backlight_lock)rw_enter_write(&dev_priv->backlight_lock);
718
719 drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0)({ int __ret = !!((panel->backlight.max == 0)); if (__ret)
printf("%s %s: " "%s", dev_driver_string(((&dev_priv->
drm))->dev), "", "drm_WARN_ON(" "panel->backlight.max == 0"
")"); __builtin_expect(!!(__ret), 0); })
;
720
721 hw_level = clamp_user_to_hw(connector, user_level, user_max);
722 panel->backlight.level = hw_level;
723
724 if (panel->backlight.device)
725 panel->backlight.device->props.brightness =
726 scale_hw_to_user(connector,
727 panel->backlight.level,
728 panel->backlight.device->props.max_brightness);
729
730 if (panel->backlight.enabled)
731 intel_panel_actually_set_backlight(conn_state, hw_level);
732
733 mutex_unlock(&dev_priv->backlight_lock)rw_exit_write(&dev_priv->backlight_lock);
734}
735
736static void lpt_disable_backlight(const struct drm_connector_state *old_conn_state)
737{
738 struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (old_conn_state->connector); (struct intel_connector
*)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
739 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
740 u32 tmp;
741
742 intel_panel_actually_set_backlight(old_conn_state, 0);
743
744 /*
745 * Although we don't support or enable CPU PWM with LPT/SPT based
746 * systems, it may have been enabled prior to loading the
747 * driver. Disable to avoid warnings on LCPLL disable.
748 *
749 * This needs rework if we need to add support for CPU PWM on PCH split
750 * platforms.
751 */
752 tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }));
753 if (tmp & BLM_PWM_ENABLE(1 << 31)) {
754 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "cpu backlight was enabled, disabling\n"
)
755 "cpu backlight was enabled, disabling\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "cpu backlight was enabled, disabling\n"
)
;
756 intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }),
757 tmp & ~BLM_PWM_ENABLE(1 << 31));
758 }
759
760 tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }));
761 intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), tmp & ~BLM_PCH_PWM_ENABLE(1 << 31));
762}
763
764static void pch_disable_backlight(const struct drm_connector_state *old_conn_state)
765{
766 struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (old_conn_state->connector); (struct intel_connector
*)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
767 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
768 u32 tmp;
769
770 intel_panel_actually_set_backlight(old_conn_state, 0);
771
772 tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }));
773 intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }), tmp & ~BLM_PWM_ENABLE(1 << 31));
774
775 tmp = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }));
776 intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), tmp & ~BLM_PCH_PWM_ENABLE(1 << 31));
777}
778
779static void i9xx_disable_backlight(const struct drm_connector_state *old_conn_state)
780{
781 intel_panel_actually_set_backlight(old_conn_state, 0);
782}
783
784static void i965_disable_backlight(const struct drm_connector_state *old_conn_state)
785{
786 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(old_conn_state->connector->dev);
787 u32 tmp;
788
789 intel_panel_actually_set_backlight(old_conn_state, 0);
790
791 tmp = intel_de_read(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61250) })
);
792 intel_de_write(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61250) })
, tmp & ~BLM_PWM_ENABLE(1 << 31));
793}
794
795static void vlv_disable_backlight(const struct drm_connector_state *old_conn_state)
796{
797 struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (old_conn_state->connector); (struct intel_connector
*)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
798 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
799 enum pipe pipe = to_intel_crtc(old_conn_state->crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr
= (old_conn_state->crtc); (struct intel_crtc *)( (char *)
__mptr - __builtin_offsetof(struct intel_crtc, base) );})
->pipe;
800 u32 tmp;
801
802 intel_panel_actually_set_backlight(old_conn_state, 0);
803
804 tmp = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61350)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61250))))
) })
);
805 intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61350)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61250))))
) })
,
806 tmp & ~BLM_PWM_ENABLE(1 << 31));
807}
808
809static void bxt_disable_backlight(const struct drm_connector_state *old_conn_state)
810{
811 struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (old_conn_state->connector); (struct intel_connector
*)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
812 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
813 struct intel_panel *panel = &connector->panel;
814 u32 tmp, val;
815
816 intel_panel_actually_set_backlight(old_conn_state, 0);
817
818 tmp = intel_de_read(dev_priv,
819 BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
);
820 intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
,
821 tmp & ~BXT_BLC_PWM_ENABLE(1 << 31));
822
823 if (panel->backlight.controller == 1) {
824 val = intel_de_read(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) }));
825 val &= ~UTIL_PIN_ENABLE(1 << 31);
826 intel_de_write(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) }), val);
827 }
828}
829
830static void cnp_disable_backlight(const struct drm_connector_state *old_conn_state)
831{
832 struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (old_conn_state->connector); (struct intel_connector
*)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
833 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
834 struct intel_panel *panel = &connector->panel;
835 u32 tmp;
836
837 intel_panel_actually_set_backlight(old_conn_state, 0);
838
839 tmp = intel_de_read(dev_priv,
840 BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
);
841 intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
,
842 tmp & ~BXT_BLC_PWM_ENABLE(1 << 31));
843}
844
845static void pwm_disable_backlight(const struct drm_connector_state *old_conn_state)
846{
847 STUB()do { printf("%s: stub\n", __func__); } while(0);
848#ifdef notyet
849 struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (old_conn_state->connector); (struct intel_connector
*)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
850 struct intel_panel *panel = &connector->panel;
851
852 panel->backlight.pwm_state.enabled = false0;
853 pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
854#endif
855}
856
857void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state)
858{
859 struct intel_connector *connector = to_intel_connector(old_conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (old_conn_state->connector); (struct intel_connector
*)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
860 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
861 struct intel_panel *panel = &connector->panel;
862
863 if (!panel->backlight.present)
864 return;
865
866 /*
867 * Do not disable backlight on the vga_switcheroo path. When switching
868 * away from i915, the other client may depend on i915 to handle the
869 * backlight. This will leave the backlight on unnecessarily when
870 * another client is not activated.
871 */
872 if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) {
873 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Skipping backlight disable on vga switch\n"
)
874 "Skipping backlight disable on vga switch\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Skipping backlight disable on vga switch\n"
)
;
875 return;
876 }
877
878 mutex_lock(&dev_priv->backlight_lock)rw_enter_write(&dev_priv->backlight_lock);
879
880 if (panel->backlight.device)
881 panel->backlight.device->props.power = FB_BLANK_POWERDOWN4;
882 panel->backlight.enabled = false0;
883 panel->backlight.disable(old_conn_state);
884
885 mutex_unlock(&dev_priv->backlight_lock)rw_exit_write(&dev_priv->backlight_lock);
886}
887
888static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
889 const struct drm_connector_state *conn_state)
890{
891 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
892 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
893 struct intel_panel *panel = &connector->panel;
894 u32 pch_ctl1, pch_ctl2, schicken;
895
896 pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }));
897 if (pch_ctl1 & BLM_PCH_PWM_ENABLE(1 << 31)) {
898 drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "pch backlight already enabled\n"
)
;
899 pch_ctl1 &= ~BLM_PCH_PWM_ENABLE(1 << 31);
900 intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), pch_ctl1);
901 }
902
903 if (HAS_PCH_LPT(dev_priv)(((dev_priv)->pch_type) == PCH_LPT)) {
904 schicken = intel_de_read(dev_priv, SOUTH_CHICKEN2((const i915_reg_t){ .reg = (0xc2004) }));
905 if (panel->backlight.alternate_pwm_increment)
906 schicken |= LPT_PWM_GRANULARITY(1 << 5);
907 else
908 schicken &= ~LPT_PWM_GRANULARITY(1 << 5);
909 intel_de_write(dev_priv, SOUTH_CHICKEN2((const i915_reg_t){ .reg = (0xc2004) }), schicken);
910 } else {
911 schicken = intel_de_read(dev_priv, SOUTH_CHICKEN1((const i915_reg_t){ .reg = (0xc2000) }));
912 if (panel->backlight.alternate_pwm_increment)
913 schicken |= SPT_PWM_GRANULARITY(1 << 0);
914 else
915 schicken &= ~SPT_PWM_GRANULARITY(1 << 0);
916 intel_de_write(dev_priv, SOUTH_CHICKEN1((const i915_reg_t){ .reg = (0xc2000) }), schicken);
917 }
918
919 pch_ctl2 = panel->backlight.max << 16;
920 intel_de_write(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) }), pch_ctl2);
921
922 pch_ctl1 = 0;
923 if (panel->backlight.active_low_pwm)
924 pch_ctl1 |= BLM_PCH_POLARITY(1 << 29);
925
926 /* After LPT, override is the default. */
927 if (HAS_PCH_LPT(dev_priv)(((dev_priv)->pch_type) == PCH_LPT))
928 pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE(1 << 30);
929
930 intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), pch_ctl1);
931 intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }));
932 intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }),
933 pch_ctl1 | BLM_PCH_PWM_ENABLE(1 << 31));
934
935 /* This won't stick until the above enable. */
936 intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
937}
938
939static void pch_enable_backlight(const struct intel_crtc_state *crtc_state,
940 const struct drm_connector_state *conn_state)
941{
942 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
943 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
944 struct intel_panel *panel = &connector->panel;
945 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
946 u32 cpu_ctl2, pch_ctl1, pch_ctl2;
947
948 cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }));
949 if (cpu_ctl2 & BLM_PWM_ENABLE(1 << 31)) {
950 drm_dbg_kms(&dev_priv->drm, "cpu backlight already enabled\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "cpu backlight already enabled\n"
)
;
951 cpu_ctl2 &= ~BLM_PWM_ENABLE(1 << 31);
952 intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }), cpu_ctl2);
953 }
954
955 pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }));
956 if (pch_ctl1 & BLM_PCH_PWM_ENABLE(1 << 31)) {
957 drm_dbg_kms(&dev_priv->drm, "pch backlight already enabled\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "pch backlight already enabled\n"
)
;
958 pch_ctl1 &= ~BLM_PCH_PWM_ENABLE(1 << 31);
959 intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), pch_ctl1);
960 }
961
962 if (cpu_transcoder == TRANSCODER_EDP)
963 cpu_ctl2 = BLM_TRANSCODER_EDP(3 << 29);
964 else
965 cpu_ctl2 = BLM_PIPE(cpu_transcoder)((cpu_transcoder) << 29);
966 intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }), cpu_ctl2);
967 intel_de_posting_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }));
968 intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }), cpu_ctl2 | BLM_PWM_ENABLE(1 << 31));
969
970 /* This won't stick until the above enable. */
971 intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
972
973 pch_ctl2 = panel->backlight.max << 16;
974 intel_de_write(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) }), pch_ctl2);
975
976 pch_ctl1 = 0;
977 if (panel->backlight.active_low_pwm)
978 pch_ctl1 |= BLM_PCH_POLARITY(1 << 29);
979
980 intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }), pch_ctl1);
981 intel_de_posting_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }));
982 intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }),
983 pch_ctl1 | BLM_PCH_PWM_ENABLE(1 << 31));
984}
985
986static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state,
987 const struct drm_connector_state *conn_state)
988{
989 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
990 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
991 struct intel_panel *panel = &connector->panel;
992 u32 ctl, freq;
993
994 ctl = intel_de_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61254) })
);
995 if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV(0xfffe)) {
996 drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "backlight already enabled\n"
)
;
997 intel_de_write(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61254) })
, 0);
998 }
999
1000 freq = panel->backlight.max;
1001 if (panel->backlight.combination_mode)
1002 freq /= 0xff;
1003
1004 ctl = freq << 17;
1005 if (panel->backlight.combination_mode)
1006 ctl |= BLM_LEGACY_MODE(1 << 16);
1007 if (IS_PINEVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_PINEVIEW) && panel->backlight.active_low_pwm)
1008 ctl |= BLM_POLARITY_PNV(1 << 0);
1009
1010 intel_de_write(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61254) })
, ctl);
1011 intel_de_posting_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61254) })
);
1012
1013 /* XXX: combine this into above write? */
1014 intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
1015
1016 /*
1017 * Needed to enable backlight on some 855gm models. BLC_HIST_CTL is
1018 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2
1019 * that has backlight.
1020 */
1021 if (IS_GEN(dev_priv, 2)(0 + (&(dev_priv)->__info)->gen == (2)))
1022 intel_de_write(dev_priv, BLC_HIST_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61260) })
, BLM_HISTOGRAM_ENABLE(1 << 31));
1023}
1024
1025static void i965_enable_backlight(const struct intel_crtc_state *crtc_state,
1026 const struct drm_connector_state *conn_state)
1027{
1028 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
1029 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1030 struct intel_panel *panel = &connector->panel;
1031 enum pipe pipe = to_intel_crtc(conn_state->crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr
= (conn_state->crtc); (struct intel_crtc *)( (char *)__mptr
- __builtin_offsetof(struct intel_crtc, base) );})
->pipe;
1032 u32 ctl, ctl2, freq;
1033
1034 ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61250) })
);
1035 if (ctl2 & BLM_PWM_ENABLE(1 << 31)) {
1036 drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "backlight already enabled\n"
)
;
1037 ctl2 &= ~BLM_PWM_ENABLE(1 << 31);
1038 intel_de_write(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61250) })
, ctl2);
1039 }
1040
1041 freq = panel->backlight.max;
1042 if (panel->backlight.combination_mode)
1043 freq /= 0xff;
1044
1045 ctl = freq << 16;
1046 intel_de_write(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61254) })
, ctl);
1047
1048 ctl2 = BLM_PIPE(pipe)((pipe) << 29);
1049 if (panel->backlight.combination_mode)
1050 ctl2 |= BLM_COMBINATION_MODE(1 << 30);
1051 if (panel->backlight.active_low_pwm)
1052 ctl2 |= BLM_POLARITY_I965(1 << 28);
1053 intel_de_write(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61250) })
, ctl2);
1054 intel_de_posting_read(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61250) })
);
1055 intel_de_write(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61250) })
, ctl2 | BLM_PWM_ENABLE(1 << 31));
1056
1057 intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
1058}
1059
1060static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state,
1061 const struct drm_connector_state *conn_state)
1062{
1063 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
1064 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1065 struct intel_panel *panel = &connector->panel;
1066 enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr
= (crtc_state->uapi.crtc); (struct intel_crtc *)( (char *
)__mptr - __builtin_offsetof(struct intel_crtc, base) );})
->pipe;
1067 u32 ctl, ctl2;
1068
1069 ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61350)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61250))))
) })
);
1070 if (ctl2 & BLM_PWM_ENABLE(1 << 31)) {
1071 drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "backlight already enabled\n"
)
;
1072 ctl2 &= ~BLM_PWM_ENABLE(1 << 31);
1073 intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61350)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61250))))
) })
, ctl2);
1074 }
1075
1076 ctl = panel->backlight.max << 16;
1077 intel_de_write(dev_priv, VLV_BLC_PWM_CTL(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61254)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61354)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61254))))
) })
, ctl);
1078
1079 /* XXX: combine this into above write? */
1080 intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
1081
1082 ctl2 = 0;
1083 if (panel->backlight.active_low_pwm)
1084 ctl2 |= BLM_POLARITY_I965(1 << 28);
1085 intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61350)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61250))))
) })
, ctl2);
1086 intel_de_posting_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61350)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61250))))
) })
);
1087 intel_de_write(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61350)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61250))))
) })
,
1088 ctl2 | BLM_PWM_ENABLE(1 << 31));
1089}
1090
1091static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state,
1092 const struct drm_connector_state *conn_state)
1093{
1094 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
1095 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1096 struct intel_panel *panel = &connector->panel;
1097 enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr
= (crtc_state->uapi.crtc); (struct intel_crtc *)( (char *
)__mptr - __builtin_offsetof(struct intel_crtc, base) );})
->pipe;
1098 u32 pwm_ctl, val;
1099
1100 /* Controller 1 uses the utility pin. */
1101 if (panel->backlight.controller == 1) {
1102 val = intel_de_read(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) }));
1103 if (val & UTIL_PIN_ENABLE(1 << 31)) {
1104 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "util pin already enabled\n"
)
1105 "util pin already enabled\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "util pin already enabled\n"
)
;
1106 val &= ~UTIL_PIN_ENABLE(1 << 31);
1107 intel_de_write(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) }), val);
1108 }
1109
1110 val = 0;
1111 if (panel->backlight.util_pin_active_low)
1112 val |= UTIL_PIN_POLARITY(1 << 22);
1113 intel_de_write(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) }),
1114 val | UTIL_PIN_PIPE(pipe)((pipe) << 29) | UTIL_PIN_MODE_PWM(1 << 24) | UTIL_PIN_ENABLE(1 << 31));
1115 }
1116
1117 pwm_ctl = intel_de_read(dev_priv,
1118 BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
);
1119 if (pwm_ctl & BXT_BLC_PWM_ENABLE(1 << 31)) {
1120 drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "backlight already enabled\n"
)
;
1121 pwm_ctl &= ~BXT_BLC_PWM_ENABLE(1 << 31);
1122 intel_de_write(dev_priv,
1123 BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
,
1124 pwm_ctl);
1125 }
1126
1127 intel_de_write(dev_priv,
1128 BXT_BLC_PWM_FREQ(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8254) + (panel->backlight
.controller) * ((0xC8354) - (0xC8254)))) })
,
1129 panel->backlight.max);
1130
1131 intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
1132
1133 pwm_ctl = 0;
1134 if (panel->backlight.active_low_pwm)
1135 pwm_ctl |= BXT_BLC_PWM_POLARITY(1 << 29);
1136
1137 intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
,
1138 pwm_ctl);
1139 intel_de_posting_read(dev_priv,
1140 BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
);
1141 intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
,
1142 pwm_ctl | BXT_BLC_PWM_ENABLE(1 << 31));
1143}
1144
1145static void cnp_enable_backlight(const struct intel_crtc_state *crtc_state,
1146 const struct drm_connector_state *conn_state)
1147{
1148 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
1149 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1150 struct intel_panel *panel = &connector->panel;
1151 u32 pwm_ctl;
1152
1153 pwm_ctl = intel_de_read(dev_priv,
1154 BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
);
1155 if (pwm_ctl & BXT_BLC_PWM_ENABLE(1 << 31)) {
1156 drm_dbg_kms(&dev_priv->drm, "backlight already enabled\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "backlight already enabled\n"
)
;
1157 pwm_ctl &= ~BXT_BLC_PWM_ENABLE(1 << 31);
1158 intel_de_write(dev_priv,
1159 BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
,
1160 pwm_ctl);
1161 }
1162
1163 intel_de_write(dev_priv,
1164 BXT_BLC_PWM_FREQ(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8254) + (panel->backlight
.controller) * ((0xC8354) - (0xC8254)))) })
,
1165 panel->backlight.max);
1166
1167 intel_panel_actually_set_backlight(conn_state, panel->backlight.level);
1168
1169 pwm_ctl = 0;
1170 if (panel->backlight.active_low_pwm)
1171 pwm_ctl |= BXT_BLC_PWM_POLARITY(1 << 29);
1172
1173 intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
,
1174 pwm_ctl);
1175 intel_de_posting_read(dev_priv,
1176 BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
);
1177 intel_de_write(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
,
1178 pwm_ctl | BXT_BLC_PWM_ENABLE(1 << 31));
1179}
1180
1181static void pwm_enable_backlight(const struct intel_crtc_state *crtc_state,
1182 const struct drm_connector_state *conn_state)
1183{
1184 STUB()do { printf("%s: stub\n", __func__); } while(0);
1185#ifdef notyet
1186 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
1187 struct intel_panel *panel = &connector->panel;
1188 int level = panel->backlight.level;
1189
1190 level = intel_panel_compute_brightness(connector, level);
1191 pwm_set_relative_duty_cycle(&panel->backlight.pwm_state, level, 100);
1192 panel->backlight.pwm_state.enabled = true1;
1193 pwm_apply_state(panel->backlight.pwm, &panel->backlight.pwm_state);
1194#endif
1195}
1196
1197static void __intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
1198 const struct drm_connector_state *conn_state)
1199{
1200 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
1201 struct intel_panel *panel = &connector->panel;
1202
1203 WARN_ON(panel->backlight.max == 0)({ int __ret = !!((panel->backlight.max == 0)); if (__ret)
printf("%s", "WARN_ON(" "panel->backlight.max == 0" ")");
__builtin_expect(!!(__ret), 0); })
;
1204
1205 if (panel->backlight.level <= panel->backlight.min) {
1206 panel->backlight.level = panel->backlight.max;
1207 if (panel->backlight.device)
1208 panel->backlight.device->props.brightness =
1209 scale_hw_to_user(connector,
1210 panel->backlight.level,
1211 panel->backlight.device->props.max_brightness);
1212 }
1213
1214 panel->backlight.enable(crtc_state, conn_state);
1215 panel->backlight.enabled = true1;
1216 if (panel->backlight.device)
1217 panel->backlight.device->props.power = FB_BLANK_UNBLANK0;
1218}
1219
1220void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
1221 const struct drm_connector_state *conn_state)
1222{
1223 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
1224 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1225 struct intel_panel *panel = &connector->panel;
1226 enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)({ const __typeof( ((struct intel_crtc *)0)->base ) *__mptr
= (crtc_state->uapi.crtc); (struct intel_crtc *)( (char *
)__mptr - __builtin_offsetof(struct intel_crtc, base) );})
->pipe;
1227
1228 if (!panel->backlight.present)
1229 return;
1230
1231 drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(pipe))drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "pipe %c\n"
, ((pipe) + 'A'))
;
1232
1233 mutex_lock(&dev_priv->backlight_lock)rw_enter_write(&dev_priv->backlight_lock);
1234
1235 __intel_panel_enable_backlight(crtc_state, conn_state);
1236
1237 mutex_unlock(&dev_priv->backlight_lock)rw_exit_write(&dev_priv->backlight_lock);
1238}
1239
1240#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)1
1241static u32 intel_panel_get_backlight(struct intel_connector *connector)
1242{
1243 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1244 struct intel_panel *panel = &connector->panel;
1245 u32 val = 0;
1246
1247 mutex_lock(&dev_priv->backlight_lock)rw_enter_write(&dev_priv->backlight_lock);
1248
1249 if (panel->backlight.enabled) {
1250 val = panel->backlight.get(connector);
1251 val = intel_panel_compute_brightness(connector, val);
1252 }
1253
1254 mutex_unlock(&dev_priv->backlight_lock)rw_exit_write(&dev_priv->backlight_lock);
1255
1256 drm_dbg_kms(&dev_priv->drm, "get backlight PWM = %d\n", val)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "get backlight PWM = %d\n"
, val)
;
1257 return val;
1258}
1259
1260/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */
1261static u32 scale_user_to_hw(struct intel_connector *connector,
1262 u32 user_level, u32 user_max)
1263{
1264 struct intel_panel *panel = &connector->panel;
1265
1266 return scale(user_level, 0, user_max,
1267 panel->backlight.min, panel->backlight.max);
1268}
1269
1270/* set backlight brightness to level in range [0..max], scaling wrt hw min */
1271static void intel_panel_set_backlight(const struct drm_connector_state *conn_state,
1272 u32 user_level, u32 user_max)
1273{
1274 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
1275 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1276 struct intel_panel *panel = &connector->panel;
1277 u32 hw_level;
1278
1279 if (!panel->backlight.present)
1280 return;
1281
1282 mutex_lock(&dev_priv->backlight_lock)rw_enter_write(&dev_priv->backlight_lock);
1283
1284 drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0)({ int __ret = !!((panel->backlight.max == 0)); if (__ret)
printf("%s %s: " "%s", dev_driver_string(((&dev_priv->
drm))->dev), "", "drm_WARN_ON(" "panel->backlight.max == 0"
")"); __builtin_expect(!!(__ret), 0); })
;
1285
1286 hw_level = scale_user_to_hw(connector, user_level, user_max);
1287 panel->backlight.level = hw_level;
1288
1289 if (panel->backlight.enabled)
1290 intel_panel_actually_set_backlight(conn_state, hw_level);
1291
1292 mutex_unlock(&dev_priv->backlight_lock)rw_exit_write(&dev_priv->backlight_lock);
1293}
1294
1295static int intel_backlight_device_update_status(struct backlight_device *bd)
1296{
1297 struct intel_connector *connector = bl_get_data(bd)(bd)->data;
1298 struct intel_panel *panel = &connector->panel;
1299 struct drm_device *dev = connector->base.dev;
1300
1301 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL((void *)0));
1302 DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",__drm_dbg(DRM_UT_KMS, "updating intel_backlight, brightness=%d/%d\n"
, bd->props.brightness, bd->props.max_brightness)
1303 bd->props.brightness, bd->props.max_brightness)__drm_dbg(DRM_UT_KMS, "updating intel_backlight, brightness=%d/%d\n"
, bd->props.brightness, bd->props.max_brightness)
;
1304 intel_panel_set_backlight(connector->base.state, bd->props.brightness,
1305 bd->props.max_brightness);
1306
1307 /*
1308 * Allow flipping bl_power as a sub-state of enabled. Sadly the
1309 * backlight class device does not make it easy to to differentiate
1310 * between callbacks for brightness and bl_power, so our backlight_power
1311 * callback needs to take this into account.
1312 */
1313 if (panel->backlight.enabled) {
1314 if (panel->backlight.power) {
1315 bool_Bool enable = bd->props.power == FB_BLANK_UNBLANK0 &&
1316 bd->props.brightness != 0;
1317 panel->backlight.power(connector, enable);
1318 }
1319 } else {
1320 bd->props.power = FB_BLANK_POWERDOWN4;
1321 }
1322
1323 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1324 return 0;
1325}
1326
1327static int intel_backlight_device_get_brightness(struct backlight_device *bd)
1328{
1329 struct intel_connector *connector = bl_get_data(bd)(bd)->data;
1330 struct drm_device *dev = connector->base.dev;
1331 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev);
1332 intel_wakeref_t wakeref;
1333 int ret = 0;
1334
1335 with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref)for ((wakeref) = intel_runtime_pm_get(&dev_priv->runtime_pm
); (wakeref); intel_runtime_pm_put((&dev_priv->runtime_pm
), (wakeref)), (wakeref) = 0)
{
1
Loop condition is true. Entering loop body
1336 u32 hw_level;
1337
1338 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL((void *)0));
1339
1340 hw_level = intel_panel_get_backlight(connector);
1341 ret = scale_hw_to_user(connector,
2
Calling 'scale_hw_to_user'
1342 hw_level, bd->props.max_brightness);
1343
1344 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1345 }
1346
1347 return ret;
1348}
1349
1350static const struct backlight_ops intel_backlight_device_ops = {
1351 .update_status = intel_backlight_device_update_status,
1352 .get_brightness = intel_backlight_device_get_brightness,
1353};
1354
1355int intel_backlight_device_register(struct intel_connector *connector)
1356{
1357 struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev);
1358 struct intel_panel *panel = &connector->panel;
1359 struct backlight_properties props;
1360
1361 if (WARN_ON(panel->backlight.device)({ int __ret = !!((panel->backlight.device)); if (__ret) printf
("%s", "WARN_ON(" "panel->backlight.device" ")"); __builtin_expect
(!!(__ret), 0); })
)
1362 return -ENODEV19;
1363
1364 if (!panel->backlight.present)
1365 return 0;
1366
1367 WARN_ON(panel->backlight.max == 0)({ int __ret = !!((panel->backlight.max == 0)); if (__ret)
printf("%s", "WARN_ON(" "panel->backlight.max == 0" ")");
__builtin_expect(!!(__ret), 0); })
;
1368
1369 memset(&props, 0, sizeof(props))__builtin_memset((&props), (0), (sizeof(props)));
1370 props.type = BACKLIGHT_RAW0;
1371
1372 /*
1373 * Note: Everything should work even if the backlight device max
1374 * presented to the userspace is arbitrarily chosen.
1375 */
1376 props.max_brightness = panel->backlight.max;
1377 props.brightness = scale_hw_to_user(connector,
1378 panel->backlight.level,
1379 props.max_brightness);
1380
1381 if (panel->backlight.enabled)
1382 props.power = FB_BLANK_UNBLANK0;
1383 else
1384 props.power = FB_BLANK_POWERDOWN4;
1385
1386 /*
1387 * Note: using the same name independent of the connector prevents
1388 * registration of multiple backlight devices in the driver.
1389 */
1390 panel->backlight.device =
1391 backlight_device_register("intel_backlight",
1392 connector->base.kdev,
1393 connector,
1394 &intel_backlight_device_ops, &props);
1395
1396 if (IS_ERR(panel->backlight.device)) {
1397 drm_err(&i915->drm, "Failed to register backlight: %ld\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to register backlight: %ld\n"
, ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc->p_p->ps_pid, __func__ , PTR_ERR
(panel->backlight.device))
1398 PTR_ERR(panel->backlight.device))printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to register backlight: %ld\n"
, ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc->p_p->ps_pid, __func__ , PTR_ERR
(panel->backlight.device))
;
1399 panel->backlight.device = NULL((void *)0);
1400 return -ENODEV19;
1401 }
1402
1403 drm_dbg_kms(&i915->drm,drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Connector %s backlight sysfs interface registered\n"
, connector->base.name)
1404 "Connector %s backlight sysfs interface registered\n",drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Connector %s backlight sysfs interface registered\n"
, connector->base.name)
1405 connector->base.name)drm_dev_dbg((&i915->drm)->dev, DRM_UT_KMS, "Connector %s backlight sysfs interface registered\n"
, connector->base.name)
;
1406
1407 return 0;
1408}
1409
1410void intel_backlight_device_unregister(struct intel_connector *connector)
1411{
1412 struct intel_panel *panel = &connector->panel;
1413
1414 if (panel->backlight.device) {
1415 backlight_device_unregister(panel->backlight.device);
1416 panel->backlight.device = NULL((void *)0);
1417 }
1418}
1419#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
1420
1421/*
1422 * CNP: PWM clock frequency is 19.2 MHz or 24 MHz.
1423 * PWM increment = 1
1424 */
1425static u32 cnp_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1426{
1427 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1428
1429 return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),((((1000 * ((&(dev_priv)->__runtime)->rawclk_freq))
) + ((pwm_freq_hz) / 2)) / (pwm_freq_hz))
1430 pwm_freq_hz)((((1000 * ((&(dev_priv)->__runtime)->rawclk_freq))
) + ((pwm_freq_hz) / 2)) / (pwm_freq_hz))
;
1431}
1432
1433/*
1434 * BXT: PWM clock frequency = 19.2 MHz.
1435 */
1436static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1437{
1438 return DIV_ROUND_CLOSEST(KHz(19200), pwm_freq_hz)((((1000 * (19200))) + ((pwm_freq_hz) / 2)) / (pwm_freq_hz));
1439}
1440
1441/*
1442 * SPT: This value represents the period of the PWM stream in clock periods
1443 * multiplied by 16 (default increment) or 128 (alternate increment selected in
1444 * SCHICKEN_1 bit 0). PWM clock is 24 MHz.
1445 */
1446static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1447{
1448 struct intel_panel *panel = &connector->panel;
1449 u32 mul;
1450
1451 if (panel->backlight.alternate_pwm_increment)
1452 mul = 128;
1453 else
1454 mul = 16;
1455
1456 return DIV_ROUND_CLOSEST(MHz(24), pwm_freq_hz * mul)((((1000 * (1000 * (24)))) + ((pwm_freq_hz * mul) / 2)) / (pwm_freq_hz
* mul))
;
1457}
1458
1459/*
1460 * LPT: This value represents the period of the PWM stream in clock periods
1461 * multiplied by 128 (default increment) or 16 (alternate increment, selected in
1462 * LPT SOUTH_CHICKEN2 register bit 5).
1463 */
1464static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1465{
1466 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1467 struct intel_panel *panel = &connector->panel;
1468 u32 mul, clock;
1469
1470 if (panel->backlight.alternate_pwm_increment)
1471 mul = 16;
1472 else
1473 mul = 128;
1474
1475 if (HAS_PCH_LPT_H(dev_priv)(((dev_priv)->pch_id) == 0x8c00 || ((dev_priv)->pch_id)
== 0x8c80)
)
1476 clock = MHz(135)(1000 * (1000 * (135))); /* LPT:H */
1477 else
1478 clock = MHz(24)(1000 * (1000 * (24))); /* LPT:LP */
1479
1480 return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul)(((clock) + ((pwm_freq_hz * mul) / 2)) / (pwm_freq_hz * mul));
1481}
1482
1483/*
1484 * ILK/SNB/IVB: This value represents the period of the PWM stream in PCH
1485 * display raw clocks multiplied by 128.
1486 */
1487static u32 pch_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1488{
1489 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1490
1491 return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(dev_priv)->rawclk_freq),((((1000 * ((&(dev_priv)->__runtime)->rawclk_freq))
) + ((pwm_freq_hz * 128) / 2)) / (pwm_freq_hz * 128))
1492 pwm_freq_hz * 128)((((1000 * ((&(dev_priv)->__runtime)->rawclk_freq))
) + ((pwm_freq_hz * 128) / 2)) / (pwm_freq_hz * 128))
;
1493}
1494
1495/*
1496 * Gen2: This field determines the number of time base events (display core
1497 * clock frequency/32) in total for a complete cycle of modulated backlight
1498 * control.
1499 *
1500 * Gen3: A time base event equals the display core clock ([DevPNV] HRAW clock)
1501 * divided by 32.
1502 */
1503static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1504{
1505 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1506 int clock;
1507
1508 if (IS_PINEVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_PINEVIEW))
1509 clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq)(1000 * ((&(dev_priv)->__runtime)->rawclk_freq));
1510 else
1511 clock = KHz(dev_priv->cdclk.hw.cdclk)(1000 * (dev_priv->cdclk.hw.cdclk));
1512
1513 return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32)(((clock) + ((pwm_freq_hz * 32) / 2)) / (pwm_freq_hz * 32));
1514}
1515
1516/*
1517 * Gen4: This value represents the period of the PWM stream in display core
1518 * clocks ([DevCTG] HRAW clocks) multiplied by 128.
1519 *
1520 */
1521static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1522{
1523 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1524 int clock;
1525
1526 if (IS_G4X(dev_priv)(IS_PLATFORM(dev_priv, INTEL_G45) || IS_PLATFORM(dev_priv, INTEL_GM45
))
)
1527 clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq)(1000 * ((&(dev_priv)->__runtime)->rawclk_freq));
1528 else
1529 clock = KHz(dev_priv->cdclk.hw.cdclk)(1000 * (dev_priv->cdclk.hw.cdclk));
1530
1531 return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128)(((clock) + ((pwm_freq_hz * 128) / 2)) / (pwm_freq_hz * 128));
1532}
1533
1534/*
1535 * VLV: This value represents the period of the PWM stream in display core
1536 * clocks ([DevCTG] 200MHz HRAW clocks) multiplied by 128 or 25MHz S0IX clocks
1537 * multiplied by 16. CHV uses a 19.2MHz S0IX clock.
1538 */
1539static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
1540{
1541 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1542 int mul, clock;
1543
1544 if ((intel_de_read(dev_priv, CBR1_VLV((const i915_reg_t){ .reg = (0x180000 + 0x70400) })) & CBR_PWM_CLOCK_MUX_SELECT(1 << 30)) == 0) {
1545 if (IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW))
1546 clock = KHz(19200)(1000 * (19200));
1547 else
1548 clock = MHz(25)(1000 * (1000 * (25)));
1549 mul = 16;
1550 } else {
1551 clock = KHz(RUNTIME_INFO(dev_priv)->rawclk_freq)(1000 * ((&(dev_priv)->__runtime)->rawclk_freq));
1552 mul = 128;
1553 }
1554
1555 return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul)(((clock) + ((pwm_freq_hz * mul) / 2)) / (pwm_freq_hz * mul));
1556}
1557
1558static u16 get_vbt_pwm_freq(struct drm_i915_privateinteldrm_softc *dev_priv)
1559{
1560 u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
1561
1562 if (pwm_freq_hz) {
1563 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "VBT defined backlight frequency %u Hz\n"
, pwm_freq_hz)
1564 "VBT defined backlight frequency %u Hz\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "VBT defined backlight frequency %u Hz\n"
, pwm_freq_hz)
1565 pwm_freq_hz)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "VBT defined backlight frequency %u Hz\n"
, pwm_freq_hz)
;
1566 } else {
1567 pwm_freq_hz = 200;
1568 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "default backlight frequency %u Hz\n"
, pwm_freq_hz)
1569 "default backlight frequency %u Hz\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "default backlight frequency %u Hz\n"
, pwm_freq_hz)
1570 pwm_freq_hz)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "default backlight frequency %u Hz\n"
, pwm_freq_hz)
;
1571 }
1572
1573 return pwm_freq_hz;
1574}
1575
1576static u32 get_backlight_max_vbt(struct intel_connector *connector)
1577{
1578 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1579 struct intel_panel *panel = &connector->panel;
1580 u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv);
1581 u32 pwm;
1582
1583 if (!panel->backlight.hz_to_pwm) {
1584 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "backlight frequency conversion not supported\n"
)
1585 "backlight frequency conversion not supported\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "backlight frequency conversion not supported\n"
)
;
1586 return 0;
1587 }
1588
1589 pwm = panel->backlight.hz_to_pwm(connector, pwm_freq_hz);
1590 if (!pwm) {
1591 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "backlight frequency conversion failed\n"
)
1592 "backlight frequency conversion failed\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "backlight frequency conversion failed\n"
)
;
1593 return 0;
1594 }
1595
1596 return pwm;
1597}
1598
1599/*
1600 * Note: The setup hooks can't assume pipe is set!
1601 */
1602static u32 get_backlight_min_vbt(struct intel_connector *connector)
1603{
1604 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1605 struct intel_panel *panel = &connector->panel;
1606 int min;
1607
1608 drm_WARN_ON(&dev_priv->drm, panel->backlight.max == 0)({ int __ret = !!((panel->backlight.max == 0)); if (__ret)
printf("%s %s: " "%s", dev_driver_string(((&dev_priv->
drm))->dev), "", "drm_WARN_ON(" "panel->backlight.max == 0"
")"); __builtin_expect(!!(__ret), 0); })
;
1609
1610 /*
1611 * XXX: If the vbt value is 255, it makes min equal to max, which leads
1612 * to problems. There are such machines out there. Either our
1613 * interpretation is wrong or the vbt has bogus data. Or both. Safeguard
1614 * against this by letting the minimum be at most (arbitrarily chosen)
1615 * 25% of the max.
1616 */
1617 min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64)({ int __min_a = (({ int __max_a = (dev_priv->vbt.backlight
.min_brightness); int __max_b = (0); __max_a > __max_b ? __max_a
: __max_b; })); int __min_b = (64); __min_a < __min_b ? __min_a
: __min_b; })
;
1618 if (min != dev_priv->vbt.backlight.min_brightness) {
1619 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "clamping VBT min backlight %d/255 to %d/255\n"
, dev_priv->vbt.backlight.min_brightness, min)
1620 "clamping VBT min backlight %d/255 to %d/255\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "clamping VBT min backlight %d/255 to %d/255\n"
, dev_priv->vbt.backlight.min_brightness, min)
1621 dev_priv->vbt.backlight.min_brightness, min)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "clamping VBT min backlight %d/255 to %d/255\n"
, dev_priv->vbt.backlight.min_brightness, min)
;
1622 }
1623
1624 /* vbt value is a coefficient in range [0..255] */
1625 return scale(min, 0, 255, 0, panel->backlight.max);
1626}
1627
1628static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused)
1629{
1630 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1631 struct intel_panel *panel = &connector->panel;
1632 u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
1633 bool_Bool alt, cpu_mode;
1634
1635 if (HAS_PCH_LPT(dev_priv)(((dev_priv)->pch_type) == PCH_LPT))
1636 alt = intel_de_read(dev_priv, SOUTH_CHICKEN2((const i915_reg_t){ .reg = (0xc2004) })) & LPT_PWM_GRANULARITY(1 << 5);
1637 else
1638 alt = intel_de_read(dev_priv, SOUTH_CHICKEN1((const i915_reg_t){ .reg = (0xc2000) })) & SPT_PWM_GRANULARITY(1 << 0);
1639 panel->backlight.alternate_pwm_increment = alt;
1640
1641 pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }));
1642 panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY(1 << 29);
1643
1644 pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) }));
1645 panel->backlight.max = pch_ctl2 >> 16;
1646
1647 cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }));
1648
1649 if (!panel->backlight.max)
1650 panel->backlight.max = get_backlight_max_vbt(connector);
1651
1652 if (!panel->backlight.max)
1653 return -ENODEV19;
1654
1655 panel->backlight.min = get_backlight_min_vbt(connector);
1656
1657 panel->backlight.enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE(1 << 31);
1658
1659 cpu_mode = panel->backlight.enabled && HAS_PCH_LPT(dev_priv)(((dev_priv)->pch_type) == PCH_LPT) &&
1660 !(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE(1 << 30)) &&
1661 (cpu_ctl2 & BLM_PWM_ENABLE(1 << 31));
1662 if (cpu_mode)
1663 val = pch_get_backlight(connector);
1664 else
1665 val = lpt_get_backlight(connector);
1666
1667 if (cpu_mode) {
1668 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "CPU backlight register was enabled, switching to PCH override\n"
)
1669 "CPU backlight register was enabled, switching to PCH override\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "CPU backlight register was enabled, switching to PCH override\n"
)
;
1670
1671 /* Write converted CPU PWM value to PCH override register */
1672 lpt_set_backlight(connector->base.state, val);
1673 intel_de_write(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }),
1674 pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE(1 << 30));
1675
1676 intel_de_write(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }),
1677 cpu_ctl2 & ~BLM_PWM_ENABLE(1 << 31));
1678 }
1679
1680 val = intel_panel_compute_brightness(connector, val);
1681 panel->backlight.level = clamp(val, panel->backlight.min,({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
1682 panel->backlight.max)({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
;
1683
1684 return 0;
1685}
1686
1687static int pch_setup_backlight(struct intel_connector *connector, enum pipe unused)
1688{
1689 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1690 struct intel_panel *panel = &connector->panel;
1691 u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
1692
1693 pch_ctl1 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL1((const i915_reg_t){ .reg = (0xc8250) }));
1694 panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY(1 << 29);
1695
1696 pch_ctl2 = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2((const i915_reg_t){ .reg = (0xc8254) }));
1697 panel->backlight.max = pch_ctl2 >> 16;
1698
1699 if (!panel->backlight.max)
1700 panel->backlight.max = get_backlight_max_vbt(connector);
1701
1702 if (!panel->backlight.max)
1703 return -ENODEV19;
1704
1705 panel->backlight.min = get_backlight_min_vbt(connector);
1706
1707 val = pch_get_backlight(connector);
1708 val = intel_panel_compute_brightness(connector, val);
1709 panel->backlight.level = clamp(val, panel->backlight.min,({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
1710 panel->backlight.max)({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
;
1711
1712 cpu_ctl2 = intel_de_read(dev_priv, BLC_PWM_CPU_CTL2((const i915_reg_t){ .reg = (0x48250) }));
1713 panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE(1 << 31)) &&
1714 (pch_ctl1 & BLM_PCH_PWM_ENABLE(1 << 31));
1715
1716 return 0;
1717}
1718
1719static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unused)
1720{
1721 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1722 struct intel_panel *panel = &connector->panel;
1723 u32 ctl, val;
1724
1725 ctl = intel_de_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61254) })
);
1726
1727 if (IS_GEN(dev_priv, 2)(0 + (&(dev_priv)->__info)->gen == (2)) || IS_I915GM(dev_priv)IS_PLATFORM(dev_priv, INTEL_I915GM) || IS_I945GM(dev_priv)IS_PLATFORM(dev_priv, INTEL_I945GM))
1728 panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE(1 << 16);
1729
1730 if (IS_PINEVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_PINEVIEW))
1731 panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV(1 << 0);
1732
1733 panel->backlight.max = ctl >> 17;
1734
1735 if (!panel->backlight.max) {
1736 panel->backlight.max = get_backlight_max_vbt(connector);
1737 panel->backlight.max >>= 1;
1738 }
1739
1740 if (!panel->backlight.max)
1741 return -ENODEV19;
1742
1743 if (panel->backlight.combination_mode)
1744 panel->backlight.max *= 0xff;
1745
1746 panel->backlight.min = get_backlight_min_vbt(connector);
1747
1748 val = i9xx_get_backlight(connector);
1749 val = intel_panel_compute_brightness(connector, val);
1750 panel->backlight.level = clamp(val, panel->backlight.min,({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
1751 panel->backlight.max)({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
;
1752
1753 panel->backlight.enabled = val != 0;
1754
1755 return 0;
1756}
1757
1758static int i965_setup_backlight(struct intel_connector *connector, enum pipe unused)
1759{
1760 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1761 struct intel_panel *panel = &connector->panel;
1762 u32 ctl, ctl2, val;
1763
1764 ctl2 = intel_de_read(dev_priv, BLC_PWM_CTL2((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61250) })
);
1765 panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE(1 << 30);
1766 panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965(1 << 28);
1767
1768 ctl = intel_de_read(dev_priv, BLC_PWM_CTL((const i915_reg_t){ .reg = (((&(dev_priv)->__info)->
display_mmio_offset) + 0x61254) })
);
1769 panel->backlight.max = ctl >> 16;
1770
1771 if (!panel->backlight.max)
1772 panel->backlight.max = get_backlight_max_vbt(connector);
1773
1774 if (!panel->backlight.max)
1775 return -ENODEV19;
1776
1777 if (panel->backlight.combination_mode)
1778 panel->backlight.max *= 0xff;
1779
1780 panel->backlight.min = get_backlight_min_vbt(connector);
1781
1782 val = i9xx_get_backlight(connector);
1783 val = intel_panel_compute_brightness(connector, val);
1784 panel->backlight.level = clamp(val, panel->backlight.min,({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
1785 panel->backlight.max)({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
;
1786
1787 panel->backlight.enabled = ctl2 & BLM_PWM_ENABLE(1 << 31);
1788
1789 return 0;
1790}
1791
1792static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe)
1793{
1794 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1795 struct intel_panel *panel = &connector->panel;
1796 u32 ctl, ctl2, val;
1797
1798 if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B)({ int __ret = !!((pipe != PIPE_A && pipe != PIPE_B))
; if (__ret) printf("%s %s: " "%s", dev_driver_string(((&
dev_priv->drm))->dev), "", "drm_WARN_ON(" "pipe != PIPE_A && pipe != PIPE_B"
")"); __builtin_expect(!!(__ret), 0); })
)
1799 return -ENODEV19;
1800
1801 ctl2 = intel_de_read(dev_priv, VLV_BLC_PWM_CTL2(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61250)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61350)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61250))))
) })
);
1802 panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965(1 << 28);
1803
1804 ctl = intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)((const i915_reg_t){ .reg = ((((((&(dev_priv)->__info)
->display_mmio_offset) + 0x61254)) + (pipe) * (((((&(dev_priv
)->__info)->display_mmio_offset) + 0x61354)) - ((((&
(dev_priv)->__info)->display_mmio_offset) + 0x61254))))
) })
);
1805 panel->backlight.max = ctl >> 16;
1806
1807 if (!panel->backlight.max)
1808 panel->backlight.max = get_backlight_max_vbt(connector);
1809
1810 if (!panel->backlight.max)
1811 return -ENODEV19;
1812
1813 panel->backlight.min = get_backlight_min_vbt(connector);
1814
1815 val = _vlv_get_backlight(dev_priv, pipe);
1816 val = intel_panel_compute_brightness(connector, val);
1817 panel->backlight.level = clamp(val, panel->backlight.min,({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
1818 panel->backlight.max)({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
;
1819
1820 panel->backlight.enabled = ctl2 & BLM_PWM_ENABLE(1 << 31);
1821
1822 return 0;
1823}
1824
1825static int
1826bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
1827{
1828 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1829 struct intel_panel *panel = &connector->panel;
1830 u32 pwm_ctl, val;
1831
1832 panel->backlight.controller = dev_priv->vbt.backlight.controller;
1833
1834 pwm_ctl = intel_de_read(dev_priv,
1835 BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
);
1836
1837 /* Controller 1 uses the utility pin. */
1838 if (panel->backlight.controller == 1) {
1839 val = intel_de_read(dev_priv, UTIL_PIN_CTL((const i915_reg_t){ .reg = (0x48400) }));
1840 panel->backlight.util_pin_active_low =
1841 val & UTIL_PIN_POLARITY(1 << 22);
1842 }
1843
1844 panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY(1 << 29);
1845 panel->backlight.max =
1846 intel_de_read(dev_priv,
1847 BXT_BLC_PWM_FREQ(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8254) + (panel->backlight
.controller) * ((0xC8354) - (0xC8254)))) })
);
1848
1849 if (!panel->backlight.max)
1850 panel->backlight.max = get_backlight_max_vbt(connector);
1851
1852 if (!panel->backlight.max)
1853 return -ENODEV19;
1854
1855 panel->backlight.min = get_backlight_min_vbt(connector);
1856
1857 val = bxt_get_backlight(connector);
1858 val = intel_panel_compute_brightness(connector, val);
1859 panel->backlight.level = clamp(val, panel->backlight.min,({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
1860 panel->backlight.max)({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
;
1861
1862 panel->backlight.enabled = pwm_ctl & BXT_BLC_PWM_ENABLE(1 << 31);
1863
1864 return 0;
1865}
1866
1867static int
1868cnp_setup_backlight(struct intel_connector *connector, enum pipe unused)
1869{
1870 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1871 struct intel_panel *panel = &connector->panel;
1872 u32 pwm_ctl, val;
1873
1874 /*
1875 * CNP has the BXT implementation of backlight, but with only one
1876 * controller. TODO: ICP has multiple controllers but we only use
1877 * controller 0 for now.
1878 */
1879 panel->backlight.controller = 0;
1880
1881 pwm_ctl = intel_de_read(dev_priv,
1882 BXT_BLC_PWM_CTL(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8250) + (panel->backlight
.controller) * ((0xC8350) - (0xC8250)))) })
);
1883
1884 panel->backlight.active_low_pwm = pwm_ctl & BXT_BLC_PWM_POLARITY(1 << 29);
1885 panel->backlight.max =
1886 intel_de_read(dev_priv,
1887 BXT_BLC_PWM_FREQ(panel->backlight.controller)((const i915_reg_t){ .reg = (((0xC8254) + (panel->backlight
.controller) * ((0xC8354) - (0xC8254)))) })
);
1888
1889 if (!panel->backlight.max)
1890 panel->backlight.max = get_backlight_max_vbt(connector);
1891
1892 if (!panel->backlight.max)
1893 return -ENODEV19;
1894
1895 panel->backlight.min = get_backlight_min_vbt(connector);
1896
1897 val = bxt_get_backlight(connector);
1898 val = intel_panel_compute_brightness(connector, val);
1899 panel->backlight.level = clamp(val, panel->backlight.min,({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
1900 panel->backlight.max)({ __typeof(val) __min_a = (({ __typeof(val) __max_a = (val);
__typeof(val) __max_b = (panel->backlight.min); __max_a >
__max_b ? __max_a : __max_b; })); __typeof(val) __min_b = (panel
->backlight.max); __min_a < __min_b ? __min_a : __min_b
; })
;
1901
1902 panel->backlight.enabled = pwm_ctl & BXT_BLC_PWM_ENABLE(1 << 31);
1903
1904 return 0;
1905}
1906
1907static int pwm_setup_backlight(struct intel_connector *connector,
1908 enum pipe pipe)
1909{
1910 struct drm_device *dev = connector->base.dev;
1911 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(dev);
1912 struct intel_panel *panel = &connector->panel;
1913 const char *desc;
1914 u32 level;
1915
1916 /* Get the right PWM chip for DSI backlight according to VBT */
1917 if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC0) {
1918 panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight");
1919 desc = "PMIC";
1920 } else {
1921 panel->backlight.pwm = pwm_get(dev->dev, "pwm_soc_backlight");
1922 desc = "SoC";
1923 }
1924
1925 if (IS_ERR(panel->backlight.pwm)) {
1926 drm_err(&dev_priv->drm, "Failed to get the %s PWM chip\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to get the %s PWM chip\n"
, ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc->p_p->ps_pid, __func__ , desc)
1927 desc)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to get the %s PWM chip\n"
, ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc->p_p->ps_pid, __func__ , desc)
;
1928 panel->backlight.pwm = NULL((void *)0);
1929 return -ENODEV19;
1930 }
1931
1932 panel->backlight.max = 100; /* 100% */
1933 panel->backlight.min = get_backlight_min_vbt(connector);
1934
1935#ifdef notyet
1936 if (pwm_is_enabled(panel->backlight.pwm)) {
1937 /* PWM is already enabled, use existing settings */
1938 pwm_get_state(panel->backlight.pwm, &panel->backlight.pwm_state);
1939
1940 level = pwm_get_relative_duty_cycle(&panel->backlight.pwm_state,
1941 100);
1942 level = intel_panel_compute_brightness(connector, level);
1943 panel->backlight.level = clamp(level, panel->backlight.min,({ __typeof(level) __min_a = (({ __typeof(level) __max_a = (level
); __typeof(level) __max_b = (panel->backlight.min); __max_a
> __max_b ? __max_a : __max_b; })); __typeof(level) __min_b
= (panel->backlight.max); __min_a < __min_b ? __min_a :
__min_b; })
1944 panel->backlight.max)({ __typeof(level) __min_a = (({ __typeof(level) __max_a = (level
); __typeof(level) __max_b = (panel->backlight.min); __max_a
> __max_b ? __max_a : __max_b; })); __typeof(level) __min_b
= (panel->backlight.max); __min_a < __min_b ? __min_a :
__min_b; })
;
1945 panel->backlight.enabled = true1;
1946
1947 drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "PWM already enabled at freq %ld, VBT freq %d, level %d\n"
, 1000000000L / (unsigned long)panel->backlight.pwm_state.
period, get_vbt_pwm_freq(dev_priv), level)
1948 NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "PWM already enabled at freq %ld, VBT freq %d, level %d\n"
, 1000000000L / (unsigned long)panel->backlight.pwm_state.
period, get_vbt_pwm_freq(dev_priv), level)
1949 get_vbt_pwm_freq(dev_priv), level)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "PWM already enabled at freq %ld, VBT freq %d, level %d\n"
, 1000000000L / (unsigned long)panel->backlight.pwm_state.
period, get_vbt_pwm_freq(dev_priv), level)
;
1950 } else {
1951 /* Set period from VBT frequency, leave other settings at 0. */
1952 panel->backlight.pwm_state.period =
1953 NSEC_PER_SEC1000000000L / get_vbt_pwm_freq(dev_priv);
1954 }
1955#else
1956 STUB()do { printf("%s: stub\n", __func__); } while(0);
1957#endif
1958
1959 drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n",do { } while(0)
1960 desc)do { } while(0);
1961 return 0;
1962}
1963
1964void intel_panel_update_backlight(struct intel_atomic_state *state,
1965 struct intel_encoder *encoder,
1966 const struct intel_crtc_state *crtc_state,
1967 const struct drm_connector_state *conn_state)
1968{
1969 struct intel_connector *connector = to_intel_connector(conn_state->connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (conn_state->connector); (struct intel_connector *
)( (char *)__mptr - __builtin_offsetof(struct intel_connector
, base) );})
;
1970 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
1971 struct intel_panel *panel = &connector->panel;
1972
1973 if (!panel->backlight.present)
1974 return;
1975
1976 mutex_lock(&dev_priv->backlight_lock)rw_enter_write(&dev_priv->backlight_lock);
1977 if (!panel->backlight.enabled)
1978 __intel_panel_enable_backlight(crtc_state, conn_state);
1979
1980 mutex_unlock(&dev_priv->backlight_lock)rw_exit_write(&dev_priv->backlight_lock);
1981}
1982
1983int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
1984{
1985 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->dev);
1986 struct intel_connector *intel_connector = to_intel_connector(connector)({ const __typeof( ((struct intel_connector *)0)->base ) *
__mptr = (connector); (struct intel_connector *)( (char *)__mptr
- __builtin_offsetof(struct intel_connector, base) );})
;
1987 struct intel_panel *panel = &intel_connector->panel;
1988 int ret;
1989
1990 if (!dev_priv->vbt.backlight.present) {
1991 if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT(1<<3)) {
1992 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "no backlight present per VBT, but present per quirk\n"
)
1993 "no backlight present per VBT, but present per quirk\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "no backlight present per VBT, but present per quirk\n"
)
;
1994 } else {
1995 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "no backlight present per VBT\n"
)
1996 "no backlight present per VBT\n")drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "no backlight present per VBT\n"
)
;
1997 return 0;
1998 }
1999 }
2000
2001 /* ensure intel_panel has been initialized first */
2002 if (drm_WARN_ON(&dev_priv->drm, !panel->backlight.setup)({ int __ret = !!((!panel->backlight.setup)); if (__ret) printf
("%s %s: " "%s", dev_driver_string(((&dev_priv->drm))->
dev), "", "drm_WARN_ON(" "!panel->backlight.setup" ")"); __builtin_expect
(!!(__ret), 0); })
)
2003 return -ENODEV19;
2004
2005 /* set level and max in panel struct */
2006 mutex_lock(&dev_priv->backlight_lock)rw_enter_write(&dev_priv->backlight_lock);
2007 ret = panel->backlight.setup(intel_connector, pipe);
2008 mutex_unlock(&dev_priv->backlight_lock)rw_exit_write(&dev_priv->backlight_lock);
2009
2010 if (ret) {
2011 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "failed to setup backlight for connector %s\n"
, connector->name)
2012 "failed to setup backlight for connector %s\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "failed to setup backlight for connector %s\n"
, connector->name)
2013 connector->name)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "failed to setup backlight for connector %s\n"
, connector->name)
;
2014 return ret;
2015 }
2016
2017 panel->backlight.present = true1;
2018
2019 drm_dbg_kms(&dev_priv->drm,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Connector %s backlight initialized, %s, brightness %u/%u\n"
, connector->name, enableddisabled(panel->backlight.enabled
), panel->backlight.level, panel->backlight.max)
2020 "Connector %s backlight initialized, %s, brightness %u/%u\n",drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Connector %s backlight initialized, %s, brightness %u/%u\n"
, connector->name, enableddisabled(panel->backlight.enabled
), panel->backlight.level, panel->backlight.max)
2021 connector->name,drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Connector %s backlight initialized, %s, brightness %u/%u\n"
, connector->name, enableddisabled(panel->backlight.enabled
), panel->backlight.level, panel->backlight.max)
2022 enableddisabled(panel->backlight.enabled),drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Connector %s backlight initialized, %s, brightness %u/%u\n"
, connector->name, enableddisabled(panel->backlight.enabled
), panel->backlight.level, panel->backlight.max)
2023 panel->backlight.level, panel->backlight.max)drm_dev_dbg((&dev_priv->drm)->dev, DRM_UT_KMS, "Connector %s backlight initialized, %s, brightness %u/%u\n"
, connector->name, enableddisabled(panel->backlight.enabled
), panel->backlight.level, panel->backlight.max)
;
2024
2025 return 0;
2026}
2027
2028static void intel_panel_destroy_backlight(struct intel_panel *panel)
2029{
2030 /* dispose of the pwm */
2031 if (panel->backlight.pwm)
2032 pwm_put(panel->backlight.pwm);
2033
2034 panel->backlight.present = false0;
2035}
2036
2037/* Set up chip specific backlight functions */
2038static void
2039intel_panel_init_backlight_funcs(struct intel_panel *panel)
2040{
2041 struct intel_connector *connector =
2042 container_of(panel, struct intel_connector, panel)({ const __typeof( ((struct intel_connector *)0)->panel ) *
__mptr = (panel); (struct intel_connector *)( (char *)__mptr -
__builtin_offsetof(struct intel_connector, panel) );})
;
2043 struct drm_i915_privateinteldrm_softc *dev_priv = to_i915(connector->base.dev);
2044
2045 if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP14 &&
2046 intel_dp_aux_init_backlight_funcs(connector) == 0)
2047 return;
2048
2049 if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI16 &&
2050 intel_dsi_dcs_init_backlight_funcs(connector) == 0)
2051 return;
2052
2053 if (IS_GEN9_LP(dev_priv)((0 + (&(dev_priv)->__info)->gen == (9)) &&
((&(dev_priv)->__info)->is_lp))
) {
2054 panel->backlight.setup = bxt_setup_backlight;
2055 panel->backlight.enable = bxt_enable_backlight;
2056 panel->backlight.disable = bxt_disable_backlight;
2057 panel->backlight.set = bxt_set_backlight;
2058 panel->backlight.get = bxt_get_backlight;
2059 panel->backlight.hz_to_pwm = bxt_hz_to_pwm;
2060 } else if (INTEL_PCH_TYPE(dev_priv)((dev_priv)->pch_type) >= PCH_CNP) {
2061 panel->backlight.setup = cnp_setup_backlight;
2062 panel->backlight.enable = cnp_enable_backlight;
2063 panel->backlight.disable = cnp_disable_backlight;
2064 panel->backlight.set = bxt_set_backlight;
2065 panel->backlight.get = bxt_get_backlight;
2066 panel->backlight.hz_to_pwm = cnp_hz_to_pwm;
2067 } else if (INTEL_PCH_TYPE(dev_priv)((dev_priv)->pch_type) >= PCH_LPT) {
2068 panel->backlight.setup = lpt_setup_backlight;
2069 panel->backlight.enable = lpt_enable_backlight;
2070 panel->backlight.disable = lpt_disable_backlight;
2071 panel->backlight.set = lpt_set_backlight;
2072 panel->backlight.get = lpt_get_backlight;
2073 if (HAS_PCH_LPT(dev_priv)(((dev_priv)->pch_type) == PCH_LPT))
2074 panel->backlight.hz_to_pwm = lpt_hz_to_pwm;
2075 else
2076 panel->backlight.hz_to_pwm = spt_hz_to_pwm;
2077 } else if (HAS_PCH_SPLIT(dev_priv)(((dev_priv)->pch_type) != PCH_NONE)) {
2078 panel->backlight.setup = pch_setup_backlight;
2079 panel->backlight.enable = pch_enable_backlight;
2080 panel->backlight.disable = pch_disable_backlight;
2081 panel->backlight.set = pch_set_backlight;
2082 panel->backlight.get = pch_get_backlight;
2083 panel->backlight.hz_to_pwm = pch_hz_to_pwm;
2084 } else if (IS_VALLEYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_VALLEYVIEW) || IS_CHERRYVIEW(dev_priv)IS_PLATFORM(dev_priv, INTEL_CHERRYVIEW)) {
2085 if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI16) {
2086 panel->backlight.setup = pwm_setup_backlight;
2087 panel->backlight.enable = pwm_enable_backlight;
2088 panel->backlight.disable = pwm_disable_backlight;
2089 panel->backlight.set = pwm_set_backlight;
2090 panel->backlight.get = pwm_get_backlight;
2091 } else {
2092 panel->backlight.setup = vlv_setup_backlight;
2093 panel->backlight.enable = vlv_enable_backlight;
2094 panel->backlight.disable = vlv_disable_backlight;
2095 panel->backlight.set = vlv_set_backlight;
2096 panel->backlight.get = vlv_get_backlight;
2097 panel->backlight.hz_to_pwm = vlv_hz_to_pwm;
2098 }
2099 } else if (IS_GEN(dev_priv, 4)(0 + (&(dev_priv)->__info)->gen == (4))) {
2100 panel->backlight.setup = i965_setup_backlight;
2101 panel->backlight.enable = i965_enable_backlight;
2102 panel->backlight.disable = i965_disable_backlight;
2103 panel->backlight.set = i9xx_set_backlight;
2104 panel->backlight.get = i9xx_get_backlight;
2105 panel->backlight.hz_to_pwm = i965_hz_to_pwm;
2106 } else {
2107 panel->backlight.setup = i9xx_setup_backlight;
2108 panel->backlight.enable = i9xx_enable_backlight;
2109 panel->backlight.disable = i9xx_disable_backlight;
2110 panel->backlight.set = i9xx_set_backlight;
2111 panel->backlight.get = i9xx_get_backlight;
2112 panel->backlight.hz_to_pwm = i9xx_hz_to_pwm;
2113 }
2114}
2115
2116enum drm_connector_status
2117intel_panel_detect(struct drm_connector *connector, bool_Bool force)
2118{
2119 struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->dev);
2120
2121 if (!INTEL_DISPLAY_ENABLED(i915)(({ int __ret = !!((!((&(i915)->__info)->pipe_mask !=
0))); if (__ret) printf("%s %s: " "%s", dev_driver_string(((
&(i915)->drm))->dev), "", "drm_WARN_ON(" "!((&(i915)->__info)->pipe_mask != 0)"
")"); __builtin_expect(!!(__ret), 0); }), !(i915)->params
.disable_display)
)
2122 return connector_status_disconnected;
2123
2124 return connector_status_connected;
2125}
2126
2127int intel_panel_init(struct intel_panel *panel,
2128 struct drm_display_mode *fixed_mode,
2129 struct drm_display_mode *downclock_mode)
2130{
2131 intel_panel_init_backlight_funcs(panel);
2132
2133 panel->fixed_mode = fixed_mode;
2134 panel->downclock_mode = downclock_mode;
2135
2136 return 0;
2137}
2138
2139void intel_panel_fini(struct intel_panel *panel)
2140{
2141 struct intel_connector *intel_connector =
2142 container_of(panel, struct intel_connector, panel)({ const __typeof( ((struct intel_connector *)0)->panel ) *
__mptr = (panel); (struct intel_connector *)( (char *)__mptr -
__builtin_offsetof(struct intel_connector, panel) );})
;
2143
2144 intel_panel_destroy_backlight(panel);
2145
2146 if (panel->fixed_mode)
2147 drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
2148
2149 if (panel->downclock_mode)
2150 drm_mode_destroy(intel_connector->base.dev,
2151 panel->downclock_mode);
2152}