Gentoo Archives: gentoo-commits

From: Mike Pagano <mpagano@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/linux-patches:5.15 commit in: /
Date: Mon, 29 Nov 2021 23:36:10
Message-Id: 1638228894.b75b7e6a336c28fa493be98a01eef5ce375e020b.mpagano@gentoo
1 commit: b75b7e6a336c28fa493be98a01eef5ce375e020b
2 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
3 AuthorDate: Mon Nov 29 23:34:54 2021 +0000
4 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
5 CommitDate: Mon Nov 29 23:34:54 2021 +0000
6 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=b75b7e6a
7
8 Add suprt for panels w. VESA backlights with PWM enable/disable
9
10 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
11
12 0000_README | 4 +
13 ...15-PWM-support-for-VESA-backlight-helpers.patch | 618 +++++++++++++++++++++
14 2 files changed, 622 insertions(+)
15
16 diff --git a/0000_README b/0000_README
17 index 68d0c0db..0923a646 100644
18 --- a/0000_README
19 +++ b/0000_README
20 @@ -75,6 +75,10 @@ Patch: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
21 From: https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@××××××××.org/raw
22 Desc: Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758
23
24 +Patch: 2800_drm-i915-PWM-support-for-VESA-backlight-helpers.patch
25 +From: https://patchwork.freedesktop.org/series/95127/
26 +Desc: drm/i915: Add support for panels with VESA backlights with PWM enable/disable
27 +
28 Patch: 2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
29 From: https://bugs.gentoo.org/710790
30 Desc: tmp513 requies REGMAP_I2C to build. Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino
31
32 diff --git a/2800_drm-i915-PWM-support-for-VESA-backlight-helpers.patch b/2800_drm-i915-PWM-support-for-VESA-backlight-helpers.patch
33 new file mode 100644
34 index 00000000..45969bce
35 --- /dev/null
36 +++ b/2800_drm-i915-PWM-support-for-VESA-backlight-helpers.patch
37 @@ -0,0 +1,618 @@
38 +From patchwork Fri Nov 5 18:33:38 2021
39 +Content-Type: text/plain; charset="utf-8"
40 +MIME-Version: 1.0
41 +Content-Transfer-Encoding: 8bit
42 +Subject: [v5,1/5] drm/i915: Add support for panels with VESA backlights with
43 + PWM enable/disable
44 +From: Lyude Paul <lyude@××××××.com>
45 +X-Patchwork-Id: 462369
46 +Message-Id: <20211105183342.130810-2-lyude@××××××.com>
47 +To: dri-devel@×××××××××××××××××.org, nouveau@×××××××××××××××××.org,
48 + intel-gfx@×××××××××××××××××.org
49 +Cc: David Airlie <airlied@×××××.ie>, open list <linux-kernel@×××××××××××.org>,
50 + stable@×××××××××××.org
51 +Date: Fri, 5 Nov 2021 14:33:38 -0400
52 +
53 +This simply adds proper support for panel backlights that can be controlled
54 +via VESA's backlight control protocol, but which also require that we
55 +enable and disable the backlight via PWM instead of via the DPCD interface.
56 +We also enable this by default, in order to fix some people's backlights
57 +that were broken by not having this enabled.
58 +
59 +For reference, backlights that require this and use VESA's backlight
60 +interface tend to be laptops with hybrid GPUs, but this very well may
61 +change in the future.
62 +
63 +v4:
64 +* Make sure that we call intel_backlight_level_to_pwm() in
65 + intel_dp_aux_vesa_enable_backlight() - vsyrjala
66 +
67 +Signed-off-by: Lyude Paul <lyude@××××××.com>
68 +Link: https://gitlab.freedesktop.org/drm/intel/-/issues/3680
69 +Fixes: fe7d52bccab6 ("drm/i915/dp: Don't use DPCD backlights that need PWM enable/disable")
70 +Reviewed-by: Ville Syrjälä <ville.syrjala@×××××××××××.com>
71 +Cc: <stable@×××××××××××.org> # v5.12+
72 +---
73 + .../drm/i915/display/intel_dp_aux_backlight.c | 27 ++++++++++++++-----
74 + 1 file changed, 21 insertions(+), 6 deletions(-)
75 +
76 +diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
77 +index 569d17b4d00f..f05b71c01b8e 100644
78 +--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
79 ++++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
80 +@@ -293,6 +293,13 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state,
81 + struct intel_panel *panel = &connector->panel;
82 + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
83 +
84 ++ if (!panel->backlight.edp.vesa.info.aux_enable) {
85 ++ u32 pwm_level = intel_backlight_invert_pwm_level(connector,
86 ++ panel->backlight.pwm_level_max);
87 ++
88 ++ panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level);
89 ++ }
90 ++
91 + drm_edp_backlight_enable(&intel_dp->aux, &panel->backlight.edp.vesa.info, level);
92 + }
93 +
94 +@@ -304,6 +311,10 @@ static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state
95 + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
96 +
97 + drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info);
98 ++
99 ++ if (!panel->backlight.edp.vesa.info.aux_enable)
100 ++ panel->backlight.pwm_funcs->disable(old_conn_state,
101 ++ intel_backlight_invert_pwm_level(connector, 0));
102 + }
103 +
104 + static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, enum pipe pipe)
105 +@@ -321,6 +332,15 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector,
106 + if (ret < 0)
107 + return ret;
108 +
109 ++ if (!panel->backlight.edp.vesa.info.aux_enable) {
110 ++ ret = panel->backlight.pwm_funcs->setup(connector, pipe);
111 ++ if (ret < 0) {
112 ++ drm_err(&i915->drm,
113 ++ "Failed to setup PWM backlight controls for eDP backlight: %d\n",
114 ++ ret);
115 ++ return ret;
116 ++ }
117 ++ }
118 + panel->backlight.max = panel->backlight.edp.vesa.info.max;
119 + panel->backlight.min = 0;
120 + if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
121 +@@ -340,12 +360,7 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector)
122 + struct intel_dp *intel_dp = intel_attached_dp(connector);
123 + struct drm_i915_private *i915 = dp_to_i915(intel_dp);
124 +
125 +- /* TODO: We currently only support AUX only backlight configurations, not backlights which
126 +- * require a mix of PWM and AUX controls to work. In the mean time, these machines typically
127 +- * work just fine using normal PWM controls anyway.
128 +- */
129 +- if ((intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) &&
130 +- drm_edp_backlight_supported(intel_dp->edp_dpcd)) {
131 ++ if (drm_edp_backlight_supported(intel_dp->edp_dpcd)) {
132 + drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n");
133 + return true;
134 + }
135 +
136 +From patchwork Fri Nov 5 18:33:39 2021
137 +Content-Type: text/plain; charset="utf-8"
138 +MIME-Version: 1.0
139 +Content-Transfer-Encoding: 7bit
140 +Subject: [v5,2/5] drm/nouveau/kms/nv50-: Explicitly check DPCD backlights for
141 + aux enable/brightness
142 +From: Lyude Paul <lyude@××××××.com>
143 +X-Patchwork-Id: 462371
144 +Message-Id: <20211105183342.130810-3-lyude@××××××.com>
145 +To: dri-devel@×××××××××××××××××.org, nouveau@×××××××××××××××××.org,
146 + intel-gfx@×××××××××××××××××.org
147 +Cc: David Airlie <airlied@×××××.ie>, Ben Skeggs <bskeggs@××××××.com>,
148 + Karol Herbst <kherbst@××××××.com>, open list <linux-kernel@×××××××××××.org>
149 +Date: Fri, 5 Nov 2021 14:33:39 -0400
150 +
151 +Since we don't support hybrid AUX/PWM backlights in nouveau right now,
152 +let's add some explicit checks so that we don't break nouveau once we
153 +enable support for these backlights in other drivers.
154 +
155 +Reviewed-by: Karol Herbst <kherbst@××××××.com>
156 +Signed-off-by: Lyude Paul <lyude@××××××.com>
157 +---
158 + drivers/gpu/drm/nouveau/nouveau_backlight.c | 5 ++++-
159 + 1 file changed, 4 insertions(+), 1 deletion(-)
160 +
161 +diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
162 +index 1cbd71abc80a..ae2f2abc8f5a 100644
163 +--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
164 ++++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
165 +@@ -308,7 +308,10 @@ nv50_backlight_init(struct nouveau_backlight *bl,
166 + if (ret < 0)
167 + return ret;
168 +
169 +- if (drm_edp_backlight_supported(edp_dpcd)) {
170 ++ /* TODO: Add support for hybrid PWM/DPCD panels */
171 ++ if (drm_edp_backlight_supported(edp_dpcd) &&
172 ++ (edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) &&
173 ++ (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP)) {
174 + NV_DEBUG(drm, "DPCD backlight controls supported on %s\n",
175 + nv_conn->base.name);
176 +
177 +
178 +From patchwork Fri Nov 5 18:33:40 2021
179 +Content-Type: text/plain; charset="utf-8"
180 +MIME-Version: 1.0
181 +Content-Transfer-Encoding: 7bit
182 +Subject: [v5,3/5] drm/dp: Don't read back backlight mode in
183 + drm_edp_backlight_enable()
184 +From: Lyude Paul <lyude@××××××.com>
185 +X-Patchwork-Id: 462376
186 +Message-Id: <20211105183342.130810-4-lyude@××××××.com>
187 +To: dri-devel@×××××××××××××××××.org, nouveau@×××××××××××××××××.org,
188 + intel-gfx@×××××××××××××××××.org
189 +Cc: Thomas Zimmermann <tzimmermann@××××.de>, David Airlie <airlied@×××××.ie>,
190 + open list <linux-kernel@×××××××××××.org>, Maxime Ripard <mripard@××××××.org>
191 +Date: Fri, 5 Nov 2021 14:33:40 -0400
192 +
193 +As it turns out, apparently some machines will actually leave additional
194 +backlight functionality like dynamic backlight control on before the OS
195 +loads. Currently we don't take care to disable unsupported features when
196 +writing back the backlight mode, which can lead to some rather strange
197 +looking behavior when adjusting the backlight.
198 +
199 +So, let's fix this by just not reading back the current backlight mode on
200 +initial enable. I don't think there should really be any downsides to this,
201 +and this will ensure we don't leave any unsupported functionality enabled.
202 +
203 +This should fix at least one (but not all) of the issues seen with DPCD
204 +backlight support on fi-bdw-samus
205 +
206 +v5:
207 +* Just avoid reading back DPCD register - Doug Anderson
208 +
209 +Signed-off-by: Lyude Paul <lyude@××××××.com>
210 +Fixes: 867cf9cd73c3 ("drm/dp: Extract i915's eDP backlight code into DRM helpers")
211 +Reviewed-by: Douglas Anderson <dianders@××××××××.org>
212 +---
213 + drivers/gpu/drm/drm_dp_helper.c | 40 ++++++++++-----------------------
214 + 1 file changed, 12 insertions(+), 28 deletions(-)
215 +
216 +diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
217 +index ada0a1ff262d..af2aad2f4725 100644
218 +--- a/drivers/gpu/drm/drm_dp_helper.c
219 ++++ b/drivers/gpu/drm/drm_dp_helper.c
220 +@@ -3363,27 +3363,13 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli
221 + const u16 level)
222 + {
223 + int ret;
224 +- u8 dpcd_buf, new_dpcd_buf;
225 ++ u8 dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
226 +
227 +- ret = drm_dp_dpcd_readb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, &dpcd_buf);
228 +- if (ret != 1) {
229 +- drm_dbg_kms(aux->drm_dev,
230 +- "%s: Failed to read backlight mode: %d\n", aux->name, ret);
231 +- return ret < 0 ? ret : -EIO;
232 +- }
233 +-
234 +- new_dpcd_buf = dpcd_buf;
235 +-
236 +- if ((dpcd_buf & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK) != DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
237 +- new_dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
238 +- new_dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
239 +-
240 +- if (bl->pwmgen_bit_count) {
241 +- ret = drm_dp_dpcd_writeb(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count);
242 +- if (ret != 1)
243 +- drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux pwmgen bit count: %d\n",
244 +- aux->name, ret);
245 +- }
246 ++ if (bl->pwmgen_bit_count) {
247 ++ ret = drm_dp_dpcd_writeb(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count);
248 ++ if (ret != 1)
249 ++ drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux pwmgen bit count: %d\n",
250 ++ aux->name, ret);
251 + }
252 +
253 + if (bl->pwm_freq_pre_divider) {
254 +@@ -3393,16 +3379,14 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli
255 + "%s: Failed to write aux backlight frequency: %d\n",
256 + aux->name, ret);
257 + else
258 +- new_dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE;
259 ++ dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE;
260 + }
261 +
262 +- if (new_dpcd_buf != dpcd_buf) {
263 +- ret = drm_dp_dpcd_writeb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, new_dpcd_buf);
264 +- if (ret != 1) {
265 +- drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux backlight mode: %d\n",
266 +- aux->name, ret);
267 +- return ret < 0 ? ret : -EIO;
268 +- }
269 ++ ret = drm_dp_dpcd_writeb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, dpcd_buf);
270 ++ if (ret != 1) {
271 ++ drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux backlight mode: %d\n",
272 ++ aux->name, ret);
273 ++ return ret < 0 ? ret : -EIO;
274 + }
275 +
276 + ret = drm_edp_backlight_set_level(aux, bl, level);
277 +
278 +From patchwork Fri Nov 5 18:33:41 2021
279 +Content-Type: text/plain; charset="utf-8"
280 +MIME-Version: 1.0
281 +Content-Transfer-Encoding: 7bit
282 +Subject: [v5,4/5] drm/dp,
283 + drm/i915: Add support for VESA backlights using PWM for brightness control
284 +From: Lyude Paul <lyude@××××××.com>
285 +X-Patchwork-Id: 462379
286 +Message-Id: <20211105183342.130810-5-lyude@××××××.com>
287 +To: dri-devel@×××××××××××××××××.org, nouveau@×××××××××××××××××.org,
288 + intel-gfx@×××××××××××××××××.org
289 +Cc: Rajeev Nandan <rajeevny@××××××××××.org>, David Airlie <airlied@×××××.ie>,
290 + Doug Anderson <dianders@××××××××.org>, Maxime Ripard <mripard@××××××.org>,
291 + open list <linux-kernel@×××××××××××.org>,
292 + Thomas Zimmermann <tzimmermann@××××.de>
293 +Date: Fri, 5 Nov 2021 14:33:41 -0400
294 +
295 +Now that we've added support to i915 for controlling panel backlights that
296 +need PWM to be enabled/disabled, let's finalize this and add support for
297 +controlling brightness levels via PWM as well. This should hopefully put us
298 +towards the path of supporting _ALL_ backlights via VESA's DPCD interface
299 +which would allow us to finally start trusting the DPCD again.
300 +
301 +Note however that we still don't enable using this by default on i915 when
302 +it's not needed, primarily because I haven't yet had a chance to confirm if
303 +it's safe to do this on the one machine in Intel's CI that had an issue
304 +with this: samus-fi-bdw. I have done basic testing of this on other
305 +machines though, by manually patching i915 to force it into PWM-only mode
306 +on some of my laptops.
307 +
308 +v2:
309 +* Correct documentation (thanks Doug!)
310 +* Get rid of backlight caps
311 +
312 +Signed-off-by: Lyude Paul <lyude@××××××.com>
313 +Reviewed-by: Doug Anderson <dianders@××××××××.org>
314 +Cc: Rajeev Nandan <rajeevny@××××××××××.org>
315 +Cc: Satadru Pramanik <satadru@×××××.com>
316 +---
317 + drivers/gpu/drm/drm_dp_helper.c | 72 +++++++++++++------
318 + .../drm/i915/display/intel_dp_aux_backlight.c | 44 +++++++++---
319 + include/drm/drm_dp_helper.h | 7 +-
320 + 3 files changed, 89 insertions(+), 34 deletions(-)
321 +
322 +diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
323 +index af2aad2f4725..23f9073bc473 100644
324 +--- a/drivers/gpu/drm/drm_dp_helper.c
325 ++++ b/drivers/gpu/drm/drm_dp_helper.c
326 +@@ -3290,6 +3290,10 @@ int drm_edp_backlight_set_level(struct drm_dp_aux *aux, const struct drm_edp_bac
327 + int ret;
328 + u8 buf[2] = { 0 };
329 +
330 ++ /* The panel uses the PWM for controlling brightness levels */
331 ++ if (!bl->aux_set)
332 ++ return 0;
333 ++
334 + if (bl->lsb_reg_used) {
335 + buf[0] = (level & 0xff00) >> 8;
336 + buf[1] = (level & 0x00ff);
337 +@@ -3316,7 +3320,7 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, const struct drm_edp_backli
338 + int ret;
339 + u8 buf;
340 +
341 +- /* The panel uses something other then DPCD for enabling its backlight */
342 ++ /* This panel uses the EDP_BL_PWR GPIO for enablement */
343 + if (!bl->aux_enable)
344 + return 0;
345 +
346 +@@ -3351,11 +3355,11 @@ drm_edp_backlight_set_enable(struct drm_dp_aux *aux, const struct drm_edp_backli
347 + * restoring any important backlight state such as the given backlight level, the brightness byte
348 + * count, backlight frequency, etc.
349 + *
350 +- * Note that certain panels, while supporting brightness level controls over DPCD, may not support
351 +- * having their backlights enabled via the standard %DP_EDP_DISPLAY_CONTROL_REGISTER. On such panels
352 +- * &drm_edp_backlight_info.aux_enable will be set to %false, this function will skip the step of
353 +- * programming the %DP_EDP_DISPLAY_CONTROL_REGISTER, and the driver must perform the required
354 +- * implementation specific step for enabling the backlight after calling this function.
355 ++ * Note that certain panels do not support being enabled or disabled via DPCD, but instead require
356 ++ * that the driver handle enabling/disabling the panel through implementation-specific means using
357 ++ * the EDP_BL_PWR GPIO. For such panels, &drm_edp_backlight_info.aux_enable will be set to %false,
358 ++ * this function becomes a no-op, and the driver is expected to handle powering the panel on using
359 ++ * the EDP_BL_PWR GPIO.
360 + *
361 + * Returns: %0 on success, negative error code on failure.
362 + */
363 +@@ -3363,7 +3367,12 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli
364 + const u16 level)
365 + {
366 + int ret;
367 +- u8 dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
368 ++ u8 dpcd_buf;
369 ++
370 ++ if (bl->aux_set)
371 ++ dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
372 ++ else
373 ++ dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_PWM;
374 +
375 + if (bl->pwmgen_bit_count) {
376 + ret = drm_dp_dpcd_writeb(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count);
377 +@@ -3405,12 +3414,13 @@ EXPORT_SYMBOL(drm_edp_backlight_enable);
378 + * @aux: The DP AUX channel to use
379 + * @bl: Backlight capability info from drm_edp_backlight_init()
380 + *
381 +- * This function handles disabling DPCD backlight controls on a panel over AUX. Note that some
382 +- * panels have backlights that are enabled/disabled by other means, despite having their brightness
383 +- * values controlled through DPCD. On such panels &drm_edp_backlight_info.aux_enable will be set to
384 +- * %false, this function will become a no-op (and we will skip updating
385 +- * %DP_EDP_DISPLAY_CONTROL_REGISTER), and the driver must take care to perform it's own
386 +- * implementation specific step for disabling the backlight.
387 ++ * This function handles disabling DPCD backlight controls on a panel over AUX.
388 ++ *
389 ++ * Note that certain panels do not support being enabled or disabled via DPCD, but instead require
390 ++ * that the driver handle enabling/disabling the panel through implementation-specific means using
391 ++ * the EDP_BL_PWR GPIO. For such panels, &drm_edp_backlight_info.aux_enable will be set to %false,
392 ++ * this function becomes a no-op, and the driver is expected to handle powering the panel off using
393 ++ * the EDP_BL_PWR GPIO.
394 + *
395 + * Returns: %0 on success or no-op, negative error code on failure.
396 + */
397 +@@ -3434,6 +3444,9 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf
398 + int ret;
399 + u8 pn, pn_min, pn_max;
400 +
401 ++ if (!bl->aux_set)
402 ++ return 0;
403 ++
404 + ret = drm_dp_dpcd_readb(aux, DP_EDP_PWMGEN_BIT_COUNT, &pn);
405 + if (ret != 1) {
406 + drm_dbg_kms(aux->drm_dev, "%s: Failed to read pwmgen bit count cap: %d\n",
407 +@@ -3519,7 +3532,7 @@ drm_edp_backlight_probe_max(struct drm_dp_aux *aux, struct drm_edp_backlight_inf
408 + }
409 +
410 + static inline int
411 +-drm_edp_backlight_probe_level(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl,
412 ++drm_edp_backlight_probe_state(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl,
413 + u8 *current_mode)
414 + {
415 + int ret;
416 +@@ -3534,6 +3547,9 @@ drm_edp_backlight_probe_level(struct drm_dp_aux *aux, struct drm_edp_backlight_i
417 + }
418 +
419 + *current_mode = (mode_reg & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK);
420 ++ if (!bl->aux_set)
421 ++ return 0;
422 ++
423 + if (*current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
424 + int size = 1 + bl->lsb_reg_used;
425 +
426 +@@ -3564,7 +3580,7 @@ drm_edp_backlight_probe_level(struct drm_dp_aux *aux, struct drm_edp_backlight_i
427 + * @bl: The &drm_edp_backlight_info struct to fill out with information on the backlight
428 + * @driver_pwm_freq_hz: Optional PWM frequency from the driver in hz
429 + * @edp_dpcd: A cached copy of the eDP DPCD
430 +- * @current_level: Where to store the probed brightness level
431 ++ * @current_level: Where to store the probed brightness level, if any
432 + * @current_mode: Where to store the currently set backlight control mode
433 + *
434 + * Initializes a &drm_edp_backlight_info struct by probing @aux for it's backlight capabilities,
435 +@@ -3584,24 +3600,38 @@ drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl
436 +
437 + if (edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP)
438 + bl->aux_enable = true;
439 ++ if (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP)
440 ++ bl->aux_set = true;
441 + if (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT)
442 + bl->lsb_reg_used = true;
443 +
444 ++ /* Sanity check caps */
445 ++ if (!bl->aux_set && !(edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_PWM_PIN_CAP)) {
446 ++ drm_dbg_kms(aux->drm_dev,
447 ++ "%s: Panel supports neither AUX or PWM brightness control? Aborting\n",
448 ++ aux->name);
449 ++ return -EINVAL;
450 ++ }
451 ++
452 + ret = drm_edp_backlight_probe_max(aux, bl, driver_pwm_freq_hz, edp_dpcd);
453 + if (ret < 0)
454 + return ret;
455 +
456 +- ret = drm_edp_backlight_probe_level(aux, bl, current_mode);
457 ++ ret = drm_edp_backlight_probe_state(aux, bl, current_mode);
458 + if (ret < 0)
459 + return ret;
460 + *current_level = ret;
461 +
462 + drm_dbg_kms(aux->drm_dev,
463 +- "%s: Found backlight level=%d/%d pwm_freq_pre_divider=%d mode=%x\n",
464 +- aux->name, *current_level, bl->max, bl->pwm_freq_pre_divider, *current_mode);
465 +- drm_dbg_kms(aux->drm_dev,
466 +- "%s: Backlight caps: pwmgen_bit_count=%d lsb_reg_used=%d aux_enable=%d\n",
467 +- aux->name, bl->pwmgen_bit_count, bl->lsb_reg_used, bl->aux_enable);
468 ++ "%s: Found backlight: aux_set=%d aux_enable=%d mode=%d\n",
469 ++ aux->name, bl->aux_set, bl->aux_enable, *current_mode);
470 ++ if (bl->aux_set) {
471 ++ drm_dbg_kms(aux->drm_dev,
472 ++ "%s: Backlight caps: level=%d/%d pwm_freq_pre_divider=%d lsb_reg_used=%d\n",
473 ++ aux->name, *current_level, bl->max, bl->pwm_freq_pre_divider,
474 ++ bl->lsb_reg_used);
475 ++ }
476 ++
477 + return 0;
478 + }
479 + EXPORT_SYMBOL(drm_edp_backlight_init);
480 +diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
481 +index f05b71c01b8e..96fe3eaba44a 100644
482 +--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
483 ++++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
484 +@@ -282,6 +282,12 @@ intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u3
485 + struct intel_panel *panel = &connector->panel;
486 + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
487 +
488 ++ if (!panel->backlight.edp.vesa.info.aux_set) {
489 ++ const u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
490 ++
491 ++ intel_backlight_set_pwm_level(conn_state, pwm_level);
492 ++ }
493 ++
494 + drm_edp_backlight_set_level(&intel_dp->aux, &panel->backlight.edp.vesa.info, level);
495 + }
496 +
497 +@@ -294,8 +300,13 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state,
498 + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
499 +
500 + if (!panel->backlight.edp.vesa.info.aux_enable) {
501 +- u32 pwm_level = intel_backlight_invert_pwm_level(connector,
502 +- panel->backlight.pwm_level_max);
503 ++ u32 pwm_level;
504 ++
505 ++ if (!panel->backlight.edp.vesa.info.aux_set)
506 ++ pwm_level = intel_backlight_level_to_pwm(connector, level);
507 ++ else
508 ++ pwm_level = intel_backlight_invert_pwm_level(connector,
509 ++ panel->backlight.pwm_level_max);
510 +
511 + panel->backlight.pwm_funcs->enable(crtc_state, conn_state, pwm_level);
512 + }
513 +@@ -332,7 +343,7 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector,
514 + if (ret < 0)
515 + return ret;
516 +
517 +- if (!panel->backlight.edp.vesa.info.aux_enable) {
518 ++ if (!panel->backlight.edp.vesa.info.aux_set || !panel->backlight.edp.vesa.info.aux_enable) {
519 + ret = panel->backlight.pwm_funcs->setup(connector, pipe);
520 + if (ret < 0) {
521 + drm_err(&i915->drm,
522 +@@ -341,14 +352,27 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector,
523 + return ret;
524 + }
525 + }
526 +- panel->backlight.max = panel->backlight.edp.vesa.info.max;
527 +- panel->backlight.min = 0;
528 +- if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
529 +- panel->backlight.level = current_level;
530 +- panel->backlight.enabled = panel->backlight.level != 0;
531 ++
532 ++ if (panel->backlight.edp.vesa.info.aux_set) {
533 ++ panel->backlight.max = panel->backlight.edp.vesa.info.max;
534 ++ panel->backlight.min = 0;
535 ++ if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
536 ++ panel->backlight.level = current_level;
537 ++ panel->backlight.enabled = panel->backlight.level != 0;
538 ++ } else {
539 ++ panel->backlight.level = panel->backlight.max;
540 ++ panel->backlight.enabled = false;
541 ++ }
542 + } else {
543 +- panel->backlight.level = panel->backlight.max;
544 +- panel->backlight.enabled = false;
545 ++ panel->backlight.max = panel->backlight.pwm_level_max;
546 ++ panel->backlight.min = panel->backlight.pwm_level_min;
547 ++ if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_PWM) {
548 ++ panel->backlight.level = panel->backlight.pwm_funcs->get(connector, pipe);
549 ++ panel->backlight.enabled = panel->backlight.pwm_enabled;
550 ++ } else {
551 ++ panel->backlight.level = panel->backlight.max;
552 ++ panel->backlight.enabled = false;
553 ++ }
554 + }
555 +
556 + return 0;
557 +diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
558 +index afdf7f4183f9..8b2ed4199284 100644
559 +--- a/include/drm/drm_dp_helper.h
560 ++++ b/include/drm/drm_dp_helper.h
561 +@@ -1868,7 +1868,7 @@ drm_dp_sink_can_do_video_without_timing_msa(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
562 + *
563 + * Note that currently this function will return %false for panels which support various DPCD
564 + * backlight features but which require the brightness be set through PWM, and don't support setting
565 +- * the brightness level via the DPCD. This is a TODO.
566 ++ * the brightness level via the DPCD.
567 + *
568 + * Returns: %True if @edp_dpcd indicates that VESA backlight controls are supported, %false
569 + * otherwise
570 +@@ -1876,8 +1876,7 @@ drm_dp_sink_can_do_video_without_timing_msa(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
571 + static inline bool
572 + drm_edp_backlight_supported(const u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE])
573 + {
574 +- return (edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP) &&
575 +- (edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP);
576 ++ return !!(edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP);
577 + }
578 +
579 + /*
580 +@@ -2238,6 +2237,7 @@ drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk)
581 + * @max: The maximum backlight level that may be set
582 + * @lsb_reg_used: Do we also write values to the DP_EDP_BACKLIGHT_BRIGHTNESS_LSB register?
583 + * @aux_enable: Does the panel support the AUX enable cap?
584 ++ * @aux_set: Does the panel support setting the brightness through AUX?
585 + *
586 + * This structure contains various data about an eDP backlight, which can be populated by using
587 + * drm_edp_backlight_init().
588 +@@ -2249,6 +2249,7 @@ struct drm_edp_backlight_info {
589 +
590 + bool lsb_reg_used : 1;
591 + bool aux_enable : 1;
592 ++ bool aux_set : 1;
593 + };
594 +
595 + int
596 +
597 +From patchwork Fri Nov 5 18:33:42 2021
598 +Content-Type: text/plain; charset="utf-8"
599 +MIME-Version: 1.0
600 +Content-Transfer-Encoding: 8bit
601 +Subject: [v5,5/5] drm/i915: Clarify probing order in
602 + intel_dp_aux_init_backlight_funcs()
603 +From: Lyude Paul <lyude@××××××.com>
604 +X-Patchwork-Id: 462382
605 +Message-Id: <20211105183342.130810-6-lyude@××××××.com>
606 +To: dri-devel@×××××××××××××××××.org, nouveau@×××××××××××××××××.org,
607 + intel-gfx@×××××××××××××××××.org
608 +Cc: David Airlie <airlied@×××××.ie>, open list <linux-kernel@×××××××××××.org>
609 +Date: Fri, 5 Nov 2021 14:33:42 -0400
610 +
611 +Hooray! We've managed to hit enough bugs upstream that I've been able to
612 +come up with a pretty solid explanation for how backlight controls are
613 +actually supposed to be detected and used these days. As well, having the
614 +rest of the PWM bits in VESA's backlight interface implemented seems to
615 +have fixed all of the problematic brightness controls laptop panels that
616 +we've hit so far.
617 +
618 +So, let's actually document this instead of just calling the laptop panels
619 +liars. As well, I would like to formally apologize to all of the laptop
620 +panels I called liars. I'm sorry laptop panels, hopefully you can all
621 +forgive me and we can move past this~
622 +
623 +Signed-off-by: Lyude Paul <lyude@××××××.com>
624 +Acked-by: Ville Syrjälä <ville.syrjala@×××××××××××.com>
625 +---
626 + .../drm/i915/display/intel_dp_aux_backlight.c | 16 +++++++++++-----
627 + 1 file changed, 11 insertions(+), 5 deletions(-)
628 +
629 +diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
630 +index 96fe3eaba44a..8b9c925c4c16 100644
631 +--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
632 ++++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
633 +@@ -456,11 +456,17 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
634 + }
635 +
636 + /*
637 +- * A lot of eDP panels in the wild will report supporting both the
638 +- * Intel proprietary backlight control interface, and the VESA
639 +- * backlight control interface. Many of these panels are liars though,
640 +- * and will only work with the Intel interface. So, always probe for
641 +- * that first.
642 ++ * Since Intel has their own backlight control interface, the majority of machines out there
643 ++ * using DPCD backlight controls with Intel GPUs will be using this interface as opposed to
644 ++ * the VESA interface. However, other GPUs (such as Nvidia's) will always use the VESA
645 ++ * interface. This means that there's quite a number of panels out there that will advertise
646 ++ * support for both interfaces, primarily systems with Intel/Nvidia hybrid GPU setups.
647 ++ *
648 ++ * There's a catch to this though: on many panels that advertise support for both
649 ++ * interfaces, the VESA backlight interface will stop working once we've programmed the
650 ++ * panel with Intel's OUI - which is also required for us to be able to detect Intel's
651 ++ * backlight interface at all. This means that the only sensible way for us to detect both
652 ++ * interfaces is to probe for Intel's first, and VESA's second.
653 + */
654 + if (try_intel_interface && intel_dp_aux_supports_hdr_backlight(connector)) {
655 + drm_dbg_kms(dev, "Using Intel proprietary eDP backlight controls\n");