i915: intel_dp_aux_backlight max_brightness set to incorrect value on Thinkpad P1 Gen2 AMOLED
Submitted by Josh Farwell
Assigned to Intel GFX Bugs mailing list
Link to original bug (#112014)
Description
I found an interesting issue concerning the backlight on my new laptop. I am running Fedora 30 and replicated the issue with 5.2.17 and 5.3.5 kernels. Hardware is as follows:
Thinkpad P1 Gen2
- i9-9880k
- Nvidia Optimus with Quadro T2000
- 4K AMOLED Touch display with eDP display connector
I would not be surprised at all if the Thinkpad X1 Extreme Gen 2 with AMOLED has the same problem, they're pretty much exactly the same hardware apparently.
This laptop's display uses AMOLED and does not have a traditional backlight. We get backlight control by turning on the enable_dpcd_backlight parameter in the i915 module and using PWM based backlight control. I dropped this config in /etc/modprobe.d/i915.conf to enable this feature:
```
[josh@lappy-mk5 linux-stable]$ cat /etc/modprobe.d/i915.conf
options i915 enable_dpcd_backlight
```
When I turned it on, I discovered that the brightness controls were very wonky. As I triggered the "brightness up" ACPI event, the backlight was switching between low brightness and high brightness with every key press, and the brightness level seemed random. There were no errors found in dmesg.
The backlight control is found in /sys/devices/pci0000:00/0000:00:02.0/drm/card0/card0-eDP-1/intel_backlight on my system. max_brightness is set to 65535, which i've seen on other systems. I discovered through some tinkering that if we pass integers 0 - 2047 to intel_backlight/brightness, the brightness scales linearly. Once we pass 2048 to the brightness function, the brightness drops back down to the same level as it was at 0. This happens again at 4097 where it is at maximum brightness, and 4098 brings the brightness level back to zero again. This sequence repeats 30 more times until we are at maximum brightness at 65535.
I traced this issue to this function in drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c (line 228-245 on 5.3.5 stable):
```
static int intel_dp_aux_setup_backlight(struct intel_connector *connector,
enum pipe pipe)
{
struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
struct intel_panel *panel = &connector->panel;
if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT)
panel->backlight.max = 0xFFFF;
else
panel->backlight.max = 0xFF;
panel->backlight.min = 0;
panel->backlight.level = intel_dp_aux_get_backlight(connector);
panel->backlight.enabled = panel->backlight.level != 0;
return 0;
}
```
When I hack this function and replace 0xFFFF with 0x7FF, my backlight works perfectly with no problems.
It seems like this function needs a third branch in that conditional that knows something specific about this laptop's display and can set the max_brightness to 2047. I don't know enough about the rest of the driver to write a patch for this, but I am happy to help by collecting debug information and testing patches. Just let me know what I should provide next.