Bug Summary

File:dev/pci/drm/i915/display/intel_dp_aux_backlight.c
Warning:line 200, column 21
Value stored to 'dev' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name intel_dp_aux_backlight.c -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 -ffp-contract=on -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 -target-feature +retpoline-external-thunk -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/llvm16/lib/clang/16 -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/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -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/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -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/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -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 SUSPEND -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 -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 -fcf-protection=branch -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 /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/pci/drm/i915/display/intel_dp_aux_backlight.c
1/*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25/*
26 * Laptops with Intel GPUs which have panels that support controlling the
27 * backlight through DP AUX can actually use two different interfaces: Intel's
28 * proprietary DP AUX backlight interface, and the standard VESA backlight
29 * interface. Unfortunately, at the time of writing this a lot of laptops will
30 * advertise support for the standard VESA backlight interface when they
31 * don't properly support it. However, on these systems the Intel backlight
32 * interface generally does work properly. Additionally, these systems will
33 * usually just indicate that they use PWM backlight controls in their VBIOS
34 * for some reason.
35 */
36
37#include <linux/kconfig.h>
38#include "i915_drv.h"
39#include "intel_backlight.h"
40#include "intel_display_types.h"
41#include "intel_dp.h"
42#include "intel_dp_aux_backlight.h"
43
44/* TODO:
45 * Implement HDR, right now we just implement the bare minimum to bring us back into SDR mode so we
46 * can make people's backlights work in the mean time
47 */
48
49/*
50 * DP AUX registers for Intel's proprietary HDR backlight interface. We define
51 * them here since we'll likely be the only driver to ever use these.
52 */
53#define INTEL_EDP_HDR_TCON_CAP00x340 0x340
54
55#define INTEL_EDP_HDR_TCON_CAP10x341 0x341
56# define INTEL_EDP_HDR_TCON_2084_DECODE_CAP(1UL << (0)) BIT(0)(1UL << (0))
57# define INTEL_EDP_HDR_TCON_2020_GAMUT_CAP(1UL << (1)) BIT(1)(1UL << (1))
58# define INTEL_EDP_HDR_TCON_TONE_MAPPING_CAP(1UL << (2)) BIT(2)(1UL << (2))
59# define INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_CAP(1UL << (3)) BIT(3)(1UL << (3))
60# define INTEL_EDP_HDR_TCON_BRIGHTNESS_NITS_CAP(1UL << (4)) BIT(4)(1UL << (4))
61# define INTEL_EDP_HDR_TCON_OPTIMIZATION_CAP(1UL << (5)) BIT(5)(1UL << (5))
62# define INTEL_EDP_HDR_TCON_SDP_COLORIMETRY_CAP(1UL << (6)) BIT(6)(1UL << (6))
63# define INTEL_EDP_HDR_TCON_SRGB_TO_PANEL_GAMUT_CONVERSION_CAP(1UL << (7)) BIT(7)(1UL << (7))
64
65#define INTEL_EDP_HDR_TCON_CAP20x342 0x342
66# define INTEL_EDP_SDR_TCON_BRIGHTNESS_AUX_CAP(1UL << (0)) BIT(0)(1UL << (0))
67
68#define INTEL_EDP_HDR_TCON_CAP30x343 0x343
69
70#define INTEL_EDP_HDR_GETSET_CTRL_PARAMS0x344 0x344
71# define INTEL_EDP_HDR_TCON_2084_DECODE_ENABLE(1UL << (0)) BIT(0)(1UL << (0))
72# define INTEL_EDP_HDR_TCON_2020_GAMUT_ENABLE(1UL << (1)) BIT(1)(1UL << (1))
73# define INTEL_EDP_HDR_TCON_TONE_MAPPING_ENABLE(1UL << (2)) BIT(2)(1UL << (2)) /* Pre-TGL+ */
74# define INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_ENABLE(1UL << (3)) BIT(3)(1UL << (3))
75# define INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE(1UL << (4)) BIT(4)(1UL << (4))
76# define INTEL_EDP_HDR_TCON_SRGB_TO_PANEL_GAMUT_ENABLE(1UL << (5)) BIT(5)(1UL << (5))
77/* Bit 6 is reserved */
78# define INTEL_EDP_HDR_TCON_SDP_COLORIMETRY_ENABLE(1UL << (7)) BIT(7)(1UL << (7))
79
80#define INTEL_EDP_HDR_CONTENT_LUMINANCE0x346 0x346 /* Pre-TGL+ */
81#define INTEL_EDP_HDR_PANEL_LUMINANCE_OVERRIDE0x34A 0x34A
82#define INTEL_EDP_SDR_LUMINANCE_LEVEL0x352 0x352
83#define INTEL_EDP_BRIGHTNESS_NITS_LSB0x354 0x354
84#define INTEL_EDP_BRIGHTNESS_NITS_MSB0x355 0x355
85#define INTEL_EDP_BRIGHTNESS_DELAY_FRAMES0x356 0x356
86#define INTEL_EDP_BRIGHTNESS_PER_FRAME_STEPS0x357 0x357
87
88#define INTEL_EDP_BRIGHTNESS_OPTIMIZATION_00x358 0x358
89# define INTEL_EDP_TCON_USAGE_MASK(((~0UL) >> (64 - (0) - 1)) & ((~0UL) << (3))
)
GENMASK(0, 3)(((~0UL) >> (64 - (0) - 1)) & ((~0UL) << (3))
)
90# define INTEL_EDP_TCON_USAGE_UNKNOWN0x0 0x0
91# define INTEL_EDP_TCON_USAGE_DESKTOP0x1 0x1
92# define INTEL_EDP_TCON_USAGE_FULL_SCREEN_MEDIA0x2 0x2
93# define INTEL_EDP_TCON_USAGE_FULL_SCREEN_GAMING0x3 0x3
94# define INTEL_EDP_TCON_POWER_MASK(1UL << (4)) BIT(4)(1UL << (4))
95# define INTEL_EDP_TCON_POWER_DC(0 << 4) (0 << 4)
96# define INTEL_EDP_TCON_POWER_AC(1 << 4) (1 << 4)
97# define INTEL_EDP_TCON_OPTIMIZATION_STRENGTH_MASK(((~0UL) >> (64 - (5) - 1)) & ((~0UL) << (7))
)
GENMASK(5, 7)(((~0UL) >> (64 - (5) - 1)) & ((~0UL) << (7))
)
98
99#define INTEL_EDP_BRIGHTNESS_OPTIMIZATION_10x359 0x359
100
101enum intel_dp_aux_backlight_modparam {
102 INTEL_DP_AUX_BACKLIGHT_AUTO = -1,
103 INTEL_DP_AUX_BACKLIGHT_OFF = 0,
104 INTEL_DP_AUX_BACKLIGHT_ON = 1,
105 INTEL_DP_AUX_BACKLIGHT_FORCE_VESA = 2,
106 INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL = 3,
107};
108
109/* Intel EDP backlight callbacks */
110static bool_Bool
111intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
112{
113 struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev);
114 struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
115 struct drm_dp_aux *aux = &intel_dp->aux;
116 struct intel_panel *panel = &connector->panel;
117 int ret;
118 u8 tcon_cap[4];
119
120 intel_dp_wait_source_oui(intel_dp);
121
122 ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP00x340, tcon_cap, sizeof(tcon_cap));
123 if (ret != sizeof(tcon_cap))
124 return false0;
125
126 if (!(tcon_cap[1] & INTEL_EDP_HDR_TCON_BRIGHTNESS_NITS_CAP(1UL << (4))))
127 return false0;
128
129 if (tcon_cap[0] >= 1) {
130 drm_dbg_kms(&i915->drm, "Detected Intel HDR backlight interface version %d\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915->
drm)->dev : ((void *)0), DRM_UT_KMS, "Detected Intel HDR backlight interface version %d\n"
, tcon_cap[0])
131 tcon_cap[0])__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915->
drm)->dev : ((void *)0), DRM_UT_KMS, "Detected Intel HDR backlight interface version %d\n"
, tcon_cap[0])
;
132 } else {
133 drm_dbg_kms(&i915->drm, "Detected unsupported HDR backlight interface version %d\n",__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915->
drm)->dev : ((void *)0), DRM_UT_KMS, "Detected unsupported HDR backlight interface version %d\n"
, tcon_cap[0])
134 tcon_cap[0])__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915->
drm)->dev : ((void *)0), DRM_UT_KMS, "Detected unsupported HDR backlight interface version %d\n"
, tcon_cap[0])
;
135 return false0;
136 }
137
138 /*
139 * If we don't have HDR static metadata there is no way to
140 * runtime detect used range for nits based control. For now
141 * do not use Intel proprietary eDP backlight control if we
142 * don't have this data in panel EDID. In case we find panel
143 * which supports only nits based control, but doesn't provide
144 * HDR static metadata we need to start maintaining table of
145 * ranges for such panels.
146 */
147 if (i915->params.enable_dpcd_backlight != INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL &&
148 !(connector->base.hdr_sink_metadata.hdmi_type1.metadata_type &
149 BIT(HDMI_STATIC_METADATA_TYPE1)(1UL << (HDMI_STATIC_METADATA_TYPE1)))) {
150 drm_info(&i915->drm,do { } while(0)
151 "Panel is missing HDR static metadata. Possible support for Intel HDR backlight interface is not used. If your backlight controls don't work try booting with i915.enable_dpcd_backlight=%d. needs this, please file a _new_ bug report on drm/i915, see " FDO_BUG_URL " for details.\n",do { } while(0)
152 INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL)do { } while(0);
153 return false0;
154 }
155
156 panel->backlight.edp.intel.sdr_uses_aux =
157 tcon_cap[2] & INTEL_EDP_SDR_TCON_BRIGHTNESS_AUX_CAP(1UL << (0));
158
159 return true1;
160}
161
162static u32
163intel_dp_aux_hdr_get_backlight(struct intel_connector *connector, enum pipe pipe)
164{
165 struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev);
166 struct intel_panel *panel = &connector->panel;
167 struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
168 u8 tmp;
169 u8 buf[2] = { 0 };
170
171 if (drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS0x344, &tmp) != 1) {
172 drm_err(&i915->drm, "Failed to read current backlight mode from DPCD\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read current backlight mode from DPCD\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__)
;
173 return 0;
174 }
175
176 if (!(tmp & INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE(1UL << (4)))) {
177 if (!panel->backlight.edp.intel.sdr_uses_aux) {
178 u32 pwm_level = panel->backlight.pwm_funcs->get(connector, pipe);
179
180 return intel_backlight_level_from_pwm(connector, pwm_level);
181 }
182
183 /* Assume 100% brightness if backlight controls aren't enabled yet */
184 return panel->backlight.max;
185 }
186
187 if (drm_dp_dpcd_read(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB0x354, buf,
188 sizeof(buf)) != sizeof(buf)) {
189 drm_err(&i915->drm, "Failed to read brightness from DPCD\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read brightness from DPCD\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__)
;
190 return 0;
191 }
192
193 return (buf[1] << 8 | buf[0]);
194}
195
196static void
197intel_dp_aux_hdr_set_aux_backlight(const struct drm_connector_state *conn_state, u32 level)
198{
199 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) );})
;
200 struct drm_device *dev = connector->base.dev;
Value stored to 'dev' during its initialization is never read
201 struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
202 u8 buf[4] = { 0 };
203
204 buf[0] = level & 0xFF;
205 buf[1] = (level & 0xFF00) >> 8;
206
207 if (drm_dp_dpcd_write(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB0x354, buf,
208 sizeof(buf)) != sizeof(buf))
209 drm_err(dev, "Failed to write brightness level to DPCD\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to write brightness level to DPCD\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__)
;
210}
211
212static void
213intel_dp_aux_hdr_set_backlight(const struct drm_connector_state *conn_state, u32 level)
214{
215 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) );})
;
216 struct intel_panel *panel = &connector->panel;
217
218 if (panel->backlight.edp.intel.sdr_uses_aux) {
219 intel_dp_aux_hdr_set_aux_backlight(conn_state, level);
220 } else {
221 const u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
222
223 intel_backlight_set_pwm_level(conn_state, pwm_level);
224 }
225}
226
227static void
228intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
229 const struct drm_connector_state *conn_state, u32 level)
230{
231 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) );})
;
232 struct intel_panel *panel = &connector->panel;
233 struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev);
234 struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
235 int ret;
236 u8 old_ctrl, ctrl;
237
238 intel_dp_wait_source_oui(intel_dp);
239
240 ret = drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS0x344, &old_ctrl);
241 if (ret != 1) {
242 drm_err(&i915->drm, "Failed to read current backlight control mode: %d\n", ret)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to read current backlight control mode: %d\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__ , ret)
;
243 return;
244 }
245
246 ctrl = old_ctrl;
247 if (panel->backlight.edp.intel.sdr_uses_aux) {
248 ctrl |= INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE(1UL << (4));
249 intel_dp_aux_hdr_set_aux_backlight(conn_state, level);
250 } else {
251 u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
252
253 panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level);
254
255 ctrl &= ~INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE(1UL << (4));
256 }
257
258 if (ctrl != old_ctrl)
259 if (drm_dp_dpcd_writeb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS0x344, ctrl) != 1)
260 drm_err(&i915->drm, "Failed to configure DPCD brightness controls\n")printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to configure DPCD brightness controls\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__)
;
261}
262
263static void
264intel_dp_aux_hdr_disable_backlight(const struct drm_connector_state *conn_state, u32 level)
265{
266 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) );})
;
267 struct intel_panel *panel = &connector->panel;
268
269 /* Nothing to do for AUX based backlight controls */
270 if (panel->backlight.edp.intel.sdr_uses_aux)
271 return;
272
273 /* Note we want the actual pwm_level to be 0, regardless of pwm_min */
274 panel->backlight.pwm_funcs->disable(conn_state, intel_backlight_invert_pwm_level(connector, 0));
275}
276
277static int
278intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector, enum pipe pipe)
279{
280 struct drm_i915_privateinteldrm_softc *i915 = to_i915(connector->base.dev);
281 struct intel_panel *panel = &connector->panel;
282 struct drm_luminance_range_info *luminance_range =
283 &connector->base.display_info.luminance_range;
284 int ret;
285
286 if (panel->backlight.edp.intel.sdr_uses_aux) {
287 drm_dbg_kms(&i915->drm, "SDR backlight is controlled through DPCD\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915->
drm)->dev : ((void *)0), DRM_UT_KMS, "SDR backlight is controlled through DPCD\n"
)
;
288 } else {
289 drm_dbg_kms(&i915->drm, "SDR backlight is controlled through PWM\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915->
drm)->dev : ((void *)0), DRM_UT_KMS, "SDR backlight is controlled through PWM\n"
)
;
290
291 ret = panel->backlight.pwm_funcs->setup(connector, pipe);
292 if (ret < 0) {
293 drm_err(&i915->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to setup SDR backlight controls through PWM: %d\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__ , ret)
294 "Failed to setup SDR backlight controls through PWM: %d\n", ret)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to setup SDR backlight controls through PWM: %d\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__ , ret)
;
295 return ret;
296 }
297 }
298
299 if (luminance_range->max_luminance) {
300 panel->backlight.max = luminance_range->max_luminance;
301 panel->backlight.min = luminance_range->min_luminance;
302 } else {
303 panel->backlight.max = 512;
304 panel->backlight.min = 0;
305 }
306
307 drm_dbg_kms(&i915->drm, "Using backlight range %d..%d\n", panel->backlight.min,__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915->
drm)->dev : ((void *)0), DRM_UT_KMS, "Using backlight range %d..%d\n"
, panel->backlight.min, panel->backlight.max)
308 panel->backlight.max)__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915->
drm)->dev : ((void *)0), DRM_UT_KMS, "Using backlight range %d..%d\n"
, panel->backlight.min, panel->backlight.max)
;
309
310 panel->backlight.level = intel_dp_aux_hdr_get_backlight(connector, pipe);
311 panel->backlight.enabled = panel->backlight.level != 0;
312
313 return 0;
314}
315
316/* VESA backlight callbacks */
317static u32 intel_dp_aux_vesa_get_backlight(struct intel_connector *connector, enum pipe unused)
318{
319 return connector->panel.backlight.level;
320}
321
322static void
323intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u32 level)
324{
325 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) );})
;
326 struct intel_panel *panel = &connector->panel;
327 struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
328
329 if (!panel->backlight.edp.vesa.info.aux_set) {
330 const u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
331
332 intel_backlight_set_pwm_level(conn_state, pwm_level);
333 }
334
335 drm_edp_backlight_set_level(&intel_dp->aux, &panel->backlight.edp.vesa.info, level);
336}
337
338static void
339intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state,
340 const struct drm_connector_state *conn_state, u32 level)
341{
342 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) );})
;
343 struct intel_panel *panel = &connector->panel;
344 struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
345
346 if (!panel->backlight.edp.vesa.info.aux_enable) {
347 u32 pwm_level;
348
349 if (!panel->backlight.edp.vesa.info.aux_set)
350 pwm_level = intel_backlight_level_to_pwm(connector, level);
351 else
352 pwm_level = intel_backlight_invert_pwm_level(connector,
353 panel->backlight.pwm_level_max);
354
355 panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level);
356 }
357
358 drm_edp_backlight_enable(&intel_dp->aux, &panel->backlight.edp.vesa.info, level);
359}
360
361static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state *old_conn_state,
362 u32 level)
363{
364 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) );})
;
365 struct intel_panel *panel = &connector->panel;
366 struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
367
368 drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info);
369
370 if (!panel->backlight.edp.vesa.info.aux_enable)
371 panel->backlight.pwm_funcs->disable(old_conn_state,
372 intel_backlight_invert_pwm_level(connector, 0));
373}
374
375static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, enum pipe pipe)
376{
377 struct intel_dp *intel_dp = intel_attached_dp(connector);
378 struct intel_panel *panel = &connector->panel;
379 struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
380 u16 current_level;
381 u8 current_mode;
382 int ret;
383
384 ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info,
385 panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd,
386 &current_level, &current_mode);
387 if (ret < 0)
388 return ret;
389
390 if (!panel->backlight.edp.vesa.info.aux_set || !panel->backlight.edp.vesa.info.aux_enable) {
391 ret = panel->backlight.pwm_funcs->setup(connector, pipe);
392 if (ret < 0) {
393 drm_err(&i915->drm,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to setup PWM backlight controls for eDP backlight: %d\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__ , ret)
394 "Failed to setup PWM backlight controls for eDP backlight: %d\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to setup PWM backlight controls for eDP backlight: %d\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__ , ret)
395 ret)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Failed to setup PWM backlight controls for eDP backlight: %d\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__ , ret)
;
396 return ret;
397 }
398 }
399
400 if (panel->backlight.edp.vesa.info.aux_set) {
401 panel->backlight.max = panel->backlight.edp.vesa.info.max;
402 panel->backlight.min = 0;
403 if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD(2 << 0)) {
404 panel->backlight.level = current_level;
405 panel->backlight.enabled = panel->backlight.level != 0;
406 } else {
407 panel->backlight.level = panel->backlight.max;
408 panel->backlight.enabled = false0;
409 }
410 } else {
411 panel->backlight.max = panel->backlight.pwm_level_max;
412 panel->backlight.min = panel->backlight.pwm_level_min;
413 if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_PWM(0 << 0)) {
414 panel->backlight.level = panel->backlight.pwm_funcs->get(connector, pipe);
415 panel->backlight.enabled = panel->backlight.pwm_enabled;
416 } else {
417 panel->backlight.level = panel->backlight.max;
418 panel->backlight.enabled = false0;
419 }
420 }
421
422 return 0;
423}
424
425static bool_Bool
426intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector)
427{
428 struct intel_dp *intel_dp = intel_attached_dp(connector);
429 struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
430
431 if (drm_edp_backlight_supported(intel_dp->edp_dpcd)) {
432 drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n")__drm_dev_dbg(((void *)0), (&i915->drm) ? (&i915->
drm)->dev : ((void *)0), DRM_UT_KMS, "AUX Backlight Control Supported!\n"
)
;
433 return true1;
434 }
435 return false0;
436}
437
438static const struct intel_panel_bl_funcs intel_dp_hdr_bl_funcs = {
439 .setup = intel_dp_aux_hdr_setup_backlight,
440 .enable = intel_dp_aux_hdr_enable_backlight,
441 .disable = intel_dp_aux_hdr_disable_backlight,
442 .set = intel_dp_aux_hdr_set_backlight,
443 .get = intel_dp_aux_hdr_get_backlight,
444};
445
446static const struct intel_panel_bl_funcs intel_dp_vesa_bl_funcs = {
447 .setup = intel_dp_aux_vesa_setup_backlight,
448 .enable = intel_dp_aux_vesa_enable_backlight,
449 .disable = intel_dp_aux_vesa_disable_backlight,
450 .set = intel_dp_aux_vesa_set_backlight,
451 .get = intel_dp_aux_vesa_get_backlight,
452};
453
454int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
455{
456 struct drm_device *dev = connector->base.dev;
457 struct intel_panel *panel = &connector->panel;
458 struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
459 struct drm_i915_privateinteldrm_softc *i915 = dp_to_i915(intel_dp)to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
460 bool_Bool try_intel_interface = false0, try_vesa_interface = false0;
461
462 /* Check the VBT and user's module parameters to figure out which
463 * interfaces to probe
464 */
465 switch (i915->params.enable_dpcd_backlight) {
466 case INTEL_DP_AUX_BACKLIGHT_OFF:
467 return -ENODEV19;
468 case INTEL_DP_AUX_BACKLIGHT_AUTO:
469 switch (panel->vbt.backlight.type) {
470 case INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE:
471 try_vesa_interface = true1;
472 break;
473 case INTEL_BACKLIGHT_DISPLAY_DDI:
474 try_intel_interface = true1;
475 break;
476 default:
477 return -ENODEV19;
478 }
479 break;
480 case INTEL_DP_AUX_BACKLIGHT_ON:
481 if (panel->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)
482 try_intel_interface = true1;
483
484 try_vesa_interface = true1;
485 break;
486 case INTEL_DP_AUX_BACKLIGHT_FORCE_VESA:
487 try_vesa_interface = true1;
488 break;
489 case INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL:
490 try_intel_interface = true1;
491 break;
492 }
493
494 /*
495 * Since Intel has their own backlight control interface, the majority of machines out there
496 * using DPCD backlight controls with Intel GPUs will be using this interface as opposed to
497 * the VESA interface. However, other GPUs (such as Nvidia's) will always use the VESA
498 * interface. This means that there's quite a number of panels out there that will advertise
499 * support for both interfaces, primarily systems with Intel/Nvidia hybrid GPU setups.
500 *
501 * There's a catch to this though: on many panels that advertise support for both
502 * interfaces, the VESA backlight interface will stop working once we've programmed the
503 * panel with Intel's OUI - which is also required for us to be able to detect Intel's
504 * backlight interface at all. This means that the only sensible way for us to detect both
505 * interfaces is to probe for Intel's first, and VESA's second.
506 */
507 if (try_intel_interface && intel_dp_aux_supports_hdr_backlight(connector)) {
508 drm_dbg_kms(dev, "Using Intel proprietary eDP backlight controls\n")__drm_dev_dbg(((void *)0), (dev) ? (dev)->dev : ((void *)0
), DRM_UT_KMS, "Using Intel proprietary eDP backlight controls\n"
)
;
509 panel->backlight.funcs = &intel_dp_hdr_bl_funcs;
510 return 0;
511 }
512
513 if (try_vesa_interface && intel_dp_aux_supports_vesa_backlight(connector)) {
514 drm_dbg_kms(dev, "Using VESA eDP backlight controls\n")__drm_dev_dbg(((void *)0), (dev) ? (dev)->dev : ((void *)0
), DRM_UT_KMS, "Using VESA eDP backlight controls\n")
;
515 panel->backlight.funcs = &intel_dp_vesa_bl_funcs;
516 return 0;
517 }
518
519 return -ENODEV19;
520}