Subject: [RFC v2] drm/kms: control display brightness through drm_connector properties As discussed already several times in the past: https://www.x.org/wiki/Events/XDC2014/XDC2014GoedeBacklight/ https://lore.kernel.org/all/4b17ba08-39f3-57dd-5aad-d37d844b02c6@linux.intel.com/ The current userspace API for brightness control offered by /sys/class/backlight devices has various issues, the biggest 2 being: 1. There is no way to map the backlight device to a specific display-output / panel (1) 2. Controlling the brightness requires root-rights requiring desktop-environments to use suid-root helpers for this. 3. The meaning of 0 is not clearly defined, it can be either off, or minimum brightness at which the display is still readable (in a low light environment) As already discussed on various conference's hallway tracks and as has been proposed on the dri-devel list once before (2), it seems that there is consensus that the best way to to solve these 2 issues is to add support for controlling a video-output's brightness through properties on the drm_connector. This RFC outlines my plan to try and actually implement this, which has 3 phases: Phase 1: Stop registering multiple /sys/class/backlight devs for a single display ================================================================================= On x86 there can be multiple firmware + direct-hw-access methods for controlling the backlight and in some cases the kernel registers multiple backlight-devices for a single internal laptop LCD panel: a) i915 and nouveau unconditionally register their "native" backlight dev even on devices where /sys/class/backlight/acpi_video0 must be used to control the backlight, relying on userspace to prefer the "firmware" acpi_video0 device over "native" devices. b) amdgpu and nouveau rely on the acpi_video driver initializing before them, which currently causes /sys/class/backlight/acpi_video0 to usually show up and then they register their own native backlight driver after which the drivers/acpi/video_detect.c code unregisters the acpi_video0 device. This means that userspace briefly sees 2 devices and the disappearing of acpi_video0 after a brief time confuses the systemd backlight level save/restore code, see e.g.: https://bbs.archlinux.org/viewtopic.php?id=269920 I already have a pretty detailed plan to tackle this, which I will post in a separate RFC email. I plan to start working on this right away, as it will be good to have this fixed regardless. Phase 2: Add drm_connector properties mirroring the matching backlight device ============================================================================= The plan is to add a drm_connector helper function, which optionally takes a pointer to the backlight device for the GPU's native backlight device, which will then mirror the backlight settings from the backlight device in a set of read/write brightness* properties on the connector. This function can then be called by GPU drivers for the drm_connector for the internal panel and it will then take care of everything. When there is no native GPU backlight device, or when it should not be used then (on x86) the helper will use the acpi_video_get_backlight_type() to determine which backlight-device should be used instead and it will find + mirror that one. Phase 3: Deprecate /sys/class/backlight uAPI ============================================ Once most userspace has moved over to using the new drm_connector brightness props, a Kconfig option can be added to stop exporting the backlight-devices under /sys/class/backlight. The plan is to just disable the sysfs interface and keep the existing backlight-device internal kernel abstraction as is, since some abstraction for (non GPU native) backlight devices will be necessary regardless. An alternative to disabling the sysfs class entirely, would be to allow setting it to read-only through Kconfig. The drm_connector brightness properties ======================================= The new uAPI for this consists of 2 properties: 1. "display brightness": rw 0-int32_max property controlling the brightness setting of the connected display. The actual maximum of this will be less then int32_max and is given in "display brightness max". Unlike the /sys/class/backlight/foo/brightness this brightness property has a clearly definition for the value 0. The kernel must ensure that 0 means minimum brightness (so 0 should _never_ turn the backlight off). If necessary the kernel must enforce a minimum value by adding an offset to the value seen in the property to ensure this behavior, see e.g. the use of AMDGPU_DM_DEFAULT_MIN_BACKLIGHT in amdgpu. Also whenever possible the kernel must ensure that the brightness range is in perceived brightness, but this cannot always be guaranteed. 2. "display brightness max": ro 0-int32_max property giving the actual maximum of the display's brightness setting. This will report 0 when brightness control is not available. The value of "display brightness max" may change at runtime, either by a legacy drivers/platform/x86 backlight driver loading after the drm driver has loaded; or when plugging in a monitor which allows brightness control over DDC/CI. In both these cases the max value will change from 0 to the actual max value, indicating backlight control has become available on this connector. Future extensions ================= Some hardware do adaptive brightness in hardware, rather then providing an ALS sensor and letting userspace handle this. One example of this is the Steam deck, which currently uses some custom sysfs attributes to allow tweaking (and enable/disable?) the adaptive brightness. Adding standardized uAPI for this through new "display brightness *" properties seems like a natural extension of this proposal. Regards, Hans 1) The need to be able to map the backlight device to a specific display has become clear once more with the recent proposal to add DDCDI support: https://lore.kernel.org/lkml/20220403230850.2986-1-yusisamerican@gmail.com/ 2) https://lore.kernel.org/all/4b17ba08-39f3-57dd-5aad-d37d844b02c6@linux.intel.com/ Note this proposal included a method for userspace to be able to tell the kernel if the native/acpi_video/vendor backlight device should be used, but this has been solved in the kernel for years now: https://www.spinics.net/lists/linux-acpi/msg50526.html An initial implementation of this proposal is available here: https://cgit.freedesktop.org/~mperes/linux/log/?h=backlight