Backlight brightness very low when using nvidia-driver-510 or newer. (Ubuntu 22.04)

I have a Razer Blade Pro 17 (2017) with 4K IGZO G-Sync Sharp CRX1200 display and GTX 1080 GPU.
On Ubuntu 22.04, using nvidia-driver-470, the backlight brightness is stuck at full. (I don’t really mind that.) However, if I upgrade to any of the newer drivers (510, 515, 520) the brightness control works, but maximum brightness is very low, maybe 20% of what I see on the 470 driver. I can barely read any text. I now need features from the 520 driver for my work, so I have no choice but to upgrade. As a workaround, I’m using an external HDMI monitor, but its frustrating that the laptop’s own display is now basically useless. I tried using various backlight brightness utilities and config file hacks, but so far nothing works.
I can adjust brightness by poking values into “/sys/class/backlight/nvidia_0/brightness”,
But even at max settings (100) the screen is very dim.
“xrandr --output DP-0 --brightness 1.5” helps a little, but that only adjusts color profile, not the backlight.
Is there any way to make the backlight as bright as it was with the 470 driver?

Did you already compare the values in /sys/class/backlight/nvidia_0/max_brightness
between 470 and 520?

On 470 and 520, in /sys/class/backlight/nvidia_0/
max_brightness=100, brightness=100, actual_brightness=100.

On 470, the screen is nice and bright, but adjusting brightness has no effect.

On 520, adjusting brightness does work, but at maximum brightness, the screen is very dark.
On 520, at bootup, the grub menu is nice and bright, but the screen darkens halfway through startup.

I found another interesting clue. The X.org driver seems to have a similar bug:
On X.org driver, after bootup, the screen is nice and bright.
Its brightness control is in : /sys/class/backlight/nv_backlight
Here, the values are: max_brightness=65520, brightness=4095, actual_brightness=65520
So, the brightness value is 16x higher than max_brightness!
However, as soon as I touch the brightness slider, brightness drops to 4095, and the screen goes just as dark as with the 520 diver. Brightness control can now be adjusted, but cannot go any higher than 4095, even if I use the terminal to echo values directly into brightness. The only way to get it back up to 65520, is to reboot.

This implies that max_brightness in the 520 is actually supposed to be 1600?

However, using 470 or X.Org driver is not really a solution, since I need the latest Vulkan drivers in 520 for my work.

Rather sounds like an acpi/bios bug. Are there any bios updates available?

It does. :)
However, I have already installed the latest bios updates from the Razer support website.
Also, screen brightness works fine under Windows 10 and 11.

Please attach an acpidump output.

Here is the acpidump:
dump (1.0 MB)

Checking the nouveau driver, the values are read directly from the panel over the eDP connector. So I guess no bios update or acpi fiddling can fix it. Unfortunately, the nvidia driver also makes a secret out of this, handling backlight control in the blob. Even the nvidia-open driver handles this in the firmware blob.
So only method that comes to my mind is patching the nvidia driver to not register the backlight device and instead try to enable an acpi handler, e.g. with kernel parameter acpi_backlight=video

The brightness values are read from the panel?
Does that mean my panel provides faulty EDID codes?
Is it possible at bootup, to apply a modified/custom EDID instead?

I tried setting “acpi_backlight=video” in /etc/default/grub, but the monitor still dims halfway through bootup.
It adds a new “acpi_video0” entry in /sys/class/backlight/ and hooks the gnome brightness slider to it.
So, the slider now updates /sys/class/backlight/acpi_video0/brightness, which has no effect.
I can still adjust brightness using the terminal, via /sys/class/backlight/nvidia_0/brightness

I also tried:
acpi_backlight=vendor
acpi_backlight=video
acpi_backlight=native
acpi_backlight=none
nvidia.NVreg_EnableBacklightHandler=0

All to no avail. Also, “modinfo nvidia” shows that the nvidia.NVreg.EnableBacklightHandler param has been removed. :(

Finally, I tried: “sudo systemctl mask systemd-backlight@backlight:nvidia_0.service”,
to prevent systemd from setting brightness at startup. This also did not work.

Is there any other way to prevent the nvidia driver from registering the backlight device?

Unfortunately, the parameter was removed from current drivers so you can only patch the driver.
nvkms_register_backlight in nvidia-modeset/nvidia-modeset-linux.c

They’re read from the panel but this is not contained in the edid but embedded in the eDP connection, defined in firmware. So for a real fix, the panel’s firmware would have to be updated but that’s rarely ever released.
I suspect Windows having a workaround in place for this, using the greater value of (max_brightness,brightness) on boot for max_brightness under the assumption the panel will start at its maximum brighness after power on.

patch the driver.
nvkms_register_backlight in nvidia-modeset/nvidia-modeset-linux.c

Is that something I can do myself? (That file is not open-source, is it?)

using the greater value of (max_brightness,brightness) on boot

That sounds like a plan! Any chance a future Linux driver could do the same?

That file is in the open source part of the driver, e.g. for driver 520.56.06
/usr/src/nvidia-520.56.06/nvidia-modeset/nvidia-modeset-linux.c
there you could try to replace
#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
with
#if false
and then recompile the modules
sudo dkms remove nvidia/520.56.06
sudo dkms install nvidia/520.56.06 --force

Oh, nice one! I didn’t know that was there!

Ok, I installed kbuild, and updated “nvidia-modeset-linux.c”
(I used: #undef CONFIG_BACKLIGHT_CLASS_DEVICE , instead of: #if false )
Then I compiled successfully, using “sudo make”.
The dkms install method didn’t quite work for me, since the dkms.conf file is missing. (Ubuntu 22.04)
Instead, I downloaded and unpacked nvidia’s .run installer, and repeated the update and compile there. Then I ran the installer. If I’m not mistaken, I THINK the patch was successful, because, for the first time, I now have the 520 driver installed, while at the same time, the /sys/class/backlight/nvidia_0 folder is missing.
Instead, I now have: /sys/class/backlight/acpi_video0

Unfortunately, this does not solve my problem… the display STILL darkens halfway through bootup.
Only now, I have no backlight control at all. Setting /sys/class/backlight/acpi_video0/brightness has no effect.

Bad. Though unlikely to work, tried setting .max_brightness to something different than 100?

I tried. max_brightness is read-only, so writing to it, gives a “Permission denied” error.
I also tried using chmod 666, to make it read-write, but then it gives a “Input/output error”.

I noticed /sys/class/backlight/nvidia_0/type = raw
According to this: Backlight support — The Linux Kernel documentation
raw implies that this type of backlight is controlled by using hardware registers.

According to this: Backlight - ArchWiki
on the Mobile 945GME, the backlight can be set with: setpci -s 00:02.0 F4.B=0

lspci | grep VGA gives me:
01:00.0 VGA compatible controller: NVIDIA Corporation GP104BM [GeForce GTX 1080 Mobile] (rev a1)

So I tried setpci -s 01:00.0 F4.B=0
This did not work. Maybe Nvidia cards use a different register? (F4.B?)

I meant setting .max_brightness in nvidia-modeset-linux.c and recompile (after reenabling the backlight handler). Though I guess the nvidia blob won’t accept values higher than 100, there’s a slim chance nvidia devs are as lazy as anyone else and rely on the kernel catching things.
Being “controlled by using hardware registers” does not necessarily mean those are exposed in the pci config space but you could check, e.g. creating a script

#!/bin/sh
echo 0 >/sys/class/backlight/nvidia_0/brightness
lspci -xxxx -s01:00.0 >brightness-zero.txt
echo 100 >/sys/class/backlight/nvidia_0/brightness
lspci -xxxx -s01:00.0 >brightness-full.txt

(assuming the bus id of your nvidia gpu is 01:00.0)
Then running it as root and afterwards doing a diff between both files should give you a hint whether or not the brightness is exposed in config space.

Oh, I see now what you mean…
In nvidia-modeset-linux.c, I set .max_brightness=200, compiled and reinstalled.
Now, /sys/class/backlight/nvidia_0/max_brightness = 200,
and I can set /sys/class/backlight/nvidia_0/brightness 200,
without getting the usual : “write error : Invalid argument”.
Unfortunately, the actual backlight does not brighten beyond the 100 level, and
/sys/class/backlight/nvidia_0/actual_brightness will not go higher than 100.

Also, thanks for the script. That was clever, but unfortunately, none of the register values change.

It seems the nvidia blob does not accept values higher than 100, as you predicted.
So, my best hope is that this issue will be fixed in a future Nvidia driver release. Is that likely to happen?

If not, maybe I could replace my laptop’s display panel with one that IS compatible with Nvidia drivers?
However, one of the main selling points of this laptop, is that it features a Certified NVIDIA G-SYNC display,
so I’m surprised that it is not compatible with proprietary Nvidia drivers.

My laptop is a Razer Blade Pro 17" (2017) | RZ09-01663
See: At a Glance: Razer Blade Pro 17" (2017) | RZ09-01663
The display panel is: LQ173D1JW33 (SHP145A)

Can you recommend a display panel that IS compatible?